mirror of
https://github.com/demostf/demo.js
synced 2026-06-04 00:54:14 +02:00
move message specific bits to their respective handlers
This commit is contained in:
parent
33fb99f07f
commit
d54f639633
8 changed files with 131 additions and 98 deletions
|
|
@ -4,6 +4,7 @@ import {ServerClass} from './ServerClass';
|
||||||
import {SendTable} from './SendTable';
|
import {SendTable} from './SendTable';
|
||||||
import {StringTable} from './StringTable';
|
import {StringTable} from './StringTable';
|
||||||
import {ParserState} from './ParserState';
|
import {ParserState} from './ParserState';
|
||||||
|
import {Vector} from './Vector';
|
||||||
|
|
||||||
export enum MessageType {
|
export enum MessageType {
|
||||||
Sigon = 1,
|
Sigon = 1,
|
||||||
|
|
@ -21,14 +22,18 @@ export interface BaseMessage {
|
||||||
rawData: BitStream;
|
rawData: BitStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SigonMessage extends BaseMessage {
|
|
||||||
type: MessageType.Sigon;
|
|
||||||
packets: Packet[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PacketMessage extends BaseMessage {
|
export interface PacketMessage extends BaseMessage {
|
||||||
type: MessageType.Packet;
|
type: MessageType.Packet;
|
||||||
packets: Packet[];
|
packets: Packet[];
|
||||||
|
viewOrigin: [Vector, Vector];
|
||||||
|
viewAngles: [Vector, Vector];
|
||||||
|
localViewAngles: [Vector, Vector];
|
||||||
|
sequenceIn: number;
|
||||||
|
sequenceOut: number;
|
||||||
|
flags: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SigonMessage extends PacketMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SyncTickMessage extends BaseMessage {
|
export interface SyncTickMessage extends BaseMessage {
|
||||||
|
|
@ -42,6 +47,7 @@ export interface ConsoleCmdMessage extends BaseMessage {
|
||||||
|
|
||||||
export interface UserCmdMessage extends BaseMessage {
|
export interface UserCmdMessage extends BaseMessage {
|
||||||
type: MessageType.UserCmd;
|
type: MessageType.UserCmd;
|
||||||
|
sequenceOut: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataTablesMessage extends BaseMessage {
|
export interface DataTablesMessage extends BaseMessage {
|
||||||
|
|
@ -69,6 +75,6 @@ export type Message = SigonMessage |
|
||||||
StringTablesMessage;
|
StringTablesMessage;
|
||||||
|
|
||||||
export interface MessageHandler<M extends Message> {
|
export interface MessageHandler<M extends Message> {
|
||||||
parseMessage: (stream: BitStream, tick: number, state: ParserState) => M;
|
parseMessage: (stream: BitStream, state: ParserState) => M;
|
||||||
encodeMessage: (message: M, stream: BitStream, state: ParserState) => void;
|
encodeMessage: (message: M, stream: BitStream, state: ParserState) => void;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {UserCmdHandler} from './Parser/Message/UserCmd';
|
||||||
import {Packet, PacketTypeId} from './Data/Packet';
|
import {Packet, PacketTypeId} from './Data/Packet';
|
||||||
import {Message, MessageHandler, MessageType, PacketMessage} from './Data/Message';
|
import {Message, MessageHandler, MessageType, PacketMessage} from './Data/Message';
|
||||||
import {ParserState} from './Data/ParserState';
|
import {ParserState} from './Data/ParserState';
|
||||||
|
import {SyncTickHandler} from './Parser/Message/SyncTick';
|
||||||
|
|
||||||
const messageHandlers: Map<MessageType, MessageHandler<Message>> = new Map<MessageType, MessageHandler<Message>>([
|
const messageHandlers: Map<MessageType, MessageHandler<Message>> = new Map<MessageType, MessageHandler<Message>>([
|
||||||
[MessageType.Sigon, PacketMessageHandler],
|
[MessageType.Sigon, PacketMessageHandler],
|
||||||
|
|
@ -16,6 +17,7 @@ const messageHandlers: Map<MessageType, MessageHandler<Message>> = new Map<Messa
|
||||||
[MessageType.UserCmd, UserCmdHandler],
|
[MessageType.UserCmd, UserCmdHandler],
|
||||||
[MessageType.DataTables, DataTableHandler],
|
[MessageType.DataTables, DataTableHandler],
|
||||||
[MessageType.StringTables, StringTableHandler],
|
[MessageType.StringTables, StringTableHandler],
|
||||||
|
[MessageType.SyncTick, SyncTickHandler]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export class Parser {
|
export class Parser {
|
||||||
|
|
@ -23,9 +25,6 @@ export class Parser {
|
||||||
public readonly parserState: ParserState;
|
public readonly parserState: ParserState;
|
||||||
private header: Header | null = null;
|
private header: Header | null = null;
|
||||||
|
|
||||||
public viewOrigin: number[][] = [[], []];
|
|
||||||
public viewAngles: number[][] = [[], []];
|
|
||||||
|
|
||||||
constructor(stream: BitStream, skipPackets: PacketTypeId[] = []) {
|
constructor(stream: BitStream, skipPackets: PacketTypeId[] = []) {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.parserState = new ParserState();
|
this.parserState = new ParserState();
|
||||||
|
|
@ -60,12 +59,12 @@ export class Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected parseMessage(data: BitStream, type: MessageType, tick: number, state: ParserState): Message {
|
protected parseMessage(data: BitStream, type: MessageType, state: ParserState): Message {
|
||||||
const handler = messageHandlers.get(type);
|
const handler = messageHandlers.get(type);
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
throw new Error(`No handler for message of type ${MessageType[type]}`);
|
throw new Error(`No handler for message of type ${MessageType[type]}`);
|
||||||
}
|
}
|
||||||
return handler.parseMessage(data, tick, state);
|
return handler.parseMessage(data, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected parseHeader(stream): Header {
|
protected parseHeader(stream): Header {
|
||||||
|
|
@ -98,43 +97,11 @@ export class Parser {
|
||||||
if (stream.bitsLeft < 8) {
|
if (stream.bitsLeft < 8) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const type: MessageType = stream.readBits(8);
|
const type: MessageType = stream.readUint8();
|
||||||
if (type === MessageType.Stop) {
|
if (type === MessageType.Stop) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const tick = stream.readInt32();
|
|
||||||
|
|
||||||
switch (type) {
|
return this.parseMessage(stream, type, state);
|
||||||
case MessageType.Sigon:
|
|
||||||
case MessageType.Packet:
|
|
||||||
this.stream.readInt32(); // flags
|
|
||||||
for (let j = 0; j < 2; j++) {
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
this.viewOrigin[j][i] = this.stream.readFloat32();
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
this.viewAngles[j][i] = this.stream.readFloat32();
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
this.stream.readInt32(); // local viewAngles
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.stream.readInt32(); // sequence in
|
|
||||||
this.stream.readInt32(); // sequence out
|
|
||||||
break;
|
|
||||||
case MessageType.UserCmd:
|
|
||||||
stream.byteIndex += 0x04; // unknown / outgoing sequence
|
|
||||||
break;
|
|
||||||
case MessageType.SyncTick:
|
|
||||||
return {
|
|
||||||
type: MessageType.SyncTick,
|
|
||||||
tick,
|
|
||||||
rawData: stream.readBitStream(0)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const length = stream.readInt32();
|
|
||||||
const buffer = stream.readBitStream(length * 8);
|
|
||||||
return this.parseMessage(buffer, type, tick, state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,17 @@ export class ConsoleCmd extends Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConsoleCmdHandler: MessageHandler<ConsoleCmdMessage> = {
|
export const ConsoleCmdHandler: MessageHandler<ConsoleCmdMessage> = {
|
||||||
parseMessage: (stream: BitStream, tick: number) => {
|
parseMessage: (stream: BitStream) => {
|
||||||
|
const tick = stream.readInt32();
|
||||||
|
|
||||||
|
const length = stream.readInt32();
|
||||||
|
const messageStream = stream.readBitStream(length * 8);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: MessageType.ConsoleCmd,
|
type: MessageType.ConsoleCmd,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream,
|
rawData: messageStream,
|
||||||
command: stream.readUTF8String()
|
command: messageStream.readUTF8String()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
encodeMessage: (message: ConsoleCmdMessage, stream: BitStream) => {
|
encodeMessage: (message: ConsoleCmdMessage, stream: BitStream) => {
|
||||||
|
|
|
||||||
|
|
@ -5,37 +5,42 @@ import {DataTablesMessage, MessageHandler, MessageType} from '../../Data/Message
|
||||||
import {BitStream} from 'bit-buffer';
|
import {BitStream} from 'bit-buffer';
|
||||||
|
|
||||||
export const DataTableHandler: MessageHandler<DataTablesMessage> = {
|
export const DataTableHandler: MessageHandler<DataTablesMessage> = {
|
||||||
parseMessage: (stream: BitStream, tick: number) => {
|
parseMessage: (stream: BitStream) => {
|
||||||
|
const tick = stream.readInt32();
|
||||||
|
|
||||||
|
const length = stream.readInt32();
|
||||||
|
const messageStream = stream.readBitStream(length * 8);
|
||||||
|
|
||||||
// https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/engine/dt_common_eng.cpp#L356
|
// https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/engine/dt_common_eng.cpp#L356
|
||||||
// https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/engine/dt_recv_eng.cpp#L310
|
// https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/engine/dt_recv_eng.cpp#L310
|
||||||
// https://github.com/PazerOP/DemoLib/blob/master/DemoLib/Commands/DemoDataTablesCommand.cs
|
// https://github.com/PazerOP/DemoLib/blob/master/DemoLib/Commands/DemoDataTablesCommand.cs
|
||||||
const tables: SendTable[] = [];
|
const tables: SendTable[] = [];
|
||||||
const tableMap: {[key: string]: SendTable} = {};
|
const tableMap: {[key: string]: SendTable} = {};
|
||||||
while (stream.readBoolean()) {
|
while (messageStream.readBoolean()) {
|
||||||
const needsDecoder = stream.readBoolean();
|
const needsDecoder = messageStream.readBoolean();
|
||||||
const tableName = stream.readASCIIString();
|
const tableName = messageStream.readASCIIString();
|
||||||
const numProps = stream.readBits(10);
|
const numProps = messageStream.readBits(10);
|
||||||
const table = new SendTable(tableName);
|
const table = new SendTable(tableName);
|
||||||
|
|
||||||
// get props metadata
|
// get props metadata
|
||||||
let arrayElementProp;
|
let arrayElementProp;
|
||||||
for (let i = 0; i < numProps; i++) {
|
for (let i = 0; i < numProps; i++) {
|
||||||
const propType = stream.readBits(5);
|
const propType = messageStream.readBits(5);
|
||||||
const propName = stream.readASCIIString();
|
const propName = messageStream.readASCIIString();
|
||||||
const nFlagsBits = 16; // might be 11 (old?), 13 (new?), 16(networked) or 17(??)
|
const nFlagsBits = 16; // might be 11 (old?), 13 (new?), 16(networked) or 17(??)
|
||||||
const flags = stream.readBits(nFlagsBits);
|
const flags = messageStream.readBits(nFlagsBits);
|
||||||
const prop = new SendPropDefinition(propType, propName, flags, tableName);
|
const prop = new SendPropDefinition(propType, propName, flags, tableName);
|
||||||
if (propType === SendPropType.DPT_DataTable) {
|
if (propType === SendPropType.DPT_DataTable) {
|
||||||
prop.excludeDTName = stream.readASCIIString();
|
prop.excludeDTName = messageStream.readASCIIString();
|
||||||
} else {
|
} else {
|
||||||
if (prop.isExcludeProp()) {
|
if (prop.isExcludeProp()) {
|
||||||
prop.excludeDTName = stream.readASCIIString();
|
prop.excludeDTName = messageStream.readASCIIString();
|
||||||
} else if (prop.type === SendPropType.DPT_Array) {
|
} else if (prop.type === SendPropType.DPT_Array) {
|
||||||
prop.numElements = stream.readBits(10);
|
prop.numElements = messageStream.readBits(10);
|
||||||
} else {
|
} else {
|
||||||
prop.lowValue = stream.readFloat32();
|
prop.lowValue = messageStream.readFloat32();
|
||||||
prop.highValue = stream.readFloat32();
|
prop.highValue = messageStream.readFloat32();
|
||||||
prop.bitCount = stream.readBits(7);
|
prop.bitCount = messageStream.readBits(7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,23 +90,23 @@ export const DataTableHandler: MessageHandler<DataTablesMessage> = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const numServerClasses = stream.readUint16(); // short
|
const numServerClasses = messageStream.readUint16(); // short
|
||||||
const serverClasses: ServerClass[] = [];
|
const serverClasses: ServerClass[] = [];
|
||||||
if (numServerClasses <= 0) {
|
if (numServerClasses <= 0) {
|
||||||
throw new Error('expected one or more serverclasses');
|
throw new Error('expected one or more serverclasses');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < numServerClasses; i++) {
|
for (let i = 0; i < numServerClasses; i++) {
|
||||||
const classId = stream.readUint16();
|
const classId = messageStream.readUint16();
|
||||||
if (classId > numServerClasses) {
|
if (classId > numServerClasses) {
|
||||||
throw new Error('invalid class id');
|
throw new Error('invalid class id');
|
||||||
}
|
}
|
||||||
const className = stream.readASCIIString();
|
const className = messageStream.readASCIIString();
|
||||||
const dataTable = stream.readASCIIString();
|
const dataTable = messageStream.readASCIIString();
|
||||||
serverClasses.push(new ServerClass(classId, className, dataTable));
|
serverClasses.push(new ServerClass(classId, className, dataTable));
|
||||||
}
|
}
|
||||||
|
|
||||||
const bitsLeft = (this.length * 8) - stream.index;
|
const bitsLeft = (this.length * 8) - messageStream.index;
|
||||||
if (bitsLeft > 7 || bitsLeft < 0) {
|
if (bitsLeft > 7 || bitsLeft < 0) {
|
||||||
throw new Error('unexpected remaining data in datatable (' + bitsLeft + ' bits)');
|
throw new Error('unexpected remaining data in datatable (' + bitsLeft + ' bits)');
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +114,7 @@ export const DataTableHandler: MessageHandler<DataTablesMessage> = {
|
||||||
return {
|
return {
|
||||||
type: MessageType.DataTables,
|
type: MessageType.DataTables,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream,
|
rawData: messageStream,
|
||||||
tables,
|
tables,
|
||||||
serverClasses,
|
serverClasses,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import {Packet as IPacket, PacketTypeId} from '../../Data/Packet';
|
||||||
import {MessageHandler, MessageType, PacketMessage} from '../../Data/Message';
|
import {MessageHandler, MessageType, PacketMessage} from '../../Data/Message';
|
||||||
import {BitStream} from 'bit-buffer';
|
import {BitStream} from 'bit-buffer';
|
||||||
import {ParserState} from '../../Data/ParserState';
|
import {ParserState} from '../../Data/ParserState';
|
||||||
|
import {Vector} from '../../Data/Vector';
|
||||||
|
|
||||||
type PacketHandlerMap = Map<PacketTypeId, PacketHandler<IPacket>>;
|
type PacketHandlerMap = Map<PacketTypeId, PacketHandler<IPacket>>;
|
||||||
|
|
||||||
|
|
@ -82,16 +83,34 @@ const handlers: PacketHandlerMap = new Map<PacketTypeId, PacketHandler<IPacket>>
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const PacketMessageHandler: MessageHandler<PacketMessage> = {
|
export const PacketMessageHandler: MessageHandler<PacketMessage> = {
|
||||||
parseMessage: (stream: BitStream, tick: number, state: ParserState) => {
|
parseMessage: (stream: BitStream, state: ParserState) => {
|
||||||
|
const tick = stream.readInt32();
|
||||||
|
const flags = stream.readInt32();
|
||||||
|
|
||||||
|
const viewOrigin: [Vector, Vector] = [new Vector(0, 0, 0), new Vector(0, 0, 0)];
|
||||||
|
const viewAngles: [Vector, Vector] = [new Vector(0, 0, 0), new Vector(0, 0, 0)];
|
||||||
|
const localViewAngles: [Vector, Vector] = [new Vector(0, 0, 0), new Vector(0, 0, 0)];
|
||||||
|
|
||||||
|
for (let j = 0; j < 2; j++) {
|
||||||
|
viewOrigin[j] = new Vector(stream.readFloat32(), stream.readFloat32(), stream.readFloat32());
|
||||||
|
viewAngles[j] = new Vector(stream.readFloat32(), stream.readFloat32(), stream.readFloat32());
|
||||||
|
localViewAngles[j] = new Vector(stream.readFloat32(), stream.readFloat32(), stream.readFloat32());
|
||||||
|
}
|
||||||
|
const sequenceIn = stream.readInt32();
|
||||||
|
const sequenceOut = stream.readInt32();
|
||||||
|
|
||||||
|
const length = stream.readInt32();
|
||||||
|
const messageStream = stream.readBitStream(length * 8);
|
||||||
|
|
||||||
const packets: IPacket[] = [];
|
const packets: IPacket[] = [];
|
||||||
let lastPacketType = 0;
|
let lastPacketType = 0;
|
||||||
while (stream.bitsLeft > 6) { // last 6 bits for NOOP
|
while (messageStream.bitsLeft > 6) { // last 6 bits for NOOP
|
||||||
const type = stream.readBits(6) as PacketTypeId;
|
const type = messageStream.readBits(6) as PacketTypeId;
|
||||||
if (type !== 0) {
|
if (type !== 0) {
|
||||||
const parser = handlers.get(type);
|
const parser = handlers.get(type);
|
||||||
if (parser) {
|
if (parser) {
|
||||||
const skip = state.skippedPackets.indexOf(type) !== -1;
|
const skip = state.skippedPackets.indexOf(type) !== -1;
|
||||||
const packet = parser.parser(stream, state, skip);
|
const packet = parser.parser(messageStream, state, skip);
|
||||||
packets.push(packet);
|
packets.push(packet);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unknown packet type ${type} just parsed a ${PacketTypeId[lastPacketType]}`);
|
throw new Error(`Unknown packet type ${type} just parsed a ${PacketTypeId[lastPacketType]}`);
|
||||||
|
|
@ -102,8 +121,14 @@ export const PacketMessageHandler: MessageHandler<PacketMessage> = {
|
||||||
return {
|
return {
|
||||||
type: MessageType.Packet,
|
type: MessageType.Packet,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream,
|
rawData: messageStream,
|
||||||
packets
|
packets,
|
||||||
|
flags,
|
||||||
|
viewOrigin,
|
||||||
|
viewAngles,
|
||||||
|
localViewAngles,
|
||||||
|
sequenceIn,
|
||||||
|
sequenceOut
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
encodeMessage: (message, stream) => {
|
encodeMessage: (message, stream) => {
|
||||||
|
|
|
||||||
|
|
@ -3,47 +3,47 @@ import {MessageHandler, MessageType, StringTablesMessage} from '../../Data/Messa
|
||||||
import {BitStream} from 'bit-buffer';
|
import {BitStream} from 'bit-buffer';
|
||||||
|
|
||||||
export const StringTableHandler: MessageHandler<StringTablesMessage> = {
|
export const StringTableHandler: MessageHandler<StringTablesMessage> = {
|
||||||
parseMessage: (stream: BitStream, tick: number) => {
|
parseMessage: (stream: BitStream) => {
|
||||||
// we get the tables from the packets
|
const tick = stream.readInt32();
|
||||||
// return [{
|
|
||||||
// packetType: 'stringTable',
|
const length = stream.readInt32();
|
||||||
// tables: []
|
const messageStream = stream.readBitStream(length * 8);
|
||||||
// }];
|
|
||||||
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/ST/StringTableParser.cs
|
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/ST/StringTableParser.cs
|
||||||
const tableCount = stream.readUint8();
|
const tableCount = messageStream.readUint8();
|
||||||
const tables: StringTableObject[] = [];
|
const tables: StringTableObject[] = [];
|
||||||
let extraDataLength;
|
let extraDataLength;
|
||||||
for (let i = 0; i < tableCount; i++) {
|
for (let i = 0; i < tableCount; i++) {
|
||||||
const entries: StringTableEntry[] = [];
|
const entries: StringTableEntry[] = [];
|
||||||
const tableName = stream.readASCIIString();
|
const tableName = messageStream.readASCIIString();
|
||||||
const entryCount = stream.readUint16();
|
const entryCount = messageStream.readUint16();
|
||||||
for (let j = 0; j < entryCount; j++) {
|
for (let j = 0; j < entryCount; j++) {
|
||||||
let entry: StringTableEntry;
|
let entry: StringTableEntry;
|
||||||
try {
|
try {
|
||||||
entry = {
|
entry = {
|
||||||
text: stream.readUTF8String(),
|
text: messageStream.readUTF8String(),
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return {
|
||||||
type: MessageType.StringTables,
|
type: MessageType.StringTables,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream,
|
rawData: messageStream,
|
||||||
tables,
|
tables,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (stream.readBoolean()) {
|
if (messageStream.readBoolean()) {
|
||||||
extraDataLength = stream.readUint16();
|
extraDataLength = messageStream.readUint16();
|
||||||
if ((extraDataLength * 8) > stream.bitsLeft) {
|
if ((extraDataLength * 8) > messageStream.bitsLeft) {
|
||||||
// extradata to long, can't continue parsing the tables
|
// extradata to long, can't continue parsing the tables
|
||||||
// seems to happen in POV demos after the MyM update
|
// seems to happen in POV demos after the MyM update
|
||||||
return {
|
return {
|
||||||
type: MessageType.StringTables,
|
type: MessageType.StringTables,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream,
|
rawData: messageStream,
|
||||||
tables,
|
tables,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
entry.extraData = stream.readBitStream(extraDataLength * 8);
|
entry.extraData = messageStream.readBitStream(extraDataLength * 8);
|
||||||
}
|
}
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
}
|
}
|
||||||
|
|
@ -53,19 +53,19 @@ export const StringTableHandler: MessageHandler<StringTablesMessage> = {
|
||||||
maxEntries: entryCount,
|
maxEntries: entryCount,
|
||||||
};
|
};
|
||||||
tables.push(table);
|
tables.push(table);
|
||||||
if (stream.readBits(1)) {
|
if (messageStream.readBits(1)) {
|
||||||
stream.readASCIIString();
|
messageStream.readASCIIString();
|
||||||
if (stream.readBits(1)) {
|
if (messageStream.readBits(1)) {
|
||||||
// throw 'more extra data not implemented';
|
// throw 'more extra data not implemented';
|
||||||
extraDataLength = stream.readBits(16);
|
extraDataLength = messageStream.readBits(16);
|
||||||
stream.readBits(extraDataLength);
|
messageStream.readBits(extraDataLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: MessageType.StringTables,
|
type: MessageType.StringTables,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream,
|
rawData: messageStream,
|
||||||
tables,
|
tables,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
||||||
17
src/Parser/Message/SyncTick.ts
Normal file
17
src/Parser/Message/SyncTick.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import {MessageHandler, MessageType, SyncTickMessage} from '../../Data/Message';
|
||||||
|
import {BitStream} from 'bit-buffer';
|
||||||
|
|
||||||
|
export const SyncTickHandler: MessageHandler<SyncTickMessage> = {
|
||||||
|
parseMessage: (stream: BitStream) => {
|
||||||
|
const tick = stream.readInt32();
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: MessageType.SyncTick,
|
||||||
|
tick,
|
||||||
|
rawData: stream.readBitStream(0)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
encodeMessage: (message, stream) => {
|
||||||
|
throw new Error('not implemented');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -2,11 +2,19 @@ import {MessageHandler, MessageType, UserCmdMessage} from '../../Data/Message';
|
||||||
import {BitStream} from 'bit-buffer';
|
import {BitStream} from 'bit-buffer';
|
||||||
|
|
||||||
export const UserCmdHandler: MessageHandler<UserCmdMessage> = {
|
export const UserCmdHandler: MessageHandler<UserCmdMessage> = {
|
||||||
parseMessage: (stream: BitStream, tick: number) => {
|
parseMessage: (stream: BitStream) => {
|
||||||
|
const tick = stream.readInt32();
|
||||||
|
|
||||||
|
const sequenceOut = stream.readInt32();
|
||||||
|
|
||||||
|
const length = stream.readInt32();
|
||||||
|
const messageStream = stream.readBitStream(length * 8);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: MessageType.UserCmd,
|
type: MessageType.UserCmd,
|
||||||
tick,
|
tick,
|
||||||
rawData: stream
|
rawData: messageStream,
|
||||||
|
sequenceOut
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
encodeMessage: (message, stream) => {
|
encodeMessage: (message, stream) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue