mirror of
https://github.com/demostf/demo.js
synced 2026-06-04 00:54:14 +02:00
dont mutate the match state when parsing datatables
This commit is contained in:
parent
c4969d23ff
commit
fc6d758a31
5 changed files with 55 additions and 26 deletions
|
|
@ -14,6 +14,7 @@ import {handleSayText2} from "../PacketHandler/SayText2";
|
||||||
import {handleGameEvent} from "../PacketHandler/GameEvent";
|
import {handleGameEvent} from "../PacketHandler/GameEvent";
|
||||||
import {handlePacketEntities} from "../PacketHandler/PacketEntities";
|
import {handlePacketEntities} from "../PacketHandler/PacketEntities";
|
||||||
import {handleGameEventList} from "../PacketHandler/GameEventList";
|
import {handleGameEventList} from "../PacketHandler/GameEventList";
|
||||||
|
import {handleDataTable} from "../PacketHandler/DataTable";
|
||||||
|
|
||||||
export class Match {
|
export class Match {
|
||||||
tick: number;
|
tick: number;
|
||||||
|
|
@ -125,6 +126,9 @@ export class Match {
|
||||||
case 'sayText2':
|
case 'sayText2':
|
||||||
handleSayText2(packet, this);
|
handleSayText2(packet, this);
|
||||||
break;
|
break;
|
||||||
|
case 'dataTable':
|
||||||
|
handleDataTable(packet, this);
|
||||||
|
break;
|
||||||
case 'stringTable':
|
case 'stringTable':
|
||||||
handleStringTable(packet, this);
|
handleStringTable(packet, this);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,20 @@ import {StringTable} from "./StringTable";
|
||||||
import {Vector} from "./Vector";
|
import {Vector} from "./Vector";
|
||||||
import {GameEvent, GameEventDefinitionMap} from "./GameEvent";
|
import {GameEvent, GameEventDefinitionMap} from "./GameEvent";
|
||||||
import {PacketEntity} from "./PacketEntity";
|
import {PacketEntity} from "./PacketEntity";
|
||||||
|
import {SendTable} from "./SendTable";
|
||||||
|
import {ServerClass} from "./ServerClass";
|
||||||
|
|
||||||
export interface StringTablePacket {
|
export interface StringTablePacket {
|
||||||
packetType: 'stringTable';
|
packetType: 'stringTable';
|
||||||
tables: StringTable[];
|
tables: StringTable[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DataTablePacket {
|
||||||
|
packetType: 'dataTable';
|
||||||
|
tables: SendTable[];
|
||||||
|
serverClasses: ServerClass[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface BSPDecalPacket {
|
export interface BSPDecalPacket {
|
||||||
packetType: 'bspDecal';
|
packetType: 'bspDecal';
|
||||||
position: Vector;
|
position: Vector;
|
||||||
|
|
@ -92,6 +100,7 @@ export type UserMessagePacket = SayText2Packet | TextMessagePacket | UnknownUser
|
||||||
|
|
||||||
export type Packet = BSPDecalPacket |
|
export type Packet = BSPDecalPacket |
|
||||||
StringTablePacket |
|
StringTablePacket |
|
||||||
|
DataTablePacket |
|
||||||
ClassInfoPacket |
|
ClassInfoPacket |
|
||||||
EntityMessagePacket |
|
EntityMessagePacket |
|
||||||
GameEventPacket |
|
GameEventPacket |
|
||||||
|
|
|
||||||
7
src/PacketHandler/DataTable.ts
Normal file
7
src/PacketHandler/DataTable.ts
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -2,29 +2,30 @@ import {SendTable} from '../../Data/SendTable';
|
||||||
import {SendPropDefinition, SendPropFlag, SendPropType} from '../../Data/SendPropDefinition';
|
import {SendPropDefinition, SendPropFlag, SendPropType} from '../../Data/SendPropDefinition';
|
||||||
import {ServerClass} from '../../Data/ServerClass';
|
import {ServerClass} from '../../Data/ServerClass';
|
||||||
import {Parser} from './Parser';
|
import {Parser} from './Parser';
|
||||||
import {BitStream} from "bit-buffer";
|
import {DataTablePacket} from "../../Data/Packet";
|
||||||
|
|
||||||
export class DataTable extends Parser {
|
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_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
|
||||||
let tables:SendTable[] = [];
|
let tables: SendTable[] = [];
|
||||||
let i, j;
|
let i, j;
|
||||||
|
const tableMap: {[key: string]: SendTable} = {};
|
||||||
while (this.stream.readBoolean()) {
|
while (this.stream.readBoolean()) {
|
||||||
const needsDecoder = this.stream.readBoolean();
|
const needsDecoder = this.stream.readBoolean();
|
||||||
const tableName = this.stream.readASCIIString();
|
const tableName = this.stream.readASCIIString();
|
||||||
const numProps = this.stream.readBits(10);
|
const numProps = this.stream.readBits(10);
|
||||||
const table = new SendTable(tableName);
|
const table = new SendTable(tableName);
|
||||||
|
|
||||||
// get props metadata
|
// get props metadata
|
||||||
let arrayElementProp;
|
let arrayElementProp;
|
||||||
for (i = 0; i < numProps; i++) {
|
for (i = 0; i < numProps; i++) {
|
||||||
const propType = this.stream.readBits(5);
|
const propType = this.stream.readBits(5);
|
||||||
const propName = this.stream.readASCIIString();
|
const propName = this.stream.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 = this.stream.readBits(nFlagsBits);
|
const flags = this.stream.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 = this.stream.readASCIIString();
|
prop.excludeDTName = this.stream.readASCIIString();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -33,9 +34,9 @@ export class DataTable extends Parser {
|
||||||
} else if (prop.type === SendPropType.DPT_Array) {
|
} else if (prop.type === SendPropType.DPT_Array) {
|
||||||
prop.numElements = this.stream.readBits(10);
|
prop.numElements = this.stream.readBits(10);
|
||||||
} else {
|
} else {
|
||||||
prop.lowValue = this.stream.readFloat32();
|
prop.lowValue = this.stream.readFloat32();
|
||||||
prop.highValue = 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";
|
throw "expected prop of type array";
|
||||||
}
|
}
|
||||||
prop.arrayProperty = arrayElementProp;
|
prop.arrayProperty = arrayElementProp;
|
||||||
arrayElementProp = null;
|
arrayElementProp = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop.hasFlag(SendPropFlag.SPROP_INSIDEARRAY)) {
|
if (prop.hasFlag(SendPropFlag.SPROP_INSIDEARRAY)) {
|
||||||
|
|
@ -70,32 +71,35 @@ export class DataTable extends Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tables.push(table);
|
tables.push(table);
|
||||||
|
tableMap[table.name] = table;
|
||||||
}
|
}
|
||||||
this.match.sendTables = tables;
|
|
||||||
|
|
||||||
// link referenced tables
|
// link referenced tables
|
||||||
for (i = 0; i < tables.length; i++) {
|
for (const table of tables) {
|
||||||
for (j = 0; j < tables[i].props.length; j++) {
|
for (const prop of table.props) {
|
||||||
if (tables[i].props[j].type === SendPropType.DPT_DataTable) {
|
if (prop.type === SendPropType.DPT_DataTable) {
|
||||||
tables[i].props[j].table = this.match.getSendTable(tables[i].props[j].excludeDTName);
|
if (prop.excludeDTName) {
|
||||||
tables[i].props[j].excludeDTName = null;
|
prop.table = tableMap[prop.excludeDTName];
|
||||||
|
prop.excludeDTName = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const serverClasses = this.stream.readUint16(); // short
|
const numServerClasses = this.stream.readUint16(); // short
|
||||||
if (serverClasses <= 0) {
|
const serverClasses: ServerClass[] = [];
|
||||||
|
if (numServerClasses <= 0) {
|
||||||
throw "expected one or more serverclasses";
|
throw "expected one or more serverclasses";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < serverClasses; i++) {
|
for (i = 0; i < numServerClasses; i++) {
|
||||||
const classId = this.stream.readUint16();
|
const classId = this.stream.readUint16();
|
||||||
if (classId > serverClasses) {
|
if (classId > numServerClasses) {
|
||||||
throw "invalid class id";
|
throw "invalid class id";
|
||||||
}
|
}
|
||||||
const className = this.stream.readASCIIString();
|
const className = this.stream.readASCIIString();
|
||||||
const dataTable = 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;
|
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)";
|
throw "unexpected remaining data in datatable (" + bitsLeft + " bits)";
|
||||||
}
|
}
|
||||||
|
|
||||||
return tables;
|
|
||||||
|
return [{
|
||||||
|
packetType: 'dataTable',
|
||||||
|
tables: tables,
|
||||||
|
serverClasses: serverClasses
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,5 @@ export abstract class Parser {
|
||||||
this.match = match;
|
this.match = match;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract parse():Packet[]|string|SendTable[];
|
abstract parse():Packet[]|string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue