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

add encoder for tempEntities

This commit is contained in:
Robin Appelman 2017-09-06 00:05:44 +02:00
commit 450300c1b0
12 changed files with 667 additions and 68 deletions

6
package-lock.json generated
View file

@ -229,9 +229,9 @@
"dev": true
},
"bit-buffer": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/bit-buffer/-/bit-buffer-0.2.0.tgz",
"integrity": "sha512-et8MIvMW4fqwgseIq0SLjyjbhmypVSBcb+4Zd/+2CkYTDsh/yWXEosXrHaCvrTdYzkeeBJraypggmE3XKPlUAw=="
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/bit-buffer/-/bit-buffer-0.2.3.tgz",
"integrity": "sha512-Ugsj2ZD23YKb4cCasdBD4l1Oy4eI/752hnCMAmZO62P+oS1emCqNMlkex02ppGWgKHTS6sfzFeUbPD6VWd+s1w=="
},
"brace-expansion": {
"version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",

View file

@ -9,7 +9,7 @@
"jsnext:main": "build/es6/index.js",
"module": "build/es6/index.js",
"dependencies": {
"bit-buffer": "^0.2.0",
"bit-buffer": "^0.2.3",
"clone": "^2.1.0",
"minimist": "1.1.x",
"snappyjs": "^0.5.0"

View file

@ -37,7 +37,7 @@ export class SendPropDefinition {
public inspect() {
const data: any = {
fromTable: this.ownerTableName,
ownerTableName: this.ownerTableName,
name: this.name,
type: SendPropType[this.type],
flags: this.flags,

30
src/DynamicBitStream.ts Normal file
View file

@ -0,0 +1,30 @@
import {BitStream, BitView} from 'bit-buffer';
class DynamicBitView extends BitView {
protected _view: Uint8Array;
setBits(offset: number, value: number, bits: number) {
const available = (this.byteLength * 8 - offset);
if (bits > available) {
this.grow();
}
return super.setBits(offset, value, bits);
}
grow() {
const newView = new Uint8Array(this.byteLength * 2);
newView.set(this._view);
this._view = newView;
}
}
export class DynamicBitStream extends BitStream {
constructor(initialByteSize: number = 16 * 1024) {
super(new DynamicBitView(new ArrayBuffer(initialByteSize)));
}
get length() {
return this.view.byteLength * 8;
}
}

View file

@ -31,7 +31,7 @@ export function encodeEntityUpdate(props: SendProp[], sendTable: SendTable, stre
stream.writeBoolean(true);
const index = allProps.findIndex(propDef => propDef.fullName === prop.definition.fullName);
if (index === -1) {
throw new Error('Unknown definition for property');
throw new Error(`Unknown definition for property ${prop.definition.fullName} in ${sendTable.name}`);
}
writeFieldIndex(index, stream, lastIndex);
lastIndex = index;

View file

@ -8,7 +8,7 @@ import {ParsePacketEntities} from '../Packet/PacketEntities';
import {PacketHandler, voidEncoder} from '../Packet/Parser';
import {EncodeParseSounds, ParseParseSounds} from '../Packet/ParseSounds';
import {EncodeSetConVar, ParseSetConVar} from '../Packet/SetConVar';
import {ParseTempEntities} from '../Packet/TempEntities';
import {EncodeTempEntities, ParseTempEntities} from '../Packet/TempEntities';
import {EncodeUpdateStringTable, ParseUpdateStringTable} from '../Packet/UpdateStringTable';
import {EncodeUserMessage, ParseUserMessage} from '../Packet/UserMessage';
import {EncodeVoiceData, ParseVoiceData} from '../Packet/VoiceData';
@ -67,7 +67,7 @@ export class Packet extends Parser {
[PacketTypeId.packetEntities,
{parser: ParsePacketEntities, encoder: voidEncoder}],
[PacketTypeId.tempEntities,
{parser: ParseTempEntities, encoder: voidEncoder}],
{parser: ParseTempEntities, encoder: EncodeTempEntities}],
[PacketTypeId.preFetch,
make('preFetch', 'index{14}')],
[PacketTypeId.menu,

View file

@ -2,47 +2,78 @@ import {BitStream} from 'bit-buffer';
import {Match} from '../../Data/Match';
import {TempEntitiesPacket} from '../../Data/Packet';
import {PacketEntity, PVS} from '../../Data/PacketEntity';
import {getEntityUpdate} from '../EntityDecoder';
import {readVarInt} from '../readBitVar';
import {encodeEntityUpdate, getEntityUpdate} from '../EntityDecoder';
import {readVarInt, writeVarInt} from '../readBitVar';
import {DynamicBitStream} from '../../DynamicBitStream';
export function ParseTempEntities(stream: BitStream, match: Match, skip: boolean = false): TempEntitiesPacket { // 10: classInfo
const entityCount = stream.readBits(8);
const entityCount = stream.readUint8();
const length = readVarInt(stream);
const end = stream.index + length;
const entityData = stream.readBitStream(length);
let entity: PacketEntity | null = null;
const entities: PacketEntity[] = [];
if (!skip) {
for (let i = 0; i < entityCount; i++) {
const delay = (stream.readBoolean()) ? stream.readUint8() / 100 : 0; // unused it seems
if (stream.readBoolean()) {
const classId = stream.readBits(match.classBits);
const delay = (entityData.readBoolean()) ? entityData.readUint8() / 100 : 0; // unused it seems
if (entityData.readBoolean()) {
const classId = entityData.readBits(match.classBits);
const serverClass = match.serverClasses[classId - 1];
if (!serverClass) {
throw new Error(`Unknown serverClass ${classId}`);
}
// no clue why the -1 but it works
// maybe because world (id=0) can never be temp
// but it's not like the -1 saves any space
const sendTable = match.getSendTable(serverClass.dataTable);
entity = new PacketEntity(serverClass, 0, PVS.ENTER);
entity.delay = delay;
entity.props = getEntityUpdate(sendTable, stream);
entity.props = getEntityUpdate(sendTable, entityData);
entities.push(entity);
} else {
if (entity) {
const updatedProps = getEntityUpdate(match.getSendTable(entity.serverClass.dataTable), stream);
const updatedProps = getEntityUpdate(match.getSendTable(entity.serverClass.dataTable), entityData);
entity.applyPropUpdate(updatedProps);
} else {
throw new Error('no entity set to update');
}
}
}
if (end - stream.index > 8) {
throw new Error('unexpected content after TempEntities');
if (entityData.bitsLeft > 8) {
throw new Error(`unexpected content after TempEntities ${entityData.bitsLeft} bits`);
}
}
stream.index = end;
return {
packetType: 'tempEntities',
entities,
};
}
export function EncodeTempEntities(packet: TempEntitiesPacket, stream: BitStream, match: Match) {
stream.writeUint8(packet.entities.length);
const entityStream = new DynamicBitStream();
for (const entity of packet.entities) {
if (entity.delay) {
entityStream.writeBoolean(true);
entityStream.writeUint8(Math.round(entity.delay * 100));
} else {
entityStream.writeBoolean(false);
}
entityStream.writeBoolean(true);
const classId = match.serverClasses.findIndex(serverClass => serverClass && serverClass.name === entity.serverClass.name) + 1;
entityStream.writeBits(classId, match.classBits);
const sendTable = match.getSendTable(entity.serverClass.dataTable);
encodeEntityUpdate(entity.props, sendTable, entityStream);
}
const entityDataLength = entityStream.index;
entityStream.index = 0;
writeVarInt(entityDataLength, stream);
stream.writeBitStream(entityStream, entityDataLength);
}

View file

@ -23,7 +23,7 @@ export class SendPropParser {
case SendPropType.DPT_Array:
return SendPropParser.readArray(propDefinition, stream);
}
throw new Error('Unknown property type');
throw new Error(`Unknown property type ${propDefinition.type}`);
}
public static readInt(propDefinition: SendPropDefinition, stream: BitStream) {

View file

@ -0,0 +1,17 @@
import * as assert from 'assert';
import {DynamicBitStream} from '../../DynamicBitStream';
suite('DynamitcBitStream', () => {
test('write grow', () => {
const stream = new DynamicBitStream(2);
stream.writeBits(0, 15);
stream.writeBits(17, 16);
assert.equal(stream.length, 32);
assert.equal(stream.index, 31);
stream.index = 18;
assert.equal(stream.readBits(2), 2);
});
});

View file

@ -1,14 +1,12 @@
import {BitStream} from 'bit-buffer';
import {assertEncoder, assertParser, getStream} from './PacketTest';
import {readFileSync} from 'fs';
import {SendTable} from '../../../../Data/SendTable';
import {encodeEntityUpdate, getEntityUpdate} from '../../../../Parser/EntityDecoder';
import {SendProp, SendPropValue} from '../../../../Data/SendProp';
import {SendPropDefinition, SendPropType} from '../../../../Data/SendPropDefinition';
import {PacketEntity} from '../../../../Data/PacketEntity';
import {Vector} from '../../../../Data/Vector';
import {SendPropType} from '../../../../Data/SendPropDefinition';
import {SendPropEncoder} from '../../../../Parser/SendPropEncoder';
import {SendPropParser} from '../../../../Parser/SendPropParser';
import {hydrateEntity, hydrateTable} from './hydrate';
const data = [
9, 128, 64, 64, 64, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 36, 0, 64, 0, 1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, 128, 0, 0, 8, 0, 128, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 64, 0, 32, 0, 16, 0, 32, 240, 255, 255, 255, 31, 0, 2, 32, 48, 0, 128, 0, 0, 4, 254, 255, 127, 224, 255, 255, 7, 254, 255, 127, 0, 8, 64, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 64, 64, 64, 64, 0, 32, 224, 136, 10, 248, 91, 2, 63, 18, 8, 40, 38, 3, 250, 163, 192, 126, 7, 2, 2, 0, 0, 0, 0, 1, 0, 0, 0, 128, 0, 0, 0, 224, 111, 0, 0, 0, 0, 32, 192, 129, 172, 140, 46, 44, 141, 237, 133, 172, 140, 46, 44, 141, 109, 14, 78, 46, 141, 174, 108, 238, 107, 46, 236, 174, 45, 141, 141, 45, 0];
@ -18,46 +16,15 @@ const sendTableData = JSON.parse(readFileSync(__dirname + '/../../../data/sendTa
const sendTable = hydrateTable(sendTableData);
const entity = hydrateEntity(entityData);
function hydrateEntity(entityData): PacketEntity {
const entity = new PacketEntity(entityData.serverClass, entityData.entityIndex, entityData.pvs);
entity.props = entityData.props.map(propData => {
const prop = new SendProp(propDataDefinition(propData.definition));
if (prop.definition.type === SendPropType.DPT_Vector || prop.definition.type === SendPropType.DPT_VectorXY) {
prop.value = new Vector(propData.value.x, propData.value.y, propData.value.z);
} else {
prop.value = propData.value;
}
return prop;
});
return entity;
}
function propDataDefinition(propData): SendPropDefinition {
const prop = new SendPropDefinition(propData.type, propData.name, propData.flags, propData.ownerTableName);
prop.arrayProperty = propData.arrayProperty;
prop.numElements = propData.numElements;
prop.bitCount = propData.bitCount;
prop.excludeDTName = propData.excludeDTName;
prop.lowValue = propData.lowValue;
prop.highValue = propData.highValue;
prop.table = propData.table ? hydrateTable(propData.table) : null;
return prop;
}
function hydrateTable(tableData): SendTable {
const table = new SendTable(tableData.name);
table.props = tableData.props.map(propDataDefinition);
return table;
}
function decodeUpdate(stream: BitStream) {
export function decodeUpdate(stream: BitStream) {
return getEntityUpdate(sendTable, stream);
}
function encodeUpdate(props: SendProp[], stream: BitStream) {
export function encodeUpdate(props: SendProp[], stream: BitStream) {
encodeEntityUpdate(props, sendTable, stream);
}
function encodeProp(prop: SendProp) {
return function (value: SendPropValue, stream: BitStream) {
return SendPropEncoder.encode(value, prop.definition, stream);

View file

@ -0,0 +1,514 @@
import {BitStream} from 'bit-buffer';
import {assertEncoder, assertParser, getStream} from './PacketTest';
import {EncodeTempEntities, ParseTempEntities} from '../../../../Parser/Packet/TempEntities';
import {Match} from '../../../../Data/Match';
import {hydrateEntity, hydrateTable} from './hydrate';
import {ServerClass} from '../../../../Data/ServerClass';
import {TempEntitiesPacket} from '../../../../Data/Packet';
const data = [
2,
142,
1,
150,
10,
68,
56,
43,
176,
245,
5,
254,
253,
192,
96,
20,
194,
14,
8,
252,
95];
const entityData = [
{
'serverClass': {
'id': 164,
'name': 'CTEPlayerAnimEvent',
'dataTable': 'DT_TEPlayerAnimEvent'
},
'entityIndex': 0,
'props': [
{
'definition': {
'type': 0,
'name': 'm_iPlayerIndex',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 7,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TEPlayerAnimEvent'
},
'value': 17
}
],
'inPVS': false,
'pvs': 1,
'delay': 0
},
{
'serverClass': {
'id': 178,
'name': 'CTETFParticleEffect',
'dataTable': 'DT_TETFParticleEffect'
},
'entityIndex': 0,
'props': [
{
'definition': {
'type': 1,
'name': 'm_vecOrigin[0]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
'value': 1004
},
{
'definition': {
'type': 1,
'name': 'm_vecOrigin[1]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
'value': -2016
},
{
'definition': {
'type': 1,
'name': 'm_vecOrigin[2]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
'value': 561
},
{
'definition': {
'type': 0,
'name': 'm_iParticleSystemIndex',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 16,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
'value': 472
},
{
'definition': {
'type': 0,
'name': 'entindex',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 11,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
'value': 2047
}
],
'inPVS': false,
'pvs': 1,
'delay': 0
}
];
const sendTableData = {
'name': 'DT_TEPlayerAnimEvent',
'props': [
{
'type': 0,
'name': 'm_iPlayerIndex',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 7,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TEPlayerAnimEvent'
},
{
'type': 0,
'name': 'm_iEvent',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 6,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TEPlayerAnimEvent'
},
{
'type': 0,
'name': 'm_nData',
'flags': 0,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 12,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TEPlayerAnimEvent'
}
],
'cachedFlattenedProps': []
};
const sendTableData2 = {
'name': 'DT_TETFParticleEffect',
'props': [
{
'type': 6,
'name': 'baseclass',
'flags': 4096,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 0,
'table': {
'name': 'DT_BaseTempEntity',
'props': [],
'cachedFlattenedProps': []
},
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_vecOrigin[0]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_vecOrigin[1]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_vecOrigin[2]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_vecStart[0]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_vecStart[1]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_vecStart[2]',
'flags': 32772,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 2,
'name': 'm_vecAngles',
'flags': 0,
'excludeDTName': null,
'lowValue': 0,
'highValue': 360,
'bitCount': 7,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_iParticleSystemIndex',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 16,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'entindex',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 11,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_iAttachType',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 5,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_iAttachmentPointIndex',
'flags': 0,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_bResetParticles',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 1,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_bCustomColors',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 1,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 2,
'name': 'm_CustomColors.m_vecColor1',
'flags': 0,
'excludeDTName': null,
'lowValue': 0,
'highValue': 1,
'bitCount': 8,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 2,
'name': 'm_CustomColors.m_vecColor2',
'flags': 0,
'excludeDTName': null,
'lowValue': 0,
'highValue': 1,
'bitCount': 8,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_bControlPoint1',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 1,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 0,
'name': 'm_ControlPoint1.m_eParticleAttachment',
'flags': 1,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 5,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_ControlPoint1.m_vecOffset[0]',
'flags': 8196,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_ControlPoint1.m_vecOffset[1]',
'flags': 8196,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
},
{
'type': 1,
'name': 'm_ControlPoint1.m_vecOffset[2]',
'flags': 8196,
'excludeDTName': null,
'lowValue': 0,
'highValue': 0,
'bitCount': 32,
'table': null,
'numElements': 0,
'arrayProperty': null,
'ownerTableName': 'DT_TETFParticleEffect'
}
],
'cachedFlattenedProps': []
};
const sendTable = hydrateTable(sendTableData);
const sendTable2 = hydrateTable(sendTableData2);
const expected = {
packetType: 'tempEntities',
entities: entityData.map(hydrateEntity)
};
const match = new Match();
match.serverClasses.length = 348;
match.serverClasses[164] = new ServerClass(164, 'CTEPlayerAnimEvent', 'DT_TEPlayerAnimEvent');
match.serverClasses[178] = new ServerClass(178, 'CTETFParticleEffect', 'DT_TETFParticleEffect');
match.sendTables.set(sendTable.name, sendTable);
match.sendTables.set(sendTable2.name, sendTable2);
function parse(stream: BitStream) {
return ParseTempEntities(stream, match);
}
function encode(value: TempEntitiesPacket, stream: BitStream) {
EncodeTempEntities(value, stream, match);
}
suite('TempEntities', () => {
test('Parse tempEntities', () => {
assertParser(parse, getStream(data), expected, 166);
});
test('Encode tempEntities', () => {
assertEncoder(parse, encode, expected, 166);
});
});

View file

@ -0,0 +1,40 @@
import {SendProp} from '../../../../Data/SendProp';
import {PacketEntity} from '../../../../Data/PacketEntity';
import {SendPropDefinition, SendPropType} from '../../../../Data/SendPropDefinition';
import {Vector} from '../../../../Data/Vector';
import {SendTable} from '../../../../Data/SendTable';
export function hydrateEntity(entityData): PacketEntity {
const entity = new PacketEntity(entityData.serverClass, entityData.entityIndex, entityData.pvs);
entity.props = entityData.props.map(propData => {
const prop = new SendProp(propDataDefinition(propData.definition));
if (prop.definition.type === SendPropType.DPT_Vector || prop.definition.type === SendPropType.DPT_VectorXY) {
prop.value = new Vector(propData.value.x, propData.value.y, propData.value.z);
} else {
prop.value = propData.value;
}
return prop;
});
if (typeof entityData.delay !== 'undefined') {
entity.delay = entityData.delay;
}
return entity;
}
export function propDataDefinition(propData): SendPropDefinition {
const prop = new SendPropDefinition(propData.type, propData.name, propData.flags, propData.ownerTableName);
prop.arrayProperty = propData.arrayProperty;
prop.numElements = propData.numElements;
prop.bitCount = propData.bitCount;
prop.excludeDTName = propData.excludeDTName;
prop.lowValue = propData.lowValue;
prop.highValue = propData.highValue;
prop.table = propData.table ? hydrateTable(propData.table) : null;
return prop;
}
export function hydrateTable(tableData): SendTable {
const table = new SendTable(tableData.name);
table.props = tableData.props.map(propDataDefinition);
return table;
}