comparison orpg/networking/mplay_server.py @ 122:36919b8a3ef9 alpha

Traipse Alpha 'OpenRPG' {091031-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 (Cleaning up for Beta) Added Bookmarks Fix to Remote Admin Commands Minor fix to text based Server Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager default_manifest.xml renamed to default_upmana.xml Cleaner clode for saved repositories New TrueDebug Class in orpg_log Mercurial's hgweb folder is ported to upmana Happy Halloween!
author sirebral
date Sat, 31 Oct 2009 22:07:55 -0500
parents 9314d63c0941
children 8827271fbe1b
comparison
equal deleted inserted replaced
121:496dbf12a6cb 122:36919b8a3ef9
29 # 29 #
30 30
31 31
32 # 04-15-2005 [Snowdog]: Added patch from Brandan Yares (xeriar). Reference: patch tracker id #1182076 32 # 04-15-2005 [Snowdog]: Added patch from Brandan Yares (xeriar). Reference: patch tracker id #1182076
33 33
34 from __future__ import with_statement
35
34 __version__ = "$Id: mplay_server.py,v 1.155 2008/01/24 03:52:03 digitalxero Exp $" 36 __version__ = "$Id: mplay_server.py,v 1.155 2008/01/24 03:52:03 digitalxero Exp $"
35 37
36 #!/usr/bin/env python 38 #!/usr/bin/env python
37 """ 39 """
38 <msg to='' from='' group_id='' /> 40 <msg to='' from='' group_id='' />
41 <create_group from='' pwd='' name='' /> 43 <create_group from='' pwd='' name='' />
42 <join_group from='' pwd='' group_id='' /> 44 <join_group from='' pwd='' group_id='' />
43 <role action='set,get,display' player='' group_id='' boot_pwd='' role=''/> 45 <role action='set,get,display' player='' group_id='' boot_pwd='' role=''/>
44 """ 46 """
45 47
46 import re 48 import re, gc, cgi, sys, string, time, urllib, traceback
47 import gc
48 import cgi
49 import sys
50 import string
51 import time
52 import urllib
53 import traceback
54 49
55 from mplay_client import * 50 from mplay_client import *
56 from mplay_client import MPLAY_LENSIZE 51 from mplay_client import MPLAY_LENSIZE
57 from orpg.dirpath import dir_struct 52 from orpg.dirpath import dir_struct
58 import orpg.tools.validate 53 import orpg.tools.validate
60 from orpg.mapper.map_msg import * 55 from orpg.mapper.map_msg import *
61 from threading import Lock, RLock 56 from threading import Lock, RLock
62 from struct import pack, unpack, calcsize 57 from struct import pack, unpack, calcsize
63 from meta_server_lib import * 58 from meta_server_lib import *
64 59
65 # Import the minidom XML module 60 from xml.etree.ElementTree import ElementTree, Element, iselement
66 from xml.dom import minidom 61 from xml.etree.ElementTree import fromstring, tostring, parse, XML
62
63 from orpg.tools.orpg_log import logger, crash, debug
64 from orpg.tools.decorators import debugging
67 65
68 # Snag the version number 66 # Snag the version number
69 from orpg.orpg_version import VERSION, PROTOCOL_VERSION, CLIENT_STRING, SERVER_MIN_CLIENT_VERSION 67 from orpg.orpg_version import VERSION, PROTOCOL_VERSION, CLIENT_STRING, SERVER_MIN_CLIENT_VERSION
70 68
71 #Plugins 69 #Plugins
75 "converts strings to intergers for list sort comparisons for group and player ids so they end up in numeric order" 73 "converts strings to intergers for list sort comparisons for group and player ids so they end up in numeric order"
76 return cmp(int(a),int(b)) 74 return cmp(int(a),int(b))
77 75
78 76
79 class game_group(object): 77 class game_group(object):
78 debug()
80 def __init__(self, id, name, pwd, desc="", boot_pwd="", 79 def __init__(self, id, name, pwd, desc="", boot_pwd="",
81 minVersion="", mapFile=None, messageFile=None, persist=0): 80 minVersion="", mapFile=None, messageFile=None, persist=0):
82 self.id = id 81 self.id = id
83 self.name = name 82 self.name = name
84 self.desc = desc 83 self.desc = desc
91 self.lock = Lock() 90 self.lock = Lock()
92 self.moderated = 0 91 self.moderated = 0
93 self.voice = {} 92 self.voice = {}
94 self.persistant = persist 93 self.persistant = persist
95 self.mapFile = None 94 self.mapFile = None
96 95 ### Needs to use Element Tree closer
97 if mapFile != None: 96 if mapFile != None:
98 """
99 try:
100 f = open(filename, "rb")
101 tree = parse(f)
102 self.xml_root = tree.getroot()
103 except:
104 f.close()
105 self.xml_root = None
106 """
107 self.mapFile = mapFile
108 f = open( mapFile ) 97 f = open( mapFile )
109 tree = f.read() 98 tree = f.read()
110 f.close() 99 f.close()
111 else: 100 else:
112 f = open(dir_struct["template"] + "default_map.xml") 101 f = open(orpg.dirpath.dir_struct["template"] + "default_map.xml")
113 tree = f.read() 102 tree = f.read()
114 f.close() 103 f.close()
115 self.game_map.init_from_xml(tree) 104 self.game_map.init_from_xml(fromstring(tree))
116 105
117 def save_map(self): 106 def save_map(self):
107 debug()
118 if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1: 108 if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1:
119 f = open(self.mapFile, "w") 109 f = open(self.mapFile, "w")
120 f.write(self.game_map.get_all_xml()) 110 f.write(self.game_map.get_all_xml())
121 f.close() 111 f.close()
122 112
123 def add_player(self,id): 113 def add_player(self,id):
114 debug()
124 self.players.append(id) 115 self.players.append(id)
125 116
126 def remove_player(self,id): 117 def remove_player(self,id):
118 debug()
127 if self.voice.has_key(id): del self.voice[id] 119 if self.voice.has_key(id): del self.voice[id]
128 self.players.remove(id) 120 self.players.remove(id)
129 121
130 def get_num_players(self): 122 def get_num_players(self):
123 debug()
131 num = len(self.players) 124 num = len(self.players)
132 return num 125 return num
133 126
134 def get_player_ids(self): 127 def get_player_ids(self):
128 debug()
135 tmp = self.players 129 tmp = self.players
136 return tmp 130 return tmp
137 131
138 def check_pwd(self,pwd): 132 def check_pwd(self,pwd):
133 debug()
139 return (pwd==self.pwd) 134 return (pwd==self.pwd)
140 135
141 def check_boot_pwd(self,pwd): 136 def check_boot_pwd(self,pwd):
142 return (pwd==self.boot_pwd) 137 return (pwd==self.boot_pwd)
143 138
144 def check_version(self,ver): 139 def check_version(self,ver):
140 debug()
145 if (self.minVersion == ""): return 1 141 if (self.minVersion == ""): return 1
146 minVersion=self.minVersion.split('.') 142 minVersion=self.minVersion.split('.')
147 version=ver.split('.') 143 version=ver.split('.')
148 for i in xrange(min(len(minVersion),len(version))): 144 for i in xrange(min(len(minVersion),len(version))):
149 w=max(len(minVersion[i]),len(version[i])) 145 w=max(len(minVersion[i]),len(version[i]))
155 return 0 151 return 0
156 return 1 152 return 1
157 153
158 #depreciated - see send_group_list() 154 #depreciated - see send_group_list()
159 def toxml(self, act="new"): 155 def toxml(self, act="new"):
156 debug(self.name)
160 # Please don't add the boot_pwd to the xml, as this will give it away to players watching their console 157 # Please don't add the boot_pwd to the xml, as this will give it away to players watching their console
161 el = Element('group') 158 el = Element('group')
162 el.set('id', self.id) 159 el.set('id', self.id)
163 el.set('name', self.name) 160 el.set('name', self.name)
164 el.set('pwd', str(self.pwd!="")) 161 el.set('pwd', str(self.pwd!=""))
165 el.set('players', str(self.get_num_players())) 162 el.set('players', str(self.get_num_players()))
166 el.set('action', act) 163 el.set('action', act)
167 return tostring(el) 164 return tostring(el)
168 #xml_data = "<group id=\"" + self.id
169 #xml_data += "\" name=\"" + self.name
170 #xml_data += "\" pwd=\"" + str(self.pwd!="")
171 #xml_data += "\" players=\"" + str(self.get_num_players())
172 #xml_data += "\" action=\"" + act + "\" />"
173 #return xml_data
174
175 165
176 class client_stub(client_base): 166 class client_stub(client_base):
167 debug()
177 def __init__(self,inbox,sock,props,log): 168 def __init__(self,inbox,sock,props,log):
178 client_base.__init__(self) 169 client_base.__init__(self)
179 self.ip = props['ip'] 170 self.ip = props['ip']
180 self.role = props['role'] 171 self.role = props['role']
181 self.id = props['id'] 172 self.id = props['id']
203 diff = curtime - self.timeout_time 194 diff = curtime - self.timeout_time
204 if diff > 1800: return 1 195 if diff > 1800: return 1
205 else: return 0 196 else: return 0
206 197
207 def send(self, msg, player, group): 198 def send(self, msg, player, group):
199 debug()
208 if self.get_status() == MPLAY_CONNECTED: 200 if self.get_status() == MPLAY_CONNECTED:
209 #el = Element('msg') 201 #el = Element('msg')
210 #el.set('to', player) 202 #el.set('to', player)
211 #el.set('from', '0') 203 #el.set('from', '0')
212 #el.set('group_id', group) 204 #el.set('group_id', group)
213 #el.text(msg) 205 #el.text(msg)
214 self.outbox.put("<msg to='" + player + "' from='0' group_id='" + group + "' />" + msg) 206 self.outbox.put("<msg to='" + player + "' from='0' group_id='" + group + "' />" + msg)
215 207
216 def change_group(self,group_id,groups): 208 def change_group(self, group_id, groups):
209 debug()
217 old_group_id = str(self.group_id) 210 old_group_id = str(self.group_id)
218 groups[group_id].add_player(self.id) 211 groups[group_id].add_player(self.id)
219 groups[old_group_id].remove_player(self.id) 212 groups[old_group_id].remove_player(self.id)
220 self.group_id = group_id 213 self.group_id = group_id
221 self.outbox.put(self.toxml('group')) 214 self.outbox.put(self.toxml('group'))
222 msg = groups[group_id].game_map.get_all_xml() 215 msg = groups[group_id].game_map.get_all_xml()
223 self.send(msg,self.id,group_id) 216 self.send(msg,self.id,group_id)
224 return old_group_id 217 return old_group_id
225 218
226 def self_message(self,act): 219 def self_message(self,act):
227 self.send(act,self.id,self.group_id) 220 self.send(act, self.id, self.group_id)
228 221
229 def take_dom(self,xml_dom): 222 def take_dom(self,xml_dom):
230 self.name = xml_dom.getAttribute("name") 223 self.name = xml_dom.get("name")
231 self.text_status = xml_dom.getAttribute("status") 224 self.text_status = xml_dom.get("status")
232 225
233 """ 226 """
234 ###################################################################### 227 ######################################################################
235 ###################################################################### 228 ######################################################################
236 ## 229 ##
241 ###################################################################### 234 ######################################################################
242 ###################################################################### 235 ######################################################################
243 """ 236 """
244 237
245 class mplay_server: 238 class mplay_server:
239 debug()
246 def __init__(self, log_console=None, name=None): 240 def __init__(self, log_console=None, name=None):
241 logger._set_log_level = 16
242 logger._set_log_to_console(True)
247 self.log_to_console = 1 243 self.log_to_console = 1
248 self.log_console = log_console 244 self.log_console = log_console
249 self.alive = 1 245 self.alive = 1
250 self.players = {} 246 self.players = {}
251 self.listen_event = Event() 247 self.listen_event = Event()
276 self.allowRemoteKill = False 272 self.allowRemoteKill = False
277 self.allowRemoteAdmin = True 273 self.allowRemoteAdmin = True
278 self.sendLobbySound = False 274 self.sendLobbySound = False
279 self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used? 275 self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used?
280 276
277 @debugging
281 def initServer(self, **kwargs): 278 def initServer(self, **kwargs):
282 for atter, value in kwargs.iteritems(): setattr(self, atter, value) 279 for atter, value in kwargs.iteritems(): setattr(self, atter, value)
283 validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" ) 280 validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" )
284 validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" ) 281 validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" )
285 self.server_start_time = time.time() 282 self.server_start_time = time.time()
333 # make sure the server_ini.xml exists! 330 # make sure the server_ini.xml exists!
334 validate.config_file(self.banFile, "default_ban_list.xml" ) 331 validate.config_file(self.banFile, "default_ban_list.xml" )
335 332
336 # try to use it. 333 # try to use it.
337 try: 334 try:
338 self.banDom = minidom.parse(self.userPath + 'ban_list.xml') 335 self.banDom = parse(self.userPath + 'ban_list.xml')
339 self.banDom.normalize() 336 #self.banDom.normalize()
340 self.banDoc = self.banDom.documentElement 337 self.banDoc = self.banDom.getroot()
341 338
342 for element in self.banDom.getElementsByTagName('banned'): 339 for element in self.banDom.findall('banned'):
343 playerName = element.getAttribute( 'name' ).replace("&", "&amp;").replace("<", "&lt;").replace('"', "&quot;").replace(">", "&gt;") 340 playerName = element.get('name').replace("&", "&amp;").replace("<", "&lt;").replace('"', "&quot;").replace(">", "&gt;")
344 playerIP = element.getAttribute('ip') 341 playerIP = element.get('ip')
345 self.ban_list[playerIP] = {} 342 self.ban_list[playerIP] = {}
346 self.ban_list[playerIP]['ip'] = playerIP 343 self.ban_list[playerIP]['ip'] = playerIP
347 self.ban_list[playerIP]['name'] = playerName 344 self.ban_list[playerIP]['name'] = playerName
348 self.log_msg(str(playerName) + " " + str(playerIP) + " is banned.") 345 self.log_msg(str(playerName) + " " + str(playerIP) + " is banned.")
349 self.saveBanList() 346 self.saveBanList()
354 def saveBanList( self ): 351 def saveBanList( self ):
355 self.log_msg("Saving Ban List File...") 352 self.log_msg("Saving Ban List File...")
356 353
357 # try to use it. 354 # try to use it.
358 try: 355 try:
359 data = [] 356 etreeEl = Element('server')
360 data.append("<server>\n")
361 for ip in self.ban_list: 357 for ip in self.ban_list:
362 data.append(' <banned name="' + str(self.ban_list[ip]['name'].replace("&amp;", "&").replace("&lt;", "<").replace("&quot;", '"').replace("&gt;", ">")) + '" ip="' + str(self.ban_list[ip]['ip']) + '" />' + "\n") 358 el = Element('banned')
363 data.append("</server>") 359 el.set('name', str(self.ban_list[ip]['name'].replace("&amp;", "&").replace("&lt;", "<").replace("&quot;", '"').replace("&gt;", ">")))
360 el.set('ip', str(self.ban_list[ip]['ip']))
361 etreeEl.append(el)
364 file = open(self.userPath + self.banFile ,"w") 362 file = open(self.userPath + self.banFile ,"w")
365 file.write("".join(data)) 363 file.write(tostring(etreeEl))
366 file.close() 364 file.close()
367 except Exception, e: 365 except Exception, e:
368 self.log_msg("Exception in saveBanList() " + str(e)) 366 self.log_msg("Exception in saveBanList() " + str(e))
369 367
370 # This method reads in the server's configuration file and reconfigs the server 368 # This method reads in the server's configuration file and reconfigs the server
373 self.log_msg("Processing Server Configuration File... " + self.userPath) 371 self.log_msg("Processing Server Configuration File... " + self.userPath)
374 # make sure the server_ini.xml exists! 372 # make sure the server_ini.xml exists!
375 validate.config_file( "server_ini.xml", "default_server_ini.xml" ) 373 validate.config_file( "server_ini.xml", "default_server_ini.xml" )
376 # try to use it. 374 # try to use it.
377 try: 375 try:
378 self.configDom = minidom.parse(self.userPath + 'server_ini.xml') 376 self.configDom = parse(self.userPath + 'server_ini.xml')
379 self.configDom.normalize() 377 #self.configDom.normalize()
380 self.configDoc = self.configDom.documentElement 378 self.configDoc = self.configDom.getroot()
381
382 if hasattr(self, 'bootPassword'): self.boot_pwd = self.bootPassword 379 if hasattr(self, 'bootPassword'): self.boot_pwd = self.bootPassword
383
384 else: 380 else:
385 if self.configDoc.hasAttribute("admin"): self.boot_pwd = self.configDoc.getAttribute("admin") 381 if self.configDoc.get("admin"): self.boot_pwd = self.configDoc.get("admin")
386 elif self.configDoc.hasAttribute("boot"): self.boot_pwd = self.configDoc.getAttribute("boot") 382 elif self.configDoc.get("boot"): self.boot_pwd = self.configDoc.get("boot")
387
388 if len(self.boot_pwd) < 1: self.boot_pwd = raw_input("Enter admin password: ") 383 if len(self.boot_pwd) < 1: self.boot_pwd = raw_input("Enter admin password: ")
389 384 if not hasattr(self, 'reg') and self.configDoc.get("register"):
390 if not hasattr(self, 'reg') and self.configDoc.hasAttribute("register"): 385 self.reg = self.configDoc.get("register")
391 self.reg = self.configDoc.getAttribute("register")
392 if not len(self.reg) > 0 or self.reg[0].upper() not in ("Y", "N"): 386 if not len(self.reg) > 0 or self.reg[0].upper() not in ("Y", "N"):
393 opt = raw_input("Do you want to post your server to the OpenRPG Meta Server list? (y,n) ") 387 opt = raw_input("Do you want to post your server to the OpenRPG Meta Server list? (y,n) ")
394 if len(opt) and (opt[0].upper() == 'Y'): self.reg = 'Y' 388 if len(opt) and (opt[0].upper() == 'Y'): self.reg = 'Y'
395 else: self.reg = 'N' 389 else: self.reg = 'N'
396 LobbyName = 'Lobby' 390 LobbyName = 'Lobby'
397 391
398 if self.configDoc.hasAttribute("lobbyname"): LobbyName = self.configDoc.getAttribute("lobbyname") 392 if self.configDoc.get("lobbyname"): LobbyName = self.configDoc.get("lobbyname")
399 map_node = service_node = self.configDoc.getElementsByTagName("map")[0] 393 map_node = service_node = self.configDoc.findall("map")[0]
400 msg_node = service_node = self.configDoc.getElementsByTagName("message")[0] 394 msg_node = service_node = self.configDoc.findall("message")[0]
401 mapFile = map_node.getAttribute('file') 395 mapFile = map_node.get('file')
402 msgFile = msg_node.getAttribute('file') 396 msgFile = msg_node.get('file')
403 if mapFile == '': mapFile = 'Lobby_map.xml' 397 if mapFile == '': mapFile = 'Lobby_map.xml'
404 if msgFile == '': msgFile = 'LobbyMessage.html' 398 if msgFile == '': msgFile = 'LobbyMessage.html'
405 # Update the lobby with the passwords if they've been specified 399 # Update the lobby with the passwords if they've been specified
406 400
407 if len(self.boot_pwd): 401 if len(self.boot_pwd):
409 self.userPath + mapFile.replace("myfiles/", ""), 403 self.userPath + mapFile.replace("myfiles/", ""),
410 self.userPath + msgFile.replace("myfiles/", ""), 1 ) 404 self.userPath + msgFile.replace("myfiles/", ""), 1 )
411 } 405 }
412 406
413 # set ip or dns name to send to meta server 407 # set ip or dns name to send to meta server
414 service_node = self.configDoc.getElementsByTagName("service")[0] 408 service_node = self.configDoc.findall("service")[0]
415 address = service_node.getAttribute("address") 409 address = service_node.get("address")
416 address = address.lower() 410 address = address.lower()
417 if address == "" or address == "hostname/address" or address == "localhost": self.server_address = None 411 if address == "" or address == "hostname/address" or address == "localhost": self.server_address = None
418 else: self.server_address = address 412 else: self.server_address = address
419 self.server_port = OPENRPG_PORT 413 self.server_port = OPENRPG_PORT
420 if service_node.hasAttribute("port"): self.server_port = int(service_node.getAttribute("port")) 414 if service_node.get("port"): self.server_port = int(service_node.get("port"))
421 if self.configDoc.hasAttribute("name") and len(self.configDoc.getAttribute("name")) > 0 : 415 if self.configDoc.get("name") and len(self.configDoc.get("name")) > 0 :
422 self.name = self.configDoc.getAttribute("name") 416 self.name = self.configDoc.get("name")
423 else: 417 else:
424 if self.reg[0].upper() == "Y": 418 if self.reg[0].upper() == "Y":
425 if self.name == None: self.name = raw_input("Server Name? ") 419 if self.name == None: self.name = raw_input("Server Name? ")
426 self.register() 420 self.register()
427 """ 421 """
431 # server_ini.xml entry for version tag... 425 # server_ini.xml entry for version tag...
432 # <version min="x.x.x"> 426 # <version min="x.x.x">
433 """ 427 """
434 428
435 try: 429 try:
436 mver = self.configDoc.getElementsByTagName("version")[0] 430 mver = self.configDoc.findall("version")[0]
437 self.minClientVersion = mver.getAttribute("min") 431 self.minClientVersion = mver.get("min")
438 except: self.minClientVersion = SERVER_MIN_CLIENT_VERSION #from orpg/orpg_version.py 432 except: self.minClientVersion = SERVER_MIN_CLIENT_VERSION #from orpg/orpg_version.py
439 self.defaultMessageFile = "" 433 self.defaultMessageFile = ""
440 # This try/except bit is to allow older versions of python to continue without a list error. 434 # This try/except bit is to allow older versions of python to continue without a list error.
441 435
442 436
448 # server_ini.xml entry for autikick tag... 442 # server_ini.xml entry for autikick tag...
449 # <autokick silent=["no","yes"] delay="(# of seconds)"> 443 # <autokick silent=["no","yes"] delay="(# of seconds)">
450 """ 444 """
451 445
452 try: 446 try:
453 ak = self.configDoc.getElementsByTagName("autokick")[0] 447 ak = self.configDoc.findall("autokick")[0]
454 if ak.hasAttribute("silent"): 448 if ak.get("silent"):
455 if ((ak.getAttribute("silent")).lower() == "yes"): self.silent_auto_kick = 1 449 if ((ak.get("silent")).lower() == "yes"): self.silent_auto_kick = 1
456 else: self.silent_auto_kick = 0 450 else: self.silent_auto_kick = 0
457 if ak.hasAttribute("delay"): 451 if ak.get("delay"):
458 try: 452 try:
459 delay = int(ak.getAttribute("delay")) 453 delay = int(ak.get("delay"))
460 self.zombie_time = delay 454 self.zombie_time = delay
461 except: 455 except:
462 #delay value cannot be converted into an int use defaut 456 #delay value cannot be converted into an int use defaut
463 self.zombie_time = 480 #(default 8 mins) 457 self.zombie_time = 480 #(default 8 mins)
464 self.log_msg("**WARNING** Error with autokick delay string using default (480 sec)") 458 self.log_msg("**WARNING** Error with autokick delay string using default (480 sec)")
491 roomdefault_pass = 1 #allow passwords 485 roomdefault_pass = 1 #allow passwords
492 486
493 487
494 #pull information from config file DOM 488 #pull information from config file DOM
495 try: 489 try:
496 roomdefaults = self.configDom.getElementsByTagName("room_defaults")[0] 490 roomdefaults = self.configDom.findall("room_defaults")[0]
497 #rd.normalize() 491 #rd.normalize()
498 #roomdefaults = self.rd.documentElement 492 #roomdefaults = self.rd.documentElement
499 try: 493 try:
500 setting = roomdefaults.getElementsByTagName('passwords')[0] 494 setting = roomdefaults.findall('passwords')[0]
501 rpw = setting.getAttribute('allow') 495 rpw = setting.get('allow')
502 if rpw == "no" or rpw == "0": 496 if rpw == "no" or rpw == "0":
503 roomdefault_pass = 0 497 roomdefault_pass = 0
504 self.log_msg("Room Defaults: Disallowing Passworded Rooms") 498 self.log_msg("Room Defaults: Disallowing Passworded Rooms")
505 else: self.log_msg("Room Defaults: Allowing Passworded Rooms") 499 else: self.log_msg("Room Defaults: Allowing Passworded Rooms")
506 except: self.log_msg("Room Defaults: [Warning] Allowing Passworded Rooms") 500 except: self.log_msg("Room Defaults: [Warning] Allowing Passworded Rooms")
507 try: 501 try:
508 setting = roomdefaults.getElementsByTagName('map')[0] 502 setting = roomdefaults.findall('map')[0]
509 map = setting.getAttribute('file') 503 map = setting.get('file')
510 if map != "": 504 if map != "":
511 roomdefault_map = self.userPath + map.replace("myfiles/", "") 505 roomdefault_map = self.userPath + map.replace("myfiles/", "")
512 self.log_msg("Room Defaults: Using " + str(map) + " for room map") 506 self.log_msg("Room Defaults: Using " + str(map) + " for room map")
513 except: self.log_msg("Room Defaults: [Warning] Using Default Map") 507 except: self.log_msg("Room Defaults: [Warning] Using Default Map")
514 508
515 try: 509 try:
516 setting = roomdefaults.getElementsByTagName('message')[0] 510 setting = roomdefaults.findall('message')[0]
517 msg = setting.getAttribute('file') 511 msg = setting.get('file')
518 if msg != "": 512 if msg != "":
519 if msg[:4].lower() == 'http': roomdefault_msg = msg 513 if msg[:4].lower() == 'http': roomdefault_msg = msg
520 else: roomdefault_msg = self.userPath + msg.replace("myfiles/", "") 514 else: roomdefault_msg = self.userPath + msg.replace("myfiles/", "")
521 self.log_msg("Room Defaults: Using " + str(msg) + " for room messages") 515 self.log_msg("Room Defaults: Using " + str(msg) + " for room messages")
522 except: print ("Room Defaults: [Warning] Using Default Message") 516 except: print ("Room Defaults: [Warning] Using Default Message")
537 else: self.allow_room_passwords = 1 531 else: self.allow_room_passwords = 1
538 """-------------------------------[ END <ROOM_DEFAULT> TAG PROCESSING ]--------------------""" 532 """-------------------------------[ END <ROOM_DEFAULT> TAG PROCESSING ]--------------------"""
539 533
540 ###Server Cheat message 534 ###Server Cheat message
541 try: 535 try:
542 cheat_node = self.configDoc.getElementsByTagName("cheat")[0] 536 cheat_node = self.configDoc.findall("cheat")[0]
543 self.cheat_msg = cheat_node.getAttribute("text") 537 self.cheat_msg = cheat_node.get("text")
544 except: 538 except:
545 self.cheat_msg = "**FAKE ROLL**" 539 self.cheat_msg = "**FAKE ROLL**"
546 self.log_msg("**WARNING** <cheat txt=\"\"> tag missing from server configuration file. Using empty string.") 540 self.log_msg("**WARNING** <cheat txt=\"\"> tag missing from server configuration file. Using empty string.")
547 541
548 # should validate protocal 542 # should validate protocal
549 validate_protocol_node = self.configDom.getElementsByTagName("validate_protocol ") 543 validate_protocol_node = self.configDom.findall("validate_protocol")
550 self.validate_protocol = 1 544 self.validate_protocol = 1
551 if(validate_protocol_node): self.validate_protocol = (validate_protocol_node[0].getAttribute("value") == "True") 545 if(validate_protocol_node): self.validate_protocol = (validate_protocol_node[0].get("value") == "True")
552 if(self.validate_protocol != 1): self.log_msg("Protocol Validation: OFF") 546 if(self.validate_protocol != 1): self.log_msg("Protocol Validation: OFF")
553 self.makePersistentRooms() 547 self.makePersistentRooms()
554 self.log_msg("Server Configuration File: Processing Completed.") 548 self.log_msg("Server Configuration File: Processing Completed.")
555 except Exception, e: 549 except Exception, e:
556 traceback.print_exc() 550 traceback.print_exc()
557 self.log_msg("Exception in initServerConfig() " + str(e)) 551 self.log_msg("Exception in initServerConfig() " + str(e))
558 552
559 def makePersistentRooms(self): 553 def makePersistentRooms(self):
560 'Creates rooms on the server as defined in the server config file.' 554 'Creates rooms on the server as defined in the server config file.'
561 for element in self.configDom.getElementsByTagName('room'): 555 for element in self.configDom.findall('room'):
562 roomName = element.getAttribute('name') 556 roomName = element.get('name')
563 roomPassword = element.getAttribute('password') 557 roomPassword = element.get('password')
564 bootPassword = element.getAttribute('boot') 558 bootPassword = element.get('boot')
565 559
566 # Conditionally check for minVersion attribute 560 # Conditionally check for minVersion attribute
567 if element.hasAttribute('minVersion'): minVersion = element.getAttribute('minVersion') 561 if element.get('minVersion'): minVersion = element.get('minVersion')
568 else: minVersion = "" 562 else: minVersion = ""
569 563
570 # Extract the map filename attribute from the map node 564 # Extract the map filename attribute from the map node
571 # we only care about the first map element found -- others are ignored 565 # we only care about the first map element found -- others are ignored
572 mapElement = element.getElementsByTagName('map')[0] 566 mapElement = element.findall('map')[0]
573 mapFile = self.userPath + mapElement.getAttribute('file').replace("myfiles/", "") 567 mapFile = self.userPath + mapElement.get('file').replace("myfiles/", "")
574 messageElement = element.getElementsByTagName('message')[0] 568 messageElement = element.findall('message')[0]
575 messageFile = messageElement.getAttribute('file') 569 messageFile = messageElement.get('file')
576 if messageFile[:4] != 'http': messageFile = self.userPath + messageFile.replace("myfiles/", "") 570 if messageFile[:4] != 'http': messageFile = self.userPath + messageFile.replace("myfiles/", "")
577 571
578 # Make sure we have a message to even mess with 572 # Make sure we have a message to even mess with
579 if(len(messageFile) == 0): messageFile = self.defaultMessageFile 573 if(len(messageFile) == 0): messageFile = self.defaultMessageFile
580 if(len(mapFile) == 0): mapFile = self.defaultMapFile 574 if(len(mapFile) == 0): mapFile = self.defaultMapFile
581 moderated = 0 575 moderated = 0
582 if element.hasAttribute('moderated') and element.getAttribute('moderated').lower() == "true": moderated = 1 576 if element.get('moderated') and element.get('moderated').lower() == "true": moderated = 1
583 577
584 #create the new persistant group 578 #create the new persistant group
585 self.new_group(roomName, roomPassword, 579 self.new_group(roomName, roomPassword,
586 bootPassword, minVersion, mapFile, 580 bootPassword, minVersion, mapFile,
587 messageFile, persist = 1, moderated=moderated) 581 messageFile, persist = 1, moderated=moderated)
637 if self.log_network_messages == 0: return "Network Traffic Log: Off" 631 if self.log_network_messages == 0: return "Network Traffic Log: Off"
638 elif self.log_network_messages == 1: return "Network Traffic Log: Logging (composite file)" 632 elif self.log_network_messages == 1: return "Network Traffic Log: Logging (composite file)"
639 elif self.log_network_messages == 2: return "Network Traffic Log: Logging (inbound/outbound files)" 633 elif self.log_network_messages == 2: return "Network Traffic Log: Logging (inbound/outbound files)"
640 else: self.log_msg("Network Traffic Log: [Unknown]") 634 else: self.log_msg("Network Traffic Log: [Unknown]")
641 635
642 def register_callback(instance, xml_dom = None,source=None): 636 def register_callback(instance, xml_dom = None, source=None):
643 if xml_dom: # if we get something 637 if xml_dom: # if we get something
644 if source == getMetaServerBaseURL(): # if the source of this DOM is the authoritative meta 638 if source == getMetaServerBaseURL(): # if the source of this DOM is the authoritative meta
645 try: 639 try:
646 metacache_lock.acquire() 640 metacache_lock.acquire()
647 curlist = getRawMetaList() # read the raw meta cache lines into a list 641 curlist = getRawMetaList() # read the raw meta cache lines into a list
774 for player in players: 768 for player in players:
775 if player is not None: pass #Do something here so they can show up in the chat room for non web users' 769 if player is not None: pass #Do something here so they can show up in the chat room for non web users'
776 data = ServerPlugins.preParseOutgoing() 770 data = ServerPlugins.preParseOutgoing()
777 for msg in data: 771 for msg in data:
778 try: 772 try:
779 xml_dom = parseXml(msg) 773 #xml_dom = parseXml(msg)
780 xml_dom = xml_dom._get_documentElement() 774 xml_dom = fromstring(msg).getroot()
781 if xml_dom.hasAttribute('from') and int(xml_dom.getAttribute('from')) > -1: 775 if xml_dom.get('from') and int(xml_dom.get('from')) > -1:
782 xml_dom.setAttribute('from', '-1') 776 xml_dom.set('from', '-1')
783 xml_dom.setAttribute('to', 'all') 777 xml_dom.set('to', 'all')
784 self.incoming_msg_handler(xml_dom, msg) 778 self.incoming_msg_handler(xml_dom, msg)
785 xml_dom.unlink() 779 #xml_dom.unlink()
786 except: pass 780 except: pass
787 self.p_lock.release() 781 self.p_lock.release()
788 time.sleep(0.250) 782 time.sleep(0.250)
789 783
790 def sendMsg( self, sock, msg, useCompression=False, cmpType=None): 784 def sendMsg( self, sock, msg, useCompression=False, cmpType=None):
791 """Very simple function that will properly encode and send a message to te 785 """Very simple function that will properly encode and send a message to the
792 remote on the specified socket.""" 786 remote on the specified socket."""
793 if useCompression and cmpType != None: 787 if not useCompression and cmpType != None:
794 mpacket = cmpType.compress(msg) 788 mpacket = cmpType.compress(msg)
795 lpacket = pack('!i', len(mpacket)) 789 lpacket = pack('!i', len(mpacket))
796 sock.send(lpacket) 790 sock.send(lpacket)
797 offset = 0 791 offset = 0
798 while offset < len(mpacket): 792 while offset < len(mpacket):
1072 print "Bad Player Ref (#" + id + ") in group" 1066 print "Bad Player Ref (#" + id + ") in group"
1073 except Exception, e: 1067 except Exception, e:
1074 self.log_msg(str(e)) 1068 self.log_msg(str(e))
1075 self.p_lock.release() 1069 self.p_lock.release()
1076 1070
1077 def update_request(self,newsock,xml_dom): 1071 def update_request(self,newsock, xml_dom):
1078 # handle reconnects 1072 # handle reconnects
1079 self.log_msg( "update_request() has been called." ) 1073 self.log_msg( "update_request() has been called." )
1080 1074
1081 # get player id 1075 # get player id
1082 id = xml_dom.getAttribute("id") 1076 id = xml_dom.get("id")
1083 group_id = xml_dom.getAttribute("group_id") 1077 group_id = xml_dom.get("group_id")
1084 self.p_lock.acquire() 1078 self.p_lock.acquire()
1085 if self.players.has_key(id): 1079 if self.players.has_key(id):
1086 self.sendMsg(newsock, self.players[id].toxml("update"), 1080 self.sendMsg(newsock, self.players[id].toxml("update"),
1087 self.players[id].useCompression, 1081 self.players[id].useCompression,
1088 self.players[id].compressionType ) 1082 self.players[id].compressionType )
1089 self.players[id].reset(newsock) 1083 self.players[id].reset(newsock)
1090 self.players[id].clear_timeout() 1084 self.players[id].clear_timeout()
1091 need_new = 0 1085 need_new = 0
1092 else: need_new = 1 1086 else: need_new = 1
1093 self.p_lock.release() 1087 self.p_lock.release()
1094 if need_new: self.new_request(newsock,xml_dom) 1088 if need_new: self.new_request(newsock, xml_dom)
1095 else: 1089 else:
1096 msg = self.groups[group_id].game_map.get_all_xml() 1090 msg = self.groups[group_id].game_map.get_all_xml()
1097 self.send(msg,id,group_id) 1091 self.send(msg,id,group_id)
1098 1092
1099 def new_request(self,newsock,xml_dom,LOBBY_ID='0'): 1093 def new_request(self,newsock, xml_dom, LOBBY_ID='0'):
1100 #build client stub 1094 #build client stub
1101 props = {} 1095 props = {}
1102 # Don't trust what the client tells us...trust what they connected as! 1096 # Don't trust what the client tells us...trust what they connected as!
1103 props['ip'] = socket.gethostbyname( newsock.getpeername()[0] ) 1097 props['ip'] = socket.gethostbyname( newsock.getpeername()[0] )
1104 1098
1105 try: props['role'] = xml_dom.getAttribute("role") 1099 props['role'] = xml_dom.get("role") or 'GM'
1106 except: props['role'] = "GM" 1100 props['name'] = xml_dom.get("name")
1107
1108 props['name'] = xml_dom.getAttribute("name")
1109 props['group_id'] = LOBBY_ID 1101 props['group_id'] = LOBBY_ID
1110 props['id'] = str(self.next_player_id) 1102 props['id'] = str(self.next_player_id)
1111 props['version'] = xml_dom.getAttribute("version") 1103 props['version'] = xml_dom.get("version")
1112 props['protocol_version'] = xml_dom.getAttribute("protocol_version") 1104 props['protocol_version'] = xml_dom.get("protocol_version")
1113 props['client_string'] = xml_dom.getAttribute("client_string") 1105 props['client_string'] = xml_dom.get("client_string")
1114 1106
1115 self.next_player_id += 1 1107 self.next_player_id += 1
1116 new_stub = client_stub(self.incoming,newsock,props,self.log_console) 1108 new_stub = client_stub(self.incoming, newsock, props, self.log_console)
1117 if xml_dom.hasAttribute('useCompression'): 1109 if xml_dom.get('useCompression'):
1118 new_stub.useCompression = True 1110 new_stub.useCompression = True
1119 if xml_dom.hasAttribute('cmpType'): 1111 if xml_dom.get('cmpType'):
1120 cmpType = xml_dom.getAttribute('cmpType') 1112 cmpType = xml_dom.get('cmpType')
1121 if cmpBZ2 and cmpType == 'bz2': new_stub.compressionType = bz2 1113 if cmpBZ2 and cmpType == 'bz2': new_stub.compressionType = bz2
1122 elif cmpZLIB and cmpType == 'zlib': new_stub.compressionType = zlib 1114 elif cmpZLIB and cmpType == 'zlib': new_stub.compressionType = zlib
1123 else: new_stub.compressionType = None 1115 else: new_stub.compressionType = None
1124 else: new_stub.compressionType = bz2 1116 else: new_stub.compressionType = bz2
1125 else: new_stub.useCompression = False 1117 else: new_stub.useCompression = False
1127 #update newly create client stub with network logging state 1119 #update newly create client stub with network logging state
1128 new_stub.EnableMessageLogging = self.log_network_messages 1120 new_stub.EnableMessageLogging = self.log_network_messages
1129 self.sendMsg(newsock, new_stub.toxml("new"), False, None) 1121 self.sendMsg(newsock, new_stub.toxml("new"), False, None)
1130 1122
1131 # try to remove circular refs 1123 # try to remove circular refs
1132 if xml_dom: 1124 #if xml_dom:
1133 xml_dom.unlink() 1125 # xml_dom.unlink()
1134 1126
1135 # send confirmation 1127 # send confirmation
1136 data = self.recvMsg(newsock, new_stub.useCompression, new_stub.compressionType) 1128 data = self.recvMsg(newsock, new_stub.useCompression, new_stub.compressionType)
1137 try: 1129 try:
1138 xml_dom = parseXml(data) 1130 xml_dom = XML(data)
1139 xml_dom = xml_dom._get_documentElement() 1131 #xml_dom = xml_dom._get_documentElement()
1140 except Exception, e: 1132 except Exception, e:
1141 print e 1133 print e
1142 (remote_host,remote_port) = newsock.getpeername() 1134 (remote_host,remote_port) = newsock.getpeername()
1143 bad_xml_string = "Your client sent an illegal message to the server and will be disconnected. " 1135 bad_xml_string = "Your client sent an illegal message to the server and will be disconnected. "
1144 bad_xml_string += "Please report this bug to the development team at:<br /> " 1136 bad_xml_string += "Please report this bug to the development team at:<br /> "
1149 time.sleep(2) 1141 time.sleep(2)
1150 newsock.close() 1142 newsock.close()
1151 print "Error in parse found from " + str(remote_host) + ". Disconnected." 1143 print "Error in parse found from " + str(remote_host) + ". Disconnected."
1152 print " Offending data(" + str(len(data)) + "bytes)=" + data 1144 print " Offending data(" + str(len(data)) + "bytes)=" + data
1153 print "Exception=" + str(e) 1145 print "Exception=" + str(e)
1154 if xml_dom: xml_dom.unlink() 1146 #if xml_dom: xml_dom.unlink()
1155 return 1147 return
1156 1148
1157 #start threads and store player 1149 #start threads and store player
1158 allowed = 1 1150 allowed = 1
1159 version_string = "" 1151 version_string = ""
1178 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + version_string, new_stub.useCompression, new_stub.compressionType) 1170 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + version_string, new_stub.useCompression, new_stub.compressionType)
1179 # Give messages time to flow 1171 # Give messages time to flow
1180 time.sleep(1) 1172 time.sleep(1)
1181 self.log_msg("Connection terminating due to version incompatibility with client (ver: " + props['version'] + " protocol: " + props['protocol_version'] + ")" ) 1173 self.log_msg("Connection terminating due to version incompatibility with client (ver: " + props['version'] + " protocol: " + props['protocol_version'] + ")" )
1182 newsock.close() 1174 newsock.close()
1183 if xml_dom: 1175 #if xml_dom: xml_dom.unlink()
1184 xml_dom.unlink()
1185 return None 1176 return None
1186 1177
1187 ip = props['ip'] 1178 ip = props['ip']
1188 if self.ban_list.has_key(ip): 1179 if self.ban_list.has_key(ip):
1189 banmsg = "You have been banned from this server.<br />" 1180 banmsg = "You have been banned from this server.<br />"
1192 allowed = 0 1183 allowed = 0
1193 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + banmsg, new_stub.useCompression, new_stub.compressionType) 1184 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + banmsg, new_stub.useCompression, new_stub.compressionType)
1194 # Give messages time to flow 1185 # Give messages time to flow
1195 time.sleep(1) 1186 time.sleep(1)
1196 newsock.close() 1187 newsock.close()
1197 if xml_dom: 1188 #if xml_dom: xml_dom.unlink()
1198 xml_dom.unlink()
1199 return None 1189 return None
1200 1190
1201 """ 1191 """
1202 #---- Connection order changed by Snowdog 1/05 1192 #---- Connection order changed by Snowdog 1/05
1203 #---- Attempt to register player and send group data 1193 #---- Attempt to register player and send group data
1211 #---- incomming message queue, when they should be sent directly to user 1201 #---- incomming message queue, when they should be sent directly to user
1212 #---- Does not solve the black hole bug totally -SD 1202 #---- Does not solve the black hole bug totally -SD
1213 """ 1203 """
1214 1204
1215 try: 1205 try:
1216 if xml_dom.getAttribute("id") == props['id']: 1206 if xml_dom.get("id") == props['id']:
1217 new_stub.initialize_threads() 1207 new_stub.initialize_threads()
1218 self.p_lock.acquire() 1208 self.p_lock.acquire()
1219 self.players[props['id']] = new_stub 1209 self.players[props['id']] = new_stub
1220 self.groups[LOBBY_ID].add_player(props['id']) #always add to lobby on connection. 1210 self.groups[LOBBY_ID].add_player(props['id']) #always add to lobby on connection.
1221 self.send_group_list(props['id']) 1211 self.send_group_list(props['id'])
1222 self.send_player_list(props['id'],LOBBY_ID) 1212 self.send_player_list(props['id'],LOBBY_ID)
1223 self.p_lock.release() 1213 self.p_lock.release()
1224 msg = self.groups[LOBBY_ID].game_map.get_all_xml() 1214 msg = self.groups[LOBBY_ID].game_map.get_all_xml()
1225 self.send(msg,props['id'],LOBBY_ID) 1215 self.send(msg, props['id'], LOBBY_ID)
1226 self.send_to_group(props['id'],LOBBY_ID,self.players[props['id']].toxml('new')) 1216 self.send_to_group(props['id'], LOBBY_ID, self.players[props['id']].toxml('new'))
1227 self.return_room_roles(props['id'],LOBBY_ID) 1217 self.return_room_roles(props['id'], LOBBY_ID)
1228 1218
1229 # Re-initialize the role for this player incase they came from a different server 1219 # Re-initialize the role for this player incase they came from a different server
1230 self.handle_role("set",props['id'], "GM",self.groups[LOBBY_ID].boot_pwd, LOBBY_ID) 1220 self.handle_role("set", props['id'], "GM", self.groups[LOBBY_ID].boot_pwd, LOBBY_ID)
1231 cmsg = "Client Connect: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" 1221 cmsg = "Client Connect: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]"
1232 self.log_msg(cmsg) 1222 self.log_msg(cmsg)
1233 cmsg = ("connect", props) ################################################# 1223 cmsg = ("connect", props) #################################################
1234 self.log_msg(cmsg) 1224 self.log_msg(cmsg)
1235 1225
1240 except: 1230 except:
1241 traceback.print_exc() 1231 traceback.print_exc()
1242 1232
1243 #something didn't go right. Notify client and drop the connection 1233 #something didn't go right. Notify client and drop the connection
1244 err_string = "<center>" 1234 err_string = "<center>"
1245 err_string += "<hr><b>The server has encountered an error while processing your connection request.</b><hr>" 1235 err_string += "<hr><b>The server has encountered an error while processing your connection request.</b><hr>"
1246 err_string += "<br /><i>You are being disconnected from the server.</i><br />" 1236 err_string += "<br /><i>You are being disconnected from the server.</i><br />"
1247 err_string += "This error may represent a problem with the server. If you continue to get this message " 1237 err_string += "This error may represent a problem with the server. If you continue to get this message "
1248 err_string += "please contact the servers administrator to correct the issue.</center> " 1238 err_string += "please contact the servers administrator to correct the issue.</center> "
1249 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='" + props['id'] + "' group_id='0' />" + err_string, new_stub.useCompression, new_stub.compressionType ) 1239 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='" + props['id'] + "' group_id='0' />" + err_string, new_stub.useCompression, new_stub.compressionType )
1250 time.sleep(2) 1240 time.sleep(2)
1251 newsock.close() 1241 newsock.close()
1252 1242
1253 # Display the lobby message 1243 # Display the lobby message
1254 self.SendLobbyMessage(newsock,props['id']) 1244 self.SendLobbyMessage(newsock,props['id'])
1255 if xml_dom: 1245 #if xml_dom: xml_dom.unlink()
1256 xml_dom.unlink()
1257 1246
1258 def checkClientVersion(self, clientversion): 1247 def checkClientVersion(self, clientversion):
1259 minv = self.minClientVersion.split('.') 1248 minv = self.minClientVersion.split('.')
1260 cver = clientversion.split('.') 1249 cver = clientversion.split('.')
1261 for i in xrange(min(len(minv),len(cver))): 1250 for i in xrange(min(len(minv),len(cver))):
1266 if v1>v2: return 0 1255 if v1>v2: return 0
1267 if len(minv)>len(cver): return 0 1256 if len(minv)>len(cver): return 0
1268 return 1 1257 return 1
1269 1258
1270 def SendLobbyMessage(self, socket, player_id): 1259 def SendLobbyMessage(self, socket, player_id):
1260 debug()
1271 """ 1261 """
1272 # Display the lobby message 1262 # Display the lobby message
1273 # prepend this server's version string to the the lobby message 1263 # prepend this server's version string to the the lobby message
1274 """ 1264 """
1275 try: 1265 try:
1276 lobbyMsg = "You have connected to an <a href=\"http://www.openrpg.com\">OpenRPG</a> " 1266 lobbyMsg = "You have connected to an <a href=\"http://www.openrpg.com\">OpenRPG</a> "
1277 lobbyMsg += "server, version '" + VERSION + "'" 1267 lobbyMsg += "server, version '" + VERSION + "'"
1278 1268
1279 # See if we have a server name to report! 1269 # See if we have a server name to report!
1280 if len(self.serverName): 1270 if len(self.serverName): lobbyMsg += ", named '" + self.serverName + "'."
1281 lobbyMsg += ", named '" + self.serverName + "'." 1271 else: lobbyMsg += "."
1282 else:
1283 lobbyMsg += "."
1284 1272
1285 # Add extra line spacing 1273 # Add extra line spacing
1286 lobbyMsg += "\n\n" 1274 lobbyMsg += "\n\n"
1287 1275
1288 try: validate.config_file("LobbyMessage.html","default_LobbyMessage.html") 1276 try: validate.config_file("LobbyMessage.html","default_LobbyMessage.html")
1339 # At this point, we're done and cleaning up. 1327 # At this point, we're done and cleaning up.
1340 self.log_msg("server socket listening thread exiting...") 1328 self.log_msg("server socket listening thread exiting...")
1341 self.listen_event.set() 1329 self.listen_event.set()
1342 1330
1343 def acceptedNewConnectionThread( self, newsock, addr ): 1331 def acceptedNewConnectionThread( self, newsock, addr ):
1332 debug()
1344 """Once a new connection comes in and is accepted, this thread starts up to handle it.""" 1333 """Once a new connection comes in and is accepted, this thread starts up to handle it."""
1345 # Initialize xml_dom 1334 # Initialize xml_dom
1346 xml_dom = None 1335 xml_dom = None
1347 data = None 1336 data = None
1348 1337
1360 if data == "<system/>": 1349 if data == "<system/>":
1361 try: newsock.close() 1350 try: newsock.close()
1362 except: pass 1351 except: pass
1363 return #returning causes connection thread instance to terminate 1352 return #returning causes connection thread instance to terminate
1364 # Clear out the xml_dom in preparation for new stuff, if necessary 1353 # Clear out the xml_dom in preparation for new stuff, if necessary
1365 try: 1354 """try: if xml_dom: xml_dom.unlink()
1366 if xml_dom: xml_dom.unlink()
1367 1355
1368 except: 1356 except:
1369 self.log_msg( "The following exception caught unlinking xml_dom:") 1357 self.log_msg( "The following exception caught unlinking xml_dom:")
1370 self.log_msg("Continuing") 1358 self.log_msg("Continuing")
1371 try: newsock.close() 1359 try: newsock.close()
1372 except: pass 1360 except: pass
1373 return #returning causes connection thread instance to terminate 1361 return #returning causes connection thread instance to terminate
1374 # Parse the XML received from the connecting client 1362 # Parse the XML received from the connecting client"""
1375 try: 1363 try:
1376 xml_dom = parseXml(data) 1364 xml_dom = XML(data)
1377 xml_dom = xml_dom._get_documentElement() 1365 #xml_dom = xml_dom._get_documentElement()
1378 1366
1379 except: 1367 except:
1380 try: newsock.close() 1368 try: newsock.close()
1381 except: pass 1369 except: pass
1382 self.log_msg( "Error in parse found from " + str(addr) + ". Disconnected.") 1370 self.log_msg( "Error in parse found from " + str(addr) + ". Disconnected.")
1386 return #returning causes connection thread instance to terminate 1374 return #returning causes connection thread instance to terminate
1387 1375
1388 # Determine the correct action and execute it 1376 # Determine the correct action and execute it
1389 try: 1377 try:
1390 # get action 1378 # get action
1391 action = xml_dom.getAttribute("action") 1379 action = xml_dom.get("action")
1392 1380
1393 # Figure out what type of connection we have going on now 1381 # Figure out what type of connection we have going on now
1394 if action == "new": self.new_request(newsock,xml_dom) 1382 if action == "new": self.new_request(newsock, xml_dom)
1395 elif action == "update": self.update_request(newsock,xml_dom) 1383 elif action == "update": self.update_request(newsock, xml_dom)
1396 else: self.log_msg("Unknown Join Request!") 1384 else: self.log_msg("Unknown Join Request!")
1397 1385
1398 except Exception, e: 1386 except Exception, e:
1399 print "The following message: " + str(data) 1387 print "The following message: " + str(data)
1400 print "from " + str(addr) + " created the following exception: " 1388 print "from " + str(addr) + " created the following exception: "
1419 # Changed thread organization from one continuous parsing/handling thread 1407 # Changed thread organization from one continuous parsing/handling thread
1420 # to multiple expiring parsing/handling threads to improve server performance 1408 # to multiple expiring parsing/handling threads to improve server performance
1421 # and player load capacity -- Snowdog 3/04 1409 # and player load capacity -- Snowdog 3/04
1422 """ 1410 """
1423 1411
1424 def message_handler(self,arg): 1412 def message_handler(self, arg):
1413 debug()
1425 xml_dom = None 1414 xml_dom = None
1426 self.log_msg( "message handler thread running..." ) 1415 self.log_msg( "message handler thread running..." )
1427 while self.alive: 1416 while self.alive:
1428 data = None 1417 data = None
1429 try: data=self.incoming.get(0) 1418 try: data=self.incoming.get(0)
1439 #so data in passed objects doesn't change (python passes by reference) 1428 #so data in passed objects doesn't change (python passes by reference)
1440 del data 1429 del data
1441 data = None 1430 data = None
1442 except Exception, e: 1431 except Exception, e:
1443 self.log_msg(str(e)) 1432 self.log_msg(str(e))
1444 if xml_dom: xml_dom.unlink() 1433 #if xml_dom: xml_dom.unlink()
1445 if xml_dom: xml_dom.unlink() 1434 #if xml_dom: xml_dom.unlink()
1446 self.log_msg("message handler thread exiting...") 1435 self.log_msg("message handler thread exiting...")
1447 self.incoming_event.set() 1436 self.incoming_event.set()
1448 1437
1449 def parse_incoming_dom(self,data): 1438 def parse_incoming_dom(self,data):
1439 debug(data)
1450 end = data.find(">") #locate end of first element of message 1440 end = data.find(">") #locate end of first element of message
1451 head = data[:end+1] 1441 head = data[:end+1]
1452 #self.log_msg(head) 1442 #self.log_msg(head)
1453 xml_dom = None 1443 xml_dom = None
1454 try: 1444 try:
1455 xml_dom = parseXml(head) 1445 xml_dom = XML(head)
1456 xml_dom = xml_dom._get_documentElement() 1446 #xml_dom = xml_dom._get_documentElement()
1457 self.message_action(xml_dom,data) 1447 self.message_action(xml_dom, data)
1458 1448
1459 except Exception, e: 1449 except Exception, e:
1460 print "Error in parse of inbound message. Ignoring message." 1450 print "Error in parse of inbound message. Ignoring message."
1461 print " Offending data(" + str(len(data)) + "bytes)=" + data 1451 print " Offending data(" + str(len(data)) + "bytes)=" + data
1462 print "Exception=" + str(e) 1452 print "Exception=" + str(e)
1463 if xml_dom: xml_dom.unlink() 1453
1464
1465 def message_action(self, xml_dom, data): 1454 def message_action(self, xml_dom, data):
1466 tag_name = xml_dom._get_tagName() 1455 debug()
1467 if self.svrcmds.has_key(tag_name): self.svrcmds[tag_name]['function'](xml_dom,data) 1456 tag_name = xml_dom.tag; print 'message_action tag_name', tag_name
1457 if self.svrcmds.has_key(tag_name): self.svrcmds[tag_name]['function'](xml_dom, data)
1468 else: raise Exception, "Not a valid header!" 1458 else: raise Exception, "Not a valid header!"
1469 #Message Action thread expires and closes here. 1459 #Message Action thread expires and closes here.
1470 return 1460 return
1471 1461
1472 def do_alter(self, xml_dom, data): 1462 def do_alter(self, xml_dom, data):
1473 target = xml_dom.getAttribute("key") 1463 debug()
1474 value = xml_dom.getAttribute("val") 1464 target = xml_dom.get("key")
1475 player = xml_dom.getAttribute("plr") 1465 value = xml_dom.get("val")
1476 group_id = xml_dom.getAttribute("gid") 1466 player = xml_dom.get("plr")
1477 boot_pwd = xml_dom.getAttribute("bpw") 1467 group_id = xml_dom.get("gid")
1468 boot_pwd = xml_dom.get("bpw")
1478 actual_boot_pwd = self.groups[group_id].boot_pwd 1469 actual_boot_pwd = self.groups[group_id].boot_pwd
1479 1470
1480 if self.allow_room_passwords == 0: 1471 if self.allow_room_passwords == 0:
1481 msg ="<msg to='" + player + "' from='0' group_id='0' /> " 1472 msg ="<msg to='" + player + "' from='0' group_id='0' /> "
1482 msg += "Room passwords have been disabled by the server administrator." 1473 msg += "Room passwords have been disabled by the server administrator."
1499 else: 1490 else:
1500 msg ="<msg to='" + player + "' from='0' group_id='0'>Invalid Administrator Password." 1491 msg ="<msg to='" + player + "' from='0' group_id='0'>Invalid Administrator Password."
1501 self.players[player].outbox.put(msg) 1492 self.players[player].outbox.put(msg)
1502 1493
1503 def do_role(self, xml_dom, data): 1494 def do_role(self, xml_dom, data):
1495 debug()
1504 role = "" 1496 role = ""
1505 boot_pwd = "" 1497 boot_pwd = ""
1506 act = xml_dom.getAttribute("action") 1498 act = xml_dom.get("action")
1507 player = xml_dom.getAttribute("player") 1499 player = xml_dom.get("player")
1508 group_id = xml_dom.getAttribute("group_id") 1500 group_id = xml_dom.get("group_id")
1509 if act == "set": 1501 if act == "set":
1510 role = xml_dom.getAttribute("role") 1502 role = xml_dom.get("role")
1511 boot_pwd = xml_dom.getAttribute("boot_pwd") 1503 boot_pwd = xml_dom.get("boot_pwd")
1512 xml_dom.unlink() 1504 #xml_dom.unlink()
1513 if group_id != "0": 1505 if group_id != "0":
1514 self.handle_role(act, player, role, boot_pwd, group_id) 1506 self.handle_role(act, player, role, boot_pwd, group_id)
1515 self.log_msg(("role", (player, role))) 1507 self.log_msg(("role", (player, role)))
1516 1508
1517 def do_ping(self, xml_dom, data): 1509 def do_ping(self, xml_dom, data):
1518 player = xml_dom.getAttribute("player") 1510 debug()
1519 group_id = xml_dom.getAttribute("group_id") 1511 player = xml_dom.get("player")
1512 group_id = xml_dom.get("group_id")
1520 sent_time = "" 1513 sent_time = ""
1521 msg = "" 1514 msg = ""
1522 try: sent_time = xml_dom.getAttribute("time") 1515 try: sent_time = xml_dom.get("time")
1523 except: pass 1516 except: pass
1524 if sent_time != "": msg ="<ping time='" + str(sent_time) + "' />" #because a time was sent return a ping response 1517 if sent_time != "": msg ="<ping time='" + str(sent_time) + "' />" #because a time was sent return a ping response
1525 else: 1518 else:
1526 msg ="<msg to='" + player + "' from='" + player + "' group_id='" + group_id + "'>" 1519 msg ="<msg to='" + player + "' from='" + player + "' group_id='" + group_id + "'>"
1527 msg += "<font color='#FF0000'>PONG!?!</font>" 1520 msg += "<font color='#FF0000'>PONG!?!</font>"
1528 self.players[player].outbox.put(msg) 1521 self.players[player].outbox.put(msg)
1529 xml_dom.unlink() 1522 #xml_dom.unlink()
1530 1523
1531 def do_system(self, xml_dom, data): 1524 def do_system(self, xml_dom, data):
1525 debug()
1532 pass 1526 pass
1533 1527
1534 def moderate_group(self,xml_dom,data): 1528 def moderate_group(self,xml_dom,data):
1535 try: 1529 try:
1536 action = xml_dom.getAttribute("action") 1530 action = xml_dom.get("action")
1537 from_id = xml_dom.getAttribute("from") 1531 from_id = xml_dom.get("from")
1538 if xml_dom.hasAttribute("pwd"): pwd=xml_dom.getAttribute("pwd") 1532 if xml_dom.get("pwd"): pwd=xml_dom.get("pwd")
1539 else: pwd="" 1533 else: pwd=""
1540 group_id=self.players[from_id].group_id 1534 group_id=self.players[from_id].group_id
1541 if action == "list": 1535 if action == "list":
1542 if (self.groups[group_id].moderated): 1536 if (self.groups[group_id].moderated):
1543 msg = "" 1537 msg = ""
1559 self.players[from_id].self_message("This channel is now moderated") 1553 self.players[from_id].self_message("This channel is now moderated")
1560 if action == 'disable': 1554 if action == 'disable':
1561 self.groups[group_id].moderated = 0 1555 self.groups[group_id].moderated = 0
1562 self.players[from_id].self_message("This channel is now unmoderated") 1556 self.players[from_id].self_message("This channel is now unmoderated")
1563 if action == 'addvoice': 1557 if action == 'addvoice':
1564 users = xml_dom.getAttribute("users").split(',') 1558 users = xml_dom.get("users").split(',')
1565 for i in users: self.groups[group_id].voice[i.strip()]=1 1559 for i in users: self.groups[group_id].voice[i.strip()]=1
1566 if action == 'delvoice': 1560 if action == 'delvoice':
1567 users = xml_dom.getAttribute("users").split(',') 1561 users = xml_dom.get("users").split(',')
1568 for i in users: 1562 for i in users:
1569 if self.groups[group_id].voice.has_key(i.strip()): del self.groups[group_id].voice[i.strip()] 1563 if self.groups[group_id].voice.has_key(i.strip()): del self.groups[group_id].voice[i.strip()]
1570 else: 1564 else:
1571 print "Bad input: " + data 1565 print "Bad input: " + data
1572 except Exception,e: 1566 except Exception,e:
1573 self.log_msg(str(e)) 1567 self.log_msg(str(e))
1574 1568
1575 def join_group(self,xml_dom,data): 1569 def join_group(self, xml_dom, data):
1576 try: 1570 try:
1577 from_id = xml_dom.getAttribute("from") 1571 from_id = xml_dom.get("from")
1578 pwd = xml_dom.getAttribute("pwd") 1572 pwd = xml_dom.get("pwd")
1579 group_id = xml_dom.getAttribute("group_id") 1573 group_id = xml_dom.get("group_id")
1580 ver = self.players[from_id].version 1574 ver = self.players[from_id].version
1581 allowed = 1 1575 allowed = 1
1582 1576
1583 if not self.groups[group_id].check_version(ver): 1577 if not self.groups[group_id].check_version(ver):
1584 allowed = 0 1578 allowed = 0
1586 1580
1587 if not self.groups[group_id].check_pwd(pwd): 1581 if not self.groups[group_id].check_pwd(pwd):
1588 allowed = 0 1582 allowed = 0
1589 1583
1590 #tell the clients password manager the password failed -- SD 8/03 1584 #tell the clients password manager the password failed -- SD 8/03
1591 pm = "<password signal=\"fail\" type=\"room\" id=\"" + group_id + "\" data=\"\"/>" 1585 pm = "<password signal='fail' type='room' id='" + group_id + "' data=''/>"
1592 self.players[from_id].outbox.put(pm) 1586 self.players[from_id].outbox.put(pm)
1593 msg = 'failed - incorrect room password' 1587 msg = 'failed - incorrect room password'
1594 1588
1595 if not allowed: 1589 if not allowed:
1596 self.players[from_id].self_message(msg) 1590 self.players[from_id].self_message(msg)
1597 #the following line makes sure that their role is reset to normal, 1591 #the following line makes sure that their role is reset to normal,
1598 #since it is briefly set to lurker when they even TRY to change 1592 #since it is briefly set to lurker when they even TRY to change
1599 #rooms 1593 #rooms
1600 msg = "<role action=\"update\" id=\"" + from_id + "\" role=\"" + self.players[from_id].role + "\" />" 1594 msg = "<role action='update' id='" + from_id + "' role='" + self.players[from_id].role + "' />"
1601 self.players[from_id].outbox.put(msg) 1595 self.players[from_id].outbox.put(msg)
1602 return 1596 return
1603 1597
1604 #move the player into their new group. 1598 #move the player into their new group.
1605 self.move_player(from_id, group_id) 1599 self.move_player(from_id, group_id)
1616 1610
1617 def move_player(self, from_id, group_id ): 1611 def move_player(self, from_id, group_id ):
1618 "move a player from one group to another" 1612 "move a player from one group to another"
1619 try: 1613 try:
1620 try: 1614 try:
1621 if group_id == "0": 1615 if group_id == "0": self.players[from_id].role = "GM"
1622 self.players[from_id].role = "GM" 1616 else: self.players[from_id].role = "Lurker"
1623 else:
1624 self.players[from_id].role = "Lurker"
1625 except Exception, e: 1617 except Exception, e:
1626 print "exception in move_player() " 1618 print "exception in move_player() "
1627 traceback.print_exc() 1619 traceback.print_exc()
1628 1620
1629 old_group_id = self.players[from_id].change_group(group_id,self.groups) 1621 old_group_id = self.players[from_id].change_group(group_id,self.groups)
1667 self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id) 1659 self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id)
1668 except Exception, e: 1660 except Exception, e:
1669 self.log_msg(str(e)) 1661 self.log_msg(str(e))
1670 thread.start_new_thread(self.registerRooms,(0,)) 1662 thread.start_new_thread(self.registerRooms,(0,))
1671 1663
1672 def return_room_roles(self,from_id,group_id): 1664 def return_room_roles(self, from_id, group_id):
1673 for m in self.players.keys(): 1665 for m in self.players.keys():
1674 if self.players[m].group_id == group_id: 1666 if self.players[m].group_id == group_id:
1675 msg = "<role action=\"update\" id=\"" + self.players[m].id + "\" role=\"" + self.players[m].role + "\" />" 1667 print 'return_room_roles', self.players[m].id, self.players[m].role, self.players[m]
1668 try: msg = "<role action='update' id='" + self.players[m].id + "' role='" + self.players[m].role + "' />"
1669 except: exit()
1676 self.players[from_id].outbox.put(msg) 1670 self.players[from_id].outbox.put(msg)
1677 1671
1678 """ 1672 """
1679 # This is pretty much the same thing as the create_group method, however, 1673 # This is pretty much the same thing as the create_group method, however,
1680 # it's much more generic whereas the create_group method is tied to a specific 1674 # it's much more generic whereas the create_group method is tied to a specific
1732 self.send_to_all('0',self.groups[gid].toxml('update')) 1726 self.send_to_all('0',self.groups[gid].toxml('update'))
1733 return lmessage 1727 return lmessage
1734 except: return "An error occured during rename of room!" 1728 except: return "An error occured during rename of room!"
1735 thread.start_new_thread(self.registerRooms,(0,)) 1729 thread.start_new_thread(self.registerRooms,(0,))
1736 1730
1737 def create_group(self,xml_dom,data): 1731 def create_group(self, xml_dom, data):
1738 try: 1732 debug((tostring(xml_dom), data))
1739 from_id = xml_dom.getAttribute("from") 1733 #try:
1740 pwd = xml_dom.getAttribute("pwd") 1734 from_id = xml_dom.get("from")
1741 name = xml_dom.getAttribute("name") 1735 pwd = xml_dom.get("pwd")
1742 boot_pwd = xml_dom.getAttribute("boot_pwd") 1736 name = xml_dom.get("name")
1743 minVersion = xml_dom.getAttribute("min_version") 1737 boot_pwd = xml_dom.get("boot_pwd")
1744 #added var reassign -- akoman 1738 minVersion = xml_dom.get("min_version")
1745 messageFile = self.defaultMessageFile 1739 #added var reassign -- akoman
1746 1740 messageFile = self.defaultMessageFile
1747 # see if passwords are allowed on this server and null password if not 1741
1748 if self.allow_room_passwords != 1: pwd = "" 1742 # see if passwords are allowed on this server and null password if not
1749 1743 if self.allow_room_passwords != 1: pwd = ""
1750 # Check for & in name. We want to allow this because of its common 1744
1751 # use in d&d games. 1745 # Check for & in name. We want to allow this because of its common
1752 1746 # use in d&d games.
1753 loc = name.find("&") 1747
1754 oldloc = 0 1748 loc = name.find("&")
1755 while loc > -1: 1749 oldloc = 0
1756 loc = name.find("&",oldloc) 1750 while loc > -1:
1757 if loc > -1: 1751 loc = name.find("&",oldloc)
1758 b = name[:loc] 1752 if loc > -1:
1759 e = name[loc+1:] 1753 b = name[:loc]
1760 name = b + "&amp;" + e 1754 e = name[loc+1:]
1761 oldloc = loc+1 1755 name = b + "&amp;" + e
1762 loc = name.find("'") 1756 oldloc = loc+1
1763 oldloc = 0 1757 loc = name.find("'")
1764 while loc > -1: 1758 oldloc = 0
1765 loc = name.find("'",oldloc) 1759 while loc > -1:
1766 if loc > -1: 1760 loc = name.find("'",oldloc)
1767 b = name[:loc] 1761 if loc > -1:
1768 e = name[loc+1:] 1762 b = name[:loc]
1769 name = b + "&#39;" + e 1763 e = name[loc+1:]
1770 oldloc = loc+1 1764 name = b + "&#39;" + e
1771 loc = name.find('"') 1765 oldloc = loc+1
1772 oldloc = 0 1766 loc = name.find('"')
1773 while loc > -1: 1767 oldloc = 0
1774 loc = name.find('"',oldloc) 1768 while loc > -1:
1775 if loc > -1: 1769 loc = name.find('"',oldloc)
1776 b = name[:loc] 1770 if loc > -1:
1777 e = name[loc+1:] 1771 b = name[:loc]
1778 name = b + "&quot;" + e 1772 e = name[loc+1:]
1779 oldloc = loc+1 1773 name = b + "&quot;" + e
1780 group_id = str(self.next_group_id) 1774 oldloc = loc+1
1781 self.next_group_id += 1 1775 group_id = str(self.next_group_id)
1782 self.groups[group_id] = game_group(group_id,name,pwd,"",boot_pwd, minVersion, None, messageFile ) 1776 self.next_group_id += 1
1783 self.groups[group_id].voice[from_id]=1 1777 self.groups[group_id] = game_group(group_id, name, pwd, "", boot_pwd, minVersion, None, messageFile)
1784 self.players[from_id].outbox.put(self.groups[group_id].toxml('new')) 1778 self.groups[group_id].voice[from_id]=1
1785 old_group_id = self.players[from_id].change_group(group_id,self.groups) 1779 self.players[from_id].outbox.put(self.groups[group_id].toxml('new'))
1786 self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del')) 1780 old_group_id = self.players[from_id].change_group(group_id,self.groups)
1787 self.check_group(from_id, old_group_id) 1781 self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del'))
1788 self.send_to_all(from_id,self.groups[group_id].toxml('new')) 1782 self.check_group(from_id, old_group_id)
1789 self.send_to_all('0',self.groups[group_id].toxml('update')) 1783 self.send_to_all(from_id,self.groups[group_id].toxml('new'))
1790 self.handle_role("set",from_id,"GM",boot_pwd, group_id) 1784 self.send_to_all('0',self.groups[group_id].toxml('update'))
1791 lmsg = "Creating Group... (" + str(group_id) + ") " + str(name) 1785 self.handle_role("set",from_id,"GM",boot_pwd, group_id)
1792 self.log_msg( lmsg ) 1786 lmsg = "Creating Group... (" + str(group_id) + ") " + str(name)
1793 jmsg = "moving to room " + str(group_id) + "." 1787 self.log_msg( lmsg )
1794 self.log_msg( jmsg ) 1788 jmsg = "moving to room " + str(group_id) + "."
1795 self.log_msg(("create_group", (str(name), group_id, from_id))) 1789 self.log_msg( jmsg )
1796 #even creators of the room should see the HTML --akoman 1790 self.log_msg(("create_group", (str(name), group_id, from_id)))
1797 #edit: jan10/03 - was placed in the except statement. Silly me. 1791 #even creators of the room should see the HTML --akoman
1798 if self.defaultMessageFile != None: 1792 #edit: jan10/03 - was placed in the except statement. Silly me.
1799 if self.defaultMessageFile[:4] == 'http': 1793 if self.defaultMessageFile != None:
1800 data = urllib.urlretrieve(self.defaultMessageFile) 1794 if self.defaultMessageFile[:4] == 'http':
1801 open_msg = open(data[0]) 1795 data = urllib.urlretrieve(self.defaultMessageFile)
1802 urllib.urlcleanup() 1796 open_msg = open(data[0])
1803 else: open_msg = open( self.defaultMessageFile, "r" ) 1797 urllib.urlcleanup()
1804 roomMsg = open_msg.read() 1798 else: open_msg = open( self.defaultMessageFile, "r" )
1805 open_msg.close() 1799 roomMsg = open_msg.read()
1806 # Send the rooms message to the client no matter what 1800 open_msg.close()
1807 self.players[from_id].outbox.put( "<msg to='" + from_id + "' from='0' group_id='" + group_id + "' />" + roomMsg ) 1801 # Send the rooms message to the client no matter what
1808 except Exception, e: self.log_msg( "Exception: create_group(): " + str(e)) 1802 self.players[from_id].outbox.put( "<msg to='" + from_id + "' from='0' group_id='" + group_id + "' />" + roomMsg )
1803 #except Exception, e: self.log_msg( "Exception: create_group(): " + str(e))
1809 thread.start_new_thread(self.registerRooms,(0,)) 1804 thread.start_new_thread(self.registerRooms,(0,))
1810 1805
1811 def check_group(self, from_id, group_id): 1806 def check_group(self, from_id, group_id):
1812 try: 1807 try:
1813 if group_id not in self.groups: return 1808 if group_id not in self.groups: return
1823 #The register Rooms thread 1818 #The register Rooms thread
1824 thread.start_new_thread(self.registerRooms,(0,)) 1819 thread.start_new_thread(self.registerRooms,(0,))
1825 1820
1826 except Exception, e: self.log_msg(str(e)) 1821 except Exception, e: self.log_msg(str(e))
1827 1822
1828 def del_player(self,id,group_id): 1823 def del_player(self, id, group_id):
1829 try: 1824 try:
1830 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name) 1825 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name)
1831 self.players[id].disconnect() 1826 self.players[id].disconnect()
1832 self.groups[group_id].remove_player(id) 1827 self.groups[group_id].remove_player(id)
1833 del self.players[id] 1828 del self.players[id]
1842 if self.be_registered: 1837 if self.be_registered:
1843 self.register() 1838 self.register()
1844 except Exception, e: self.log_msg(str(e)) 1839 except Exception, e: self.log_msg(str(e))
1845 self.log_msg("Explicit garbage collection shows %s undeletable items." % str(gc.collect())) 1840 self.log_msg("Explicit garbage collection shows %s undeletable items." % str(gc.collect()))
1846 1841
1847 def incoming_player_handler(self,xml_dom,data): 1842 def incoming_player_handler(self, xml_dom, data):
1848 id = xml_dom.getAttribute("id") 1843 debug()
1849 act = xml_dom.getAttribute("action") 1844 id = xml_dom.get("id")
1850 #group_id = xml_dom.getAttribute("group_id") 1845 act = xml_dom.get("action")
1846 #group_id = xml_dom.get("group_id")
1851 group_id = self.players[id].group_id 1847 group_id = self.players[id].group_id
1852 ip = self.players[id].ip 1848 ip = self.players[id].ip
1853 self.log_msg("Player with IP: " + str(ip) + " joined.") 1849 self.log_msg("Player with IP: " + str(ip) + " joined.")
1854 ServerPlugins.setPlayer(self.players[id]) 1850 ServerPlugins.setPlayer(self.players[id])
1855 self.send_to_group(id,group_id,data) 1851 self.send_to_group(id,group_id,data)
1857 try: 1853 try:
1858 self.send_player_list(id,group_id) 1854 self.send_player_list(id,group_id)
1859 self.send_group_list(id) 1855 self.send_group_list(id)
1860 except Exception, e: traceback.print_exc() 1856 except Exception, e: traceback.print_exc()
1861 elif act=="del": 1857 elif act=="del":
1862 #print "del player"
1863 self.del_player(id,group_id) 1858 self.del_player(id,group_id)
1864 self.check_group(id, group_id) 1859 self.check_group(id, group_id)
1865 elif act=="update": 1860 elif act=="update":
1861 debug(xml_dom)
1862 print xml_dom.get('name')
1866 self.players[id].take_dom(xml_dom) 1863 self.players[id].take_dom(xml_dom)
1867 self.log_msg(("update", {"id": id, 1864 self.log_msg(("update", {"id": id,
1868 "name": xml_dom.getAttribute("name"), 1865 "name": xml_dom.get("name"),
1869 "status": xml_dom.getAttribute("status"), 1866 "status": xml_dom.get("status"),
1870 "role": xml_dom.getAttribute("role"), 1867 "role": xml_dom.get("role"),
1871 "ip": str(ip), 1868 "ip": str(ip),
1872 "group": xml_dom.getAttribute("group_id"), 1869 "group": xml_dom.get("group_id"),
1873 "room": xml_dom.getAttribute("name"), 1870 "room": xml_dom.get("name"),
1874 "boot": xml_dom.getAttribute("rm_boot"), 1871 "boot": xml_dom.get("rm_boot"),
1875 "version": xml_dom.getAttribute("version"), 1872 "version": xml_dom.get("version"),
1876 "ping": xml_dom.getAttribute("time") \ 1873 "ping": xml_dom.get("time") \
1877 })) 1874 }))
1878 1875
1879 def strip_cheat_roll(self, string): 1876 def strip_cheat_roll(self, string):
1880 try: 1877 try:
1881 cheat_regex = re.compile('&amp;#91;(.*?)&amp;#93;') 1878 cheat_regex = re.compile('&amp;#91;(.*?)&amp;#93;')
1893 def msgTooLong(self, length): 1890 def msgTooLong(self, length):
1894 if length > self.maxSendSize and not self.maxSendSize == 0: return True 1891 if length > self.maxSendSize and not self.maxSendSize == 0: return True
1895 return False 1892 return False
1896 1893
1897 def incoming_msg_handler(self,xml_dom,data): 1894 def incoming_msg_handler(self,xml_dom,data):
1895 debug()
1898 xml_dom, data = ServerPlugins.preParseIncoming(xml_dom, data) 1896 xml_dom, data = ServerPlugins.preParseIncoming(xml_dom, data)
1899 to_id = xml_dom.getAttribute("to") 1897 ###########################################################
1900 from_id = xml_dom.getAttribute("from") 1898 to_id = xml_dom.get("to")
1901 group_id = xml_dom.getAttribute("group_id") 1899 from_id = xml_dom.get("from")
1900 group_id = xml_dom.get("group_id")
1902 end = data.find(">") 1901 end = data.find(">")
1903 msg = data[end+1:] 1902 msg = data[end+1:]
1904 1903
1905 if from_id == "0" or len(from_id) == 0: 1904 if from_id == "0" or len(from_id) == 0:
1906 print "WARNING!! Message received with an invalid from_id. Message dropped." 1905 print "WARNING!! Message received with an invalid from_id. Message dropped."
1941 else: self.players[to_id].outbox.put(data) 1940 else: self.players[to_id].outbox.put(data)
1942 self.check_group_members(group_id) 1941 self.check_group_members(group_id)
1943 return 1942 return
1944 1943
1945 def sound_msg_handler(self, xml_dom, data): 1944 def sound_msg_handler(self, xml_dom, data):
1946 from_id = xml_dom.getAttribute("from") 1945 debug()
1947 group_id = xml_dom.getAttribute("group_id") 1946 from_id = xml_dom.get("from")
1947 group_id = xml_dom.get("group_id")
1948 if group_id != 0: self.send_to_group(from_id, group_id, data) 1948 if group_id != 0: self.send_to_group(from_id, group_id, data)
1949 1949
1950 def plugin_msg_handler(self,xml_dom,data): 1950 def plugin_msg_handler(self,xml_dom,data):
1951 to_id = xml_dom.getAttribute("to") 1951 to_id = xml_dom.get("to")
1952 from_id = xml_dom.getAttribute("from") 1952 from_id = xml_dom.get("from")
1953 group_id = xml_dom.getAttribute("group_id") 1953 group_id = xml_dom.get("group_id")
1954 end = data.find(">") 1954 end = data.find(">")
1955 msg = data[end+1:] 1955 msg = data[end+1:]
1956 1956
1957 if from_id == "0" or len(from_id) == 0: 1957 if from_id == "0" or len(from_id) == 0:
1958 print "WARNING!! Message received with an invalid from_id. Message dropped." 1958 print "WARNING!! Message received with an invalid from_id. Message dropped."
2000 def handle_boot(self,from_id,to_id,group_id,msg): 2000 def handle_boot(self,from_id,to_id,group_id,msg):
2001 xml_dom = None 2001 xml_dom = None
2002 try: 2002 try:
2003 given_boot_pwd = None 2003 given_boot_pwd = None
2004 try: 2004 try:
2005 xml_dom = parseXml(msg) 2005 xml_dom = XML(msg)
2006 xml_dom = xml_dom._get_documentElement() 2006 #xml_dom = xml_dom._get_documentElement()
2007 given_boot_pwd = xml_dom.getAttribute("boot_pwd") 2007 given_boot_pwd = xml_dom.get("boot_pwd")
2008 2008
2009 except: 2009 except:
2010 print "Error in parse of boot message, Ignoring." 2010 print "Error in parse of boot message, Ignoring."
2011 print "Exception: " 2011 print "Exception: "
2012 traceback.print_exc() 2012 traceback.print_exc()
2100 self.log_msg('Exception in admin_kick() ' + str(e)) 2100 self.log_msg('Exception in admin_kick() ' + str(e))
2101 2101
2102 ### Alpha ### Addition added to assist in Un Banning users. 2102 ### Alpha ### Addition added to assist in Un Banning users.
2103 def admin_build_banlist(self): 2103 def admin_build_banlist(self):
2104 validate.config_file("ban_list.xml", "default_ban_list.xml" ) 2104 validate.config_file("ban_list.xml", "default_ban_list.xml" )
2105 configDom = minidom.parse(dir_struct["user"] + 'ban_list.xml') 2105 configDom = parse(dir_struct["user"] + 'ban_list.xml')
2106 self.ban_list = {} 2106 self.ban_list = {}
2107 for element in configDom.getElementsByTagName('banned'): 2107 for element in configDom.findall('banned'):
2108 player = element.getAttribute('name').replace("&", "&amp;").replace("<", "&lt;").replace('"', "&quot;").replace(">", "&gt;") 2108 player = element.get('name').replace("&", "&amp;").replace("<", "&lt;").replace('"', "&quot;").replace(">", "&gt;")
2109 ip = element.getAttribute('ip') 2109 ip = element.get('ip')
2110 self.ban_list[ip] = {} 2110 self.ban_list[ip] = {}
2111 self.ban_list[ip]['ip'] = ip 2111 self.ban_list[ip]['ip'] = ip
2112 self.ban_list[ip]['name'] = element.getAttribute('name') 2112 self.ban_list[ip]['name'] = element.get('name')
2113 ################ 2113 ################
2114 2114
2115 def admin_banip(self, ip, name="", silent = 0): 2115 def admin_banip(self, ip, name="", silent = 0):
2116 "Ban a player from a server from the console" 2116 "Ban a player from a server from the console"
2117 self.adming_buile_banlist() ### Alpha ### 2117 self.adming_buile_banlist() ### Alpha ###
2243 traceback.print_exc() 2243 traceback.print_exc()
2244 self.log_msg("Exception: send_player_list(): " + str(e)) 2244 self.log_msg("Exception: send_player_list(): " + str(e))
2245 2245
2246 def send_group_list(self, to_id, action="new"): 2246 def send_group_list(self, to_id, action="new"):
2247 try: 2247 try:
2248 print self.groups
2248 for key in self.groups: 2249 for key in self.groups:
2249 xml = self.groups[key].toxml(action) 2250 xml = self.groups[key].toxml(action)
2251 print xml, key
2250 self.players[to_id].outbox.put(xml) 2252 self.players[to_id].outbox.put(xml)
2251 except Exception, e: 2253 except Exception, e:
2252 self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e)) 2254 self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e))
2253 traceback.print_exc() 2255 traceback.print_exc()
2254 2256
2301 # (allows basic administration of server from a remote client) 2303 # (allows basic administration of server from a remote client)
2302 # base message format: <admin id="" pwd="" cmd="" [data for command]> 2304 # base message format: <admin id="" pwd="" cmd="" [data for command]>
2303 """ 2305 """
2304 if not self.allowRemoteAdmin: return 2306 if not self.allowRemoteAdmin: return
2305 try: 2307 try:
2306 pid = xml_dom.getAttribute("id") 2308 pid = xml_dom.get("id")
2307 gid = "" 2309 gid = ""
2308 given_pwd = xml_dom.getAttribute("pwd") 2310 given_pwd = xml_dom.get("pwd")
2309 cmd = xml_dom.getAttribute("cmd") 2311 cmd = xml_dom.get("cmd")
2310 server_admin_pwd = self.groups["0"].boot_pwd 2312 server_admin_pwd = self.groups["0"].boot_pwd
2311 p_id = "" 2313 p_id = ""
2312 p_name= "" 2314 p_name= ""
2313 p_ip = "" 2315 p_ip = ""
2314 2316
2343 if cmd == "list": 2345 if cmd == "list":
2344 #return player list to this user. 2346 #return player list to this user.
2345 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.player_list_remote() 2347 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.player_list_remote()
2346 self.players[pid].outbox.put(msg) 2348 self.players[pid].outbox.put(msg)
2347 elif cmd == "banip": 2349 elif cmd == "banip":
2348 ip = xml_dom.getAttribute("bip") 2350 ip = xml_dom.get("bip")
2349 name = xml_dom.getAttribute("bname") 2351 name = xml_dom.get("bname")
2350 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Banned: " + str(ip) 2352 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Banned: " + str(ip)
2351 self.admin_banip(ip, name) 2353 self.admin_banip(ip, name)
2352 elif cmd == "ban": 2354 elif cmd == "ban":
2353 id = xml_dom.getAttribute("bid") 2355 id = xml_dom.get("bid")
2354 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Banned!" 2356 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Banned!"
2355 self.players[pid].outbox.put(msg) 2357 self.players[pid].outbox.put(msg)
2356 self.admin_ban(id, "") 2358 self.admin_ban(id, "")
2357 ### Alpha ### and untested 2359 ### Alpha ### and untested
2358 elif cmd == "boot": 2360 elif cmd == "boot":
2359 id = xml_dom.getAttribute("bid") 2361 id = xml_dom.get("bid")
2360 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Booted!" 2362 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Booted!"
2361 self.players[pid].outbox.put(msg) 2363 self.players[pid].outbox.put(msg)
2362 self.admin_kick(id, "") 2364 self.admin_kick(id, "")
2363 ############# 2365 #############
2364 elif cmd == "unban": 2366 elif cmd == "unban":
2365 ip = xml_dom.getAttribute("ip") 2367 ip = xml_dom.get("ip")
2366 self.admin_unban(ip) 2368 self.admin_unban(ip)
2367 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Unbaned: " + str(ip) 2369 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Unbaned: " + str(ip)
2368 self.players[pid].outbox.put(msg) 2370 self.players[pid].outbox.put(msg)
2369 elif cmd == "banlist": 2371 elif cmd == "banlist":
2370 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.admin_banlist() 2372 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.admin_banlist()
2371 self.players[pid].outbox.put(msg) 2373 self.players[pid].outbox.put(msg)
2372 elif cmd == "killgroup": 2374 elif cmd == "killgroup":
2373 ugid = xml_dom.getAttribute("gid") 2375 ugid = xml_dom.get("gid")
2374 if ugid == "0": 2376 if ugid == "0":
2375 m = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" 2377 m = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>"
2376 m += "Cannot Remove Lobby! Remote administrator request denied!" 2378 m += "Cannot Remove Lobby! Remote administrator request denied!"
2377 self.players[pid].outbox.put(m) 2379 self.players[pid].outbox.put(m)
2378 else: 2380 else:
2379 result = self.prune_room(ugid) 2381 result = self.prune_room(ugid)
2380 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + str(result) 2382 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + str(result)
2381 self.players[pid].outbox.put(msg) 2383 self.players[pid].outbox.put(msg)
2382 2384
2383 elif cmd == "message": 2385 elif cmd == "message":
2384 tuid = xml_dom.getAttribute("to_id") 2386 tuid = xml_dom.get("to_id")
2385 msg = xml_dom.getAttribute("msg") 2387 msg = xml_dom.get("msg")
2386 pmsg = "<msg to='" + tuid + "' from='0' group_id='" + self.players[tuid].group_id + "' >" + msg 2388 pmsg = "<msg to='" + tuid + "' from='0' group_id='" + self.players[tuid].group_id + "' >" + msg
2387 try: self.players[tuid].outbox.put(pmsg) 2389 try: self.players[tuid].outbox.put(pmsg)
2388 except: 2390 except:
2389 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + ">Unknown Player ID: No message sent." 2391 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + ">Unknown Player ID: No message sent."
2390 self.players[pid].outbox.put(msg) 2392 self.players[pid].outbox.put(msg)
2391 elif cmd == "broadcast": 2393 elif cmd == "broadcast":
2392 bmsg = xml_dom.getAttribute("msg") 2394 bmsg = xml_dom.get("msg")
2393 self.broadcast(bmsg) 2395 self.broadcast(bmsg)
2394 elif cmd == "killserver" and self.allowRemoteKill: 2396 elif cmd == "killserver" and self.allowRemoteKill:
2395 #dangerous command..once server stopped it must be restarted manually 2397 #dangerous command..once server stopped it must be restarted manually
2396 self.kill_server() 2398 self.kill_server()
2397 elif cmd == "uptime": 2399 elif cmd == "uptime":
2405 # Toggle if room passwords are allowed on this server 2407 # Toggle if room passwords are allowed on this server
2406 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" 2408 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>"
2407 msg += self.RoomPasswords() 2409 msg += self.RoomPasswords()
2408 self.players[pid].outbox.put( msg) 2410 self.players[pid].outbox.put( msg)
2409 elif cmd == "createroom": 2411 elif cmd == "createroom":
2410 rm_name = xml_dom.getAttribute("name") 2412 rm_name = xml_dom.get("name")
2411 rm_pass = xml_dom.getAttribute("pass") 2413 rm_pass = xml_dom.get("pass")
2412 rm_boot = xml_dom.getAttribute("boot") 2414 rm_boot = xml_dom.get("boot")
2413 result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass) 2415 result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass)
2414 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + result 2416 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + result
2415 self.players[pid].outbox.put(msg) 2417 self.players[pid].outbox.put(msg)
2416 elif cmd == "nameroom": 2418 elif cmd == "nameroom":
2417 rm_id = xml_dom.getAttribute("rmid") 2419 rm_id = xml_dom.get("rmid")
2418 rm_name = xml_dom.getAttribute("name") 2420 rm_name = xml_dom.get("name")
2419 result = self.change_group_name(rm_id,rm_name,pid) 2421 result = self.change_group_name(rm_id,rm_name,pid)
2420 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'/>" + result 2422 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'/>" + result
2421 self.players[pid].outbox.put(msg) 2423 self.players[pid].outbox.put(msg)
2422 elif cmd == "passwd": 2424 elif cmd == "passwd":
2423 tgid = xml_dom.getAttribute("gid") 2425 tgid = xml_dom.get("gid")
2424 npwd = xml_dom.getAttribute("pass") 2426 npwd = xml_dom.get("pass")
2425 if tgid == "0": 2427 if tgid == "0":
2426 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" 2428 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>"
2427 msg += "Server password may not be changed remotely!" 2429 msg += "Server password may not be changed remotely!"
2428 self.players[pid].outbox.put(msg) 2430 self.players[pid].outbox.put(msg)
2429 else: 2431 else: