packet.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. """The PacketBuffer class has been adapted from source originally released by gnufrk"""
  2. import struct
  3. packet_lengths = [
  4. 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  5. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  6. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  7. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  8. #0x0040
  9. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  10. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  11. 0, 50, 3, -1, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2,
  12. 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
  13. #0x0080
  14. 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0,
  15. 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6,
  16. 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
  17. 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3,
  18. #0x00C0
  19. 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27,
  20. 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1,
  21. 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2,
  22. 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10,
  23. #0x0100
  24. 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
  25. 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
  26. 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
  27. 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
  28. #0x0140
  29. 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
  30. 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
  31. -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182,
  32. 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
  33. #0x0180
  34. 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6,
  35. 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6,
  36. 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
  37. 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3,
  38. #0x01C0
  39. 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28,
  40. 8, 14, 10, 35, 6, 8, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6,
  41. 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1,
  42. -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 4,
  43. #0x0200
  44. 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 10, 0, 0, 0,
  45. 0, 0, 16, 0, 8, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  46. 0, 0, 0, 0, 0, -1, 10, -1, -1, -1, 0, 0, 0, 0, 0, 0,
  47. -1, 34, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  48. ]
  49. class PacketOut:
  50. def __init__(self, out):
  51. self.buff = ""
  52. self.write_int16(out)
  53. def __str__(self):
  54. return self.buff
  55. def write_string(self, string_val, length):
  56. self.buff += string_val.ljust(length, '\0')
  57. def write_int8(self, value):
  58. self.buff += struct.pack("<B", value)
  59. def write_int16(self, value):
  60. self.buff += struct.pack("<H", value)
  61. def write_int32(self, value):
  62. self.buff += struct.pack("<L", value)
  63. def write_coords(self, x, y, direction):
  64. tmp = x
  65. tmp <<= 6
  66. d_0 = 0
  67. d_1 = 1
  68. d_2 = 2
  69. d_0 = (tmp >> 8) % 256
  70. d_1 = (tmp) % 256
  71. tmp = y
  72. tmp <<= 4
  73. d_1 |= (tmp >> 8) % 256
  74. d_2 = tmp % 256
  75. d_2 |= direction
  76. self.buff += chr(d_0) + chr(d_1) + chr(d_2)
  77. class PacketIn:
  78. def __init__(self, set_data, pkt_type):
  79. self.data = set_data
  80. self.pkttype = pkt_type
  81. self.pos = 0
  82. def is_type(self, pkt_type):
  83. return self.pkttype == pkt_type
  84. def get_type(self):
  85. return self.pkttype
  86. def read_string(self, length):
  87. msg = self.data[self.pos:self.pos + length]
  88. self.pos = self.pos + length
  89. return msg[:msg.find('\0')]
  90. def read_raw_string(self, length):
  91. msg = self.data[self.pos:self.pos + length]
  92. self.pos = self.pos + length
  93. return msg
  94. def read_int8(self):
  95. int_value = struct.unpack("<B", self.data[self.pos:self.pos + 1])[0]
  96. self.pos = self.pos + 1
  97. return int_value
  98. def make_word(self, low, high):
  99. return (low | (high << 8))
  100. def read_coord_pair(self):
  101. cdata = self.data[self.pos:self.pos + 5]
  102. dst_x = (self.make_word(struct.unpack("<B", cdata[3])[0], struct.unpack("<B", cdata[2])[0] & 0x000f) >> 2)
  103. dst_y = self.make_word(struct.unpack("<B", cdata[4])[0], struct.unpack("<B", cdata[3])[0] & 0x0003)
  104. src_x = (self.make_word(struct.unpack("<B", cdata[1])[0], struct.unpack("<B", cdata[0])[0]) >> 6)
  105. src_y = (self.make_word(struct.unpack("<B", cdata[2])[0], struct.unpack("<B", cdata[1])[0] & 0x003f) >> 4)
  106. self.pos = self.pos + 5
  107. return src_x, src_y, dst_x, dst_y
  108. def read_coord_dir(self):
  109. cdata = self.data[self.pos:self.pos + 3]
  110. x = (self.make_word(struct.unpack("<B", cdata[1])[0] & 0x00c0, struct.unpack("<B", cdata[0])[0] & 0x00ff) >> 6) % 255
  111. y = (self.make_word(struct.unpack("<B", cdata[2])[0] & 0x00f0, struct.unpack("<B", cdata[1])[0] & 0x003f) >> 4) % 255
  112. dir = struct.unpack("<B", cdata[2])[0] & 0x000f
  113. self.pos = self.pos + 3
  114. return x, y, dir
  115. def read_int16(self):
  116. int_value = struct.unpack("<H", self.data[self.pos:self.pos + 2])[0]
  117. self.pos = self.pos + 2
  118. return int_value
  119. def read_int32(self):
  120. int_value = struct.unpack("<L", self.data[self.pos:self.pos + 4])[0]
  121. self.pos = self.pos + 4
  122. return int_value
  123. def skip(self, count):
  124. self.pos = self.pos + count
  125. class PacketBuffer:
  126. def __init__(self):
  127. self.buff = ""
  128. def feed(self, data):
  129. self.buff += data
  130. def drop(self, count):
  131. self.buff = self.buff[count:]
  132. def __iter__(self):
  133. return self
  134. def next(self):
  135. if len(self.buff) < 2:
  136. raise StopIteration
  137. pktlen = 0
  138. pkttype = struct.unpack("<H", self.buff[:2])[0]
  139. assert pkttype < len(packet_lengths)
  140. assert packet_lengths[pkttype] != 0
  141. if packet_lengths[pkttype] < 0:
  142. if len(self.buff) < 4:
  143. raise StopIteration
  144. pktlen = struct.unpack("<H", self.buff[2:4])[0]
  145. assert pktlen >= 4
  146. else:
  147. pktlen = packet_lengths[pkttype]
  148. if len(self.buff) < pktlen:
  149. raise StopIteration
  150. packet = PacketIn(self.buff[2:pktlen], pkttype)
  151. self.buff = self.buff[pktlen:]
  152. return packet