diff orpg/networking/meta_server_lib.py @ 96:65c1604e7949 alpha

Traipse Alpha 'OpenRPG' {090924-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary: 00: Update forwards to the 090909-02 Server code that now works. New default Lobby Map, designed for Traipse. Feel free to change it. Updates to Server GUI: * Admin can Ban from Backend. * Prework to modify Ban List in back end. * Server GUI finds your Lobby Name * New users default as Lurker unless a Role is set New Addition to Chat Die Roll commands. Math Ordering. Ex. [(X+Y)dZ]. Currently does pairs only, no nesting either. Cleaner TraipseSuiteAttention portability and clean up in Main (Beta!)
author sirebral
date Thu, 24 Sep 2009 02:05:08 -0500
parents d1aff41c031b
children 9314d63c0941 dcf4fbe09b70
line wrap: on
line diff
--- a/orpg/networking/meta_server_lib.py	Sat Sep 19 12:19:17 2009 -0500
+++ b/orpg/networking/meta_server_lib.py	Thu Sep 24 02:05:08 2009 -0500
@@ -34,9 +34,9 @@
 __version__ = "$Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $"
 
 from orpg.orpg_version import PROTOCOL_VERSION
-from orpg.orpg_xml import xml
-import orpg.dirpath
-import orpg.tools.validate
+from orpg.orpgCore import component
+from orpg.tools.validate import validate
+from orpg.dirpath import dir_struct
 import urllib
 import orpg.minidom
 from threading import *
@@ -69,8 +69,7 @@
     # Remove any leading or trailing data.  This can happen on some satellite connections
     p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE)
     mo = p.search(data)
-    if mo:
-        data = mo.group(0)
+    if mo: data = mo.group(0)
 
     if META_DEBUG:
         print
@@ -79,16 +78,12 @@
         print data
         print
     # build dom
+    xml = component.get('xml')
     xml_dom = xml.parseXml(data)
     xml_dom = xml_dom._get_documentElement()
     return xml_dom
 
 def post_server_data( name, realHostName=None):
-    # build POST data
-##    data = urllib.urlencode( {"server_data[name]":name,
-##                              "server_data[version]":PROTOCOL_VERSION,
-##                              "act":"new"} )
-##
     if realHostName:
         data = urllib.urlencode( {"server_data[name]":name,
                                   "server_data[version]":PROTOCOL_VERSION,
@@ -101,7 +96,9 @@
                                   "server_data[version]":PROTOCOL_VERSION,
                                   "act":"new"} )
 
-    xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php")
+    #xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php")#Sourceforge still?
+    path = component.get('settings').get_setting('MetaServerBaseURL') #getMetaServerBaseURL()
+    xml_dom = get_server_dom(data, path)
     ret_val = int( xml_dom.getAttribute( "id" ) )
     return ret_val
 
@@ -109,10 +106,10 @@
     #  For now, turning this off.  This needs to be re-vamped for
     #  handling multiple Metas.
     return 0
-#    data = urllib.urlencode({"id":id,"act":"failed"});
-#    xml_dom = get_server_dom(data)
-#    ret_val = int(xml_dom.getAttribute("return"))
-#    return ret_val
+    #data = urllib.urlencode({"id":id,"act":"failed"});
+    #xml_dom = get_server_dom(data)
+    #ret_val = int(xml_dom.getAttribute("return"))
+    #return ret_val
 
 def remove_server(id):
     data = urllib.urlencode({"id":id,"act":"del"});
@@ -125,15 +122,11 @@
     #  This function is used to easily sort a list of nodes
     #  by their start time
 
-    if first.hasAttribute("start"):
-        first_start = int(first.getAttribute("start"))
-    else:
-        first_start = 0
+    if first.hasAttribute("start"): first_start = int(first.getAttribute("start"))
+    else: first_start = 0
 
-    if second.hasAttribute("start"):
-        second_start = int(second.getAttribute("start"))
-    else:
-        second_start = 0
+    if second.hasAttribute("start"): second_start = int(second.getAttribute("start"))
+    else: second_start = 0
 
     # Return the result of the cmp function on the two strings
     return cmp(first_start,second_start)
@@ -144,18 +137,13 @@
 
     # Ensure there is something to sort with for each
 
-    if first.hasAttribute("name"):
-        first_name = str(first.getAttribute("name")).lower()
-    else:
-        first_name = ""
+    if first.hasAttribute("name"): first_name = str(first.getAttribute("name")).lower()
+    else: first_name = ""
 
-    if second.hasAttribute("name"):
-        second_name = str(second.getAttribute("name")).lower()
-    else:
-        second_name = ""
+    if second.hasAttribute("name"): second_name = str(second.getAttribute("name")).lower()
+    else: second_name = ""
 
     # Return the result of the cmp function on the two strings
-
     return cmp(first_name,second_name)
 
 
@@ -171,11 +159,10 @@
 
     for meta in all_metas:                  # check all of the metas
 
-        #  get the server's xml from the current meta
+        #get the server's xml from the current meta
         bad_meta = 0
         #print "Getting server list from " + meta + "..."
-        try:
-            xml_dom = get_server_dom(data=data,path=meta)
+        try: xml_dom = get_server_dom(data=data,path=meta)
         except:
             #print "Trouble getting servers from " + meta + "..."
             bad_meta = 1
@@ -198,17 +185,13 @@
 
                 # set them from current node
 
-                if not n.hasAttribute('name'):
-                    n.setAttribute('name','NO_NAME_GIVEN')
+                if not n.hasAttribute('name'): n.setAttribute('name','NO_NAME_GIVEN')
                 name = n.getAttribute('name')
-                if not n.hasAttribute('num_users'):
-                    n.setAttribute('num_users','N/A')
+                if not n.hasAttribute('num_users'): n.setAttribute('num_users','N/A')
                 num_users = n.getAttribute('num_users')
-                if not n.hasAttribute('address'):
-                    n.setAttribute('address','NO_ADDRESS_GIVEN')
+                if not n.hasAttribute('address'): n.setAttribute('address','NO_ADDRESS_GIVEN')
                 address = n.getAttribute('address')
-                if not n.hasAttribute('port'):
-                    n.setAttribute('port','6774')
+                if not n.hasAttribute('port'): n.setAttribute('port','6774')
                 port = n.getAttribute('port')
                 n.setAttribute('meta',meta)
                 end_point = str(address) + ":" + str(port)
@@ -228,14 +211,11 @@
     #  sort them by their name attribute.  Uses byNameAttribute()
     #  defined above as a comparison function
 
-    if sort_by == "start":
-        return_list.sort(byStartAttribute)
-    elif sort_by == "name":
-        return_list.sort(byNameAttribute)
+    if sort_by == "start": return_list.sort(byStartAttribute)
+    elif sort_by == "name": return_list.sort(byNameAttribute)
 
     #  Add each node to the DOM
-    for n in return_list:
-        return_dom.appendChild(n)
+    for n in return_list: return_dom.appendChild(n)
     return return_dom
 
 ## List Format:
@@ -257,7 +237,7 @@
         if META_DEBUG: print "  Meta List ("+str(len(metas))+" servers)"
         try:
             metacache_lock.acquire()
-            ini = open(orpg.dirpath.dir_struct["user"]+"metaservers.cache","w")
+            ini = open(dir_struct["user"]+"metaservers.cache","w")
             for meta in metas:
                 if META_DEBUG: print "   Writing: "+str(meta.getAttribute('path'))
                 ini.write(str(meta.getAttribute('path')) + " " + str(meta.getAttribute('versions')) + "\n")
@@ -273,8 +253,8 @@
         try:
             metacache_lock.acquire()
             #  Read in the metas
-            orpg.tools.validate.Validate().config_file("metaservers.cache","metaservers.cache")
-            ini = open(orpg.dirpath.dir_struct["user"]+"metaservers.cache","r")
+            validate.config_file("metaservers.cache","metaservers.cache")
+            ini = open(dir_struct["user"]+"metaservers.cache","r")
             metas = ini.readlines()
             ini.close()
             return metas
@@ -286,23 +266,27 @@
         return []
 
 def getMetaServers(versions = None, pick_random=0):
-    # get meta server URLs as a list
+    """
+     get meta server URLs as a list
 
-    #  versions is a list of acceptable version numbers.
-    #    A False truth value will use getMetaServerBaseURL()
+      versions is a list of acceptable version numbers.
+        A False truth value will use getMetaServerBaseURL()
 
-    # set a default if we have weird reading problems
-    # default_url = "http://www.openrpg.com/openrpg_servers.php"
+     set a default if we have weird reading problems
+     default_url = "http://www.openrpg.com/openrpg_servers.php"
+    """
 
     meta_names = []
 
     if(versions):  #  If versions are supplied, then look in metaservers.conf
         try:
-            #  read in the metas from file
-            #  format of file is one meta entry per line
-            #  each entry will be the meta url, followed by one or more version numbers that it
-            #  handle.  Generally, this will be either a 1 for the original Meta format, or
-            #  2 for the new one.
+            """
+              read in the metas from file
+              format of file is one meta entry per line
+              each entry will be the meta url, followed by one or more version numbers that it
+              handle.  Generally, this will be either a 1 for the original Meta format, or
+              2 for the new one.
+            """
 
             #  Read in the metas
             metas = getRawMetaList()
@@ -315,13 +299,10 @@
                 # split the line on whitespace
                 #   obviously, your meta servers urls shouldn't contain whitespace.  duh.
                 words = meta.split()
-
                 success = 0         #  init success flag for version check
-
                 for version in versions:    # run through each allowed version from caller
                     if version in words[1:]:  #  if the allowed version token was found
                         success += 1          #  then increment the success indicator
-
                 if success:          #  if the meta entry is acceptable to the caller
                     meta_names.append(words[0])    #  add the entry
                     if META_DEBUG: print "adding metaserver " + meta
@@ -330,8 +311,8 @@
             if not meta_names:
                 default_meta = getMetaServerBaseURL()       # grab the meta from ini.xml
                 meta_names.append(default_meta)             # add it to the return list
-#                print "Warning!!\nNo valid metaservers cached."
-#                print "Using meta from MetaServerBaseURL: " + default_meta + "\n"
+            # print "Warning!!\nNo valid metaservers cached."
+            # print "Using meta from MetaServerBaseURL: " + default_meta + "\n"
             # if we have more than one and want a random one
             elif pick_random:
                 if META_DEBUG: print "choosing random meta from: " + str(meta_names)
@@ -357,9 +338,10 @@
     # get meta server URL
     url = "http://www.openrpg.com/openrpg_servers.php"
     try:
-        orpg.tools.validate.Validate().config_file("settings.xml","default_settings.xml")
-        ini = open(orpg.dirpath.dir_struct["user"]+"settings.xml","r")
+        component.get('validate').config_file("settings.xml","default_settings.xml")
+        ini = open(dir_struct["user"]+"settings.xml","r")
         txt = ini.read()
+        xml = component.get('xml')
         tree = xml.parseXml(txt)._get_documentElement()
         ini.close()
         node_list = tree.getElementsByTagName("MetaServerBaseURL")
@@ -367,47 +349,47 @@
             url = node_list[0].getAttribute("value")
 
         # allow tree to be collected
-        try:
-            tree.unlink()
-        except:
-            pass
+        try: tree.unlink()
+        except: pass
 
     except Exception,e:
         print e
-#    print "using meta server URI: " + url
+    #print "using meta server URI: " + url
     return url
 
-#######################################################################################
-#  Beginning of Class registerThread
-#
-#  A Class to Manage Registration with the Meta2
-#  Create an instance and call it's start() method
-#  if you want to be (and stay) registered.  This class
-#  will take care of registering and re-registering as
-#  often as necessary to stay in the Meta list.
-#
-#  You may call register() yourself if you wish to change your
-#  server's name.  It will immediately update the Meta.  There
-#  is no need to unregister first.
-#
-#  Call unregister() when you no longer want to be registered.
-#  This will result in the registerThread dying after
-#  attempting to immediately remove itself from the Meta.
-#
-#  If you need to become registered again after that, you
-#  must create a new instance of class registerThread.  Don't
-#  just try to call register() on the old, dead thread class.
+"""
+  Beginning of Class registerThread
+
+  A Class to Manage Registration with the Meta2
+  Create an instance and call it's start() method
+  if you want to be (and stay) registered.  This class
+  will take care of registering and re-registering as
+  often as necessary to stay in the Meta list.
 
+  You may call register() yourself if you wish to change your
+  server's name.  It will immediately update the Meta.  There
+  is no need to unregister first.
+
+  Call unregister() when you no longer want to be registered.
+  This will result in the registerThread dying after
+  attempting to immediately remove itself from the Meta.
+
+  If you need to become registered again after that, you
+  must create a new instance of class registerThread.  Don't
+  just try to call register() on the old, dead thread class.
+"""
 
 class registerThread(Thread):
-#  Originally, I wrote this as a sub-class of wxThread, but
-#       A)  I couldn't get it to import right
-#       B)  I realized that I want this to be used in a server,
-#           which I don't want needing wxWindows to run!
-#
-#   Because of this fact, there are some methods from wxThread
-#   that I implemented to minimize changes to the code I had
-#   just written, i.e. TestDeleteStatus() and Delete()
+    """
+      Originally, I wrote this as a sub-class of wxThread, but
+           A)  I couldn't get it to import right
+           B)  I realized that I want this to be used in a server,
+               which I don't want needing wxWindows to run!
+    
+       Because of this fact, there are some methods from wxThread
+       that I implemented to minimize changes to the code I had
+       just written, i.e. TestDeleteStatus() and Delete()
+    """
 
     def __init__(self,name=None,realHostName=None,num_users = "Hmmm",MetaPath=None,port=6774,register_callback=None):
 
@@ -429,15 +411,17 @@
                                                 #  re-register, in minutes.
         self.destroy = 0                        #  Used to flag that this thread should die
         self.port = str(port)
-        self.register_callback = register_callback               # set a method to call to report result of register
-        #  This thread will communicate with one and only one
-        #  Meta.  If the Meta in ini.xml is changed after
-        #  instantiation, then this instance must be
-        #  unregistered and a new instance instantiated.
-        #
-        #  Also, if MetaPath is specified, then use that.  Makes
-        #  it easier to have multiple registerThreads going to keep the server registered
-        #  on multiple (compatible) Metas.
+        self.register_callback = register_callback  # set a method to call to report result of register
+        """
+          This thread will communicate with one and only one
+          Meta.  If the Meta in ini.xml is changed after
+          instantiation, then this instance must be
+          unregistered and a new instance instantiated.
+        
+          Also, if MetaPath is specified, then use that.  Makes
+          it easier to have multiple registerThreads going to keep the server registered
+          on multiple (compatible) Metas.
+        """
 
         if MetaPath == None:
             self.path = getMetaServerBaseURL()  #  Do this if no Meta specified
@@ -462,18 +446,19 @@
             self.rlock.release()
 
     def run(self):
-    #  This method gets called by Thread implementation
-    #  when self.start() is called to begin the thread's
-    #  execution
-    #
-    #  We will basically enter a loop that continually
-    #  re-registers this server and sleeps Interval
-    #  minutes until the thread is ordered to die in place
+        """
+          This method gets called by Thread implementation
+          when self.start() is called to begin the thread's
+          execution
+        
+          We will basically enter a loop that continually
+          re-registers this server and sleeps Interval
+          minutes until the thread is ordered to die in place
+        """
         while(not self.TestDeleteStatus()):         # Loop while until told to die
             #  Otherwise, call thread safe register().
             self.register(self.name, self.realHostName, self.num_users)
             if META_DEBUG: print "Sent Registration Data"
-
             #  register() will end up setting the state variables
             #  for us, including self.interval.
             try:
@@ -496,19 +481,21 @@
         #  calls to Thread.isAlive() return False.
 
     def unregister(self):
-        #  This method can (I hope) be called from both within the thread
-        #  and from other threads.  It will attempt to unregister this
-        #  server from the Meta database
-        #  When this is either accomplished or has been tried hard enough
-        #  (after which it just makes sense to let the Meta remove the
-        #  entry itself when we don't re-register using this id),
-        #  this method will either cause the thread to immediately die
-        #  (if called from this thread's context) or set the Destroy flag
-        #  (if called from the main thread), a positive test for which will cause
-        #  the code in Entry() to exit() when the thread wakes up and
-        #  checks TestDeleteStatus().
-        #  lock the critical section.  The unlock will
-        #  automatically occur at the end of the function in the finally clause
+        """
+          This method can (I hope) be called from both within the thread
+          and from other threads.  It will attempt to unregister this
+          server from the Meta database
+          When this is either accomplished or has been tried hard enough
+          (after which it just makes sense to let the Meta remove the
+          entry itself when we don't re-register using this id),
+          this method will either cause the thread to immediately die
+          (if called from this thread's context) or set the Destroy flag
+          (if called from the main thread), a positive test for which will cause
+          the code in Entry() to exit() when the thread wakes up and
+          checks TestDeleteStatus().
+          lock the critical section.  The unlock will
+          automatically occur at the end of the function in the finally clause
+        """
         try:
             self.rlock.acquire()
             if not self.isAlive():      #  check to see if this thread is dead
@@ -531,35 +518,31 @@
             #  way, we can't do anything else, so die.
             self.Delete()            #  This will cause the registerThread to die in register()
             #  prep xml_dom for garbage collection
-            try:
-                xml_dom.unlink()
-            except:
-                pass
+            try: xml_dom.unlink()
+            except: pass
             return 0
-        finally:
-            self.rlock.release()
+        finally: self.rlock.release()
 
     def register(self, name=None, realHostName=None, num_users=None):
-        #  Designed to handle the registration, both new and
-        #  repeated.
-        #
-        #  It is intended to be called once every interval
-        #    (or interval - delta) minutes.
+        """
+          Designed to handle the registration, both new and
+          repeated.
+        
+          It is intended to be called once every interval
+            (or interval - delta) minutes.
 
-        #  lock the critical section.  The unlock will
-        #  automatically occur at the end of the function in the finally clause
+          lock the critical section.  The unlock will
+          automatically occur at the end of the function in the finally clause
+        """
         try:
             self.rlock.acquire()
             if not self.isAlive():      #  check to see if this thread is dead
                 return 1                #  If so, return an error result
 
             #  Set the server's attibutes, if specified.
-            if name:
-                self.name = name
-            if num_users != None:
-                self.num_users = num_users
-            if realHostName:
-                self.realHostName = realHostName
+            if name: self.name = name
+            if num_users != None: self.num_users = num_users
+            if realHostName: self.realHostName = realHostName
             # build POST data
             if self.realHostName:
                 data = urllib.urlencode( {"server_data[id]":self.id,
@@ -586,17 +569,20 @@
                 if META_DEBUG: print data
                 if META_DEBUG: print
                 self.interval = 0
-                #  If we are in the registerThread thread, then setting interval to 0
-                #  will end up causing a retry in about 6 seconds (see self.run())
-                #  If we are in the main thread, then setting interval to 0 will do one
-                #  of two things:
-                #  1)  Do the same as if we were in the registerThread
-                #  2)  Cause the next, normally scheduled register() call to use the values
-                #      provided in this call.
-                #
-                #  Which case occurs depends on where the registerThread thread is when
-                #  the main thread calls register().
+                """
+                  If we are in the registerThread thread, then setting interval to 0
+                  will end up causing a retry in about 6 seconds (see self.run())
+                  If we are in the main thread, then setting interval to 0 will do one
+                  of two things:
+                  1)  Do the same as if we were in the registerThread
+                  2)  Cause the next, normally scheduled register() call to use the values
+                      provided in this call.
+                
+                  Which case occurs depends on where the registerThread thread is when
+                  the main thread calls register().
+                """
                 return 0  # indicates that it was okay to call, not that no errors occurred
+
             #  If there is a DOM returned ....
             if xml_dom:
                 #  If there's an error, echo it to the console
@@ -604,22 +590,24 @@
                     print "Error durring registration:  " + xml_dom.getAttribute("errmsg")
                     if META_DEBUG: print data
                     if META_DEBUG: print
-                #  No special handling is required.  If the registration worked, id, cookie, and interval
-                #  can be stored and used for the next time.
-                #  If an error occurred, then the Meta will delete us and we need to re-register as
-                #  a new server.  The way to indicate this is with a "0" id and "0" cookie sent to
-                #  the server during the next registration.  Since that's what the server returns to
-                #  us on an error anyway, we just store them and the next registration will
-                #  automatically be set up as a new one.
-                #
-                #  Unless the server calls register() itself in the meantime.  Of course, that's okay
-                #  too, because a success on THAT register() call will set up the next one to use
-                #  the issued id and cookie.
-                #
-                #  The interval is stored unconditionally for similar reasons.  If there's an error,
-                #  the interval will be less than 1, and the main thread's while loop will reset it
-                #  to 6 seconds for the next retry.
-                #  Is it wrong to have a method where there's more comments than code?  :)
+                """
+                  No special handling is required.  If the registration worked, id, cookie, and interval
+                  can be stored and used for the next time.
+                  If an error occurred, then the Meta will delete us and we need to re-register as
+                  a new server.  The way to indicate this is with a "0" id and "0" cookie sent to
+                  the server during the next registration.  Since that's what the server returns to
+                  us on an error anyway, we just store them and the next registration will
+                  automatically be set up as a new one.
+                
+                  Unless the server calls register() itself in the meantime.  Of course, that's okay
+                  too, because a success on THAT register() call will set up the next one to use
+                  the issued id and cookie.
+                
+                  The interval is stored unconditionally for similar reasons.  If there's an error,
+                  the interval will be less than 1, and the main thread's while loop will reset it
+                  to 6 seconds for the next retry.
+                  Is it wrong to have a method where there's more comments than code?  :)
+                """
                 try:
                     self.interval = int(xml_dom.getAttribute("interval"))
                     self.id = xml_dom.getAttribute("id")