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

only apply updates for entities from the current packet

This commit is contained in:
Robin Appelman 2017-02-13 18:55:26 +01:00
commit 7cb74d93de
8 changed files with 46 additions and 50 deletions

View file

@ -1,4 +1,4 @@
import {Entity} from "./Entity"; import {PacketEntity} from "./PacketEntity";
import {ServerClass} from "./ServerClass"; import {ServerClass} from "./ServerClass";
import {SendTable} from "./SendTable"; import {SendTable} from "./SendTable";
import {StringTable} from "./StringTable"; import {StringTable} from "./StringTable";
@ -22,7 +22,7 @@ export class Match {
rounds: any[]; rounds: any[];
startTick: number; startTick: number;
intervalPerTick: number; intervalPerTick: number;
entities: (Entity|null)[]; packetEntities: (PacketEntity|null)[];
stringTables: StringTable[]; stringTables: StringTable[];
serverClasses: ServerClass[]; serverClasses: ServerClass[];
sendTables: SendTable[]; sendTables: SendTable[];
@ -41,11 +41,11 @@ export class Match {
this.rounds = []; this.rounds = [];
this.startTick = 0; this.startTick = 0;
this.intervalPerTick = 0; this.intervalPerTick = 0;
this.entities = []; this.packetEntities = [];
this.stringTables = []; this.stringTables = [];
this.sendTables = []; this.sendTables = [];
this.serverClasses = []; this.serverClasses = [];
this.entities = []; this.packetEntities = [];
this.instanceBaselines = [[], []]; this.instanceBaselines = [[], []];
this.staticBaseLines = []; this.staticBaseLines = [];
this.eventDefinitions = {}; this.eventDefinitions = {};
@ -147,7 +147,7 @@ export class Match {
return this.users[userId]; return this.users[userId];
} }
getUserInfoForEntity(entity: Entity): UserInfo { getUserInfoForEntity(entity: PacketEntity): UserInfo {
for (const id of Object.keys(this.users)) { for (const id of Object.keys(this.users)) {
const user = this.users[id]; const user = this.users[id];
if (user && user.entityId === entity.entityIndex) { if (user && user.entityId === entity.entityIndex) {

View file

@ -1,7 +1,7 @@
import {StringTable} from "./StringTable"; import {StringTable} from "./StringTable";
import {Vector} from "./Vector"; import {Vector} from "./Vector";
import {GameEvent} from "./GameEvent"; import {GameEvent} from "./GameEvent";
import {Entity} from "./Entity"; import {PacketEntity} from "./PacketEntity";
export interface StringTablePacket { export interface StringTablePacket {
packetType: 'stringTable'; packetType: 'stringTable';
@ -46,6 +46,7 @@ export interface GameEventListPacket {
export interface PacketEntitiesPacket { export interface PacketEntitiesPacket {
packetType: 'packetEntities'; packetType: 'packetEntities';
entities: PacketEntity[];
} }
export interface ParseSoundsPacket { export interface ParseSoundsPacket {
@ -62,7 +63,7 @@ export interface SetConVarPacket {
export interface TempEntitiesPacket { export interface TempEntitiesPacket {
packetType: 'tempEntities'; packetType: 'tempEntities';
entities: Entity[]; entities: PacketEntity[];
} }
export interface SayText2Packet { export interface SayText2Packet {

View file

@ -2,7 +2,7 @@ import {ServerClass} from "./ServerClass";
import {SendTable} from "./SendTable"; import {SendTable} from "./SendTable";
import {SendProp} from "./SendProp"; import {SendProp} from "./SendProp";
import {SendPropDefinition} from "./SendPropDefinition"; import {SendPropDefinition} from "./SendPropDefinition";
export class Entity { export class PacketEntity {
serverClass: ServerClass; serverClass: ServerClass;
sendTable: SendTable; sendTable: SendTable;
entityIndex: number; entityIndex: number;

View file

@ -1,18 +1,16 @@
import {PacketEntitiesPacket} from "../Data/Packet"; import {PacketEntitiesPacket} from "../Data/Packet";
import {Match} from "../Data/Match"; import {Match} from "../Data/Match";
import {Entity} from "../Data/Entity"; import {PacketEntity} from "../Data/PacketEntity";
import {Vector} from "../Data/Vector"; import {Vector} from "../Data/Vector";
import {Player} from "../Data/Player"; import {Player} from "../Data/Player";
export function handlePacketEntities(packet: PacketEntitiesPacket, match: Match) { export function handlePacketEntities(packet: PacketEntitiesPacket, match: Match) {
for (const entity of match.entities) { for (const entity of packet.entities) {
if (entity) { handleEntity(entity, match);
handleEntity(entity, match);
}
} }
} }
function handleEntity(entity: Entity, match: Match) { function handleEntity(entity: PacketEntity, match: Match) {
switch (entity.serverClass.name) { switch (entity.serverClass.name) {
case 'CWorld': case 'CWorld':
match.world.boundaryMin = <Vector>entity.getProperty('DT_WORLD', 'm_WorldMins').value; match.world.boundaryMin = <Vector>entity.getProperty('DT_WORLD', 'm_WorldMins').value;

View file

@ -1,14 +1,11 @@
import {Entity} from "../Data/Entity"; import {PacketEntity} from "../Data/PacketEntity";
import {BitStream} from "bit-buffer"; import {BitStream} from "bit-buffer";
import {SendProp} from "../Data/SendProp"; import {SendProp} from "../Data/SendProp";
import {SendPropParser} from "./SendPropParser"; import {SendPropParser} from "./SendPropParser";
import {readUBitVar} from "./readBitVar"; import {readUBitVar} from "./readBitVar";
import {SendTable} from "../Data/SendTable"; import {SendTable} from "../Data/SendTable";
export function applyEntityUpdate(entity: Entity, stream: BitStream, sendTable?: SendTable): Entity { export function applyEntityUpdate(entity: PacketEntity, sendTable: SendTable, stream: BitStream): PacketEntity {
if (!sendTable) {
sendTable = entity.sendTable;
}
let index = -1; let index = -1;
const allProps = sendTable.flattenedProps; const allProps = sendTable.flattenedProps;
let lastProps:SendProp[] = []; let lastProps:SendProp[] = [];

View file

@ -1,4 +1,4 @@
import {Entity} from '../../Data/Entity'; import {PacketEntity} from '../../Data/PacketEntity';
import {SendProp} from '../../Data/SendProp'; import {SendProp} from '../../Data/SendProp';
import {PacketEntitiesPacket} from "../../Data/Packet"; import {PacketEntitiesPacket} from "../../Data/Packet";
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
@ -30,19 +30,16 @@ function readPVSType(stream: BitStream): PVS {
return pvs; return pvs;
} }
function readEnterPVS(stream: BitStream, entityId: number, match: Match, baseLine: number): Entity { function readEnterPVS(stream: BitStream, entityId: number, match: Match, baseLine: number): 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 sendTable = match.getSendTable(serverClass.dataTable); const sendTable = match.getSendTable(serverClass.dataTable);
const serialNumber = stream.readBits(10); const serialNumber = stream.readBits(10);
if (!sendTable) { if (!sendTable) {
throw new Error('Unknown SendTable for serverclass'); throw new Error('Unknown SendTable for serverclass');
} }
// if (match.entities[entityId]) { const entity = new PacketEntity(serverClass, sendTable, entityId, serialNumber);
// console.log('overwriting entity');
// }
const entity = new Entity(serverClass, sendTable, entityId, serialNumber);
const decodedBaseLine = match.instanceBaselines[baseLine][entityId]; const decodedBaseLine = match.instanceBaselines[baseLine][entityId];
if (decodedBaseLine) { if (decodedBaseLine) {
@ -56,7 +53,7 @@ function readEnterPVS(stream: BitStream, entityId: number, match: Match, baseLin
const staticBaseLine = match.staticBaseLines[serverClass.id]; const staticBaseLine = match.staticBaseLines[serverClass.id];
if (staticBaseLine) { if (staticBaseLine) {
staticBaseLine.index = 0; staticBaseLine.index = 0;
applyEntityUpdate(entity, staticBaseLine, sendTable); applyEntityUpdate(entity, sendTable, staticBaseLine);
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');
@ -68,7 +65,7 @@ function readEnterPVS(stream: BitStream, entityId: number, match: Match, baseLin
function readLeavePVS(match, entityId, shouldDelete) { function readLeavePVS(match, entityId, shouldDelete) {
if (shouldDelete) { if (shouldDelete) {
match.entities[entityId] = null; match.packetEntities[entityId] = null;
} }
} }
@ -97,14 +94,15 @@ export function PacketEntities(stream: BitStream, match: Match): PacketEntitiesP
} }
} }
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 entity = readEnterPVS(stream, entityId, match, baseLine); const entity = readEnterPVS(stream, entityId, match, baseLine);
applyEntityUpdate(entity, stream); applyEntityUpdate(entity, entity.sendTable, stream);
match.entities[entityId] = entity; match.packetEntities[entityId] = entity;
if (updatedBaseLine) { if (updatedBaseLine) {
const newBaseLine: SendProp[] = []; const newBaseLine: SendProp[] = [];
@ -112,16 +110,18 @@ export function PacketEntities(stream: BitStream, match: Match): PacketEntitiesP
match.instanceBaselines[baseLine][entityId] = newBaseLine; match.instanceBaselines[baseLine][entityId] = newBaseLine;
} }
entity.inPVS = true; entity.inPVS = true;
receivedEntities.push(entity);
} else if (pvs === PVS.PRESERVE) { } else if (pvs === PVS.PRESERVE) {
const entity = match.entities[entityId]; const entity = match.packetEntities[entityId];
if (entity) { if (entity) {
applyEntityUpdate(entity, stream); applyEntityUpdate(entity, entity.sendTable, stream);
receivedEntities.push(entity);
} else { } else {
console.log(entityId, match.entities.length); console.log(entityId, match.packetEntities.length);
throw new Error("unknown entity"); throw new Error("unknown entity");
} }
} else { } else {
const entity = match.entities[entityId]; const entity = match.packetEntities[entityId];
if (entity) { if (entity) {
entity.inPVS = false; entity.inPVS = false;
} }
@ -131,13 +131,14 @@ export function PacketEntities(stream: BitStream, match: Match): PacketEntitiesP
if (isDelta) { if (isDelta) {
while (stream.readBoolean()) { while (stream.readBoolean()) {
const ent = stream.readBits(11); const ent = stream.readBits(11);
match.entities[ent] = null; match.packetEntities[ent] = null;
} }
} }
stream.index = end; stream.index = end;
return { return {
packetType: 'packetEntities' packetType: 'packetEntities',
entities: receivedEntities
}; };
} }

View file

@ -1,8 +1,6 @@
import {Packet} from "../../Data/Packet"; import {Packet} from "../../Data/Packet";
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {GameEventDefinitionMap} from "../../Data/GameEvent";
import {Match} from "../../Data/Match"; import {Match} from "../../Data/Match";
import {Entity} from "../../Data/Entity";
export type Parser = (stream: BitStream, match?: Match) => Packet; export type Parser = (stream: BitStream, match?: Match) => Packet;
export type PacketParserMap = {[id: number]: Parser}; export type PacketParserMap = {[id: number]: Parser};

View file

@ -1,7 +1,7 @@
import {TempEntitiesPacket} from "../../Data/Packet"; import {TempEntitiesPacket} from "../../Data/Packet";
import {BitStream} from 'bit-buffer'; import {BitStream} from 'bit-buffer';
import {Match} from "../../Data/Match"; import {Match} from "../../Data/Match";
import {Entity} from "../../Data/Entity"; import {PacketEntity} from "../../Data/PacketEntity";
import {applyEntityUpdate} from "../EntityDecoder"; import {applyEntityUpdate} from "../EntityDecoder";
export function TempEntities(stream: BitStream, match: Match): TempEntitiesPacket { // 10: classInfo export function TempEntities(stream: BitStream, match: Match): TempEntitiesPacket { // 10: classInfo
@ -9,22 +9,23 @@ export function TempEntities(stream: BitStream, match: Match): TempEntitiesPacke
const length = readVarInt(stream); const length = readVarInt(stream);
const end = stream.index + length; const end = stream.index + length;
let entity: Entity|null = null; let entity: PacketEntity|null = null;
let entities: Entity[] = []; let entities: PacketEntity[] = [];
for (let i = 0; i < entityCount; i++) { for (let i = 0; i < entityCount; i++) {
const delay = (stream.readBoolean()) ? stream.readUint8() / 100 : 0; //unused it seems const delay = (stream.readBoolean()) ? stream.readUint8() / 100 : 0; //unused it seems
if (stream.readBoolean()) { if (stream.readBoolean()) {
const classId = stream.readBits(match.classBits); const classId = stream.readBits(match.classBits);
const serverClass = match.serverClasses[classId - 1]; // no clue why the -1 but it works const serverClass = match.serverClasses[classId - 1];
// maybe because world (id=0) can never be tem // no clue why the -1 but it works
// but it's not like the -1 saves any space // maybe because world (id=0) can never be temp
const sendTable = match.getSendTable(serverClass.dataTable); // but it's not like the -1 saves any space
entity = new Entity(serverClass, sendTable, 0, 0); const sendTable = match.getSendTable(serverClass.dataTable);
applyEntityUpdate(entity, stream); entity = new PacketEntity(serverClass, sendTable, 0, 0);
applyEntityUpdate(entity, sendTable, stream);
entities.push(entity); entities.push(entity);
} else { } else {
if (entity) { if (entity) {
applyEntityUpdate(entity, stream); applyEntityUpdate(entity, entity.sendTable, stream);
} else { } else {
throw new Error("no entity set to update"); throw new Error("no entity set to update");
} }
@ -37,7 +38,7 @@ export function TempEntities(stream: BitStream, match: Match): TempEntitiesPacke
stream.index = end; stream.index = end;
return { return {
packetType: 'tempEntities', packetType: 'tempEntities',
entities: entities entities: entities
} }
} }