mirror of
https://github.com/demostf/demo.js
synced 2026-06-04 00:54:14 +02:00
more preparation for encoders
This commit is contained in:
parent
69386f7d60
commit
305937d8b0
5 changed files with 84 additions and 71 deletions
|
|
@ -9,7 +9,7 @@ import {ParseGameEvent} from '../Packet/GameEvent';
|
|||
import {ParseGameEventList} from '../Packet/GameEventList';
|
||||
import {ParseMenu} from '../Packet/Menu';
|
||||
import {ParsePacketEntities} from '../Packet/PacketEntities';
|
||||
import {PacketParserMap} from '../Packet/Parser';
|
||||
import {PacketParserMap, voidEncoder} from '../Packet/Parser';
|
||||
import {ParseParseSounds} from '../Packet/ParseSounds';
|
||||
import {ParseSetConVar} from '../Packet/SetConVar';
|
||||
import {ParseTempEntities} from '../Packet/TempEntities';
|
||||
|
|
@ -19,8 +19,6 @@ import {ParseVoiceData} from '../Packet/VoiceData';
|
|||
import {ParseVoiceInit} from '../Packet/VoiceInit';
|
||||
import {Parser} from './Parser';
|
||||
|
||||
import {GameEventDefinitionMap} from '../../Data/GameEvent';
|
||||
|
||||
import {Packet as IPacket} from '../../Data/Packet';
|
||||
|
||||
// https://code.google.com/p/coldemoplayer/source/browse/branches/2.0/compLexity+Demo+Player/CDP.Source/Messages/?r=219
|
||||
|
|
@ -28,49 +26,50 @@ import {Packet as IPacket} from '../../Data/Packet';
|
|||
// https://github.com/stgn/netdecode/blob/master/Packet.cs
|
||||
// https://github.com/LestaD/SourceEngine2007/blob/master/src_main/common/netmessages.cpp
|
||||
|
||||
|
||||
export class Packet extends Parser {
|
||||
private static parsers: PacketParserMap = {
|
||||
2: ParserGenerator.make('file', 'transferId{32}fileName{s}requested{b}'),
|
||||
3: ParserGenerator.make('netTick', 'tick{32}frameTime{16}stdDev{16}'),
|
||||
4: ParserGenerator.make('stringCmd', 'command{s}'),
|
||||
5: ParseSetConVar,
|
||||
6: ParserGenerator.make('sigOnState', 'state{8}count{32}'),
|
||||
7: ParserGenerator.make('print', 'value{s}'),
|
||||
8: ParserGenerator.make('serverInfo',
|
||||
2: ParserGenerator.make('file', 'transferId{32}fileName{s}requested{b}'),
|
||||
3: ParserGenerator.make('netTick', 'tick{32}frameTime{16}stdDev{16}'),
|
||||
4: ParserGenerator.make('stringCmd', 'command{s}'),
|
||||
5: {parser: ParseSetConVar, encoder: voidEncoder},
|
||||
6: ParserGenerator.make('sigOnState', 'state{8}count{32}'),
|
||||
7: ParserGenerator.make('print', 'value{s}'),
|
||||
8: ParserGenerator.make('serverInfo',
|
||||
'version{16}serverCount{32}stv{b}dedicated{b}maxCrc{32}maxClasses{16}' +
|
||||
'mapHash{128}playerCount{8}maxPlayerCount{8}intervalPerTick{f32}platform{s1}' +
|
||||
'game{s}map{s}skybox{s}serverName{s}replay{b}'),
|
||||
10: ParseClassInfo,
|
||||
10: {parser: ParseClassInfo, encoder: voidEncoder},
|
||||
11: ParserGenerator.make('setPause', 'paused{b}'),
|
||||
12: ParseCreateStringTable,
|
||||
13: ParseUpdateStringTable,
|
||||
14: ParseVoiceInit,
|
||||
15: ParseVoiceData,
|
||||
17: ParseParseSounds,
|
||||
12: {parser: ParseCreateStringTable, encoder: voidEncoder},
|
||||
13: {parser: ParseUpdateStringTable, encoder: voidEncoder},
|
||||
14: {parser: ParseVoiceInit, encoder: voidEncoder},
|
||||
15: {parser: ParseVoiceData, encoder: voidEncoder},
|
||||
17: {parser: ParseParseSounds, encoder: voidEncoder},
|
||||
18: ParserGenerator.make('setView', 'index{11}'),
|
||||
19: ParserGenerator.make('fixAngle', 'relative{b}x{16}y{16}z{16}'),
|
||||
21: ParseBSPDecal,
|
||||
23: ParseUserMessage,
|
||||
24: ParseEntityMessage,
|
||||
25: ParseGameEvent,
|
||||
26: ParsePacketEntities,
|
||||
27: ParseTempEntities,
|
||||
21: {parser: ParseBSPDecal, encoder: voidEncoder},
|
||||
23: {parser: ParseUserMessage, encoder: voidEncoder},
|
||||
24: {parser: ParseEntityMessage, encoder: voidEncoder},
|
||||
25: {parser: ParseGameEvent, encoder: voidEncoder},
|
||||
26: {parser: ParsePacketEntities, encoder: voidEncoder},
|
||||
27: {parser: ParseTempEntities, encoder: voidEncoder},
|
||||
28: ParserGenerator.make('preFetch', 'index{14}'),
|
||||
29: ParseMenu,
|
||||
30: ParseGameEventList,
|
||||
29: {parser: ParseMenu, encoder: voidEncoder},
|
||||
30: {parser: ParseGameEventList, encoder: voidEncoder},
|
||||
31: ParserGenerator.make('getCvarValue', 'cookie{32}value{s}'),
|
||||
32: ParseCmdKeyValues,
|
||||
32: {parser: ParseCmdKeyValues, encoder: voidEncoder},
|
||||
};
|
||||
|
||||
public parse() {
|
||||
const packets: IPacket[] = [];
|
||||
let lastPacketType = 0;
|
||||
let lastPacketType = 0;
|
||||
while (this.bitsLeft > 6) { // last 6 bits for NOOP
|
||||
const type = this.stream.readBits(6);
|
||||
if (type !== 0) {
|
||||
if (Packet.parsers[type]) {
|
||||
const skip = this.skippedPackets.indexOf(type) !== -1;
|
||||
const packet = Packet.parsers[type].call(this, this.stream, this.match, skip);
|
||||
const packet = Packet.parsers[type].parser.call(this, this.stream, this.match, skip);
|
||||
packets.push(packet);
|
||||
} else {
|
||||
throw new Error('Unknown packet type ' + type + ' just parsed a ' + PacketType[lastPacketType]);
|
||||
|
|
@ -87,31 +86,31 @@ export class Packet extends Parser {
|
|||
}
|
||||
|
||||
export enum PacketType {
|
||||
file = 2,
|
||||
netTick = 3,
|
||||
stringCmd = 4,
|
||||
setConVar = 5,
|
||||
sigOnState = 6,
|
||||
print = 7,
|
||||
serverInfo = 8,
|
||||
classInfo = 10,
|
||||
setPause = 11,
|
||||
file = 2,
|
||||
netTick = 3,
|
||||
stringCmd = 4,
|
||||
setConVar = 5,
|
||||
sigOnState = 6,
|
||||
print = 7,
|
||||
serverInfo = 8,
|
||||
classInfo = 10,
|
||||
setPause = 11,
|
||||
createStringTable = 12,
|
||||
updateStringTable = 13,
|
||||
voiceInit = 14,
|
||||
voiceData = 15,
|
||||
parseSounds = 17,
|
||||
setView = 18,
|
||||
fixAngle = 19,
|
||||
bspDecal = 21,
|
||||
userMessage = 23,
|
||||
entityMessage = 24,
|
||||
gameEvent = 25,
|
||||
packetEntities = 26,
|
||||
tempEntities = 27,
|
||||
preFetch = 28,
|
||||
menu = 29,
|
||||
gameEventList = 30,
|
||||
getCvarValue = 30,
|
||||
cmdKeyValues = 32,
|
||||
voiceInit = 14,
|
||||
voiceData = 15,
|
||||
parseSounds = 17,
|
||||
setView = 18,
|
||||
fixAngle = 19,
|
||||
bspDecal = 21,
|
||||
userMessage = 23,
|
||||
entityMessage = 24,
|
||||
gameEvent = 25,
|
||||
packetEntities = 26,
|
||||
tempEntities = 27,
|
||||
preFetch = 28,
|
||||
menu = 29,
|
||||
gameEventList = 30,
|
||||
getCvarValue = 30,
|
||||
cmdKeyValues = 32,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ import {EntityMessagePacket} from '../../Data/Packet';
|
|||
const baseParser = make('entityMessage', 'index{11}classId{9}length{11}data{$length}');
|
||||
|
||||
export function ParseEntityMessage(stream: BitStream, match: Match): EntityMessagePacket { // 24: entityMessage
|
||||
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?
|
||||
return baseParser.parser(stream) as EntityMessagePacket;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,17 @@ import {Match} from '../../Data/Match';
|
|||
import {Packet} from '../../Data/Packet';
|
||||
|
||||
export type Parser = (stream: BitStream, match?: Match, skip?: boolean) => Packet;
|
||||
export type Encoder = (packet: Packet, match: Match, stream: BitStream) => void;
|
||||
|
||||
export interface PacketHandler {
|
||||
parser: Parser,
|
||||
encoder: Encoder
|
||||
}
|
||||
|
||||
|
||||
export const voidEncoder: Encoder = () => {
|
||||
};
|
||||
|
||||
export interface PacketParserMap {
|
||||
[id: number]: Parser;
|
||||
[id: number]: PacketHandler;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
import {Packet} from '../../Data/Packet';
|
||||
import {Parser} from './Parser';
|
||||
import {PacketHandler, Parser} from './Parser';
|
||||
|
||||
export function make(name: string, definition: string): Parser {
|
||||
export function make(name: string, definition: string): PacketHandler {
|
||||
const parts = definition.substr(0, definition.length - 1).split('}'); // remove leading } to prevent empty part
|
||||
const items = parts.map((part) => {
|
||||
return part.split('{');
|
||||
});
|
||||
return (stream) => {
|
||||
const result = {
|
||||
packetType: name,
|
||||
};
|
||||
try {
|
||||
for (const group of items) {
|
||||
const value = readItem(stream, group[1], result);
|
||||
if (group[0] !== '_') {
|
||||
result[group[0]] = value;
|
||||
return {
|
||||
parser: (stream) => {
|
||||
const result = {
|
||||
packetType: name,
|
||||
};
|
||||
try {
|
||||
for (const group of items) {
|
||||
const value = readItem(stream, group[1], result);
|
||||
if (group[0] !== '_') {
|
||||
result[group[0]] = value;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error('Failed reading pattern ' + definition + '. ' + e);
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error('Failed reading pattern ' + definition + '. ' + e);
|
||||
return result as Packet;
|
||||
},
|
||||
encoder: (packet, match, stream) => {
|
||||
}
|
||||
return result as Packet;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {BitStream} from 'bit-buffer';
|
|||
import {UserMessagePacket} from '../../Data/Packet';
|
||||
import {SayText2} from '../UserMessage/SayText2';
|
||||
import {make} from './ParserGenerator';
|
||||
import {voidEncoder} from './Parser';
|
||||
|
||||
enum UserMessageType {
|
||||
Geiger = 0,
|
||||
|
|
@ -65,7 +66,7 @@ enum UserMessageType {
|
|||
}
|
||||
|
||||
const userMessageParsers = {
|
||||
4: SayText2,
|
||||
4: {parser: SayText2, voidEncoder},
|
||||
5: make('textMsg', 'destType{8}text{s}'),
|
||||
};
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ export function ParseUserMessage(stream: BitStream): UserMessagePacket { // 23:
|
|||
const length = stream.readBits(11);
|
||||
const messageData = stream.readBitStream(length);
|
||||
|
||||
return userMessageParsers[type] ? userMessageParsers[type](messageData) : {
|
||||
return userMessageParsers[type] ? userMessageParsers[type].parser(messageData) : {
|
||||
packetType: 'unknownUserMessage',
|
||||
type,
|
||||
data: messageData,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue