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