From 4812d9c35d6919d668973bca548fe92c8dd53010 Mon Sep 17 00:00:00 2001 From: Sunpy Date: Tue, 4 May 2021 15:50:53 +0200 Subject: [PATCH] Commit before bitstream rewrite --- notes/notes.txt | 45 +++++++++++++++++++++++++++++ sampy/client/player.py | 22 ++++++++++---- sampy/raknet/bitstream.py | 60 ++++++++++++++++++++++++++++++++++----- 3 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 notes/notes.txt diff --git a/notes/notes.txt b/notes/notes.txt new file mode 100644 index 0000000..e231118 --- /dev/null +++ b/notes/notes.txt @@ -0,0 +1,45 @@ +SendImmediate( (char*)bitStream.GetData(), bitStream.GetNumberOfBitsUsed(), SYSTEM_PRIORITY, UNRELIABLE, 0, target, false, false, currentTimeNS ) + +char* data = bitStream.GetData() +int numberOfBitsToSend = bitStream.GetNumberOfBitsUsed() +PacketPriority priority = SYSTEM_PRIORITY +PacketReliability reliability = UNRELIABLE +char orderingChannel = 0 +PlayerID playerId = target +bool broadcast = false +bool useCallerDataAllocation = false +RakNetTimeNS currentTime = currentTimeNS + + + +Send( char *data, int numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, unsigned char orderingChannel, bool makeDataCopy, int MTUSize, RakNetTimeNS currentTime ) + +char* data = bitStream.GetData() +int numberOfBitsToSend = bitStream.GetNumberOfBitsUsed() +PacketPriority priority = SYSTEM_PRIORITY +PacketReliability reliability = UNRELIABLE +char orderingChannel = 0 +bool makeDataCopy = true +int MTUSize = 576 +RakNetTimeNS currentTime = currentTimeNS + + + +internalPacket->creationTime = currentTime +internalPacket->data = data // (cpy) +internalPacket->dataBitLength = numberOfBitsToSend +internalPacket->nextActionTime = 0 +internalPacket->messageNumber = messageNumber +internalPacket->priority = priority +internalPacket->reliability = reliability +internalPacket->splitPacketCount = 0 + + + +int headerLength = BITS_TO_BYTES( GetBitStreamHeaderLength(internalPacket) ) +int maxDataSize = 576 - 28 - headerLength // MTUSize - UDP_HEADER_SIZE - headerLength + +; More stuff to note from + +... +sendPacketSet[ internalPacket->priority ].Push( internalPacket ); diff --git a/sampy/client/player.py b/sampy/client/player.py index 696c3f4..1a9bc1a 100644 --- a/sampy/client/player.py +++ b/sampy/client/player.py @@ -75,8 +75,8 @@ class PlayerClient(BaseClient): async def on_player_packet(self, packet: bytes): bitstream = Bitstream(packet) - _, has_acks = bitstream.read(0x01) - if has_acks[0]: + _, has_acks = bitstream.read_bit() + if has_acks: logger.debug("Unfinished code hit; has_acks: True") return @@ -90,16 +90,26 @@ class PlayerClient(BaseClient): return False _, message_number = bitstream.read(0x10) - _, reliability = bitstream.read(0x04) - _, is_split_packet = bitstream.read(0x01) + _, reliability = bitstream.read_int(0x04) - if is_split_packet[0]: + if reliability in (7, 9, 10): + success, ordering_channel = bitstream.read_int(0x05) + if success == False: + return False + success, ordering_index = bitstream.read_int(0x10) + if success == False: + return False + + _, is_split_packet = bitstream.read_bit() + + if is_split_packet: logger.warning("Skipping split packet") return # Something I dont understand yet # TODO: ReadCompressed - bitstream.offset += 1 + #bitstream.offset += 1 + _, data = bitstream.read_compressed(0x10, True) _, unknown = bitstream.read(0x01) _, bit_length = bitstream.read(0x08) ## diff --git a/sampy/raknet/bitstream.py b/sampy/raknet/bitstream.py index f7e28f4..876675e 100644 --- a/sampy/raknet/bitstream.py +++ b/sampy/raknet/bitstream.py @@ -2,7 +2,7 @@ import ctypes as c from array import array -from typing import Tuple +from typing import Tuple, Union import logging logger = logging.getLogger(__name__) @@ -78,10 +78,10 @@ class Bitstream: self._buffer[byte_index] = byte return True - - def read(self, bit_length: int) -> Tuple[bool, bytes]: + + def read_int(self, bit_length: int) -> Tuple[bool, int]: if not self._can_access_bits(bit_length): - return False, b"" + return False, 0 byte_from = self._offset >> 3 byte_to = (self._offset + bit_length + 7) >> 3 @@ -105,10 +105,56 @@ class Bitstream: #if self._offset % 8 == 0: #value += - return True, value.to_bytes((bit_length + 7) >> 3, "big") # bytes(value) + return True, value + + def read(self, bit_length: int) -> Tuple[bool, bytes]: + success, value = self.read_int(bit_length) + return success, value.to_bytes((bit_length + 7) >> 3, "big") # bytes(value) - def read_compressed(self): - pass + def read_compressed(self, bit_length: int, unsigned: bool = True) -> Tuple[bool, bytes]: + current_byte = (bit_length >> 3) - 1 + + out = bytearray(current_byte + 1) + + byte_match = 0 if unsigned else 0xFF + half_byte_match = 0 if unsigned else 0xF0 + + while current_byte > 0: + success, bit = self.read_bit() + if success == False: # Cannot read the bit (end of stream) + return False, out + + if bit: + out[current_byte] = byte_match + current_byte -= 1 + else: + success, data = self.read((current_byte + 1) << 3) + out[:current_byte] = data + if success == False: + return False, out + return True, out + + if self.offset + 1 > self.length: + return False, out + + success, bit = self.read_bit() + if success == False: # Cannot read the bit (end of stream) + return False, out + + if bit: + success, data = self.read(4) + out[current_byte:current_byte + 4] = data + if success == False: + return False, out + + out[current_byte] |= half_byte_match # Maybe recheck this in BitStream.cpp@L617; We have to set the high 4 bits since these are set to 0 by ReadBits + else: + success, data = self.read(8) + out[current_byte:current_byte + 8] = data + if success == False: + return False, out + + return True, out def pretty(self) -> str: b = bytearray(" " + " ".join(" ".join(format(c, "08b")) for c in self._buffer) + " ", "ascii")