1
0
Fork 0
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:
Robin Appelman 2017-09-24 15:27:02 +02:00
commit d54f639633
8 changed files with 131 additions and 98 deletions

View file

@ -13,12 +13,17 @@ export class ConsoleCmd extends Parser {
}
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 {
type: MessageType.ConsoleCmd,
tick,
rawData: stream,
command: stream.readUTF8String()
rawData: messageStream,
command: messageStream.readUTF8String()
};
},
encodeMessage: (message: ConsoleCmdMessage, stream: BitStream) => {

View file

@ -5,37 +5,42 @@ import {DataTablesMessage, MessageHandler, MessageType} from '../../Data/Message
import {BitStream} from 'bit-buffer';
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_recv_eng.cpp#L310
// https://github.com/PazerOP/DemoLib/blob/master/DemoLib/Commands/DemoDataTablesCommand.cs
const tables: SendTable[] = [];
const tableMap: {[key: string]: SendTable} = {};
while (stream.readBoolean()) {
const needsDecoder = stream.readBoolean();
const tableName = stream.readASCIIString();
const numProps = stream.readBits(10);
while (messageStream.readBoolean()) {
const needsDecoder = messageStream.readBoolean();
const tableName = messageStream.readASCIIString();
const numProps = messageStream.readBits(10);
const table = new SendTable(tableName);
// get props metadata
let arrayElementProp;
for (let i = 0; i < numProps; i++) {
const propType = stream.readBits(5);
const propName = stream.readASCIIString();
const propType = messageStream.readBits(5);
const propName = messageStream.readASCIIString();
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);
if (propType === SendPropType.DPT_DataTable) {
prop.excludeDTName = stream.readASCIIString();
prop.excludeDTName = messageStream.readASCIIString();
} else {
if (prop.isExcludeProp()) {
prop.excludeDTName = stream.readASCIIString();
prop.excludeDTName = messageStream.readASCIIString();
} else if (prop.type === SendPropType.DPT_Array) {
prop.numElements = stream.readBits(10);
prop.numElements = messageStream.readBits(10);
} else {
prop.lowValue = stream.readFloat32();
prop.highValue = stream.readFloat32();
prop.bitCount = stream.readBits(7);
prop.lowValue = messageStream.readFloat32();
prop.highValue = messageStream.readFloat32();
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[] = [];
if (numServerClasses <= 0) {
throw new Error('expected one or more serverclasses');
}
for (let i = 0; i < numServerClasses; i++) {
const classId = stream.readUint16();
const classId = messageStream.readUint16();
if (classId > numServerClasses) {
throw new Error('invalid class id');
}
const className = stream.readASCIIString();
const dataTable = stream.readASCIIString();
const className = messageStream.readASCIIString();
const dataTable = messageStream.readASCIIString();
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) {
throw new Error('unexpected remaining data in datatable (' + bitsLeft + ' bits)');
}
@ -109,7 +114,7 @@ export const DataTableHandler: MessageHandler<DataTablesMessage> = {
return {
type: MessageType.DataTables,
tick,
rawData: stream,
rawData: messageStream,
tables,
serverClasses,
};

View file

@ -18,6 +18,7 @@ import {Packet as IPacket, PacketTypeId} from '../../Data/Packet';
import {MessageHandler, MessageType, PacketMessage} from '../../Data/Message';
import {BitStream} from 'bit-buffer';
import {ParserState} from '../../Data/ParserState';
import {Vector} from '../../Data/Vector';
type PacketHandlerMap = Map<PacketTypeId, PacketHandler<IPacket>>;
@ -82,16 +83,34 @@ const handlers: PacketHandlerMap = new Map<PacketTypeId, PacketHandler<IPacket>>
]);
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[] = [];
let lastPacketType = 0;
while (stream.bitsLeft > 6) { // last 6 bits for NOOP
const type = stream.readBits(6) as PacketTypeId;
while (messageStream.bitsLeft > 6) { // last 6 bits for NOOP
const type = messageStream.readBits(6) as PacketTypeId;
if (type !== 0) {
const parser = handlers.get(type);
if (parser) {
const skip = state.skippedPackets.indexOf(type) !== -1;
const packet = parser.parser(stream, state, skip);
const packet = parser.parser(messageStream, state, skip);
packets.push(packet);
} else {
throw new Error(`Unknown packet type ${type} just parsed a ${PacketTypeId[lastPacketType]}`);
@ -102,8 +121,14 @@ export const PacketMessageHandler: MessageHandler<PacketMessage> = {
return {
type: MessageType.Packet,
tick,
rawData: stream,
packets
rawData: messageStream,
packets,
flags,
viewOrigin,
viewAngles,
localViewAngles,
sequenceIn,
sequenceOut
};
},
encodeMessage: (message, stream) => {

View file

@ -3,47 +3,47 @@ import {MessageHandler, MessageType, StringTablesMessage} from '../../Data/Messa
import {BitStream} from 'bit-buffer';
export const StringTableHandler: MessageHandler<StringTablesMessage> = {
parseMessage: (stream: BitStream, tick: number) => {
// we get the tables from the packets
// return [{
// packetType: 'stringTable',
// tables: []
// }];
parseMessage: (stream: BitStream) => {
const tick = stream.readInt32();
const length = stream.readInt32();
const messageStream = stream.readBitStream(length * 8);
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/ST/StringTableParser.cs
const tableCount = stream.readUint8();
const tableCount = messageStream.readUint8();
const tables: StringTableObject[] = [];
let extraDataLength;
for (let i = 0; i < tableCount; i++) {
const entries: StringTableEntry[] = [];
const tableName = stream.readASCIIString();
const entryCount = stream.readUint16();
const tableName = messageStream.readASCIIString();
const entryCount = messageStream.readUint16();
for (let j = 0; j < entryCount; j++) {
let entry: StringTableEntry;
try {
entry = {
text: stream.readUTF8String(),
text: messageStream.readUTF8String(),
};
} catch (e) {
return {
type: MessageType.StringTables,
tick,
rawData: stream,
rawData: messageStream,
tables,
};
}
if (stream.readBoolean()) {
extraDataLength = stream.readUint16();
if ((extraDataLength * 8) > stream.bitsLeft) {
if (messageStream.readBoolean()) {
extraDataLength = messageStream.readUint16();
if ((extraDataLength * 8) > messageStream.bitsLeft) {
// extradata to long, can't continue parsing the tables
// seems to happen in POV demos after the MyM update
return {
type: MessageType.StringTables,
tick,
rawData: stream,
rawData: messageStream,
tables,
};
}
entry.extraData = stream.readBitStream(extraDataLength * 8);
entry.extraData = messageStream.readBitStream(extraDataLength * 8);
}
entries.push(entry);
}
@ -53,19 +53,19 @@ export const StringTableHandler: MessageHandler<StringTablesMessage> = {
maxEntries: entryCount,
};
tables.push(table);
if (stream.readBits(1)) {
stream.readASCIIString();
if (stream.readBits(1)) {
if (messageStream.readBits(1)) {
messageStream.readASCIIString();
if (messageStream.readBits(1)) {
// throw 'more extra data not implemented';
extraDataLength = stream.readBits(16);
stream.readBits(extraDataLength);
extraDataLength = messageStream.readBits(16);
messageStream.readBits(extraDataLength);
}
}
}
return {
type: MessageType.StringTables,
tick,
rawData: stream,
rawData: messageStream,
tables,
};
},

View 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');
}
};

View file

@ -2,11 +2,19 @@ import {MessageHandler, MessageType, UserCmdMessage} from '../../Data/Message';
import {BitStream} from 'bit-buffer';
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 {
type: MessageType.UserCmd,
tick,
rawData: stream
rawData: messageStream,
sequenceOut
};
},
encodeMessage: (message, stream) => {