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