1
0
Fork 0
mirror of https://github.com/demostf/demo.js synced 2026-06-04 00:54:14 +02:00

handle string table compression

This commit is contained in:
Robin Appelman 2017-11-24 23:00:58 +01:00
commit 31440704d6
5 changed files with 31 additions and 7 deletions

View file

@ -7,6 +7,7 @@ export interface StringTable {
fixedUserDataSize?: number; fixedUserDataSize?: number;
fixedUserDataSizeBits?: number; fixedUserDataSizeBits?: number;
clientEntries?: StringTableEntry[]; clientEntries?: StringTableEntry[];
compressed: boolean;
} }
export interface StringTableEntry { export interface StringTableEntry {

View file

@ -24,7 +24,8 @@ export const StringTableHandler: MessageHandler<StringTablesMessage> = {
entries, entries,
name: tableName, name: tableName,
maxEntries: entryCount, maxEntries: entryCount,
clientEntries: [] clientEntries: [],
compressed: false
}; };
if (messageStream.readBoolean()) { if (messageStream.readBoolean()) {

View file

@ -3,7 +3,7 @@ import {CreateStringTablePacket} from '../../Data/Packet';
import {logBase2} from '../../Math'; import {logBase2} from '../../Math';
import {readVarInt, writeVarInt} from '../readBitVar'; import {readVarInt, writeVarInt} from '../readBitVar';
import {uncompress} from 'snappyjs'; import {uncompress, compress} from 'snappyjs';
import {StringTable} from '../../Data/StringTable'; import {StringTable} from '../../Data/StringTable';
import {encodeStringTableEntries, guessStringTableEntryLength, parseStringTableEntries} from '../StringTableParser'; import {encodeStringTableEntries, guessStringTableEntryLength, parseStringTableEntries} from '../StringTableParser';
@ -53,7 +53,8 @@ export function ParseCreateStringTable(stream: BitStream): CreateStringTablePack
entries: [], entries: [],
maxEntries, maxEntries,
fixedUserDataSize: userDataSize, fixedUserDataSize: userDataSize,
fixedUserDataSizeBits: userDataSizeBits fixedUserDataSizeBits: userDataSizeBits,
compressed: isCompressed
}; };
// console.log(`${tableName} ${entityCount} ${bitCount}`); // console.log(`${tableName} ${entityCount} ${bitCount}`);
@ -72,9 +73,20 @@ export function EncodeCreateStringTable(packet: CreateStringTablePacket, stream:
const numEntries = packet.table.entries.filter((entry) => entry).length; const numEntries = packet.table.entries.filter((entry) => entry).length;
stream.writeBits(numEntries, encodeBits + 1); stream.writeBits(numEntries, encodeBits + 1);
const entryData = new BitStream(new ArrayBuffer(guessStringTableEntryLength(packet.table, packet.table.entries))); let entryData = new BitStream(new ArrayBuffer(guessStringTableEntryLength(packet.table, packet.table.entries)));
encodeStringTableEntries(entryData, packet.table, packet.table.entries); encodeStringTableEntries(entryData, packet.table, packet.table.entries);
if (packet.table.compressed) {
const decompressedByteLength = Math.ceil(entryData.length / 8);
entryData.index = 0;
const compressedData = compress(entryData.readArrayBuffer(decompressedByteLength));
entryData = new BitStream(new ArrayBuffer(decompressedByteLength));
entryData.writeUint32(decompressedByteLength);
entryData.writeUint32(compressedData.byteLength + 4); // 4 magic bytes
entryData.writeASCIIString('SNAP', 4);
let typeForce: any = compressedData.buffer;
entryData.writeArrayBuffer(typeForce as BitStream);
}
const entryLength = entryData.index; const entryLength = entryData.index;
entryData.index = 0; entryData.index = 0;
@ -88,8 +100,7 @@ export function EncodeCreateStringTable(packet: CreateStringTablePacket, stream:
stream.writeBoolean(false); stream.writeBoolean(false);
} }
// we never compress table data stream.writeBoolean(packet.table.compressed);
stream.writeBoolean(false);
if (entryLength) { if (entryLength) {
stream.writeBitStream(entryData, entryLength); stream.writeBitStream(entryData, entryLength);

Binary file not shown.

View file

@ -3,9 +3,10 @@ import {readFileSync} from 'fs';
import {PacketTypeId} from '../../../../Data/Packet'; import {PacketTypeId} from '../../../../Data/Packet';
import {ParserState} from '../../../../Data/ParserState'; import {ParserState} from '../../../../Data/ParserState';
import {PacketMessageHandler} from '../../../../Parser/Message/Packet'; import {PacketMessageHandler} from '../../../../Parser/Message/Packet';
import {assertEncoder, assertParser, getStream} from '../Packet/PacketTest'; import {assertEncoder, assertParser, assertReEncode, getStream} from '../Packet/PacketTest';
const data = Object.values(JSON.parse(readFileSync(__dirname + '/../../../data/packetMessageData.json', 'utf8'))); const data = Object.values(JSON.parse(readFileSync(__dirname + '/../../../data/packetMessageData.json', 'utf8')));
const firstPacketData = readFileSync(__dirname + '/../../../data/packetMessageFirst.bin');
const expected = JSON.parse(readFileSync(__dirname + '/../../../data/packetMessageResult.json', 'utf8')); const expected = JSON.parse(readFileSync(__dirname + '/../../../data/packetMessageResult.json', 'utf8'));
const getParserState = (fastMode) => { const getParserState = (fastMode) => {
@ -40,4 +41,14 @@ suite('Packet', () => {
// shorted since empty entity list encoded, instead of skipping over entities // shorted since empty entity list encoded, instead of skipping over entities
assertEncoder(parser, encoder, expected, 920, ''); assertEncoder(parser, encoder, expected, 920, '');
}); });
test('Encode first packet message', () => {
const expected = parser(new BitStream(firstPacketData));
assertEncoder(parser, encoder, expected, 1512600, '');
});
test('Re-encode packet message', () => {
// shorted since empty entity list encoded, instead of skipping over entities
assertReEncode(parser, encoder, new BitStream(firstPacketData));
});
}); });