diff orpg/networking/meta_server_lib.py @ 90:d1aff41c031b alpha

Traipse Alpha 'OpenRPG' {090919-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: Adds menu changes to draw attention to important updates, errors, or other events. (image info coming soon) Traipse URL is not included in the repos tab and is set as default. 01: Fixes Copy for Windows and Linux (finally!!) users. Fixes incomplete update to Grid and List nodes. Fixes incomplete update to Chat Commands. 02: Fixes problems with Remote Image Upload. Fixes Drop and Drag of Minis to Map. CherryPy can now use any image in the webfiles/ folder and sub-folders. CherryPy can now Drop and Drag Minis to the Map. 03: Minor changes to Update Manager's GUI. Expert recommendation warning added to Revision Update. Step down compatibility with open_rpg & component added to orpgCore. 19-00: Better backwards compatibility in orpgCore. Using majority of 'Grumpy' network folder to correct server lag.
author sirebral
date Sat, 19 Sep 2009 06:45:21 -0500
parents 449a8900f9ac
children 65c1604e7949
line wrap: on
line diff
--- a/orpg/networking/meta_server_lib.py	Thu Sep 17 06:29:32 2009 -0500
+++ b/orpg/networking/meta_server_lib.py	Sat Sep 19 06:45:21 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.orpgCore import component
-from orpg.tools.validate import validate
-from orpg.dirpath import dir_struct
+from orpg.orpg_xml import xml
+import orpg.dirpath
+import orpg.tools.validate
 import urllib
 import orpg.minidom
 from threading import *
@@ -69,7 +69,8 @@
     # 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
@@ -78,12 +79,16 @@
         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,
@@ -96,9 +101,7 @@
                                   "server_data[version]":PROTOCOL_VERSION,
                                   "act":"new"} )
 
-    #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)
+    xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php")
     ret_val = int( xml_dom.getAttribute( "id" ) )
     return ret_val
 
@@ -106,10 +109,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"});
@@ -122,11 +125,15 @@
     #  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)
@@ -137,13 +144,18 @@
 
     # 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)
 
 
@@ -159,10 +171,11 @@
 
     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
@@ -185,13 +198,17 @@
 
                 # 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)
@@ -211,11 +228,14 @@
     #  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:
@@ -237,7 +257,7 @@
         if META_DEBUG: print "  Meta List ("+str(len(metas))+" servers)"
         try:
             metacache_lock.acquire()
-            ini = open(dir_struct["user"]+"metaservers.cache","w")
+            ini = open(orpg.dirpath.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")
@@ -253,8 +273,8 @@
         try:
             metacache_lock.acquire()
             #  Read in the metas
-            validate.config_file("metaservers.cache","metaservers.cache")
-            ini = open(dir_struct["user"]+"metaservers.cache","r")
+            orpg.tools.validate.Validate().config_file("metaservers.cache","metaservers.cache")
+            ini = open(orpg.dirpath.dir_struct["user"]+"metaservers.cache","r")
             metas = ini.readlines()
             ini.close()
             return metas
@@ -266,27 +286,23 @@
         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()
@@ -299,10 +315,13 @@
                 # 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
@@ -311,8 +330,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)
@@ -338,10 +357,9 @@
     # get meta server URL
     url = "http://www.openrpg.com/openrpg_servers.php"
     try:
-        component.get('validate').config_file("settings.xml","default_settings.xml")
-        ini = open(dir_struct["user"]+"settings.xml","r")
+        orpg.tools.validate.Validate().config_file("settings.xml","default_settings.xml")
+        ini = open(orpg.dirpath.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")
@@ -349,47 +367,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.
+#######################################################################################
+#  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.
 
-  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):
 
@@ -411,17 +429,15 @@
                                                 #  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
@@ -446,19 +462,18 @@
             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:
@@ -481,21 +496,19 @@
         #  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
@@ -518,31 +531,35 @@
             #  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,
@@ -569,20 +586,17 @@
                 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
@@ -590,24 +604,22 @@
                     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")