Module bzClient
[frames] | no frames]

Source Code for Module bzClient

  1  ##bzClient.py defines main class for a BZoo client. 
  2  ##Copyright (C) 2006  Jean-Baptiste PERIN 
  3  ## 
  4  ##This program is free software; you can redistribute it and/or 
  5  ##modify it under the terms of the GNU General Public License 
  6  ##as published by the Free Software Foundation; either version 2 
  7  ##of the License, or (at your option) any later version. 
  8  ## 
  9  ##This program is distributed in the hope that it will be useful, 
 10  ##but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  ##GNU General Public License for more details. 
 13  ## 
 14  ##You should have received a copy of the GNU General Public License 
 15  ##along with this program; if not, write to the Free Software 
 16  ##Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. 
 17   
 18  # TODO: adapter la recherche d'id a partir des pseudos (utiliser le tableau self.ids plutot que self.pseudos.index()) car le serveur n'envoie plus les infos des clients connectes dans une autre scene 
 19  # TODO: le self.id et self.pseudo doivent pouvoir etre supprimer de bzClient et laisser uniquement dans bzConnection. 
 20  """ 
 21   This module contains Bzoo Client object definition 
 22   
 23  """ 
 24  import socket 
 25  import sys 
 26  import struct 
 27   
 28  import bzMessage 
 29   
 30  import bzException 
 31  import bzTools 
 32  import bzInventory 
 33  import bzPicture 
 34  from bzPicture import bzPicture 
 35  import bzProtocol 
 36  from bzProtocol import bzProtocol 
 37   
 38   
39 -class bzClientSocket:
40 """ 41 This object deals with socket connection and low level data exchanges 42 43 @ivar servername: servername 44 @type servername: string. 45 @ivar port: port number of socket 46 @type port: integer 47 @ivar socket : the socket 48 @type socket: socket 49 @ivar connected = False 50 @type connected: boolean 51 @ivar sa: sockaddr 52 @type sa: ??? 53 @ivar receive_status: indicates whether last read action succeeded. 54 @type receive_status: boolean 55 """ 56
57 - def __init__ (self, servername='127.0.0.1', port=50000):
58 """ 59 @param servername: The server hostname or IP adress 60 @type servername: String. 61 @param port: The port of the server to connect to 62 @type port: Integer 63 @return: N/A 64 @rtype: L{bzClient} 65 """ 66 self.servername = servername 67 self.port = port 68 self.socket = None 69 self.connected = False 70 #self.address = None 71 self.socket = None 72 self.sa = None 73 self.receive_status = False 74 for res in socket.getaddrinfo(self.servername, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM): 75 af, socktype, proto, canonname, self.sa = res 76 try: 77 self.socket = socket.socket(af, socktype, proto) 78 except socket.error, msg: 79 self.socket = None 80 continue
81
82 - def __repr__ (self, ):
83 return ""
84 85
86 - def Connect (self):
87 """ 88 Attempts to connect to server. 89 Socket is supposed not to be in blocking mode. 90 @return: True if connection was successfully established .. False otherwise 91 @rtype: Boolean 92 """ 93 try: 94 self.socket.connect(self.sa) 95 self.connected = True 96 except socket.error, msg: 97 self.socket.close() 98 #self.socket = None 99 self.connected = False 100 #if self.socket is None: 101 # print 'could not open socket' 102 return (self.connected)
103 104 105 106
107 - def ReceiveData (self):
108 """ 109 Attempts to receive a data packet from server. 110 Socket is supposed not to be in blocking mode. 111 @return: received data if attempt succeed.. None otherwise 112 @rtype: Byte array or None 113 """ 114 data = None 115 try: 116 self.receive_status = False 117 data = self.socket.recv(1024) 118 self.receive_status = True 119 except socket.error, (errno, msg): 120 #print "Exception %s %s while receiving "%(errno,msg) 121 if (errno == 10054) or (errno == 10053): # TODO: find the corresponding symbolic constant 122 self.receive_status = False 123 self.connected=False 124 125 return data
126
127 - def SendData (self, data):
128 """ 129 Send a raw data packet to server. 130 @param data: the data to send to server. 131 @type data: byte array. 132 """ 133 try: 134 self.socket.send(data) 135 except socket.error, (errno, msg): 136 #print "Exception %s %s while sending"%(errno,msg) 137 if (errno == 10054) or (errno == 10053): # TODO: what are the corresponding symbolic constant ? 138 self.connected=False
139
140 - def CloseConnection (self):
141 """ 142 Close connection with server by closing socket 143 """ 144 self.socket.close() 145 self.connected = False
146
147 - def Connected (self):
148 """ 149 Indicates if socket is opened 150 @return: a boolean indicating whether socket is connected or not 151 @rtype: Boolean 152 """ 153 return self.connected
154
155 -class bzConnection(bzClientSocket):
156 """ 157 A connection to the server 158 159 @ivar id: the identifier given by server 160 @type id: integer 161 @ivar pseudo: the pseudo used for the connection 162 @type pseudo: string. 163 @ivar password: the password used for this connection 164 @type password: string. 165 """ 166
167 - def __init__ (self, hostname='127.0.0.1', port=50000):
168 """ 169 @param hostname: The server hostname or IP adress 170 @type hostname: String. 171 @param port: The port of the server to connect to 172 @type port: Integer 173 @return: N/A 174 @rtype: bzClient 175 """ 176 self.id = 0 177 self.pseudo = 'Guest' 178 self.password = '' 179 bzClientSocket.__init__(self, hostname, port)
180
181 - def __repr__ (self, ):
182 return ""
183
184 - def OpenSession (self, pseudo, password):
185 """ 186 Open a session on the server by: 187 sending an ACCEPT String 188 receiving a WelcomeMessage 189 throw bzException.BZooConnectionError 190 @param pseudo: the login to use for this session. 191 @type pseudo: String. 192 @param password: the password. 193 @type password: String. 194 @return: [realid, result, reason, effpseudo, position , orientation , heading, state,action, scene] 195 @rtype: [Int, Int, Int , string, vector , matrix , matrix, Int ,Int, Int] 196 """ 197 realid = 0 198 bzClientSocket.Connect(self) 199 200 self.pseudo = pseudo 201 self.password = password 202 203 if self.Connected(): 204 print "Connection established" 205 chaine = 'ACCEPT:%s:%s'%(self.pseudo, self.password) 206 self.SendData(chaine) 207 data = self.ReceiveData () 208 209 nbbyte, [realid, result, reason, effpseudo, position , orientation , heading, state,action,scene] = bzMessage.WelcomeMessage().Decode(data) 210 211 self.id = realid 212 self.pseudo = effpseudo 213 214 if (result != 0): 215 # result == 0 (OK), 1 (OK New User), 2 (KO Wrong Password), 3 (KO Player Already Connected), 4 (KO Server Full) 216 print 'Connection refused . Serveur full ...' 217 raise bzException.BZooConnectionError("Connection refused") 218 else: 219 print 'Connected. My pseudo is: %s, my id is %d,'%(self.pseudo, self.id) 220 self.socket.setblocking(0) 221 else: 222 raise bzException.BZooConnectionError("Unable to connect") 223 return (realid, result, reason, effpseudo, position , orientation , heading, state,action,scene)
224
225 - def CloseSession (self):
226 """ 227 Close connection with server 228 """ 229 self.CloseConnection()
230 231 232
233 -class bzClient(bzProtocol, bzConnection, bzPicture):
234 """ 235 This class is the main canevas for a BZoo client application object. 236 237 238 The Hello World program. 239 ======================== 240 241 The simplest BZoo client. 242 ------------------------- 243 244 245 Source:: 246 import bzClient 247 248 login = 'MyLogin' 249 password = 'MyPassword' 250 251 aClient = bzClient.bzClient(hostname='127.0.0.1', port=50001, pseudo=login) 252 aClient.OpenSession(login, password) 253 aClient.SayMessage('Hello World') 254 aClient.CloseSession() 255 256 This simple program opens a connection with the server that should be running on the local computer. 257 Next, it opens a session and send a "Hello world" message to others. 258 The message should appear in the chat windows of all connected people currently playing in the same scene. 259 Finally, it closes the session with the server. 260 261 It is to be noted that in this basic example, no control is made upon connection results. 262 Moreover, it is a very short session. The connection only last the time to say "Hello World" . 263 264 Entertaining connection. 265 ------------------------ 266 Let's see a more complete example. 267 268 269 Sources:: 270 class ThreadClient ( threading.Thread, bzClient.bzClient ): 271 272 def __init__ ( self , login, passwd): 273 bzClient.bzClient.__init__(self, hostname='127.0.0.1', port=50001, pseudo=login) 274 [result, reason] = self.OpenSession(login, passwd) 275 print "Connection result = ", [result, reason] 276 threading.Thread.__init__(self) 277 self.running = False 278 279 280 def run ( self ): 281 self.running = True 282 while (self.running == True): 283 self.Pulse() 284 time.sleep (0.35) 285 286 def stop ( self ): 287 self.running = False 288 self.CloseConnection() 289 290 login = 'MyLogin' 291 passwd = 'MyPassword' 292 client = ThreadClient(login, passwd) 293 client.start () 294 295 In practice, when using BZoo client within Blender Game engine, you don't have to deal with thread. 296 The game engine does it for you. 297 Thus, in a Blender game, a typical use of bzClient object could be to: 298 - Create an object with an allways sensor 299 - Attach this sensor to a Python controller with the following content: 300 301 Sources:: 302 303 if hasattribute(GameLogic,"BClient") == False: 304 GameLogic.BClient = bzClient.bzClient(hostname='127.0.0.1', port=50001, pseudo=login) 305 GameLogic.BClient.OpenSession(login, password) 306 GameLogic.BClient.SayMessage('Hello World') 307 else: 308 GameLogic.BClient.Pulse() 309 310 The program above, when cyclically called by an always sensor, first creates a bzClient if it doesn't already exist and start a session on server. 311 It entertains the connection with the server by periodically calling the C{Pulse()} method of bzClient Object it it exists. 312 313 314 Depicting the current world situation. 315 ====================================== 316 The goal of the connection we depicted above is to provide a way, for a BZoo Client program, to get informed of what other client situation (their position, oritentation, their current action, and so on). 317 Thanks to these informations, a BZoo client application can control the game engine to make it depicting the whole game context. 318 The principle relies on a periodic exchange of information between client and server that runs in 3 steps: 319 - The client reports his situation to the server. 320 - Server, as a reply, gives it the report of other client situation. 321 - The client update scene content in the game engine. 322 Information exchanges are handled and monitored by the bzClient.Pulse() function. 323 The BZoo programmer is only in charge of providing updated information about player situation so that the reporting process can send them to the server. 324 Typical information are: 325 - Current position 326 - Current orientation 327 - Current heading 328 - Current status 329 - Current action 330 - Current visited scene 331 the bzClient provides method to 332 It also provides functions to read equivalent report from other players. 333 The two following sections describe the way to refresh player current information and 334 The third section talks about the exchange that can occurs aperiodically 335 336 337 Getting information on game context 338 ----------------------------------- 339 340 TO BE WRITTEN 341 342 Sources:: 343 344 if hasattribute(GameLogic,"BClient") == True: 345 nbc = GameLogic.BClient.GetNbClients() 346 print "there are %d people in this game scene"%nbc 347 348 inventory = GameLogic.BClient.GetInventoryContent() 349 print "My inventory content is : ", inventory 350 351 352 Updating your information on server 353 ----------------------------------- 354 TO BE WRITTEN 355 356 Sources:: 357 358 if hasattribute(GameLogic,"BClient") == True: 359 GameLogic.BClient.StorePosition([posX, posY, posZ]) 360 GameLogic.BClient.StoreScene() 361 362 The above example only shows the position updating. 363 Similar call StorePosition() StoreOrientation() and StoreHeading() 364 365 Aperiodic exchanges 366 ------------------- 367 TO BE WRITTEN 368 369 Sources:: 370 if hasattribute(GameLogic,"BClient") == True: 371 372 GameLogic.BClient.GrabObject(1, "Lamp") 373 GameLogic.BClient.SayMessage("I've just grabbed a lamp!") 374 375 GameLogic.BClient.ActivateObject("Door", 1) 376 GameLogic.BClient.SayMessage("I've just opened the door!") 377 378 379 Getting closer from the protocol. 380 ================================= 381 382 Using Network Message Handler 383 ----------------------------- 384 TO BE WRITTEN 385 386 Using System Command 387 -------------------- 388 TO BE WRITTEN 389 390 391 Extending protocol 392 ------------------ 393 TO BE WRITTEN 394 395 396 @ivar position: the current position of the player 397 @type position: 3*1 Vector 398 @ivar orientation: the current orientation of the player 399 @type orientation: 3*3 Matrix 400 @ivar start_position : the start position 401 @type start_position: 3*1 Vector 402 @ivar start_orientation = the start orientation 403 @type start_orientation: 3*3 Matrix. 404 @ivar start_scene: the scene number to start in. 405 @type start_scene: integer. 406 @ivar heading: the current heading of the player. 407 @type heading: 3*3 Matrix. 408 @ivar action: the current action of the player (???). 409 @type action: integer 410 @ivar scene: the scene the player is currently in. 411 @type scene: integer 412 @ivar state: the state the player is in (???). 413 @type state: integer 414 @ivar id_avatar: the number of the player's avatar 415 @type id_avatar: integer 416 @ivar inventory: the player's inventory 417 @type inventory: L{bzInventory.bzInventory} 418 @ivar message_queue: the message to be sent. 419 @type message_queue: array of L???? 420 @ivar display: the ???? 421 @type display: L{bzTools.bzDisplay} 422 423 @ivar pseudos: list of pseudos 424 @type pseudos: list of string 425 @ivar positions: list of players'positions 426 @type positions: list of 3*1 vector 427 @ivar orientations: list of players'orientations 428 @type orientations: list of 3*3 matrix 429 @ivar headings: list of players'headings 430 @type headings: list of 3*3 matrix 431 @ivar states: lsit of player's states 432 @type states: list of integer 433 @ivar actions: list of players'current actions 434 @type actions: list of integer 435 @ivar scenes: list of scene player's are in. 436 @type scenes: list of integer 437 @ivar avatars: list of players'avatar id 438 @type avatars: list of integer 439 @ivar object_activation: dictionnary of action upon object. 440 @type object_activation: 441 442 443 """ 444
445 - def __init__ (self, hostname='127.0.0.1', port=50000, pseudo='Guest'):
446 """ 447 @param hostname: The server hostname or IP adress 448 @type hostname: String. 449 @param port: The port of the server to connect to 450 @type port: Integer 451 @param pseudo: The pseudo of the player 452 @type pseudo: Character string. 453 @return: N/A 454 @rtype: bzClient 455 """ 456 self.hostname = hostname 457 self.port = port 458 self.pseudo = pseudo 459 self.id = 0 460 461 self.position = [0.0, 0.0, -20.0] 462 self.orientation = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] 463 self.start_position = [0.0, 0.0, 4.0] 464 self.start_orientation = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] 465 self.start_scene = 0 466 self.heading = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] 467 self.action = 0 468 self.scene = 0 469 self.state = 0 470 self.id_avatar = 0 471 self.inventory = bzInventory.bzInventory() 472 self.message_queue = [] 473 self.display=bzTools.bzDisplay() 474 475 self.pseudos = [] 476 self.positions = [] 477 self.orientations = [] 478 self.headings = [] 479 self.states = [] 480 self.actions = [] 481 self.scenes = [] 482 self.avatars = [] 483 #self.incomming_message=[] 484 self.object_activation = {} 485 486 #self.nb_client = 0 487 488 bzConnection.__init__(self,hostname, port) 489 bzProtocol.__init__(self) 490 bzPicture.__init__(self) 491 492 self.addHandler(bzMessage.SITUATION_REPORT_MESSAGE,self.ClientsSituationReportEvent) 493 self.addHandler(bzMessage.CLIENTS_MESSAGES_MESSAGE,self.ClientsMessagesEvent) 494 self.addHandler(bzMessage.VANISH_OBJECT_MESSAGE,self.VanishObjectEvent) 495 self.addHandler(bzMessage.INSTANCIATE_OBJECT_MESSAGE,self.InstanciateObjectEvent) 496 self.addHandler(bzMessage.ACTIVATE_OBJECT_MESSAGE,self.ActivateObjectEvent) 497 self.addHandler(bzMessage.INVENTORY_ADD_MESSAGE,self.InventoryAddEvent) 498 self.addHandler(bzMessage.INIT_INVENTORY_MESSAGE, self.InitInventoryEvent)
499
500 - def ActivateObjectEvent(self, values):
501 """ 502 Handles reception of a Activate Object Message 503 @param values: [objname, action] 504 @type values: [String, Integer]. 505 """ 506 #print "ActivateObjectEvent, values=", values 507 [objname, action] = values 508 self.object_activation [objname] = action 509 pass
510
511 - def InitInventoryEvent(self, values):
512 """ 513 Handles reception of a Init Inventory Message 514 @param values: [list of [object_name, quantity]] 515 @type values: [list of [String, Integer]]. 516 """ 517 print "InitInventoryEvent, values=", values 518 [inventory] = values 519 self.inventory.getContent().extend(inventory) 520 pass
521
522 - def ClientsMessagesEvent(self, values):
523 """ 524 Handles reception of a Clients Message 525 @param values: [pseudo, message] 526 @type values: [String, String]. 527 """ 528 #print "ClientsMessagesEvent, values=", values 529 messages = values 530 # find the index of sender from table self.ids 531 idx_client = self.ids.index(messages[0]) 532 self.display.QueueMessage(messages[1], self.pseudos[idx_client])
533
534 - def ClientsSituationReportEvent(self, values):
535 """ 536 Handles reception of a Clients Situation Report. 537 @param values: [ ids, pseudos, positions, orientations, headings, states, actions, scenes, avatars] 538 @type values: [ Int[],String[], Vector[], Matrix[], Matrix[], Int[], Int[], Int[], Int[]]. 539 """ 540 #print "ClientsSituationReportEvent, values=", values 541 [self.ids, self.pseudos, self.positions, self.orientations, self.headings, self.states, self.actions, self.scenes, self.avatars] = values 542 lenewid = self.ids[self.pseudos.index(self.pseudo)] 543 if lenewid != self.id: 544 self.id = self.ids[self.pseudos.index(self.pseudo)] 545 print "my new id is %d"%(self.id) 546 lenewid_avatar = self.avatars[self.pseudos.index(self.pseudo)] 547 if lenewid_avatar != self.id_avatar: 548 self.id_avatar = self.avatars[self.pseudos.index(self.pseudo)] 549 print "my new id is %d"%(self.id)
550 551
552 - def VanishObjectEvent(self, values):
553 """ 554 Handles reception of a Vanish Object message. 555 DO NOTHING !! 556 @param values: [ obj_name] 557 @type values: [ String]. 558 """ 559 #print "VanishObjectEvent, values=", values 560 [objname] = values
561
562 - def InventoryAddEvent(self, values):
563 """ 564 Handles reception of an Inventory Add message. 565 @param values: [ quantity, obj_name] 566 @type values: [ Int, String]. 567 """ 568 #print "InventoryAddEvent, values=", values 569 [quantity, objname] = values 570 571 self.inventory.add(quantity, objname)
572 #print self.inventory.getContent() 573 574
575 - def InstanciateObjectEvent (self, values):
576 """ 577 Handles reception of an Instanciate Object message. 578 DO NOTHING !! 579 @param values: [ quantity, obj_name] 580 @type values: [ Int, String]. 581 """ 582 #print "InstanciateObjectEvent, values=", values 583 [quantity, objname] = values
584 585 586 587 588
589 - def OpenSession (self, pseudo, password):
590 """ 591 Open a session on the server by: 592 sending an ACCEPT String 593 Initialize scene, position, orientation, heading, and 594 throw bzException.BZooConnectionError 595 @param pseudo: the login to use for this session. 596 @type pseudo: String. 597 @param password: the password. 598 @type password: String. 599 @return: [result, reason] 600 @rtype: [Int, Int] 601 """ 602 self.start_id, result, reason, self.pseudo, self.start_position , self.start_orientation , self.start_heading, self.start_state, self.start_action, self.start_scene = bzConnection.OpenSession (self, pseudo, password) 603 self.id = self.start_id 604 #print "position ", self.start_position 605 606 return([result, reason])
607
608 - def GetPseudo (self):
609 """ 610 @return: The pseudo used in the session 611 @rtype: String 612 """ 613 return (self.pseudo)
614
615 - def GetId (self):
616 """ 617 @return: The current id for this session 618 @rtype: Integer 619 """ 620 return (self.id)
621
622 - def GetScene (self):
623 """ 624 @return: The number of the scene the client is in 625 @rtype: Integer 626 """ 627 return (self.scene)
628
629 - def GetNbClients (self):
630 """ 631 Give the number of clients connected to the serveur. 632 633 @return: The number of people connected to the server 634 @rtype: Integer 635 """ 636 return (len(self.pseudos))
637
638 - def GetInventoryContent (self):
639 """ 640 Gives the content of the client's inventory 641 642 @return: the client's inventory (list of [Quantity, ObjectType]) 643 @rtype: list of tuple [Integer, String] 644 """ 645 return (self.inventory.getContent())
646
647 - def GetVariableValue (self, var_name):
648 """ 649 Gives the value of player's variable 'var_name' 650 651 @param var_name: the name of the variable. 652 @type var_name: String. 653 @return: the client's inventory (list of [Quantity, ObjectType]) 654 @rtype: Integer 655 """ 656 return (self.inventory.count(var_name))
657
658 - def StorePosition (self, position):
659 """ 660 Give the current position of the player associated with this client. 661 This position is the one that is sent. 662 This function must be periodically called to inform other players 663 of the player's current position 664 665 @param position: The current position of the Player 666 @type position: 3*1 Vector 667 """ 668 self.position = [position[0], position[1], position[2]]
669
670 - def StoreOrientation (self, orientation):
671 """ 672 Set the current orientation of the player associated with this client 673 674 This orientation is the one that is sent to other clients 675 676 This function must be periodically called to inform other players 677 of the player's current orientation 678 679 @param orientation: The current orientation of the Player 680 @type orientation: 3*3 Matrix 681 """ 682 self.orientation = [[orientation[0][0], orientation[0][1], orientation[0][2]], 683 [orientation[1][0], orientation[1][1], orientation[1][2]], 684 [orientation[2][0], orientation[2][1], orientation[2][2]]]
685 686
687 - def StoreHeading (self, heading):
688 """ 689 Set the current heading of the player associated with this client 690 691 This orientation is the one that is sent to other clients 692 693 This function must be periodically called to inform other players 694 of the player's current heading 695 696 @param heading: The current heading of the Player 697 @type heading: 3*3 Matrix 698 """ 699 self.heading = [[heading[0][0], heading[0][1], heading[0][2]], 700 [heading[1][0], heading[1][1], heading[1][2]], 701 [heading[2][0], heading[2][1], heading[2][2]]]
702 703
704 - def StoreScene (self, scene):
705 """ 706 Set the current scene of the player associated with this client 707 708 This orientation is the one that is sent to other clients 709 710 This function must be periodically called to inform other players 711 of the player's current scene 712 713 @param scene: The current scene of the Player 714 @type scene: Integer 715 """ 716 self.scene = scene
717 718 719 720
721 - def StoreAction (self, action):
722 """ 723 Set the current action of the player associated with this client 724 725 This action is the one that is sent to other clients 726 727 This function must be periodically called to inform other players 728 of the player's current action 729 730 @param action: The current action of the Player 731 @type action: Integer 732 """ 733 if self.action != action: 734 self.action = action
735
736 - def StoreState (self, state):
737 """ 738 Set the current state of the player associated with this client 739 740 This state is the one that is sent to other clients 741 742 This function must be periodically called to inform other players 743 of the player's current state 744 745 @param state: The current state of the Player 746 @type state: Integer 747 """ 748 if self.state != state: 749 self.state = state
750 751
752 - def Pulse (self):
753 """ 754 Performs an exchange with server. 755 756 Player send information about his position and orientation and collect other client's information from server 757 This function must be periodically called (at each game TIC) 758 """ 759 data = None 760 761 try: 762 #print self.scene 763 self.message_queue.append(bzMessage.PositionReport(self.position, self.orientation , self.heading, self.state ,self.action , self.scene )) 764 765 766 data2send = self.getNextDataMessage(self.message_queue, 1024) 767 768 self.SendData (data2send) 769 770 # little hack for bombing 771 self.action = self.action & 0xFD 772 #self.action = self.action & 0xFE 773 774 data = self.ReceiveData () 775 if (self.receive_status == True) and (data is not None): 776 self.processDataMessage(data) 777 778 except socket.error, msg: 779 print "Exception %s %s"%(socket.error, msg)
780 781 782 783
784 - def Say (self, message):
785 """ 786 Send a text message to all players connected to the server 787 788 @param message: The message to be sent to other players 789 @type message: String 790 """ 791 self.message_queue.append(bzMessage.SayMessage(message))
792 #print self.message_queue 793
794 - def ChooseAvatar (self, id_avatar):
795 """ 796 Set the avatar choosen by the player 797 798 This function is called when player choose is avatar 799 800 @param id_avatar: The id of the choosen avatar 801 @type id_avatar: Integer 802 """ 803 self.id_avatar = id_avatar 804 self.message_queue.append(bzMessage.StoreAvatar(self.id_avatar))
805
806 - def PrivateSay (self, pseudo, message):
807 """ 808 Send a text message to all players connected to the server 809 810 @param pseudo: The pseudo of the player to sent the message to 811 @type pseudo: String 812 @param message: The message to be sent to other players 813 @type message: String 814 """ 815 self.message_queue.append(bzMessage.PrivateSayMessage(pseudo, message))
816
817 - def GrabObject (self, quantity, objname):
818 """ 819 Make the client grab an object from the scene 820 @param quantity: The quantity of grabbed object 821 @type quantity: String 822 @param objname: The name of the grabbed object 823 @type objname: String 824 """ 825 self.message_queue.append(bzMessage.GrabObject(quantity,objname))
826
827 - def DeclareVar (self, quantity, varname):
828 """ 829 Declare a player variable onto the server. 830 It is used to inform the server of a variable that has to be dealt with for this player "Health", "Strength", ... 831 @param quantity: The initialisation value of variable 832 @type quantity: Int 833 @param varname: The name of the variable 834 @type varname: String 835 """ 836 self.message_queue.append(bzMessage.DeclareVar(quantity,varname))
837 838
839 - def ReleaseObject (self, objname='Lamp', position = [0.0, 0.0, 0.0]):
840 """ 841 Make the client release an object from the scene at a given position. 842 843 844 @param objname: The name of the released object 845 @type objname: String 846 @param position: The location where the object is released 847 @type position: String 848 """ 849 self.message_queue.append(bzMessage.ReleaseObject(objname, position))
850 851
852 - def ActivateObject (self, objname,value):
853 """ 854 Make the client activate an object from the scene 855 856 @param objname: The name of the activated object 857 @type objname: String 858 @param value: The activation value 859 @type value: Integer 860 """ 861 self.message_queue.append(bzMessage.ActivateObject(objname,value))
862
863 - def SaveOnServer (self):
864 """ 865 Make the client send a SAVEME command to the server 866 867 """ 868 self.message_queue.append(bzMessage.SayMessage("$SAVEME"))
869 870 if __name__ == "__main__": 871 #print "coucou" 872 aClient = bzClient(hostname='127.0.0.1', port=50000, pseudo='Guest') 873 aClient.OpenSession('coucou','pass') 874 del aClient 875