jk, just continue to build ontop (added better debug prints, colors, bitstream additions, continuation for bitstream parsing, and currently working on acks)
This commit is contained in:
185
test.py
185
test.py
@@ -1,85 +1,128 @@
|
||||
from sampy.raknet.bitstream import Bitstream
|
||||
from sampy.client.player import PlayerClient
|
||||
|
||||
bitstream = Bitstream(b"\x00" * 4)
|
||||
MAGIC_BYTES = b"\x01\xff\x02"
|
||||
MAGIC_BITS = [int(bit) for bit in " ".join([format(byte, "08b") for byte in MAGIC_BYTES]) if bit in ("0", "1")]
|
||||
fail = 0
|
||||
import struct
|
||||
|
||||
def print_pretty(prefix, msg):
|
||||
prefix += " " * (40 - len(prefix))
|
||||
print(prefix, msg)
|
||||
class Packet:
|
||||
def __init__(self, data: bytes, is_client: bool):
|
||||
self.data = data
|
||||
self.is_client = is_client
|
||||
self.bitstream = Bitstream(bytearray.fromhex(self.data))
|
||||
|
||||
def reset_bitstream():
|
||||
bitstream._buffer = bytearray(b"\x00" * len(bitstream._buffer))
|
||||
bitstream._offset = 0
|
||||
PACKETS = [
|
||||
Packet("18 69 69", True),
|
||||
Packet("1a 18 be", False),
|
||||
Packet("18 71 d7", True),
|
||||
Packet("19 00", False),
|
||||
Packet("00 00 43 80 0b", True),
|
||||
Packet("e3 00 00", False),
|
||||
Packet("00 00 42 98 0c 11 33 30 45 39 33 39 33 33 36 39 42 35 36 38 43 32 00", False)
|
||||
]
|
||||
|
||||
def test_write_bit(var_bits):
|
||||
global fail
|
||||
print_pretty("<Test bitstream.write_bit:in>", bitstream.pretty())
|
||||
for bit in var_bits:
|
||||
if not bitstream.write_bit(bit):
|
||||
print_pretty("<Test bitstream.write_bit>", "Failed")
|
||||
fail += 1
|
||||
print_pretty("<Test bitstream.write_bit:out>", bitstream.pretty())
|
||||
#client = PlayerClient(None, "127.0.0.1", 7777)
|
||||
#client.state = 1
|
||||
|
||||
def test_read_bit(var_compare_bits):
|
||||
global fail
|
||||
print_pretty("<Test bitstream.read_bit:in>", bitstream.pretty())
|
||||
for bit in var_compare_bits:
|
||||
ok, bit2 = bitstream.read_bit()
|
||||
if not ok:
|
||||
print_pretty("<Test bitstream.read_bit>", "Failed (ok)")
|
||||
fail += 1
|
||||
continue
|
||||
if bit2 != bit:
|
||||
print_pretty("<Test bitstream.read_bit>", "Failed (match)")
|
||||
fail += 1
|
||||
continue
|
||||
print_pretty("<Test bitstream.read_bit:out>", bitstream.pretty())
|
||||
def pbs(bitstream: Bitstream, prefix: str = ""):
|
||||
print(prefix, bitstream.pretty())
|
||||
|
||||
def test_write(var_bytes):
|
||||
global fail
|
||||
print_pretty("<Test bitstream.write:in>", bitstream.pretty())
|
||||
if not bitstream.write(var_bytes, len(var_bytes) << 3):
|
||||
print_pretty("<Test bitstream.write>", "Failed")
|
||||
fail += 1
|
||||
print_pretty("<Test bitstream.write:out>", bitstream.pretty())
|
||||
def deserialize(bitstream: Bitstream): # TODO: Something weird with range thing DS_RangeList.h@L92
|
||||
success, count = bitstream.read_compressed(0x10, True)
|
||||
if not success:
|
||||
return False
|
||||
|
||||
count, = struct.unpack(b"<H", count)
|
||||
|
||||
def test_read(var_compare_bytes):
|
||||
global fail
|
||||
print_pretty("<Test bitstream.read:in>", bitstream.pretty())
|
||||
ok, bytez = bitstream.read(len(var_compare_bytes) << 3)
|
||||
if ok:
|
||||
print(var_compare_bytes, bytez)
|
||||
if bytez != var_compare_bytes:
|
||||
print_pretty("<Test bitstream.read>", "Failed (match)")
|
||||
fail += 1
|
||||
else:
|
||||
print_pretty("<Test bitstream.read>", "Failed (ok)")
|
||||
fail += 1
|
||||
print_pretty("<Test bitstream.read:out>", bitstream.pretty())
|
||||
min, max = 0, 0
|
||||
for i in range(count):
|
||||
_, max_equal_to_min = bitstream.read_bit()
|
||||
success, min = bitstream.read_bits(0x10)
|
||||
if not success:
|
||||
return False
|
||||
|
||||
min, = struct.unpack(b"<H", min)
|
||||
|
||||
def test_rw_bit(offset):
|
||||
bitstream._offset = offset
|
||||
test_write_bit(MAGIC_BITS)
|
||||
bitstream._offset = offset
|
||||
test_read_bit(MAGIC_BITS)
|
||||
if not max_equal_to_min:
|
||||
success, max = bitstream.read_bits(0x10)
|
||||
if not success:
|
||||
return False
|
||||
|
||||
max, = struct.unpack(b"<H", max)
|
||||
|
||||
def test_rw_bytes(offset):
|
||||
bitstream._offset = offset
|
||||
test_write(MAGIC_BYTES)
|
||||
bitstream._offset = offset
|
||||
test_read(MAGIC_BYTES)
|
||||
if max < min:
|
||||
return False
|
||||
else:
|
||||
max = min
|
||||
|
||||
# Test all edges
|
||||
for i in range(9):
|
||||
reset_bitstream()
|
||||
test_rw_bit(i)
|
||||
return True
|
||||
|
||||
reset_bitstream()
|
||||
def on_player_packet(packet: bytes):
|
||||
bitstream = Bitstream(packet)
|
||||
pbs(bitstream, "Created")
|
||||
|
||||
for i in range(9):
|
||||
reset_bitstream()
|
||||
test_rw_bytes(i)
|
||||
_, has_acks = bitstream.read_bit()
|
||||
pbs(bitstream, "has_acks")
|
||||
if has_acks:
|
||||
print("has_acks: True")
|
||||
if not deserialize(bitstream):
|
||||
return False
|
||||
return
|
||||
|
||||
handled = handle_internal_packet(bitstream)
|
||||
|
||||
if not handled:
|
||||
print("Internal packet were not handled")
|
||||
|
||||
def handle_internal_packet(bitstream: Bitstream) -> bool:
|
||||
if bitstream.length - bitstream.offset < 0x10:
|
||||
return False
|
||||
|
||||
print("Failed: %d" % fail)
|
||||
_, message_number = bitstream.read_bits(0x10)
|
||||
pbs(bitstream, "message_number")
|
||||
_, reliability = bitstream.read_bits(0x04)
|
||||
pbs(bitstream, "reliability")
|
||||
|
||||
if reliability in (7, 9, 10):
|
||||
success, ordering_channel = bitstream.read_bits(0x05)
|
||||
pbs(bitstream, "ordering_channel")
|
||||
if not success:
|
||||
return False
|
||||
success, ordering_index = bitstream.read_bits(0x10)
|
||||
pbs(bitstream, "ordering_index")
|
||||
if not success:
|
||||
return False
|
||||
|
||||
_, is_split_packet = bitstream.read_bit()
|
||||
pbs(bitstream, "is_split_packet")
|
||||
|
||||
if is_split_packet:
|
||||
print("Skipping split packet")
|
||||
return
|
||||
|
||||
# TODO: set global split_packet index and count back to 0
|
||||
|
||||
# Something I dont understand yet
|
||||
# TODO: ReadCompressed
|
||||
#bitstream.offset += 1
|
||||
success, data_bit_length = bitstream.read_compressed(0x10, True)
|
||||
pbs(bitstream, "data_bit_length")
|
||||
if not success:
|
||||
return False
|
||||
|
||||
#_, unknown = bitstream.read(0x01)
|
||||
#_, bit_length = bitstream.read(0x08)
|
||||
##
|
||||
|
||||
#logger.debug("bit_length: %d" % bit_length)
|
||||
#logger.debug("bitstream: %s" % bitstream)
|
||||
|
||||
data_bit_length, = struct.unpack(b"<H", data_bit_length)
|
||||
print("data_bit_length:", data_bit_length)
|
||||
|
||||
# TODO: ReadAlignedBytes
|
||||
#_, data = bitstream.read(bit_length)
|
||||
_, data = bitstream.read_aligned_bytes((data_bit_length + 7) >> 3)
|
||||
pbs(bitstream, "data")
|
||||
|
||||
print("data: %s" % data)
|
||||
|
||||
on_player_packet(PACKETS[-2].bitstream._buffer)
|
||||
Reference in New Issue
Block a user