comparison orpg/networking/mplay_client.py @ 66:c54768cffbd4 ornery-dev

Traipse Dev 'OpenRPG' {090818-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: *Unstable* This is the first wave of Code Refinement updates. Includes new material from Core Beta; new debugger material (partially implemented), beginnings of switch to etree, TerminalWriter, and a little more. open_rpg has been renamed to component; functioning now as component.get(), component.add(), component.delete(). This version has known bugs, specifically with the gametree and nodes. I think the XML files where not removed during testing of Core and switching back.
author sirebral
date Tue, 18 Aug 2009 06:33:37 -0500
parents d5e81dac98ff
children 449a8900f9ac
comparison
equal deleted inserted replaced
65:4840657c23c5 66:c54768cffbd4
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 * 41 from orpg.orpg_version import CLIENT_STRING, PROTOCOL_VERSION, VERSION
42 import errno 42 import errno
43 import os 43 import os
44 import time 44 import time
45 from orpg.orpgCore import *
45 46
46 try: 47 try:
47 import bz2 48 import bz2
48 cmpBZ2 = True 49 cmpBZ2 = True
49 except: 50 except: cmpBZ2 = False
50 cmpBZ2 = False
51 51
52 try: 52 try:
53 import zlib 53 import zlib
54 cmpZLIB = True 54 cmpZLIB = True
55 except: 55 except: cmpZLIB = False
56 cmpZLIB = False
57 56
58 57
59 # This should be configurable 58 # This should be configurable
60 OPENRPG_PORT = 9557 59 OPENRPG_PORT = 9557
61 60
81 STATUS_SET_URL = 1 80 STATUS_SET_URL = 1
82 81
83 def parseXml(data): 82 def parseXml(data):
84 "parse and return doc" 83 "parse and return doc"
85 #print data 84 #print data
86 doc = orpg.minidom.parseString(data) 85 doc = component.get('xml').parseXml(data)
87 doc.normalize() 86 doc.normalize()
88 return doc 87 return doc
89 88
90 def myescape(data): 89 def myescape(data):
91 return escape(data,{"\"":""}) 90 return escape(data,{"\"":""})
131 self.log_console = None 130 self.log_console = None
132 self.sock = None 131 self.sock = None
133 self.text_status = "Idle" 132 self.text_status = "Idle"
134 self.statLock = Lock() 133 self.statLock = Lock()
135 self.useroles = 0 134 self.useroles = 0
136 self.ROLE_GM = "GM"
137 self.ROLE_PLAYER = "Player"
138 self.ROLE_LURKER = "Lurker"
139 self.lastmessagetime = time.time() 135 self.lastmessagetime = time.time()
140 self.connecttime = time.time() 136 self.connecttime = time.time()
141 137
142 def sendThread( self, arg ): 138 def sendThread( self, arg ):
143 "Sending thread. This thread reads from the data queue and writes to the socket." 139 "Sending thread. This thread reads from the data queue and writes to the socket."
174 while( self.get_status() == MPLAY_CONNECTED ): 170 while( self.get_status() == MPLAY_CONNECTED ):
175 readMsg = self.recvMsg( self.sock ) 171 readMsg = self.recvMsg( self.sock )
176 try: 172 try:
177 if self.useCompression and self.compressionType != None: 173 if self.useCompression and self.compressionType != None:
178 readMsg = self.compressionType.decompress(readMsg) 174 readMsg = self.compressionType.decompress(readMsg)
179 except: 175 except: pass
180 pass
181 176
182 # Check the length of the message 177 # Check the length of the message
183 bytes = len( readMsg ) 178 bytes = len( readMsg )
184 179
185 # Make sure we are still connected 180 # Make sure we are still connected
186 if bytes == 0: 181 if bytes == 0: break
187 break
188 else: 182 else:
189 # Pass along the message so it can be processed 183 # Pass along the message so it can be processed
190 self.inbox.put( readMsg ) 184 self.inbox.put( readMsg )
191 self.update_idle_time() #update the last message time 185 self.update_idle_time() #update the last message time
192 if bytes == 0: 186 if bytes == 0:
320 def update_self_from_player(self, player): 314 def update_self_from_player(self, player):
321 try: 315 try:
322 (self.name, self.ip, self.id, self.text_status, self.version, self.protocol_version, self.client_string,role) = player 316 (self.name, self.ip, self.id, self.text_status, self.version, self.protocol_version, self.client_string,role) = player
323 except Exception, e: 317 except Exception, e:
324 print e 318 print e
325 319 """
326 # The IP field should really be deprecated as too many systems are NAT'd and/or behind firewalls for a 320 The IP field should really be deprecated as too many systems are NAT'd and/or behind firewalls for a
327 # client provided IP address to have much value. As such, we now label it as deprecated. 321 client provided IP address to have much value. As such, we now label it as deprecated.
322 """
328 def toxml(self,action): 323 def toxml(self,action):
329 xml_data = '<player name="' + myescape(self.name) + '"' 324 xml_data = '<player name="' + myescape(self.name) + '"'
330 xml_data += ' action="' + action + '" id="' + self.id + '"' 325 xml_data += ' action="' + action + '" id="' + self.id + '"'
331 xml_data += ' group_id="' + self.group_id + '" ip="' + self.ip + '"' 326 xml_data += ' group_id="' + self.group_id + '" ip="' + self.ip + '"'
332 xml_data += ' status="' + self.text_status + '"' 327 xml_data += ' status="' + self.text_status + '"'
336 xml_data += ' useCompression="' + str(self.useCompression) + '"' 331 xml_data += ' useCompression="' + str(self.useCompression) + '"'
337 if cmpBZ2 and (self.compressionType == 'Undefined' or self.compressionType == bz2): 332 if cmpBZ2 and (self.compressionType == 'Undefined' or self.compressionType == bz2):
338 xml_data += ' cmpType="bz2"' 333 xml_data += ' cmpType="bz2"'
339 elif cmpZLIB and (self.compressionType == 'Undefined' or self.compressionType == zlib): 334 elif cmpZLIB and (self.compressionType == 'Undefined' or self.compressionType == zlib):
340 xml_data += ' cmpType="zlib"' 335 xml_data += ' cmpType="zlib"'
341 else: 336 else: xml_data += ' cmpType="None"'
342 xml_data += ' cmpType="None"'
343 xml_data += ' />' 337 xml_data += ' />'
344 return xml_data 338 return xml_data
345 339
346 def log_msg(self,msg): 340 def log_msg(self,msg):
347 if self.log_console: 341 if self.log_console:
354 status = self.status 348 status = self.status
355 self.statLock.release() 349 self.statLock.release()
356 return status 350 return status
357 351
358 def my_role(self): 352 def my_role(self):
359 #Why create the three different objects? Why not just assign a value to self.role and use that? Prof_Ebral ponders. 353 #Leaving this for testing.
354 return self.role
355 """
360 if self.role == "GM": 356 if self.role == "GM":
361 return self.ROLE_GM 357 return self.ROLE_GM
362 elif self.role == "Player": 358 elif self.role == "Player":
363 return self.ROLE_PLAYER 359 return self.ROLE_PLAYER
364 elif self.role == "Lurker": 360 elif self.role == "Lurker":
365 return self.ROLE_LURKER 361 return self.ROLE_LURKER
366 return -1 362 return -1
363 """
367 364
368 def set_status(self,status): 365 def set_status(self,status):
369 self.statLock.acquire() 366 self.statLock.acquire()
370 self.status = status 367 self.status = status
371 self.statLock.release() 368 self.statLock.release()
389 386
390 def idle_status(self): 387 def idle_status(self):
391 idletime = self.idle_time() 388 idletime = self.idle_time()
392 idlemins = idletime / 60 389 idlemins = idletime / 60
393 status = "Unknown" 390 status = "Unknown"
394 if idlemins < 3: 391 if idlemins < 3: status = "Active"
395 status = "Active" 392 elif idlemins < 10: status = "Idle ("+str(int(idlemins))+" mins)"
396 elif idlemins < 10: 393 else: status = "Inactive ("+str(int(idlemins))+" mins)"
397 status = "Idle ("+str(int(idlemins))+" mins)"
398 else:
399 status = "Inactive ("+str(int(idlemins))+" mins)"
400 return status 394 return status
401 395
402 def connected_time(self): 396 def connected_time(self):
403 curtime = time.time() 397 curtime = time.time()
404 timeoffset = curtime - self.connecttime 398 timeoffset = curtime - self.connecttime
423 #======================================================================== 417 #========================================================================
424 class mplay_client(client_base): 418 class mplay_client(client_base):
425 "mplay client" 419 "mplay client"
426 def __init__(self,name,callbacks): 420 def __init__(self,name,callbacks):
427 client_base.__init__(self) 421 client_base.__init__(self)
422 component.add('mp_client', self)
423 self.xml = component.get('xml')
428 self.set_name(name) 424 self.set_name(name)
429 self.on_receive = callbacks['on_receive'] 425 self.on_receive = callbacks['on_receive']
430 self.on_mplay_event = callbacks['on_mplay_event'] 426 self.on_mplay_event = callbacks['on_mplay_event']
431 self.on_group_event = callbacks['on_group_event'] 427 self.on_group_event = callbacks['on_group_event']
432 self.on_player_event = callbacks['on_player_event'] 428 self.on_player_event = callbacks['on_player_event']
435 # I know this is a bad thing to do but it has to be 431 # I know this is a bad thing to do but it has to be
436 # be done to use the unified password manager. 432 # be done to use the unified password manager.
437 # Should really find a better solution. -- SD 8/03 433 # Should really find a better solution. -- SD 8/03
438 self.orpgFrame_callback = callbacks['orpgFrame'] 434 self.orpgFrame_callback = callbacks['orpgFrame']
439 self.settings = self.orpgFrame_callback.settings 435 self.settings = self.orpgFrame_callback.settings
440 #self.version = VERSION
441 #self.protocol_version = PROTOCOL_VERSION
442 #self.client_string = CLIENT_STRING
443 self.ignore_id = [] 436 self.ignore_id = []
444 self.ignore_name = [] 437 self.ignore_name = []
445 self.players = {} 438 self.players = {}
446 self.groups = {} 439 self.groups = {}
447 self.unique_cookie = 0 440 self.unique_cookie = 0
677 if len(data) < 5: 670 if len(data) < 5:
678 return 671 return
679 end = data.find(">") 672 end = data.find(">")
680 head = data[:end+1] 673 head = data[:end+1]
681 msg = data[end+1:] 674 msg = data[end+1:]
682 xml_dom = parseXml(head) 675 xml_dom = self.xml.parseXml(head)
683 xml_dom = xml_dom._get_documentElement() 676 xml_dom = xml_dom._get_documentElement()
684 tag_name = xml_dom._get_tagName() 677 tag_name = xml_dom._get_tagName()
685 id = xml_dom.getAttribute("from") 678 id = xml_dom.getAttribute("from")
686 if id == '': 679 if id == '':
687 id = xml_dom.getAttribute("id") 680 id = xml_dom.getAttribute("id")
856 self.sock.connect((address,port)) 849 self.sock.connect((address,port))
857 # send client into with id=0 850 # send client into with id=0
858 self.sendMsg( self.sock, self.toxml("new") ) 851 self.sendMsg( self.sock, self.toxml("new") )
859 data = self.recvMsg( self.sock ) 852 data = self.recvMsg( self.sock )
860 # get new id and group_id 853 # get new id and group_id
861 xml_dom = parseXml(data) 854 xml_dom = self.xml.parseXml(data)
862 xml_dom = xml_dom._get_documentElement() 855 xml_dom = xml_dom._get_documentElement()
863 self.id = xml_dom.getAttribute("id") 856 self.id = xml_dom.getAttribute("id")
864 self.group_id = xml_dom.getAttribute("group_id") 857 self.group_id = xml_dom.getAttribute("group_id")
865 if xml_dom.hasAttribute('useCompression') and xml_dom.getAttribute('useCompression') == 'True': 858 if xml_dom.hasAttribute('useCompression') and xml_dom.getAttribute('useCompression') == 'True':
866 self.useCompression = True 859 self.useCompression = True
911 904
912 def get_next_id(self): 905 def get_next_id(self):
913 self.unique_cookie += 1 906 self.unique_cookie += 1
914 return_str = self.id + "-" + str(self.unique_cookie) 907 return_str = self.id + "-" + str(self.unique_cookie)
915 return return_str 908 return return_str
909