Mercurial > traipse_dev
comparison orpg/networking/mplay_server.py @ 100:7ed4979cc1cf beta
Traipse Beta 'OpenRPG' {090925-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:
090925-00:
Adds menu changes to draw attention to important updates, errors, or other events. (image info coming soon)
Traipse URL is not included in the repos tab and is set as default.
Fixes Copy for Windows and Linux (finally!!) users.
Fixes incomplete update to Grid and List nodes.
Fixes incomplete update to Chat Commands.
Fixes problems with Remote Image Upload.
Fixes Drop and Drag of Minis to Map.
CherryPy can now use any image in the webfiles/ folder and sub-folders.
CherryPy can now Drop and Drag Minis to the Map.
Minor changes to Update Manager's GUI.
Expert recommendation warning added to Revision Update.
Step down compatibility with open_rpg & component added to orpgCore.
Fixes CherryPit misspelling.
Makes Traipse Suite 'Attention' item portable, and executes it on 'Critical' debug notices.
Adds incomplete Shift + Enter to Text Entry, currently creates a 'Critical' warning.
New default Lobby Map, designed for Traipse. Feel free to change it.
Updates to Server GUI:
* Admin can Ban from Backend.
* Admin can Modify Ban List and Un Ban users.
* Server GUI finds your Lobby Name
* New users default as Lurker unless a Role is set
Cleaner TraipseSuiteAttention portability and clean up in Main.
Die Roll Commands addition from Core code allowing Math Ordering with ()'s
New About Dialog. A more uniform About Dialog.
Corrects image loading of duplicate images.
author | sirebral |
---|---|
date | Fri, 25 Sep 2009 20:46:02 -0500 |
parents | 68c7bd272f27 |
children | dcf4fbe09b70 |
comparison
equal
deleted
inserted
replaced
94:118fbe111922 | 100:7ed4979cc1cf |
---|---|
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")) |
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 | 2082 |
2083 ### Alpha ### Addition added to assist in Un Banning users. | |
2084 def admin_build_banlist(self): | |
2085 validate.config_file("ban_list.xml", "default_ban_list.xml" ) | |
2086 configDom = minidom.parse(dir_struct["user"] + 'ban_list.xml') | |
2087 self.ban_list = {} | |
2088 for element in configDom.getElementsByTagName('banned'): | |
2089 player = element.getAttribute('name').replace("&", "&").replace("<", "<").replace('"', """).replace(">", ">") | |
2090 ip = element.getAttribute('ip') | |
2091 self.ban_list[ip] = {} | |
2092 self.ban_list[ip]['ip'] = ip | |
2093 self.ban_list[ip]['name'] = element.getAttribute('name') | |
2094 ################ | |
2293 | 2095 |
2294 def admin_banip(self, ip, name="", silent = 0): | 2096 def admin_banip(self, ip, name="", silent = 0): |
2295 "Ban a player from a server from the console" | 2097 "Ban a player from a server from the console" |
2098 self.adming_buile_banlist() ### Alpha ### | |
2296 try: | 2099 try: |
2297 self.ban_list[ip] = {} | 2100 self.ban_list[ip] = {} |
2298 self.ban_list[ip]['ip'] = ip | 2101 self.ban_list[ip]['ip'] = ip |
2299 self.ban_list[ip]['name'] = name | 2102 self.ban_list[ip]['name'] = name |
2300 self.saveBanList() | 2103 self.saveBanList() |
2334 except Exception, e: | 2137 except Exception, e: |
2335 traceback.print_exc() | 2138 traceback.print_exc() |
2336 self.log_msg('Exception in admin_ban() ' + str(e)) | 2139 self.log_msg('Exception in admin_ban() ' + str(e)) |
2337 | 2140 |
2338 def admin_unban(self, ip): | 2141 def admin_unban(self, ip): |
2339 try: | 2142 self.admin_build_banlist() |
2340 if self.ban_list.has_key(ip): | 2143 try: |
2341 del self.ban_list[ip] | 2144 if self.ban_list.has_key(ip): del self.ban_list[ip] |
2342 | |
2343 self.saveBanList() | 2145 self.saveBanList() |
2344 | 2146 |
2345 except Exception, e: | 2147 except Exception, e: |
2346 traceback.print_exc() | 2148 traceback.print_exc() |
2347 self.log_msg('Exception in admin_unban() ' + str(e)) | 2149 self.log_msg('Exception in admin_unban() ' + str(e)) |
2354 msg.append(self.ban_list[ip]['name']) | 2156 msg.append(self.ban_list[ip]['name']) |
2355 msg.append("</td><td>") | 2157 msg.append("</td><td>") |
2356 msg.append(self.ban_list[ip]['ip']) | 2158 msg.append(self.ban_list[ip]['ip']) |
2357 msg.append("</td></tr>") | 2159 msg.append("</td></tr>") |
2358 msg.append("</table>") | 2160 msg.append("</table>") |
2359 | |
2360 return "".join(msg) | 2161 return "".join(msg) |
2361 | 2162 |
2362 def admin_toggleSound(self): | 2163 def admin_toggleSound(self): |
2363 if self.sendLobbySound: | 2164 if self.sendLobbySound: self.sendLobbySound = False |
2364 self.sendLobbySound = False | 2165 else: self.sendLobbySound = True |
2365 else: | |
2366 self.sendLobbySound = True | |
2367 | |
2368 return self.sendLobbySound | 2166 return self.sendLobbySound |
2369 | 2167 |
2370 def admin_soundFile(self, file): | 2168 def admin_soundFile(self, file): |
2371 self.lobbySound = file | 2169 self.lobbySound = file |
2372 | 2170 |
2381 return "Invalid Room Id. Ignoring remove request." | 2179 return "Invalid Room Id. Ignoring remove request." |
2382 | 2180 |
2383 self.groups[group].persistant = 0 | 2181 self.groups[group].persistant = 0 |
2384 try: | 2182 try: |
2385 keys = self.groups[group].get_player_ids() | 2183 keys = self.groups[group].get_player_ids() |
2386 for k in keys: | 2184 for k in keys: self.del_player(k, str(group)) |
2387 self.del_player(k, str(group)) | |
2388 self.check_group("0", str(group)) | 2185 self.check_group("0", str(group)) |
2389 except: | 2186 except: pass |
2390 pass | |
2391 | 2187 |
2392 def send(self,msg,player,group): | 2188 def send(self,msg,player,group): |
2393 self.players[player].send(msg,player,group) | 2189 self.players[player].send(msg,player,group) |
2394 | |
2395 | 2190 |
2396 def send_to_all(self,from_id,data): | 2191 def send_to_all(self,from_id,data): |
2397 try: | 2192 try: |
2398 print data | 2193 print data |
2399 self.p_lock.acquire() | 2194 self.p_lock.acquire() |
2400 keys = self.players.keys() | 2195 keys = self.players.keys() |
2401 self.p_lock.release() | 2196 self.p_lock.release() |
2402 for k in keys: | 2197 for k in keys: |
2403 if k != from_id: | 2198 if k != from_id: self.players[k].outbox.put(data) |
2404 self.players[k].outbox.put(data) | |
2405 except Exception, e: | 2199 except Exception, e: |
2406 traceback.print_exc() | 2200 traceback.print_exc() |
2407 self.log_msg("Exception: send_to_all(): " + str(e)) | 2201 self.log_msg("Exception: send_to_all(): " + str(e)) |
2408 | 2202 |
2409 def send_to_group(self, from_id, group_id, data): | 2203 def send_to_group(self, from_id, group_id, data): |
2412 try: | 2206 try: |
2413 self.p_lock.acquire() | 2207 self.p_lock.acquire() |
2414 keys = self.groups[group_id].get_player_ids() | 2208 keys = self.groups[group_id].get_player_ids() |
2415 self.p_lock.release() | 2209 self.p_lock.release() |
2416 for k in keys: | 2210 for k in keys: |
2417 if k != from_id: | 2211 if k != from_id: self.players[k].outbox.put(data) |
2418 self.players[k].outbox.put(data) | |
2419 except Exception, e: | 2212 except Exception, e: |
2420 traceback.print_exc() | 2213 traceback.print_exc() |
2421 self.log_msg("Exception: send_to_group(): " + str(e)) | 2214 self.log_msg("Exception: send_to_group(): " + str(e)) |
2422 | 2215 |
2423 def send_player_list(self,to_id,group_id): | 2216 def send_player_list(self,to_id,group_id): |
2438 self.players[to_id].outbox.put(xml) | 2231 self.players[to_id].outbox.put(xml) |
2439 except Exception, e: | 2232 except Exception, e: |
2440 self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e)) | 2233 self.log_msg("Exception: send_group_list(): (client #"+to_id+") : " + str(e)) |
2441 traceback.print_exc() | 2234 traceback.print_exc() |
2442 | 2235 |
2443 #-------------------------------------------------------------------------- | 2236 """ |
2444 # KICK_ALL_CLIENTS() | 2237 # KICK_ALL_CLIENTS() |
2445 # | 2238 # |
2446 # Convience method for booting all clients off the server at once. | 2239 # Convience method for booting all clients off the server at once. |
2447 # used while troubleshooting mysterious "black hole" server bug | 2240 # used while troubleshooting mysterious "black hole" server bug |
2448 # Added by Snowdog 11-19-04 | 2241 # Added by Snowdog 11-19-04 |
2242 """ | |
2449 def kick_all_clients(self): | 2243 def kick_all_clients(self): |
2450 try: | 2244 try: |
2451 keys = self.groups.keys() | 2245 keys = self.groups.keys() |
2452 for k in keys: | 2246 for k in keys: |
2453 pl = self.groups[k].get_player_ids() | 2247 pl = self.groups[k].get_player_ids() |
2454 for p in pl: | 2248 for p in pl: self.admin_kick(p,"Purged from server") |
2455 self.admin_kick(p,"Purged from server") | |
2456 except Exception, e: | 2249 except Exception, e: |
2457 traceback.print_exc() | 2250 traceback.print_exc() |
2458 self.log_msg("Exception: kick_all_clients(): " + str(e)) | 2251 self.log_msg("Exception: kick_all_clients(): " + str(e)) |
2459 | 2252 |
2460 | 2253 """ |
2461 # This really has little value as it will only catch people that are hung | 2254 # 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 | 2255 # on a disconnect which didn't complete. Other idle connections which are |
2463 # really dead go undeterred. | 2256 # really dead go undeterred. |
2464 # | 2257 # |
2465 # UPDATED 11-29-04: Changed remove XML send to forced admin_kick for 'dead clients' | 2258 # 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 | 2259 # Dead clients now removed more effeciently as soon as they are detected |
2467 # --Snowdog | 2260 # --Snowdog |
2261 """ | |
2468 def check_group_members(self, group_id): | 2262 def check_group_members(self, group_id): |
2469 try: | 2263 try: |
2470 keys = self.groups[group_id].get_player_ids() | 2264 keys = self.groups[group_id].get_player_ids() |
2471 for k in keys: | 2265 for k in keys: |
2472 #drop any clients that are idle for more than 8 hours | 2266 #drop any clients that are idle for more than 8 hours |
2473 #as these are likely dead clients | 2267 #as these are likely dead clients |
2474 idlemins = self.players[k].idle_time() | 2268 idlemins = self.players[k].idle_time() |
2475 idlemins = idlemins/60 | 2269 idlemins = idlemins/60 |
2476 if (idlemins > self.zombie_time): | 2270 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: | 2271 elif self.players[k].get_status() != MPLAY_CONNECTED: |
2479 if self.players[k].check_time_out(): | 2272 if self.players[k].check_time_out(): |
2480 self.log_msg("Player #" + k + " Lost connection!") | 2273 self.log_msg("Player #" + k + " Lost connection!") |
2481 self.admin_kick(k,"Removing dead client", self.silent_auto_kick) | 2274 self.admin_kick(k,"Removing dead client", self.silent_auto_kick) |
2482 except Exception, e: | 2275 except Exception, e: |
2483 self.log_msg("Exception: check_group_members(): " + str(e)) | 2276 self.log_msg("Exception: check_group_members(): " + str(e)) |
2484 | 2277 |
2485 | 2278 |
2486 def remote_admin_handler(self,xml_dom,data): | 2279 def remote_admin_handler(self,xml_dom,data): |
2280 """ | |
2487 # handle incoming remove server admin messages | 2281 # handle incoming remove server admin messages |
2488 # (allows basic administration of server from a remote client) | 2282 # (allows basic administration of server from a remote client) |
2489 # base message format: <admin id="" pwd="" cmd="" [data for command]> | 2283 # base message format: <admin id="" pwd="" cmd="" [data for command]> |
2490 | 2284 """ |
2491 if not self.allowRemoteAdmin: | 2285 if not self.allowRemoteAdmin: return |
2492 return | |
2493 | |
2494 try: | 2286 try: |
2495 pid = xml_dom.getAttribute("id") | 2287 pid = xml_dom.getAttribute("id") |
2496 gid = "" | 2288 gid = "" |
2497 given_pwd = xml_dom.getAttribute("pwd") | 2289 given_pwd = xml_dom.getAttribute("pwd") |
2498 cmd = xml_dom.getAttribute("cmd") | 2290 cmd = xml_dom.getAttribute("cmd") |
2499 server_admin_pwd = self.groups["0"].boot_pwd | 2291 server_admin_pwd = self.groups["0"].boot_pwd |
2500 p_id = "" | 2292 p_id = "" |
2501 p_name= "" | 2293 p_name= "" |
2502 p_ip = "" | 2294 p_ip = "" |
2503 | |
2504 | 2295 |
2505 #verify that the message came from the proper ID/Socket and get IP address for logging | 2296 #verify that the message came from the proper ID/Socket and get IP address for logging |
2506 if self.players.has_key(pid): | 2297 if self.players.has_key(pid): |
2507 p_name=(self.players[pid]).name | 2298 p_name=(self.players[pid]).name |
2508 p_ip=(self.players[pid]).ip | 2299 p_ip=(self.players[pid]).ip |
2521 #dump and log any attempts to control server remotely with invalid password | 2312 #dump and log any attempts to control server remotely with invalid password |
2522 if server_admin_pwd != given_pwd: | 2313 if server_admin_pwd != given_pwd: |
2523 #tell the clients password manager the password failed -- SD 8/03 | 2314 #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=\"\"/>" | 2315 pm = "<password signal=\"fail\" type=\"server\" id=\"" + str(self.players[pid].group_id) + "\" data=\"\"/>" |
2525 self.players[pid].outbox.put(pm) | 2316 self.players[pid].outbox.put(pm) |
2526 m = "Invalid Remote Server Control Message (bad password) from #" + str(pid) + " (" + str(p_name) + ") " + str(p_ip) | 2317 m = "Invalid Remote Server Control Message (bad password) from " |
2318 m += "#" + str(pid) + " (" + str(p_name) + ") " + str(p_ip) | |
2527 self.log_msg( m ) | 2319 self.log_msg( m ) |
2528 return | 2320 return |
2529 | 2321 |
2530 #message now deemed 'authentic' | 2322 #message now deemed 'authentic' |
2531 #determine action to take based on command (cmd) | 2323 #determine action to take based on command (cmd) |
2532 | |
2533 if cmd == "list": | 2324 if cmd == "list": |
2534 #return player list to this user. | 2325 #return player list to this user. |
2535 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.player_list_remote() | 2326 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.player_list_remote() |
2536 self.players[pid].outbox.put(msg) | 2327 self.players[pid].outbox.put(msg) |
2537 | |
2538 elif cmd == "banip": | 2328 elif cmd == "banip": |
2539 ip = xml_dom.getAttribute("bip") | 2329 ip = xml_dom.getAttribute("bip") |
2540 name = xml_dom.getAttribute("bname") | 2330 name = xml_dom.getAttribute("bname") |
2541 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Banned: " + str(ip) | 2331 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Banned: " + str(ip) |
2542 self.admin_banip(ip, name) | 2332 self.admin_banip(ip, name) |
2543 | |
2544 elif cmd == "ban": | 2333 elif cmd == "ban": |
2545 id = xml_dom.getAttribute("bid") | 2334 id = xml_dom.getAttribute("bid") |
2546 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Banned!" | 2335 msg = "<msg to='" + id + "' from='0' group_id='" + gid + "'> Banned!" |
2547 self.players[pid].outbox.put(msg) | 2336 self.players[pid].outbox.put(msg) |
2548 self.admin_ban(id, "") | 2337 self.admin_ban(id, "") |
2549 | |
2550 elif cmd == "unban": | 2338 elif cmd == "unban": |
2551 ip = xml_dom.getAttribute("ip") | 2339 ip = xml_dom.getAttribute("ip") |
2552 self.admin_unban(ip) | 2340 self.admin_unban(ip) |
2553 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Unbaned: " + str(ip) | 2341 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'> Unbaned: " + str(ip) |
2554 self.players[pid].outbox.put(msg) | 2342 self.players[pid].outbox.put(msg) |
2555 | |
2556 elif cmd == "banlist": | 2343 elif cmd == "banlist": |
2557 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.admin_banlist() | 2344 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.admin_banlist() |
2558 self.players[pid].outbox.put(msg) | 2345 self.players[pid].outbox.put(msg) |
2559 | |
2560 elif cmd == "killgroup": | 2346 elif cmd == "killgroup": |
2561 ugid = xml_dom.getAttribute("gid") | 2347 ugid = xml_dom.getAttribute("gid") |
2562 if ugid == "0": | 2348 if ugid == "0": |
2563 m = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>Cannot Remove Lobby! Remote administrator request denied!" | 2349 m = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2350 m += "Cannot Remove Lobby! Remote administrator request denied!" | |
2564 self.players[pid].outbox.put(m) | 2351 self.players[pid].outbox.put(m) |
2565 else: | 2352 else: |
2566 result = self.prune_room(ugid) | 2353 result = self.prune_room(ugid) |
2567 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + str(result) | 2354 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + str(result) |
2568 self.players[pid].outbox.put(msg) | 2355 self.players[pid].outbox.put(msg) |
2573 pmsg = "<msg to='" + tuid + "' from='0' group_id='" + self.players[tuid].group_id + "' >" + msg | 2360 pmsg = "<msg to='" + tuid + "' from='0' group_id='" + self.players[tuid].group_id + "' >" + msg |
2574 try: self.players[tuid].outbox.put(pmsg) | 2361 try: self.players[tuid].outbox.put(pmsg) |
2575 except: | 2362 except: |
2576 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + ">Unknown Player ID: No message sent." | 2363 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + ">Unknown Player ID: No message sent." |
2577 self.players[pid].outbox.put(msg) | 2364 self.players[pid].outbox.put(msg) |
2578 | |
2579 elif cmd == "broadcast": | 2365 elif cmd == "broadcast": |
2580 bmsg = xml_dom.getAttribute("msg") | 2366 bmsg = xml_dom.getAttribute("msg") |
2581 self.broadcast(bmsg) | 2367 self.broadcast(bmsg) |
2582 | |
2583 elif cmd == "killserver" and self.allowRemoteKill: | 2368 elif cmd == "killserver" and self.allowRemoteKill: |
2584 #dangerous command..once server stopped it must be restarted manually | 2369 #dangerous command..once server stopped it must be restarted manually |
2585 self.kill_server() | 2370 self.kill_server() |
2586 | |
2587 elif cmd == "uptime": | 2371 elif cmd == "uptime": |
2588 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.uptime(1) | 2372 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + self.uptime(1) |
2589 self.players[pid].outbox.put(msg) | 2373 self.players[pid].outbox.put(msg) |
2590 | |
2591 elif cmd == "help": | 2374 elif cmd == "help": |
2592 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" | 2375 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2593 msg += self.AdminHelpMessage() | 2376 msg += self.AdminHelpMessage() |
2594 self.players[pid].outbox.put( msg) | 2377 self.players[pid].outbox.put( msg) |
2595 | |
2596 elif cmd == "roompasswords": | 2378 elif cmd == "roompasswords": |
2597 # Toggle if room passwords are allowed on this server | 2379 # Toggle if room passwords are allowed on this server |
2598 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" | 2380 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2599 msg += self.RoomPasswords() | 2381 msg += self.RoomPasswords() |
2600 self.players[pid].outbox.put( msg) | 2382 self.players[pid].outbox.put( msg) |
2601 | |
2602 elif cmd == "createroom": | 2383 elif cmd == "createroom": |
2603 rm_name = xml_dom.getAttribute("name") | 2384 rm_name = xml_dom.getAttribute("name") |
2604 rm_pass = xml_dom.getAttribute("pass") | 2385 rm_pass = xml_dom.getAttribute("pass") |
2605 rm_boot = xml_dom.getAttribute("boot") | 2386 rm_boot = xml_dom.getAttribute("boot") |
2606 result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass) | 2387 result = self.create_temporary_persistant_room(rm_name, rm_boot, rm_pass) |
2607 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + result | 2388 msg = "<msg to='" + pid + "' from='0' group_id='" + gid + "'>" + result |
2608 self.players[pid].outbox.put(msg) | 2389 self.players[pid].outbox.put(msg) |
2609 | |
2610 elif cmd == "nameroom": | 2390 elif cmd == "nameroom": |
2611 rm_id = xml_dom.getAttribute("rmid") | 2391 rm_id = xml_dom.getAttribute("rmid") |
2612 rm_name = xml_dom.getAttribute("name") | 2392 rm_name = xml_dom.getAttribute("name") |
2613 result = self.change_group_name(rm_id,rm_name,pid) | 2393 result = self.change_group_name(rm_id,rm_name,pid) |
2614 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'/>" + result | 2394 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'/>" + result |
2615 self.players[pid].outbox.put(msg) | 2395 self.players[pid].outbox.put(msg) |
2616 | |
2617 elif cmd == "passwd": | 2396 elif cmd == "passwd": |
2618 tgid = xml_dom.getAttribute("gid") | 2397 tgid = xml_dom.getAttribute("gid") |
2619 npwd = xml_dom.getAttribute("pass") | 2398 npwd = xml_dom.getAttribute("pass") |
2620 if tgid == "0": | 2399 if tgid == "0": |
2621 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Server password may not be changed remotely!" | 2400 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>" |
2401 msg += "Server password may not be changed remotely!" | |
2622 self.players[pid].outbox.put(msg) | 2402 self.players[pid].outbox.put(msg) |
2623 else: | 2403 else: |
2624 try: | 2404 try: |
2625 self.groups[tgid].boot_pwd = npwd | 2405 self.groups[tgid].boot_pwd = npwd |
2626 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Password changed for room " + tgid | 2406 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Password changed for room " + tgid |
2627 self.players[pid].outbox.put(msg) | 2407 self.players[pid].outbox.put(msg) |
2628 except: pass | 2408 except: pass |
2629 | |
2630 elif cmd == "savemaps": | 2409 elif cmd == "savemaps": |
2631 for g in self.groups.itervalues(): | 2410 for g in self.groups.itervalues(): |
2632 g.save_map() | 2411 g.save_map() |
2633 | |
2634 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Persistent room maps saved" | 2412 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'>Persistent room maps saved" |
2635 self.players[pid].outbox.put(msg) | 2413 self.players[pid].outbox.put(msg) |
2636 | |
2637 | |
2638 else: | 2414 else: |
2639 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'><i>[Unknown Remote Administration Command]</i>" | 2415 msg ="<msg to='" + pid + "' from='0' group_id='" + gid + "'><i>[Unknown Remote Administration Command]</i>" |
2640 self.players[pid].outbox.put(msg) | 2416 self.players[pid].outbox.put(msg) |
2641 | |
2642 | |
2643 except Exception, e: | 2417 except Exception, e: |
2644 self.log_msg("Exception: Remote Admin Handler Error: " + str(e)) | 2418 self.log_msg("Exception: Remote Admin Handler Error: " + str(e)) |
2645 traceback.print_exc() | 2419 traceback.print_exc() |
2646 | 2420 |
2647 | |
2648 def toggleRemoteKill(self): | 2421 def toggleRemoteKill(self): |
2649 if self.allowRemoteKill: | 2422 if self.allowRemoteKill: self.allowRemoteKill = False |
2650 self.allowRemoteKill = False | 2423 else: self.allowRemoteKill = True |
2651 else: | |
2652 self.allowRemoteKill = True | |
2653 | |
2654 return self.allowRemoteKill | 2424 return self.allowRemoteKill |
2655 | 2425 |
2656 def toggleRemoteAdmin(self): | 2426 def toggleRemoteAdmin(self): |
2657 if self.allowRemoteAdmin: | 2427 if self.allowRemoteAdmin: self.allowRemoteAdmin = False |
2658 self.allowRemoteAdmin = False | 2428 else: self.allowRemoteAdmin = True |
2659 else: | |
2660 self.allowRemoteAdmin = True | |
2661 | |
2662 return self.allowRemoteAdmin | 2429 return self.allowRemoteAdmin |
2663 | 2430 |
2664 #----------------------------------------------------------------- | 2431 """ |
2665 # Remote Administrator Help (returns from server not client) | 2432 # Remote Administrator Help (returns from server not client) |
2666 #----------------------------------------------------------------- | 2433 """ |
2667 def AdminHelpMessage(self): | 2434 def AdminHelpMessage(self): |
2668 "returns a string to be sent as a message to a remote admin" | 2435 "returns a string to be sent as a message to a remote admin" |
2669 | |
2670 #define the help command list information | 2436 #define the help command list information |
2671 info = [] | 2437 info = [] |
2672 info.append( ['list', '/admin list', 'Displays information about rooms and players on the server'] ) | 2438 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'] ) | 2439 info.append( ['uptime', '/admin uptime', 'Information on how long server has been running'] ) |
2674 info.append( ['help', '/admin help', 'This help message']) | 2440 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']) | 2441 info.append( ['passwd', '/admin passwd <group id> <new password>', |
2442 '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)']) | 2443 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']) | 2444 info.append( ['message', '/admin message <user id> <message>', |
2445 'Send a message to a specific user on the server']) | |
2678 info.append( ['broadcast', '/admin broadcast <message>', 'Broadcast message to all players on server']) | 2446 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']) | 2447 info.append( ['createroom', '/admin createroom <room name> <boot password> [password]', |
2448 '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']) | 2449 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.']) | 2450 info.append( ['killgroup', '/admin killgroup <room id>', |
2451 'Remove a room from the server and kick everyone in it.']) | |
2682 if self.allowRemoteKill: | 2452 if self.allowRemoteKill: |
2683 info.append( ['killserver', '/admin killserver', 'Shuts down the server. <b>WARNING: Server cannot be restarted remotely via OpenRPG</b>']) | 2453 info.append( ['killserver', '/admin killserver', |
2454 '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.']) | 2455 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.']) | 2456 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']) | 2457 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.']) | 2458 info.append( ['savemaps', '/admin savemaps', |
2688 | 2459 'Save all persistent room maps that are not using the default map file.']) |
2689 | 2460 |
2690 #define the HTML for the help display | 2461 #define the HTML for the help display |
2691 FS = "<font size='-1'>" | 2462 FS = "<font size='-1'>" |
2692 FE = "<font>" | 2463 FE = "<font>" |
2693 | |
2694 help = "<hr><B>REMOTE ADMINISTRATOR COMMANDS SUPPORTED</b><br /><br />" | 2464 help = "<hr><B>REMOTE ADMINISTRATOR COMMANDS SUPPORTED</b><br /><br />" |
2695 help += "<table border='1' cellpadding='2'>" | 2465 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>" | 2466 help += "<tr><td width='15%'><b>Command</b></td><td width='25%'><b>Format</b>" |
2467 help += "</td><td width='60%'><b>Description</b></td></tr>" | |
2697 for n in info: | 2468 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>" | 2469 help += "<tr><td>" + FS + n[0] + FE + "</td><td><nobr>" + FS + n[1] + FE + "</nobr>" |
2470 help += "</td><td>" + FS + n[2] + FE + "</td></tr>" | |
2699 help += "</table>" | 2471 help += "</table>" |
2700 return help | 2472 return help |
2701 | 2473 |
2702 | 2474 """ |
2703 #---------------------------------------------------------------- | |
2704 # Create Persistant Group -- Added by Snowdog 6/03 | 2475 # Create Persistant Group -- Added by Snowdog 6/03 |
2705 # | 2476 # |
2706 # Allows persistant groups to be created on the fly. | 2477 # Allows persistant groups to be created on the fly. |
2707 # These persistant groups are not added to the server.ini file | 2478 # These persistant groups are not added to the server.ini file |
2708 # however and are lost on server restarts | 2479 # however and are lost on server restarts |
2709 # | 2480 # |
2710 # Updated function code to use per-group based persistance and | 2481 # Updated function code to use per-group based persistance and |
2711 # removed references to outdated persistRoomIdThreshold | 2482 # removed references to outdated persistRoomIdThreshold |
2712 #---------------------------------------------------------------- | 2483 """ |
2713 | 2484 |
2714 def create_temporary_persistant_room(self, roomname, bootpass, password=""): | 2485 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) | 2486 # 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 | 2487 # then it will be assigned as a persistant room on the server |
2717 "create a temporary persistant room" | 2488 "create a temporary persistant room" |
2718 | 2489 |
2719 group_id = str(self.next_group_id) | 2490 group_id = str(self.next_group_id) |
2720 self.next_group_id += 1 | 2491 self.next_group_id += 1 |
2721 self.groups[group_id] = game_group( group_id, roomname, password, "", bootpass, persist = 1 ) | 2492 self.groups[group_id] = game_group( group_id, roomname, password, "", bootpass, persist = 1 ) |
2723 self.log_msg( cgmsg ) | 2494 self.log_msg( cgmsg ) |
2724 self.send_to_all('0',self.groups[group_id].toxml('new')) | 2495 self.send_to_all('0',self.groups[group_id].toxml('new')) |
2725 self.send_to_all('0',self.groups[group_id].toxml('update')) | 2496 self.send_to_all('0',self.groups[group_id].toxml('update')) |
2726 return str("Persistant room created (group " + group_id + ").") | 2497 return str("Persistant room created (group " + group_id + ").") |
2727 | 2498 |
2728 #---------------------------------------------------------------- | 2499 """ |
2729 # Prune Room -- Added by Snowdog 6/03 | 2500 # Prune Room -- Added by Snowdog 6/03 |
2730 # | 2501 # |
2731 # similar to remove_room() except rooms are removed regardless | 2502 # similar to remove_room() except rooms are removed regardless |
2732 # of them being persistant or not | 2503 # of them being persistant or not |
2733 # | 2504 # |
2734 # Added some error checking and updated room removal for per-room | 2505 # Added some error checking and updated room removal for per-room |
2735 # based persistance -- Snowdog 4/04 | 2506 # based persistance -- Snowdog 4/04 |
2736 #---------------------------------------------------------------- | 2507 """ |
2737 | 2508 |
2738 def prune_room(self,group): | 2509 def prune_room(self,group): |
2739 #don't allow lobby to be removed | 2510 #don't allow lobby to be removed |
2740 if group == '0': return "Lobby is required to exist and cannot be removed." | 2511 if group == '0': return "Lobby is required to exist and cannot be removed." |
2741 | 2512 |
2742 #check that group id exists | 2513 #check that group id exists |
2743 if group not in self.groups: | 2514 if group not in self.groups: return "Invalid Room Id. Ignoring remove request." |
2744 return "Invalid Room Id. Ignoring remove request." | |
2745 | 2515 |
2746 try: | 2516 try: |
2747 keys = self.groups[group].get_player_ids() | 2517 keys = self.groups[group].get_player_ids() |
2748 for k in keys: | 2518 for k in keys: self.move_player(k,'0') |
2749 self.move_player(k,'0') | |
2750 | |
2751 ins = "Room" | 2519 ins = "Room" |
2752 if self.isPersistentRoom(group) : ins="Persistant room" | 2520 if self.isPersistentRoom(group) : ins="Persistant room" |
2753 self.send_to_all("0",self.groups[group].toxml('del')) | 2521 self.send_to_all("0",self.groups[group].toxml('del')) |
2754 del self.groups[group] | 2522 del self.groups[group] |
2755 self.log_msg(("delete_group", ('0',group))) | 2523 self.log_msg(("delete_group", ('0',group))) |
2756 return ins + " removed." | 2524 return ins + " removed." |
2757 | |
2758 except: | 2525 except: |
2759 traceback.print_exc() | 2526 traceback.print_exc() |
2760 return "An Error occured on the server during room removal!" | 2527 return "An Error occured on the server during room removal!" |
2761 | 2528 |
2762 | 2529 """ |
2763 #---------------------------------------------------------------- | 2530 # Remote Player List -- Added by snowdog 6/03 |
2764 # Remote Player List -- Added by snowdog 6/03 | 2531 # |
2765 # | 2532 # Similar to console listing except formated for web display |
2766 # Similar to console listing except formated for web display | 2533 # in chat window on remote client |
2767 # in chat window on remote client | 2534 """ |
2768 #---------------------------------------------------------------- | |
2769 def player_list_remote(self): | 2535 def player_list_remote(self): |
2770 COLOR1 = "\"#004080\"" #header/footer background color | 2536 COLOR1 = "\"#004080\"" #header/footer background color |
2771 COLOR2 = "\"#DDDDDD\"" #group line background color | 2537 COLOR2 = "\"#DDDDDD\"" #group line background color |
2772 COLOR3 = "\"#FFFFFF\"" #player line background color | 2538 COLOR3 = "\"#FFFFFF\"" #player line background color |
2773 COLOR4 = "\"#FFFFFF\"" #header/footer text color | 2539 COLOR4 = "\"#FFFFFF\"" #header/footer text color |
2775 LCOLOR = "\"#404040\"" #Lurker text color | 2541 LCOLOR = "\"#404040\"" #Lurker text color |
2776 GCOLOR = "\"#FF0000\"" #GM text color | 2542 GCOLOR = "\"#FF0000\"" #GM text color |
2777 SIZE = "size=\"-1\"" #player info text size | 2543 SIZE = "size=\"-1\"" #player info text size |
2778 FG = PCOLOR | 2544 FG = PCOLOR |
2779 | 2545 |
2780 | |
2781 "display a condensed list of players on the server" | 2546 "display a condensed list of players on the server" |
2782 self.p_lock.acquire() | 2547 self.p_lock.acquire() |
2783 pl = "<br /><table border=\"0\" cellpadding=\"1\" cellspacing=\"2\">" | 2548 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>" | 2549 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color=" + COLOR4 + ">" |
2785 try: | 2550 pl += "<b>GROUP & PLAYER LIST</b></font></td></tr>" |
2786 | 2551 try: |
2787 keys = self.groups.keys() | 2552 keys = self.groups.keys() |
2788 keys.sort(id_compare) | 2553 keys.sort(id_compare) |
2789 for k in keys: | 2554 for k in keys: |
2790 groupstring = "<tr><td bgcolor=" + COLOR2 + " colspan='2'><b>Group " + str(k) + ": " + self.groups[k].name + "</b>" | 2555 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>" | 2556 groutstring += "<b>Group " + str(k) + ": " + self.groups[k].name + "</b>" |
2557 groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: \"" + self.groups[k].pwd + "\"</td>" | |
2558 groupstring += "<td bgcolor=" + COLOR2 + " > Boot: \"" + self.groups[k].boot_pwd + "\"</i></td></tr>" | |
2792 pl += groupstring | 2559 pl += groupstring |
2793 ids = self.groups[k].get_player_ids() | 2560 ids = self.groups[k].get_player_ids() |
2794 ids.sort(id_compare) | 2561 ids.sort(id_compare) |
2795 for id in ids: | 2562 for id in ids: |
2796 if self.players.has_key(id): | 2563 if self.players.has_key(id): |
2800 else: FG = LCOLOR | 2567 else: FG = LCOLOR |
2801 else: FG = PCOLOR | 2568 else: FG = PCOLOR |
2802 pl += "<tr><td bgcolor=" + COLOR3 + ">" | 2569 pl += "<tr><td bgcolor=" + COLOR3 + ">" |
2803 pl += "<font color=" + FG + " " + SIZE + "> (" + (self.players[id]).id + ") " | 2570 pl += "<font color=" + FG + " " + SIZE + "> (" + (self.players[id]).id + ") " |
2804 pl += (self.players[id]).name | 2571 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 + "> " | 2572 pl += "</font></td><td bgcolor=" + COLOR3 + " >" |
2573 pl += "<font color=" + FG + " " + SIZE + ">[IP: " + (self.players[id]).ip + "]</font>" | |
2574 pl += "</td><td bgcolor=" + COLOR3 + " ><font color=" + FG + " " + SIZE + "> " | |
2806 pl += (self.players[id]).idle_status() | 2575 pl += (self.players[id]).idle_status() |
2807 pl += "</font></td><td><font color=" + FG + " " + SIZE + ">" | 2576 pl += "</font></td><td><font color=" + FG + " " + SIZE + ">" |
2808 pl += (self.players[id]).connected_time_string() | 2577 pl += (self.players[id]).connected_time_string() |
2809 pl += "</font>" | 2578 pl += "</font>" |
2810 | |
2811 else: | 2579 else: |
2812 self.groups[k].remove_player(id) | 2580 self.groups[k].remove_player(id) |
2813 pl +="<tr><td colspan='4' bgcolor=" + COLOR3 + " >Bad Player Ref (#" + id + ") in group" | 2581 pl +="<tr><td colspan='4' bgcolor=" + COLOR3 + " >Bad Player Ref (#" + id + ") in group" |
2814 pl+="</td></tr>" | 2582 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>" | 2583 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + ">" |
2816 except Exception, e: | 2584 pl += "<font color=" + COLOR4 + "><b><i>Statistics: groups: " + str(len(self.groups)) + " " |
2817 self.log_msg(str(e)) | 2585 pl += "players: " + str(len(self.players)) + "</i></b></font></td></tr></table>" |
2586 except Exception, e: self.log_msg(str(e)) | |
2818 self.p_lock.release() | 2587 self.p_lock.release() |
2819 return pl | 2588 return pl |
2589 | |
2590 server = mplay_server() |