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:
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 {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;
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
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 {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
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,5 @@ export abstract class Parser {
|
|||
this.match = match;
|
||||
}
|
||||
|
||||
abstract parse():Packet[]|string|SendTable[];
|
||||
abstract parse():Packet[]|string;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue