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

cache entity baseline

This commit is contained in:
Robin Appelman 2017-02-14 22:53:27 +01:00
commit 255602d1e2
6 changed files with 33 additions and 43 deletions

View file

@ -27,7 +27,6 @@ export class Match {
stringTables: StringTable[]; stringTables: StringTable[];
serverClasses: ServerClass[]; serverClasses: ServerClass[];
sendTables: SendTable[]; sendTables: SendTable[];
instanceBaselines: SendProp[][][];
staticBaseLines: BitStream[]; staticBaseLines: BitStream[];
eventDefinitions: GameEventDefinitionMap; eventDefinitions: GameEventDefinitionMap;
world: World; world: World;
@ -47,7 +46,6 @@ export class Match {
this.stringTables = []; this.stringTables = [];
this.sendTables = []; this.sendTables = [];
this.serverClasses = []; this.serverClasses = [];
this.instanceBaselines = [[], []];
this.staticBaseLines = []; this.staticBaseLines = [];
this.eventDefinitions = {}; this.eventDefinitions = {};
this.players = []; this.players = [];

View file

@ -16,14 +16,12 @@ export class PacketEntity {
entityIndex: number; entityIndex: number;
props: SendProp[]; props: SendProp[];
inPVS: boolean; inPVS: boolean;
updatedProps: SendProp[];
constructor(serverClass: ServerClass, entityIndex: number, pvs: PVS) { constructor(serverClass: ServerClass, entityIndex: number, pvs: PVS) {
this.serverClass = serverClass; this.serverClass = serverClass;
this.entityIndex = entityIndex; this.entityIndex = entityIndex;
this.props = []; this.props = [];
this.inPVS = false; this.inPVS = false;
this.updatedProps = [];
this.pvs = pvs; this.pvs = pvs;
} }
@ -44,5 +42,13 @@ export class PacketEntity {
} }
throw new Error('Property not found in entity'); throw new Error('Property not found in entity');
} }
clone(): PacketEntity {
const result = new PacketEntity(this.serverClass, this.entityIndex, this.pvs);
for (const prop of this.props) {
result.props.push(prop.clone());
}
return result;
}
} }

View file

@ -13,7 +13,7 @@ export class SendProp {
clone():SendProp { clone():SendProp {
const prop = new SendProp(this.definition); const prop = new SendProp(this.definition);
prop.value = clone(this.value); prop.value = clone(this.value, false);
return prop; return prop;
} }
} }

View file

@ -44,7 +44,7 @@ function handleEntity(entity: PacketEntity, match: Match) {
match.players.push(player); match.players.push(player);
} }
for (const prop of entity.updatedProps) { for (const prop of entity.props) {
const propName = prop.definition.ownerTableName + '.' + prop.definition.name; const propName = prop.definition.ownerTableName + '.' + prop.definition.name;
// console.log(propName, prop.value); // console.log(propName, prop.value);
switch (propName) { switch (propName) {
@ -75,5 +75,4 @@ function handleEntity(entity: PacketEntity, match: Match) {
} }
} }
entity.updatedProps = [];
} }

View file

@ -21,7 +21,6 @@ export function applyEntityUpdate(entity: PacketEntity, sendTable: SendTable, st
const prop = existingProp ? existingProp : new SendProp(propDefinition); const prop = existingProp ? existingProp : new SendProp(propDefinition);
prop.value = SendPropParser.decode(propDefinition, stream); prop.value = SendPropParser.decode(propDefinition, stream);
entity.updatedProps.push(prop);
lastProps.push(prop); lastProps.push(prop);
if (!existingProp) { if (!existingProp) {

View file

@ -23,38 +23,36 @@ function readPVSType(stream: BitStream): PVS {
return pvs; return pvs;
} }
function readEnterPVS(stream: BitStream, entityId: number, match: Match, baseLine: number): PacketEntity { const baseLineCache: {[serverClass: string]: PacketEntity} = {};
function readEnterPVS(stream: BitStream, entityId: number, 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)];
stream.readBits(10); // unused serial number
if (baseLineCache[serverClass.id]) {
const result = baseLineCache[serverClass.id].clone();
result.entityIndex = entityId;
return result;
} else {
const entity = new PacketEntity(serverClass, entityId, PVS.ENTER);
const sendTable = match.getSendTable(serverClass.dataTable); const sendTable = match.getSendTable(serverClass.dataTable);
const serialNumber = stream.readBits(10); // unused it seems
if (!sendTable) { if (!sendTable) {
throw new Error('Unknown SendTable for serverclass'); throw new Error('Unknown SendTable for serverclass');
} }
const entity = new PacketEntity(serverClass, entityId, PVS.ENTER);
const decodedBaseLine = match.instanceBaselines[baseLine][entityId];
if (decodedBaseLine) {
for (let i = 0; i < decodedBaseLine.length; i++) {
const newProp = decodedBaseLine[i];
if (!entity.getPropByDefinition(newProp.definition)) {
entity.props.push(newProp.clone());
}
}
} else {
const staticBaseLine = match.staticBaseLines[serverClass.id]; const staticBaseLine = match.staticBaseLines[serverClass.id];
if (staticBaseLine) { if (staticBaseLine) {
staticBaseLine.index = 0; staticBaseLine.index = 0;
applyEntityUpdate(entity, sendTable, staticBaseLine); applyEntityUpdate(entity, sendTable, staticBaseLine);
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');
} }
} }
}
return entity; return entity;
} }
}
function getPacketEntityForExisting(entityId: number, match: Match, pvs: PVS) { function getPacketEntityForExisting(entityId: number, match: Match, pvs: PVS) {
if (!match.entityClasses[entityId]) { if (!match.entityClasses[entityId]) {
@ -79,29 +77,19 @@ export function PacketEntities(stream: BitStream, match: Match): PacketEntitiesP
const end = stream.index + length; const end = stream.index + length;
let entityId = -1; let entityId = -1;
if (updatedBaseLine) {
if (baseLine === 0) {
match.instanceBaselines[1] = match.instanceBaselines[0];
match.instanceBaselines[0] = new Array((1 << 11)); // array of SendPropDefinition with size MAX_EDICTS
} else {
match.instanceBaselines[0] = match.instanceBaselines[1];
match.instanceBaselines[1] = new Array((1 << 11)); // array of SendPropDefinition with size MAX_EDICTS
}
}
const receivedEntities: PacketEntity[] = []; const receivedEntities: PacketEntity[] = [];
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, baseLine); const packetEntity = readEnterPVS(stream, entityId, match);
applyEntityUpdate(packetEntity, match.getSendTable(packetEntity.serverClass.dataTable), stream); applyEntityUpdate(packetEntity, match.getSendTable(packetEntity.serverClass.dataTable), stream);
if (updatedBaseLine) { if (updatedBaseLine) {
const newBaseLine: SendProp[] = []; const newBaseLine: SendProp[] = [];
newBaseLine.concat(packetEntity.props); newBaseLine.concat(packetEntity.props);
match.instanceBaselines[baseLine][entityId] = newBaseLine; baseLineCache[packetEntity.serverClass.id] = packetEntity.clone();
} }
packetEntity.inPVS = true; packetEntity.inPVS = true;
receivedEntities.push(packetEntity); receivedEntities.push(packetEntity);