Mercurial > traipse_dev
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")