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:
parent
5fcbbe540e
commit
255602d1e2
6 changed files with 33 additions and 43 deletions
|
|
@ -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 = [];
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = [];
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -23,37 +23,35 @@ 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) {
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue