1
0
Fork 0
mirror of https://github.com/demostf/demo.js synced 2026-06-04 00:54:14 +02:00

use map for entity classes

This commit is contained in:
Robin Appelman 2017-09-02 15:42:38 +02:00
commit d5173b4548
4 changed files with 32 additions and 34 deletions

View file

@ -31,7 +31,7 @@ export class Match {
public eventDefinitions: Map<number, GameEventDefinition>; public eventDefinitions: Map<number, GameEventDefinition>;
public world: World; public world: World;
public playerEntityMap: Map<EntityId, Player>; public playerEntityMap: Map<EntityId, Player>;
public entityClasses: {[entityId: string]: ServerClass}; public entityClasses: Map<EntityId, ServerClass> = new Map();
public sendTableMap: {[name: string]: SendTable}; public sendTableMap: {[name: string]: SendTable};
public baseLineCache: {[serverClass: string]: PacketEntity}; public baseLineCache: {[serverClass: string]: PacketEntity};
public weaponMap: {[entityId: string]: Weapon}; public weaponMap: {[entityId: string]: Weapon};
@ -63,7 +63,6 @@ export class Match {
boundaryMin: {x: 0, y: 0, z: 0}, boundaryMin: {x: 0, y: 0, z: 0},
boundaryMax: {x: 0, y: 0, z: 0}, boundaryMax: {x: 0, y: 0, z: 0},
}; };
this.entityClasses = {};
this.sendTableMap = {}; this.sendTableMap = {};
this.baseLineCache = {}; this.baseLineCache = {};
this.weaponMap = {}; this.weaponMap = {};

View file

@ -13,7 +13,7 @@ export type EntityId = number;
export class PacketEntity { export class PacketEntity {
public serverClass: ServerClass; public serverClass: ServerClass;
public entityIndex: number; public entityIndex: EntityId;
public props: SendProp[]; public props: SendProp[];
public inPVS: boolean; public inPVS: boolean;
public pvs: PVS; public pvs: PVS;

View file

@ -10,7 +10,7 @@ import {TeamNumber} from '../Data/Team';
export function handlePacketEntities(packet: PacketEntitiesPacket, match: Match) { export function handlePacketEntities(packet: PacketEntitiesPacket, match: Match) {
for (const removedEntityId of packet.removedEntities) { for (const removedEntityId of packet.removedEntities) {
delete match.entityClasses[removedEntityId]; match.entityClasses.delete(removedEntityId);
} }
for (const entity of packet.entities) { for (const entity of packet.entities) {
@ -21,10 +21,10 @@ export function handlePacketEntities(packet: PacketEntitiesPacket, match: Match)
function saveEntity(packetEntity: PacketEntity, match: Match) { function saveEntity(packetEntity: PacketEntity, match: Match) {
if (packetEntity.pvs === PVS.DELETE) { if (packetEntity.pvs === PVS.DELETE) {
delete match.entityClasses[packetEntity.entityIndex]; match.entityClasses.delete(packetEntity.entityIndex);
} }
match.entityClasses[packetEntity.entityIndex] = packetEntity.serverClass; match.entityClasses.set(packetEntity.entityIndex, packetEntity.serverClass);
} }
function handleEntity(entity: PacketEntity, match: Match) { function handleEntity(entity: PacketEntity, match: Match) {

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {Match} from '../../Data/Match'; import {Match} from '../../Data/Match';
import {PacketEntitiesPacket} from '../../Data/Packet'; import {PacketEntitiesPacket} from '../../Data/Packet';
import {PacketEntity, PVS} from '../../Data/PacketEntity'; import {EntityId, PacketEntity, PVS} from '../../Data/PacketEntity';
import {SendProp} from '../../Data/SendProp'; import {SendProp} from '../../Data/SendProp';
import {applyEntityUpdate} from '../EntityDecoder'; import {applyEntityUpdate} from '../EntityDecoder';
import {readUBitVar} from '../readBitVar'; import {readUBitVar} from '../readBitVar';
@ -19,18 +19,18 @@ function readPVSType(stream: BitStream): PVS {
return pvsMap[pvs]; return pvsMap[pvs];
} }
function readEnterPVS(stream: BitStream, entityId: number, match: Match): PacketEntity { function readEnterPVS(stream: BitStream, entityId: EntityId, match: Match): PacketEntity {
// https://github.com/PazerOP/DemoLib/blob/5f9467650f942a4a70f9ec689eadcd3e0a051956/TF2Net/NetMessages/NetPacketEntitiesMessage.cs#L198 // https://github.com/PazerOP/DemoLib/blob/5f9467650f942a4a70f9ec689eadcd3e0a051956/TF2Net/NetMessages/NetPacketEntitiesMessage.cs#L198
const serverClass = match.serverClasses[stream.readBits(match.classBits)]; const serverClass = match.serverClasses[stream.readBits(match.classBits)];
const serial = stream.readBits(10); // unused serial number const serial = stream.readBits(10); // unused serial number
if (match.baseLineCache[serverClass.id]) { if (match.baseLineCache[serverClass.id]) {
const result = match.baseLineCache[serverClass.id].clone(); const result = match.baseLineCache[serverClass.id].clone();
result.entityIndex = entityId; result.entityIndex = entityId;
result.serialNumber = serial; result.serialNumber = serial;
return result; return result;
} else { } else {
const entity = new PacketEntity(serverClass, entityId, PVS.ENTER); const entity = new PacketEntity(serverClass, entityId, PVS.ENTER);
const sendTable = match.getSendTable(serverClass.dataTable); const sendTable = match.getSendTable(serverClass.dataTable);
if (!sendTable) { if (!sendTable) {
throw new Error('Unknown SendTable for serverclass'); throw new Error('Unknown SendTable for serverclass');
@ -41,8 +41,8 @@ function readEnterPVS(stream: BitStream, entityId: number, match: Match): Packet
applyEntityUpdate(entity, sendTable, staticBaseLine); applyEntityUpdate(entity, sendTable, staticBaseLine);
match.baseLineCache[serverClass.id] = entity.clone(); match.baseLineCache[serverClass.id] = entity.clone();
// if (staticBaseLine.bitsLeft > 7) { // if (staticBaseLine.bitsLeft > 7) {
// console.log(staticBaseLine.length, staticBaseLine.index); // console.log(staticBaseLine.length, staticBaseLine.index);
// throw new Error('Unexpected data left at the end of staticBaseline, ' + staticBaseLine.bitsLeft + ' bits left'); // throw new Error('Unexpected data left at the end of staticBaseline, ' + staticBaseLine.bitsLeft + ' bits left');
// } // }
} }
entity.serialNumber = serial; entity.serialNumber = serial;
@ -50,11 +50,12 @@ function readEnterPVS(stream: BitStream, entityId: number, match: Match): Packet
} }
} }
function getPacketEntityForExisting(entityId: number, match: Match, pvs: PVS) { function getPacketEntityForExisting(entityId: EntityId, match: Match, pvs: PVS) {
if (!match.entityClasses[entityId]) { const serverClass = match.entityClasses.get(entityId);
if (!serverClass) {
throw new Error(`"unknown entity ${entityId} for ${PVS[pvs]}(${pvs})`); throw new Error(`"unknown entity ${entityId} for ${PVS[pvs]}(${pvs})`);
} }
const serverClass = match.entityClasses[entityId];
return new PacketEntity(serverClass, entityId, pvs); return new PacketEntity(serverClass, entityId, pvs);
} }
@ -63,24 +64,24 @@ export function ParsePacketEntities(stream: BitStream, match: Match, skip: boole
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Handler/PacketEntitesHandler.cs // https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Handler/PacketEntitesHandler.cs
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Entity.cs // https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Entity.cs
// https://github.com/PazerOP/DemoLib/blob/5f9467650f942a4a70f9ec689eadcd3e0a051956/TF2Net/NetMessages/NetPacketEntitiesMessage.cs // https://github.com/PazerOP/DemoLib/blob/5f9467650f942a4a70f9ec689eadcd3e0a051956/TF2Net/NetMessages/NetPacketEntitiesMessage.cs
const maxEntries = stream.readBits(11); const maxEntries = stream.readBits(11);
const isDelta = !!stream.readBits(1); const isDelta = stream.readBoolean();
const delta = (isDelta) ? stream.readInt32() : 0; const delta = (isDelta) ? stream.readInt32() : 0;
const baseLine = stream.readBits(1); const baseLine = stream.readBits(1);
const updatedEntries = stream.readBits(11); const updatedEntries = stream.readBits(11);
const length = stream.readBits(20); const length = stream.readBits(20);
const updatedBaseLine = stream.readBoolean(); const updatedBaseLine = stream.readBoolean();
const end = stream.index + length; const end = stream.index + length;
let entityId = -1; let entityId = -1;
const receivedEntities: PacketEntity[] = []; const receivedEntities: PacketEntity[] = [];
const removedEntityIds: number[] = []; const removedEntityIds: EntityId[] = [];
if (!skip) { if (!skip) {
for (let i = 0; i < updatedEntries; i++) { for (let i = 0; i < updatedEntries; i++) {
const diff = readUBitVar(stream); const diff = readUBitVar(stream);
entityId += 1 + diff; entityId += 1 + diff;
const pvs = readPVSType(stream); const pvs = readPVSType(stream);
if (pvs === PVS.ENTER) { if (pvs === PVS.ENTER) {
const packetEntity = readEnterPVS(stream, entityId, match); const packetEntity = readEnterPVS(stream, entityId, match);
applyEntityUpdate(packetEntity, match.getSendTable(packetEntity.serverClass.dataTable), stream); applyEntityUpdate(packetEntity, match.getSendTable(packetEntity.serverClass.dataTable), stream);
@ -96,11 +97,9 @@ export function ParsePacketEntities(stream: BitStream, match: Match, skip: boole
const packetEntity = getPacketEntityForExisting(entityId, match, pvs); const packetEntity = getPacketEntityForExisting(entityId, match, pvs);
applyEntityUpdate(packetEntity, match.getSendTable(packetEntity.serverClass.dataTable), stream); applyEntityUpdate(packetEntity, match.getSendTable(packetEntity.serverClass.dataTable), stream);
receivedEntities.push(packetEntity); receivedEntities.push(packetEntity);
} else { } else if (match.entityClasses.has(entityId)) {
if (match.entityClasses[entityId]) { const packetEntity = getPacketEntityForExisting(entityId, match, pvs);
const packetEntity = getPacketEntityForExisting(entityId, match, pvs); receivedEntities.push(packetEntity);
receivedEntities.push(packetEntity);
}
} }
} }
@ -113,8 +112,8 @@ export function ParsePacketEntities(stream: BitStream, match: Match, skip: boole
stream.index = end; stream.index = end;
return { return {
packetType: 'packetEntities', packetType: 'packetEntities',
entities: receivedEntities, entities: receivedEntities,
removedEntities: removedEntityIds, removedEntities: removedEntityIds,
maxEntries, maxEntries,
isDelta, isDelta,