2015-05-15 03:36:57 +02:00
|
|
|
|
|
|
|
#include "svc_createstringtable.h"
|
2015-06-25 05:59:39 +02:00
|
|
|
#include "base/bitfile.h"
|
2016-04-28 04:31:33 +02:00
|
|
|
#include "game/sourcecontext.h"
|
2021-05-01 18:38:37 +02:00
|
|
|
#include "game/stringtables.h"
|
2015-05-15 03:36:57 +02:00
|
|
|
#include "netmath.h"
|
|
|
|
#include "netcontants.h"
|
|
|
|
|
2016-04-21 03:18:56 +02:00
|
|
|
#include "sourcesdk/common.h"
|
|
|
|
#include <vector>
|
|
|
|
|
2015-05-15 03:36:57 +02:00
|
|
|
namespace NetHandlers
|
|
|
|
{
|
2015-06-19 02:23:26 +02:00
|
|
|
bool SVC_CreateStringTable_BitRead_Internal(BitRead& bitbuf, SourceGameContext& context, NetMsg::SVC_CreateStringTable* data)
|
2015-05-15 03:36:57 +02:00
|
|
|
{
|
|
|
|
if (bitbuf.PeekUBitLong(8) == ':')
|
|
|
|
{
|
|
|
|
data->isFileNames = true;
|
|
|
|
bitbuf.ReadByte();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data->isFileNames = false;
|
|
|
|
}
|
|
|
|
bitbuf.ReadString(data->tableName, sizeof(data->tableName));
|
|
|
|
data->maxEntries = bitbuf.ReadWord();
|
2016-04-21 03:18:56 +02:00
|
|
|
|
2021-05-01 18:38:37 +02:00
|
|
|
const uint32_t numEncodeBits = math::log2(data->maxEntries);
|
2016-04-21 03:18:56 +02:00
|
|
|
data->numEntries = bitbuf.ReadUBitLong(numEncodeBits + 1);
|
2016-04-21 04:42:43 +02:00
|
|
|
|
2015-05-15 03:36:57 +02:00
|
|
|
if (context.protocol > 23)
|
|
|
|
{
|
2021-05-01 18:38:37 +02:00
|
|
|
data->dataLengthInBits = bitbuf.ReadVarInt32();
|
2015-05-15 03:36:57 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-05-01 18:38:37 +02:00
|
|
|
data->dataLengthInBits = bitbuf.ReadUBitLong(NET_MAX_PAYLOAD_BITS_OLD + 3);
|
2015-05-15 03:36:57 +02:00
|
|
|
}
|
2021-05-01 18:38:37 +02:00
|
|
|
const uint32_t dataLengthInBytes = math::BitsToBytes(data->dataLengthInBits);
|
2016-04-21 04:42:43 +02:00
|
|
|
|
2015-05-15 03:36:57 +02:00
|
|
|
data->isUserDataFixedSize = bitbuf.ReadOneBit() != 0;
|
|
|
|
if (data->isUserDataFixedSize)
|
|
|
|
{
|
|
|
|
data->userDataSize = bitbuf.ReadUBitLong(12);
|
|
|
|
data->userDataSizeBits = bitbuf.ReadUBitLong(4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data->userDataSize = 0;
|
|
|
|
data->userDataSizeBits = 0;
|
|
|
|
}
|
|
|
|
if (context.protocol > 14)
|
|
|
|
{
|
2016-04-21 03:12:24 +02:00
|
|
|
data->compressedData = bitbuf.ReadOneBit() != 0;
|
2015-05-15 03:36:57 +02:00
|
|
|
}
|
2021-05-01 18:38:37 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
data->compressedData = false;
|
|
|
|
}
|
|
|
|
|
2016-04-21 04:42:43 +02:00
|
|
|
data->data.reset(new uint8_t[dataLengthInBytes]);
|
2021-05-01 18:38:37 +02:00
|
|
|
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
|
|
|
|
|
|
|
|
StringTable *table = context.stringTables->GetStringTable(data->tableName, true);
|
|
|
|
table->maxEntries = data->maxEntries;
|
|
|
|
table->isUserDataFixedSize = data->isUserDataFixedSize;
|
|
|
|
table->userDataSize = data->userDataSize;
|
|
|
|
table->userDataSizeBits = data->userDataSizeBits;
|
|
|
|
table->entryBits = math::log2(table->maxEntries);
|
2016-04-21 03:18:56 +02:00
|
|
|
|
|
|
|
if (data->compressedData)
|
|
|
|
{
|
2021-05-01 18:38:37 +02:00
|
|
|
bf_read bitbuf2(data->data.get(), dataLengthInBytes, data->dataLengthInBits);
|
2016-04-21 03:18:56 +02:00
|
|
|
const uint32_t decompressedNumBytes = bitbuf2.ReadUBitLong(32);
|
|
|
|
const uint32_t compressedNumBytes = bitbuf2.ReadUBitLong(32);
|
|
|
|
std::unique_ptr<uint8_t[]> compressedData(new uint8[compressedNumBytes]);
|
|
|
|
std::unique_ptr<uint8_t[]> uncompressedData(new uint8[decompressedNumBytes]);
|
|
|
|
bitbuf2.ReadBytes(compressedData.get(), compressedNumBytes);
|
|
|
|
|
|
|
|
uint32_t numWritten = COM_BufferToBufferDecompress(uncompressedData.get(), decompressedNumBytes, compressedData.get(), compressedNumBytes);
|
2021-05-01 18:38:37 +02:00
|
|
|
assert(numWritten == decompressedNumBytes);
|
2016-04-21 03:18:56 +02:00
|
|
|
bitbuf2 = bf_read(uncompressedData.get(), decompressedNumBytes);
|
2021-05-01 18:38:37 +02:00
|
|
|
table->ParseUpdate(bitbuf2, data->numEntries, context);
|
2016-04-21 03:18:56 +02:00
|
|
|
}
|
2021-05-01 18:38:37 +02:00
|
|
|
else if(dataLengthInBytes)
|
2016-04-21 03:18:56 +02:00
|
|
|
{
|
2021-05-01 18:38:37 +02:00
|
|
|
bf_read bitbuf2(data->data.get(), dataLengthInBytes, data->dataLengthInBits);
|
|
|
|
table->ParseUpdate(bitbuf2, data->numEntries, context);
|
2016-04-21 03:18:56 +02:00
|
|
|
}
|
|
|
|
|
2015-05-15 03:36:57 +02:00
|
|
|
return !bitbuf.IsOverflowed();
|
|
|
|
}
|
|
|
|
}
|