1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import struct
19 import bzTools
20
21 """
22 This module contains Message object used by bzProtocol
23
24 Each message is an object providing encoding and decoding convenience for network transportation.
25
26 Client Messages
27 ===============
28 This is a paragraph in section 1.
29
30 Periodic messages
31 -----------------
32 such as Postion and Oriention Report
33
34 Asynchronous messages
35 ---------------------
36 such as message broadcasting, objetct activation,
37
38
39 Server Messages
40 ===============
41 Use numerical constant instead of string for indexing received message.
42
43 Periodic messages
44 -----------------
45 such as players'positions and orientions Report
46
47 Asynchronous messages
48 ---------------------
49 such as message broadcasting, objetct activation.
50
51 """
52
53
54 BOTH_SIDE=0
55 CLIENT_SIDE=1
56 SERVER_SIDE=2
57
58 HIGH_PRIORITY = 0
59 MEDIUM_PRIORITY = 1
60 LOW_PRIORITY = 2
61
62 CONSUMABLE = 0
63 PERMANENT = 1
64
65 POSITION_REPORT_MESSAGE = 0
66 SITUATION_REPORT_MESSAGE = 1
67 SAY_MESSAGE = 2
68 CLIENTS_MESSAGES_MESSAGE = 3
69 PRIVATE_SAY_MESSAGE = 4
70 WELCOME_MESSAGE = 5
71 INIT_INVENTORY_MESSAGE = 6
72 GRAB_OBJECT_MESSAGE = 7
73 VANISH_OBJECT_MESSAGE = 8
74 INVENTORY_ADD_MESSAGE = 9
75 INSTANCIATE_OBJECT_MESSAGE = 10
76 ACTIVATE_OBJECT_MESSAGE = 11
77 RELEASE_OBJECT_MESSAGE = 12
78 STORE_AVATAR_MESSAGE = 13
79 DECLARE_VAR_MESSAGE = 14
80
81 msgid =[
82 POSITION_REPORT_MESSAGE,
83 SITUATION_REPORT_MESSAGE,
84 SAY_MESSAGE,
85 CLIENTS_MESSAGES_MESSAGE,
86 PRIVATE_SAY_MESSAGE,
87 WELCOME_MESSAGE,
88 INIT_INVENTORY_MESSAGE,
89 GRAB_OBJECT_MESSAGE,
90 VANISH_OBJECT_MESSAGE,
91 INVENTORY_ADD_MESSAGE,
92 INSTANCIATE_OBJECT_MESSAGE,
93 ACTIVATE_OBJECT_MESSAGE,
94 RELEASE_OBJECT_MESSAGE,
95 STORE_AVATAR_MESSAGE,
96 DECLARE_VAR_MESSAGE
97 ]
98
101 self.MsgType = type
102 self.MsgPriority = priority
103 self.MsgSide = BOTH_SIDE
104 self.MsgPersistence = CONSUMABLE
105 self.header = struct.pack ('B',self.MsgType)
106 self.data = ''
107
109 return "type = %d"%(self.MsgType)
110
115
117 chaine = ''
118 return ""
119
128
129
131 """
132 Init message sent when connection accepted.
133
134 Message is sent periodically (at each TIC).
135 'hhhh%dsfffffffffhhh'
136 """
137 - def __init__ (self,
138 realid = 0,
139 result = 0,
140 reason = 0,
141 pseudo = "Guest",
142 position = [0.0, 0.0, 0.0],
143 orientation = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
144 heading = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
145 state = 0,
146 action = 0,
147 scene = 0,
148 ):
149 self.id = realid
150 self.result = result
151 self.reason = reason
152 self.pseudo = pseudo
153 self.PosX = position[0]
154 self.PosY = position[1]
155 self.PosZ = position[2]
156 self.Action = action
157 self.State = state
158 self.Scene = scene
159
160 self.Orientation = orientation
161 self.Heading = heading
162
163 ServerMessage.__init__(self, WELCOME_MESSAGE, HIGH_PRIORITY)
164 self.MsgPersistence = CONSUMABLE
165
166 - def Encode (self,
167 realid = 0,
168 result = 0,
169 reason = 0,
170 pseudo = "Guest",
171 position = [0.0, 0.0, 0.0],
172 orientation = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
173 heading = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
174 state = 0,
175 action = 0,
176 scene = 0 ):
177 """
178 @param realid: Id of the client
179 @type realid: Integer
180 @param result: Result of session opening
181 @type result: Integer
182 @param reason: The reason associated with the result
183 @type reason: Integer
184 @param pseudo: pseudo for the session
185 @type pseudo: String
186 @param position: Vector [posX, posY, posZ]
187 @type position: = 3*1 Vector
188 @param orientation: [[r11, r12, r13],[r21, r22, r23],[r31, r32, r33]]
189 @type orientation: 3*3 Matrix
190 @param heading: [[h11, h12, h13],[h21, h22, h23],[h31, h32, h33]]
191 @type heading: 3*3 Matrix
192 @param state: the last state the player was in
193 @type state: Integer
194 @param action: the Action played by the player
195 @type action: Integer
196 @param scene: the scene in which the client was seen the last time he disconnected.
197 @type scene: Integer
198 @return: the encoded data
199 @rtype: Byte Array. 'B' + '!BBBBBBB%dsfffffffff'
200 """
201 self.id = realid
202 self.result = result
203 self.reason = reason
204 self.pseudo = pseudo
205 self.PosX = position[0]
206 self.PosY = position[1]
207 self.PosZ = position[2]
208 self.Action = action
209 self.State = state
210 self.Scene = scene
211
212 self.Orientation = orientation
213 self.Heading = heading
214
215 eul = bzTools.mat2eul(self.Orientation)
216 heul = bzTools.mat2eul(self.Heading)
217 self.data = struct.pack ('!BBBBBBB%dsfffffffff'%len(self.pseudo),
218 self.id,
219 self.result,
220 self.reason,
221 self.State,
222 self.Action,
223 self.Scene,
224 len(self.pseudo),
225 self.pseudo,
226 self.PosX, self.PosY, self.PosZ,
227 eul[0],
228 eul[1],
229 eul[2],
230 heul[0],
231 heul[1],
232 heul[2]
233
234 )
235
236 return (self.header + self.data)
237
239 """
240 @param data: the data to decode.
241 @type data: Byte Array. 'B' + '!BBBBBBB%dsfffffffff'
242 @return: nb_processed_bytes, [Id, Result, Reason, Pseudo, Position, Orientation, Heading, State, Action, Scene ]
243 @rtype: Int, [Int,Int, Int, String, Vector, Matrix, Matrix, Integer, Integer, Integer
244 """
245
246 idx_byte = 0
247
248
249 [typ] = struct.unpack ('!B', data [idx_byte:idx_byte+struct.calcsize('!B')])
250 idx_byte = idx_byte + struct.calcsize('!B')
251
252
253 [self.id] = struct.unpack ('!B',data[idx_byte:idx_byte+struct.calcsize('!B')])
254 idx_byte = idx_byte + struct.calcsize('!B')
255
256 [self.result] = struct.unpack ('!B',data[idx_byte:idx_byte+struct.calcsize('!B')])
257 idx_byte = idx_byte + struct.calcsize('!B')
258
259 [self.reason] = struct.unpack ('!B',data[idx_byte:idx_byte+struct.calcsize('!B')])
260 idx_byte = idx_byte + struct.calcsize('!B')
261
262 [self.State,self.Action,self.Scene] = struct.unpack ('!BBB',data[idx_byte:idx_byte+struct.calcsize('!BBB')])
263 idx_byte = idx_byte + struct.calcsize('!BBB')
264
265
266 [pseudolen] = struct.unpack ('!B',data[idx_byte:idx_byte+struct.calcsize('!B')])
267 idx_byte = idx_byte + struct.calcsize('!B')
268
269 self.pseudo = str(data[idx_byte:idx_byte+struct.calcsize('!%ds'%pseudolen)])
270 idx_byte = idx_byte + struct.calcsize('!%ds'%pseudolen)
271
272 eul = [0.0, 0.0, 0.0]
273 heul = [0.0, 0.0, 0.0]
274 [ self.PosX, self.PosY, self.PosZ,eul[0],eul[1],eul[2],heul[0],heul[1],heul[2]] = struct.unpack ('!fffffffff',data[idx_byte:idx_byte+struct.calcsize('!fffffffff')])
275 idx_byte = idx_byte + struct.calcsize('!fffffffff')
276
277
278 self.Heading = bzTools.eul2mat(eul)
279 self.Orientation = bzTools.eul2mat(heul)
280
281 return (idx_byte, [self.id, self.result, self.reason, self.pseudo,
282 [self.PosX, self.PosY, self.PosZ],
283 self.Orientation,
284 self.Heading,
285 self.State,self.Action,self.Scene])
286
287
289 """
290 Init player inventory.
291
292 Message sent when connection accepted.
293 'BB' + 'BB%ds'*NbObject
294 """
295 - def __init__ (self,
296 inventory = [],
297 ):
300
301 - def Encode (self,
302 inventory = [],
303 ):
304 """
305 @param inventory: list of owned objects
306 @type inventory: list of tuple [quantity, object]
307 @return: the encoded data
308 @rtype: Byte Array. 'B' + 'B' + 'BB%ds'*NbObject
309 """
310 if len(inventory) != 0:
311 self.inventory = inventory
312
313 nbObjects = len(self.inventory)
314
315 self.data = struct.pack ('B',nbObjects)
316
317 for idx_obj in range(nbObjects):
318 self.data = self.data + struct.pack ('BB%ds'%len(self.inventory[idx_obj][1]),
319 self.inventory[idx_obj][0],
320 len(self.inventory[idx_obj][1]),
321 self.inventory[idx_obj][1]
322 )
323 return (self.header + self.data)
324
326 """
327 @param data: the data to decode.
328 @type data: Byte Array. 'B' + 'B' + 'BB%ds'*NbObject
329 @return: list of NbObject objects in inventory [quantity, object name]
330 @rtype: list of tuple [Integer, String]
331 """
332
333 idx_byte = 0
334
335 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
336 idx_byte = idx_byte + struct.calcsize('B')
337
338 [nbObjectType] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
339 idx_byte = idx_byte + struct.calcsize('B')
340 self.inventory = []
341
342 for i in range (nbObjectType):
343
344
345 [quantity] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
346 idx_byte = idx_byte + struct.calcsize('B')
347
348 [objnamelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
349 idx_byte = idx_byte + struct.calcsize('B')
350
351
352 object_name = str(data[idx_byte:idx_byte+struct.calcsize('%ds'%objnamelen)])
353 idx_byte = idx_byte + struct.calcsize('%ds'%objnamelen)
354
355 self.inventory.append ([quantity, object_name])
356
357
358
359
360
361 return (idx_byte, [self.inventory])
362
364 """
365 Client message sent to server when player grab an object.
366
367 Message is sent when player grab an object.
368 'B' + 'bB%ds' : [quantity lenName ObjectName]
369 """
370
371 - def __init__ (self, quantity = 0, objname = '' ):
375
376 - def Encode (self, quantity = 0, objname =''):
377 """
378 @param quantity: The number of collected elements
379 @type quantity: Int
380 @param objname: The name of the object
381 @type objname: String
382 @return: the encoded data
383 @rtype: Byte Array. 'B' + 'bB%ds'
384 """
385 if objname !='':
386 self.quantity = quantity
387 self.objname = objname
388 self.data = struct.pack ('bB%ds'%(len(self.objname)),
389 self.quantity,
390 len(self.objname),
391 self.objname)
392 return (self.header + self.data)
393
395 """
396 @param data: The encoded data
397 @type data: Byte Array: 'B' + 'bB%ds'
398 @return: nb_processed_bytes, [quantity, objname]
399 @rtype: Int, [Int, String]
400 """
401
402 idx_byte = 0
403
404 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
405 idx_byte = idx_byte + struct.calcsize('B')
406
407 [self.quantity] = struct.unpack ('b',data[idx_byte:idx_byte+struct.calcsize('b')])
408 idx_byte = idx_byte + struct.calcsize('b')
409
410 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
411 idx_byte = idx_byte + struct.calcsize('B')
412
413 self.objname = str(data[idx_byte:idx_byte+namelen])
414 idx_byte = idx_byte+namelen
415
416 return (idx_byte, [self.quantity, self.objname])
417
419 chaine = ''
420 return chaine
421
422
424 """
425 Client message sent to server to declare player variables.
426
427 Message is sent when player first connect to the server.
428 'B' + 'bB%ds' : [quantity lenName VariableName]
429 """
430
431 - def __init__ (self, quantity = 0, varname = '' ):
435
436 - def Encode (self, quantity = 0, varname =''):
437 """
438 @param quantity: The initial value of variables
439 @type quantity: Int
440 @param varname: The name of the variable
441 @type varname: String
442 @return: the encoded data
443 @rtype: Byte Array. 'B' + 'bB%ds'
444 """
445 if varname !='':
446 self.quantity = quantity
447 self.varname = varname
448 self.data = struct.pack ('bB%ds'%(len(self.varname)),
449 self.quantity,
450 len(self.varname),
451 self.varname)
452 return (self.header + self.data)
453
455 """
456 @param data: The encoded data
457 @type data: Byte Array: 'B' + 'bB%ds'
458 @return: nb_processed_bytes, [quantity, varname]
459 @rtype: Int, [Int, String]
460 """
461
462 idx_byte = 0
463
464 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
465 idx_byte = idx_byte + struct.calcsize('B')
466
467 [self.quantity] = struct.unpack ('b',data[idx_byte:idx_byte+struct.calcsize('b')])
468 idx_byte = idx_byte + struct.calcsize('b')
469
470 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
471 idx_byte = idx_byte + struct.calcsize('B')
472
473 self.varname = str(data[idx_byte:idx_byte+namelen])
474 idx_byte = idx_byte+namelen
475
476 return (idx_byte, [self.quantity, self.varname])
477
479 chaine = ''
480 return chaine
482 """
483 Client message sent to server when player choose an avatar.
484
485 Message is sent when player choose an avatar.
486 'B' + 'B' : [avatar_number]
487 """
488
492
493 - def Encode (self, id_avatar = 0):
494 """
495 @param id_avatar: The number of the chosen avatar
496 @type id_avatar: Int
497 @return: the encoded data
498 @rtype: Byte Array. 'B' + 'B'
499 """
500 if id_avatar != 0:
501 self.id_avatar = id_avatar
502 self.data = struct.pack ('B',self.id_avatar)
503 return (self.header + self.data)
504
506 """
507 @param data: The encoded data
508 @type data: Byte Array: 'B' + 'B'
509 @return: nb_processed_bytes, [avatar_id]
510 @rtype: Int, [Int]
511 """
512 idx_byte = 0
513
514 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
515 idx_byte = idx_byte + struct.calcsize('B')
516
517 [self.id_avatar] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
518 idx_byte = idx_byte + struct.calcsize('B')
519
520 return (idx_byte, [self.id_avatar])
521
523 chaine = ''
524 return chaine
525
527 """
528 Server message sent to client when an object has to be removed from scene.
529
530 Message is sent when player grab an object.
531 'B' + 'B%ds' : [lenName ObjectName]
532 """
533
537
538 - def Encode (self, objname =''):
539 """
540 @param objname:
541 @type objname:
542 @return: the encoded data
543 @rtype: Byte Array. 'B' + 'B%ds'
544 """
545 if objname != '':
546 self.objname = objname
547 self.data = struct.pack ('B%ds'%(len(self.objname)),
548 len(self.objname),
549 self.objname)
550 return (self.header + self.data)
551
553 """
554 @param data: The encoded data
555 @type data: Byte Array: 'B' + 'B%ds'
556 @return: nb_processed_bytes, [objname]
557 @rtype: Int, [objname]
558 """
559
560 idx_byte = 0
561
562 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
563 idx_byte = idx_byte + struct.calcsize('B')
564
565 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
566 idx_byte = idx_byte + struct.calcsize('B')
567
568 self.objname = str(data[idx_byte:idx_byte+namelen])
569 idx_byte = idx_byte + namelen
570
571 return (idx_byte, [self.objname])
572
574 chaine = ''
575 return chaine
576
577
578
580 """
581 Client message sent to server when player release an object.
582
583 Message is typically sent when player realease an object from his inventory.
584 'B' + 'fffB%ds' : [lenName ObjectName]
585 """
586
587 - def __init__ (self, objname = '', position= [0.0, 0.0, 0.0]):
591
592 - def Encode (self, objname ='', position= [0.0, 0.0, 0.0]):
593 """
594 @param objname:
595 @type objname:
596 @param position:
597 @type position:
598 @return: the encoded data
599 @rtype: Byte Array. 'B' + 'fffB%ds'
600 """
601 if objname != '':
602 self.objname = objname
603 self.position = position
604 self.data = struct.pack ('fffB%ds'%(len(self.objname)),
605 self.position[0], self.position[1], self.position[2],
606 len(self.objname),
607 self.objname
608 )
609 return (self.header + self.data)
610
612 """
613 @param data: The encoded data
614 @type data: Byte Array: 'B' + 'fffB%ds'
615 @return: nb_processed_bytes, []
616 @rtype: Int, []
617 """
618
619 idx_byte = 0
620
621 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
622 idx_byte = idx_byte + struct.calcsize('B')
623 self.position = [0.0, 0.0, 0.0]
624 [self.position[0], self.position[1], self.position[2]] = struct.unpack ('fff',data[idx_byte:idx_byte+struct.calcsize('fff')])
625 idx_byte = idx_byte + struct.calcsize('fff')
626
627 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
628 idx_byte = idx_byte + struct.calcsize('B')
629
630 self.objname = str(data[idx_byte:idx_byte+namelen])
631 idx_byte = idx_byte + namelen
632
633 return (idx_byte, [self.objname, self.position])
634
636 chaine = ''
637 return chaine
638
639
640
641
643 """
644 Server message sent to client when an object has to be added to scene.
645
646 Message is typically sent when player realease an object from his inventory.
647 'B' + 'B%ds' : [lenName ObjectName]
648 """
649
650 - def __init__ (self, objname = '', position= [0.0, 0.0, 0.0]):
654
655 - def Encode (self, objname ='', position= [0.0, 0.0, 0.0]):
656 """
657 @param objname:
658 @type objname:
659 @param position:
660 @type position:
661 @return: the encoded data
662 @rtype: Byte Array. 'B' + 'fffB%ds'
663 """
664 if (objname != ''):
665 self.objname = objname
666 self.position = position
667 self.data = struct.pack ('fffB%ds'%(len(self.objname)),
668 self.position[0], self.position[1], self.position[2],
669 len(self.objname),
670 self.objname
671 )
672 return (self.header + self.data)
673
675 """
676 @param data: The encoded data
677 @type data: Byte Array: 'B' + 'fffB%ds'
678 @return: nb_processed_bytes, []
679 @rtype: Int, []
680 """
681
682 idx_byte = 0
683
684 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
685 idx_byte = idx_byte + struct.calcsize('B')
686 self.position = [0.0, 0.0, 0.0]
687 [self.position[0], self.position[1], self.position[2]] = struct.unpack ('fff',data[idx_byte:idx_byte+struct.calcsize('fff')])
688 idx_byte = idx_byte + struct.calcsize('fff')
689
690 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
691 idx_byte = idx_byte + struct.calcsize('B')
692
693 self.objname = str(data[idx_byte:idx_byte+namelen])
694 idx_byte = idx_byte + namelen
695
696 return (idx_byte, [self.objname, self.position])
697
699 chaine = ''
700 return chaine
701
702
704 """
705 Message to activate an object of the scene.
706
707 Message is typically sent when player activate an object.
708 Server forward this message.
709 'B' + 'BB%ds' : [value lenName ObjectName]
710 """
711
712 - def __init__ (self, objname = '', value = 0):
716
717 - def Encode (self, objname ='', value = 0):
718 """
719 @param objname:
720 @type objname:
721 @return: the encoded data
722 @rtype: Byte Array. 'B' + ''
723 """
724 if objname != '':
725 self.objname = objname
726 self.value = value
727 self.data = struct.pack ('BB%ds'%(len(self.objname)),
728 self.value,
729 len(self.objname),
730 self.objname
731 )
732 return (self.header + self.data)
733
735 """
736 @param data: The encoded data
737 @type data: Byte Array: 'B' + ''
738 @return: nb_processed_bytes, []
739 @rtype: Int, []
740 """
741
742 idx_byte = 0
743
744 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
745 idx_byte = idx_byte + struct.calcsize('B')
746
747 [self.value] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
748 idx_byte = idx_byte + struct.calcsize('B')
749
750 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
751 idx_byte = idx_byte + struct.calcsize('B')
752
753 self.objname = str(data[idx_byte:idx_byte+namelen])
754 idx_byte = idx_byte + namelen
755
756 return (idx_byte, [ self.objname, self.value])
757
759 chaine = ''
760 return chaine
761
762
763
764
766 """
767 Server message sent to client when an object has to be added into inventory.
768
769 Message is typically sent when player grab an object.
770 'B' + 'bB%ds' : [Quantity lenName ObjectName]
771 """
772
773 - def __init__ (self, quantity=0, objname = ''):
777
778 - def Encode (self, quantity=0, objname =''):
779 """
780 @param quantity:
781 @type quantity: Int
782 @param objname:
783 @type objname: String
784 @return: the encoded data
785 @rtype: Byte Array. 'B' + 'bB%ds'
786 """
787 if objname != '':
788 self.quantity = quantity
789 self.objname = objname
790 self.data = struct.pack ('bB%ds'%(len(self.objname)),
791 self.quantity,
792 len(self.objname),
793 self.objname)
794 return (self.header + self.data)
795
797 """
798 @param data: The encoded data
799 @type data: Byte Array: 'B' + 'bB%ds'
800 @return: nb_processed_bytes, [quantity, objname]
801 @rtype: Int, [quantity, objname]
802 """
803 idx_byte = 0
804
805 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
806 idx_byte = idx_byte + struct.calcsize('B')
807
808 [self.quantity] = struct.unpack ('b',data[idx_byte:idx_byte+struct.calcsize('b')])
809 idx_byte = idx_byte + struct.calcsize('b')
810
811 [namelen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
812 idx_byte = idx_byte + struct.calcsize('B')
813
814 self.objname = str(data[idx_byte:idx_byte+namelen])
815 idx_byte = idx_byte + namelen
816
817 return (idx_byte, [self.quantity, self.objname])
818
820 chaine = ''
821 return chaine
822
823
825 """
826 Client cyclic position report to server.
827
828 Message is sent periodically (at each TIC).
829 'ffffffb'
830 """
831 - def __init__ (self, position = [0.0, 0.0, 0.0], orientation = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]], heading = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]], state = 0,action = 0, scene = 0 ):
832
833 self.PosX = position[0]
834 self.PosY = position[1]
835 self.PosZ = position[2]
836 self.Action = action
837 self.State = state
838 self.Scene = scene
839
840 self.Orientation = orientation
841 self.Heading = heading
842
843 ClientMessage.__init__(self, POSITION_REPORT_MESSAGE, HIGH_PRIORITY)
844
845 - def Encode (self, position = [0.0, 0.0, 0.0],
846 orientation = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
847 heading = [[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]],
848 state = 0,
849 action = 0,
850 scene = 0 ):
851 """
852 @param position: Vector [posX, posY, posZ]
853 @type position: = 3*1 Vector
854 @param orientation: [[r11, r12, r13],[r21, r22, r23],[r31, r32, r33]]
855 @type orientation: 3*3 Matrix
856 @param heading: [[h11, h12, h13],[h21, h22, h23],[h31, h32, h33]]
857 @type heading: 3*3 Matrix
858 @param state: the last state the player was in
859 @type state: Integer
860 @param action: the Action played by the player
861 @type action: Integer
862 @param scene: the scene in which the client was seen the last time he disconnected.
863 @type scene: Integer
864 @return: the encoded data
865 @rtype: Byte Array. 'B' + 'fffffffffBBB'
866 """
867 if position[0]!=0 or position[1]!=0 or position[2]!=0 or scene != 0:
868 self.PosX = position[0]
869 self.PosY = position[1]
870 self.PosZ = position[2]
871 self.Action = action
872 self.State = state
873 self.Scene = scene
874
875 self.Orientation = orientation
876 self.Heading = heading
877
878 eul = bzTools.mat2eul(self.Orientation)
879 heul = bzTools.mat2eul(self.Heading)
880 self.data = struct.pack ('fffffffffBBB',
881 self.PosX, self.PosY, self.PosZ,
882 eul[0],
883 eul[1],
884 eul[2],
885 heul[0],
886 heul[1],
887 heul[2],
888 self.State,
889 self.Action,
890 self.Scene
891 )
892 return (self.header + self.data)
893
895 """
896 @param data: the data to decode.
897 @type data: Byte Array. 'B' + 'fffffffffBBB'
898 @return: Position, Orientation, Heading, State, Action, Scene
899 @rtype: 3*1 Vector, 3*3 Matrix, 3*3 Matrix, Integer, Integer, Integer
900 """
901 eul = [0.0, 0.0, 0.0]
902 heul = [0.0, 0.0, 0.0]
903 self.PosX, self.PosY, self.PosZ = 0.0, 0.0, -20.0
904
905 self.PosX, self.PosY, self.PosZ, eul[0], eul[1], eul[2], heul[0], heul[1], heul[2] , self.State, self.Action , self.Scene = struct.unpack ('fffffffffBBB',data[1:1+struct.calcsize('fffffffffBBB')])
906
907 beul = [eul[0], eul[1], eul[2]]
908 head_eul = [heul[0], heul[1], heul[2]]
909 ori_mat = bzTools.eul2mat(beul)
910 head_mat = bzTools.eul2mat(head_eul)
911 self.Orientation = [[ori_mat [0][0], ori_mat [0][1], ori_mat [0][2]],
912 [ori_mat [1][0], ori_mat [1][1], ori_mat [1][2]],
913 [ori_mat [2][0], ori_mat [2][1], ori_mat [2][2]]]
914 self.Heading = [[head_mat [0][0], head_mat [0][1], head_mat [0][2]],
915 [head_mat [1][0], head_mat [1][1], head_mat [1][2]],
916 [head_mat [2][0], head_mat [2][1], head_mat [2][2]]]
917
918 return (1+struct.calcsize ('fffffffffBBB'), [[self.PosX, self.PosY, self.PosZ], self.Orientation, self.Heading, self.State, self.Action, self.Scene])
919
921 chaine = 'size = %d, data = [%s]'%(len(self.data), self.data)
922 return chaine
923
925 """
926 Client message sent to all other connected clients (into the same scene ???).
927
928 Message is sent when player .
929 'B%ds' : [lenMessage Message]
930 """
931
935
936 - def Encode (self, message =''):
937 """
938 @param message:
939 @type message: String
940 @return: the encoded data
941 @rtype: Byte Array. 'B' + 'B%ds'
942 """
943 if message != '':
944 self.message = message
945 self.data = struct.pack ('B%ds'%(len(self.message)),
946 len(self.message),
947 self.message)
948 return (self.header + self.data)
949
951 """
952 @param data: The encoded data
953 @type data: Byte Array: 'B' + 'B%ds'
954 @return: nb_processed_bytes, [message]
955 @rtype: Int, [String]
956 """
957 bzTools.dump_data(data)
958 [msglen] = struct.unpack ('B',data[1:1+struct.calcsize('B')])
959 self.message = str(data[2:2+msglen])
960 return (2+msglen, [self.message])
961
963 chaine = ''
964 return chaine
965
967 """
968 Client message sent to an other client.
969
970 Message is sent periodically (at each TIC).
971 'B%dsB%ds' : [pseudo, message]
972 """
973
974 - def __init__ (self,to ='', message = ''):
978
979 - def Encode (self, to ='', message = ''):
980 """
981 @param to:
982 @type to: String
983 @param message:
984 @type message: String
985 @return: the encoded data
986 @rtype: Byte Array. 'B' + 'B%dsB%ds'
987 """
988 if (message != '') and (to != ''):
989 self.message = message
990 self.pseudo = to
991 self.data = struct.pack ('B%dsB%ds'%(len(self.pseudo),len(self.message) ),
992 len(self.pseudo),
993 self.pseudo,
994 len(self.message),
995 self.message)
996 return (self.header + self.data)
997
999 """
1000 @param data: The encoded data
1001 @type data: Byte Array: 'B' + 'B%dsB%ds'
1002 @return: nb_processed_bytes, [pseudo, message]
1003 @rtype: Int, [String String]
1004 """
1005
1006 idx_byte = 0
1007
1008 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
1009 idx_byte = idx_byte + struct.calcsize('B')
1010
1011 [pseudolen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
1012 idx_byte = idx_byte + struct.calcsize('B')
1013
1014 self.pseudo = str(data[idx_byte:idx_byte+struct.calcsize('%ds'%pseudolen)])
1015 idx_byte = idx_byte + struct.calcsize('%ds'%pseudolen)
1016
1017 [msglen] = struct.unpack ('B',data[idx_byte:idx_byte+struct.calcsize('B')])
1018 idx_byte = idx_byte + struct.calcsize('B')
1019
1020 self.message = str(data[idx_byte:idx_byte+struct.calcsize('%ds'%msglen)])
1021 idx_byte = idx_byte + struct.calcsize('%ds'%msglen)
1022
1023
1024 return (idx_byte, [self.pseudo, self.message])
1025
1027 chaine = ''
1028 return chaine
1029
1030
1031
1033 """
1034 Message that server periodically sends to all clients ???.
1035 It contains 'BfffffffffBBBBB%ds'*NbClients
1036
1037 Message is sent periodically (at each TIC).
1038 'BfffffffffBBBBB%ds'*NbClients
1039 """
1040
1041 - def __init__ (self, ids = [], pseudos = [],
1042 positions = [], orientations = [], headings = [], states = [], actions = [], scenes = [], avatars=[]):
1043
1044 self.NbData = 0
1045 self.PseudoLg = []
1046 self.Id = []
1047 self.Pseudo = []
1048 self.PosX = []
1049 self.PosY = []
1050 self.PosZ = []
1051 self.RotX = []
1052 self.RotY = []
1053 self.RotZ = []
1054 self.HRotX = []
1055 self.HRotY = []
1056 self.HRotZ = []
1057 self.State = []
1058 self.Action = []
1059 self.Scene = []
1060 self.Avatar = []
1061
1062 self.NbData = len(pseudos)
1063 idx_clt = 0
1064 for ps in pseudos:
1065 self.PseudoLg.append(len (ps))
1066 self.Pseudo.append(ps)
1067 self.Id.append(ids[idx_clt])
1068 self.PosX.append(positions[idx_clt][0])
1069 self.PosY.append(positions[idx_clt][1])
1070 self.PosZ.append(positions[idx_clt][2])
1071
1072 mat = orientations[idx_clt]
1073 eul = bzTools.mat2eul(mat)
1074
1075 self.RotX.append(eul[0])
1076 self.RotY.append(eul[1])
1077 self.RotZ.append(eul[2])
1078
1079 mat = headings[idx_clt]
1080 eul = bzTools.mat2eul(mat)
1081
1082 self.HRotX.append(eul[0])
1083 self.HRotY.append(eul[1])
1084 self.HRotZ.append(eul[2])
1085
1086
1087 self.State.append(states[idx_clt])
1088 self.Action.append(actions[idx_clt])
1089 self.Scene.append(scenes[idx_clt])
1090 self.Avatar.append(avatars[idx_clt])
1091
1092 idx_clt = idx_clt + 1
1093
1094
1095 ServerMessage.__init__(self, SITUATION_REPORT_MESSAGE, HIGH_PRIORITY)
1096
1097 - def Encode (self, ids = [], pseudos = [],
1098 positions = [], orientations = [], states = [], actions = [], scenes=[], avatars=[]):
1099 """
1100 @param ids: players ids
1101 @type ids: list of Integer
1102 @param pseudos: players pseudo
1103 @type pseudos: list of String
1104 @param positions: Vector [posX, posY, posZ]
1105 @type positions: list of 3*1 Vector
1106 @param orientations: [[r11, r12, r13],[r21, r22, r23],[r31, r32, r33]], action = 0
1107 @type orientations: list of 3*1 Euler angle vector (in degrees)
1108 @param states: States of players
1109 @type states: list of Integer
1110 @param actions: the Action played by players
1111 @type actions: list of Integer
1112 @param scenes: the scenes players are in
1113 @type scenes: list of Integer
1114 @param avatars: the Avatar used by players
1115 @type avatars: list of Integer
1116 @return: the encoded data
1117 @rtype: Byte Array. 'BfffffffffBBBBB%ds' * NbClients
1118 """
1119 if len (pseudos) != 0:
1120 self.NbData = 0
1121 self.PseudoLg = []
1122 self.Id = []
1123 self.Pseudo = []
1124 self.PosX = []
1125 self.PosY = []
1126 self.PosZ = []
1127 self.RotX = []
1128 self.RotY = []
1129 self.RotZ = []
1130 self.HRotX = []
1131 self.HRotY = []
1132 self.HRotZ = []
1133 self.State = []
1134 self.Action = []
1135 self.Scene = []
1136 self.Avatar = []
1137
1138 self.NbData = len(pseudos)
1139 idx_clt = 0
1140 for ps in pseudos:
1141 self.PseudoLg.append(len (ps))
1142 self.Pseudo.append(ps)
1143 self.Id.append(ids[idx_clt])
1144 self.PosX.append(positions[idx_clt][0])
1145 self.PosY.append(positions[idx_clt][1])
1146 self.PosZ.append(positions[idx_clt][2])
1147 self.Id.append(ids[idx_clt])
1148 self.State.append(states[idx_clt])
1149 self.Scene.append(scenes[idx_clt])
1150
1151 mat = orientations[idx_clt]
1152 eul = bzTools.mat2eul(mat)
1153
1154 self.RotX.append(eul[0])
1155 self.RotY.append(eul[1])
1156 self.RotZ.append(eul[2])
1157
1158
1159 mat = headings[idx_clt]
1160 eul = bzTools.mat2eul(mat)
1161
1162 self.HRotX.append(eul[0])
1163 self.HRotY.append(eul[1])
1164 self.HRotZ.append(eul[2])
1165
1166 self.State.append(states[idx_clt])
1167 self.Action.append(actions[idx_clt])
1168 self.Scene.append(scenes[idx_clt])
1169 self.Avatar.append(avatars[idx_clt])
1170
1171 idx_clt = idx_clt + 1
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190 self.data = ''
1191 for idx_clt in range (self.NbData):
1192 fmt = 'BfffffffffBBBBB%ds'%(self.PseudoLg[idx_clt])
1193 self.data = self.data + struct.pack (fmt , self.Id[idx_clt],
1194 self.PosX[idx_clt], self.PosY[idx_clt], self.PosZ[idx_clt],
1195 self.RotX[idx_clt],
1196 self.RotY[idx_clt],
1197 self.RotZ[idx_clt],
1198 self.HRotX[idx_clt],
1199 self.HRotY[idx_clt],
1200 self.HRotZ[idx_clt],
1201 self.State[idx_clt],
1202 self.Action[idx_clt],
1203 self.Scene[idx_clt],
1204 self.Avatar[idx_clt],
1205 self.PseudoLg[idx_clt],
1206 self.Pseudo[idx_clt])
1207 return (self.header + struct.pack ('B',self.NbData) + self.data)
1208
1210 """
1211 @param data: the data to decode.
1212 @type data: Byte Array. 'BB' + 'BfffffffffBBBBB%ds' * NbClients
1213 @return: nb_processed_byte, ids[], pseudos[], positions[], orientations[], headings[], states[], actions[], scenes[], avatars[]
1214 @rtype: tuple of (Integer, list of Integer, list of String, list of 3*1 Vector, list of 3*3 Matrix, list of 3*3 Matrix, list of Integer, list of Integer, list of Integer, list of Integer)
1215 """
1216
1217 self.ids=[]
1218 self.pseudos=[]
1219 self.positions=[]
1220 self.orientations=[]
1221 self.headings=[]
1222 self.states=[]
1223 self.actions=[]
1224 self.scenes=[]
1225 self.avatars=[]
1226
1227 idx_byte = 0
1228
1229 [typ, nb_data] = struct.unpack ('BB', data [idx_byte:idx_byte+struct.calcsize('BB')])
1230 idx_byte = idx_byte + struct.calcsize('BB')
1231 idx_data = 0
1232
1233
1234 while (idx_data< nb_data):
1235
1236
1237 [theid, px, py, pz, rx, ry, rz, hrx, hry, hrz, sta, act, sce, ava] = struct.unpack ('BfffffffffBBBB', data [idx_byte:idx_byte+struct.calcsize('BfffffffffBBBB')])
1238 idx_byte = idx_byte + struct.calcsize('BfffffffffBBBB')
1239
1240 [lg_ps]=struct.unpack ('B',data[idx_byte])
1241 idx_byte = idx_byte + struct.calcsize('B')
1242
1243 pseudo = str(data[idx_byte:idx_byte+lg_ps])
1244 idx_byte = idx_byte + lg_ps
1245
1246 self.pseudos.append(pseudo)
1247 self.ids.append(theid)
1248 self.positions.append([px, py, pz])
1249 beul = [rx, ry, rz]
1250 mat = bzTools.eul2mat(beul)
1251 orientation = mat
1252
1253 self.orientations.append(orientation)
1254
1255 heul = [hrx, hry, hrz]
1256 mat = bzTools.eul2mat(heul)
1257 heading = mat
1258
1259 self.headings.append(heading)
1260
1261 self.states.append(sta)
1262 self.actions.append(act)
1263 self.scenes.append(sce)
1264 self.avatars.append(ava)
1265 idx_data = idx_data + 1
1266
1267 return (idx_byte, [self.ids, self.pseudos, self.positions, self.orientations, self.headings, self.states, self.actions, self.scenes, self.avatars])
1268
1270
1271 chaine = 'size = %d, data = |%s|'%(len(self.data), self.data)
1272 return chaine
1273
1274
1276 """
1277 Chat messages from other client.
1278
1279 Message is sent when a player says something.
1280 'BB%ds'
1281 """
1286
1287 - def Encode (self, messages = []):
1288 """
1289 @param messages: list of messages [idfrom(Integer), message(String)]
1290 @type messages: list of String
1291 @return: the encoded data
1292 @rtype: Byte Array. 'BB'+'B%ds' * NbClients
1293 """
1294
1295
1296 if len(messages) !=0:
1297 self.messages = messages
1298
1299 idx_msg = 0
1300 self.data = ''
1301
1302 fmt = 'BB%ds'%(len(self.messages[1]))
1303 self.data = self.data + struct.pack (fmt ,
1304 self.messages[0], len(self.messages[1]), self.messages[1])
1305 return (self.header + self.data)
1306
1308 """
1309 @param data: the data to decode.
1310 @type data: Byte Array. 'BB' + '%ds' * NbMessages
1311 @return: playerMessages[] list of [idfrom, message]
1312 @rtype: list of tuples (Integer,String)
1313 """
1314
1315
1316 self.messages=[]
1317 lenmsg=[]
1318
1319 idx_byte = 0
1320
1321 [typ] = struct.unpack ('B', data [idx_byte:idx_byte+struct.calcsize('B')])
1322 idx_byte = idx_byte + struct.calcsize('B')
1323
1324
1325
1326 [theid,lenmsg] = struct.unpack ('BB', data [idx_byte:idx_byte+struct.calcsize('BB')])
1327 idx_byte = idx_byte + struct.calcsize('BB')
1328
1329
1330 self.messages= [int(theid), str(data[idx_byte:idx_byte+lenmsg])]
1331 idx_byte = idx_byte + lenmsg
1332
1333
1334 return (idx_byte, self.messages)
1335
1337
1338 chaine = ''
1339 return chaine
1340
1341
1342
1343
1344
1345 if __name__ == "__main__":
1346
1347 print "debut bzMessage"
1348
1349 aPR = PositionReport ()
1350 aCSR = ClientsSituationReport ()
1351 aSM = SayMessage ()
1352 aCM = ClientsMessages ()
1353
1354 aIIM = InitInventory ()
1355 data = aIIM.Encode([[1, "Lamp"], [12, "HealthPotion"]])
1356 print bzTools.dump_data(data)
1357 nb_bytes, inventory = aIIM.Decode (data)
1358 print nb_bytes, inventory
1359
1360 aGOM = GrabObject ()
1361 data = aGOM.Encode(1, "HealthPotion")
1362 nb_bytes, quantity, objname = aGOM.Decode (data)
1363 print nb_bytes, quantity, objname
1364
1365 aVOM = VanishObject ()
1366 data = aVOM.Encode("HealthPotion")
1367 nb_bytes, objname = aVOM.Decode (data)
1368 print nb_bytes, objname
1369
1370 aIAM = InventoryAdd ()
1371 data = aIAM.Encode(1, "HealthPotion")
1372 nb_bytes, quantity, objname = aIAM.Decode (data)
1373 print nb_bytes, quantity, objname
1374
1375 aIOM = InstanciateObject ()
1376 data = aIOM.Encode("HealthPotion", [10.0, 1.0, 0.0])
1377 nb_bytes, objname, position = aIOM.Decode (data)
1378 print nb_bytes, objname, position
1379
1380 aAOM = ActivateObject ()
1381 data = aAOM.Encode("Escalator", 2)
1382 nb_bytes, objname , value = aAOM.Decode (data)
1383 print nb_bytes, objname, value
1384
1385
1386 del aPR,
1387 del aCSR
1388 del aSM
1389 del aCM
1390 del aIIM
1391 del aVOM
1392 del aIAM
1393 del aIOM
1394
1395
1396 print "end"
1397