Guest User

Untitled

a guest
May 22nd, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. from __future__ import print_function
  4.  
  5. import sys
  6. import os
  7. import re
  8. import io
  9. import base64
  10. import zlib
  11.  
  12. import yaml as y
  13.  
  14. from minecraft import SUPPORTED_PROTOCOL_VERSIONS
  15. from minecraft.networking import types, packets, connection
  16. from minecraft.networking.packets import clientbound, serverbound
  17.  
  18.  
  19. CLIENT, SERVER = 0, 1
  20. HANDSHAKE, STATUS, LOGIN, PLAY = 0, 1, 2, 3
  21. PEER_RE = re.compile(r'peer(\d+)_(\d+)$')
  22.  
  23. def parse_file(file):
  24. events = y.parse(file, y.SafeLoader)
  25. for etype in y.StreamStartEvent, y.DocumentStartEvent, y.MappingStartEvent:
  26. event = next(events)
  27. assert isinstance(event, etype), 'not isinstance(%r, %r)' % (event, etype)
  28.  
  29. streams = {CLIENT: io.BytesIO(), SERVER: io.BytesIO()}
  30. counts = {CLIENT: 0, SERVER: 0}
  31.  
  32. context = connection.ConnectionContext(
  33. protocol_version=max(SUPPORTED_PROTOCOL_VERSIONS))
  34. compression = False
  35. state = HANDSHAKE
  36. packet_map = get_packets(context)
  37.  
  38. for event1 in events:
  39. assert isinstance(event1, y.ScalarEvent), \
  40. 'not isinstance(%r, y.ScalarEvent)' % event1
  41. peer, index = map(int, PEER_RE.match(event1.value).groups())
  42. assert counts[peer] == index, \
  43. 'counts[%r] == %r != %r' % (peer, counts[peer], index)
  44. counts[peer] += 1
  45.  
  46. event2 = next(events)
  47. assert isinstance(event2, y.ScalarEvent), \
  48. 'not isinstance(%r, y.ScalarEvent)' % event2
  49. assert event2.tag == 'tag:yaml.org,2002:binary'
  50.  
  51. streams[peer].seek(len(streams[peer].getbuffer()))
  52. streams[peer].write(base64.b64decode(event2.value))
  53. streams[peer].seek(0)
  54.  
  55. try:
  56. while True:
  57. for packet in read_packet(
  58. stream = streams[peer],
  59. compression = compression,
  60. packet_map = packet_map[peer][state],
  61. context = context
  62. ):
  63. if packet is None: break
  64. streams[peer] = io.BytesIO(streams[peer].read())
  65.  
  66. if isinstance(packet, serverbound.handshake.HandShakePacket):
  67. assert state == HANDSHAKE
  68. context.protocol_version = packet.protocol_version
  69. packet_map = get_packets(context)
  70. state = packet.next_state
  71. elif isinstance(packet, clientbound.login.LoginSuccessPacket):
  72. assert state == LOGIN
  73. state = PLAY
  74. elif packet.packet_name == 'set compression':
  75. assert state in (LOGIN, PLAY)
  76. compression = packet.threshold > 0
  77.  
  78. print('%s %s' % ('<--' if peer == CLIENT else '-->', packet))
  79.  
  80. if packet is None: break
  81. except:
  82. print('<--' if peer == CLIENT else '-->', end=' ***Exception:\n')
  83. raise
  84.  
  85. unused = { p: s.read() for (p, s) in stream }
  86. if any(len(s) > 0 for s in unused.values()):
  87. print('Unused data at end of stream: %r' % unused)
  88.  
  89. def read_packet(stream, compression, packet_map, context):
  90. try:
  91. for buffer in read_packet_buffer(stream, compression):
  92. if buffer is not None: break
  93. yield None
  94. except zlib.error as e:
  95. print('*** Exception: %s' % e)
  96. packet = packets.Packet(context)
  97. else:
  98. packet_id = next(read_varint(buffer))
  99. assert packet_id is not None
  100. if packet_id in packet_map:
  101. packet = packet_map[packet_id](context)
  102. packet.read(buffer)
  103. else:
  104. packet = packets.Packet(context, id=packet_id)
  105. yield packet
  106.  
  107. def read_packet_buffer(stream, compression):
  108. for length in read_varint(stream):
  109. if length is not None: break
  110. yield None
  111. buffer = packets.PacketBuffer()
  112. while True:
  113. buffer.send(stream.read(length - len(buffer.get_writable())))
  114. if len(buffer.get_writable()) >= length: break
  115. yield None
  116. assert len(buffer.get_writable()) == length
  117. buffer.reset_cursor()
  118. if compression:
  119. data_length = next(read_varint(buffer))
  120. assert data_length is not None
  121. if data_length > 0:
  122. data = zlib.decompress(buffer.read())
  123. assert len(data) == data_length
  124. buffer.reset()
  125. buffer.send(data)
  126. buffer.reset_cursor()
  127. yield buffer
  128.  
  129. def read_varint(stream):
  130. value = 0
  131. for n in range(5):
  132. while True:
  133. byte = stream.read(1)
  134. if len(byte) > 0: break
  135. yield None
  136. value |= (byte[0] & 0x7F) << 7*n
  137. if byte[0] & 0x80 == 0: break
  138. else:
  139. raise Exception('VarInt overflow.')
  140. yield value
  141.  
  142. def get_packets(context):
  143. return {bk: {sk: {p.get_id(context): p for p in sm.get_packets(context)}
  144. for (sk,sm) in ((HANDSHAKE, bm.handshake),
  145. (LOGIN, bm.login),
  146. (STATUS, bm.status),
  147. (PLAY, bm.play))}
  148. for (bk,bm) in ((CLIENT,serverbound), (SERVER,clientbound))}
  149.  
  150. def main(*args):
  151. if not args:
  152. parse_file(sys.stdin)
  153. for arg in args:
  154. print('%s:' % arg)
  155. with open(arg) as file:
  156. parse_file(file)
  157.  
  158. if __name__ == '__main__':
  159. main(*sys.argv[1:])
Add Comment
Please, Sign In to add comment