1
0
Fork 0
mirror of https://github.com/demostf/demo.js synced 2026-06-03 16:44:12 +02:00

dont mutate the match state when parsing datatables

This commit is contained in:
Robin Appelman 2017-02-14 22:26:21 +01:00
commit fc6d758a31
5 changed files with 55 additions and 26 deletions

View file

@ -14,6 +14,7 @@ import {handleSayText2} from "../PacketHandler/SayText2";
import {handleGameEvent} from "../PacketHandler/GameEvent";
import {handlePacketEntities} from "../PacketHandler/PacketEntities";
import {handleGameEventList} from "../PacketHandler/GameEventList";
import {handleDataTable} from "../PacketHandler/DataTable";
export class Match {
tick: number;
@ -125,6 +126,9 @@ export class Match {
case 'sayText2':
handleSayText2(packet, this);
break;
case 'dataTable':
handleDataTable(packet, this);
break;
case 'stringTable':
handleStringTable(packet, this);
break;

View file

@ -2,12 +2,20 @@ import {StringTable} from "./StringTable";
import {Vector} from "./Vector";
import {GameEvent, GameEventDefinitionMap} from "./GameEvent";
import {PacketEntity} from "./PacketEntity";
import {SendTable} from "./SendTable";
import {ServerClass} from "./ServerClass";
export interface StringTablePacket {
packetType: 'stringTable';
tables: StringTable[];
}
export interface DataTablePacket {
packetType: 'dataTable';
tables: SendTable[];
serverClasses: ServerClass[];
}
export interface BSPDecalPacket {
packetType: 'bspDecal';
position: Vector;
@ -92,6 +100,7 @@ export type UserMessagePacket = SayText2Packet | TextMessagePacket | UnknownUser
export type Packet = BSPDecalPacket |
StringTablePacket |
DataTablePacket |
ClassInfoPacket |
EntityMessagePacket |
GameEventPacket |

View file

@ -0,0 +1,7 @@
import {DataTablePacket} from "../Data/Packet";
import {Match} from "../Data/Match";
export function handleDataTable(packet: DataTablePacket, match: Match) {
match.sendTables = packet.tables;
match.serverClasses = packet.serverClasses;
}

View file

@ -2,29 +2,30 @@ import {SendTable} from '../../Data/SendTable';
import {SendPropDefinition, SendPropFlag, SendPropType} from '../../Data/SendPropDefinition';
import {ServerClass} from '../../Data/ServerClass';
import {Parser} from './Parser';
import {BitStream} from "bit-buffer";
import {DataTablePacket} from "../../Data/Packet";
export class DataTable extends Parser {
parse() {
parse(): DataTablePacket[] {
// 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
let tables:SendTable[] = [];
let tables: SendTable[] = [];
let i, j;
const tableMap: {[key: string]: SendTable} = {};
while (this.stream.readBoolean()) {
const needsDecoder = this.stream.readBoolean();
const tableName = this.stream.readASCIIString();
const numProps = this.stream.readBits(10);
const table = new SendTable(tableName);
const tableName = this.stream.readASCIIString();
const numProps = this.stream.readBits(10);
const table = new SendTable(tableName);
// get props metadata
let arrayElementProp;
for (i = 0; i < numProps; i++) {
const propType = this.stream.readBits(5);
const propName = this.stream.readASCIIString();
const propType = this.stream.readBits(5);
const propName = this.stream.readASCIIString();
const nFlagsBits = 16; // might be 11 (old?), 13 (new?), 16(networked) or 17(??)
const flags = this.stream.readBits(nFlagsBits);
const prop = new SendPropDefinition(propType, propName, flags, tableName);
const flags = this.stream.readBits(nFlagsBits);
const prop = new SendPropDefinition(propType, propName, flags, tableName);
if (propType === SendPropType.DPT_DataTable) {
prop.excludeDTName = this.stream.readASCIIString();
} else {
@ -33,9 +34,9 @@ export class DataTable extends Parser {
} else if (prop.type === SendPropType.DPT_Array) {
prop.numElements = this.stream.readBits(10);
} else {
prop.lowValue = this.stream.readFloat32();
prop.lowValue = this.stream.readFloat32();
prop.highValue = this.stream.readFloat32();
prop.bitCount = this.stream.readBits(7);
prop.bitCount = this.stream.readBits(7);
}
}
@ -54,7 +55,7 @@ export class DataTable extends Parser {
throw "expected prop of type array";
}
prop.arrayProperty = arrayElementProp;
arrayElementProp = null;
arrayElementProp = null;
}
if (prop.hasFlag(SendPropFlag.SPROP_INSIDEARRAY)) {
@ -70,32 +71,35 @@ export class DataTable extends Parser {
}
}
tables.push(table);
tableMap[table.name] = table;
}
this.match.sendTables = tables;
// link referenced tables
for (i = 0; i < tables.length; i++) {
for (j = 0; j < tables[i].props.length; j++) {
if (tables[i].props[j].type === SendPropType.DPT_DataTable) {
tables[i].props[j].table = this.match.getSendTable(tables[i].props[j].excludeDTName);
tables[i].props[j].excludeDTName = null;
for (const table of tables) {
for (const prop of table.props) {
if (prop.type === SendPropType.DPT_DataTable) {
if (prop.excludeDTName) {
prop.table = tableMap[prop.excludeDTName];
prop.excludeDTName = null;
}
}
}
}
const serverClasses = this.stream.readUint16(); // short
if (serverClasses <= 0) {
const numServerClasses = this.stream.readUint16(); // short
const serverClasses: ServerClass[] = [];
if (numServerClasses <= 0) {
throw "expected one or more serverclasses";
}
for (i = 0; i < serverClasses; i++) {
for (i = 0; i < numServerClasses; i++) {
const classId = this.stream.readUint16();
if (classId > serverClasses) {
if (classId > numServerClasses) {
throw "invalid class id";
}
const className = this.stream.readASCIIString();
const dataTable = this.stream.readASCIIString();
this.match.serverClasses.push(new ServerClass(classId, className, dataTable));
serverClasses.push(new ServerClass(classId, className, dataTable));
}
const bitsLeft = (this.length * 8) - this.stream.index;
@ -103,6 +107,11 @@ export class DataTable extends Parser {
throw "unexpected remaining data in datatable (" + bitsLeft + " bits)";
}
return tables;
return [{
packetType: 'dataTable',
tables: tables,
serverClasses: serverClasses
}];
}
}

View file

@ -18,5 +18,5 @@ export abstract class Parser {
this.match = match;
}
abstract parse():Packet[]|string|SendTable[];
abstract parse():Packet[]|string;
}