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

handle duplicated sendprops

This commit is contained in:
Robin Appelman 2017-09-16 17:58:39 +02:00
commit 79c4782806
4 changed files with 46 additions and 48 deletions

View file

@ -28,7 +28,7 @@ export class PacketEntity {
this.pvs = pvs;
}
private static getPropByFullName(props: SendProp[], fullName: string): SendProp | null {
public static getPropByFullName(props: SendProp[], fullName: string): SendProp | null {
for (const prop of props) {
if (prop.definition.fullName === fullName) {
return prop;
@ -56,7 +56,9 @@ export class PacketEntity {
result.props.push(prop.clone());
}
result.serialNumber = this.serialNumber;
if (this.delay) {
result.delay = this.delay;
}
result.inPVS = this.inPVS;
return result;
}

View file

@ -8,7 +8,7 @@ import {SendPropEncoder} from './SendPropEncoder';
export function getEntityUpdate(sendTable: SendTable, stream: BitStream): SendProp[] {
let index = -1;
const allProps = sendTable.flattenedProps;
const props: SendProp[] = [];
const props: Map<string, SendProp> = new Map();
while (stream.readBoolean()) {
index = readFieldIndex(stream, index);
if (index >= 4096 || index > allProps.length) {
@ -19,9 +19,9 @@ export function getEntityUpdate(sendTable: SendTable, stream: BitStream): SendPr
const propDefinition = allProps[index];
const prop = new SendProp(propDefinition);
prop.value = SendPropParser.decode(propDefinition, stream);
props.push(prop);
props.set(propDefinition.fullName, prop);
}
return props;
return Array.from(props.values());
}
export function encodeEntityUpdate(props: SendProp[], sendTable: SendTable, stream: BitStream) {

View file

@ -34,7 +34,7 @@ function writePVSType(pvs: PVS, stream: BitStream) {
stream.writeBits(raw, 2);
}
function readEnterPVS(stream: BitStream, entityId: EntityId, state: ParserState, baseLine: number): PacketEntity {
function readEnterPVS(stream: BitStream, entityId: EntityId, state: ParserState, baseLineIndex: number): PacketEntity {
// https://github.com/PazerOP/DemoLib/blob/5f9467650f942a4a70f9ec689eadcd3e0a051956/TF2Net/NetMessages/NetPacketEntitiesMessage.cs#L198
const classBits = getClassBits(state);
const serverClass = state.serverClasses[stream.readBits(classBits)];
@ -42,7 +42,7 @@ function readEnterPVS(stream: BitStream, entityId: EntityId, state: ParserState,
const sendTable = getSendTable(state, serverClass.dataTable);
const instanceBaseline = state.instanceBaselines[baseLine].get(entityId);
const instanceBaseline = state.instanceBaselines[baseLineIndex].get(entityId);
const entity = new PacketEntity(serverClass, entityId, PVS.ENTER);
entity.serialNumber = serial;
if (instanceBaseline) {
@ -52,23 +52,24 @@ function readEnterPVS(stream: BitStream, entityId: EntityId, state: ParserState,
} else {
const staticBaseLine = state.staticBaseLines.get(serverClass.id);
if (staticBaseLine) {
let baseline = state.staticBaselineCache.get(serverClass.id);
if (!baseline) {
let parsedBaseLine = state.staticBaselineCache.get(serverClass.id);
if (!parsedBaseLine) {
staticBaseLine.index = 0;
baseline = getEntityUpdate(sendTable, staticBaseLine);
state.staticBaselineCache.set(serverClass.id, baseline);
parsedBaseLine = getEntityUpdate(sendTable, staticBaseLine);
state.staticBaselineCache.set(serverClass.id, parsedBaseLine);
}
entity.applyPropUpdate(baseline);
entity.applyPropUpdate(parsedBaseLine);
// if (staticBaseLine.bitsLeft > 7) {
// console.log(staticBaseLine.length, staticBaseLine.index);
// throw new Error('Unexpected data left at the end of staticBaseline, ' + staticBaseLine.bitsLeft + ' bits left');
// }
}
return entity;
}
}
function writeEnterPVS(entity: PacketEntity, stream: BitStream, state: ParserState, baseLine: number) {
function writeEnterPVS(entity: PacketEntity, stream: BitStream, state: ParserState, baseLineIndex: number) {
const serverClassId = state.serverClasses.findIndex(serverClass => serverClass && entity.serverClass.id === serverClass.id);
if (serverClassId === -1) {
throw new Error(`Unknown server class ${entity.serverClass.name}(${entity.serverClass.id})`);
@ -81,20 +82,21 @@ function writeEnterPVS(entity: PacketEntity, stream: BitStream, state: ParserSta
const sendTable = getSendTable(state, serverClass.dataTable);
let instanceBaseLine = state.instanceBaselines[baseLine].get(entity.entityIndex);
let instanceBaseLine = state.instanceBaselines[baseLineIndex].get(entity.entityIndex);
if (!instanceBaseLine) {
const staticBaseLine = state.staticBaseLines.get(serverClass.id);
if (staticBaseLine) {
instanceBaseLine = state.staticBaselineCache.get(serverClass.id);
if (!instanceBaseLine) {
staticBaseLine.index = 0;
instanceBaseLine = getEntityUpdate(sendTable, staticBaseLine);
// state.instanceBaselines.set(serverClass, instanceBaseLine.clone());
state.staticBaselineCache.set(serverClass.id, instanceBaseLine);
}
}
}
const propsToEncode = instanceBaseLine ? entity.diffFromBaseLine(instanceBaseLine) : entity.props;
// console.log(propsToEncode.map(prop => `${prop.definition.name}: ${prop.value}`));
const allProps = sendTable.flattenedProps;
propsToEncode.sort((a, b) => allProps.findIndex(propDef => propDef.fullName === a.definition.fullName) -
allProps.findIndex(propDef => propDef.fullName === b.definition.fullName));
@ -112,9 +114,6 @@ function getPacketEntityForExisting(entityId: EntityId, state: ParserState, pvs:
}
export function ParsePacketEntities(stream: BitStream, state: ParserState, skip: boolean = false): PacketEntitiesPacket { // 26: packetEntities
// require('fs').writeFileSync('src/tests/data/packetEntitiesParserState.json', JSON.stringify(state), 'utf8');
// process.exit();
// https://github.com/skadistats/smoke/blob/master/smoke/replay/handler/svc_packetentities.pyx
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Handler/PacketEntitesHandler.cs
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/DP/Entity.cs

View file

@ -124,35 +124,32 @@ const sunEntityData = {
};
suite('PacketEntities', () => {
// test('Parse packetEntities', () => {
// const length = 130435;
// const stream = getStream(data);
// const start = stream.index;
// const resultPacket = parse(stream);
// assert.equal(stream.index - start, length, 'Unexpected number of bits consumed from stream');
//
// for (let i = 0; i < resultPacket.entities.length; i++) {
// const resultEntity = resultPacket.entities[i];
// const expectedEntity = expected.entities[i];
// assert.deepEqual(expectedEntity.serverClass, resultEntity.serverClass);
// assert.equal(expectedEntity.serialNumber, resultEntity.serialNumber);
// assert.equal(expectedEntity.entityIndex, resultEntity.entityIndex);
// if (!deepEqual(resultEntity, expectedEntity)) {
// for (let i = 0; i < expectedEntity.props.length; i++) {
// console.log(resultEntity.getPropByDefinition(expectedEntity.props[i].definition),expectedEntity.props[i].definition);
// assert.deepEqual(resultEntity.getPropByDefinition(expectedEntity.props[i].definition), expectedEntity.props[i], `invalid property #${i} for ${resultEntity.serverClass.name}`);
// }
// assert.equal(resultEntity.props.length, expectedEntity.props.length, `Unexpected number of props for ${resultEntity.serverClass.name}`);
// assert(false, 'Invalid entity ' + resultEntity.serverClass.name);
// }
// }
// });
test('Parse packetEntities', () => {
const length = 130435;
const stream = getStream(data);
const start = stream.index;
const resultPacket = parse(stream);
assert.equal(stream.index - start, length, 'Unexpected number of bits consumed from stream');
for (let i = 0; i < resultPacket.entities.length; i++) {
const resultEntity = resultPacket.entities[i];
const expectedEntity = expected.entities[i];
assert.deepEqual(expectedEntity.serverClass, resultEntity.serverClass);
assert.equal(expectedEntity.serialNumber, resultEntity.serialNumber);
assert.equal(expectedEntity.entityIndex, resultEntity.entityIndex);
if (!deepEqual(resultEntity, expectedEntity)) {
for (let i = 0; i < expectedEntity.props.length; i++) {
console.log(resultEntity.getPropByDefinition(expectedEntity.props[i].definition),expectedEntity.props[i].definition);
assert.deepEqual(resultEntity.getPropByDefinition(expectedEntity.props[i].definition), expectedEntity.props[i], `invalid property #${i} for ${resultEntity.serverClass.name}`);
}
assert.equal(resultEntity.props.length, expectedEntity.props.length, `Unexpected number of props for ${resultEntity.serverClass.name}`);
assert(false, 'Invalid entity ' + resultEntity.serverClass.name);
}
}
});
test('Encode packetEntities', () => {
const toEncode = {...expected};
// entity.props.map(prop => console.log(`${prop.definition.fullName}: ${prop.value}`));
// entity.props = [entity.props[0]];
toEncode.entities = toEncode.entities.slice(281, 282);
assertEncoder(parse, encode, toEncode, 0);
});