Mercurial > traipse_dev
comparison orpg/networking/mplay_server.py @ 71:449a8900f9ac ornery-dev
Code refining almost completed, for this round. Some included files are still in need of some clean up, but this is test worthy.
author | sirebral |
---|---|
date | Thu, 20 Aug 2009 03:00:39 -0500 |
parents | c54768cffbd4 |
children | d1aff41c031b |
comparison
equal
deleted
inserted
replaced
70:52a5fa913008 | 71:449a8900f9ac |
---|---|
41 <create_group from='' pwd='' name='' /> | 41 <create_group from='' pwd='' name='' /> |
42 <join_group from='' pwd='' group_id='' /> | 42 <join_group from='' pwd='' group_id='' /> |
43 <role action='set,get,display' player='' group_id='' boot_pwd='' role=''/> | 43 <role action='set,get,display' player='' group_id='' boot_pwd='' role=''/> |
44 """ | 44 """ |
45 | 45 |
46 from mplay_client import * | 46 import re |
47 from mplay_client import MPLAY_LENSIZE | |
48 from orpg.dirpath import dir_struct | |
49 import orpg.tools.validate | |
50 import gc | 47 import gc |
51 import cgi | 48 import cgi |
52 import sys | 49 import sys |
53 import string | 50 import string |
54 import time | 51 import time |
55 import urllib | 52 import urllib |
53 import traceback | |
54 | |
55 from mplay_client import * | |
56 from mplay_client import MPLAY_LENSIZE | |
57 from orpg.dirpath import dir_struct | |
58 import orpg.tools.validate | |
59 | |
56 from orpg.mapper.map_msg import * | 60 from orpg.mapper.map_msg import * |
57 from threading import Lock, RLock | 61 from threading import Lock, RLock |
58 from struct import pack, unpack, calcsize | 62 from struct import pack, unpack, calcsize |
59 from meta_server_lib import * | 63 from meta_server_lib import * |
60 import traceback | |
61 import re | |
62 | 64 |
63 # Import the minidom XML module | 65 # Import the minidom XML module |
64 from xml.dom import minidom | 66 from xml.dom import minidom |
65 | 67 |
66 # Snag the version number | 68 # Snag the version number |
67 from orpg.orpg_version import * | 69 from orpg.orpg_version import VERSION, PROTOCOL_VERSION, CLIENT_STRING, SERVER_MIN_CLIENT_VERSION |
68 | 70 |
69 #Plugins | 71 #Plugins |
70 from server_plugins import ServerPlugins | 72 from server_plugins import ServerPlugins |
71 | 73 |
72 def id_compare(a,b): | 74 def id_compare(a,b): |
108 if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1: | 110 if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1: |
109 f = open(self.mapFile, "w") | 111 f = open(self.mapFile, "w") |
110 f.write(self.game_map.get_all_xml()) | 112 f.write(self.game_map.get_all_xml()) |
111 f.close() | 113 f.close() |
112 | 114 |
113 | |
114 def add_player(self,id): | 115 def add_player(self,id): |
115 self.players.append(id) | 116 self.players.append(id) |
116 | 117 |
117 def remove_player(self,id): | 118 def remove_player(self,id): |
118 if self.voice.has_key(id): | 119 if self.voice.has_key(id): |
125 | 126 |
126 def get_player_ids(self): | 127 def get_player_ids(self): |
127 tmp = self.players | 128 tmp = self.players |
128 return tmp | 129 return tmp |
129 | 130 |
130 | |
131 def check_pwd(self,pwd): | 131 def check_pwd(self,pwd): |
132 return (pwd==self.pwd) | 132 return (pwd==self.pwd) |
133 | 133 |
134 def check_boot_pwd(self,pwd): | 134 def check_boot_pwd(self,pwd): |
135 return (pwd==self.boot_pwd) | 135 return (pwd==self.boot_pwd) |
136 | 136 |
137 def check_version(self,ver): | 137 def check_version(self,ver): |
138 if (self.minVersion == ""): | 138 if (self.minVersion == ""): return 1 |
139 return 1 | |
140 minVersion=self.minVersion.split('.') | 139 minVersion=self.minVersion.split('.') |
141 version=ver.split('.') | 140 version=ver.split('.') |
142 for i in xrange(min(len(minVersion),len(version))): | 141 for i in xrange(min(len(minVersion),len(version))): |
143 w=max(len(minVersion[i]),len(version[i])) | 142 w=max(len(minVersion[i]),len(version[i])) |
144 v1=minVersion[i].rjust(w); | 143 v1=minVersion[i].rjust(w); |
145 v2=version[i].rjust(w); | 144 v2=version[i].rjust(w); |
146 if v1<v2: | 145 if v1<v2: return 1 |
147 return 1 | 146 if v1>v2: return 0 |
148 if v1>v2: | |
149 return 0 | |
150 | |
151 if len(minVersion)>len(version): | 147 if len(minVersion)>len(version): |
152 return 0 | 148 return 0 |
153 return 1 | 149 return 1 |
154 | 150 |
155 #depreciated - see send_group_list() | 151 #depreciated - see send_group_list() |
159 xml_data += "\" name=\"" + self.name | 155 xml_data += "\" name=\"" + self.name |
160 xml_data += "\" pwd=\"" + str(self.pwd!="") | 156 xml_data += "\" pwd=\"" + str(self.pwd!="") |
161 xml_data += "\" players=\"" + str(self.get_num_players()) | 157 xml_data += "\" players=\"" + str(self.get_num_players()) |
162 xml_data += "\" action=\"" + act + "\" />" | 158 xml_data += "\" action=\"" + act + "\" />" |
163 return xml_data | 159 return xml_data |
164 | |
165 | 160 |
166 | 161 |
167 class client_stub(client_base): | 162 class client_stub(client_base): |
168 def __init__(self,inbox,sock,props,log): | 163 def __init__(self,inbox,sock,props,log): |
169 client_base.__init__(self) | 164 client_base.__init__(self) |
187 | 182 |
188 def clear_timeout(self): | 183 def clear_timeout(self): |
189 self.timeout_time = None | 184 self.timeout_time = None |
190 | 185 |
191 def check_time_out(self): | 186 def check_time_out(self): |
192 if self.timeout_time==None: | 187 if self.timeout_time==None: self.timeout_time = time.time() |
193 self.timeout_time = time.time() | |
194 curtime = time.time() | 188 curtime = time.time() |
195 diff = curtime - self.timeout_time | 189 diff = curtime - self.timeout_time |
196 if diff > 1800: | 190 if diff > 1800: return 1 |
197 return 1 | 191 else: return 0 |
198 else: | |
199 return 0 | |
200 | 192 |
201 def send(self,msg,player,group): | 193 def send(self,msg,player,group): |
202 if self.get_status() == MPLAY_CONNECTED: | 194 if self.get_status() == MPLAY_CONNECTED: |
203 self.outbox.put("<msg to='" + player + "' from='0' group_id='" + group + "' />" + msg) | 195 self.outbox.put("<msg to='" + player + "' from='0' group_id='" + group + "' />" + msg) |
204 | 196 |
217 | 209 |
218 def take_dom(self,xml_dom): | 210 def take_dom(self,xml_dom): |
219 self.name = xml_dom.getAttribute("name") | 211 self.name = xml_dom.getAttribute("name") |
220 self.text_status = xml_dom.getAttribute("status") | 212 self.text_status = xml_dom.getAttribute("status") |
221 | 213 |
222 | 214 """ |
223 ###################################################################### | 215 ###################################################################### |
224 ###################################################################### | 216 ###################################################################### |
225 ## | 217 ## |
226 ## | 218 ## |
227 ## MPLAY SERVER | 219 ## MPLAY SERVER |
228 ## | 220 ## |
229 ## | 221 ## |
230 ###################################################################### | 222 ###################################################################### |
231 ###################################################################### | 223 ###################################################################### |
224 """ | |
232 | 225 |
233 class mplay_server: | 226 class mplay_server: |
234 def __init__(self, log_console=None, name=None): | 227 def __init__(self, log_console=None, name=None): |
235 self.log_to_console = 1 | 228 self.log_to_console = 1 |
236 self.log_console = log_console | 229 self.log_console = log_console |
262 self.maxSendSize = 1024 | 255 self.maxSendSize = 1024 |
263 self.server_port = OPENRPG_PORT | 256 self.server_port = OPENRPG_PORT |
264 self.allowRemoteKill = False | 257 self.allowRemoteKill = False |
265 self.allowRemoteAdmin = True | 258 self.allowRemoteAdmin = True |
266 self.sendLobbySound = False | 259 self.sendLobbySound = False |
267 self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' | 260 self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used? |
268 | 261 |
269 def initServer(self, **kwargs): | 262 def initServer(self, **kwargs): |
270 for atter, value in kwargs.iteritems(): | 263 for atter, value in kwargs.iteritems(): setattr(self, atter, value) |
271 setattr(self, atter, value) | 264 validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" ) |
272 self.validate = orpg.tools.validate.Validate(self.userPath) | 265 validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" ) |
273 self.validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" ) | |
274 self.validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" ) | |
275 self.server_start_time = time.time() | 266 self.server_start_time = time.time() |
276 | 267 |
277 # Since the server is just starting here, we read in the XML configuration | 268 # Since the server is just starting here, we read in the XML configuration |
278 # file. Notice the lobby is still created here by default. | 269 # file. Notice the lobby is still created here by default. |
279 self.groups = { '0': game_group('0','Lobby','','The game lobby', '', '', self.userPath + self.lobbyMapFile, self.userPath + self.lobbyMessageFile, 1)} | 270 self.groups = { '0': game_group('0','Lobby','', |
271 'The game lobby', '', '', self.userPath + self.lobbyMapFile, | |
272 self.userPath + self.lobbyMessageFile, 1)} | |
280 # Make sure the server's name gets set, in case we are being started from | 273 # Make sure the server's name gets set, in case we are being started from |
281 # elsewhere. Basically, if it's passed in, we'll over ride what we were | 274 # elsewhere. Basically, if it's passed in, we'll over ride what we were |
282 # prompted for. This should never really happen at any rate. | 275 # prompted for. This should never really happen at any rate. |
283 | 276 |
284 self.initServerConfig() | 277 self.initServerConfig() |
312 self.addsvrcmd('create_group', self.create_group) | 305 self.addsvrcmd('create_group', self.create_group) |
313 self.addsvrcmd('moderate', self.moderate_group) | 306 self.addsvrcmd('moderate', self.moderate_group) |
314 self.addsvrcmd('plugin', self.plugin_msg_handler) | 307 self.addsvrcmd('plugin', self.plugin_msg_handler) |
315 self.addsvrcmd('sound', self.sound_msg_handler) | 308 self.addsvrcmd('sound', self.sound_msg_handler) |
316 | 309 |
317 | |
318 # This method reads in the server's ban list added by Darren | 310 # This method reads in the server's ban list added by Darren |
319 def initBanList( self ): | 311 def initBanList( self ): |
320 self.log_msg("Processing Ban List File...") | 312 self.log_msg("Processing Ban List File...") |
321 | 313 |
322 # make sure the server_ini.xml exists! | 314 # make sure the server_ini.xml exists! |
323 self.validate.config_file(self.banFile, "default_ban_list.xml" ) | 315 validate.config_file(self.banFile, "default_ban_list.xml" ) |
324 | 316 |
325 # try to use it. | 317 # try to use it. |
326 try: | 318 try: |
327 self.banDom = minidom.parse(self.userPath + 'ban_list.xml') | 319 self.banDom = minidom.parse(self.userPath + 'ban_list.xml') |
328 self.banDom.normalize() | 320 self.banDom.normalize() |
359 # This method reads in the server's configuration file and reconfigs the server | 351 # This method reads in the server's configuration file and reconfigs the server |
360 # as needed, over-riding any default values as requested. | 352 # as needed, over-riding any default values as requested. |
361 def initServerConfig(self): | 353 def initServerConfig(self): |
362 self.log_msg("Processing Server Configuration File... " + self.userPath) | 354 self.log_msg("Processing Server Configuration File... " + self.userPath) |
363 # make sure the server_ini.xml exists! | 355 # make sure the server_ini.xml exists! |
364 self.validate.config_file( "server_ini.xml", "default_server_ini.xml" ) | 356 validate.config_file( "server_ini.xml", "default_server_ini.xml" ) |
365 # try to use it. | 357 # try to use it. |
366 try: | 358 try: |
367 self.configDom = minidom.parse(self.userPath + 'server_ini.xml') | 359 self.configDom = minidom.parse(self.userPath + 'server_ini.xml') |
368 self.configDom.normalize() | 360 self.configDom.normalize() |
369 self.configDoc = self.configDom.documentElement | 361 self.configDoc = self.configDom.documentElement |
381 if not len(self.reg) > 0 or self.reg[0].upper() not in ("Y", "N"): | 373 if not len(self.reg) > 0 or self.reg[0].upper() not in ("Y", "N"): |
382 opt = raw_input("Do you want to post your server to the OpenRPG Meta Server list? (y,n) ") | 374 opt = raw_input("Do you want to post your server to the OpenRPG Meta Server list? (y,n) ") |
383 if len(opt) and (opt[0].upper() == 'Y'): self.reg = 'Y' | 375 if len(opt) and (opt[0].upper() == 'Y'): self.reg = 'Y' |
384 else: self.reg = 'N' | 376 else: self.reg = 'N' |
385 LobbyName = 'Lobby' | 377 LobbyName = 'Lobby' |
378 | |
386 if self.configDoc.hasAttribute("lobbyname"): LobbyName = self.configDoc.getAttribute("lobbyname") | 379 if self.configDoc.hasAttribute("lobbyname"): LobbyName = self.configDoc.getAttribute("lobbyname") |
387 map_node = service_node = self.configDoc.getElementsByTagName("map")[0] | 380 map_node = service_node = self.configDoc.getElementsByTagName("map")[0] |
388 msg_node = service_node = self.configDoc.getElementsByTagName("message")[0] | 381 msg_node = service_node = self.configDoc.getElementsByTagName("message")[0] |
389 mapFile = map_node.getAttribute('file') | 382 mapFile = map_node.getAttribute('file') |
390 msgFile = msg_node.getAttribute('file') | 383 msgFile = msg_node.getAttribute('file') |
391 if mapFile == '': mapFile = 'Lobby_map.xml' | 384 if mapFile == '': mapFile = 'Lobby_map.xml' |
392 if msgFile == '': msgFile = 'LobbyMessage.html' | 385 if msgFile == '': msgFile = 'LobbyMessage.html' |
393 # Update the lobby with the passwords if they've been specified | 386 # Update the lobby with the passwords if they've been specified |
387 | |
394 if len(self.boot_pwd): | 388 if len(self.boot_pwd): |
395 self.groups = {'0': game_group( '0', LobbyName, "", 'The game lobby', self.boot_pwd, "", | 389 self.groups = {'0': game_group( '0', LobbyName, "", 'The game lobby', self.boot_pwd, "", |
396 self.userPath + mapFile.replace("myfiles/", ""), | 390 self.userPath + mapFile.replace("myfiles/", ""), |
397 self.userPath + msgFile.replace("myfiles/", ""), 1 ) | 391 self.userPath + msgFile.replace("myfiles/", ""), 1 ) |
398 } | 392 } |
409 self.name = self.configDoc.getAttribute("name") | 403 self.name = self.configDoc.getAttribute("name") |
410 else: | 404 else: |
411 if self.reg[0].upper() == "Y": | 405 if self.reg[0].upper() == "Y": |
412 if self.name == None: self.name = raw_input("Server Name? ") | 406 if self.name == None: self.name = raw_input("Server Name? ") |
413 self.register() | 407 self.register() |
414 | 408 """ |
415 # Get the minimum openrpg version from config if available | 409 # Get the minimum openrpg version from config if available |
416 # if it isn't set min version to internal default. | 410 # if it isn't set min version to internal default. |
417 # | 411 # |
418 # server_ini.xml entry for version tag... | 412 # server_ini.xml entry for version tag... |
419 # <version min="x.x.x"> | 413 # <version min="x.x.x"> |
414 """ | |
415 | |
420 try: | 416 try: |
421 mver = self.configDoc.getElementsByTagName("version")[0] | 417 mver = self.configDoc.getElementsByTagName("version")[0] |
422 self.minClientVersion = mver.getAttribute("min") | 418 self.minClientVersion = mver.getAttribute("min") |
423 except: self.minClientVersion = SERVER_MIN_CLIENT_VERSION #from orpg/orpg_version.py | 419 except: self.minClientVersion = SERVER_MIN_CLIENT_VERSION #from orpg/orpg_version.py |
424 self.defaultMessageFile = "" | 420 self.defaultMessageFile = "" |
425 # This try/except bit is to allow older versions of python to continue without a list error. | 421 # This try/except bit is to allow older versions of python to continue without a list error. |
426 | 422 |
427 | 423 |
428 | 424 """ |
429 #------------------------[ START <AUTOKICK> TAG PROCESSING ]-------------- | 425 #------------------------[ START <AUTOKICK> TAG PROCESSING ]-------------- |
430 # Auto-kick option defaults for silent booting and | 426 # Auto-kick option defaults for silent booting and |
431 # setting the default zombie-client delay time --Snowdog 9/05 | 427 # setting the default zombie-client delay time --Snowdog 9/05 |
432 # | 428 # |
433 # server_ini.xml entry for autikick tag... | 429 # server_ini.xml entry for autikick tag... |
434 # <autokick silent=["no","yes"] delay="(# of seconds)"> | 430 # <autokick silent=["no","yes"] delay="(# of seconds)"> |
431 """ | |
435 | 432 |
436 try: | 433 try: |
437 ak = self.configDoc.getElementsByTagName("autokick")[0] | 434 ak = self.configDoc.getElementsByTagName("autokick")[0] |
438 if ak.hasAttribute("silent"): | 435 if ak.hasAttribute("silent"): |
439 if ((ak.getAttribute("silent")).lower() == "yes"): self.silent_auto_kick = 1 | 436 if ((ak.getAttribute("silent")).lower() == "yes"): self.silent_auto_kick = 1 |
453 self.log_msg("**WARNING** Error loading autokick settings... using defaults") | 450 self.log_msg("**WARNING** Error loading autokick settings... using defaults") |
454 | 451 |
455 alk = "" | 452 alk = "" |
456 if (self.silent_auto_kick == 1): alk = "(Silent Mode)" | 453 if (self.silent_auto_kick == 1): alk = "(Silent Mode)" |
457 self.log_msg("Auto Kick: Delay="+str(self.zombie_time) + " " + alk) | 454 self.log_msg("Auto Kick: Delay="+str(self.zombie_time) + " " + alk) |
458 #------------------------[ END <AUTOKICK> TAG PROCESSING ]-------------- | 455 """------------------------[ END <AUTOKICK> TAG PROCESSING ]--------------""" |
459 | 456 |
460 | 457 |
461 | 458 """ |
462 #-------------------------------[ START <ROOM_DEFAULT> TAG PROCESSING ]-------------------- | 459 #-------------------------------[ START <ROOM_DEFAULT> TAG PROCESSING ]-------------------- |
463 # | 460 # |
464 # New room_defaults configuration option used to set various defaults | 461 # New room_defaults configuration option used to set various defaults |
465 # for all user created rooms on the server. Incorporates akomans older | 462 # for all user created rooms on the server. Incorporates akomans older |
466 # default room message code (from above) --Snowdog 11/03 | 463 # default room message code (from above) --Snowdog 11/03 |
467 # | 464 # |
468 # option syntax | 465 # option syntax |
469 # <room_defaults passwords="yes" map="myfiles/LobbyMap.xml" message="myfiles/LobbyMessage.html" /> | 466 # <room_defaults passwords="yes" map="myfiles/LobbyMap.xml" message="myfiles/LobbyMessage.html" /> |
467 """ | |
470 | 468 |
471 #default settings for tag options... | 469 #default settings for tag options... |
472 roomdefault_msg = str(self.defaultMessageFile) #no message is the default | 470 roomdefault_msg = str(self.defaultMessageFile) #no message is the default |
473 roomdefault_map = "" #use lobby map as default | 471 roomdefault_map = "" #use lobby map as default |
474 roomdefault_pass = 1 #allow passwords | 472 roomdefault_pass = 1 #allow passwords |
491 setting = roomdefaults.getElementsByTagName('map')[0] | 489 setting = roomdefaults.getElementsByTagName('map')[0] |
492 map = setting.getAttribute('file') | 490 map = setting.getAttribute('file') |
493 if map != "": | 491 if map != "": |
494 roomdefault_map = self.userPath + map.replace("myfiles/", "") | 492 roomdefault_map = self.userPath + map.replace("myfiles/", "") |
495 self.log_msg("Room Defaults: Using " + str(map) + " for room map") | 493 self.log_msg("Room Defaults: Using " + str(map) + " for room map") |
496 except: | 494 except: self.log_msg("Room Defaults: [Warning] Using Default Map") |
497 self.log_msg("Room Defaults: [Warning] Using Default Map") | |
498 | 495 |
499 try: | 496 try: |
500 setting = roomdefaults.getElementsByTagName('message')[0] | 497 setting = roomdefaults.getElementsByTagName('message')[0] |
501 msg = setting.getAttribute('file') | 498 msg = setting.getAttribute('file') |
502 if msg != "": | 499 if msg != "": |
506 except: print ("Room Defaults: [Warning] Using Default Message") | 503 except: print ("Room Defaults: [Warning] Using Default Message") |
507 except: | 504 except: |
508 traceback.print_exc() | 505 traceback.print_exc() |
509 self.log_msg("**WARNING** Error loading default room settings from configuration file. Using internal defaults.") | 506 self.log_msg("**WARNING** Error loading default room settings from configuration file. Using internal defaults.") |
510 | 507 |
511 | |
512 #set the defaults | 508 #set the defaults |
513 if roomdefault_msg != "" or roomdefault_msg != None: | 509 if roomdefault_msg != "" or roomdefault_msg != None: |
514 self.defaultMessageFile = roomdefault_msg #<room_defaults> tag superceeds older <newrooms> tag | 510 self.defaultMessageFile = roomdefault_msg #<room_defaults> tag superceeds older <newrooms> tag |
515 else: self.defaultMessageFile = None | 511 else: self.defaultMessageFile = None |
516 | |
517 if roomdefault_map != "" or roomdefault_map != None: | 512 if roomdefault_map != "" or roomdefault_map != None: |
518 self.defaultMapFile = roomdefault_map #<room_defaults> tag superceeds older <newrooms> tag | 513 self.defaultMapFile = roomdefault_map #<room_defaults> tag superceeds older <newrooms> tag |
519 else: self.defaultMapFile = None | 514 else: self.defaultMapFile = None |
520 | 515 |
521 ##### room default map not handled yet. SETTING IGNORED | 516 ##### room default map not handled yet. SETTING IGNORED |
522 if roomdefault_pass == 0: self.allow_room_passwords = 0 | 517 if roomdefault_pass == 0: self.allow_room_passwords = 0 |
523 else: self.allow_room_passwords = 1 | 518 else: self.allow_room_passwords = 1 |
524 | 519 """-------------------------------[ END <ROOM_DEFAULT> TAG PROCESSING ]--------------------""" |
525 #-------------------------------[ END <ROOM_DEFAULT> TAG PROCESSING ]-------------------- | |
526 | |
527 | 520 |
528 ###Server Cheat message | 521 ###Server Cheat message |
529 try: | 522 try: |
530 cheat_node = self.configDoc.getElementsByTagName("cheat")[0] | 523 cheat_node = self.configDoc.getElementsByTagName("cheat")[0] |
531 self.cheat_msg = cheat_node.getAttribute("text") | 524 self.cheat_msg = cheat_node.getAttribute("text") |
532 except: | 525 except: |
533 self.cheat_msg = "**FAKE ROLL**" | 526 self.cheat_msg = "**FAKE ROLL**" |
534 self.log_msg("**WARNING** <cheat txt=\"\"> tag missing from server configuration file. Using empty string.") | 527 self.log_msg("**WARNING** <cheat txt=\"\"> tag missing from server configuration file. Using empty string.") |
535 | 528 |
536 | |
537 | |
538 # should validate protocal | 529 # should validate protocal |
539 validate_protocol_node = self.configDom.getElementsByTagName("validate_protocol ") | 530 validate_protocol_node = self.configDom.getElementsByTagName("validate_protocol ") |
540 | |
541 self.validate_protocol = 1 | 531 self.validate_protocol = 1 |
542 | |
543 if(validate_protocol_node): self.validate_protocol = (validate_protocol_node[0].getAttribute("value") == "True") | 532 if(validate_protocol_node): self.validate_protocol = (validate_protocol_node[0].getAttribute("value") == "True") |
544 if(self.validate_protocol != 1): self.log_msg("Protocol Validation: OFF") | 533 if(self.validate_protocol != 1): self.log_msg("Protocol Validation: OFF") |
545 self.makePersistentRooms() | 534 self.makePersistentRooms() |
546 | |
547 self.log_msg("Server Configuration File: Processing Completed.") | 535 self.log_msg("Server Configuration File: Processing Completed.") |
548 | |
549 except Exception, e: | 536 except Exception, e: |
550 traceback.print_exc() | 537 traceback.print_exc() |
551 self.log_msg("Exception in initServerConfig() " + str(e)) | 538 self.log_msg("Exception in initServerConfig() " + str(e)) |
552 | 539 |
553 | |
554 def makePersistentRooms(self): | 540 def makePersistentRooms(self): |
555 'Creates rooms on the server as defined in the server config file.' | 541 'Creates rooms on the server as defined in the server config file.' |
556 | |
557 for element in self.configDom.getElementsByTagName('room'): | 542 for element in self.configDom.getElementsByTagName('room'): |
558 roomName = element.getAttribute('name') | 543 roomName = element.getAttribute('name') |
559 roomPassword = element.getAttribute('password') | 544 roomPassword = element.getAttribute('password') |
560 bootPassword = element.getAttribute('boot') | 545 bootPassword = element.getAttribute('boot') |
561 | 546 |
565 | 550 |
566 # Extract the map filename attribute from the map node | 551 # Extract the map filename attribute from the map node |
567 # we only care about the first map element found -- others are ignored | 552 # we only care about the first map element found -- others are ignored |
568 mapElement = element.getElementsByTagName('map')[0] | 553 mapElement = element.getElementsByTagName('map')[0] |
569 mapFile = self.userPath + mapElement.getAttribute('file').replace("myfiles/", "") | 554 mapFile = self.userPath + mapElement.getAttribute('file').replace("myfiles/", "") |
570 | |
571 messageElement = element.getElementsByTagName('message')[0] | 555 messageElement = element.getElementsByTagName('message')[0] |
572 messageFile = messageElement.getAttribute('file') | 556 messageFile = messageElement.getAttribute('file') |
573 | |
574 if messageFile[:4] != 'http': messageFile = self.userPath + messageFile.replace("myfiles/", "") | 557 if messageFile[:4] != 'http': messageFile = self.userPath + messageFile.replace("myfiles/", "") |
575 | 558 |
576 # Make sure we have a message to even mess with | 559 # Make sure we have a message to even mess with |
577 if(len(messageFile) == 0): messageFile = self.defaultMessageFile | 560 if(len(messageFile) == 0): messageFile = self.defaultMessageFile |
578 | |
579 if(len(mapFile) == 0): mapFile = self.defaultMapFile | 561 if(len(mapFile) == 0): mapFile = self.defaultMapFile |
580 | |
581 moderated = 0 | 562 moderated = 0 |
582 if element.hasAttribute('moderated') and element.getAttribute('moderated').lower() == "true": moderated = 1 | 563 if element.hasAttribute('moderated') and element.getAttribute('moderated').lower() == "true": moderated = 1 |
583 | 564 |
584 #create the new persistant group | 565 #create the new persistant group |
585 self.new_group(roomName, roomPassword, bootPassword, minVersion, mapFile, messageFile, persist = 1, moderated=moderated) | 566 self.new_group(roomName, roomPassword, |
586 | 567 bootPassword, minVersion, mapFile, |
587 | 568 messageFile, persist = 1, moderated=moderated) |
588 | 569 |
589 def isPersistentRoom(self, id): | 570 def isPersistentRoom(self, id): |
590 'Returns True if the id is a persistent room (other than the lobby), otherwise, False.' | 571 'Returns True if the id is a persistent room (other than the lobby), otherwise, False.' |
591 | 572 """ |
592 # altered persistance tracking from simple room id based to per-group setting | 573 # altered persistance tracking from simple room id based to per-group setting |
593 # allows arbitrary rooms to be marked as persistant without needing the self.persistRoomThreshold | 574 # allows arbitrary rooms to be marked as persistant without needing the self.persistRoomThreshold |
594 # -- Snowdog 4/04 | 575 # -- Snowdog 4/04 |
576 """ | |
595 try: | 577 try: |
596 id = str(id) #just in case someone sends an int instead of a str into the function | 578 id = str(id) #just in case someone sends an int instead of a str into the function |
597 if id not in self.groups: return 0 #invalid room, can't be persistant | 579 if id not in self.groups: return 0 #invalid room, can't be persistant |
598 pr = (self.groups[id]).persistant | 580 pr = (self.groups[id]).persistant |
599 return pr | 581 return pr |
600 except: | 582 except: |
601 self.log_msg("Exception occured in isPersistentRoom(self,id)") | 583 self.log_msg("Exception occured in isPersistentRoom(self,id)") |
602 return 0 | 584 return 0 |
603 | |
604 | |
605 | 585 |
606 #----------------------------------------------------- | 586 #----------------------------------------------------- |
607 # Toggle Meta Logging -- Added by Snowdog 4/03 | 587 # Toggle Meta Logging -- Added by Snowdog 4/03 |
608 #----------------------------------------------------- | 588 #----------------------------------------------------- |
609 def toggleMetaLogging(self): | 589 def toggleMetaLogging(self): |
631 else: return | 611 else: return |
632 #when log mode changes update all connection stubs | 612 #when log mode changes update all connection stubs |
633 for n in self.players: | 613 for n in self.players: |
634 try: self.players[n].EnableMessageLogging = mode | 614 try: self.players[n].EnableMessageLogging = mode |
635 except: self.log_msg("Error changing Message Logging Mode for client #" + str(self.players[n].id)) | 615 except: self.log_msg("Error changing Message Logging Mode for client #" + str(self.players[n].id)) |
616 | |
636 def NetworkLoggingStatus(self): | 617 def NetworkLoggingStatus(self): |
637 if self.log_network_messages == 0: return "Network Traffic Log: Off" | 618 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)" | 619 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)" | 620 elif self.log_network_messages == 2: return "Network Traffic Log: Logging (inbound/outbound files)" |
640 else: self.log_msg("Network Traffic Log: [Unknown]") | 621 else: self.log_msg("Network Traffic Log: [Unknown]") |
641 | |
642 | |
643 | |
644 | 622 |
645 def register_callback(instance, xml_dom = None,source=None): | 623 def register_callback(instance, xml_dom = None,source=None): |
646 if xml_dom: # if we get something | 624 if xml_dom: # if we get something |
647 if source == getMetaServerBaseURL(): # if the source of this DOM is the authoritative meta | 625 if source == getMetaServerBaseURL(): # if the source of this DOM is the authoritative meta |
648 try: | 626 try: |
653 finally: | 631 finally: |
654 metacache_lock.release() | 632 metacache_lock.release() |
655 | 633 |
656 if newlist != curlist: # If the two lists aren't identical | 634 if newlist != curlist: # If the two lists aren't identical |
657 # then something has changed. | 635 # then something has changed. |
658 instance.register() # Call self.register() | 636 instance.register() # Call self.register() |
659 # which will force a re-read of the meta cache and | 637 # which will force a re-read of the meta cache and |
660 # redo the registerThreads | 638 # redo the registerThreads |
661 else: instance.register() | 639 else: instance.register() |
662 | 640 |
663 # Eventually, reset the MetaServerBaseURL here | 641 # Eventually, reset the MetaServerBaseURL here |
664 | 642 |
643 """ | |
665 ## Added to help clean up parser errors in the XML on clients | 644 ## Added to help clean up parser errors in the XML on clients |
666 ## due to characters that break welformedness of the XML from | 645 ## due to characters that break welformedness of the XML from |
667 ## the meta server. | 646 ## the meta server. |
668 ## NOTE: this is a stopgap measure -SD | 647 ## NOTE: this is a stopgap measure -SD |
648 """ | |
669 def clean_published_servername(self, name): | 649 def clean_published_servername(self, name): |
670 #clean name of all apostrophes and quotes | 650 #clean name of all apostrophes and quotes |
671 badchars = "\"\\`><" | 651 badchars = "\"\\`><" |
672 for c in badchars: name = name.replace(c,"") | 652 for c in badchars: name = name.replace(c,"") |
673 return name | 653 return name |
677 id = '0' | 657 id = '0' |
678 time.sleep(500) | 658 time.sleep(500) |
679 for rnum in self.groups.keys(): | 659 for rnum in self.groups.keys(): |
680 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][name]":self.groups[rnum].name, | 660 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][name]":self.groups[rnum].name, |
681 "room_data[rooms][" + str(rnum) + "][pwd]":str(self.groups[rnum].pwd != "")})+'&' | 661 "room_data[rooms][" + str(rnum) + "][pwd]":str(self.groups[rnum].pwd != "")})+'&' |
682 | |
683 for pid in self.groups[rnum].players: | 662 for pid in self.groups[rnum].players: |
684 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][players]["+str(pid)+"]":self.players[pid].name,})+'&' | 663 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][players]["+str(pid)+"]":self.players[pid].name,})+'&' |
685 | |
686 | |
687 for meta in self.metas.keys(): | 664 for meta in self.metas.keys(): |
688 while id == '0': | 665 while id == '0': |
689 id, cookie = self.metas[meta].getIdAndCookie() | 666 id, cookie = self.metas[meta].getIdAndCookie() |
690 data = urllib.urlencode( {"room_data[server_id]":id, | 667 data = urllib.urlencode( {"room_data[server_id]":id, |
691 "act":'registerrooms'}) | 668 "act":'registerrooms'}) |
692 get_server_dom(data+'&'+rooms, self.metas[meta].path) | 669 get_server_dom(data+'&'+rooms, self.metas[meta].path) |
693 | 670 |
694 | |
695 def register(self,name_given=None): | 671 def register(self,name_given=None): |
696 if name_given == None: name = self.name | 672 if name_given == None: name = self.name |
697 else: self.name = name = name_given | 673 else: self.name = name = name_given |
698 | |
699 name = self.clean_published_servername(name) | 674 name = self.clean_published_servername(name) |
700 | 675 |
701 # Set up the value for num_users | 676 # Set up the value for num_users |
702 if self.players: num_players = len(self.players) | 677 if self.players: num_players = len(self.players) |
703 else: num_players = 0 | 678 else: num_players = 0 |
706 metalist = getMetaServers(versions=["2"]) | 681 metalist = getMetaServers(versions=["2"]) |
707 if self.show_meta_messages != 0: | 682 if self.show_meta_messages != 0: |
708 self.log_msg("Found these valid metas:") | 683 self.log_msg("Found these valid metas:") |
709 for meta in metalist: self.log_msg("Meta:" + meta) | 684 for meta in metalist: self.log_msg("Meta:" + meta) |
710 | 685 |
686 """ | |
711 # Go through the list and see if there is already a running register | 687 # Go through the list and see if there is already a running register |
712 # thread for the meta. | 688 # thread for the meta. |
713 # If so, call it's register() method | 689 # If so, call it's register() method |
714 # If not, start one, implicitly calling the new thread's register() method | 690 # If not, start one, implicitly calling the new thread's register() method |
715 | 691 |
716 | |
717 # iterate through the currently running metas and prune any | 692 # iterate through the currently running metas and prune any |
718 # not currently listed in the Meta Server list. | 693 # not currently listed in the Meta Server list. |
694 """ | |
695 | |
719 if self.show_meta_messages != 0: self.log_msg( "Checking running register threads for outdated metas.") | 696 if self.show_meta_messages != 0: self.log_msg( "Checking running register threads for outdated metas.") |
720 for meta in self.metas.keys(): | 697 for meta in self.metas.keys(): |
721 if self.show_meta_messages != 0: self.log_msg("meta:" + meta + ": ") | 698 if self.show_meta_messages != 0: self.log_msg("meta:" + meta + ": ") |
722 if not meta in metalist: # if the meta entry running is not in the list | 699 if not meta in metalist: # if the meta entry running is not in the list |
723 if self.show_meta_messages != 0: self.log_msg( "Outdated. Unregistering and removing") | 700 if self.show_meta_messages != 0: self.log_msg( "Outdated. Unregistering and removing") |
727 if self.show_meta_messages != 0: self.log_msg( "Found in current meta list. Leaving intact.") | 704 if self.show_meta_messages != 0: self.log_msg( "Found in current meta list. Leaving intact.") |
728 | 705 |
729 # Now call register() for alive metas or start one if we need one | 706 # Now call register() for alive metas or start one if we need one |
730 for meta in metalist: | 707 for meta in metalist: |
731 if self.metas.has_key(meta) and self.metas[meta] and self.metas[meta].isAlive(): | 708 if self.metas.has_key(meta) and self.metas[meta] and self.metas[meta].isAlive(): |
732 self.metas[meta].register(name=name, realHostName=self.server_address, num_users=num_players) | 709 self.metas[meta].register(name=name, |
710 realHostName=self.server_address, | |
711 num_users=num_players) | |
733 else: | 712 else: |
734 self.metas[meta] = registerThread(name=name, realHostName=self.server_address, num_users=num_players, MetaPath=meta, port=self.server_port,register_callback=self.register_callback) | 713 self.metas[meta] = registerThread(name=name, realHostName=self.server_address, |
714 num_users=num_players, MetaPath=meta, port=self.server_port, | |
715 register_callback=self.register_callback) | |
735 self.metas[meta].start() | 716 self.metas[meta].start() |
736 | 717 |
737 #The register Rooms thread | 718 #The register Rooms thread |
738 | |
739 self.be_registered = 1 | 719 self.be_registered = 1 |
740 thread.start_new_thread(self.registerRooms,(0,)) | 720 thread.start_new_thread(self.registerRooms,(0,)) |
741 | 721 |
742 | |
743 | |
744 def unregister(self): | 722 def unregister(self): |
723 """ | |
745 # loop through all existing meta entries | 724 # loop through all existing meta entries |
746 # Don't rely on getMetaServers(), as a server may have been | 725 # Don't rely on getMetaServers(), as a server may have been |
747 # removed since it was started. In that case, then the meta | 726 # removed since it was started. In that case, then the meta |
748 # would never get unregistered. | 727 # would never get unregistered. |
749 # | 728 # |
750 # Instead, loop through all existing meta threads and unregister them | 729 # Instead, loop through all existing meta threads and unregister them |
730 """ | |
751 | 731 |
752 for meta in self.metas.values(): | 732 for meta in self.metas.values(): |
753 if meta and meta.isAlive(): meta.unregister() | 733 if meta and meta.isAlive(): meta.unregister() |
754 self.be_registered = 0 | 734 self.be_registered = 0 |
755 | 735 |
736 """ | |
756 # This method runs as it's own thread and does the group_member_check every | 737 # This method runs as it's own thread and does the group_member_check every |
757 # sixty seconds. This should eliminate zombies that linger when no one is | 738 # sixty seconds. This should eliminate zombies that linger when no one is |
758 # around to spook them. GC: Frequency has been reduced as I question how valid | 739 # around to spook them. GC: Frequency has been reduced as I question how valid |
759 # the implementation is as it will only catch a very small segment of lingering | 740 # the implementation is as it will only catch a very small segment of lingering |
760 # connections. | 741 # connections. |
742 """ | |
761 def player_reaper_thread_func(self,arg): | 743 def player_reaper_thread_func(self,arg): |
762 while self.alive: | 744 while self.alive: |
763 time.sleep(60) | 745 time.sleep(60) |
764 | |
765 self.p_lock.acquire() | 746 self.p_lock.acquire() |
766 for group in self.groups.keys(): self.check_group_members(group) | 747 for group in self.groups.keys(): self.check_group_members(group) |
767 self.p_lock.release() | 748 self.p_lock.release() |
768 | 749 |
769 #This thread runs ever 250 miliseconds, and checks various plugin stuff | 750 #This thread runs ever 250 miliseconds, and checks various plugin stuff |
770 def PluginThread(self): | 751 def PluginThread(self): |
771 while self.alive: | 752 while self.alive: |
772 self.p_lock.acquire() | 753 self.p_lock.acquire() |
773 players = ServerPlugins.getPlayer() | 754 players = ServerPlugins.getPlayer() |
774 | |
775 for player in players: | 755 for player in players: |
776 if player is not None: pass #Do something here so they can show up in the chat room for non web users' | 756 if player is not None: pass #Do something here so they can show up in the chat room for non web users' |
777 data = ServerPlugins.preParseOutgoing() | 757 data = ServerPlugins.preParseOutgoing() |
778 for msg in data: | 758 for msg in data: |
779 try: | 759 try: |
780 xml_dom = parseXml(msg) | 760 xml_dom = parseXml(msg) |
781 xml_dom = xml_dom._get_documentElement() | 761 xml_dom = xml_dom._get_documentElement() |
782 | |
783 if xml_dom.hasAttribute('from') and int(xml_dom.getAttribute('from')) > -1: | 762 if xml_dom.hasAttribute('from') and int(xml_dom.getAttribute('from')) > -1: |
784 xml_dom.setAttribute('from', '-1') | 763 xml_dom.setAttribute('from', '-1') |
785 | |
786 xml_dom.setAttribute('to', 'all') | 764 xml_dom.setAttribute('to', 'all') |
787 self.incoming_msg_handler(xml_dom, msg) | 765 self.incoming_msg_handler(xml_dom, msg) |
788 xml_dom.unlink() | 766 xml_dom.unlink() |
789 except: pass | 767 except: pass |
790 | |
791 self.p_lock.release() | 768 self.p_lock.release() |
792 time.sleep(0.250) | 769 time.sleep(0.250) |
793 | |
794 | 770 |
795 def sendMsg( self, sock, msg, useCompression=False, cmpType=None): | 771 def sendMsg( self, sock, msg, useCompression=False, cmpType=None): |
796 """Very simple function that will properly encode and send a message to te | 772 """Very simple function that will properly encode and send a message to te |
797 remote on the specified socket.""" | 773 remote on the specified socket.""" |
798 | |
799 if useCompression and cmpType != None: | 774 if useCompression and cmpType != None: |
800 mpacket = cmpType.compress(msg) | 775 mpacket = cmpType.compress(msg) |
801 lpacket = pack('!i', len(mpacket)) | 776 lpacket = pack('!i', len(mpacket)) |
802 sock.send(lpacket) | 777 sock.send(lpacket) |
803 | |
804 offset = 0 | 778 offset = 0 |
805 while offset < len(mpacket): | 779 while offset < len(mpacket): |
806 slice = buffer(mpacket, offset, len(mpacket)-offset) | 780 slice = buffer(mpacket, offset, len(mpacket)-offset) |
807 sent = sock.send(slice) | 781 sent = sock.send(slice) |
808 offset += sent | 782 offset += sent |
819 | 793 |
820 def recvData( self, sock, readSize ): | 794 def recvData( self, sock, readSize ): |
821 """Simple socket receive method. This method will only return when the exact | 795 """Simple socket receive method. This method will only return when the exact |
822 byte count has been read from the connection, if remote terminates our | 796 byte count has been read from the connection, if remote terminates our |
823 connection or we get some other socket exception.""" | 797 connection or we get some other socket exception.""" |
824 | |
825 data = "" | 798 data = "" |
826 offset = 0 | 799 offset = 0 |
827 try: | 800 try: |
828 while offset != readSize: | 801 while offset != readSize: |
829 frag = sock.recv( readSize - offset ) | 802 frag = sock.recv( readSize - offset ) |
832 # Loudly raise an exception because we've been disconnected! | 805 # Loudly raise an exception because we've been disconnected! |
833 raise IOError, "Remote closed the connection!" | 806 raise IOError, "Remote closed the connection!" |
834 else: # Continue to build complete message | 807 else: # Continue to build complete message |
835 offset += rs | 808 offset += rs |
836 data += frag | 809 data += frag |
837 | |
838 except socket.error, e: | 810 except socket.error, e: |
839 self.log_msg("Socket Error: recvData(): " + e ) | 811 self.log_msg("Socket Error: recvData(): " + e ) |
840 data = "" | 812 data = "" |
841 return data | 813 return data |
842 | 814 |
851 with the OS until we attempt to read the next complete message.""" | 823 with the OS until we attempt to read the next complete message.""" |
852 | 824 |
853 msgData = "" | 825 msgData = "" |
854 try: | 826 try: |
855 lenData = self.recvData( sock, MPLAY_LENSIZE ) | 827 lenData = self.recvData( sock, MPLAY_LENSIZE ) |
856 # Now, convert to a usable form | 828 (length,) = unpack('!i', lenData) # Now, convert to a usable form |
857 (length,) = unpack('!i', lenData) | 829 msgData = self.recvData( sock, length ) # Read exactly the remaining amount of data |
858 # Read exactly the remaining amount of data | |
859 msgData = self.recvData( sock, length ) | |
860 try: | 830 try: |
861 if useCompression and cmpType != None: msgData = cmpType.decompress(msgData) | 831 if useCompression and cmpType != None: msgData = cmpType.decompress(msgData) |
862 except: traceback.print_exc() | 832 except: traceback.print_exc() |
863 | |
864 except Exception, e: self.log_msg( "Exception: recvMsg(): " + str(e) ) | 833 except Exception, e: self.log_msg( "Exception: recvMsg(): " + str(e) ) |
865 return msgData | 834 return msgData |
866 | |
867 | 835 |
868 def kill_server(self): | 836 def kill_server(self): |
869 self.alive = 0 | 837 self.alive = 0 |
870 self.log_msg("Server stopping...") | 838 self.log_msg("Server stopping...") |
871 self.unregister() # unregister from the Meta | 839 self.unregister() # unregister from the Meta |
872 for p in self.players.itervalues(): | 840 for p in self.players.itervalues(): |
873 p.disconnect() | 841 p.disconnect() |
874 self.incoming.put("<system/>") | 842 self.incoming.put("<system/>") |
875 | |
876 for g in self.groups.itervalues(): | 843 for g in self.groups.itervalues(): |
877 g.save_map() | 844 g.save_map() |
878 | |
879 try: | 845 try: |
880 ip = socket.gethostbyname(socket.gethostname()) | 846 ip = socket.gethostbyname(socket.gethostname()) |
881 kill = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 847 kill = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
882 kill.connect((ip, self.server_port)) | 848 kill.connect((ip, self.server_port)) |
883 | 849 |
890 self.listen_sock.close() | 856 self.listen_sock.close() |
891 self.listen_event.wait(10) | 857 self.listen_event.wait(10) |
892 self.incoming_event.wait(10) | 858 self.incoming_event.wait(10) |
893 self.log_msg("Server stopped!") | 859 self.log_msg("Server stopped!") |
894 | 860 |
895 | |
896 | |
897 def log_msg(self,msg): | 861 def log_msg(self,msg): |
898 if self.log_to_console: | 862 if self.log_to_console: |
899 if self.log_console: | 863 if self.log_console: self.log_console(msg) |
900 self.log_console(msg) | 864 else: print str(msg) |
901 else: | |
902 print str(msg) | |
903 | |
904 | 865 |
905 def print_help(self): | 866 def print_help(self): |
906 print | 867 print |
907 print "Commands: " | 868 print "Commands: " |
908 print "'kill' or 'quit' - to stop the server" | 869 print "'kill' or 'quit' - to stop the server" |
935 print "'togglelobbysound' - Will turn on or off the Auto sending of a sound to all players who join the loby" | 896 print "'togglelobbysound' - Will turn on or off the Auto sending of a sound to all players who join the loby" |
936 print "'lobbysound' - Lets you specify which sound file to send to players joining the lobby" | 897 print "'lobbysound' - Lets you specify which sound file to send to players joining the lobby" |
937 print "'help' or '?' or 'h' - for this help message" | 898 print "'help' or '?' or 'h' - for this help message" |
938 print | 899 print |
939 | 900 |
940 | |
941 def broadcast(self,msg): | 901 def broadcast(self,msg): |
942 self.send_to_all("0","<msg to='all' from='0' group_id='1'><font color='#FF0000'>" + msg + "</font>") | 902 self.send_to_all("0","<msg to='all' from='0' group_id='1'><font color='#FF0000'>" + msg + "</font>") |
943 | |
944 | 903 |
945 def console_log(self): | 904 def console_log(self): |
946 if self.log_to_console == 1: | 905 if self.log_to_console == 1: |
947 print "console logging now off" | 906 print "console logging now off" |
948 self.log_to_console = 0 | 907 self.log_to_console = 0 |
949 else: | 908 else: |
950 print "console logging now on" | 909 print "console logging now on" |
951 self.log_to_console = 1 | 910 self.log_to_console = 1 |
952 | 911 |
953 | |
954 def groups_list(self): | 912 def groups_list(self): |
955 self.p_lock.acquire() | 913 self.p_lock.acquire() |
956 try: | 914 try: |
957 keys = self.groups.keys() | 915 keys = self.groups.keys() |
958 for k in keys: | 916 for k in keys: |
959 pw = "-" | 917 pw = "-" |
960 pr = " -" | 918 pr = " -" |
961 if self.groups[k].pwd != "": | 919 if self.groups[k].pwd != "": pw = "P" |
962 pw = "P" | 920 if self.isPersistentRoom( k ): pr = " S" #using S for static (P for persistant conflicts with password) |
963 if self.isPersistentRoom( k ): | |
964 pr = " S" #using S for static (P for persistant conflicts with password) | |
965 print "Group: " + k + pr + pw + ' Name: ' + self.groups[k].name | 921 print "Group: " + k + pr + pw + ' Name: ' + self.groups[k].name |
966 print | 922 print |
967 | |
968 except Exception, e: | 923 except Exception, e: |
969 self.log_msg(str(e)) | 924 self.log_msg(str(e)) |
970 | |
971 self.p_lock.release() | 925 self.p_lock.release() |
972 | 926 |
973 #---------------------------------------------------------------- | 927 """ |
974 # Monitor Function -- Added by snowdog 2/05 | 928 #---------------------------------------------------------------- |
975 #---------------------------------------------------------------- | 929 # Monitor Function -- Added by snowdog 2/05 |
930 #---------------------------------------------------------------- | |
931 """ | |
976 def monitor(self, pid, mode=1 ): | 932 def monitor(self, pid, mode=1 ): |
977 "allows monitoring of a specific user(s) network i/o" | 933 "allows monitoring of a specific user(s) network i/o" |
978 #if mode is not set to 1 then monitor adds toggles the state | 934 #if mode is not set to 1 then monitor adds toggles the state |
979 #of monitoring on the given user | 935 #of monitoring on the given user |
980 | |
981 if (mode == 1): | 936 if (mode == 1): |
982 for p in self.players: | 937 for p in self.players: |
983 try: p.monitor("off") | 938 try: p.monitor("off") |
984 except: pass | 939 except: pass |
985 try: | 940 try: |
986 r = (self.players[pid]).set_traffic_monitor("toggle") | 941 r = (self.players[pid]).set_traffic_monitor("toggle") |
987 self.log_msg("Monitor: Mode=" + str(r) + " on Player #" + str(pid)) | 942 self.log_msg("Monitor: Mode=" + str(r) + " on Player #" + str(pid)) |
988 except: | 943 except: |
989 self.log_msg("Monitor: Invalid Player ID") | 944 self.log_msg("Monitor: Invalid Player ID") |
990 traceback.print_exc() | 945 traceback.print_exc() |
991 | |
992 | 946 |
993 def search(self,patern): | 947 def search(self,patern): |
994 keys = self.groups.keys() | 948 keys = self.groups.keys() |
995 print "Search results:" | 949 print "Search results:" |
996 for k in keys: | 950 for k in keys: |
997 ids = self.groups[k].get_player_ids() | 951 ids = self.groups[k].get_player_ids() |
998 for id in ids: | 952 for id in ids: |
999 if self.players[id].id.find(patern)>-1: | 953 if self.players[id].id.find(patern)>-1: self.print_player_info(self.players[id]) |
1000 self.print_player_info(self.players[id]) | 954 elif self.players[id].name.find(patern)>-1: self.print_player_info(self.players[id]) |
1001 | 955 elif self.players[id].ip.find(patern)>-1: self.print_player_info(self.players[id]) |
1002 elif self.players[id].name.find(patern)>-1: | 956 elif self.players[id].group_id.find(patern)>-1: self.print_player_info(self.players[id]) |
1003 self.print_player_info(self.players[id]) | 957 elif self.players[id].role.find(patern)>-1: self.print_player_info(self.players[id]) |
1004 | 958 elif self.players[id].version.find(patern)>-1: self.print_player_info(self.players[id]) |
1005 elif self.players[id].ip.find(patern)>-1: | 959 elif self.players[id].protocol_version.find(patern)>-1: self.print_player_info(self.players[id]) |
1006 self.print_player_info(self.players[id]) | 960 elif self.players[id].client_string.find(patern)>-1: self.print_player_info(self.players[id]) |
1007 | |
1008 elif self.players[id].group_id.find(patern)>-1: | |
1009 self.print_player_info(self.players[id]) | |
1010 | |
1011 elif self.players[id].role.find(patern)>-1: | |
1012 self.print_player_info(self.players[id]) | |
1013 | |
1014 elif self.players[id].version.find(patern)>-1: | |
1015 self.print_player_info(self.players[id]) | |
1016 | |
1017 elif self.players[id].protocol_version.find(patern)>-1: | |
1018 self.print_player_info(self.players[id]) | |
1019 | |
1020 elif self.players[id].client_string.find(patern)>-1: | |
1021 self.print_player_info(self.players[id]) | |
1022 | |
1023 | 961 |
1024 def print_player_info(self,player): | 962 def print_player_info(self,player): |
1025 print player.id,player.name,player.ip,player.group_id, player.role,player.version,player.protocol_version,player.client_string | 963 print player.id, player.name, player.ip, player.group_id, player.role, player.version, player.protocol_version, player.client_string |
1026 | 964 |
965 """ | |
1027 #---------------------------------------------------------------- | 966 #---------------------------------------------------------------- |
1028 # Uptime Function -- Added by snowdog 4/03 | 967 # Uptime Function -- Added by snowdog 4/03 |
1029 #---------------------------------------------------------------- | 968 #---------------------------------------------------------------- |
969 """ | |
1030 def uptime(self , mode = 0): | 970 def uptime(self , mode = 0): |
1031 "returns string containing how long server has been in operation" | 971 "returns string containing how long server has been in operation" |
1032 ut = time.time() - self.server_start_time | 972 ut = time.time() - self.server_start_time |
1033 d = int(ut/86400) | 973 d = int(ut/86400) |
1034 h = int( (ut-(86400*d))/3600 ) | 974 h = int( (ut-(86400*d))/3600 ) |
1036 s = int( (ut-(86400*d)-(3600*h)-(60*m)) ) | 976 s = int( (ut-(86400*d)-(3600*h)-(60*m)) ) |
1037 uts = str( "This server has been running for:\n " + str(d) + " days " + str(h) + " hours " + str(m) + " min. " + str(s) + " sec. [" + str(int(ut)) + " seconds]") | 977 uts = str( "This server has been running for:\n " + str(d) + " days " + str(h) + " hours " + str(m) + " min. " + str(s) + " sec. [" + str(int(ut)) + " seconds]") |
1038 if mode == 0: print uts | 978 if mode == 0: print uts |
1039 else: return uts | 979 else: return uts |
1040 | 980 |
981 """ | |
1041 #----------------------------------------------------- | 982 #----------------------------------------------------- |
1042 # Toggle Room Password Allow -- Added by Snowdog 11/03 | 983 # Toggle Room Password Allow -- Added by Snowdog 11/03 |
1043 #----------------------------------------------------- | 984 #----------------------------------------------------- |
985 """ | |
1044 def RoomPasswords(self): | 986 def RoomPasswords(self): |
1045 if self.allow_room_passwords != 0: | 987 if self.allow_room_passwords != 0: |
1046 self.allow_room_passwords = 0 | 988 self.allow_room_passwords = 0 |
1047 return "Client Created Room Passwords: Disallowed" | 989 return "Client Created Room Passwords: Disallowed" |
1048 else: | 990 else: |
1049 self.allow_room_passwords = 1 | 991 self.allow_room_passwords = 1 |
1050 return "Client Created Room Passwords: Allowed" | 992 return "Client Created Room Passwords: Allowed" |
1051 | |
1052 | 993 |
1053 def group_dump(self,k): | 994 def group_dump(self,k): |
1054 self.p_lock.acquire() | 995 self.p_lock.acquire() |
1055 try: | 996 try: |
1056 print "Group: " + k | 997 print "Group: " + k |
1063 print | 1004 print |
1064 except Exception, e: | 1005 except Exception, e: |
1065 self.log_msg(str(e)) | 1006 self.log_msg(str(e)) |
1066 self.p_lock.release() | 1007 self.p_lock.release() |
1067 | 1008 |
1009 """ | |
1068 #---------------------------------------------------------------- | 1010 #---------------------------------------------------------------- |
1069 # Player List -- Added by snowdog 4/03 | 1011 # Player List -- Added by snowdog 4/03 |
1070 #---------------------------------------------------------------- | 1012 #---------------------------------------------------------------- |
1013 """ | |
1071 def player_list(self): | 1014 def player_list(self): |
1072 "display a condensed list of players on the server" | 1015 "display a condensed list of players on the server" |
1073 self.p_lock.acquire() | 1016 self.p_lock.acquire() |
1074 try: | 1017 try: |
1075 print "------------[ PLAYER LIST ]------------" | 1018 print "------------[ PLAYER LIST ]------------" |
1100 self.p_lock.acquire() | 1043 self.p_lock.acquire() |
1101 try: | 1044 try: |
1102 keys = self.groups.keys() | 1045 keys = self.groups.keys() |
1103 for k in keys: | 1046 for k in keys: |
1104 print "Group: %s %s (pass: \"%s\")" % (str(k),self.groups[k].name, self.groups[k].pwd) | 1047 print "Group: %s %s (pass: \"%s\")" % (str(k),self.groups[k].name, self.groups[k].pwd) |
1105 | |
1106 ids = self.groups[k].get_player_ids() | 1048 ids = self.groups[k].get_player_ids() |
1107 for id in ids: | 1049 for id in ids: |
1108 if self.players.has_key(id): | 1050 if self.players.has_key(id): print str(self.players[id]) |
1109 print str(self.players[id]) | |
1110 else: | 1051 else: |
1111 self.groups[k].remove_player(id) | 1052 self.groups[k].remove_player(id) |
1112 print "Bad Player Ref (#" + id + ") in group" | 1053 print "Bad Player Ref (#" + id + ") in group" |
1113 except Exception, e: | 1054 except Exception, e: |
1114 self.log_msg(str(e)) | 1055 self.log_msg(str(e)) |
1115 | |
1116 self.p_lock.release() | 1056 self.p_lock.release() |
1117 | |
1118 | 1057 |
1119 def update_request(self,newsock,xml_dom): | 1058 def update_request(self,newsock,xml_dom): |
1120 # handle reconnects | 1059 # handle reconnects |
1121 | |
1122 self.log_msg( "update_request() has been called." ) | 1060 self.log_msg( "update_request() has been called." ) |
1123 | 1061 |
1124 # get player id | 1062 # get player id |
1125 id = xml_dom.getAttribute("id") | 1063 id = xml_dom.getAttribute("id") |
1126 group_id = xml_dom.getAttribute("group_id") | 1064 group_id = xml_dom.getAttribute("group_id") |
1127 | |
1128 self.p_lock.acquire() | 1065 self.p_lock.acquire() |
1129 if self.players.has_key(id): | 1066 if self.players.has_key(id): |
1130 self.sendMsg( newsock, self.players[id].toxml("update"), self.players[id].useCompression, self.players[id].compressionType ) | 1067 self.sendMsg(newsock, self.players[id].toxml("update"), |
1068 self.players[id].useCompression, | |
1069 self.players[id].compressionType ) | |
1131 self.players[id].reset(newsock) | 1070 self.players[id].reset(newsock) |
1132 self.players[id].clear_timeout() | 1071 self.players[id].clear_timeout() |
1133 need_new = 0 | 1072 need_new = 0 |
1134 else: | 1073 else: need_new = 1 |
1135 need_new = 1 | |
1136 self.p_lock.release() | 1074 self.p_lock.release() |
1137 | 1075 if need_new: self.new_request(newsock,xml_dom) |
1138 if need_new: | |
1139 self.new_request(newsock,xml_dom) | |
1140 else: | 1076 else: |
1141 msg = self.groups[group_id].game_map.get_all_xml() | 1077 msg = self.groups[group_id].game_map.get_all_xml() |
1142 self.send(msg,id,group_id) | 1078 self.send(msg,id,group_id) |
1143 | |
1144 | 1079 |
1145 def new_request(self,newsock,xml_dom,LOBBY_ID='0'): | 1080 def new_request(self,newsock,xml_dom,LOBBY_ID='0'): |
1146 #build client stub | 1081 #build client stub |
1147 props = {} | 1082 props = {} |
1148 # Don't trust what the client tells us...trust what they connected as! | 1083 # Don't trust what the client tells us...trust what they connected as! |
1149 props['ip'] = socket.gethostbyname( newsock.getpeername()[0] ) | 1084 props['ip'] = socket.gethostbyname( newsock.getpeername()[0] ) |
1150 | 1085 |
1151 try: | 1086 try: props['role'] = xml_dom.getAttribute("role") |
1152 props['role'] = xml_dom.getAttribute("role") | 1087 except: props['role'] = "GM" |
1153 except: | |
1154 props['role'] = "GM" | |
1155 | 1088 |
1156 props['name'] = xml_dom.getAttribute("name") | 1089 props['name'] = xml_dom.getAttribute("name") |
1157 props['group_id'] = LOBBY_ID | 1090 props['group_id'] = LOBBY_ID |
1158 props['id'] = str(self.next_player_id) | 1091 props['id'] = str(self.next_player_id) |
1159 props['version'] = xml_dom.getAttribute("version") | 1092 props['version'] = xml_dom.getAttribute("version") |
1160 props['protocol_version'] = xml_dom.getAttribute("protocol_version") | 1093 props['protocol_version'] = xml_dom.getAttribute("protocol_version") |
1161 props['client_string'] = xml_dom.getAttribute("client_string") | 1094 props['client_string'] = xml_dom.getAttribute("client_string") |
1095 | |
1162 self.next_player_id += 1 | 1096 self.next_player_id += 1 |
1163 new_stub = client_stub(self.incoming,newsock,props,self.log_console) | 1097 new_stub = client_stub(self.incoming,newsock,props,self.log_console) |
1164 if xml_dom.hasAttribute('useCompression'): | 1098 if xml_dom.hasAttribute('useCompression'): |
1165 new_stub.useCompression = True | 1099 new_stub.useCompression = True |
1166 | |
1167 if xml_dom.hasAttribute('cmpType'): | 1100 if xml_dom.hasAttribute('cmpType'): |
1168 cmpType = xml_dom.getAttribute('cmpType') | 1101 cmpType = xml_dom.getAttribute('cmpType') |
1169 if cmpBZ2 and cmpType == 'bz2': | 1102 if cmpBZ2 and cmpType == 'bz2': new_stub.compressionType = bz2 |
1170 new_stub.compressionType = bz2 | 1103 elif cmpZLIB and cmpType == 'zlib': new_stub.compressionType = zlib |
1171 elif cmpZLIB and cmpType == 'zlib': | 1104 else: new_stub.compressionType = None |
1172 new_stub.compressionType = zlib | 1105 else: new_stub.compressionType = bz2 |
1173 else: | 1106 else: new_stub.useCompression = False |
1174 new_stub.compressionType = None | |
1175 else: | |
1176 new_stub.compressionType = bz2 | |
1177 | |
1178 else: | |
1179 new_stub.useCompression = False | |
1180 | 1107 |
1181 #update newly create client stub with network logging state | 1108 #update newly create client stub with network logging state |
1182 new_stub.EnableMessageLogging = self.log_network_messages | 1109 new_stub.EnableMessageLogging = self.log_network_messages |
1183 | |
1184 self.sendMsg(newsock, new_stub.toxml("new"), False, None) | 1110 self.sendMsg(newsock, new_stub.toxml("new"), False, None) |
1185 | 1111 |
1186 # try to remove circular refs | 1112 # try to remove circular refs |
1187 if xml_dom: | 1113 if xml_dom: |
1188 xml_dom.unlink() | 1114 xml_dom.unlink() |
1204 time.sleep(2) | 1130 time.sleep(2) |
1205 newsock.close() | 1131 newsock.close() |
1206 print "Error in parse found from " + str(remote_host) + ". Disconnected." | 1132 print "Error in parse found from " + str(remote_host) + ". Disconnected." |
1207 print " Offending data(" + str(len(data)) + "bytes)=" + data | 1133 print " Offending data(" + str(len(data)) + "bytes)=" + data |
1208 print "Exception=" + str(e) | 1134 print "Exception=" + str(e) |
1209 | 1135 if xml_dom: xml_dom.unlink() |
1210 if xml_dom: | |
1211 xml_dom.unlink() | |
1212 return | 1136 return |
1213 | 1137 |
1214 #start threads and store player | 1138 #start threads and store player |
1215 | |
1216 allowed = 1 | 1139 allowed = 1 |
1217 version_string = "" | 1140 version_string = "" |
1218 | 1141 |
1219 if ((props['protocol_version'] != PROTOCOL_VERSION) and self.validate_protocol): | 1142 if ((props['protocol_version'] != PROTOCOL_VERSION) and self.validate_protocol): |
1220 version_string = "Sorry, this server can't handle your client version. (Protocol mismatch)<br />" | 1143 version_string = "Sorry, this server can't handle your client version. (Protocol mismatch)<br />" |
1221 allowed = 0 | 1144 allowed = 0 |
1222 | 1145 |
1223 if not self.checkClientVersion(props['version']): | 1146 if not self.checkClientVersion(props['version']): |
1224 version_string = "Sorry, your client is out of date. <br />" | 1147 version_string = "Sorry, your client is out of date. <br />" |
1225 version_string += "This server requires your client be version " + self.minClientVersion + " or higher to connect.<br />" | 1148 version_string += "This server requires your client be version " |
1149 version_string += "" + self.minClientVersion + " or higher to connect.<br />" | |
1226 allowed = 0 | 1150 allowed = 0 |
1227 | 1151 |
1228 if not allowed: | 1152 if not allowed: |
1229 version_string += ' Please go to <a href="http://openrpg.digitalxero.net">http://openrpg.digitalxero.net</a> to find a compatible client.<br />' | 1153 version_string += " Please go to <a href='http://www.assembla.com/traipse'>" |
1230 version_string += "If you can't find a compatible client on the website, chances are that the server is running an unreleased development version for testing purposes.<br />" | 1154 version_string += "http://www.assembla.com/traipse</a> to find a compatible client.<br />" |
1155 version_string += "If you can't find a compatible client on the website, " | |
1156 version_string += "chances are that the server is running an unreleased development " | |
1157 version_string += "version for testing purposes.<br />" | |
1231 | 1158 |
1232 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + version_string, new_stub.useCompression, new_stub.compressionType) | 1159 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + version_string, new_stub.useCompression, new_stub.compressionType) |
1233 # Give messages time to flow | 1160 # Give messages time to flow |
1234 time.sleep(1) | 1161 time.sleep(1) |
1235 self.log_msg("Connection terminating due to version incompatibility with client (ver: " + props['version'] + " protocol: " + props['protocol_version'] + ")" ) | 1162 self.log_msg("Connection terminating due to version incompatibility with client (ver: " + props['version'] + " protocol: " + props['protocol_version'] + ")" ) |
1242 if self.ban_list.has_key(ip): | 1169 if self.ban_list.has_key(ip): |
1243 banmsg = "You have been banned from this server.<br />" | 1170 banmsg = "You have been banned from this server.<br />" |
1244 cmsg = "Banned Client: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" | 1171 cmsg = "Banned Client: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" |
1245 self.log_msg(cmsg) | 1172 self.log_msg(cmsg) |
1246 allowed = 0 | 1173 allowed = 0 |
1247 | |
1248 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + banmsg, new_stub.useCompression, new_stub.compressionType) | 1174 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='0' group_id='0' />" + banmsg, new_stub.useCompression, new_stub.compressionType) |
1249 # Give messages time to flow | 1175 # Give messages time to flow |
1250 time.sleep(1) | 1176 time.sleep(1) |
1251 newsock.close() | 1177 newsock.close() |
1252 if xml_dom: | 1178 if xml_dom: |
1253 xml_dom.unlink() | 1179 xml_dom.unlink() |
1254 return None | 1180 return None |
1255 | 1181 |
1182 """ | |
1256 #---- Connection order changed by Snowdog 1/05 | 1183 #---- Connection order changed by Snowdog 1/05 |
1257 #---- Attempt to register player and send group data | 1184 #---- Attempt to register player and send group data |
1258 #---- before displaying lobby message | 1185 #---- before displaying lobby message |
1259 #---- Does not solve the Blackhole bug but under some conditions may | 1186 #---- Does not solve the Blackhole bug but under some conditions may |
1260 #---- allow for a graceful server response. -SD | 1187 #---- allow for a graceful server response. -SD |
1262 #---- changed method of sending group names to user 8/05 | 1189 #---- changed method of sending group names to user 8/05 |
1263 #---- black hole bug causes the group information to not be sent | 1190 #---- black hole bug causes the group information to not be sent |
1264 #---- to clients. Not sure why the group messages were being sent to the | 1191 #---- to clients. Not sure why the group messages were being sent to the |
1265 #---- incomming message queue, when they should be sent directly to user | 1192 #---- incomming message queue, when they should be sent directly to user |
1266 #---- Does not solve the black hole bug totally -SD | 1193 #---- Does not solve the black hole bug totally -SD |
1194 """ | |
1267 | 1195 |
1268 try: | 1196 try: |
1269 if xml_dom.getAttribute("id") == props['id']: | 1197 if xml_dom.getAttribute("id") == props['id']: |
1270 new_stub.initialize_threads() | 1198 new_stub.initialize_threads() |
1271 self.p_lock.acquire() | 1199 self.p_lock.acquire() |
1272 self.players[props['id']] = new_stub | 1200 self.players[props['id']] = new_stub |
1273 self.groups[LOBBY_ID].add_player(props['id']) #always add to lobby on connection. | 1201 self.groups[LOBBY_ID].add_player(props['id']) #always add to lobby on connection. |
1274 self.send_group_list(props['id']) | 1202 self.send_group_list(props['id']) |
1275 self.send_player_list(props['id'],LOBBY_ID) | 1203 self.send_player_list(props['id'],LOBBY_ID) |
1276 self.p_lock.release() | 1204 self.p_lock.release() |
1277 | |
1278 msg = self.groups[LOBBY_ID].game_map.get_all_xml() | 1205 msg = self.groups[LOBBY_ID].game_map.get_all_xml() |
1279 self.send(msg,props['id'],LOBBY_ID) | 1206 self.send(msg,props['id'],LOBBY_ID) |
1280 self.send_to_group(props['id'],LOBBY_ID,self.players[props['id']].toxml('new')) | 1207 self.send_to_group(props['id'],LOBBY_ID,self.players[props['id']].toxml('new')) |
1281 self.return_room_roles(props['id'],LOBBY_ID) | 1208 self.return_room_roles(props['id'],LOBBY_ID) |
1282 | 1209 |
1283 # Re-initialize the role for this player incase they came from a different server | 1210 # Re-initialize the role for this player incase they came from a different server |
1284 self.handle_role("set",props['id'], "GM",self.groups[LOBBY_ID].boot_pwd, LOBBY_ID) | 1211 self.handle_role("set",props['id'], "GM",self.groups[LOBBY_ID].boot_pwd, LOBBY_ID) |
1285 | |
1286 cmsg = "Client Connect: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" | 1212 cmsg = "Client Connect: (" + str(props['id']) + ") " + str(props['name']) + " [" + str(props['ip']) + "]" |
1287 self.log_msg(cmsg) | 1213 self.log_msg(cmsg) |
1288 cmsg = ("connect", props) ################################################# | 1214 cmsg = ("connect", props) ################################################# |
1289 self.log_msg(cmsg) | 1215 self.log_msg(cmsg) |
1290 | 1216 |
1303 err_string += "please contact the servers administrator to correct the issue.</center> " | 1229 err_string += "please contact the servers administrator to correct the issue.</center> " |
1304 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='" + props['id'] + "' group_id='0' />" + err_string, new_stub.useCompression, new_stub.compressionType ) | 1230 self.sendMsg( newsock, "<msg to='" + props['id'] + "' from='" + props['id'] + "' group_id='0' />" + err_string, new_stub.useCompression, new_stub.compressionType ) |
1305 time.sleep(2) | 1231 time.sleep(2) |
1306 newsock.close() | 1232 newsock.close() |
1307 | 1233 |
1308 | |
1309 # Display the lobby message | 1234 # Display the lobby message |
1310 self.SendLobbyMessage(newsock,props['id']) | 1235 self.SendLobbyMessage(newsock,props['id']) |
1311 | |
1312 if xml_dom: | 1236 if xml_dom: |
1313 xml_dom.unlink() | 1237 xml_dom.unlink() |
1314 | |
1315 | 1238 |
1316 def checkClientVersion(self, clientversion): | 1239 def checkClientVersion(self, clientversion): |
1317 minv = self.minClientVersion.split('.') | 1240 minv = self.minClientVersion.split('.') |
1318 cver = clientversion.split('.') | 1241 cver = clientversion.split('.') |
1319 for i in xrange(min(len(minv),len(cver))): | 1242 for i in xrange(min(len(minv),len(cver))): |
1320 w=max(len(minv[i]),len(cver[i])) | 1243 w=max(len(minv[i]),len(cver[i])) |
1321 v1=minv[i].rjust(w); | 1244 v1=minv[i].rjust(w); |
1322 v2=cver[i].rjust(w); | 1245 v2=cver[i].rjust(w); |
1323 if v1<v2: | 1246 if v1<v2: return 1 |
1324 return 1 | 1247 if v1>v2: return 0 |
1325 if v1>v2: | 1248 if len(minv)>len(cver): return 0 |
1326 return 0 | |
1327 | |
1328 if len(minv)>len(cver): | |
1329 return 0 | |
1330 return 1 | 1249 return 1 |
1331 | 1250 |
1332 | |
1333 | |
1334 def SendLobbyMessage(self, socket, player_id): | 1251 def SendLobbyMessage(self, socket, player_id): |
1335 ####################################################################### | 1252 """ |
1336 # Display the lobby message | 1253 # Display the lobby message |
1337 # prepend this server's version string to the the lobby message | 1254 # prepend this server's version string to the the lobby message |
1338 try: | 1255 """ |
1339 lobbyMsg = "You have connected to an <a href=\"http://www.openrpg.com\">OpenRPG</a> server, version '" + VERSION + "'" | 1256 try: |
1257 lobbyMsg = "You have connected to an <a href=\"http://www.openrpg.com\">OpenRPG</a> " | |
1258 lobbyMsg += "server, version '" + VERSION + "'" | |
1340 | 1259 |
1341 # See if we have a server name to report! | 1260 # See if we have a server name to report! |
1342 | |
1343 if len(self.serverName): | 1261 if len(self.serverName): |
1344 lobbyMsg += ", named '" + self.serverName + "'." | 1262 lobbyMsg += ", named '" + self.serverName + "'." |
1345 | |
1346 else: | 1263 else: |
1347 lobbyMsg += "." | 1264 lobbyMsg += "." |
1348 | 1265 |
1349 # Add extra line spacing | 1266 # Add extra line spacing |
1350 lobbyMsg += "\n\n" | 1267 lobbyMsg += "\n\n" |
1351 | 1268 |
1352 try: | 1269 try: validate.config_file("LobbyMessage.html","default_LobbyMessage.html") |
1353 self.validate.config_file("LobbyMessage.html","default_LobbyMessage.html") | 1270 except: pass |
1354 except: | |
1355 pass | |
1356 else: | 1271 else: |
1357 open_msg = open( self.userPath + "LobbyMessage.html", "r" ) | 1272 open_msg = open( self.userPath + "LobbyMessage.html", "r" ) |
1358 lobbyMsg += open_msg.read() | 1273 lobbyMsg += open_msg.read() |
1359 open_msg.close() | 1274 open_msg.close() |
1360 | 1275 |
1361 # Send the server's lobby message to the client no matter what | 1276 # Send the server's lobby message to the client no matter what |
1362 self.sendMsg(socket, "<msg to='" + player_id + "' from='0' group_id='0' />" + lobbyMsg, self.players[player_id].useCompression, self.players[player_id].compressionType) | 1277 self.sendMsg(socket, "<msg to='" + player_id + "' from='0' group_id='0' />" + lobbyMsg, |
1278 self.players[player_id].useCompression, self.players[player_id].compressionType) | |
1363 if self.sendLobbySound: | 1279 if self.sendLobbySound: |
1364 self.sendMsg(socket, '<sound url="' + self.lobbySound + '" group_id="0" from="0" loop="True" />', self.players[player_id].useCompression, self.players[player_id].compressionType) | 1280 self.sendMsg(socket, '<sound url="' + self.lobbySound + '" group_id="0" from="0" loop="True" />', |
1281 self.players[player_id].useCompression, self.players[player_id].compressionType) | |
1365 return | 1282 return |
1366 except: | 1283 except: traceback.print_exc() |
1367 traceback.print_exc() | 1284 """ |
1368 # End of lobby message code | 1285 # End of lobby message code |
1369 ####################################################################### | 1286 """ |
1370 | 1287 |
1371 | 1288 |
1372 def listenAcceptThread(self,arg): | 1289 def listenAcceptThread(self,arg): |
1373 # Set up the socket to listen on. | 1290 # Set up the socket to listen on. |
1374 try: | 1291 try: |
1375 self.log_msg("\nlisten thread running...") | 1292 self.log_msg("\nlisten thread running...") |
1376 adder = "" | 1293 adder = "" |
1377 if self.server_address is not None: | 1294 if self.server_address is not None: adder = self.server_address |
1378 adder = self.server_address | |
1379 self.listen_sock.bind(('', self.server_port)) | 1295 self.listen_sock.bind(('', self.server_port)) |
1380 self.listen_sock.listen(5) | 1296 self.listen_sock.listen(5) |
1381 | 1297 |
1382 except Exception, e: | 1298 except Exception, e: |
1383 self.log_msg(("Error binding request socket!", e)) | 1299 self.log_msg(("Error binding request socket!", e)) |
1384 self.alive = 0 | 1300 self.alive = 0 |
1385 | 1301 |
1386 | |
1387 while self.alive: | 1302 while self.alive: |
1388 | |
1389 # Block on the socket waiting for a new connection | 1303 # Block on the socket waiting for a new connection |
1390 try: | 1304 try: |
1391 (newsock, addr) = self.listen_sock.accept() | 1305 (newsock, addr) = self.listen_sock.accept() |
1306 """ | |
1392 ## self.log_msg("New connection from " + str(addr)+ ". Interfacing with server...") | 1307 ## self.log_msg("New connection from " + str(addr)+ ". Interfacing with server...") |
1393 | 1308 |
1394 # Now that we've accepted a new connection, we must immediately spawn a new | 1309 # Now that we've accepted a new connection, we must immediately spawn a new |
1395 # thread to handle it...otherwise we run the risk of having a DoS shoved into | 1310 # thread to handle it...otherwise we run the risk of having a DoS shoved into |
1396 # our face! :O After words, this thread is dead ready for another connection | 1311 # our face! :O After words, this thread is dead ready for another connection |
1397 # accept to come in. | 1312 # accept to come in. |
1313 """ | |
1398 thread.start_new_thread(self.acceptedNewConnectionThread, ( newsock, addr )) | 1314 thread.start_new_thread(self.acceptedNewConnectionThread, ( newsock, addr )) |
1399 | 1315 |
1400 except: | 1316 except: |
1401 print "The following exception caught accepting new connection:" | 1317 print "The following exception caught accepting new connection:" |
1402 traceback.print_exc() | 1318 traceback.print_exc() |
1403 | 1319 |
1404 # At this point, we're done and cleaning up. | 1320 # At this point, we're done and cleaning up. |
1405 self.log_msg("server socket listening thread exiting...") | 1321 self.log_msg("server socket listening thread exiting...") |
1406 self.listen_event.set() | 1322 self.listen_event.set() |
1407 | 1323 |
1408 | |
1409 | |
1410 def acceptedNewConnectionThread( self, newsock, addr ): | 1324 def acceptedNewConnectionThread( self, newsock, addr ): |
1411 """Once a new connection comes in and is accepted, this thread starts up to handle it.""" | 1325 """Once a new connection comes in and is accepted, this thread starts up to handle it.""" |
1412 | |
1413 # Initialize xml_dom | 1326 # Initialize xml_dom |
1414 xml_dom = None | 1327 xml_dom = None |
1415 data = None | 1328 data = None |
1416 | 1329 |
1417 # get client info and send othe client info | 1330 # get client info and send othe client info |
1418 # If this receive fails, this thread should exit without even attempting to process it | 1331 # If this receive fails, this thread should exit without even attempting to process it |
1419 self.log_msg("Connection from " + str(addr) + " has been accepted. Waiting for data...") | 1332 self.log_msg("Connection from " + str(addr) + " has been accepted. Waiting for data...") |
1420 | |
1421 data = self.recvMsg( newsock ) | 1333 data = self.recvMsg( newsock ) |
1422 | |
1423 if data=="" or data == None: | 1334 if data=="" or data == None: |
1424 self.log_msg("Connection from " + str(addr) + " failed. Closing connection.") | 1335 self.log_msg("Connection from " + str(addr) + " failed. Closing connection.") |
1425 try: | 1336 try: newsock.close() |
1426 newsock.close() | |
1427 except Exception, e: | 1337 except Exception, e: |
1428 self.log_msg( str(e) ) | 1338 self.log_msg( str(e) ) |
1429 print str(e) | 1339 print str(e) |
1430 return #returning causes connection thread instance to terminate | 1340 return #returning causes connection thread instance to terminate |
1431 | |
1432 | |
1433 if data == "<system/>": | 1341 if data == "<system/>": |
1434 try: | 1342 try: newsock.close() |
1435 newsock.close() | 1343 except: pass |
1436 except: | |
1437 pass | |
1438 return #returning causes connection thread instance to terminate | 1344 return #returning causes connection thread instance to terminate |
1439 | |
1440 # Clear out the xml_dom in preparation for new stuff, if necessary | 1345 # Clear out the xml_dom in preparation for new stuff, if necessary |
1441 try: | 1346 try: |
1442 if xml_dom: | 1347 if xml_dom: xml_dom.unlink() |
1443 xml_dom.unlink() | |
1444 | 1348 |
1445 except: | 1349 except: |
1446 self.log_msg( "The following exception caught unlinking xml_dom:") | 1350 self.log_msg( "The following exception caught unlinking xml_dom:") |
1447 self.log_msg("Continuing") | 1351 self.log_msg("Continuing") |
1448 | 1352 try: newsock.close() |
1449 try: | 1353 except: pass |
1450 newsock.close() | |
1451 except: | |
1452 pass | |
1453 return #returning causes connection thread instance to terminate | 1354 return #returning causes connection thread instance to terminate |
1454 | |
1455 # Parse the XML received from the connecting client | 1355 # Parse the XML received from the connecting client |
1456 try: | 1356 try: |
1457 xml_dom = parseXml(data) | 1357 xml_dom = parseXml(data) |
1458 xml_dom = xml_dom._get_documentElement() | 1358 xml_dom = xml_dom._get_documentElement() |
1459 | 1359 |
1460 except: | 1360 except: |
1461 try: | 1361 try: newsock.close() |
1462 newsock.close() | 1362 except: pass |
1463 except: | |
1464 pass | |
1465 self.log_msg( "Error in parse found from " + str(addr) + ". Disconnected.") | 1363 self.log_msg( "Error in parse found from " + str(addr) + ". Disconnected.") |
1466 self.log_msg(" Offending data(" + str(len(data)) + "bytes)=" + data) | 1364 self.log_msg(" Offending data(" + str(len(data)) + "bytes)=" + data) |
1467 self.log_msg( "Exception:") | 1365 self.log_msg( "Exception:") |
1468 traceback.print_exc() | 1366 traceback.print_exc() |
1469 return #returning causes connection thread instance to terminate | 1367 return #returning causes connection thread instance to terminate |
1472 try: | 1370 try: |
1473 # get action | 1371 # get action |
1474 action = xml_dom.getAttribute("action") | 1372 action = xml_dom.getAttribute("action") |
1475 | 1373 |
1476 # Figure out what type of connection we have going on now | 1374 # Figure out what type of connection we have going on now |
1477 if action == "new": | 1375 if action == "new": self.new_request(newsock,xml_dom) |
1478 self.new_request(newsock,xml_dom) | 1376 elif action == "update": self.update_request(newsock,xml_dom) |
1479 | 1377 else: self.log_msg("Unknown Join Request!") |
1480 elif action == "update": | |
1481 self.update_request(newsock,xml_dom) | |
1482 | |
1483 else: | |
1484 self.log_msg("Unknown Join Request!") | |
1485 | 1378 |
1486 except Exception, e: | 1379 except Exception, e: |
1487 print "The following message: " + str(data) | 1380 print "The following message: " + str(data) |
1488 print "from " + str(addr) + " created the following exception: " | 1381 print "from " + str(addr) + " created the following exception: " |
1489 traceback.print_exc() | 1382 traceback.print_exc() |
1490 return #returning causes connection thread instance to terminate | 1383 return #returning causes connection thread instance to terminate |
1491 | 1384 |
1492 # Again attempt to clean out DOM stuff | 1385 # Again attempt to clean out DOM stuff |
1493 try: | 1386 try: |
1494 if xml_dom: | 1387 if xml_dom: xml_dom.unlink() |
1495 xml_dom.unlink() | |
1496 except: | 1388 except: |
1497 print "The following exception caught unlinking xml_dom:" | 1389 print "The following exception caught unlinking xml_dom:" |
1498 traceback.print_exc() | 1390 traceback.print_exc() |
1499 return #returning causes connection thread instance to terminate | 1391 return #returning causes connection thread instance to terminate |
1500 | 1392 |
1501 | 1393 """ |
1502 | |
1503 #======================================================== | 1394 #======================================================== |
1504 # | 1395 # |
1505 # Message_handler | 1396 # Message_handler |
1506 # | 1397 # |
1507 #======================================================== | 1398 #======================================================== |
1508 # | 1399 # |
1509 # Changed thread organization from one continuous parsing/handling thread | 1400 # Changed thread organization from one continuous parsing/handling thread |
1510 # to multiple expiring parsing/handling threads to improve server performance | 1401 # to multiple expiring parsing/handling threads to improve server performance |
1511 # and player load capacity -- Snowdog 3/04 | 1402 # and player load capacity -- Snowdog 3/04 |
1403 """ | |
1512 | 1404 |
1513 def message_handler(self,arg): | 1405 def message_handler(self,arg): |
1514 xml_dom = None | 1406 xml_dom = None |
1515 self.log_msg( "message handler thread running..." ) | 1407 self.log_msg( "message handler thread running..." ) |
1516 while self.alive: | 1408 while self.alive: |
1517 data = None | 1409 data = None |
1518 try: | 1410 try: data=self.incoming.get(0) |
1519 data=self.incoming.get(0) | |
1520 except Queue.Empty: | 1411 except Queue.Empty: |
1521 time.sleep(0.5) #sleep 1/2 second | 1412 time.sleep(0.5) #sleep 1/2 second |
1522 continue | 1413 continue |
1523 | 1414 |
1524 bytes = len(data) | 1415 bytes = len(data) |
1525 if bytes <= 0: | 1416 if bytes <= 0: continue |
1526 continue | |
1527 try: | 1417 try: |
1528 thread.start_new_thread(self.parse_incoming_dom,(str(data),)) | 1418 thread.start_new_thread(self.parse_incoming_dom,(str(data),)) |
1529 #data has been passed... unlink from the variable references | 1419 #data has been passed... unlink from the variable references |
1530 #so data in passed objects doesn't change (python passes by reference) | 1420 #so data in passed objects doesn't change (python passes by reference) |
1531 del data | 1421 del data |
1549 | 1439 |
1550 except Exception, e: | 1440 except Exception, e: |
1551 print "Error in parse of inbound message. Ignoring message." | 1441 print "Error in parse of inbound message. Ignoring message." |
1552 print " Offending data(" + str(len(data)) + "bytes)=" + data | 1442 print " Offending data(" + str(len(data)) + "bytes)=" + data |
1553 print "Exception=" + str(e) | 1443 print "Exception=" + str(e) |
1554 | |
1555 if xml_dom: xml_dom.unlink() | 1444 if xml_dom: xml_dom.unlink() |
1556 | |
1557 | 1445 |
1558 def message_action(self, xml_dom, data): | 1446 def message_action(self, xml_dom, data): |
1559 tag_name = xml_dom._get_tagName() | 1447 tag_name = xml_dom._get_tagName() |
1560 if self.svrcmds.has_key(tag_name): | 1448 if self.svrcmds.has_key(tag_name): self.svrcmds[tag_name]['function'](xml_dom,data) |
1561 self.svrcmds[tag_name]['function'](xml_dom,data) | 1449 else: raise Exception, "Not a valid header!" |
1562 else: | |
1563 raise Exception, "Not a valid header!" | |
1564 #Message Action thread expires and closes here. | 1450 #Message Action thread expires and closes here. |
1565 return | 1451 return |
1566 | |
1567 | 1452 |
1568 def do_alter(self, xml_dom, data): | 1453 def do_alter(self, xml_dom, data): |
1569 target = xml_dom.getAttribute("key") | 1454 target = xml_dom.getAttribute("key") |
1570 value = xml_dom.getAttribute("val") | 1455 value = xml_dom.getAttribute("val") |
1571 player = xml_dom.getAttribute("plr") | 1456 player = xml_dom.getAttribute("plr") |
1572 group_id = xml_dom.getAttribute("gid") | 1457 group_id = xml_dom.getAttribute("gid") |
1573 boot_pwd = xml_dom.getAttribute("bpw") | 1458 boot_pwd = xml_dom.getAttribute("bpw") |
1574 actual_boot_pwd = self.groups[group_id].boot_pwd | 1459 actual_boot_pwd = self.groups[group_id].boot_pwd |
1575 | 1460 |
1576 if self.allow_room_passwords == 0: | 1461 if self.allow_room_passwords == 0: |
1577 msg ="<msg to='" + player + "' from='0' group_id='0' /> Room passwords have been disabled by the server administrator." | 1462 msg ="<msg to='" + player + "' from='0' group_id='0' /> " |
1463 msg += "Room passwords have been disabled by the server administrator." | |
1578 self.players[player].outbox.put(msg) | 1464 self.players[player].outbox.put(msg) |
1579 return | 1465 return |
1580 elif boot_pwd == actual_boot_pwd: | 1466 elif boot_pwd == actual_boot_pwd: |
1581 if target == "pwd": | 1467 if target == "pwd": |
1582 lmessage = "Room password changed to from \"" + self.groups[group_id].pwd + "\" to \"" + value + "\" by " + player | 1468 lmessage = "Room password changed to from " + self.groups[group_id].pwd + " to " + value + " by " + player |
1583 self.groups[group_id].pwd = value | 1469 self.groups[group_id].pwd = value |
1584 msg ="<msg to='" + player + "' from='0' group_id='0' /> Room password changed to \"" + value + "\"." | 1470 msg ="<msg to='" + player + "' from='0' group_id='0' /> Room password changed to " + value + "." |
1585 self.players[player].outbox.put(msg) | 1471 self.players[player].outbox.put(msg) |
1586 self.log_msg(lmessage) | 1472 self.log_msg(lmessage) |
1587 self.send_to_all('0',self.groups[group_id].toxml('update')) | 1473 self.send_to_all('0',self.groups[group_id].toxml('update')) |
1588 elif target == "name": | 1474 elif target == "name": |
1589 # Check for & in name. We want to allow this because of its common | 1475 # Check for & in name. We want to allow this because of its common |
1592 msg ="<msg to='" + player + "' from='0' group_id='0' />" + result | 1478 msg ="<msg to='" + player + "' from='0' group_id='0' />" + result |
1593 self.players[player].outbox.put(msg) | 1479 self.players[player].outbox.put(msg) |
1594 else: | 1480 else: |
1595 msg ="<msg to='" + player + "' from='0' group_id='0'>Invalid Administrator Password." | 1481 msg ="<msg to='" + player + "' from='0' group_id='0'>Invalid Administrator Password." |
1596 self.players[player].outbox.put(msg) | 1482 self.players[player].outbox.put(msg) |
1597 | |
1598 | 1483 |
1599 def do_role(self, xml_dom, data): | 1484 def do_role(self, xml_dom, data): |
1600 role = "" | 1485 role = "" |
1601 boot_pwd = "" | 1486 boot_pwd = "" |
1602 act = xml_dom.getAttribute("action") | 1487 act = xml_dom.getAttribute("action") |
1613 def do_ping(self, xml_dom, data): | 1498 def do_ping(self, xml_dom, data): |
1614 player = xml_dom.getAttribute("player") | 1499 player = xml_dom.getAttribute("player") |
1615 group_id = xml_dom.getAttribute("group_id") | 1500 group_id = xml_dom.getAttribute("group_id") |
1616 sent_time = "" | 1501 sent_time = "" |
1617 msg = "" | 1502 msg = "" |
1618 try: | 1503 try: sent_time = xml_dom.getAttribute("time") |
1619 sent_time = xml_dom.getAttribute("time") | 1504 except: pass |
1620 except: | 1505 if sent_time != "": msg ="<ping time='" + str(sent_time) + "' />" #because a time was sent return a ping response |
1621 pass | |
1622 | |
1623 if sent_time != "": | |
1624 #because a time was sent return a ping response | |
1625 msg ="<ping time='" + str(sent_time) + "' />" | |
1626 else: | 1506 else: |
1627 msg ="<msg to='" + player + "' from='" + player + "' group_id='" + group_id + "'><font color='#FF0000'>PONG!?!</font>" | 1507 msg ="<msg to='" + player + "' from='" + player + "' group_id='" + group_id + "'>" |
1628 | 1508 msg += "<font color='#FF0000'>PONG!?!</font>" |
1629 self.players[player].outbox.put(msg) | 1509 self.players[player].outbox.put(msg) |
1630 xml_dom.unlink() | 1510 xml_dom.unlink() |
1631 | 1511 |
1632 def do_system(self, xml_dom, data): | 1512 def do_system(self, xml_dom, data): |
1633 pass | 1513 pass |
1634 | 1514 |
1635 def moderate_group(self,xml_dom,data): | 1515 def moderate_group(self,xml_dom,data): |
1636 try: | 1516 try: |
1637 action = xml_dom.getAttribute("action") | 1517 action = xml_dom.getAttribute("action") |
1638 from_id = xml_dom.getAttribute("from") | 1518 from_id = xml_dom.getAttribute("from") |
1639 if xml_dom.hasAttribute("pwd"): | 1519 if xml_dom.hasAttribute("pwd"): pwd=xml_dom.getAttribute("pwd") |
1640 pwd=xml_dom.getAttribute("pwd") | 1520 else: pwd="" |
1641 else: | |
1642 pwd="" | |
1643 group_id=self.players[from_id].group_id | 1521 group_id=self.players[from_id].group_id |
1644 | |
1645 if action == "list": | 1522 if action == "list": |
1646 if (self.groups[group_id].moderated): | 1523 if (self.groups[group_id].moderated): |
1647 msg = "" | 1524 msg = "" |
1648 for i in self.groups[group_id].voice.keys(): | 1525 for i in self.groups[group_id].voice.keys(): |
1649 if msg != "": | 1526 if msg != "": msg +=", " |
1650 msg +=", " | 1527 if self.players.has_key(i): msg += '('+i+') '+self.players[i].name |
1651 if self.players.has_key(i): | 1528 else: del self.groups[group_id].voice[i] |
1652 msg += '('+i+') '+self.players[i].name | 1529 if (msg != ""): msg = "The following users may speak in this room: " + msg |
1653 else: | 1530 else: msg = "No people are currently in this room with the ability to chat" |
1654 del self.groups[group_id].voice[i] | |
1655 if (msg != ""): | |
1656 msg = "The following users may speak in this room: " + msg | |
1657 else: | |
1658 msg = "No people are currently in this room with the ability to chat" | |
1659 self.players[from_id].self_message(msg) | 1531 self.players[from_id].self_message(msg) |
1660 else: | 1532 else: self.players[from_id].self_message("This room is currently unmoderated") |
1661 self.players[from_id].self_message("This room is currently unmoderated") | 1533 elif action == 'enable' or 'disable' or 'addvoice' or 'delvoice': |
1662 elif action == "enable": | 1534 #condenses password check --TaS 2009 |
1663 if not self.groups[group_id].check_boot_pwd(pwd): | 1535 if not self.groups[group_id].check_boot_pwd(pwd): |
1664 self.players[from_id].self_message("Failed - incorrect admin password") | 1536 self.players[from_id].self_message("Failed - incorrect admin password") |
1665 return | 1537 return |
1666 self.groups[group_id].moderated = 1 | 1538 if action == 'enable': |
1667 self.players[from_id].self_message("This channel is now moderated") | 1539 self.groups[group_id].moderated = 1 |
1668 elif action == "disable": | 1540 self.players[from_id].self_message("This channel is now moderated") |
1669 if not self.groups[group_id].check_boot_pwd(pwd): | 1541 if action == 'disable': |
1670 self.players[from_id].self_message("Failed - incorrect admin password") | 1542 self.groups[group_id].moderated = 0 |
1671 return | 1543 self.players[from_id].self_message("This channel is now unmoderated") |
1672 self.groups[group_id].moderated = 0 | 1544 if action == 'addvoice': |
1673 self.players[from_id].self_message("This channel is now unmoderated") | 1545 users = xml_dom.getAttribute("users").split(',') |
1674 elif action == "addvoice": | 1546 for i in users: self.groups[group_id].voice[i.strip()]=1 |
1675 if not self.groups[group_id].check_boot_pwd(pwd): | 1547 if action == 'delvoice': |
1676 self.players[from_id].self_message("Failed - incorrect admin password") | 1548 users = xml_dom.getAttribute("users").split(',') |
1677 return | 1549 for i in users: |
1678 users = xml_dom.getAttribute("users").split(',') | 1550 if self.groups[group_id].voice.has_key(i.strip()): del self.groups[group_id].voice[i.strip()] |
1679 for i in users: | |
1680 self.groups[group_id].voice[i.strip()]=1 | |
1681 elif action == "delvoice": | |
1682 if not self.groups[group_id].check_boot_pwd(pwd): | |
1683 self.players[from_id].self_message("Failed - incorrect admin password") | |
1684 return | |
1685 users = xml_dom.getAttribute("users").split(',') | |
1686 for i in users: | |
1687 if self.groups[group_id].voice.has_key(i.strip()): | |
1688 del self.groups[group_id].voice[i.strip()] | |
1689 else: | 1551 else: |
1690 print "Bad input: " + data | 1552 print "Bad input: " + data |
1691 | |
1692 except Exception,e: | 1553 except Exception,e: |
1693 self.log_msg(str(e)) | 1554 self.log_msg(str(e)) |
1694 | |
1695 | |
1696 | |
1697 | 1555 |
1698 def join_group(self,xml_dom,data): | 1556 def join_group(self,xml_dom,data): |
1699 try: | 1557 try: |
1700 from_id = xml_dom.getAttribute("from") | 1558 from_id = xml_dom.getAttribute("from") |
1701 pwd = xml_dom.getAttribute("pwd") | 1559 pwd = xml_dom.getAttribute("pwd") |
1711 allowed = 0 | 1569 allowed = 0 |
1712 | 1570 |
1713 #tell the clients password manager the password failed -- SD 8/03 | 1571 #tell the clients password manager the password failed -- SD 8/03 |
1714 pm = "<password signal=\"fail\" type=\"room\" id=\"" + group_id + "\" data=\"\"/>" | 1572 pm = "<password signal=\"fail\" type=\"room\" id=\"" + group_id + "\" data=\"\"/>" |
1715 self.players[from_id].outbox.put(pm) | 1573 self.players[from_id].outbox.put(pm) |
1716 | |
1717 msg = 'failed - incorrect room password' | 1574 msg = 'failed - incorrect room password' |
1718 | 1575 |
1719 if not allowed: | 1576 if not allowed: |
1720 self.players[from_id].self_message(msg) | 1577 self.players[from_id].self_message(msg) |
1721 #the following line makes sure that their role is reset to normal, | 1578 #the following line makes sure that their role is reset to normal, |
1725 self.players[from_id].outbox.put(msg) | 1582 self.players[from_id].outbox.put(msg) |
1726 return | 1583 return |
1727 | 1584 |
1728 #move the player into their new group. | 1585 #move the player into their new group. |
1729 self.move_player(from_id, group_id) | 1586 self.move_player(from_id, group_id) |
1730 | |
1731 except Exception, e: | 1587 except Exception, e: |
1732 self.log_msg(str(e)) | 1588 self.log_msg(str(e)) |
1733 | 1589 |
1734 | 1590 """ |
1735 | |
1736 | |
1737 #---------------------------------------------------------------------------- | |
1738 # move_player function -- added by Snowdog 4/03 | 1591 # move_player function -- added by Snowdog 4/03 |
1739 # | 1592 # |
1740 # Split join_group function in half. separating the player validation checks | 1593 # Split join_group function in half. separating the player validation checks |
1741 # from the actual group changing code. Done primarily to impliment | 1594 # from the actual group changing code. Done primarily to impliment |
1742 # boot-from-room-to-lobby behavior in the server. | 1595 # boot-from-room-to-lobby behavior in the server. |
1596 """ | |
1743 | 1597 |
1744 def move_player(self, from_id, group_id ): | 1598 def move_player(self, from_id, group_id ): |
1745 "move a player from one group to another" | 1599 "move a player from one group to another" |
1746 try: | 1600 try: |
1747 try: | 1601 try: |
1756 old_group_id = self.players[from_id].change_group(group_id,self.groups) | 1610 old_group_id = self.players[from_id].change_group(group_id,self.groups) |
1757 self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del')) | 1611 self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del')) |
1758 self.send_to_group(from_id,group_id,self.players[from_id].toxml('new')) | 1612 self.send_to_group(from_id,group_id,self.players[from_id].toxml('new')) |
1759 self.check_group(from_id, old_group_id) | 1613 self.check_group(from_id, old_group_id) |
1760 | 1614 |
1615 """ | |
1761 # Here, if we have a group specific lobby message to send, push it on | 1616 # Here, if we have a group specific lobby message to send, push it on |
1762 # out the door! Make it put the message then announce the player...just | 1617 # out the door! Make it put the message then announce the player...just |
1763 # like in the lobby during a new connection. | 1618 # like in the lobby during a new connection. |
1764 # -- only do this check if the room id is within range of known persistent id thresholds | 1619 # -- only do this check if the room id is within range of known persistent id thresholds |
1765 #also goes ahead if there is a defaultRoomMessage --akoman | 1620 #also goes ahead if there is a defaultRoomMessage --akoman |
1621 """ | |
1766 | 1622 |
1767 if self.isPersistentRoom(group_id) or self.defaultMessageFile != None: | 1623 if self.isPersistentRoom(group_id) or self.defaultMessageFile != None: |
1768 try: | 1624 try: |
1769 if self.groups[group_id].messageFile[:4] == 'http': | 1625 if self.groups[group_id].messageFile[:4] == 'http': |
1770 data = urllib.urlretrieve(self.groups[group_id].messageFile) | 1626 data = urllib.urlretrieve(self.groups[group_id].messageFile) |
1771 roomMsgFile = open(data[0]) | 1627 roomMsgFile = open(data[0]) |
1772 else: | 1628 else: roomMsgFile = open(self.groups[group_id].messageFile, "r") |
1773 roomMsgFile = open(self.groups[group_id].messageFile, "r") | |
1774 roomMsg = roomMsgFile.read() | 1629 roomMsg = roomMsgFile.read() |
1775 roomMsgFile.close() | 1630 roomMsgFile.close() |
1776 urllib.urlcleanup() | 1631 urllib.urlcleanup() |
1777 | 1632 |
1778 except Exception, e: | 1633 except Exception, e: |
1779 roomMsg = "" | 1634 roomMsg = "" |
1780 self.log_msg(str(e)) | 1635 self.log_msg(str(e)) |
1781 | 1636 |
1782 # Spit that darn message out now! | 1637 # Spit that darn message out now! |
1783 self.players[from_id].outbox.put("<msg to='" + from_id + "' from='0' group_id='" + group_id + "' />" + roomMsg) | 1638 self.players[from_id].outbox.put("<msg to='" + from_id + "' from='0' group_id='" + group_id + "' />" + roomMsg) |
1784 | |
1785 if self.sendLobbySound and group_id == '0': | 1639 if self.sendLobbySound and group_id == '0': |
1786 self.players[from_id].outbox.put('<sound url="' + self.lobbySound + '" group_id="0" from="0" loop="True" />') | 1640 self.players[from_id].outbox.put('<sound url="' + self.lobbySound + '" group_id="0" from="0" loop="True" />') |
1787 | |
1788 # Now, tell everyone that we've arrived | 1641 # Now, tell everyone that we've arrived |
1789 self.send_to_all('0', self.groups[group_id].toxml('update')) | 1642 self.send_to_all('0', self.groups[group_id].toxml('update')) |
1790 | |
1791 # this line sends a handle role message to change the players role | 1643 # this line sends a handle role message to change the players role |
1792 self.send_player_list(from_id,group_id) | 1644 self.send_player_list(from_id,group_id) |
1793 | |
1794 #notify user about others in the room | 1645 #notify user about others in the room |
1795 self.return_room_roles(from_id,group_id) | 1646 self.return_room_roles(from_id,group_id) |
1796 self.log_msg(("join_group", (self.groups[group_id].name, group_id, from_id))) | 1647 self.log_msg(("join_group", (self.groups[group_id].name, group_id, from_id))) |
1797 self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id) | 1648 self.handle_role("set", from_id, self.players[from_id].role, self.groups[group_id].boot_pwd, group_id) |
1798 | |
1799 except Exception, e: | 1649 except Exception, e: |
1800 self.log_msg(str(e)) | 1650 self.log_msg(str(e)) |
1801 | |
1802 thread.start_new_thread(self.registerRooms,(0,)) | 1651 thread.start_new_thread(self.registerRooms,(0,)) |
1803 | 1652 |
1804 def return_room_roles(self,from_id,group_id): | 1653 def return_room_roles(self,from_id,group_id): |
1805 for m in self.players.keys(): | 1654 for m in self.players.keys(): |
1806 if self.players[m].group_id == group_id: | 1655 if self.players[m].group_id == group_id: |
1807 msg = "<role action=\"update\" id=\"" + self.players[m].id + "\" role=\"" + self.players[m].role + "\" />" | 1656 msg = "<role action=\"update\" id=\"" + self.players[m].id + "\" role=\"" + self.players[m].role + "\" />" |
1808 self.players[from_id].outbox.put(msg) | 1657 self.players[from_id].outbox.put(msg) |
1809 | 1658 |
1810 | 1659 """ |
1811 # This is pretty much the same thing as the create_group method, however, | 1660 # This is pretty much the same thing as the create_group method, however, |
1812 # it's much more generic whereas the create_group method is tied to a specific | 1661 # it's much more generic whereas the create_group method is tied to a specific |
1813 # xml message. Ack! This version simply creates the groups, it does not | 1662 # xml message. Ack! This version simply creates the groups, it does not |
1814 # send them to players. Also note, both these methods have race | 1663 # send them to players. Also note, both these methods have race |
1815 # conditions written all over them. Ack! Ack! | 1664 # conditions written all over them. Ack! Ack! |
1665 """ | |
1816 def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ): | 1666 def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ): |
1817 group_id = str( self.next_group_id ) | 1667 group_id = str( self.next_group_id ) |
1818 self.next_group_id += 1 | 1668 self.next_group_id += 1 |
1819 self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist ) | 1669 self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist ) |
1820 self.groups[group_id].moderated = moderated | 1670 self.groups[group_id].moderated = moderated |
1822 if persist !=0: ins="Persistant " | 1672 if persist !=0: ins="Persistant " |
1823 lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name) | 1673 lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name) |
1824 self.log_msg( lmsg ) | 1674 self.log_msg( lmsg ) |
1825 self.log_msg(("create_group", (str(name), int(group_id), 0) )) ##-99 works, could be better. | 1675 self.log_msg(("create_group", (str(name), int(group_id), 0) )) ##-99 works, could be better. |
1826 | 1676 |
1827 | |
1828 def change_group_name(self,gid,name,pid): | 1677 def change_group_name(self,gid,name,pid): |
1829 "Change the name of a group" | 1678 "Change the name of a group" |
1830 # Check for & in name. We want to allow this because of its common | 1679 # Check for & in name. We want to allow this because of its common |
1831 # use in d&d games. | 1680 # use in d&d games. |
1832 try: | 1681 try: |
1837 if loc > -1: | 1686 if loc > -1: |
1838 b = name[:loc] | 1687 b = name[:loc] |
1839 e = name[loc+1:] | 1688 e = name[loc+1:] |
1840 value = b + "&" + e | 1689 value = b + "&" + e |
1841 oldloc = loc+1 | 1690 oldloc = loc+1 |
1842 | |
1843 loc = name.find("'") | 1691 loc = name.find("'") |
1844 oldloc = 0 | 1692 oldloc = 0 |
1845 while loc > -1: | 1693 while loc > -1: |
1846 loc = name.find("'",oldloc) | 1694 loc = name.find("'",oldloc) |
1847 if loc > -1: | 1695 if loc > -1: |
1848 b = name[:loc] | 1696 b = name[:loc] |
1849 e = name[loc+1:] | 1697 e = name[loc+1:] |
1850 name = b + "'" + e | 1698 name = b + "'" + e |
1851 oldloc = loc+1 | 1699 oldloc = loc+1 |
1852 | |
1853 loc = name.find('"') | 1700 loc = name.find('"') |
1854 oldloc = 0 | 1701 oldloc = 0 |
1855 while loc > -1: | 1702 while loc > -1: |
1856 loc = name.find('"',oldloc) | 1703 loc = name.find('"',oldloc) |
1857 if loc > -1: | 1704 if loc > -1: |
1858 b = name[:loc] | 1705 b = name[:loc] |
1859 e = name[loc+1:] | 1706 e = name[loc+1:] |
1860 name = b + """ + e | 1707 name = b + """ + e |
1861 oldloc = loc+1 | 1708 oldloc = loc+1 |
1862 | |
1863 oldroomname = self.groups[gid].name | 1709 oldroomname = self.groups[gid].name |
1864 self.groups[gid].name = str(name) | 1710 self.groups[gid].name = str(name) |
1865 lmessage = "Room name changed to from \"" + oldroomname + "\" to \"" + name + "\"" | 1711 lmessage = "Room name changed to from \"" + oldroomname + "\" to \"" + name + "\"" |
1866 self.log_msg(lmessage + " by " + str(pid) ) | 1712 self.log_msg(lmessage + " by " + str(pid) ) |
1867 self.send_to_all('0',self.groups[gid].toxml('update')) | 1713 self.send_to_all('0',self.groups[gid].toxml('update')) |
1868 return lmessage | 1714 return lmessage |
1869 except: | 1715 except: return "An error occured during rename of room!" |
1870 return "An error occured during rename of room!" | |
1871 | |
1872 thread.start_new_thread(self.registerRooms,(0,)) | 1716 thread.start_new_thread(self.registerRooms,(0,)) |
1873 | |
1874 | |
1875 | 1717 |
1876 def create_group(self,xml_dom,data): | 1718 def create_group(self,xml_dom,data): |
1877 try: | 1719 try: |
1878 from_id = xml_dom.getAttribute("from") | 1720 from_id = xml_dom.getAttribute("from") |
1879 pwd = xml_dom.getAttribute("pwd") | 1721 pwd = xml_dom.getAttribute("pwd") |
1884 messageFile = self.defaultMessageFile | 1726 messageFile = self.defaultMessageFile |
1885 | 1727 |
1886 # see if passwords are allowed on this server and null password if not | 1728 # see if passwords are allowed on this server and null password if not |
1887 if self.allow_room_passwords != 1: pwd = "" | 1729 if self.allow_room_passwords != 1: pwd = "" |
1888 | 1730 |
1889 | |
1890 # | |
1891 # Check for & in name. We want to allow this because of its common | 1731 # Check for & in name. We want to allow this because of its common |
1892 # use in d&d games. | 1732 # use in d&d games. |
1893 | 1733 |
1894 loc = name.find("&") | 1734 loc = name.find("&") |
1895 oldloc = 0 | 1735 oldloc = 0 |
1898 if loc > -1: | 1738 if loc > -1: |
1899 b = name[:loc] | 1739 b = name[:loc] |
1900 e = name[loc+1:] | 1740 e = name[loc+1:] |
1901 name = b + "&" + e | 1741 name = b + "&" + e |
1902 oldloc = loc+1 | 1742 oldloc = loc+1 |
1903 | |
1904 loc = name.find("'") | 1743 loc = name.find("'") |
1905 oldloc = 0 | 1744 oldloc = 0 |
1906 while loc > -1: | 1745 while loc > -1: |
1907 loc = name.find("'",oldloc) | 1746 loc = name.find("'",oldloc) |
1908 if loc > -1: | 1747 if loc > -1: |
1909 b = name[:loc] | 1748 b = name[:loc] |
1910 e = name[loc+1:] | 1749 e = name[loc+1:] |
1911 name = b + "'" + e | 1750 name = b + "'" + e |
1912 oldloc = loc+1 | 1751 oldloc = loc+1 |
1913 | |
1914 loc = name.find('"') | 1752 loc = name.find('"') |
1915 oldloc = 0 | 1753 oldloc = 0 |
1916 while loc > -1: | 1754 while loc > -1: |
1917 loc = name.find('"',oldloc) | 1755 loc = name.find('"',oldloc) |
1918 if loc > -1: | 1756 if loc > -1: |
1919 b = name[:loc] | 1757 b = name[:loc] |
1920 e = name[loc+1:] | 1758 e = name[loc+1:] |
1921 name = b + """ + e | 1759 name = b + """ + e |
1922 oldloc = loc+1 | 1760 oldloc = loc+1 |
1923 | |
1924 | |
1925 group_id = str(self.next_group_id) | 1761 group_id = str(self.next_group_id) |
1926 self.next_group_id += 1 | 1762 self.next_group_id += 1 |
1927 self.groups[group_id] = game_group(group_id,name,pwd,"",boot_pwd, minVersion, None, messageFile ) | 1763 self.groups[group_id] = game_group(group_id,name,pwd,"",boot_pwd, minVersion, None, messageFile ) |
1928 self.groups[group_id].voice[from_id]=1 | 1764 self.groups[group_id].voice[from_id]=1 |
1929 self.players[from_id].outbox.put(self.groups[group_id].toxml('new')) | 1765 self.players[from_id].outbox.put(self.groups[group_id].toxml('new')) |
1943 if self.defaultMessageFile != None: | 1779 if self.defaultMessageFile != None: |
1944 if self.defaultMessageFile[:4] == 'http': | 1780 if self.defaultMessageFile[:4] == 'http': |
1945 data = urllib.urlretrieve(self.defaultMessageFile) | 1781 data = urllib.urlretrieve(self.defaultMessageFile) |
1946 open_msg = open(data[0]) | 1782 open_msg = open(data[0]) |
1947 urllib.urlcleanup() | 1783 urllib.urlcleanup() |
1948 else: | 1784 else: open_msg = open( self.defaultMessageFile, "r" ) |
1949 open_msg = open( self.defaultMessageFile, "r" ) | |
1950 | |
1951 roomMsg = open_msg.read() | 1785 roomMsg = open_msg.read() |
1952 open_msg.close() | 1786 open_msg.close() |
1953 # Send the rooms message to the client no matter what | 1787 # Send the rooms message to the client no matter what |
1954 self.players[from_id].outbox.put( "<msg to='" + from_id + "' from='0' group_id='" + group_id + "' />" + roomMsg ) | 1788 self.players[from_id].outbox.put( "<msg to='" + from_id + "' from='0' group_id='" + group_id + "' />" + roomMsg ) |
1955 | 1789 except Exception, e: self.log_msg( "Exception: create_group(): " + str(e)) |
1956 except Exception, e: | |
1957 self.log_msg( "Exception: create_group(): " + str(e)) | |
1958 | |
1959 thread.start_new_thread(self.registerRooms,(0,)) | 1790 thread.start_new_thread(self.registerRooms,(0,)) |
1960 | |
1961 | 1791 |
1962 def check_group(self, from_id, group_id): | 1792 def check_group(self, from_id, group_id): |
1963 try: | 1793 try: |
1964 if group_id not in self.groups: return | 1794 if group_id not in self.groups: return |
1965 if group_id == '0': | 1795 if group_id == '0': |
1967 return #never remove lobby *sanity check* | 1797 return #never remove lobby *sanity check* |
1968 if not self.isPersistentRoom(group_id) and self.groups[group_id].get_num_players() == 0: | 1798 if not self.isPersistentRoom(group_id) and self.groups[group_id].get_num_players() == 0: |
1969 self.send_to_all("0",self.groups[group_id].toxml('del')) | 1799 self.send_to_all("0",self.groups[group_id].toxml('del')) |
1970 del self.groups[group_id] | 1800 del self.groups[group_id] |
1971 self.log_msg(("delete_group", (group_id, from_id))) | 1801 self.log_msg(("delete_group", (group_id, from_id))) |
1972 | 1802 else: self.send_to_all("0",self.groups[group_id].toxml('update')) |
1973 else: | |
1974 self.send_to_all("0",self.groups[group_id].toxml('update')) | |
1975 | 1803 |
1976 #The register Rooms thread | 1804 #The register Rooms thread |
1977 thread.start_new_thread(self.registerRooms,(0,)) | 1805 thread.start_new_thread(self.registerRooms,(0,)) |
1978 | 1806 |
1979 except Exception, e: | 1807 except Exception, e: self.log_msg(str(e)) |
1980 self.log_msg(str(e)) | |
1981 | 1808 |
1982 def del_player(self,id,group_id): | 1809 def del_player(self,id,group_id): |
1983 try: | 1810 try: |
1984 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name) | 1811 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name) |
1985 self.players[id].disconnect() | 1812 self.players[id].disconnect() |
1986 self.groups[group_id].remove_player(id) | 1813 self.groups[group_id].remove_player(id) |
1987 del self.players[id] | 1814 del self.players[id] |
1988 self.log_msg(dmsg) | 1815 self.log_msg(dmsg) |
1989 self.log_msg(("disconnect",id)) | 1816 self.log_msg(("disconnect",id)) |
1990 | 1817 """ |
1991 | |
1992 # If already registered then re-register, thereby updating the Meta | 1818 # If already registered then re-register, thereby updating the Meta |
1993 # on the number of players | 1819 # on the number of players |
1994 # Note: Upon server shutdown, the server is first unregistered, so | 1820 # Note: Upon server shutdown, the server is first unregistered, so |
1995 # this code won't be repeated for each player being deleted. | 1821 # this code won't be repeated for each player being deleted. |
1822 """ | |
1996 if self.be_registered: | 1823 if self.be_registered: |
1997 self.register() | 1824 self.register() |
1998 | 1825 except Exception, e: self.log_msg(str(e)) |
1999 | |
2000 except Exception, e: | |
2001 self.log_msg(str(e)) | |
2002 | |
2003 self.log_msg("Explicit garbage collection shows %s undeletable items." % str(gc.collect())) | 1826 self.log_msg("Explicit garbage collection shows %s undeletable items." % str(gc.collect())) |
2004 | |
2005 | |
2006 | 1827 |
2007 def incoming_player_handler(self,xml_dom,data): | 1828 def incoming_player_handler(self,xml_dom,data): |
2008 id = xml_dom.getAttribute("id") | 1829 id = xml_dom.getAttribute("id") |
2009 act = xml_dom.getAttribute("action") | 1830 act = xml_dom.getAttribute("action") |
2010 #group_id = xml_dom.getAttribute("group_id") | 1831 #group_id = xml_dom.getAttribute("group_id") |
2011 group_id = self.players[id].group_id | 1832 group_id = self.players[id].group_id |
2012 ip = self.players[id].ip | 1833 ip = self.players[id].ip |
2013 self.log_msg("Player with IP: " + str(ip) + " joined.") | 1834 self.log_msg("Player with IP: " + str(ip) + " joined.") |
2014 | |
2015 ServerPlugins.setPlayer(self.players[id]) | 1835 ServerPlugins.setPlayer(self.players[id]) |
2016 | |
2017 self.send_to_group(id,group_id,data) | 1836 self.send_to_group(id,group_id,data) |
2018 if act=="new": | 1837 if act=="new": |
2019 try: | 1838 try: |
2020 self.send_player_list(id,group_id) | 1839 self.send_player_list(id,group_id) |
2021 self.send_group_list(id) | 1840 self.send_group_list(id) |
2022 except Exception, e: | 1841 except Exception, e: traceback.print_exc() |
2023 traceback.print_exc() | |
2024 elif act=="del": | 1842 elif act=="del": |
2025 #print "del player" | 1843 #print "del player" |
2026 self.del_player(id,group_id) | 1844 self.del_player(id,group_id) |
2027 self.check_group(id, group_id) | 1845 self.check_group(id, group_id) |
2028 elif act=="update": | 1846 elif act=="update": |
2037 "boot": xml_dom.getAttribute("rm_boot"), | 1855 "boot": xml_dom.getAttribute("rm_boot"), |
2038 "version": xml_dom.getAttribute("version"), | 1856 "version": xml_dom.getAttribute("version"), |
2039 "ping": xml_dom.getAttribute("time") \ | 1857 "ping": xml_dom.getAttribute("time") \ |
2040 })) | 1858 })) |
2041 | 1859 |
2042 | |
2043 def strip_cheat_roll(self, string): | 1860 def strip_cheat_roll(self, string): |
2044 try: | 1861 try: |
2045 cheat_regex = re.compile('&#91;(.*?)&#93;') | 1862 cheat_regex = re.compile('&#91;(.*?)&#93;') |
2046 string = cheat_regex.sub( r'[ ' + self.cheat_msg + " \\1 " + self.cheat_msg + ' ]', string) | 1863 string = cheat_regex.sub( r'[ ' + self.cheat_msg + " \\1 " + self.cheat_msg + ' ]', string) |
2047 except: | 1864 except: pass |
2048 pass | |
2049 return string | 1865 return string |
2050 | 1866 |
2051 def strip_body_tags(self, string): | 1867 def strip_body_tags(self, string): |
2052 try: | 1868 try: |
2053 bodytag_regex = re.compile('<\/?body(.*?)>') | 1869 bodytag_regex = re.compile('<\/?body(.*?)>') |
2054 string = bodytag_regex.sub('', string) | 1870 string = bodytag_regex.sub('', string) |
2055 except: | 1871 except: pass |
2056 pass | |
2057 return string | 1872 return string |
2058 | 1873 |
2059 def msgTooLong(self, length): | 1874 def msgTooLong(self, length): |
2060 if length > self.maxSendSize and not self.maxSendSize == 0: | 1875 if length > self.maxSendSize and not self.maxSendSize == 0: return True |
2061 return True | |
2062 return False | 1876 return False |
2063 | 1877 |
2064 def incoming_msg_handler(self,xml_dom,data): | 1878 def incoming_msg_handler(self,xml_dom,data): |
2065 xml_dom, data = ServerPlugins.preParseIncoming(xml_dom, data) | 1879 xml_dom, data = ServerPlugins.preParseIncoming(xml_dom, data) |
2066 | |
2067 to_id = xml_dom.getAttribute("to") | 1880 to_id = xml_dom.getAttribute("to") |
2068 from_id = xml_dom.getAttribute("from") | 1881 from_id = xml_dom.getAttribute("from") |
2069 group_id = xml_dom.getAttribute("group_id") | 1882 group_id = xml_dom.getAttribute("group_id") |
2070 end = data.find(">") | 1883 end = data.find(">") |
2071 msg = data[end+1:] | 1884 msg = data[end+1:] |
2072 | 1885 |
2073 if from_id == "0" or len(from_id) == 0: | 1886 if from_id == "0" or len(from_id) == 0: |
2074 print "WARNING!! Message received with an invalid from_id. Message dropped." | 1887 print "WARNING!! Message received with an invalid from_id. Message dropped." |
2075 return None | 1888 return None |
2076 | 1889 |
2077 # | 1890 """ check for < body to prevent someone from changing the background""" |
2078 # check for < body to prevent someone from changing the background | |
2079 # | |
2080 | |
2081 data = self.strip_body_tags(data) | 1891 data = self.strip_body_tags(data) |
2082 | 1892 |
2083 # | 1893 """check for [ and ] codes which are often used to cheat with dice.""" |
2084 # check for [ and ] codes which are often used to cheat with dice. | |
2085 # | |
2086 if self.players[from_id].role != "GM": | 1894 if self.players[from_id].role != "GM": |
2087 data = self.strip_cheat_roll(data) | 1895 data = self.strip_cheat_roll(data) |
2088 | 1896 |
2089 if group_id == '0' and self.msgTooLong(len(msg) and msg[:5] == '<chat'): | 1897 if group_id == '0' and self.msgTooLong(len(msg) and msg[:5] == '<chat'): |
2090 self.send("Your message was too long, break it up into smaller parts please", from_id, group_id) | 1898 self.send("Your message was too long, break it up into smaller parts please", from_id, group_id) |
2108 | 1916 |
2109 else: | 1917 else: |
2110 if to_id == 'all': | 1918 if to_id == 'all': |
2111 if self.groups[group_id].moderated and not self.groups[group_id].voice.has_key(from_id): | 1919 if self.groups[group_id].moderated and not self.groups[group_id].voice.has_key(from_id): |
2112 self.players[from_id].self_message('This room is moderated - message not sent to others') | 1920 self.players[from_id].self_message('This room is moderated - message not sent to others') |
2113 else: | 1921 else: self.send_to_group(from_id,group_id,data) |
2114 self.send_to_group(from_id,group_id,data) | 1922 else: self.players[to_id].outbox.put(data) |
2115 else: | |
2116 self.players[to_id].outbox.put(data) | |
2117 | |
2118 self.check_group_members(group_id) | 1923 self.check_group_members(group_id) |
2119 return | 1924 return |
2120 | 1925 |
2121 def sound_msg_handler(self, xml_dom, data): | 1926 def sound_msg_handler(self, xml_dom, data): |
2122 from_id = xml_dom.getAttribute("from") | 1927 from_id = xml_dom.getAttribute("from") |
2123 group_id = xml_dom.getAttribute("group_id") | 1928 group_id = xml_dom.getAttribute("group_id") |
2124 if group_id != 0: | 1929 if group_id != 0: self.send_to_group(from_id, group_id, data) |
2125 self.send_to_group(from_id, group_id, data) | |
2126 | 1930 |
2127 def plugin_msg_handler(self,xml_dom,data): | 1931 def plugin_msg_handler(self,xml_dom,data): |
2128 to_id = xml_dom.getAttribute("to") | 1932 to_id = xml_dom.getAttribute("to") |
2129 from_id = xml_dom.getAttribute("from") | 1933 from_id = xml_dom.getAttribute("from") |
2130 group_id = xml_dom.getAttribute("group_id") | 1934 group_id = xml_dom.getAttribute("group_id") |
2132 msg = data[end+1:] | 1936 msg = data[end+1:] |
2133 | 1937 |
2134 if from_id == "0" or len(from_id) == 0: | 1938 if from_id == "0" or len(from_id) == 0: |
2135 print "WARNING!! Message received with an invalid from_id. Message dropped." | 1939 print "WARNING!! Message received with an invalid from_id. Message dropped." |
2136 return None | 1940 return None |
2137 | |
2138 | |
2139 if to_id == 'all': | 1941 if to_id == 'all': |
2140 if self.groups[group_id].moderated and not self.groups[group_id].voice.has_key(from_id): | 1942 if self.groups[group_id].moderated and not self.groups[group_id].voice.has_key(from_id): |
2141 self.players[from_id].self_message('This room is moderated - message not sent to others') | 1943 self.players[from_id].self_message('This room is moderated - message not sent to others') |
2142 else: | 1944 else: self.send_to_group(from_id, group_id, msg) |
2143 self.send_to_group(from_id, group_id, msg) | 1945 else: self.players[to_id].outbox.put(msg) |
2144 else: | |
2145 self.players[to_id].outbox.put(msg) | |
2146 | |
2147 self.check_group_members(group_id) | 1946 self.check_group_members(group_id) |
2148 return | 1947 return |
2149 | 1948 |
2150 def handle_role(self, act, player, role, given_boot_pwd, group_id): | 1949 def handle_role(self, act, player, role, given_boot_pwd, group_id): |
2151 if act == "display": | 1950 if act == "display": |
2152 msg = "<msg to=\"" + player + "\" from=\"0\" group_id=\"" + group_id + "\" />" | 1951 msg = "<msg to=\"" + player + "\" from=\"0\" group_id=\"" + group_id + "\" />" |
2153 msg += "Displaying Roles<br /><br /><u>Role</u>   <u>Player</u><br />" | 1952 msg += "Displaying Roles<br /><br /><u>Role</u>   <u>Player</u><br />" |
2154 keys = self.players.keys() | 1953 keys = self.players.keys() |
2155 for m in keys: | 1954 for m in keys: |
2156 if self.players[m].group_id == group_id: | 1955 if self.players[m].group_id == group_id: msg += self.players[m].role + " " + self.players[m].name + "<br />" |
2157 msg += self.players[m].role + " " + self.players[m].name + "<br />" | |
2158 self.send(msg,player,group_id) | 1956 self.send(msg,player,group_id) |
2159 elif act == "set": | 1957 elif act == "set": |
2160 try: | 1958 try: |
2161 actual_boot_pwd = self.groups[group_id].boot_pwd | 1959 actual_boot_pwd = self.groups[group_id].boot_pwd |
2162 if self.players[player].group_id == group_id: | 1960 if self.players[player].group_id == group_id: |
2165 | 1963 |
2166 # Send update role event to all | 1964 # Send update role event to all |
2167 msg = "<role action=\"update\" id=\"" + player + "\" role=\"" + role + "\" />" | 1965 msg = "<role action=\"update\" id=\"" + player + "\" role=\"" + role + "\" />" |
2168 self.send_to_group("0", group_id, msg) | 1966 self.send_to_group("0", group_id, msg) |
2169 self.players[player].role = role | 1967 self.players[player].role = role |
2170 if (role.lower() == "gm" or role.lower() == "player"): | 1968 if (role.lower() == "gm" or role.lower() == "player"): self.groups[group_id].voice[player]=1 |
2171 self.groups[group_id].voice[player]=1 | |
2172 else: | 1969 else: |
2173 #tell the clients password manager the password failed -- SD 8/03 | 1970 #tell the clients password manager the password failed -- SD 8/03 |
2174 pm = "<password signal=\"fail\" type=\"admin\" id=\"" + group_id + "\" data=\"\"/>" | 1971 pm = "<password signal=\"fail\" type=\"admin\" id=\"" + group_id + "\" data=\"\"/>" |
2175 self.players[player].outbox.put(pm) | 1972 self.players[player].outbox.put(pm) |
2176 self.log_msg( "Administrator passwords did not match") | 1973 self.log_msg( "Administrator passwords did not match") |
2196 traceback.print_exc() | 1993 traceback.print_exc() |
2197 | 1994 |
2198 try: | 1995 try: |
2199 actual_boot_pwd = self.groups[group_id].boot_pwd | 1996 actual_boot_pwd = self.groups[group_id].boot_pwd |
2200 server_admin_pwd = self.groups["0"].boot_pwd | 1997 server_admin_pwd = self.groups["0"].boot_pwd |
2201 | |
2202 self.log_msg("Actual boot pwd = " + actual_boot_pwd) | 1998 self.log_msg("Actual boot pwd = " + actual_boot_pwd) |
2203 self.log_msg("Given boot pwd = " + given_boot_pwd) | 1999 self.log_msg("Given boot pwd = " + given_boot_pwd) |
2204 | 2000 |
2205 if self.players[to_id].group_id == group_id: | 2001 if self.players[to_id].group_id == group_id: |
2206 | 2002 """ |
2207 ### ---CHANGES BY SNOWDOG 4/03 --- | 2003 ### ---CHANGES BY SNOWDOG 4/03 --- |
2208 ### added boot to lobby code. | 2004 ### added boot to lobby code. |
2209 ### if boot comes from lobby dump player from the server | 2005 ### if boot comes from lobby dump player from the server |
2210 ### any user in-room boot will dump to lobby instead | 2006 ### any user in-room boot will dump to lobby instead |
2007 """ | |
2211 if given_boot_pwd == server_admin_pwd: | 2008 if given_boot_pwd == server_admin_pwd: |
2212 # Send a message to everyone in the room, letting them know someone has been booted | 2009 # Send a message to everyone in the room, letting them know someone has been booted |
2213 boot_msg = "<msg to='all' from='%s' group_id='%s'/><font color='#FF0000'>Booting '(%s) %s' from server...</font>" % (from_id, group_id, to_id, self.players[to_id].name) | 2010 boot_msg = "<msg to='all' from='%s' group_id='%s'/><font color='#FF0000'>Booting '(%s) %s' from server...</font>" % (from_id, group_id, to_id, self.players[to_id].name) |
2214 | |
2215 self.log_msg("boot_msg:" + boot_msg) | 2011 self.log_msg("boot_msg:" + boot_msg) |
2216 | |
2217 self.send_to_group( "0", group_id, boot_msg ) | 2012 self.send_to_group( "0", group_id, boot_msg ) |
2218 time.sleep( 1 ) | 2013 time.sleep( 1 ) |
2219 | |
2220 self.log_msg("Booting player " + str(to_id) + " from server.") | 2014 self.log_msg("Booting player " + str(to_id) + " from server.") |
2221 | 2015 |
2222 # Send delete player event to all | 2016 # Send delete player event to all |
2223 self.send_to_group("0",group_id,self.players[to_id].toxml("del")) | 2017 self.send_to_group("0",group_id,self.players[to_id].toxml("del")) |
2224 | 2018 |
2229 self.check_group(to_id, group_id) | 2023 self.check_group(to_id, group_id) |
2230 | 2024 |
2231 elif actual_boot_pwd == given_boot_pwd: | 2025 elif actual_boot_pwd == given_boot_pwd: |
2232 # Send a message to everyone in the room, letting them know someone has been booted | 2026 # Send a message to everyone in the room, letting them know someone has been booted |
2233 boot_msg = "<msg to='all' from='%s' group_id='%s'/><font color='#FF0000'>Booting '(%s) %s' from room...</font>" % (from_id, group_id, to_id, self.players[to_id].name) | 2027 boot_msg = "<msg to='all' from='%s' group_id='%s'/><font color='#FF0000'>Booting '(%s) %s' from room...</font>" % (from_id, group_id, to_id, self.players[to_id].name) |
2234 | |
2235 self.log_msg("boot_msg:" + boot_msg) | 2028 self.log_msg("boot_msg:" + boot_msg) |
2236 | |
2237 self.send_to_group( "0", group_id, boot_msg ) | 2029 self.send_to_group( "0", group_id, boot_msg ) |
2238 time.sleep( 1 ) | 2030 time.sleep( 1 ) |
2239 | 2031 |
2240 #dump player into the lobby | 2032 #dump player into the lobby |
2241 self.move_player(to_id,"0") | 2033 self.move_player(to_id,"0") |
2252 traceback.print_exc() | 2044 traceback.print_exc() |
2253 self.log_msg('Exception in handle_boot() ' + str(e)) | 2045 self.log_msg('Exception in handle_boot() ' + str(e)) |
2254 | 2046 |
2255 finally: | 2047 finally: |
2256 try: | 2048 try: |
2257 if xml_dom: | 2049 if xml_dom: xml_dom.unlink() |
2258 xml_dom.unlink() | |
2259 except Exception, e: | 2050 except Exception, e: |
2260 traceback.print_exc() | 2051 traceback.print_exc() |
2261 self.log_msg('Exception in xml_dom.unlink() ' + str(e)) | 2052 self.log_msg('Exception in xml_dom.unlink() ' + str(e)) |
2262 | 2053 |
2263 | 2054 """ |
2264 #--------------------------------------------------------------- | |
2265 # admin_kick function -- by Snowdog 4/03 | 2055 # admin_kick function -- by Snowdog 4/03 |
2266 # 9/17/05 updated to allow stealth boots (no client chat announce) -SD | 2056 # 9/17/05 updated to allow stealth boots (no client chat announce) -SD |
2267 #--------------------------------------------------------------- | 2057 """ |
2268 def admin_kick(self, id, message="", silent = 0 ): | 2058 def admin_kick(self, id, message="", silent = 0 ): |
2269 "Kick a player from a server from the console" | 2059 "Kick a player from a server from the console" |
2270 | 2060 |
2271 try: | 2061 try: |
2272 group_id = self.players[id].group_id | 2062 group_id = self.players[id].group_id |
2273 # Send a message to everyone in the victim's room, letting them know someone has been booted | 2063 # Send a message to everyone in the victim's room, letting them know someone has been booted |
2274 boot_msg = "<msg to='all' from='0' group_id='%s'/><font color='#FF0000'>Kicking '(%s) %s' from server... %s</font>" % ( group_id, id, self.players[id].name, str(message)) | 2064 boot_msg = "<msg to='all' from='0' group_id='%s'/><font color='#FF0000'>Kicking '(%s) %s' from server... %s</font>" % ( group_id, id, self.players[id].name, str(message)) |
2275 self.log_msg("boot_msg:" + boot_msg) | 2065 self.log_msg("boot_msg:" + boot_msg) |
2276 if (silent == 0): | 2066 if (silent == 0): self.send_to_group( "0", group_id, boot_msg ) |
2277 self.send_to_group( "0", group_id, boot_msg ) | |
2278 time.sleep( 1 ) | 2067 time.sleep( 1 ) |
2279 | 2068 |
2280 self.log_msg("kicking player " + str(id) + " from server.") | 2069 self.log_msg("kicking player " + str(id) + " from server.") |
2281 # Send delete player event to all | 2070 # Send delete player event to all |
2282 self.send_to_group("0",group_id,self.players[id].toxml("del")) | 2071 self.send_to_group("0",group_id,self.players[id].toxml("del")) |
2288 self.check_group(id, group_id) | 2077 self.check_group(id, group_id) |
2289 | 2078 |
2290 except Exception, e: | 2079 except Exception, e: |
2291 traceback.print_exc() | 2080 traceback.print_exc() |
2292 self.log_msg('Exception in admin_kick() ' + str(e)) | 2081 self.log_msg('Exception in admin_kick() ' + str(e)) |
2293 | |
2294 | 2082 |
2295 def admin_banip(self, ip, name="", silent = 0): | 2083 def admin_banip(self, ip, name="", silent = 0): |
2296 "Ban a player from a server from the console" | 2084 "Ban a player from a server from the console" |
2297 try: | 2085 try: |
2298 self.ban_list[ip] = {} | 2086 self.ban_list[ip] = {} |
2336 traceback.print_exc() | 2124 traceback.print_exc() |
2337 self.log_msg('Exception in admin_ban() ' + str(e)) | 2125 self.log_msg('Exception in admin_ban() ' + str(e)) |
2338 | 2126 |
2339 def admin_unban(self, ip): | 2127 def admin_unban(self, ip): |
2340 try: | 2128 try: |
2341 if self.ban_list.has_key(ip): | 2129 if self.ban_list.has_key(ip): del self.ban_list[ip] |
2342 del self.ban_list[ip] | |
2343 | |
2344 self.saveBanList() | 2130 self.saveBanList() |
2345 | 2131 |
2346 except Exception, e: | 2132 except Exception, e: |
2347 traceback.print_exc() | 2133 traceback.print_exc() |
2348 self.log_msg('Exception in admin_unban() ' + str(e)) | 2134 self.log_msg('Exception in admin_unban() ' + str(e)) |
2355 msg.append(self.ban_list[ip]['name']) | 2141 msg.append(self.ban_list[ip]['name']) |
2356 msg.append("</td><td>") | 2142 msg.append("</td><td>") |
2357 msg.append(self.ban_list[ip]['ip']) | 2143 msg.append(self.ban_list[ip]['ip']) |
2358 msg.append("</td></tr>") | 2144 msg.append("</td></tr>") |
2359 msg.append("</table>") | 2145 msg.append("</table>") |
2360 | |
2361 return "".join(msg) | 2146 return "".join(msg) |
2362 | 2147 |
2363 def admin_toggleSound(self): | 2148 def admin_toggleSound(self): |
2364 if self.sendLobbySound: | 2149 if self.sendLobbySound: self.sendLobbySound = False |
2365 self.sendLobbySound = False | 2150 else: self.sendLobbySound = True |
2366 else: | |
2367 self.sendLobbySound = True | |
2368 | |
2369 return self.sendLobbySound | 2151 return self.sendLobbySound |
2370 | 2152 |
2371 def admin_soundFile(self, file): | 2153 def admin_soundFile(self, file): |
2372 self.lobbySound = file | 2154 self.lobbySound = file |
2373 | 2155 |
2382 return "Invalid Room Id. Ignoring remove request." | 2164 return "Invalid Room Id. Ignoring remove request." |
2383 | 2165 |
2384 self.groups[group].persistant = 0 | 2166 self.groups[group].persistant = 0 |
2385 try: | 2167 try: |
2386 keys = self.groups[group].get_player_ids() | 2168 keys = self.groups[group].get_player_ids() |
2387 for k in keys: | 2169 for k in keys: self.del_player(k, str(group)) |
2388 self.del_player(k, str(group)) | |
2389 self.check_group("0", str(group)) | 2170 self.check_group("0", str(group)) |
2390 except: | 2171 except: pass |
2391 pass | |
2392 | 2172 |
2393 def send(self,msg,player,group): | 2173 def send(self,msg,player,group): |
2394 self.players[player].send(msg,player,group) | 2174 self.players[player].send(msg,player,group) |
2395 | |
2396 | 2175 |
2397 def send_to_all(self,from_id,data): | 2176 def send_to_all(self,from_id,data): |
2398 try: | 2177 try: |
2399 print data | 2178 print data |
2400 self.p_lock.acquire() | 2179 self.p_lock.acquire() |
2401 keys = self.players.keys() | 2180 keys = self.players.keys() |
2402 self.p_lock.release() | 2181 self.p_lock.release() |
2403 for k in keys: | 2182 for k in keys: |
2404 if k != from_id: | 2183 if k != from_id: self.players[k].outbox.put(data) |
2405 self.players[k].outbox.put(data) | |
2406 except Exception, e: | 2184 except Exception, e: |
2407 traceback.print_exc() | 2185 traceback.print_exc() |
2408 self.log_msg("Exception: send_to_all(): " + str(e)) | 2186 self.log_msg("Exception: send_to_all(): " + str(e)) |
2409 | 2187 |
2410 def send_to_group(self, from_id, group_id, data): | 2188 def send_to_group(self, from_id, group_id, data): |
2413 try: | 2191 try: |
2414 self.p_lock.acquire() | 2192 self.p_lock.acquire() |
2415 keys = self.groups[group_id].get_player_ids() | 2193 keys = self.groups[group_id].get_player_ids() |
2416 self.p_lock.release() | 2194 self.p_lock.release() |
2417 for k in keys: | 2195 for k in keys: |
2418 if k != from_id: | 2196 if k != from_id: self.players[k].outbox.put(data) |
2419 self.players[k].outbox.put(data) | |
2420 except Exception, e: | 2197 except Exception, e: |
2421 traceback.print_exc() | 2198 traceback.print_exc() |
2422 self.log_msg("Exception: send_to_group(): " + str(e)) | 2199 self.log_msg("Exception: send_to_group(): " + str(e)) |
2423 | 2200 |
2424 def send_player_list(self,to_id,group_id): | 2201 def send_player_list(self,to_id,group_id): |
2439 self.players[to_id].outbox.put(xml) | 2216 self.players[to_id].outbox.put(xml) |
2440 except Exception, e: | 2217 except Exception, e: |
2441 self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e)) | 2218 self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e)) |
2442 traceback.print_exc() | 2219 traceback.print_exc() |
2443 | 2220 |
2444 #-------------------------------------------------------------------------- | 2221 """ |
2445 # KICK_ALL_CLIENTS() | 2222 # KICK_ALL_CLIENTS() |
2446 # | 2223 # |
2447 # Convience method for booting all clients off the server at once. | 2224 # Convience method for booting all clients off the server at once. |
2448 # used while troubleshooting mysterious "black hole" server bug | 2225 # used while troubleshooting mysterious "black hole" server bug |
2449 # Added by Snowdog 11-19-04 | 2226 # Added by Snowdog 11-19-04 |
2227 """ | |
2450 def kick_all_clients(self): | 2228 def kick_all_clients(self): |
2451 try: | 2229 try: |
2452 keys = self.groups.keys() | 2230 keys = self.groups.keys() |
2453 for k in keys: | 2231 for k in keys: |
2454 pl = self.groups[k].get_player_ids() | 2232 pl = self.groups[k].get_player_ids() |
2455 for p in pl: | 2233 for p in pl: self.admin_kick(p,"Purged from server") |
2456 self.admin_kick(p,"Purged from server") | |
2457 except Exception, e: | 2234 except Exception, e: |
2458 traceback.print_exc() | 2235 traceback.print_exc() |
2459 self.log_msg("Exception: kick_all_clients(): " + str(e)) | 2236 self.log_msg("Exception: kick_all_clients(): " + str(e)) |
2460 | 2237 |
2461 | 2238 """ |
2462 # This really has little value as it will only catch people that are hung | 2239 # This really has little value as it will only catch people that are hung |
2463 # on a disconnect which didn't complete. Other idle connections which are | 2240 # on a disconnect which didn't complete. Other idle connections which are |
2464 # really dead go undeterred. | 2241 # really dead go undeterred. |
2465 # | 2242 # |
2466 # UPDATED 11-29-04: Changed remove XML send to forced admin_kick for 'dead clients' | 2243 # UPDATED 11-29-04: Changed remove XML send to forced admin_kick for 'dead clients' |
2467 # Dead clients now removed more effeciently as soon as they are detected | 2244 # Dead clients now removed more effeciently as soon as they are detected |
2468 # --Snowdog | 2245 # --Snowdog |
2246 """ | |
2469 def check_group_members(self, group_id): | 2247 def check_group_members(self, group_id): |
2470 try: | 2248 try: |
2471 keys = self.groups[group_id].get_player_ids() | 2249 keys = self.groups[group_id].get_player_ids() |
2472 for k in keys: | 2250 for k in keys: |
2473 #drop any clients that are idle for more than 8 hours | 2251 #drop any clients that are idle for more than 8 hours |
2474 #as these are likely dead clients | 2252 #as these are likely dead clients |
2475 idlemins = self.players[k].idle_time() | 2253 idlemins = self.players[k].idle_time() |
2476 idlemins = idlemins/60 | 2254 idlemins = idlemins/60 |
2477 if (idlemins > self.zombie_time): | 2255 if (idlemins > self.zombie_time): self.admin_kick(k,"Removing zombie client", self.silent_auto_kick) |
2478 self.admin_kick(k,"Removing zombie client", self.silent_auto_kick) | |
2479 elif self.players[k].get_status() != MPLAY_CONNECTED: | 2256 elif self.players[k].get_status() != MPLAY_CONNECTED: |
2480 if self.players[k].check_time_out(): | 2257 if self.players[k].check_time_out(): |
2481 self.log_msg("Player #" + k + " Lost connection!") | 2258 self.log_msg("Player #" + k + " Lost connection!") |
2482 self.admin_kick(k,"Removing dead client", self.silent_auto_kick) | 2259 self.admin_kick(k,"Removing dead client", self.silent_auto_kick) |
2483 except Exception, e: | 2260 except Exception, e: |
2484 self.log_msg("Exception: check_group_members(): " + str(e)) | 2261 self.log_msg("Exception: check_group_members(): " + str(e)) |
2485 | 2262 |
2486 | 2263 |
2487 def remote_admin_handler(self,xml_dom,data): | 2264 def remote_admin_handler(self,xml_dom,data): |
2265 """ | |
2488 # handle incoming remove server admin messages | 2266 # handle incoming remove server admin messages |
2489 # (allows basic administration of server from a remote client) | 2267 # (allows basic administration of server from a remote client) |
2490 # base message format: <admin id="" pwd="" cmd="" [data for command]> | 2268 # base message format: <admin id="" pwd="" cmd="" [data for command]> |
2491 | 2269 """ |
2492 if not self.allowRemoteAdmin: | 2270 if not self.allowRemoteAdmin: return |
2493 return | |
2494 | |
2495 try: | 2271 try: |
2496 pid = xml_dom.getAttribute("id") | 2272 pid = xml_dom.getAttribute("id") |
2497 gid = "" | 2273 gid = "" |
2498 given_pwd = xml_dom.getAttribute("pwd") | 2274 given_pwd = xml_dom.getAttribute("pwd") |
2499 cmd = xml_dom.getAttribute("cmd") | 2275 cmd = xml_dom.getAttribute("cmd") |
2500 server_admin_pwd = self.groups["0"].boot_pwd | 2276 server_admin_pwd = self.groups["0"].boot_pwd |
2501 p_id = "" | 2277 p_id = "" |
2502 p_name= "" | 2278 p_name= "" |
2503 p_ip = "" | 2279 p_ip = "" |
2504 | |
2505 | 2280 |
2506 #verify that the message came from the proper ID/Socket and get IP address for logging | 2281 #verify that the message came from the proper ID/Socket and get IP address for logging |
2507 if self.players.has_key(pid): | 2282 if self.players.has_key(pid): |
2508 p_name=(self.players[pid]).name | 2283 p_name=(self.players[pid]).name |
2509 p_ip=(self.players[pid]).ip | 2284 p_ip=(self.players[pid]).ip |
2522 #dump and log any attempts to control server remotely with invalid password | 2297 #dump and log any attempts to control server remotely with invalid password |
2523 if server_admin_pwd != given_pwd: | 2298 if server_admin_pwd != given_pwd: |
2524 #tell the clients password manager the password failed -- SD 8/03 | 2299 #tell the clients password manager the password failed -- SD 8/03 |
2525 pm = "<password signal=\"fail\" type=\"server\" id=\"" + str(self.players[pid].group_id) + "\" data=\"\"/>" | 2300 pm = "<password signal=\"fail\" type=\"server\" id=\"" + str(self.players[pid].group_id) + "\" data=\"\"/>" |
2526 self.players[pid].outbox.put(pm) | 2301 self.players[pid].outbox.put(pm) |
2527 m = "Invalid Remote Server Control Message (bad password) from #" + str(pid) + " (" + str(p_name) + ") " + str(p_ip) | 2302 m = "Invalid Remote Server Control Message (bad password) from " |
2303 m += "#" + str(pid) + " (" + str(p_name) + ") " + str(p_ip) | |
2528 self.log_msg( m ) | 2304 self.log_msg( m ) |
2529 return | 2305 return |
2530 | 2306 |
2531 #message now deemed 'authentic' | 2307 #message now deemed 'authentic' |
2532 #determine action to take based on command (cmd) | 2308 #determine action to take based on command (cmd) |
2533 | |
2534 if cmd == "list": | 2309 if cmd == "list": |
2535 #return player list to this user. | 2310 #return player list to this user. |
2536 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.player_list_remote() | 2311 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.player_list_remote() |
2537 self.players[pid].outbox.put(msg) | 2312 self.players[pid].outbox.put(msg) |
2538 | |
2539 elif cmd == "banip": | 2313 elif cmd == "banip": |
2540 ip = xml_dom.getAttribute("bip") | 2314 ip = xml_dom.getAttribute("bip") |
2541 name = xml_dom.getAttribute("bname") | 2315 name = xml_dom.getAttribute("bname") |
2542 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Banned: " + str(ip) | 2316 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Banned: " + str(ip) |
2543 self.admin_banip(ip, name) | 2317 self.admin_banip(ip, name) |
2544 | |
2545 elif cmd == "ban": | 2318 elif cmd == "ban": |
2546 id = xml_dom.getAttribute("bid") | 2319 id = xml_dom.getAttribute("bid") |
2547 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Banned!" | 2320 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Banned!" |
2548 self.players[pid].outbox.put(msg) | 2321 self.players[pid].outbox.put(msg) |
2549 self.admin_ban(id, "") | 2322 self.admin_ban(id, "") |
2550 | |
2551 elif cmd == "unban": | 2323 elif cmd == "unban": |
2552 ip = xml_dom.getAttribute("ip") | 2324 ip = xml_dom.getAttribute("ip") |
2553 self.admin_unban(ip) | 2325 self.admin_unban(ip) |
2554 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Unbaned: " + str(ip) | 2326 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Unbaned: " + str(ip) |
2555 self.players[pid].outbox.put(msg) | 2327 self.players[pid].outbox.put(msg) |
2556 | |
2557 elif cmd == "banlist": | 2328 elif cmd == "banlist": |
2558 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.admin_banlist() | 2329 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.admin_banlist() |
2559 self.players[pid].outbox.put(msg) | 2330 self.players[pid].outbox.put(msg) |
2560 | |
2561 elif cmd == "killgroup": | 2331 elif cmd == "killgroup": |
2562 ugid = xml_dom.getAttribute("gid") | 2332 ugid = xml_dom.getAttribute("gid") |
2563 if ugid == "0": | 2333 if ugid == "0": |
2564 m = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>Cannot Remove Lobby! Remote administrator request denied!" | 2334 m = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2335 m += "Cannot Remove Lobby! Remote administrator request denied!" | |
2565 self.players[pid].outbox.put(m) | 2336 self.players[pid].outbox.put(m) |
2566 else: | 2337 else: |
2567 result = self.prune_room(ugid) | 2338 result = self.prune_room(ugid) |
2568 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + str(result) | 2339 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + str(result) |
2569 self.players[pid].outbox.put(msg) | 2340 self.players[pid].outbox.put(msg) |
2574 pmsg = "<msg to='" + tuid + "' from='0' group_id='" + self.players[tuid].group_id + "' >" + msg | 2345 pmsg = "<msg to='" + tuid + "' from='0' group_id='" + self.players[tuid].group_id + "' >" + msg |
2575 try: self.players[tuid].outbox.put(pmsg) | 2346 try: self.players[tuid].outbox.put(pmsg) |
2576 except: | 2347 except: |
2577 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + ">Unknown Player ID: No message sent." | 2348 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + ">Unknown Player ID: No message sent." |
2578 self.players[pid].outbox.put(msg) | 2349 self.players[pid].outbox.put(msg) |
2579 | |
2580 elif cmd == "broadcast": | 2350 elif cmd == "broadcast": |
2581 bmsg = xml_dom.getAttribute("msg") | 2351 bmsg = xml_dom.getAttribute("msg") |
2582 self.broadcast(bmsg) | 2352 self.broadcast(bmsg) |
2583 | |
2584 elif cmd == "killserver" and self.allowRemoteKill: | 2353 elif cmd == "killserver" and self.allowRemoteKill: |
2585 #dangerous command..once server stopped it must be restarted manually | 2354 #dangerous command..once server stopped it must be restarted manually |
2586 self.kill_server() | 2355 self.kill_server() |
2587 | |
2588 elif cmd == "uptime": | 2356 elif cmd == "uptime": |
2589 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.uptime(1) | 2357 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.uptime(1) |
2590 self.players[pid].outbox.put(msg) | 2358 self.players[pid].outbox.put(msg) |
2591 | |
2592 elif cmd == "help": | 2359 elif cmd == "help": |
2593 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" | 2360 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2594 msg += self.AdminHelpMessage() | 2361 msg += self.AdminHelpMessage() |
2595 self.players[pid].outbox.put( msg) | 2362 self.players[pid].outbox.put( msg) |
2596 | |
2597 elif cmd == "roompasswords": | 2363 elif cmd == "roompasswords": |
2598 # Toggle if room passwords are allowed on this server | 2364 # Toggle if room passwords are allowed on this server |
2599 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" | 2365 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2600 msg += self.RoomPasswords() | 2366 msg += self.RoomPasswords() |
2601 self.players[pid].outbox.put( msg) | 2367 self.players[pid].outbox.put( msg) |
2602 | |
2603 elif cmd == "createroom": | 2368 elif cmd == "createroom": |
2604 rm_name = xml_dom.getAttribute("name") | 2369 rm_name = xml_dom.getAttribute("name") |
2605 rm_pass = xml_dom.getAttribute("pass") | 2370 rm_pass = xml_dom.getAttribute("pass") |
2606 rm_boot = xml_dom.getAttribute("boot") | 2371 rm_boot = xml_dom.getAttribute("boot") |
2607 result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass) | 2372 result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass) |
2608 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + result | 2373 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + result |
2609 self.players[pid].outbox.put(msg) | 2374 self.players[pid].outbox.put(msg) |
2610 | |
2611 elif cmd == "nameroom": | 2375 elif cmd == "nameroom": |
2612 rm_id = xml_dom.getAttribute("rmid") | 2376 rm_id = xml_dom.getAttribute("rmid") |
2613 rm_name = xml_dom.getAttribute("name") | 2377 rm_name = xml_dom.getAttribute("name") |
2614 result = self.change_group_name(rm_id,rm_name,pid) | 2378 result = self.change_group_name(rm_id,rm_name,pid) |
2615 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'/>" + result | 2379 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'/>" + result |
2616 self.players[pid].outbox.put(msg) | 2380 self.players[pid].outbox.put(msg) |
2617 | |
2618 elif cmd == "passwd": | 2381 elif cmd == "passwd": |
2619 tgid = xml_dom.getAttribute("gid") | 2382 tgid = xml_dom.getAttribute("gid") |
2620 npwd = xml_dom.getAttribute("pass") | 2383 npwd = xml_dom.getAttribute("pass") |
2621 if tgid == "0": | 2384 if tgid == "0": |
2622 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Server password may not be changed remotely!" | 2385 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2386 msg += "Server password may not be changed remotely!" | |
2623 self.players[pid].outbox.put(msg) | 2387 self.players[pid].outbox.put(msg) |
2624 else: | 2388 else: |
2625 try: | 2389 try: |
2626 self.groups[tgid].boot_pwd = npwd | 2390 self.groups[tgid].boot_pwd = npwd |
2627 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Password changed for room " + tgid | 2391 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Password changed for room " + tgid |
2628 self.players[pid].outbox.put(msg) | 2392 self.players[pid].outbox.put(msg) |
2629 except: pass | 2393 except: pass |
2630 | |
2631 elif cmd == "savemaps": | 2394 elif cmd == "savemaps": |
2632 for g in self.groups.itervalues(): | 2395 for g in self.groups.itervalues(): |
2633 g.save_map() | 2396 g.save_map() |
2634 | |
2635 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Persistent room maps saved" | 2397 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Persistent room maps saved" |
2636 self.players[pid].outbox.put(msg) | 2398 self.players[pid].outbox.put(msg) |
2637 | |
2638 | |
2639 else: | 2399 else: |
2640 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'><i>[Unknown Remote Administration Command]</i>" | 2400 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'><i>[Unknown Remote Administration Command]</i>" |
2641 self.players[pid].outbox.put(msg) | 2401 self.players[pid].outbox.put(msg) |
2642 | |
2643 | |
2644 except Exception, e: | 2402 except Exception, e: |
2645 self.log_msg("Exception: Remote Admin Handler Error: " + str(e)) | 2403 self.log_msg("Exception: Remote Admin Handler Error: " + str(e)) |
2646 traceback.print_exc() | 2404 traceback.print_exc() |
2647 | 2405 |
2648 | |
2649 def toggleRemoteKill(self): | 2406 def toggleRemoteKill(self): |
2650 if self.allowRemoteKill: | 2407 if self.allowRemoteKill: self.allowRemoteKill = False |
2651 self.allowRemoteKill = False | 2408 else: self.allowRemoteKill = True |
2652 else: | |
2653 self.allowRemoteKill = True | |
2654 | |
2655 return self.allowRemoteKill | 2409 return self.allowRemoteKill |
2656 | 2410 |
2657 def toggleRemoteAdmin(self): | 2411 def toggleRemoteAdmin(self): |
2658 if self.allowRemoteAdmin: | 2412 if self.allowRemoteAdmin: self.allowRemoteAdmin = False |
2659 self.allowRemoteAdmin = False | 2413 else: self.allowRemoteAdmin = True |
2660 else: | |
2661 self.allowRemoteAdmin = True | |
2662 | |
2663 return self.allowRemoteAdmin | 2414 return self.allowRemoteAdmin |
2664 | 2415 |
2665 #----------------------------------------------------------------- | 2416 """ |
2666 # Remote Administrator Help (returns from server not client) | 2417 # Remote Administrator Help (returns from server not client) |
2667 #----------------------------------------------------------------- | 2418 """ |
2668 def AdminHelpMessage(self): | 2419 def AdminHelpMessage(self): |
2669 "returns a string to be sent as a message to a remote admin" | 2420 "returns a string to be sent as a message to a remote admin" |
2670 | |
2671 #define the help command list information | 2421 #define the help command list information |
2672 info = [] | 2422 info = [] |
2673 info.append( ['list', '/admin list', 'Displays information about rooms and players on the server'] ) | 2423 info.append( ['list', '/admin list', 'Displays information about rooms and players on the server'] ) |
2674 info.append( ['uptime', '/admin uptime', 'Information on how long server has been running'] ) | 2424 info.append( ['uptime', '/admin uptime', 'Information on how long server has been running'] ) |
2675 info.append( ['help', '/admin help', 'This help message']) | 2425 info.append( ['help', '/admin help', 'This help message']) |
2676 info.append( ['passwd', '/admin passwd <group id> <new password>', 'Changes a rooms bootpassword. Server(lobby) password may not be changed']) | 2426 info.append( ['passwd', '/admin passwd <group id> <new password>', |
2427 'Changes a rooms bootpassword. Server(lobby) password may not be changed']) | |
2677 info.append( ['roompasswords', '/admin roompasswords', 'Allow/Disallow Room Passwords on the server (toggles)']) | 2428 info.append( ['roompasswords', '/admin roompasswords', 'Allow/Disallow Room Passwords on the server (toggles)']) |
2678 info.append( ['message', '/admin message <user id> <message>', 'Send a message to a specific user on the server']) | 2429 info.append( ['message', '/admin message <user id> <message>', |
2430 'Send a message to a specific user on the server']) | |
2679 info.append( ['broadcast', '/admin broadcast <message>', 'Broadcast message to all players on server']) | 2431 info.append( ['broadcast', '/admin broadcast <message>', 'Broadcast message to all players on server']) |
2680 info.append( ['createroom', '/admin createroom <room name> <boot password> [password]', 'Creates a temporary persistant room if possible.<i>Rooms created this way are lost on server restarts']) | 2432 info.append( ['createroom', '/admin createroom <room name> <boot password> [password]', |
2433 'Creates a temporary persistant room if possible.<i>Rooms created this way are lost on server restarts']) | |
2681 info.append( ['nameroom', '/admin nameroom <group id> <new name>', 'Rename a room']) | 2434 info.append( ['nameroom', '/admin nameroom <group id> <new name>', 'Rename a room']) |
2682 info.append( ['killgroup', '/admin killgroup <room id>', 'Remove a room from the server and kick everyone in it.']) | 2435 info.append( ['killgroup', '/admin killgroup <room id>', |
2436 'Remove a room from the server and kick everyone in it.']) | |
2683 if self.allowRemoteKill: | 2437 if self.allowRemoteKill: |
2684 info.append( ['killserver', '/admin killserver', 'Shuts down the server. <b>WARNING: Server cannot be restarted remotely via OpenRPG</b>']) | 2438 info.append( ['killserver', '/admin killserver', |
2439 'Shuts down the server. <b>WARNING: Server cannot be restarted remotely via OpenRPG</b>']) | |
2685 info.append( ['ban', '/admin ban {playerId}', 'Ban a player from the server.']) | 2440 info.append( ['ban', '/admin ban {playerId}', 'Ban a player from the server.']) |
2686 info.append( ['unban', '/admin unban {bannedIP}', 'UnBan a player from the server.']) | 2441 info.append( ['unban', '/admin unban {bannedIP}', 'UnBan a player from the server.']) |
2687 info.append( ['banlist', '/admin banlist', 'List Banned IPs and the Names associated with them']) | 2442 info.append( ['banlist', '/admin banlist', 'List Banned IPs and the Names associated with them']) |
2688 info.append( ['savemaps', '/admin savemaps', 'Save all persistent room maps that are not using the default map file.']) | 2443 info.append( ['savemaps', '/admin savemaps', |
2689 | 2444 'Save all persistent room maps that are not using the default map file.']) |
2690 | 2445 |
2691 #define the HTML for the help display | 2446 #define the HTML for the help display |
2692 FS = "<font size='-1'>" | 2447 FS = "<font size='-1'>" |
2693 FE = "<font>" | 2448 FE = "<font>" |
2694 | |
2695 help = "<hr><B>REMOTE ADMINISTRATOR COMMANDS SUPPORTED</b><br /><br />" | 2449 help = "<hr><B>REMOTE ADMINISTRATOR COMMANDS SUPPORTED</b><br /><br />" |
2696 help += "<table border='1' cellpadding='2'>" | 2450 help += "<table border='1' cellpadding='2'>" |
2697 help += "<tr><td width='15%'><b>Command</b></td><td width='25%'><b>Format</b></td><td width='60%'><b>Description</b></td></tr>" | 2451 help += "<tr><td width='15%'><b>Command</b></td><td width='25%'><b>Format</b>" |
2452 help += "</td><td width='60%'><b>Description</b></td></tr>" | |
2698 for n in info: | 2453 for n in info: |
2699 help += "<tr><td>" + FS + n[0] + FE + "</td><td><nobr>" + FS + n[1] + FE + "</nobr></td><td>" + FS + n[2] + FE + "</td></tr>" | 2454 help += "<tr><td>" + FS + n[0] + FE + "</td><td><nobr>" + FS + n[1] + FE + "</nobr>" |
2455 help += "</td><td>" + FS + n[2] + FE + "</td></tr>" | |
2700 help += "</table>" | 2456 help += "</table>" |
2701 return help | 2457 return help |
2702 | 2458 |
2703 | 2459 """ |
2704 #---------------------------------------------------------------- | |
2705 # Create Persistant Group -- Added by Snowdog 6/03 | 2460 # Create Persistant Group -- Added by Snowdog 6/03 |
2706 # | 2461 # |
2707 # Allows persistant groups to be created on the fly. | 2462 # Allows persistant groups to be created on the fly. |
2708 # These persistant groups are not added to the server.ini file | 2463 # These persistant groups are not added to the server.ini file |
2709 # however and are lost on server restarts | 2464 # however and are lost on server restarts |
2710 # | 2465 # |
2711 # Updated function code to use per-group based persistance and | 2466 # Updated function code to use per-group based persistance and |
2712 # removed references to outdated persistRoomIdThreshold | 2467 # removed references to outdated persistRoomIdThreshold |
2713 #---------------------------------------------------------------- | 2468 """ |
2714 | 2469 |
2715 def create_temporary_persistant_room(self, roomname, bootpass, password=""): | 2470 def create_temporary_persistant_room(self, roomname, bootpass, password=""): |
2716 # if the room id just above the persistant room limit is available (not in use) | 2471 # if the room id just above the persistant room limit is available (not in use) |
2717 # then it will be assigned as a persistant room on the server | 2472 # then it will be assigned as a persistant room on the server |
2718 "create a temporary persistant room" | 2473 "create a temporary persistant room" |
2719 | 2474 |
2720 group_id = str(self.next_group_id) | 2475 group_id = str(self.next_group_id) |
2721 self.next_group_id += 1 | 2476 self.next_group_id += 1 |
2722 self.groups[group_id] = game_group( group_id, roomname, password, "", bootpass, persist = 1 ) | 2477 self.groups[group_id] = game_group( group_id, roomname, password, "", bootpass, persist = 1 ) |
2724 self.log_msg( cgmsg ) | 2479 self.log_msg( cgmsg ) |
2725 self.send_to_all('0',self.groups[group_id].toxml('new')) | 2480 self.send_to_all('0',self.groups[group_id].toxml('new')) |
2726 self.send_to_all('0',self.groups[group_id].toxml('update')) | 2481 self.send_to_all('0',self.groups[group_id].toxml('update')) |
2727 return str("Persistant room created (group " + group_id + ").") | 2482 return str("Persistant room created (group " + group_id + ").") |
2728 | 2483 |
2729 #---------------------------------------------------------------- | 2484 """ |
2730 # Prune Room -- Added by Snowdog 6/03 | 2485 # Prune Room -- Added by Snowdog 6/03 |
2731 # | 2486 # |
2732 # similar to remove_room() except rooms are removed regardless | 2487 # similar to remove_room() except rooms are removed regardless |
2733 # of them being persistant or not | 2488 # of them being persistant or not |
2734 # | 2489 # |
2735 # Added some error checking and updated room removal for per-room | 2490 # Added some error checking and updated room removal for per-room |
2736 # based persistance -- Snowdog 4/04 | 2491 # based persistance -- Snowdog 4/04 |
2737 #---------------------------------------------------------------- | 2492 """ |
2738 | 2493 |
2739 def prune_room(self,group): | 2494 def prune_room(self,group): |
2740 #don't allow lobby to be removed | 2495 #don't allow lobby to be removed |
2741 if group == '0': return "Lobby is required to exist and cannot be removed." | 2496 if group == '0': return "Lobby is required to exist and cannot be removed." |
2742 | 2497 |
2743 #check that group id exists | 2498 #check that group id exists |
2744 if group not in self.groups: | 2499 if group not in self.groups: return "Invalid Room Id. Ignoring remove request." |
2745 return "Invalid Room Id. Ignoring remove request." | |
2746 | 2500 |
2747 try: | 2501 try: |
2748 keys = self.groups[group].get_player_ids() | 2502 keys = self.groups[group].get_player_ids() |
2749 for k in keys: | 2503 for k in keys: self.move_player(k,'0') |
2750 self.move_player(k,'0') | |
2751 | |
2752 ins = "Room" | 2504 ins = "Room" |
2753 if self.isPersistentRoom(group) : ins="Persistant room" | 2505 if self.isPersistentRoom(group) : ins="Persistant room" |
2754 self.send_to_all("0",self.groups[group].toxml('del')) | 2506 self.send_to_all("0",self.groups[group].toxml('del')) |
2755 del self.groups[group] | 2507 del self.groups[group] |
2756 self.log_msg(("delete_group", ('0',group))) | 2508 self.log_msg(("delete_group", ('0',group))) |
2757 return ins + " removed." | 2509 return ins + " removed." |
2758 | |
2759 except: | 2510 except: |
2760 traceback.print_exc() | 2511 traceback.print_exc() |
2761 return "An Error occured on the server during room removal!" | 2512 return "An Error occured on the server during room removal!" |
2762 | 2513 |
2763 | 2514 """ |
2764 #---------------------------------------------------------------- | 2515 # Remote Player List -- Added by snowdog 6/03 |
2765 # Remote Player List -- Added by snowdog 6/03 | 2516 # |
2766 # | 2517 # Similar to console listing except formated for web display |
2767 # Similar to console listing except formated for web display | 2518 # in chat window on remote client |
2768 # in chat window on remote client | 2519 """ |
2769 #---------------------------------------------------------------- | |
2770 def player_list_remote(self): | 2520 def player_list_remote(self): |
2771 COLOR1 = "\"#004080\"" #header/footer background color | 2521 COLOR1 = "\"#004080\"" #header/footer background color |
2772 COLOR2 = "\"#DDDDDD\"" #group line background color | 2522 COLOR2 = "\"#DDDDDD\"" #group line background color |
2773 COLOR3 = "\"#FFFFFF\"" #player line background color | 2523 COLOR3 = "\"#FFFFFF\"" #player line background color |
2774 COLOR4 = "\"#FFFFFF\"" #header/footer text color | 2524 COLOR4 = "\"#FFFFFF\"" #header/footer text color |
2776 LCOLOR = "\"#404040\"" #Lurker text color | 2526 LCOLOR = "\"#404040\"" #Lurker text color |
2777 GCOLOR = "\"#FF0000\"" #GM text color | 2527 GCOLOR = "\"#FF0000\"" #GM text color |
2778 SIZE = "size=\"-1\"" #player info text size | 2528 SIZE = "size=\"-1\"" #player info text size |
2779 FG = PCOLOR | 2529 FG = PCOLOR |
2780 | 2530 |
2781 | |
2782 "display a condensed list of players on the server" | 2531 "display a condensed list of players on the server" |
2783 self.p_lock.acquire() | 2532 self.p_lock.acquire() |
2784 pl = "<br /><table border=\"0\" cellpadding=\"1\" cellspacing=\"2\">" | 2533 pl = "<br /><table border=\"0\" cellpadding=\"1\" cellspacing=\"2\">" |
2785 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color=" + COLOR4 + "><b>GROUP & PLAYER LIST</b></font></td></tr>" | 2534 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color=" + COLOR4 + ">" |
2786 try: | 2535 pl += "<b>GROUP & PLAYER LIST</b></font></td></tr>" |
2787 | 2536 try: |
2788 keys = self.groups.keys() | 2537 keys = self.groups.keys() |
2789 keys.sort(id_compare) | 2538 keys.sort(id_compare) |
2790 for k in keys: | 2539 for k in keys: |
2791 groupstring = "<tr><td bgcolor=" + COLOR2 + " colspan='2'><b>Group " + str(k) + ": " + self.groups[k].name + "</b>" | 2540 groupstring = "<tr><td bgcolor=" + COLOR2 + " colspan='2'>" |
2792 groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: \"" + self.groups[k].pwd + "\"</td><td bgcolor=" + COLOR2 + " > Boot: \"" + self.groups[k].boot_pwd + "\"</i></td></tr>" | 2541 groutstring += "<b>Group " + str(k) + ": " + self.groups[k].name + "</b>" |
2542 groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: \"" + self.groups[k].pwd + "\"</td>" | |
2543 groupstring += "<td bgcolor=" + COLOR2 + " > Boot: \"" + self.groups[k].boot_pwd + "\"</i></td></tr>" | |
2793 pl += groupstring | 2544 pl += groupstring |
2794 ids = self.groups[k].get_player_ids() | 2545 ids = self.groups[k].get_player_ids() |
2795 ids.sort(id_compare) | 2546 ids.sort(id_compare) |
2796 for id in ids: | 2547 for id in ids: |
2797 if self.players.has_key(id): | 2548 if self.players.has_key(id): |
2801 else: FG = LCOLOR | 2552 else: FG = LCOLOR |
2802 else: FG = PCOLOR | 2553 else: FG = PCOLOR |
2803 pl += "<tr><td bgcolor=" + COLOR3 + ">" | 2554 pl += "<tr><td bgcolor=" + COLOR3 + ">" |
2804 pl += "<font color=" + FG + " " + SIZE + "> (" + (self.players[id]).id + ") " | 2555 pl += "<font color=" + FG + " " + SIZE + "> (" + (self.players[id]).id + ") " |
2805 pl += (self.players[id]).name | 2556 pl += (self.players[id]).name |
2806 pl += "</font></td><td bgcolor=" + COLOR3 + " ><font color=" + FG + " " + SIZE + ">[IP: " + (self.players[id]).ip + "]</font></td><td bgcolor=" + COLOR3 + " ><font color=" + FG + " " + SIZE + "> " | 2557 pl += "</font></td><td bgcolor=" + COLOR3 + " >" |
2558 pl += "<font color=" + FG + " " + SIZE + ">[IP: " + (self.players[id]).ip + "]</font>" | |
2559 pl += "</td><td bgcolor=" + COLOR3 + " ><font color=" + FG + " " + SIZE + "> " | |
2807 pl += (self.players[id]).idle_status() | 2560 pl += (self.players[id]).idle_status() |
2808 pl += "</font></td><td><font color=" + FG + " " + SIZE + ">" | 2561 pl += "</font></td><td><font color=" + FG + " " + SIZE + ">" |
2809 pl += (self.players[id]).connected_time_string() | 2562 pl += (self.players[id]).connected_time_string() |
2810 pl += "</font>" | 2563 pl += "</font>" |
2811 | |
2812 else: | 2564 else: |
2813 self.groups[k].remove_player(id) | 2565 self.groups[k].remove_player(id) |
2814 pl +="<tr><td colspan='4' bgcolor=" + COLOR3 + " >Bad Player Ref (#" + id + ") in group" | 2566 pl +="<tr><td colspan='4' bgcolor=" + COLOR3 + " >Bad Player Ref (#" + id + ") in group" |
2815 pl+="</td></tr>" | 2567 pl+="</td></tr>" |
2816 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color=" + COLOR4 + "><b><i>Statistics: groups: " + str(len(self.groups)) + " players: " + str(len(self.players)) + "</i></b></font></td></tr></table>" | 2568 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + ">" |
2817 except Exception, e: | 2569 pl += "<font color=" + COLOR4 + "><b><i>Statistics: groups: " + str(len(self.groups)) + " " |
2818 self.log_msg(str(e)) | 2570 pl += "players: " + str(len(self.players)) + "</i></b></font></td></tr></table>" |
2571 except Exception, e: self.log_msg(str(e)) | |
2819 self.p_lock.release() | 2572 self.p_lock.release() |
2820 return pl | 2573 return pl |