Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <cstdlib>
- const uint8_t GShift[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- const uint8_t GMask [8]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f};
- const uint32_t MAX_NAME_INDEX = 410;
- struct BitReader {
- private:
- uint8_t shift(uint8_t count) {
- return 1 << count;
- }
- public:
- BitReader(const uint8_t* src_buffer = nullptr, int64_t n_bits = 0) : num(n_bits), pos(0) {
- buffer = new uint8_t[(n_bits + 7) >> 3];
- if (src_buffer != nullptr) {
- memcpy(buffer, src_buffer, (n_bits + 7) >> 3);
- if (num & 7) {
- buffer[num >> 3] &= GMask[num & 7];
- }
- }
- }
- uint32_t read_int(uint32_t max_value) {
- uint32_t val = 0;
- serialize_int(val, max_value);
- return val;
- }
- // should return data here, but I haven't imlemented the hardcoded stuff, so shrug
- void read_fname() {
- bool bHardcoded;
- serialize_bits(&bHardcoded, 1);
- if (bHardcoded) {
- uint32_t name_index = read_int(MAX_NAME_INDEX + 1);
- } else {
- char* attach_socket;
- read_fstring(attach_socket);
- uint32_t num;
- serialize_bits(&num, 32);
- }
- }
- // "UnrealEngine/Engine/Source/Runtime/Core/Private/Containers/String.cpp"
- void read_fstring(char* & bytes) {
- int32_t save_num;
- serialize_bits(&save_num, 32);
- bool LoadUCS2Char = save_num < 0;
- if (LoadUCS2Char) {
- save_num = -save_num;
- }
- if (save_num) {
- if (LoadUCS2Char) {
- // uint16_t bytes2 = new uint16_t[save_num];
- // serialize(bytes2, save_num * 2);
- // bytes2[save_num * 2 - 1] = 0;
- // pretty sure there aren't any of these in the PUBG data.
- printf("LOADUSC2CHAR :( \n");
- exit(1);
- } else {
- bytes = new char[save_num];
- serialize(bytes, save_num);
- bytes[save_num-1] = 0;
- }
- } else {
- bytes = NULL;
- }
- }
- void serialize( void* dst, int64_t n_bytes ) {
- serialize_bits(dst, n_bytes*8);
- }
- uint8_t read_bit() {
- uint8_t bit = 0 ;
- int64_t local_pos = pos;
- const int64_t local_num = num;
- if (local_pos >= local_num) {
- // SetOverflowed(1);
- //UE_LOG( LogNetSerialization, Error, TEXT( "FBitReader::SerializeInt: LocalPos >= LocalNum" ) );
- } else {
- bit = !!(buffer[local_pos>>3] & shift(local_pos&7));
- pos++;
- }
- return bit;
- }
- uint64_t bits_left() {
- return (num - pos);
- }
- void serialize_vector(Vector & value, uint32_t scale, int32_t max_bits) {
- uint32_t bits = 0;
- serialize_int(bits, max_bits);
- int32_t bias = 1 << (bits + 1);
- uint32_t max = 1 << (bits + 2);
- uint32_t dx;
- uint32_t dy;
- uint32_t dz;
- serialize_int(dx, max);
- serialize_int(dy, max);
- serialize_int(dz, max);
- float factor = (float)scale;
- value.x = (float)(static_cast<int32_t>(dx)-bias) / factor;
- value.y = (float)(static_cast<int32_t>(dy)-bias) / factor;
- value.z = (float)(static_cast<int32_t>(dz)-bias) / factor;
- }
- void read_compressed_float(float &Value, uint32_t MaxValue, uint32_t NumBits) {
- uint32_t MaxBitValue = (1 << (NumBits - 1)) - 1; // 0111 1111 - Max abs value we will serialize
- uint32_t Bias = (1 << (NumBits - 1)) - 1; // 0111 1111 - Max abs value we will serialize
- uint32_t SerIntMax = (1 << (NumBits - 0)); // 1 0000 0000 - What we pass into SerializeInt
- uint32_t MaxDelta = (1 << (NumBits - 0)) - 1; // 1111 1111 - Max delta is
- uint32_t Delta;
- serialize_int(Delta, SerIntMax);
- float UnscaledValue = (float)(((uint32_t) Delta) - Bias );
- if ( MaxValue > MaxBitValue ) {
- // We have to scale down, scale needs to be a float:
- const float InvScale = MaxValue / (float)MaxBitValue;
- Value = UnscaledValue * InvScale;
- } else {
- uint32_t scale = MaxBitValue / MaxValue;
- const float InvScale = 1.f / (float) scale;
- Value = UnscaledValue * InvScale;
- }
- }
- void serialize_fixed_vector(Vector & value, uint32_t max_value, int32_t num_bits) {
- read_compressed_float(value.x, max_value, num_bits);
- read_compressed_float(value.y, max_value, num_bits);
- read_compressed_float(value.z, max_value, num_bits);
- }
- void serialize_vector_full(Vector & value) {
- float x;
- float y;
- float z;
- serialize_float(&x);
- serialize_float(&y);
- serialize_float(&z);
- value.x = x;
- value.y = y;
- value.z = z;
- }
- void serialize_compressed_short_vector(Vector & value) {
- uint16_t short_pitch;
- uint16_t short_yaw;
- uint16_t short_roll;
- if (read_bit()) {
- serialize_bits(&short_pitch, 16);
- } else {
- short_pitch = 0;
- }
- if (read_bit()) {
- serialize_bits(&short_yaw, 16);
- } else {
- short_yaw = 0;
- }
- if (read_bit()) {
- serialize_bits(&short_roll, 16);
- } else {
- short_roll = 0;
- }
- value.x = (short_pitch * 360.f / 65536.f);
- value.y = (short_yaw * 360.f / 65536.f);
- value.z = (short_roll * 360.f / 65536.f);
- }
- void serialize_compressed_byte_vector(Vector & value) {
- uint8_t short_pitch;
- uint8_t short_yaw;
- uint8_t short_roll;
- if (read_bit()) {
- serialize_bits(&short_pitch, 8);
- } else {
- short_pitch = 0;
- }
- if (read_bit()) {
- serialize_bits(&short_yaw, 8);
- } else {
- short_yaw = 0;
- }
- if (read_bit()) {
- serialize_bits(&short_roll, 8);
- } else {
- short_roll = 0;
- }
- value.x = (short_pitch * 360.f / 256.f);
- value.y = (short_yaw * 360.f / 256.f);
- value.z = (short_roll * 360.f / 256.f);
- }
- void serialize_int_packed(uint32_t& value) {
- value = 0;
- uint8_t count = 0;
- uint8_t more = 1;
- while(more) {
- uint8_t next_byte;
- serialize(&next_byte, 1); // Read next byte
- more = next_byte & 1; // Check 1 bit to see if theres more after this
- next_byte = next_byte >> 1; // Shift to get actual 7 bit value
- value += next_byte << (7 * count++); // Add to total value
- }
- }
- void serialize_float(float* value) {
- serialize(value, sizeof(float));
- }
- void appBitsCpy( uint8_t* Dest, int32_t DestBit, uint8_t* Src, int32_t SrcBit, int32_t BitCount) {
- if(BitCount == 0) return;
- // Special case - always at least one bit to copy,
- // a maximum of 2 bytes to read, 2 to write - only touch bytes that are actually used.
- if (BitCount <= 8) {
- uint32_t DestIndex = DestBit / 8;
- uint32_t SrcIndex = SrcBit / 8;
- uint32_t LastDest =( DestBit+BitCount-1 )/8;
- uint32_t LastSrc =( SrcBit +BitCount-1 )/8;
- uint32_t ShiftSrc = SrcBit & 7;
- uint32_t ShiftDest = DestBit & 7;
- uint32_t FirstMask = 0xFF << ShiftDest;
- uint32_t LastMask = 0xFE << ((DestBit + BitCount-1) & 7) ; // Pre-shifted left by 1.
- uint32_t Accu;
- if (SrcIndex == LastSrc) {
- Accu = (Src[SrcIndex] >> ShiftSrc);
- } else {
- Accu =( (Src[SrcIndex] >> ShiftSrc) | (Src[LastSrc] << (8 - ShiftSrc)));
- }
- if (DestIndex == LastDest) {
- uint32_t MultiMask = FirstMask & ~LastMask;
- Dest[DestIndex] = ( ( Dest[DestIndex] & ~MultiMask ) | ((Accu << ShiftDest) & MultiMask) );
- } else {
- Dest[DestIndex] = (uint8_t)( ( Dest[DestIndex] & ~FirstMask ) | (( Accu << ShiftDest) & FirstMask) ) ;
- Dest[LastDest ] = (uint8_t)( ( Dest[LastDest ] & LastMask ) | (( Accu >> (8 - ShiftDest)) & ~LastMask) ) ;
- }
- return;
- }
- // Main copier, uses byte sized shifting. Minimum size is 9 bits, so at least 2 reads and 2 writes.
- uint32_t DestIndex = DestBit/8;
- uint32_t FirstSrcMask = 0xFF << ( DestBit & 7);
- uint32_t LastDest = ( DestBit+BitCount )/8;
- uint32_t LastSrcMask = 0xFF << ((DestBit + BitCount) & 7);
- uint32_t SrcIndex = SrcBit/8;
- uint32_t LastSrc = ( SrcBit+BitCount )/8;
- int32_t ShiftCount = (DestBit & 7) - (SrcBit & 7);
- int32_t DestLoop = LastDest-DestIndex;
- int32_t SrcLoop = LastSrc -SrcIndex;
- uint32_t FullLoop;
- uint32_t BitAccu;
- // Lead-in needs to read 1 or 2 source bytes depending on alignment.
- if (ShiftCount>=0) {
- FullLoop = std::max(DestLoop, SrcLoop);
- BitAccu = Src[SrcIndex] << ShiftCount;
- ShiftCount += 8; //prepare for the inner loop.
- } else {
- ShiftCount +=8; // turn shifts -7..-1 into +1..+7
- FullLoop = std::max(DestLoop, SrcLoop-1);
- BitAccu = Src[SrcIndex] << ShiftCount;
- SrcIndex++;
- ShiftCount += 8; // Prepare for inner loop.
- BitAccu = ( ( (uint32_t)Src[SrcIndex] << ShiftCount ) + (BitAccu)) >> 8;
- }
- // Lead-in - first copy.
- Dest[DestIndex] = (uint8_t) (( BitAccu & FirstSrcMask) | ( Dest[DestIndex] & ~FirstSrcMask ) );
- SrcIndex++;
- DestIndex++;
- // Fast inner loop.
- for (; FullLoop>1; FullLoop--) { // ShiftCount ranges from 8 to 15 - all reads are relevant.
- BitAccu = (( (uint32_t)Src[SrcIndex] << ShiftCount ) + (BitAccu)) >> 8; // Copy in the new, discard the old.
- SrcIndex++;
- Dest[DestIndex] = (uint8_t) BitAccu; // Copy low 8 bits.
- DestIndex++;
- }
- // Lead-out.
- if (LastSrcMask != 0xFF) {
- if ((uint32_t)(SrcBit + BitCount - 1) / 8 == SrcIndex) {// Last legal byte ?
- BitAccu = ( ( (uint32_t)Src[SrcIndex] << ShiftCount ) + (BitAccu)) >> 8;
- } else {
- BitAccu = BitAccu >> 8;
- }
- Dest[DestIndex] = (uint8_t)( ( Dest[DestIndex] & LastSrcMask ) | (BitAccu & ~LastSrcMask) );
- }
- }
- void serialize_bits(void* dst, int64_t n_bits) {
- if (pos + n_bits > num) {
- printf("%lld + %lld = %lld > %lld OVERFLOWEDDDDD\n", pos, n_bits, pos + n_bits, num);
- exit(1);
- }
- // if (!IsError()) {
- // // SetOverflowed(LengthBits);
- // //UE_LOG( LogNetSerialization, Error, TEXT( "FBitReader::SerializeBits: Pos + LengthBits > Num" ) );
- // }
- // FMemory::Memzero( Dest, (LengthBits+7)>>3 );
- // return;
- // }
- //for( int32 i=0; i<LengthBits; i++,Pos++ )
- // if( Buffer(Pos>>3) & GShift[Pos&7] )
- // ((uint8*)Dest)[i>>3] |= GShift[i&7];
- if (n_bits == 1) {
- ((uint8_t*)dst)[0] = 0;
- if (buffer[pos >> 3] & shift(pos & 7)) {
- ((uint8_t*)dst)[0] |= 0x01;
- }
- pos++;
- } else if (n_bits != 0) {
- ((uint8_t*)dst)[((n_bits+7) >> 3) - 1] = 0;
- appBitsCpy((uint8_t*)dst, 0, buffer, pos, n_bits);
- pos += n_bits;
- }
- }
- void serialize_int(uint32_t& out_value, uint32_t max_value) {
- uint32_t value = 0;
- int64_t local_pos = pos;
- const int64_t local_num = num;
- for (uint32_t mask = 1; (value + mask) < max_value && mask; mask *= 2, local_pos++) {
- if (local_pos >= local_num) {
- break;
- }
- if (buffer[local_pos >> 3] & shift(local_pos & 7)) {
- value |= mask;
- }
- }
- // Now write back
- pos = local_pos;
- out_value = value;
- }
- void set_data(BitReader & src, int64_t n_bits ) {
- num = n_bits;
- pos = 0;
- delete[] buffer;
- buffer = new uint8_t[(n_bits+7) >>3];
- src.serialize_bits(buffer, n_bits);
- }
- void append_data(BitReader & src, int64_t n_bits) {
- int64_t oldnum_bytes = (num + 7) >> 3;
- num += n_bits;
- uint8_t* tmp = new uint8_t[(num + 7) >> 3];
- this->serialize_bits(tmp, oldnum_bytes * 8);
- src.serialize_bits(tmp + oldnum_bytes, n_bits);
- delete[] buffer;
- buffer = tmp;
- pos = 0;
- if (num & 7) {
- buffer[num >> 3] &= GMask[num & 7];
- }
- }
- int64_t get_pos() {
- return pos;
- }
- int64_t get_num() {
- return num;
- }
- ~BitReader() {
- if (buffer) {
- delete[] buffer;
- }
- }
- protected:
- uint8_t* buffer;
- int64_t num;
- int64_t pos;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement