1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 This module contains Bzoo Server side objects.
19
20 Each message is an object providing encoding and decoding convenience for network transportation.
21
22 Client Messages
23 ===============
24 This is a paragraph in section 1.
25
26 Periodic messages
27 -----------------
28 such as Postion and Oriention Report
29
30 Asynchronous messages
31 ---------------------
32 such as message broadcasting, objetct activation,
33
34
35 Server Messages
36 ===============
37 Use numerical constant instead of string for indexing received message.
38
39 Periodic messages
40 -----------------
41 such as players'positions and orientions Report
42
43 Asynchronous messages
44 ---------------------
45 such as message broadcasting, objetct activation.
46
47 """
48
49 import socket
50
51 import bzProtocol
52 from bzProtocol import bzProtocol
53
54 import bzPicture
55 from bzPicture import bzPicture
56
57 import bzMessage
58 import bzTools
59 import time
60 import bzInventory
61 import bzException
62 import sys
63
65 """
66 This object deals with socket connection and low level data exchanges
67
68 @ivar pseudo: the pseudo of the player.
69 @type pseudo: string.
70 @ivar password: the password of the player
71 @type password: string.
72 @ivar current_id: the current identifier of the player
73 @type current_id: integer
74 @ivar connected: indicates if the player is currently connected.
75 @type connected: boolean
76 @ivar avatar: the avatar id choosen by the player.
77 @type avatar: integer.
78 @ivar last_connection_date:
79 @type last_connection_date:
80 @ivar last_disconnection_date:
81 @type last_disconnection_date:
82 @ivar last_saved_position: the position of the player when saved for the last time.
83 @type last_saved_position: 1*3 vector.
84 @ivar last_saved_orientation:
85 @type last_saved_orientation: 3*3 matrix.
86 @ivar last_saved_heading:
87 @type last_saved_heading: 3*3 matrix
88 @ivar last_saved_state:
89 @type last_saved_state: integer.
90 @ivar last_saved_action:
91 @type last_saved_action: integer.
92 @ivar last_saved_scene:
93 @type last_saved_scene: integer.
94 @ivar current_inventory:
95 @type current_inventory: L{bzInventory.bzInventory}
96 @ivar last_saved_inventory:
97 @type last_saved_inventory: L{bzInventory.bzInventory}
98 """
99
101 """
102 @param pseudo: the pseudo of the user
103 @type pseudo: string.
104 @param password: password of the user
105 @type password: string.
106 @return: N/A
107 @rtype: L{bzUser}
108 """
109 self.pseudo = pseudo
110 self.password = password
111 self.current_id = -1
112 self.connected = False
113 self.avatar = None
114 self.last_connection_date = time.localtime()
115 self.last_disconnection_date = 0
116 self.last_saved_position = [0.0, 0.0, 4.0]
117 self.last_saved_orientation = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]
118 self.last_saved_heading = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]
119 self.last_saved_state = 0
120 self.last_saved_action = 0
121 self.last_saved_scene = 0
122
123 self.current_inventory = bzInventory.bzInventory()
124 self.last_saved_inventory = bzInventory.bzInventory()
125
126
127
128
130 s= ''
131 s = s + "pseudo = %s, password = %s, cur_id = %d, last_connection = %s\n"%(self.pseudo, self.password, self.current_id, self.last_connection_date )
132 s = s + "pos = %s,\n ori = %s,\n heading = %s,\n state = %d,\n action = %d,\n scene = %d\n"%(self.last_saved_position, self.last_saved_orientation, self.last_saved_heading, self.last_saved_state, self.last_saved_action, self.last_saved_scene)
133 s = s + "inventory = %s\n"%(self.current_inventory.getContent())
134 return s
135
138
140 """
141 returns the pseudo of the player
142 @return: the pseudo of the player.
143 @rtype: string.
144 """
145 return (self.pseudo)
146
148 """
149 returns the inventory of the user
150 @return: the inventory of the user.
151 @rtype: L{bzInventory.bzInventory}.
152 """
153 return (self.current_inventory)
154
156 """
157 indicates if the user has already choosen an avatar
158 @return: True if user has selected an avatar, False otherwise
159 @rtype: boolean.
160 """
161 return (self.avatar != None)
162
164 """
165 returns the identifier of the avatar choosen by user.
166 @return: the identifier of the avatar choosen by user.
167 @rtype: integer.
168 """
169 return(self.avatar)
170
172 """
173 returns the password of user.
174 @return: the password used to authenticate the user.
175 @rtype: string.
176 """
177 return (self.password)
178
180 """
181 Changes the connection status of user to 'Connected'.
182 This function is called when user log in.
183 @param current_id: the id the player was given at connection.
184 @type current_id: string.
185 """
186 self.current_id = current_id
187 self.connected = True
188 self.last_connection_date = time.localtime()
189
191 """
192 Changes the connection status of user to 'Disconnected'.
193 This function is called when user log off.
194 """
195 self.current_id = -1
196 self.connected = False
197 self.last_disconnection_date = time.localtime()
198
200 """
201 returns the user current id (-1 if user is not connected).
202 @return: the user current id.
203 @rtype: integer.
204 """
205 return (self.current_id)
206
208 """
209 Indicates whether the player is connected or not.
210 @return: True if the user is connected, False otherwise.
211 @rtype: boolean.
212 """
213 if self.current_id == -1:
214 return (False)
215 else:
216 return (True)
217
219 """
220 Set the avatar id choosen by the user.
221 This function is typically called when user choose his avatar.
222 """
223 self.avatar = avatar
224
225 - def save(self, position = [0.0, 0.0, 0.0],
226 orientation = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
227 heading = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
228 scene = 0,
229 inventory = None):
230 """
231 Save information of user (position, orientation, scene number, inventory content).
232 User information that was saved can than be retrieved next time user connects.
233 @param position: the current position of the user.
234 @param position: 1*3 vector.
235 @param orientation: the current orientation of the user.
236 @param orientation: 3*3 matrix.
237 @param heading: the current heading of the user.
238 @param heading: 3*3 matrix.
239 @param scene: the scene id the user is currently in.
240 @param scene: integer.
241 @param inventory: the inventory of the user.
242 @param inventory: L{bzInventory.bzInventory}
243 """
244 self.last_saved_position = position
245 self.last_saved_orientation = orientation
246 self.last_saved_heading = heading
247 self.last_saved_scene = scene
248 self.last_saved_inventory = bzInventory.bzInventory()
249 inv = inventory.getContent()
250 for ii in inv:
251 self.last_saved_inventory.add(ii[0], ii[1])
252
253
255 """
256 Save player inventory with current known content.
257 """
258 self.last_saved_inventory = bzInventory.bzInventory()
259 inv = self.current_inventory.getContent()
260 for ii in inv:
261 self.last_saved_inventory.add(ii[0], ii[1])
262
263
264
266 """
267 Returns the last known position of user.
268 @return: the saved user position.
269 @rtype: integer.
270 """
271 return self.last_saved_position
272
274 """
275 Returns the inventory the user had the last time he saved game.
276 @return: the last saved inventory.
277 @rtype: L{bzInventory.bzInventory}.
278 """
279
280 return self.last_saved_inventory
281
283 """
284 Returns the last known orientation of user.
285 @return: the user orientation.
286 @rtype: 3*3 matrix.
287 """
288 return self.last_saved_orientation
289
291 """
292 Returns the last known heading of user.
293 @return: the user heading.
294 @rtype: 3*3 matrix.
295 """
296 return self.last_saved_heading
297
299 """
300 Returns the id of the last scene the user saved in.
301 @return: the user scene id.
302 @rtype: integer.
303 """
304 return self.last_saved_scene
305
307 """
308 This object deals server memory
309
310 @ivar users: the pseudo of the player.
311 @type users: List of L{bzUser}.
312 """
314 self.users = {}
315 pass
316
319
321 self.users[user_name] = bzUser(user_name,password)
322 self.users[user_name].setDisconnected()
323 return self.users[user_name]
324
326 usr = None
327 if usr_pseudo in self.users.keys():
328 usr = self.users[usr_pseudo]
329 return (usr)
330
333
335 """
336 A socket
337
338 @ivar hostname: the socket.
339 @type hostname: string.
340 @ivar port: the port number on which the server accept connection from.
341 @type port: integer.
342 @ivar socket: the socket.
343 @type socket: socket.socket.
344 @ivar sa: socket address.
345 @type sa: sockaddr.
346 """
347
349 self.hostname, self.port = hostname, port
350
351 self.socket = None
352 self.sa = None
353
354
355 for res in socket.getaddrinfo(self.hostname, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
356 af, socktype, proto, canonname, self.sa = res
357 try:
358 self.socket = socket.socket(af, socktype, proto)
359 except socket.error, msg:
360 print "socket error"
361 self.socket = None
362 continue
363 try:
364 self.socket.bind(self.sa)
365 self.socket.listen(1)
366 except socket.error, msg:
367 print "bind error"
368 self.socket.close()
369 self.socket = None
370 continue
371 break
372 if self.socket is None:
373 print 'could not open socket'
374 self.socket.setblocking(0)
375
376
379
380
381
383 """
384 A connection with a client
385
386 @ivar connected: .
387 @type connected: boolean.
388 @ivar connection: .
389 @type connection: socket.
390 @ivar address: .
391 @type address: sockaddr.
392 @ivar receive_status: .
393 @type receive_status: boolean.
394 @ivar serversocket: .
395 @type serversocket: socket.
396 """
398 self.connected = False
399 self.connection = None
400 self.address = None
401 self.receive_status = False
402 self.serversocket = serversocket
403
405 """
406 Check for connection request.
407 Socket is supposed not to be in blocking mode.
408 @return: True if a new connection was received
409 @rtype: Boolean
410 """
411 try:
412 [self.connection, self.address] = self.serversocket.accept()
413 print "connection from ", self.address
414 except:
415 [self.connection, self.address] = [None, None]
416 pass
417
418 if self.connection != None:
419 self.connected = True
420 else:
421 self.connected = False
422 return (self.connected)
423
424
426 """
427 Attempts to receive a data packet from a client.
428 Socket is supposed not to be in blocking mode.
429 @return: received data if attempt succeed.. None otherwise
430 @rtype: Byte array or None
431 """
432 data = None
433 try:
434 self.receive_status = False
435 data = self.connection.recv(1024)
436 self.receive_status = True
437 except socket.error, (errno, msg):
438
439 if (errno == 10054) or (errno == 10053):
440 self.receive_status = False
441 self.connected=False
442 return data
443
445 """
446 Send a raw data packet to client.
447 @param data: the data to send to the client.
448 @type data: Byte Array.
449 """
450 try:
451 self.connection.send(data)
452 except socket.error, (errno, msg):
453
454 if (errno == 10054) or (errno == 10053):
455 self.connected=False
456
457
459 """
460 Close connection with client.
461 """
462 self.connection.close()
463 self.connected = False
464
465
467 """
468 Gives the connection status of the socket.
469 @return: a boolean indicating whether socket is connected or not
470 @rtype: Boolean
471 """
472 return self.connected
473
474
475 -class bzServer(bzProtocol, bzServerSocket,bzPicture):
476 """
477 A Bzoo server.
478
479 @ivar nb_max_client: The maximum number of accepted client.
480 @type nb_max_client: integer.
481 @ivar nb_client: The current number of connected client.
482 @type nb_client: integer.
483 @ivar connections: .
484 @type connections: list of L{bzServerConnection}.
485 @ivar pseudos: .
486 @type pseudos: list of string.
487 @ivar logged: .
488 @type logged: list of boolean.
489 @ivar positions: .
490 @type positions: list of 1*3 vector.
491 @ivar orientations: .
492 @type orientations: list of 3*3 matrix.
493 @ivar headings: .
494 @type headings: list of 3*3 matrix.
495 @ivar states: .
496 @type states: list of integer.
497 @ivar actions: .
498 @type actions: list of integer.
499 @ivar avatars: .
500 @type avatars: list of integer.
501 @ivar message_queue: .
502 @type message_queue: socket.
503 @ivar inventories: .
504 @type inventories: list of L{bzInventory.bzInventory}.
505 @ivar visible_client: .
506 @type visible_client: socket.
507 """
508
509 - def __init__ (self, hostname='127.0.0.1', port=50000, nb_max_client=5):
510 """
511 @param hostname: The server hostname or IP adress ("" for internet hosting, "127.0.0.1" for local hosting)
512 @type hostname: Character string.
513 @param port: The port the server will listen and accept connection on.
514 @type port: Integer
515 @param nb_max_client: The max number of player.
516 @type nb_max_client: Integer.
517 @return: N/A
518 @rtype: L{bzServer}
519 """
520 self.nb_max_client = nb_max_client
521 self.nb_client = 0
522 self.current_client_id = 0
523
524 self.connections=[]
525 self.pseudos=[]
526
527 self.logged=[]
528 self.positions=[]
529 self.orientations=[]
530 self.headings=[]
531 self.states=[]
532 self.actions=[]
533 self.scenes=[]
534 self.avatars=[]
535 self.message_queue=[]
536 self.inventories=[]
537
538 self.visible_client=[[]]
539
540 bzServerSocket.__init__(self,hostname, port)
541 bzProtocol.__init__(self,)
542 bzPicture.__init__(self,)
543
544 self.ServerMemory = bzMemory()
545
546 self.addHandler(bzMessage.POSITION_REPORT_MESSAGE,self.PositionReportEvent)
547 self.addHandler(bzMessage.SAY_MESSAGE,self.SayMessageEvent)
548 self.addHandler(bzMessage.PRIVATE_SAY_MESSAGE,self.PrivateSayMessageEvent)
549 self.addHandler(bzMessage.GRAB_OBJECT_MESSAGE,self.GrabObjectEvent)
550 self.addHandler(bzMessage.ACTIVATE_OBJECT_MESSAGE,self.ActivateObjectEvent)
551 self.addHandler(bzMessage.RELEASE_OBJECT_MESSAGE, self.ReleaseObjectEvent)
552 self.addHandler(bzMessage.STORE_AVATAR_MESSAGE, self.StoreAvatarEvent)
553 self.addHandler(bzMessage.DECLARE_VAR_MESSAGE, self.DeclareVarEvent)
554
555
556 self.connections.append(bzServerConnection (self.socket))
557
558
561
563 self.visible_client=[[]]
564 if self.nb_client != 0:
565 self.visible_client=[[]] * (max(self.scenes)+1)
566 for i in range(max(self.scenes)+1):
567 self.visible_client[i]=[x for x in range(len(self.scenes)) if self.scenes[x]==i]
568
569
570
572 """
573 Close connection with all client.
574 """
575 idx_cnx =0
576 for co in self.connections:
577 if co.connected == True:
578 clt_pseudo = self.pseudos[idx_cnx]
579 self.ServerMemory.GetUser(clt_pseudo).setDisconnected()
580
581 co.CloseConnection()
582 idx_cnx = idx_cnx + 1
583
585 """
586 Saves user information into server memory for retrieval at next connection.
587 @param client_id: the current user id
588 @type client_id: Character string.
589 """
590
591 clt_pseudo = self.pseudos[client_id]
592 self.ServerMemory.GetUser(clt_pseudo).save (
593 self.positions[client_id] ,
594 self.orientations[client_id],
595 self.headings[client_id],
596 self.scenes[client_id] ,
597 self.inventories[client_id])
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
615 """
616 Create an entry into server's tables for a new user.
617 If the given pseudo is already in use on current Server, a new one is computed.
618 The given pseudo is used as a radical to which is added an index .Ex::
619 Nick will become Nick.001 is Nick is already used.
620 @param pseudo: The asked pseudo of the new user.
621 @type pseudo: String.
622 @return: The effective pseudo of the player.
623 @rtype: String.
624 """
625 effpseudo = pseudo
626 self.pseudos.append (effpseudo)
627
628 self.logged.append (False)
629 self.positions.append([0.0, 0.0, 4.0])
630 self.orientations.append([[0.0, 1.0, 0.0],[-1.0, 0.0, 0.0],[0.0, 0.0, 1.0]])
631 self.headings.append([[0.0, 1.0, 0.0],[-1.0, 0.0, 0.0],[0.0, 0.0, 1.0]])
632 self.states.append(0)
633 self.actions.append(0)
634 self.scenes.append(0)
635 self.inventories.append(bzInventory.bzInventory())
636
637 self.avatars.append(0)
638 self.message_queue.append([])
639 return (effpseudo)
640
642 """
643 Remove a player from server's tables.
644 @param idClient: The id in Server tables of the player to remove.
645 @type idClient: Integer.
646 """
647 del self.connections[idClient]
648 del self.pseudos[idClient]
649
650 del self.logged[idClient]
651 del self.positions[idClient]
652 del self.orientations[idClient]
653 del self.headings[idClient]
654 del self.states[idClient]
655 del self.actions[idClient]
656 del self.inventories[idClient]
657 del self.scenes[idClient]
658 del self.avatars[idClient]
659 del self.message_queue[idClient]
660
661
662 - def fct (self, idClient, part):
663 if self.connections[idClient].Connected():
664 data = self.connections[idClient].ReceiveData()
665 if (self.connections[idClient].receive_status == True) and (data is not None):
666
667 effpseudo = self.registerPseudo(data.split (':')[1])
668
669 pseudo = data.split (':')[1]
670 given_password = data.split (':')[2]
671
672 player = self.ServerMemory.GetUser(pseudo)
673 result = 0
674 reason = 0
675 if (player == None):
676 player = self.ServerMemory.RegisterUser(pseudo, given_password)
677
678
679 if (player.hasAvatar() == False):
680 reason = 1
681 else:
682 self.avatars[idClient]=self.ServerMemory.GetUser(effpseudo).getAvatar()
683
684 if part == 1:
685 reg_password = player.getPassword()
686 else:
687 reg_password = self.ServerMemory.GetUserPassword(pseudo)
688
689 if (reg_password == given_password) and (player.isConnected() == False):
690 self.pseudos[idClient]=pseudo
691
692 player.setConnected(idClient)
693 print "%s : connection from %s at %s"%(bzTools.getDateTime(), self.pseudos[idClient], self.connections[idClient].address)
694
695
696 responsedata = bzMessage.WelcomeMessage ().Encode(idClient, result, reason, effpseudo,
697 self.ServerMemory.GetUser(effpseudo).getSavedPosition(),
698 self.ServerMemory.GetUser(effpseudo).getSavedOrientation(),
699 self.ServerMemory.GetUser(effpseudo).getSavedHeading(),
700 0,
701 0,
702 self.ServerMemory.GetUser(effpseudo).getSavedScene())
703
704
705
706
707
708
709
710
711 self.connections[idClient].SendData(responsedata)
712
713
714 inv=self.ServerMemory.GetUser(effpseudo).getSavedInventory().getContent()
715 self.inventories[idClient] = bzInventory.bzInventory()
716 for inp in inv:
717 self.inventories[idClient].add(inp[0], inp[1])
718
719
720
721 self.message_queue[idClient].append(bzMessage.InitInventory(self.inventories[idClient].getContent()))
722
723
724
725 self.logged[idClient] = True
726 if part == 2:
727 self.nb_client = self.nb_client+1
728 print "nb_client = ", self.nb_client
729 self.connections.append(bzServerConnection (self.socket))
730
731
732
733 else:
734 result = 1
735 if (reg_password != given_password):
736 reason = 2
737 elif (player.isConnected() == True):
738 reason = 3
739 responsedata = bzMessage.WelcomeMessage ().Encode(idClient, result, reason, "DENIED",
740 [1.0, 0.0, 4.0],
741 [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
742 [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
743 0,
744 0,
745 0)
746 self.connections[idClient].SendData(responsedata)
747 print "Already connected player or wrong password 1"
748
749 self.connections[idClient].CloseConnection()
750 if part == 1:
751 self.logged[idClient] = False
752 lostClients.append(idClient)
753 else:
754 self.removeClient(idClient)
755 self.connections.append(bzServerConnection (self.socket))
756
757 else:
758 if part == 1:
759 print "Client %d still not connected .."%idClient
760 self.logged[idClient] = False
761 else:
762 effpseudo = self.registerPseudo("Unlogged")
763
764
765
767 """
768 Check for login and new connection.
769 """
770
771 lostClients = []
772
773
774
775
776 for idClient in range (self.nb_client):
777 if self.logged[idClient] == False:
778 self.fct(idClient, 1)
779
780
781
782
783 ii = 0;
784 for idClient in lostClients:
785 self.connections[idClient-ii].CloseConnection()
786 print "%s: disconnection from %s"%(bzTools.getDateTime(),self.pseudos[idClient-ii])
787
788 theuser = self.ServerMemory.GetUser(self.pseudos[idClient])
789 theuser.setDisconnected()
790
791 self.removeClient(idClient -ii)
792 ii = ii+1
793 self.nb_client = self.nb_client -1
794 print "nb_client = ", self.nb_client
795
796
797
798
799 nb_client = self.nb_client
800
801 if self.connections[nb_client].NewConnection() == True:
802
803 if nb_client < self.nb_max_client:
804
805 self.fct(nb_client,2)
806 else:
807
808 data = self.connections[nb_client].ReceiveData()
809 if (self.connections[nb_client].receive_status == True) and (data is not None):
810 print "%s: Refused connection from %s at %s "%(bzTools.getDateTime(),self.effpseudo, self.connections[nb_client].address)
811 reason = 4
812 response = bzMessage.WelcomeMessage ().Encode(nb_client, 1, reason, "DENIED",
813 [1.0, 0.0, 4.0],
814 [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
815 [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
816 0,
817 0,
818 0)
819 self.connections[nb_client].SendData(response)
820 print "4.0"
821
822 self.connections[nb_client].CloseConnection()
823 del self.connections[nb_client]
824 self.connections.append(bzServerConnection (self.socket))
825
826
827
828
830 """
831 Handles reception of a Position Report Message
832 @param values: [position, orientation, heading, state, action, scene]
833 @type values: [3*1 vector, 3*3 matrix, 3*3matrix, integer, integer, integer].
834 """
835
836 [position, orientation, heading, state, action, scene] = values
837 self.positions[self.current_client_id] = position
838 self.orientations[self.current_client_id] = orientation
839 self.headings[self.current_client_id] = heading
840 self.actions[self.current_client_id] = action
841 self.states[self.current_client_id] = state
842 self.scenes[self.current_client_id] = scene
843
844
846 """
847 Handles reception of a Say Message
848 @param values: [message]
849 @type values: [string].
850 """
851
852 [message] = values
853 if message.startswith("$"):
854 if message.startswith("$SAVEME"):
855 self.SaveUser(self.current_client_id)
856 else:
857 pass
858 else:
859 for cltid in range(self.nb_client):
860 self.message_queue[cltid].append(bzMessage.ClientsMessages([self.current_client_id, message]))
861
863 """
864 Handles reception of a Private Say Message
865 @param values: [topseudo, message]
866 @type values: [string, string].
867 """
868
869 [topseudo, message] = values
870 if topseudo in self.pseudos:
871 cltid = self.pseudos.index(topseudo)
872 self.message_queue[cltid].append(bzMessage.ClientsMessages([self.current_client_id, message]))
873
875 """
876 Handles reception of a Grab Object Message
877 @param values: [quantity, objname]
878 @type values: [integer, string].
879 """
880
881 [quantity, objname] = values
882 for cltid in range(self.nb_client):
883 self.message_queue[cltid].append(bzMessage.VanishObject(objname))
884 self.message_queue[self.current_client_id].append(bzMessage.InventoryAdd(quantity, objname))
885 self.inventories[self.current_client_id].add(quantity, objname)
886
887
888
890 """
891 Handles reception of a Declare Var Message
892 @param values: [quantity, varname]
893 @type values: [integer, string].
894 """
895
896 [quantity, varname] = values
897 self.message_queue[self.current_client_id].append(bzMessage.InventoryAdd(quantity, varname))
898 self.inventories[self.current_client_id].add(quantity, varname)
899 player = self.ServerMemory.GetUser(self.pseudos[self.current_client_id])
900 player.getInventory().add(quantity, varname)
901 player.saveInventory()
902
904 """
905 Handles reception of an Activate Object Message
906 @param values: [objname, activation type]
907 @type values: [string, integer].
908 """
909
910 [objname, value] = values
911 for cltid in range(self.nb_client):
912 self.message_queue[cltid].append(bzMessage.ActivateObject(objname, value))
913
915 """
916 Handles reception of a Realease Object Message
917 @param values: [objname, position]
918 @type values: [string, 3*1 vector].
919 """
920
921 [objname, position] = values
922 for cltid in range(self.nb_client):
923 self.message_queue[cltid].append(bzMessage.InstanciateObject(objname, position))
924 self.message_queue[self.current_client_id].append(bzMessage.InventoryAdd(-1, objname))
925
926
927 inventories[self.current_client_id].add(quantity, objname)
928
930 """
931 Handles reception of a Store Avatar Message
932 @param values: [id_avatar]
933 @type values: [integer].
934 """
935 [id_avatar] = values
936 self.ServerMemory.GetUser(self.pseudos[self.current_client_id]).setAvatar(id_avatar)
937 self.avatars[self.current_client_id] = id_avatar
938
939
941 """
942 Performs an exchange with each client.
943 """
944
945 self.handleConnection()
946
947
948
949
950
951
952 lostClients = []
953 self.current_client_id = 0
954
955 self.__rebuildVisibleClients__()
956
957
958 for self.current_client_id in range (self.nb_client):
959 if (self.logged[self.current_client_id] == True):
960 if (self.connections[self.current_client_id].Connected() == True) :
961
962 data = self.connections[self.current_client_id].ReceiveData()
963 if (self.connections[self.current_client_id].receive_status == True) and (data is not None):
964 self.processDataMessage(data)
965
966
967 self.__rebuildVisibleClients__()
968
969 client_scene = self.scenes[self.current_client_id]
970
971
972 ids = self.visible_client[client_scene]
973 pseudos = [self.pseudos[x] for x in self.visible_client[client_scene]]
974 positions = [self.positions[x] for x in self.visible_client[client_scene]]
975 orientations= [self.orientations[x] for x in self.visible_client[client_scene]]
976 headings= [self.headings[x] for x in self.visible_client[client_scene]]
977 states= [self.states[x] for x in self.visible_client[client_scene]]
978 actions= [self.actions[x] for x in self.visible_client[client_scene]]
979 scenes= [self.scenes[x] for x in self.visible_client[client_scene]]
980 avatars= [self.avatars[x] for x in self.visible_client[client_scene]]
981
982 self.message_queue[self.current_client_id].append(bzMessage.ClientsSituationReport(ids,pseudos, positions,orientations,headings, states, actions, scenes, avatars))
983
984
985
986 packet = self.getNextDataMessage(self.message_queue[self.current_client_id], 1024)
987 self.connections[self.current_client_id].SendData(packet)
988 else:
989 lostClients.append(self.current_client_id)
990
991
992
993
994
995 ii = 0;
996 for idClient in lostClients:
997 self.connections[idClient-ii].CloseConnection()
998 print "disconnection from %s"%self.pseudos[idClient-ii]
999 theuser = self.ServerMemory.GetUser(self.pseudos[idClient])
1000 theuser.setDisconnected()
1001 self.removeClient(idClient -ii)
1002 ii = ii+1
1003 self.nb_client = self.nb_client -1
1004 print "nb_client = ", self.nb_client
1005