int Int_Decode( CBitRead &entityBitBuffer, const CSVCMsg_SendTable::sendprop_t *pSendProp ) { int flags = pSendProp->flags(); if ( flags & SPROP_VARINT ) { if ( flags & SPROP_UNSIGNED ) { return (int)entityBitBuffer.ReadVarInt32(); } else { return entityBitBuffer.ReadSignedVarInt32(); } } else { if ( flags & SPROP_UNSIGNED ) { return entityBitBuffer.ReadUBitLong( pSendProp->num_bits() ); } else { return entityBitBuffer.ReadSBitLong( pSendProp->num_bits() ); } } }
void Vector_Decode( CBitRead &entityBitBuffer, const CSVCMsg_SendTable::sendprop_t *pSendProp, Vector &v ) { v.x = Float_Decode( entityBitBuffer, pSendProp ); v.y = Float_Decode( entityBitBuffer, pSendProp ); // Don't read in the third component for normals if ( ( pSendProp->flags() & SPROP_NORMAL ) == 0 ) { v.z = Float_Decode( entityBitBuffer, pSendProp ); } else { int signbit = entityBitBuffer.ReadOneBit(); float v0v0v1v1 = v.x * v.x + v.y * v.y; if (v0v0v1v1 < 1.0f) { v.z = sqrtf( 1.0f - v0v0v1v1 ); } else { v.z = 0.0f; } if (signbit) { v.z *= -1.0f; } } }
// Look for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL and // decode if they're there. Fills in fVal and returns true if it decodes anything. static inline bool DecodeSpecialFloat( CBitRead &entityBitBuffer, const CSVCMsg_SendTable::sendprop_t *pSendProp, float &fVal ) { int flags = pSendProp->flags(); if ( flags & SPROP_COORD ) { fVal = entityBitBuffer.ReadBitCoord(); return true; } else if ( flags & SPROP_COORD_MP ) { fVal = entityBitBuffer.ReadBitCoordMP( kCW_None ); return true; } else if ( flags & SPROP_COORD_MP_LOWPRECISION ) { fVal = entityBitBuffer.ReadBitCoordMP( kCW_LowPrecision ); return true; } else if ( flags & SPROP_COORD_MP_INTEGRAL ) { fVal = entityBitBuffer.ReadBitCoordMP( kCW_Integral ); return true; } else if ( flags & SPROP_NOSCALE ) { fVal = entityBitBuffer.ReadBitFloat(); return true; } else if ( flags & SPROP_NORMAL ) { fVal = entityBitBuffer.ReadBitNormal(); return true; } else if ( flags & SPROP_CELL_COORD ) { fVal = entityBitBuffer.ReadBitCellCoord( pSendProp->num_bits(), kCW_None ); return true; } else if ( flags & SPROP_CELL_COORD_LOWPRECISION ) { fVal = entityBitBuffer.ReadBitCellCoord( pSendProp->num_bits(), kCW_LowPrecision ); return true; } else if ( flags & SPROP_CELL_COORD_INTEGRAL ) { fVal = entityBitBuffer.ReadBitCellCoord( pSendProp->num_bits(), kCW_Integral ); return true; } return false; }
int64_t decode_int64(CBitRead& entityBitBuffer, const CSVCMsg_SendTable::sendprop_t* pSendProp) { if(pSendProp->flags() & SPROP_VARINT) { if(pSendProp->flags() & SPROP_UNSIGNED) { return (int64_t)entityBitBuffer.ReadVarInt64(); } else { return entityBitBuffer.ReadSignedVarInt64(); } } else { uint32_t highInt = 0; uint32_t lowInt = 0; bool bNeg = false; if(!(pSendProp->flags() & SPROP_UNSIGNED)) { bNeg = entityBitBuffer.ReadOneBit() != 0; lowInt = entityBitBuffer.ReadUBitLong(32); highInt = entityBitBuffer.ReadUBitLong(pSendProp->num_bits() - 32 - 1); } else { lowInt = entityBitBuffer.ReadUBitLong(32); highInt = entityBitBuffer.ReadUBitLong(pSendProp->num_bits() - 32); } int64_t temp; uint32_t* pInt = (uint32_t*)&temp; *pInt++ = lowInt; *pInt = highInt; if(bNeg) { temp = -temp; } return temp; } }
float decode_float(CBitRead& entityBitBuffer, const CSVCMsg_SendTable::sendprop_t* pSendProp) { float fVal = 0.0f; unsigned long dwInterp; if(decode_special_float(entityBitBuffer, pSendProp, fVal)) { return fVal; } dwInterp = entityBitBuffer.ReadUBitLong(pSendProp->num_bits()); fVal = (float)dwInterp / ((1 << pSendProp->num_bits()) - 1); fVal = pSendProp->low_value() + (pSendProp->high_value() - pSendProp->low_value()) * fVal; return fVal; }
static inline bool decode_special_float(CBitRead& entityBitBuffer, const CSVCMsg_SendTable::sendprop_t* pSendProp, float& fVal) { // Look for special flags like SPROP_COORD, SPROP_NOSCALE, and SPROP_NORMAL and // decode if they're there. Fills in fVal and returns true if it decodes anything. int flags = pSendProp->flags(); if(flags & SPROP_COORD) { fVal = entityBitBuffer.ReadBitCoord(); return true; } else if(flags & SPROP_COORD_MP) { fVal = entityBitBuffer.ReadBitCoordMP(kCW_None); return true; } else if(flags & SPROP_COORD_MP_LOWPRECISION) { fVal = entityBitBuffer.ReadBitCoordMP(kCW_LowPrecision); return true; } else if(flags & SPROP_COORD_MP_INTEGRAL) { fVal = entityBitBuffer.ReadBitCoordMP(kCW_Integral); return true; } else if(flags & SPROP_NOSCALE) { fVal = entityBitBuffer.ReadBitFloat(); return true; } else if(flags & SPROP_NORMAL) { fVal = entityBitBuffer.ReadBitNormal(); return true; } else if(flags & SPROP_CELL_COORD) { fVal = entityBitBuffer.ReadBitCellCoord(pSendProp->num_bits(), kCW_None); return true; } else if(flags & SPROP_CELL_COORD_LOWPRECISION) { fVal = entityBitBuffer.ReadBitCellCoord(pSendProp->num_bits(), kCW_LowPrecision); return true; } else if(flags & SPROP_CELL_COORD_INTEGRAL) { fVal = entityBitBuffer.ReadBitCellCoord(pSendProp->num_bits(), kCW_Integral); return true; } return false; }
void decode_vector_xyz(CBitRead& entityBitBuffer, const CSVCMsg_SendTable::sendprop_t* pSendProp, vector_t& v) { v.x = decode_float(entityBitBuffer, pSendProp); v.y = decode_float(entityBitBuffer, pSendProp); //don't read in the third component for normals if(0 == (pSendProp->flags() & SPROP_NORMAL)) { v.z = decode_float(entityBitBuffer, pSendProp); } else { int signbit = entityBitBuffer.ReadOneBit(); float v0v0v1v1 = v.x * v.x + v.y * v.y; if(v0v0v1v1 < 1.0f) { v.z = sqrtf(1.0f - v0v0v1v1); } else { v.z = 0.0f; } if(signbit) { v.z *= -1.0f; } } }
bool demo_csgo::parse_data_table(CBitRead& bs) { CSVCMsg_SendTable msg; while(true) { int32_t type = bs.ReadVarInt32(); // bs.nReadVarSInt32(); uint8_t* msg_buffer = 0; int32_t size = 0; if(!bitstream_read_bytes(&bs, &msg_buffer, &size)) { std::cerr << "demo_csgo::parse_data_table(): !bitstream_read_bytes(&bs, &msg_buffer, &size)" << std::endl; return false; } msg.ParseFromArray(msg_buffer, size); delete[] msg_buffer; if(msg.is_end()) { break; } m_data_tables.push_back(msg); } int16_t num_server_classes = bs.ReadShort(); // bs.nReadSInt(16); if(0 == num_server_classes) { std::cerr << "demo_csgo::parse_data_table(): 0 == num_server_classes" << std::endl; return false; } for(auto i = 0; i < num_server_classes; ++i) { ServerClass_t entry; entry.nClassID = bs.ReadShort(); // bs.nReadSInt(16); if(entry.nClassID >= num_server_classes) { std::cerr << "demo_csgo::parse_data_table(): entry.nClassID >= num_server_classes" << std::endl; return false; } bs.ReadString(entry.strName, sizeof(entry.strName), false, 0); // bs.nReadString(entry.strName, sizeof(entry.strName)); bs.ReadString(entry.strDTName, sizeof(entry.strDTName), false, 0); // bs.nReadString(entry.strDTName, sizeof(entry.strDTName)); entry.nDataTable = -1; for(unsigned int j = 0; j < m_data_tables.size(); ++j) { if(0 == m_data_tables[j].net_table_name().compare(entry.strDTName)) { entry.nDataTable = j; break; } } m_server_classes.push_back(entry); } for(auto i = 0; i < num_server_classes; ++i) { flatten_data_table(m_server_classes, m_data_tables, m_excludes, i); //flatten_data_table(i); } int32_t i = num_server_classes; m_server_classes_bits = 0; while (i >>= 1) m_server_classes_bits += 1; m_server_classes_bits += 1; return true; }