Mercurial > traipse_dev
comparison orpg/networking/mplay_client.py @ 92:68c7bd272f27 beta
Traipse Beta 'OpenRPG' {090919-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:
Adds menu changes to draw attention to important updates, errors, or other events. (image info coming soon)
Traipse URL is not included in the repos tab and is set as default.
Fixes Copy for Windows and Linux (finally!!) users.
Fixes incomplete update to Grid and List nodes.
Fixes incomplete update to Chat Commands.
Fixes problems with Remote Image Upload.
Fixes Drop and Drag of Minis to Map.
CherryPy can now use any image in the webfiles/ folder and sub-folders.
CherryPy can now Drop and Drag Minis to the Map.
Minor changes to Update Manager's GUI.
Expert recommendation warning added to Revision Update.
Step down compatibility with open_rpg & component added to orpgCore.
Using majority of 'Grumpy' network folder to correct server lag.
author | sirebral |
---|---|
date | Sat, 19 Sep 2009 06:50:43 -0500 |
parents | 449a8900f9ac |
children | 7ed4979cc1cf |
comparison
equal
deleted
inserted
replaced
84:5c12918d6bb2 | 92:68c7bd272f27 |
---|---|
27 # features in the orpg project. | 27 # features in the orpg project. |
28 # | 28 # |
29 | 29 |
30 __version__ = "$Id: mplay_client.py,v 1.71 2007/05/12 20:41:54 digitalxero Exp $" | 30 __version__ = "$Id: mplay_client.py,v 1.71 2007/05/12 20:41:54 digitalxero Exp $" |
31 | 31 |
32 #import orpg.minidom | 32 import orpg.minidom |
33 import socket | 33 import socket |
34 import Queue | 34 import Queue |
35 import thread | 35 import thread |
36 import traceback | 36 import traceback |
37 from threading import Event, Lock | 37 from threading import Event, Lock |
38 from xml.sax.saxutils import escape | 38 from xml.sax.saxutils import escape |
39 from struct import pack, unpack, calcsize | 39 from struct import pack, unpack, calcsize |
40 from string import * | 40 from string import * |
41 from orpg.orpg_version import CLIENT_STRING, PROTOCOL_VERSION, VERSION | 41 from orpg.orpg_version import * |
42 import errno | 42 import errno |
43 import os | 43 import os |
44 import time | 44 import time |
45 from orpg.orpgCore import component | |
46 from orpg.orpg_xml import xml | 45 from orpg.orpg_xml import xml |
46 import orpg.minidom as minidom | |
47 | 47 |
48 try: | 48 try: |
49 import bz2 | 49 import bz2 |
50 cmpBZ2 = True | 50 cmpBZ2 = True |
51 except: cmpBZ2 = False | 51 except: |
52 cmpBZ2 = False | |
52 | 53 |
53 try: | 54 try: |
54 import zlib | 55 import zlib |
55 cmpZLIB = True | 56 cmpZLIB = True |
56 except: cmpZLIB = False | 57 except: |
58 cmpZLIB = False | |
57 | 59 |
58 | 60 |
59 # This should be configurable | 61 # This should be configurable |
60 OPENRPG_PORT = 9557 | 62 OPENRPG_PORT = 9557 |
61 | 63 |
81 STATUS_SET_URL = 1 | 83 STATUS_SET_URL = 1 |
82 | 84 |
83 def parseXml(data): | 85 def parseXml(data): |
84 "parse and return doc" | 86 "parse and return doc" |
85 #print data | 87 #print data |
86 doc = xml.parseXml(data) | 88 doc = minidom.parseString(data) |
87 doc.normalize() | 89 doc.normalize() |
88 return doc | 90 return doc |
89 | 91 |
90 def myescape(data): | 92 def myescape(data): |
91 return escape(data,{"\"":""}) | 93 return escape(data,{"\"":""}) |
115 self.recvThreadExitEvent = Event() | 117 self.recvThreadExitEvent = Event() |
116 self.id = "0" | 118 self.id = "0" |
117 self.group_id = "0" | 119 self.group_id = "0" |
118 self.name = "" | 120 self.name = "" |
119 self.role = "GM" | 121 self.role = "GM" |
120 ## Soon to be removed | |
121 self.ROLE_GM = "GM" | 122 self.ROLE_GM = "GM" |
122 self.ROLE_PLAYER = "Player" | 123 self.ROLE_PLAYER = "Player" |
123 self.ROLE_LURKER = "Lurker" | 124 self.ROLE_LURKER = "Lurker" |
124 ## --TaS | |
125 self.ip = socket.gethostbyname(socket.gethostname()) | 125 self.ip = socket.gethostbyname(socket.gethostname()) |
126 self.remote_ip = None | 126 self.remote_ip = None |
127 self.version = VERSION | 127 self.version = VERSION |
128 self.protocol_version = PROTOCOL_VERSION | 128 self.protocol_version = PROTOCOL_VERSION |
129 self.client_string = CLIENT_STRING | 129 self.client_string = CLIENT_STRING |
133 self.log_console = None | 133 self.log_console = None |
134 self.sock = None | 134 self.sock = None |
135 self.text_status = "Idle" | 135 self.text_status = "Idle" |
136 self.statLock = Lock() | 136 self.statLock = Lock() |
137 self.useroles = 0 | 137 self.useroles = 0 |
138 self.ROLE_GM = "GM" | |
139 self.ROLE_PLAYER = "Player" | |
140 self.ROLE_LURKER = "Lurker" | |
138 self.lastmessagetime = time.time() | 141 self.lastmessagetime = time.time() |
139 self.connecttime = time.time() | 142 self.connecttime = time.time() |
140 | 143 |
141 def sendThread( self, arg ): | 144 def sendThread( self, arg ): |
142 "Sending thread. This thread reads from the data queue and writes to the socket." | 145 "Sending thread. This thread reads from the data queue and writes to the socket." |
144 # Wait to be told it's okay to start running | 147 # Wait to be told it's okay to start running |
145 self.startedEvent.wait() | 148 self.startedEvent.wait() |
146 | 149 |
147 # Loop as long as we have a connection | 150 # Loop as long as we have a connection |
148 while( self.get_status() == MPLAY_CONNECTED ): | 151 while( self.get_status() == MPLAY_CONNECTED ): |
149 try: readMsg = self.outbox.get( block=1 ) | 152 try: |
153 readMsg = self.outbox.get( block=1 ) | |
150 except Exception, text: | 154 except Exception, text: |
151 self.log_msg( ("outbox.get() got an exception: ", text) ) | 155 self.log_msg( ("outbox.get() got an exception: ", text) ) |
152 | 156 |
153 # If we are here, it's because we have data to send, no doubt! | 157 # If we are here, it's because we have data to send, no doubt! |
154 if self.status == MPLAY_CONNECTED: | 158 if self.status == MPLAY_CONNECTED: |
172 while( self.get_status() == MPLAY_CONNECTED ): | 176 while( self.get_status() == MPLAY_CONNECTED ): |
173 readMsg = self.recvMsg( self.sock ) | 177 readMsg = self.recvMsg( self.sock ) |
174 try: | 178 try: |
175 if self.useCompression and self.compressionType != None: | 179 if self.useCompression and self.compressionType != None: |
176 readMsg = self.compressionType.decompress(readMsg) | 180 readMsg = self.compressionType.decompress(readMsg) |
177 except: pass | 181 except: |
182 pass | |
178 | 183 |
179 # Check the length of the message | 184 # Check the length of the message |
180 bytes = len( readMsg ) | 185 bytes = len( readMsg ) |
181 | 186 |
182 # Make sure we are still connected | 187 # Make sure we are still connected |
183 if bytes == 0: break | 188 if bytes == 0: |
189 break | |
184 else: | 190 else: |
185 # Pass along the message so it can be processed | 191 # Pass along the message so it can be processed |
186 self.inbox.put( readMsg ) | 192 self.inbox.put( readMsg ) |
187 self.update_idle_time() #update the last message time | 193 self.update_idle_time() #update the last message time |
188 if bytes == 0: | 194 if bytes == 0: |
217 # Send the encoded length | 223 # Send the encoded length |
218 sentl = sock.send( lp ) | 224 sentl = sock.send( lp ) |
219 | 225 |
220 # Now, send the message the the length was describing | 226 # Now, send the message the the length was describing |
221 sentm = sock.send( msg ) | 227 sentm = sock.send( msg ) |
222 if self.isServer(): self.log_msg(("data_sent", sentl+sentm)) | 228 if self.isServer(): |
223 except socket.error, e: self.log_msg( e ) | 229 self.log_msg(("data_sent", sentl+sentm)) |
224 except Exception, e: self.log_msg( e ) | 230 except socket.error, e: |
231 self.log_msg( e ) | |
232 except Exception, e: | |
233 self.log_msg( e ) | |
225 return sentm | 234 return sentm |
226 | 235 |
227 def recvData( self, sock, readSize ): | 236 def recvData( self, sock, readSize ): |
228 """Simple socket receive method. This method will only return when the exact | 237 """Simple socket receive method. This method will only return when the exact |
229 byte count has been read from the connection, if remote terminates our | 238 byte count has been read from the connection, if remote terminates our |
267 if self.isServer(): | 276 if self.isServer(): |
268 self.log_msg(("data_recv", length+4)) | 277 self.log_msg(("data_recv", length+4)) |
269 # Make the peer IP address available for reference later | 278 # Make the peer IP address available for reference later |
270 if self.remote_ip is None: | 279 if self.remote_ip is None: |
271 self.remote_ip = self.sock.getpeername() | 280 self.remote_ip = self.sock.getpeername() |
272 except IOError, e: self.log_msg( e ) | 281 except IOError, e: |
273 except Exception, e: self.log_msg( e ) | 282 self.log_msg( e ) |
283 except Exception, e: | |
284 self.log_msg( e ) | |
274 return msgData | 285 return msgData |
275 | 286 |
276 def initialize_threads(self): | 287 def initialize_threads(self): |
277 "Starts up our threads (2) and waits for them to make sure they are running!" | 288 "Starts up our threads (2) and waits for them to make sure they are running!" |
278 self.status = MPLAY_CONNECTED | 289 self.status = MPLAY_CONNECTED |
284 | 295 |
285 def disconnect(self): | 296 def disconnect(self): |
286 self.set_status(MPLAY_DISCONNECTING) | 297 self.set_status(MPLAY_DISCONNECTING) |
287 self.log_msg("client stub " + self.ip +" disconnecting...") | 298 self.log_msg("client stub " + self.ip +" disconnecting...") |
288 self.log_msg("closing sockets...") | 299 self.log_msg("closing sockets...") |
289 try: self.sock.shutdown( 2 ) | 300 try: |
301 self.sock.shutdown( 2 ) | |
290 except Exception, e: | 302 except Exception, e: |
291 print "Caught exception: " + str(e) | 303 print "Caught exception: " + str(e) |
292 print | 304 print |
293 print "Continuing" | 305 print "Continuing" |
294 self.set_status(MPLAY_DISCONNECTED) | 306 self.set_status(MPLAY_DISCONNECTED) |
306 if self.useroles: | 318 if self.useroles: |
307 return 1 | 319 return 1 |
308 else: | 320 else: |
309 return 0 | 321 return 0 |
310 def update_self_from_player(self, player): | 322 def update_self_from_player(self, player): |
311 try: (self.name, self.ip, self.id, | 323 try: |
312 self.text_status, self.version, | 324 (self.name, self.ip, self.id, self.text_status, self.version, self.protocol_version, self.client_string,role) = player |
313 self.protocol_version, self.client_string, role) = player | |
314 except Exception, e: | 325 except Exception, e: |
315 print e | 326 print e |
316 """ | 327 |
317 The IP field should really be deprecated as too many systems are NAT'd and/or behind firewalls for a | 328 # The IP field should really be deprecated as too many systems are NAT'd and/or behind firewalls for a |
318 client provided IP address to have much value. As such, we now label it as deprecated. | 329 # client provided IP address to have much value. As such, we now label it as deprecated. |
319 """ | |
320 def toxml(self,action): | 330 def toxml(self,action): |
321 xml_data = '<player name="' + myescape(self.name) + '"' | 331 xml_data = '<player name="' + myescape(self.name) + '"' |
322 xml_data += ' action="' + action + '" id="' + self.id + '"' | 332 xml_data += ' action="' + action + '" id="' + self.id + '"' |
323 xml_data += ' group_id="' + self.group_id + '" ip="' + self.ip + '"' | 333 xml_data += ' group_id="' + self.group_id + '" ip="' + self.ip + '"' |
324 xml_data += ' status="' + self.text_status + '"' | 334 xml_data += ' status="' + self.text_status + '"' |
328 xml_data += ' useCompression="' + str(self.useCompression) + '"' | 338 xml_data += ' useCompression="' + str(self.useCompression) + '"' |
329 if cmpBZ2 and (self.compressionType == 'Undefined' or self.compressionType == bz2): | 339 if cmpBZ2 and (self.compressionType == 'Undefined' or self.compressionType == bz2): |
330 xml_data += ' cmpType="bz2"' | 340 xml_data += ' cmpType="bz2"' |
331 elif cmpZLIB and (self.compressionType == 'Undefined' or self.compressionType == zlib): | 341 elif cmpZLIB and (self.compressionType == 'Undefined' or self.compressionType == zlib): |
332 xml_data += ' cmpType="zlib"' | 342 xml_data += ' cmpType="zlib"' |
333 else: xml_data += ' cmpType="None"' | 343 else: |
344 xml_data += ' cmpType="None"' | |
334 xml_data += ' />' | 345 xml_data += ' />' |
335 return xml_data | 346 return xml_data |
336 | 347 |
337 def log_msg(self,msg): | 348 def log_msg(self,msg): |
338 if self.log_console: | 349 if self.log_console: |
339 self.log_console(msg) | 350 self.log_console(msg) |
351 # else: | |
352 # print "message", msg | |
340 | 353 |
341 def get_status(self): | 354 def get_status(self): |
342 self.statLock.acquire() | 355 self.statLock.acquire() |
343 status = self.status | 356 status = self.status |
344 self.statLock.release() | 357 self.statLock.release() |
345 return status | 358 return status |
346 | 359 |
347 def my_role(self): | 360 def my_role(self): |
348 #Leaving this for testing. | 361 #Why create the three different objects? Why not just assign a value to self.role and use that? Prof_Ebral ponders. |
349 return self.role | |
350 """ | |
351 if self.role == "GM": | 362 if self.role == "GM": |
352 return self.ROLE_GM | 363 return self.ROLE_GM |
353 elif self.role == "Player": | 364 elif self.role == "Player": |
354 return self.ROLE_PLAYER | 365 return self.ROLE_PLAYER |
355 elif self.role == "Lurker": | 366 elif self.role == "Lurker": |
356 return self.ROLE_LURKER | 367 return self.ROLE_LURKER |
357 return -1 | 368 return -1 |
358 """ | |
359 | 369 |
360 def set_status(self,status): | 370 def set_status(self,status): |
361 self.statLock.acquire() | 371 self.statLock.acquire() |
362 self.status = status | 372 self.status = status |
363 self.statLock.release() | 373 self.statLock.release() |
381 | 391 |
382 def idle_status(self): | 392 def idle_status(self): |
383 idletime = self.idle_time() | 393 idletime = self.idle_time() |
384 idlemins = idletime / 60 | 394 idlemins = idletime / 60 |
385 status = "Unknown" | 395 status = "Unknown" |
386 if idlemins < 3: status = "Active" | 396 if idlemins < 3: |
387 elif idlemins < 10: status = "Idle ("+str(int(idlemins))+" mins)" | 397 status = "Active" |
388 else: status = "Inactive ("+str(int(idlemins))+" mins)" | 398 elif idlemins < 10: |
399 status = "Idle ("+str(int(idlemins))+" mins)" | |
400 else: | |
401 status = "Inactive ("+str(int(idlemins))+" mins)" | |
389 return status | 402 return status |
390 | 403 |
391 def connected_time(self): | 404 def connected_time(self): |
392 curtime = time.time() | 405 curtime = time.time() |
393 timeoffset = curtime - self.connecttime | 406 timeoffset = curtime - self.connecttime |
412 #======================================================================== | 425 #======================================================================== |
413 class mplay_client(client_base): | 426 class mplay_client(client_base): |
414 "mplay client" | 427 "mplay client" |
415 def __init__(self,name,callbacks): | 428 def __init__(self,name,callbacks): |
416 client_base.__init__(self) | 429 client_base.__init__(self) |
417 component.add('mp_client', self) | |
418 self.xml = component.get('xml') | |
419 self.set_name(name) | 430 self.set_name(name) |
420 self.on_receive = callbacks['on_receive'] | 431 self.on_receive = callbacks['on_receive'] |
421 self.on_mplay_event = callbacks['on_mplay_event'] | 432 self.on_mplay_event = callbacks['on_mplay_event'] |
422 self.on_group_event = callbacks['on_group_event'] | 433 self.on_group_event = callbacks['on_group_event'] |
423 self.on_player_event = callbacks['on_player_event'] | 434 self.on_player_event = callbacks['on_player_event'] |
426 # I know this is a bad thing to do but it has to be | 437 # I know this is a bad thing to do but it has to be |
427 # be done to use the unified password manager. | 438 # be done to use the unified password manager. |
428 # Should really find a better solution. -- SD 8/03 | 439 # Should really find a better solution. -- SD 8/03 |
429 self.orpgFrame_callback = callbacks['orpgFrame'] | 440 self.orpgFrame_callback = callbacks['orpgFrame'] |
430 self.settings = self.orpgFrame_callback.settings | 441 self.settings = self.orpgFrame_callback.settings |
442 #self.version = VERSION | |
443 #self.protocol_version = PROTOCOL_VERSION | |
444 #self.client_string = CLIENT_STRING | |
431 self.ignore_id = [] | 445 self.ignore_id = [] |
432 self.ignore_name = [] | 446 self.ignore_name = [] |
433 self.players = {} | 447 self.players = {} |
434 self.groups = {} | 448 self.groups = {} |
435 self.unique_cookie = 0 | 449 self.unique_cookie = 0 |
493 | 507 |
494 def get_player_by_player_id(self,player): | 508 def get_player_by_player_id(self,player): |
495 players = self.get_players() | 509 players = self.get_players() |
496 if self.players.has_key(player): | 510 if self.players.has_key(player): |
497 for m in players: | 511 for m in players: |
498 if player == m[2]: return m | 512 if player == m[2]: |
513 return m | |
499 return -1 | 514 return -1 |
500 | 515 |
501 def get_id(self): | 516 def get_id(self): |
502 return self.id | 517 return self.id |
503 | 518 |
504 def get_my_info(self): | 519 def get_my_info(self): |
505 return (self.name, self.ip, self.id, | 520 return (self.name, self.ip, self.id, self.text_status, self.version, self.protocol_version, self.client_string, self.role) |
506 self.text_status, self.version, | |
507 self.protocol_version, self.client_string, | |
508 self.role) | |
509 | 521 |
510 def is_valid_id(self,id): | 522 def is_valid_id(self,id): |
511 self.statLock.acquire() | 523 self.statLock.acquire() |
512 value = self.players.has_key( id ) | 524 value = self.players.has_key( id ) |
513 self.statLock.release() | 525 self.statLock.release() |
514 return value | 526 return value |
515 | 527 |
516 def clear_players(self,save_self=0): | 528 def clear_players(self,save_self=0): |
517 self.statLock.acquire() | 529 self.statLock.acquire() |
518 keys = self.players.keys() | 530 keys = self.players.keys() |
519 for k in keys: del self.players[k] | 531 for k in keys: |
532 del self.players[k] | |
520 self.statLock.release() | 533 self.statLock.release() |
521 | 534 |
522 def clear_groups(self): | 535 def clear_groups(self): |
523 self.statLock.acquire() | 536 self.statLock.acquire() |
524 keys = self.groups.keys() | 537 keys = self.groups.keys() |
525 for k in keys: del self.groups[k] | 538 for k in keys: |
539 del self.groups[k] | |
526 self.statLock.release() | 540 self.statLock.release() |
527 | 541 |
528 def find_role(self,id): | 542 def find_role(self,id): |
529 return self.players[id].role | 543 return self.players[id].role |
530 | 544 |
531 def get_ignore_list(self): | 545 def get_ignore_list(self): |
532 try: return (self.ignore_id, self.ignore_name) | 546 try: |
533 except: return (None, None) | 547 return (self.ignore_id, self.ignore_name) |
548 except: | |
549 return (None, None) | |
534 | 550 |
535 def toggle_ignore(self, id): | 551 def toggle_ignore(self, id): |
536 for m in self.ignore_id: | 552 for m in self.ignore_id: |
537 if `self.ignore_id[self.ignore_id.index(m)]` == `id`: | 553 if `self.ignore_id[self.ignore_id.index(m)]` == `id`: |
538 name = self.ignore_name[self.ignore_id.index(m)] | 554 name = self.ignore_name[self.ignore_id.index(m)] |
551 #--------------------------------------------------------- | 567 #--------------------------------------------------------- |
552 # [START] Snowdog Password/Room Name altering code 12/02 | 568 # [START] Snowdog Password/Room Name altering code 12/02 |
553 #--------------------------------------------------------- | 569 #--------------------------------------------------------- |
554 | 570 |
555 def set_room_pass(self,npwd,pwd=""): | 571 def set_room_pass(self,npwd,pwd=""): |
556 recycle_bin = "<alter key=\"pwd\" " | 572 self.outbox.put("<alter key=\"pwd\" val=\"" +npwd+ "\" bpw=\"" + pwd + "\" plr=\"" + self.id +"\" gid=\"" + self.group_id + "\" />") |
557 recycle_bin += "val=\"" +npwd+ "\" bpw=\"" + pwd + "\" " | |
558 recycle_bin += "plr=\"" + self.id +"\" gid=\"" + self.group_id + "\" />" | |
559 self.outbox.put(recycle_bin); del recycle_bin #makes line easier to read. --TaS | |
560 self.update() | 573 self.update() |
561 | 574 |
562 def set_room_name(self,name,pwd=""): | 575 def set_room_name(self,name,pwd=""): |
563 loc = name.find("&") | 576 loc = name.find("&") |
564 oldloc=0 | 577 oldloc=0 |
585 if loc > -1: | 598 if loc > -1: |
586 b = name[:loc] | 599 b = name[:loc] |
587 e = name[loc+1:] | 600 e = name[loc+1:] |
588 name = b + "'" + e | 601 name = b + "'" + e |
589 oldloc = loc+1 | 602 oldloc = loc+1 |
590 recycle_bin = "<alter key=\"name\" " | 603 self.outbox.put("<alter key=\"name\" val=\"" + name + "\" bpw=\"" + pwd + "\" plr=\"" + self.id +"\" gid=\"" + self.group_id + "\" />") |
591 recycle_bin += "val=\"" + name + "\" bpw=\"" + pwd + "\" " | |
592 recycle_bin += "plr=\"" + self.id +"\" gid=\"" + self.group_id + "\" />" | |
593 self.outbox.put(recycle_bin); del recycle_bin #makes line easier to read. --TaS | |
594 self.update() | 604 self.update() |
595 | 605 |
596 #--------------------------------------------------------- | 606 #--------------------------------------------------------- |
597 # [END] Snowdog Password/Room Name altering code 12/02 | 607 # [END] Snowdog Password/Room Name altering code 12/02 |
598 #--------------------------------------------------------- | 608 #--------------------------------------------------------- |
602 | 612 |
603 def get_role(self): | 613 def get_role(self): |
604 self.outbox.put("<role action=\"get\" player=\"" + self.id +"\" group_id=\""+self.group_id + "\" />") | 614 self.outbox.put("<role action=\"get\" player=\"" + self.id +"\" group_id=\""+self.group_id + "\" />") |
605 | 615 |
606 def set_role(self,player,role,pwd=""): | 616 def set_role(self,player,role,pwd=""): |
607 recycle_bin = "<role action=\"set\" player=\"" + player + "\" " | 617 self.outbox.put("<role action=\"set\" player=\"" + player + "\" role=\"" +role+ "\" boot_pwd=\"" + pwd + "\" group_id=\"" + self.group_id + "\" />") |
608 recycle_bin += "role=\"" +role+ "\" boot_pwd=\"" + pwd + "\" group_id=\"" + self.group_id + "\" />" | |
609 self.outbox.put(recycle_bin); del recycle_bin #makes line easer to read. --TaS | |
610 self.update() | 618 self.update() |
611 | 619 |
612 def send(self,msg,player="all"): | 620 def send(self,msg,player="all"): |
613 if self.status == MPLAY_CONNECTED and player != self.id: | 621 if self.status == MPLAY_CONNECTED and player != self.id: |
614 self.outbox.put("<msg to='"+player+"' from='"+self.id+"' group_id='"+self.group_id+"' />"+msg) | 622 self.outbox.put("<msg to='"+player+"' from='"+self.id+"' group_id='"+self.group_id+"' />"+msg) |
618 if self.status == MPLAY_CONNECTED: | 626 if self.status == MPLAY_CONNECTED: |
619 self.outbox.put(snd_xml) | 627 self.outbox.put(snd_xml) |
620 self.check_my_status() | 628 self.check_my_status() |
621 | 629 |
622 def send_create_group(self,name,pwd,boot_pwd,minversion): | 630 def send_create_group(self,name,pwd,boot_pwd,minversion): |
623 recycle_bin = "<create_group from=\""+self.id+"\" " | 631 self.outbox.put("<create_group from=\""+self.id+"\" pwd=\""+pwd+"\" name=\""+ |
624 recycle_bin += "pwd=\""+pwd+"\" name=\""+ name+"\" boot_pwd=\""+boot_pwd+"\" " | 632 name+"\" boot_pwd=\""+boot_pwd+"\" min_version=\"" + minversion +"\" />") |
625 recycle_bin += "min_version=\"" + minversion +"\" />" | |
626 self.outbox.put(recycle_bin); del recycle_bin #makes line easier to read. --TaS | |
627 | 633 |
628 def send_join_group(self,group_id,pwd): | 634 def send_join_group(self,group_id,pwd): |
629 if (group_id != 0): self.update_role("Lurker") | 635 if (group_id != 0): |
636 self.update_role("Lurker") | |
630 self.outbox.put("<join_group from=\""+self.id+"\" pwd=\""+pwd+"\" group_id=\""+str(group_id)+"\" />") | 637 self.outbox.put("<join_group from=\""+self.id+"\" pwd=\""+pwd+"\" group_id=\""+str(group_id)+"\" />") |
631 | 638 |
632 def poll(self, evt=None): | 639 def poll(self, evt=None): |
633 try: | 640 try: |
634 msg = self.inbox.get_nowait() | 641 msg = self.inbox.get_nowait() |
635 except: | 642 except: |
636 if self.get_status() != MPLAY_CONNECTED: | 643 if self.get_status() != MPLAY_CONNECTED: |
637 self.check_my_status() | 644 self.check_my_status() |
638 else: | 645 else: |
639 try: self.pretranslate(msg) | 646 try: |
647 self.pretranslate(msg) | |
640 except Exception, e: | 648 except Exception, e: |
641 print "The following message: " + str(msg) | 649 print "The following message: " + str(msg) |
642 print "created the following exception: " | 650 print "created the following exception: " |
643 traceback.print_exc() | 651 traceback.print_exc() |
644 | 652 |
645 def add_msg_handler(self, tag, function, core=False): | 653 def add_msg_handler(self, tag, function, core=False): |
646 if not self.msg_handlers.has_key(tag): | 654 if not self.msg_handlers.has_key(tag): |
647 self.msg_handlers[tag] = function | 655 self.msg_handlers[tag] = function |
648 if core: self.core_msg_handlers.append(tag) | 656 if core: |
649 else: print 'XML Messages ' + tag + ' already has a handler' | 657 self.core_msg_handlers.append(tag) |
658 else: | |
659 print 'XML Messages ' + tag + ' already has a handler' | |
650 | 660 |
651 def remove_msg_handler(self, tag): | 661 def remove_msg_handler(self, tag): |
652 if self.msg_handlers.has_key(tag) and not tag in self.core_msg_handlers: | 662 if self.msg_handlers.has_key(tag) and not tag in self.core_msg_handlers: |
653 del self.msg_handlers[tag] | 663 del self.msg_handlers[tag] |
654 else: print 'XML Messages ' + tag + ' already deleted' | 664 else: |
665 print 'XML Messages ' + tag + ' already deleted' | |
655 | 666 |
656 def load_core_msg_handlers(self): | 667 def load_core_msg_handlers(self): |
657 self.add_msg_handler('msg', self.on_msg, True) | 668 self.add_msg_handler('msg', self.on_msg, True) |
658 self.add_msg_handler('ping', self.on_ping, True) | 669 self.add_msg_handler('ping', self.on_ping, True) |
659 self.add_msg_handler('group', self.on_group, True) | 670 self.add_msg_handler('group', self.on_group, True) |
663 self.add_msg_handler('sound', self.on_sound, True) | 674 self.add_msg_handler('sound', self.on_sound, True) |
664 | 675 |
665 def pretranslate(self,data): | 676 def pretranslate(self,data): |
666 # Pre-qualify our data. If we don't have atleast 5-bytes, then there is | 677 # Pre-qualify our data. If we don't have atleast 5-bytes, then there is |
667 # no way we even have a valid message! | 678 # no way we even have a valid message! |
668 if len(data) < 5: return | 679 if len(data) < 5: |
680 return | |
669 end = data.find(">") | 681 end = data.find(">") |
670 head = data[:end+1] | 682 head = data[:end+1] |
671 msg = data[end+1:] | 683 msg = data[end+1:] |
672 xml_dom = self.xml.parseXml(head) | 684 xml_dom = xml.parseXml(head) |
673 xml_dom = xml_dom._get_documentElement() | 685 xml_dom = xml_dom._get_documentElement() |
674 tag_name = xml_dom._get_tagName() | 686 tag_name = xml_dom._get_tagName() |
675 id = xml_dom.getAttribute("from") | 687 id = xml_dom.getAttribute("from") |
676 if id == '': id = xml_dom.getAttribute("id") | 688 if id == '': |
677 if self.msg_handlers.has_key(tag_name): self.msg_handlers[tag_name](id, data, xml_dom) | 689 id = xml_dom.getAttribute("id") |
690 if self.msg_handlers.has_key(tag_name): | |
691 self.msg_handlers[tag_name](id, data, xml_dom) | |
678 else: | 692 else: |
679 #Unknown messages recived ignoring | 693 #Unknown messages recived ignoring |
680 #using pass insted or printing an error message | 694 #using pass insted or printing an error message |
681 #because plugins should now be able to send and proccess messages | 695 #because plugins should now be able to send and proccess messages |
682 #if someone is using a plugin to send messages and this user does not | 696 #if someone is using a plugin to send messages and this user does not |
683 #have the plugin they would be getting errors | 697 #have the plugin they would be getting errors |
684 pass | 698 pass |
685 if xml_dom: xml_dom.unlink() | 699 if xml_dom: |
700 xml_dom.unlink() | |
686 | 701 |
687 def on_sound(self, id, data, xml_dom): | 702 def on_sound(self, id, data, xml_dom): |
688 (ignore_id,ignore_name) = self.get_ignore_list() | 703 (ignore_id,ignore_name) = self.get_ignore_list() |
689 for m in ignore_id: | 704 for m in ignore_id: |
690 if m == id: | 705 if m == id: |
702 msg = data[end+1:] | 717 msg = data[end+1:] |
703 if id == "0": | 718 if id == "0": |
704 self.on_receive(msg,None) # None get's interpreted in on_receive as the sys admin. | 719 self.on_receive(msg,None) # None get's interpreted in on_receive as the sys admin. |
705 # Doing it this way makes it harder to impersonate the admin | 720 # Doing it this way makes it harder to impersonate the admin |
706 else: | 721 else: |
707 if self.is_valid_id(id): self.on_receive(msg,self.players[id]) | 722 if self.is_valid_id(id): |
708 if xml_dom: xml_dom.unlink() | 723 self.on_receive(msg,self.players[id]) |
724 if xml_dom: | |
725 xml_dom.unlink() | |
709 | 726 |
710 def on_ping(self, id, msg, xml_dom): | 727 def on_ping(self, id, msg, xml_dom): |
711 #a REAL ping time implementation by Snowdog 8/03 | 728 #a REAL ping time implementation by Snowdog 8/03 |
712 # recieves special server <ping time="###" /> command | 729 # recieves special server <ping time="###" /> command |
713 # where ### is a returning time from the clients ping command | 730 # where ### is a returning time from the clients ping command |
718 latency = float(float(ct) - float(ot)) | 735 latency = float(float(ct) - float(ot)) |
719 latency = int( latency * 10000.0 ) | 736 latency = int( latency * 10000.0 ) |
720 latency = float( latency) / 10.0 | 737 latency = float( latency) / 10.0 |
721 ping_msg = "Ping Results: " + str(latency) + " ms (parsed message, round trip)" | 738 ping_msg = "Ping Results: " + str(latency) + " ms (parsed message, round trip)" |
722 self.on_receive(ping_msg,None) | 739 self.on_receive(ping_msg,None) |
723 if xml_dom: xml_dom.unlink() | 740 if xml_dom: |
741 xml_dom.unlink() | |
724 | 742 |
725 def on_group(self, id, msg, xml_dom): | 743 def on_group(self, id, msg, xml_dom): |
726 name = xml_dom.getAttribute("name") | 744 name = xml_dom.getAttribute("name") |
727 players = xml_dom.getAttribute("players") | 745 players = xml_dom.getAttribute("players") |
728 act = xml_dom.getAttribute("action") | 746 act = xml_dom.getAttribute("action") |
736 del self.groups[id] | 754 del self.groups[id] |
737 self.on_group_event(mplay_event(GROUP_DEL, group_data)) | 755 self.on_group_event(mplay_event(GROUP_DEL, group_data)) |
738 elif act == 'update': | 756 elif act == 'update': |
739 self.groups[id] = group_data | 757 self.groups[id] = group_data |
740 self.on_group_event(mplay_event(GROUP_UPDATE, group_data)) | 758 self.on_group_event(mplay_event(GROUP_UPDATE, group_data)) |
741 if xml_dom: xml_dom.unlink() | 759 if xml_dom: |
760 xml_dom.unlink() | |
742 | 761 |
743 def on_role(self, id, msg, xml_dom): | 762 def on_role(self, id, msg, xml_dom): |
744 act = xml_dom.getAttribute("action") | 763 act = xml_dom.getAttribute("action") |
745 role = xml_dom.getAttribute("role") | 764 role = xml_dom.getAttribute("role") |
746 if (act == "set") or (act == "update"): | 765 if (act == "set") or (act == "update"): |
747 try: | 766 try: |
748 (a,b,c,d,e,f,g,h) = self.players[id] | 767 (a,b,c,d,e,f,g,h) = self.players[id] |
749 if id == self.id: | 768 if id == self.id: |
750 self.players[id] = (a,b,c,d,e,f,g,role) | 769 self.players[id] = (a,b,c,d,e,f,g,role) |
751 self.update_role(role) | 770 self.update_role(role) |
752 else: self.players[id] = (a,b,c,d,e,f,g,role) | 771 else: |
772 self.players[id] = (a,b,c,d,e,f,g,role) | |
753 self.on_player_event(mplay_event(PLAYER_UPDATE,self.players[id])) | 773 self.on_player_event(mplay_event(PLAYER_UPDATE,self.players[id])) |
754 except: pass | 774 except: |
755 if xml_dom: xml_dom.unlink() | 775 pass |
776 if xml_dom: | |
777 xml_dom.unlink() | |
756 | 778 |
757 def on_player(self, id, msg, xml_dom): | 779 def on_player(self, id, msg, xml_dom): |
758 act = xml_dom.getAttribute("action") | 780 act = xml_dom.getAttribute("action") |
759 ip = xml_dom.getAttribute("ip") | 781 ip = xml_dom.getAttribute("ip") |
760 name = xml_dom.getAttribute("name") | 782 name = xml_dom.getAttribute("name") |
761 status = xml_dom.getAttribute("status") | 783 status = xml_dom.getAttribute("status") |
762 version = xml_dom.getAttribute("version") | 784 version = xml_dom.getAttribute("version") |
763 protocol_version = xml_dom.getAttribute("protocol_version") | 785 protocol_version = xml_dom.getAttribute("protocol_version") |
764 client_string = xml_dom.getAttribute("client_string") | 786 client_string = xml_dom.getAttribute("client_string") |
765 try: player = (name, ip, id, status, | 787 try: |
766 version, protocol_version, | 788 player = (name,ip,id,status,version,protocol_version,client_string,self.players[id][7]) |
767 client_string, self.players[id][7]) | |
768 except Exception, e: | 789 except Exception, e: |
769 player = (name, ip, id, status, | 790 player = (name,ip,id,status,version,protocol_version,client_string,"Player") |
770 version, protocol_version, | |
771 client_string, "Player") | |
772 if act == "new": | 791 if act == "new": |
773 self.players[id] = player | 792 self.players[id] = player |
774 self.on_player_event(mplay_event(PLAYER_NEW, self.players[id])) | 793 self.on_player_event(mplay_event(PLAYER_NEW,self.players[id])) |
775 elif act == "group": | 794 elif act == "group": |
776 self.group_id = xml_dom.getAttribute("group_id") | 795 self.group_id = xml_dom.getAttribute("group_id") |
777 self.clear_players() | 796 self.clear_players() |
778 self.on_mplay_event(mplay_event(MPLAY_GROUP_CHANGE, self.groups[self.group_id])) | 797 self.on_mplay_event(mplay_event(MPLAY_GROUP_CHANGE,self.groups[self.group_id])) |
779 self.players[self.id] = self.get_my_info() #(self.name,self.ip,self.id,self.text_status) | 798 self.players[self.id] = self.get_my_info() #(self.name,self.ip,self.id,self.text_status) |
780 self.on_player_event(mplay_event(PLAYER_NEW, self.players[self.id])) | 799 self.on_player_event(mplay_event(PLAYER_NEW,self.players[self.id])) |
781 elif act == "failed": | 800 elif act == "failed": |
782 self.on_mplay_event(mplay_event(MPLAY_GROUP_CHANGE_F)) | 801 self.on_mplay_event(mplay_event(MPLAY_GROUP_CHANGE_F)) |
783 elif act == "del": | 802 elif act == "del": |
784 self.on_player_event(mplay_event(PLAYER_DEL,self.players[id])) | 803 self.on_player_event(mplay_event(PLAYER_DEL,self.players[id])) |
785 if self.players.has_key(id): del self.players[id] | 804 if self.players.has_key(id): |
786 if id == self.id: self.do_disconnect() | 805 del self.players[id] |
806 if id == self.id: | |
807 self.do_disconnect() | |
787 # the next two cases handle the events that are used to let you know when others are typing | 808 # the next two cases handle the events that are used to let you know when others are typing |
788 elif act == "update": | 809 elif act == "update": |
789 if id == self.id: | 810 if id == self.id: |
790 self.players[id] = player | 811 self.players[id] = player |
791 self.update_self_from_player(player) | 812 self.update_self_from_player(player) |
792 else: self.players[id] = player | 813 else: |
814 self.players[id] = player | |
793 dont_send = 0 | 815 dont_send = 0 |
794 for m in self.ignore_id: | 816 for m in self.ignore_id: |
795 if m == id: dont_send=1 | 817 if m == id: |
796 if dont_send != 1: self.on_player_event(mplay_event(PLAYER_UPDATE,self.players[id])) | 818 dont_send=1 |
797 if xml_dom: xml_dom.unlink() | 819 if dont_send != 1: |
820 self.on_player_event(mplay_event(PLAYER_UPDATE,self.players[id])) | |
821 if xml_dom: | |
822 xml_dom.unlink() | |
798 | 823 |
799 def on_password(self, id, msg, xml_dom): | 824 def on_password(self, id, msg, xml_dom): |
800 signal = type = id = data = None | 825 signal = type = id = data = None |
801 id = xml_dom.getAttribute("id") | 826 id = xml_dom.getAttribute("id") |
802 type = xml_dom.getAttribute("type") | 827 type = xml_dom.getAttribute("type") |
806 if xml_dom: | 831 if xml_dom: |
807 xml_dom.unlink() | 832 xml_dom.unlink() |
808 | 833 |
809 def check_my_status(self): | 834 def check_my_status(self): |
810 status = self.get_status() | 835 status = self.get_status() |
811 if status == MPLAY_DISCONNECTING: self.do_disconnect() | 836 if status == MPLAY_DISCONNECTING: |
837 self.do_disconnect() | |
812 | 838 |
813 def connect(self, addressport): | 839 def connect(self, addressport): |
814 """Establish a connection to a server while still using sendThread & recvThread for its | 840 """Establish a connection to a server while still using sendThread & recvThread for its |
815 communication.""" | 841 communication.""" |
816 if self.is_connected(): | 842 if self.is_connected(): |
832 self.sock.connect((address,port)) | 858 self.sock.connect((address,port)) |
833 # send client into with id=0 | 859 # send client into with id=0 |
834 self.sendMsg( self.sock, self.toxml("new") ) | 860 self.sendMsg( self.sock, self.toxml("new") ) |
835 data = self.recvMsg( self.sock ) | 861 data = self.recvMsg( self.sock ) |
836 # get new id and group_id | 862 # get new id and group_id |
837 xml_dom = self.xml.parseXml(data) | 863 xml_dom = xml.parseXml(data) |
838 xml_dom = xml_dom._get_documentElement() | 864 xml_dom = xml_dom._get_documentElement() |
839 self.id = xml_dom.getAttribute("id") | 865 self.id = xml_dom.getAttribute("id") |
840 self.group_id = xml_dom.getAttribute("group_id") | 866 self.group_id = xml_dom.getAttribute("group_id") |
841 if xml_dom.hasAttribute('useCompression') and xml_dom.getAttribute('useCompression') == 'True': | 867 if xml_dom.hasAttribute('useCompression') and xml_dom.getAttribute('useCompression') == 'True': |
842 self.useCompression = True | 868 self.useCompression = True |
843 if xml_dom.hasAttribute('cmpType'): | 869 if xml_dom.hasAttribute('cmpType'): |
844 if cmpBZ2 and xml_dom.getAttribute('cmpType') == 'bz2': | 870 if cmpBZ2 and xml_dom.getAttribute('cmpType') == 'bz2': |
845 self.compressionType = bz2 | 871 self.compressionType = bz2 |
846 elif cmpZLIB and xml_dom.getAttribute('cmpType') == 'zlib': | 872 elif cmpZLIB and xml_dom.getAttribute('cmpType') == 'zlib': |
847 self.compressionType = zlib | 873 self.compressionType = zlib |
848 else: self.compressionType = None | 874 else: |
849 else: self.compressionType = bz2 | 875 self.compressionType = None |
876 else: | |
877 self.compressionType = bz2 | |
850 #send confirmation | 878 #send confirmation |
851 self.sendMsg( self.sock, self.toxml("new") ) | 879 self.sendMsg( self.sock, self.toxml("new") ) |
852 except Exception, e: | 880 except Exception, e: |
853 self.log_msg(e) | 881 self.log_msg(e) |
854 if xml_dom: xml_dom.unlink() | 882 if xml_dom: |
883 xml_dom.unlink() | |
855 return 0 | 884 return 0 |
856 | 885 |
857 # Start things rollings along | 886 # Start things rollings along |
858 self.initialize_threads() | 887 self.initialize_threads() |
859 self.on_mplay_event(mplay_event(MPLAY_CONNECTED)) | 888 self.on_mplay_event(mplay_event(MPLAY_CONNECTED)) |
860 self.players[self.id] = (self.name, self.ip, self.id, | 889 self.players[self.id] = (self.name,self.ip,self.id,self.text_status,self.version,self.protocol_version,self.client_string,self.role) |
861 self.text_status, self.version, | |
862 self.protocol_version, self.client_string, self.role) | |
863 self.on_player_event(mplay_event(PLAYER_NEW,self.players[self.id])) | 890 self.on_player_event(mplay_event(PLAYER_NEW,self.players[self.id])) |
864 if xml_dom: xml_dom.unlink() | 891 if xml_dom: |
892 xml_dom.unlink() | |
865 return 1 | 893 return 1 |
866 | 894 |
867 def start_disconnect(self): | 895 def start_disconnect(self): |
868 self.on_mplay_event(mplay_event(MPLAY_DISCONNECTING)) | 896 self.on_mplay_event(mplay_event(MPLAY_DISCONNECTING)) |
869 self.outbox.put( self.toxml("del") ) | 897 self.outbox.put( self.toxml("del") ) |
870 ## Client Side Disconect Forced -- Snowdog 10-09-2003 | 898 ## Client Side Disconect Forced -- Snowdog 10-09-2003 |
871 #pause to allow GUI events time to sync. | 899 #pause to allow GUI events time to sync. |
872 time.sleep(1) | 900 time.sleep(1) |
873 self.do_disconnect() | 901 self.do_disconnect() |
874 | 902 |
875 def do_disconnect(self): | 903 def do_disconnect(self): |