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

some minor refactoring to prepare for re-encoding

This commit is contained in:
Robin Appelman 2017-08-12 00:52:04 +02:00
commit 69386f7d60
18 changed files with 121 additions and 122 deletions

View file

@ -107,6 +107,7 @@ export interface TextMessagePacket {
export interface UnknownUserMessagePacket { export interface UnknownUserMessagePacket {
packetType: 'unknownUserMessage'; packetType: 'unknownUserMessage';
type: number; type: number;
data: BitStream;
} }
export interface VoiceInitPacket { export interface VoiceInitPacket {

View file

@ -1,22 +1,22 @@
import * as ParserGenerator from '../Packet/ParserGenerator'; import * as ParserGenerator from '../Packet/ParserGenerator';
import {BSPDecal} from '../Packet/BSPDecal'; import {ParseBSPDecal} from '../Packet/BSPDecal';
import {ClassInfo} from '../Packet/ClassInfo'; import {ParseClassInfo} from '../Packet/ClassInfo';
import {CmdKeyValues} from '../Packet/CmdKeyValues'; import {ParseCmdKeyValues} from '../Packet/CmdKeyValues';
import {CreateStringTable} from '../Packet/CreateStringTable'; import {ParseCreateStringTable} from '../Packet/CreateStringTable';
import {EntityMessage} from '../Packet/EntityMessage'; import {ParseEntityMessage} from '../Packet/EntityMessage';
import {GameEvent} from '../Packet/GameEvent'; import {ParseGameEvent} from '../Packet/GameEvent';
import {GameEventList} from '../Packet/GameEventList'; import {ParseGameEventList} from '../Packet/GameEventList';
import {Menu} from '../Packet/Menu'; import {ParseMenu} from '../Packet/Menu';
import {PacketEntities} from '../Packet/PacketEntities'; import {ParsePacketEntities} from '../Packet/PacketEntities';
import {PacketParserMap} from '../Packet/Parser'; import {PacketParserMap} from '../Packet/Parser';
import {ParseSounds} from '../Packet/ParseSounds'; import {ParseParseSounds} from '../Packet/ParseSounds';
import {SetConVar} from '../Packet/SetConVar'; import {ParseSetConVar} from '../Packet/SetConVar';
import {TempEntities} from '../Packet/TempEntities'; import {ParseTempEntities} from '../Packet/TempEntities';
import {UpdateStringTable} from '../Packet/UpdateStringTable'; import {ParseUpdateStringTable} from '../Packet/UpdateStringTable';
import {UserMessage} from '../Packet/UserMessage'; import {ParseUserMessage} from '../Packet/UserMessage';
import {VoiceData} from '../Packet/VoiceData'; import {ParseVoiceData} from '../Packet/VoiceData';
import {VoiceInit} from '../Packet/VoiceInit'; import {ParseVoiceInit} from '../Packet/VoiceInit';
import {Parser} from './Parser'; import {Parser} from './Parser';
import {GameEventDefinitionMap} from '../../Data/GameEvent'; import {GameEventDefinitionMap} from '../../Data/GameEvent';
@ -33,33 +33,33 @@ export class Packet extends Parser {
2: ParserGenerator.make('file', 'transferId{32}fileName{s}requested{b}'), 2: ParserGenerator.make('file', 'transferId{32}fileName{s}requested{b}'),
3: ParserGenerator.make('netTick', 'tick{32}frameTime{16}stdDev{16}'), 3: ParserGenerator.make('netTick', 'tick{32}frameTime{16}stdDev{16}'),
4: ParserGenerator.make('stringCmd', 'command{s}'), 4: ParserGenerator.make('stringCmd', 'command{s}'),
5: SetConVar, 5: ParseSetConVar,
6: ParserGenerator.make('sigOnState', 'state{8}count{32}'), 6: ParserGenerator.make('sigOnState', 'state{8}count{32}'),
7: ParserGenerator.make('print', 'value{s}'), 7: ParserGenerator.make('print', 'value{s}'),
8: ParserGenerator.make('serverInfo', 8: ParserGenerator.make('serverInfo',
'version{16}serverCount{32}stv{b}dedicated{b}maxCrc{32}maxClasses{16}' + 'version{16}serverCount{32}stv{b}dedicated{b}maxCrc{32}maxClasses{16}' +
'mapHash{128}playerCount{8}maxPlayerCount{8}intervalPerTick{f32}platform{s1}' + 'mapHash{128}playerCount{8}maxPlayerCount{8}intervalPerTick{f32}platform{s1}' +
'game{s}map{s}skybox{s}serverName{s}replay{b}'), 'game{s}map{s}skybox{s}serverName{s}replay{b}'),
10: ClassInfo, 10: ParseClassInfo,
11: ParserGenerator.make('setPause', 'paused{b}'), 11: ParserGenerator.make('setPause', 'paused{b}'),
12: CreateStringTable, 12: ParseCreateStringTable,
13: UpdateStringTable, 13: ParseUpdateStringTable,
14: VoiceInit, 14: ParseVoiceInit,
15: VoiceData, 15: ParseVoiceData,
17: ParseSounds, 17: ParseParseSounds,
18: ParserGenerator.make('setView', 'index{11}'), 18: ParserGenerator.make('setView', 'index{11}'),
19: ParserGenerator.make('fixAngle', 'relative{b}x{16}y{16}z{16}'), 19: ParserGenerator.make('fixAngle', 'relative{b}x{16}y{16}z{16}'),
21: BSPDecal, 21: ParseBSPDecal,
23: UserMessage, 23: ParseUserMessage,
24: EntityMessage, 24: ParseEntityMessage,
25: GameEvent, 25: ParseGameEvent,
26: PacketEntities, 26: ParsePacketEntities,
27: TempEntities, 27: ParseTempEntities,
28: ParserGenerator.make('preFetch', 'index{14}'), 28: ParserGenerator.make('preFetch', 'index{14}'),
29: Menu, 29: ParseMenu,
30: GameEventList, 30: ParseGameEventList,
31: ParserGenerator.make('getCvarValue', 'cookie{32}value{s}'), 31: ParserGenerator.make('getCvarValue', 'cookie{32}value{s}'),
32: CmdKeyValues, 32: ParseCmdKeyValues,
}; };
public parse() { public parse() {

View file

@ -22,9 +22,9 @@ function getCoord(stream) {
} }
function getVecCoord(stream): Vector { function getVecCoord(stream): Vector {
const hasX = !!stream.readBits(1); const hasX = stream.readBoolean();
const hasY = !!stream.readBits(1); const hasY = stream.readBoolean();
const hasZ = !!stream.readBits(1); const hasZ = stream.readBoolean();
return { return {
x: hasX ? getCoord(stream) : 0, x: hasX ? getCoord(stream) : 0,
y: hasY ? getCoord(stream) : 0, y: hasY ? getCoord(stream) : 0,
@ -32,7 +32,7 @@ function getVecCoord(stream): Vector {
}; };
} }
export function BSPDecal(stream: BitStream): BSPDecalPacket { // 21: BSPDecal export function ParseBSPDecal(stream: BitStream): BSPDecalPacket { // 21: ParseBSPDecal
let modelIndex = 0; let modelIndex = 0;
let entIndex = 0; let entIndex = 0;
const position = getVecCoord(stream); const position = getVecCoord(stream);

View file

@ -2,7 +2,7 @@ import {BitStream} from 'bit-buffer';
import {ClassInfoPacket} from '../../Data/Packet'; import {ClassInfoPacket} from '../../Data/Packet';
import {logBase2} from '../../Math'; import {logBase2} from '../../Math';
export function ClassInfo(stream: BitStream): ClassInfoPacket { // 10: classInfo export function ParseClassInfo(stream: BitStream): ClassInfoPacket { // 10: classInfo
const count = stream.readBits(16); const count = stream.readBits(16);
const create = stream.readBoolean(); const create = stream.readBoolean();
const entries: any[] = []; const entries: any[] = [];

View file

@ -1,10 +1,10 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {CmdKeyValuesPacket} from '../../Data/Packet'; import {CmdKeyValuesPacket} from '../../Data/Packet';
export function CmdKeyValues(stream: BitStream): CmdKeyValuesPacket { export function ParseCmdKeyValues(stream: BitStream): CmdKeyValuesPacket {
// 'length{32}data{$length}'
const length = stream.readUint32(); const length = stream.readUint32();
const data = stream.readBitStream(length); const data = stream.readBitStream(length);
// 'length{32}data{$length}'
return { return {
packetType: 'cmdKeyValues', packetType: 'cmdKeyValues',
length, length,

View file

@ -8,7 +8,7 @@ import {Match} from '../../Data/Match';
import {StringTable} from '../../Data/StringTable'; import {StringTable} from '../../Data/StringTable';
import {parseStringTable} from '../StringTableParser'; import {parseStringTable} from '../StringTableParser';
export function CreateStringTable(stream: BitStream, match: Match): StringTablePacket { // 12: createStringTable export function ParseCreateStringTable(stream: BitStream, match: Match): StringTablePacket { // 12: createStringTable
const tableName = stream.readASCIIString(); const tableName = stream.readASCIIString();
const maxEntries = stream.readUint16(); const maxEntries = stream.readUint16();
const encodeBits = logBase2(maxEntries); const encodeBits = logBase2(maxEntries);

View file

@ -6,6 +6,9 @@ import {EntityMessagePacket} from '../../Data/Packet';
const baseParser = make('entityMessage', 'index{11}classId{9}length{11}data{$length}'); const baseParser = make('entityMessage', 'index{11}classId{9}length{11}data{$length}');
export function EntityMessage(stream: BitStream, match: Match): EntityMessagePacket { // 24: entityMessage export function ParseEntityMessage(stream: BitStream, match: Match): EntityMessagePacket { // 24: entityMessage
return baseParser(stream) as EntityMessagePacket; // todo parse data further? const basePacketData: EntityMessagePacket = baseParser(stream) as EntityMessagePacket;
// entity messages seem pretty unimportant, they are unreliable messages and from testing only the "clear decals"
// message seems to be used in practice, probably safe to just leave as is
return basePacketData; // todo parse data further?
} }

View file

@ -45,7 +45,7 @@ function getGameEventValue(stream: BitStream, entry: GameEventEntry): GameEventV
} }
} }
export function GameEvent(stream: BitStream, match: Match): GameEventPacket { // 25: game event export function ParseGameEvent(stream: BitStream, match: Match): GameEventPacket { // 25: game event
const length = stream.readBits(11); const length = stream.readBits(11);
const end = stream.index + length; const end = stream.index + length;
const eventId = stream.readBits(9); const eventId = stream.readBits(9);

View file

@ -3,7 +3,7 @@ import {GameEventDefinitionMap, GameEventEntry} from '../../Data/GameEvent';
import {Match} from '../../Data/Match'; import {Match} from '../../Data/Match';
import {GameEventListPacket} from '../../Data/Packet'; import {GameEventListPacket} from '../../Data/Packet';
export function GameEventList(stream: BitStream, match: Match): GameEventListPacket { // 30: gameEventList export function ParseGameEventList(stream: BitStream, match: Match): GameEventListPacket { // 30: gameEventList
// list of game events and parameters // list of game events and parameters
const numEvents = stream.readBits(9); const numEvents = stream.readBits(9);
const length = stream.readBits(20); const length = stream.readBits(20);

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {MenuPacket} from '../../Data/Packet'; import {MenuPacket} from '../../Data/Packet';
export function Menu(stream: BitStream): MenuPacket { export function ParseMenu(stream: BitStream): MenuPacket {
const type = stream.readUint16(); const type = stream.readUint16();
const length = stream.readUint16(); const length = stream.readUint16();
const data = stream.readBitStream(length * 8); // length is in bytes const data = stream.readBitStream(length * 8); // length is in bytes

View file

@ -58,7 +58,7 @@ function getPacketEntityForExisting(entityId: number, match: Match, pvs: PVS) {
return new PacketEntity(serverClass, entityId, pvs); return new PacketEntity(serverClass, entityId, pvs);
} }
export function PacketEntities(stream: BitStream, match: Match, skip: boolean = false): PacketEntitiesPacket { // 26: packetEntities export function ParsePacketEntities(stream: BitStream, match: Match, skip: boolean = false): PacketEntitiesPacket { // 26: packetEntities
// https://github.com/skadistats/smoke/blob/master/smoke/replay/handler/svc_packetentities.pyx // https://github.com/skadistats/smoke/blob/master/smoke/replay/handler/svc_packetentities.pyx
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Handler/PacketEntitesHandler.cs // https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Handler/PacketEntitesHandler.cs
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Entity.cs // https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Entity.cs

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {ParseSoundsPacket} from '../../Data/Packet'; import {ParseSoundsPacket} from '../../Data/Packet';
export function ParseSounds(stream: BitStream): ParseSoundsPacket { // 17: parseSounds export function ParseParseSounds(stream: BitStream): ParseSoundsPacket { // 17: parseSounds
const reliable = stream.readBoolean(); const reliable = stream.readBoolean();
const num = (reliable) ? 1 : stream.readUint8(); const num = (reliable) ? 1 : stream.readUint8();
const length = (reliable) ? stream.readUint8() : stream.readUint16(); const length = (reliable) ? stream.readUint8() : stream.readUint16();

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {SetConVarPacket} from '../../Data/Packet'; import {SetConVarPacket} from '../../Data/Packet';
export function SetConVar(stream: BitStream): SetConVarPacket { // 5: setconvar export function ParseSetConVar(stream: BitStream): SetConVarPacket { // 5: setconvar
const count = stream.readBits(8); const count = stream.readBits(8);
const vars: {[key: string]: string} = {}; const vars: {[key: string]: string} = {};
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {

View file

@ -4,7 +4,7 @@ import {TempEntitiesPacket} from '../../Data/Packet';
import {PacketEntity, PVS} from '../../Data/PacketEntity'; import {PacketEntity, PVS} from '../../Data/PacketEntity';
import {applyEntityUpdate} from '../EntityDecoder'; import {applyEntityUpdate} from '../EntityDecoder';
export function TempEntities(stream: BitStream, match: Match, skip: boolean = false): TempEntitiesPacket { // 10: classInfo export function ParseTempEntities(stream: BitStream, match: Match, skip: boolean = false): TempEntitiesPacket { // 10: classInfo
const entityCount = stream.readBits(8); const entityCount = stream.readBits(8);
const length = readVarInt(stream); const length = readVarInt(stream);
const end = stream.index + length; const end = stream.index + length;

View file

@ -3,7 +3,7 @@ import {Match} from '../../Data/Match';
import {StringTablePacket} from '../../Data/Packet'; import {StringTablePacket} from '../../Data/Packet';
import {parseStringTable} from '../StringTableParser'; import {parseStringTable} from '../StringTableParser';
export function UpdateStringTable(stream: BitStream, match: Match): StringTablePacket { // 12: updateStringTable export function ParseUpdateStringTable(stream: BitStream, match: Match): StringTablePacket { // 12: updateStringTable
const tableId = stream.readBits(5); const tableId = stream.readBits(5);
const multipleChanged = stream.readBoolean(); const multipleChanged = stream.readBoolean();

View file

@ -69,19 +69,14 @@ const userMessageParsers = {
5: make('textMsg', 'destType{8}text{s}'), 5: make('textMsg', 'destType{8}text{s}'),
}; };
export function UserMessage(stream: BitStream): UserMessagePacket { // 23: user message export function ParseUserMessage(stream: BitStream): UserMessagePacket { // 23: user message
const type = stream.readBits(8); const type = stream.readBits(8);
const length = stream.readBits(11); const length = stream.readBits(11);
const pos = stream.index; const messageData = stream.readBitStream(length);
let result;
if (userMessageParsers[type]) { return userMessageParsers[type] ? userMessageParsers[type](messageData) : {
result = userMessageParsers[type](stream);
} else {
result = {
packetType: 'unknownUserMessage', packetType: 'unknownUserMessage',
type, type,
data: messageData,
}; };
}
stream.index = pos + length;
return result;
} }

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {VoiceDataPacket} from '../../Data/Packet'; import {VoiceDataPacket} from '../../Data/Packet';
export function VoiceData(stream: BitStream): VoiceDataPacket { export function ParseVoiceData(stream: BitStream): VoiceDataPacket {
// 'client{8}proximity{8}length{16}_{$length}' // 'client{8}proximity{8}length{16}_{$length}'
const client = stream.readUint8(); const client = stream.readUint8();
const proximity = stream.readUint8(); const proximity = stream.readUint8();

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {VoiceInitPacket} from '../../Data/Packet'; import {VoiceInitPacket} from '../../Data/Packet';
export function VoiceInit(stream: BitStream): VoiceInitPacket { export function ParseVoiceInit(stream: BitStream): VoiceInitPacket {
const codec = stream.readASCIIString(); const codec = stream.readASCIIString();
const quality = stream.readUint8(); const quality = stream.readUint8();
// no clue, from 2017-2-14 update // no clue, from 2017-2-14 update