mirror of
https://github.com/demostf/demo.js
synced 2026-06-04 00:54:14 +02:00
encoder for updateStringTable
This commit is contained in:
parent
89b9c3b25c
commit
ae79b6a0d4
11 changed files with 280 additions and 57 deletions
|
|
@ -13,7 +13,7 @@ import {PacketParserMap, voidEncoder} from '../Packet/Parser';
|
|||
import {ParseParseSounds} from '../Packet/ParseSounds';
|
||||
import {EncodeSetConVar, ParseSetConVar} from '../Packet/SetConVar';
|
||||
import {ParseTempEntities} from '../Packet/TempEntities';
|
||||
import {ParseUpdateStringTable} from '../Packet/UpdateStringTable';
|
||||
import {EncodeUpdateStringTable, ParseUpdateStringTable} from '../Packet/UpdateStringTable';
|
||||
import {ParseUserMessage} from '../Packet/UserMessage';
|
||||
import {ParseVoiceData} from '../Packet/VoiceData';
|
||||
import {ParseVoiceInit} from '../Packet/VoiceInit';
|
||||
|
|
@ -42,7 +42,7 @@ export class Packet extends Parser {
|
|||
10: {parser: ParseClassInfo, encoder: EncodeClassInfo},
|
||||
11: make('setPause', 'paused{b}'),
|
||||
12: {parser: ParseCreateStringTable, encoder: EncodeCreateStringTable},
|
||||
13: {parser: ParseUpdateStringTable, encoder: voidEncoder},
|
||||
13: {parser: ParseUpdateStringTable, encoder: EncodeUpdateStringTable},
|
||||
14: {parser: ParseVoiceInit, encoder: voidEncoder},
|
||||
15: {parser: ParseVoiceData, encoder: voidEncoder},
|
||||
17: {parser: ParseParseSounds, encoder: voidEncoder},
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ export function EncodeCreateStringTable(packet: CreateStringTablePacket, stream:
|
|||
const encodeBits = logBase2(packet.table.maxEntries);
|
||||
stream.writeBits(packet.table.entries.length, encodeBits + 1);
|
||||
|
||||
const entryData = new BitStream(new ArrayBuffer(guessStringTableEntryLength(packet.table)));
|
||||
encodeStringTableEntries(entryData, packet.table);
|
||||
const entryData = new BitStream(new ArrayBuffer(guessStringTableEntryLength(packet.table, packet.table.entries)));
|
||||
encodeStringTableEntries(entryData, packet.table, packet.table.entries);
|
||||
|
||||
const entryLength = entryData.index;
|
||||
entryData.index = 0;
|
||||
|
|
|
|||
|
|
@ -1,32 +1,53 @@
|
|||
import {BitStream} from 'bit-buffer';
|
||||
import {Match} from '../../Data/Match';
|
||||
import {UpdateStringTablePacket} from '../../Data/Packet';
|
||||
import {parseStringTableEntries} from '../StringTableParser';
|
||||
import {encodeStringTableEntries, guessStringTableEntryLength, parseStringTableEntries} from '../StringTableParser';
|
||||
|
||||
export function ParseUpdateStringTable(stream: BitStream, match: Match): UpdateStringTablePacket { // 12: updateStringTable
|
||||
const tableId = stream.readBits(5);
|
||||
|
||||
const multipleChanged = stream.readBoolean();
|
||||
const changedEntries = (multipleChanged) ? stream.readBits(16) : 1;
|
||||
const changedEntries = multipleChanged ? stream.readUint16() : 1;
|
||||
|
||||
const bitCount = stream.readBits(20);
|
||||
const data = stream.readBitStream(bitCount);
|
||||
data.index = 0;
|
||||
|
||||
if (!match.stringTables[tableId]) {
|
||||
throw new Error('Table not found for update');
|
||||
throw new Error(`Table not found for update: ${tableId}`);
|
||||
}
|
||||
|
||||
const table = match.stringTables[tableId];
|
||||
const updatedEntries = parseStringTableEntries(data, table, changedEntries, table.entries);
|
||||
|
||||
for (let i = 0; i < updatedEntries.length; i++) {
|
||||
if (updatedEntries[i]) {
|
||||
table.entries[i] = updatedEntries[i];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
packetType: 'updateStringTable',
|
||||
table: table,
|
||||
entries: updatedEntries,
|
||||
tableId
|
||||
};
|
||||
}
|
||||
|
||||
export function EncodeUpdateStringTable(packet: UpdateStringTablePacket, stream: BitStream, match: Match) {
|
||||
stream.writeBits(packet.tableId, 5);
|
||||
|
||||
const changedEntryCount = packet.entries.filter(entry => entry).length;
|
||||
const multipleChanged = changedEntryCount > 1;
|
||||
stream.writeBoolean(multipleChanged);
|
||||
|
||||
if (multipleChanged) {
|
||||
stream.writeUint16(changedEntryCount);
|
||||
}
|
||||
|
||||
if (!match.stringTables[packet.tableId]) {
|
||||
throw new Error(`Table not found for update: ${packet.tableId}`);
|
||||
}
|
||||
const table = match.stringTables[packet.tableId];
|
||||
const entryData = new BitStream(new ArrayBuffer(guessStringTableEntryLength(table, packet.entries)));
|
||||
encodeStringTableEntries(entryData, table, packet.entries);
|
||||
|
||||
const entryLength = entryData.index;
|
||||
entryData.index = 0;
|
||||
|
||||
stream.writeBits(entryLength, 20);
|
||||
stream.writeBitStream(entryData, entryLength);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import {BitStream} from 'bit-buffer';
|
||||
import {Match} from '../Data/Match';
|
||||
import {StringTable, StringTableEntry} from '../Data/StringTable';
|
||||
import {logBase2} from '../Math';
|
||||
|
||||
|
|
@ -11,12 +10,12 @@ export function parseStringTableEntries(stream: BitStream, table: StringTable, e
|
|||
const history: StringTableEntry[] = [];
|
||||
|
||||
for (let i = 0; i < entryCount; i++) {
|
||||
const entryIndex = (!stream.readBoolean()) ? stream.readBits(entryBits) : lastEntry + 1;
|
||||
const entryIndex = !stream.readBoolean() ? stream.readBits(entryBits) : lastEntry + 1;
|
||||
|
||||
lastEntry = entryIndex;
|
||||
|
||||
if (entryIndex < 0 || entryIndex > table.maxEntries) {
|
||||
throw new Error('Invalid string index for stringtable');
|
||||
throw new Error('Invalid string index for string table');
|
||||
}
|
||||
|
||||
let value;
|
||||
|
|
@ -31,7 +30,7 @@ export function parseStringTableEntries(stream: BitStream, table: StringTable, e
|
|||
const restOfString = stream.readASCIIString();
|
||||
|
||||
if (!history[index].text) {
|
||||
value = restOfString; // best guess, happens in some pov demos but only for unimported tables it seems
|
||||
value = restOfString; // best guess, happens in some pov demos but only for unimportant tables it seems
|
||||
} else {
|
||||
value = history[index].text.substr(0, bytesToCopy) + restOfString;
|
||||
}
|
||||
|
|
@ -67,7 +66,6 @@ export function parseStringTableEntries(stream: BitStream, table: StringTable, e
|
|||
text: value,
|
||||
extraData: userData,
|
||||
};
|
||||
console.log(entries[entryIndex]);
|
||||
history.push(entries[entryIndex]);
|
||||
}
|
||||
if (history.length > 32) {
|
||||
|
|
@ -78,10 +76,10 @@ export function parseStringTableEntries(stream: BitStream, table: StringTable, e
|
|||
return entries;
|
||||
}
|
||||
|
||||
export function guessStringTableEntryLength(table: StringTable): number {
|
||||
export function guessStringTableEntryLength(table: StringTable, entries: StringTableEntry[]): number {
|
||||
// a rough guess of how many bytes are needed to encode the table entries
|
||||
const entryBytes = Math.ceil(logBase2(table.maxEntries) / 8);
|
||||
return table.entries.reduce((length: number, entry: StringTableEntry) => {
|
||||
return entries.reduce((length: number, entry: StringTableEntry) => {
|
||||
return length +
|
||||
entryBytes +
|
||||
1 + // misc boolean
|
||||
|
|
@ -90,13 +88,13 @@ export function guessStringTableEntryLength(table: StringTable): number {
|
|||
}, 1);
|
||||
}
|
||||
|
||||
export function encodeStringTableEntries(stream: BitStream, table: StringTable) {
|
||||
export function encodeStringTableEntries(stream: BitStream, table: StringTable, entries: StringTableEntry[]) {
|
||||
const entryBits = logBase2(table.maxEntries);
|
||||
let lastIndex = -1;
|
||||
for (let i = 0; i < table.entries.length; i++) {
|
||||
if (table.entries[i]) {
|
||||
const entry = table.entries[i];
|
||||
if (i !== lastIndex) {
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
if (entries[i]) {
|
||||
const entry = entries[i];
|
||||
if (i !== (lastIndex + 1)) {
|
||||
stream.writeBoolean(false);
|
||||
stream.writeBits(i, entryBits);
|
||||
} else {
|
||||
|
|
@ -113,10 +111,14 @@ export function encodeStringTableEntries(stream: BitStream, table: StringTable)
|
|||
if (entry.extraData) {
|
||||
stream.writeBoolean(true);
|
||||
|
||||
if (!table.fixedUserDataSizeBits) {
|
||||
stream.writeBits(Math.ceil(entry.extraData.length / 8), 14);
|
||||
entry.extraData.index = 0;
|
||||
if (table.fixedUserDataSizeBits) {
|
||||
stream.writeBitStream(entry.extraData, table.fixedUserDataSizeBits);
|
||||
} else {
|
||||
const byteLength = Math.ceil(entry.extraData.length / 8);
|
||||
stream.writeBits(byteLength, 14);
|
||||
stream.writeBitStream(entry.extraData, byteLength * 8);
|
||||
}
|
||||
stream.writeBitStream(entry.extraData);
|
||||
entry.extraData.index = 0;
|
||||
} else {
|
||||
stream.writeBoolean(false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue