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

parsing of datatable prop headers

This commit is contained in:
Robin Appelman 2016-12-17 17:03:26 +01:00
commit 2579197ab6
2 changed files with 150 additions and 10 deletions

View file

@ -1,4 +1,4 @@
var DataTable = function (type, tick, stream, length, match) {
var DataTableParser = function (type, tick, stream, length, match) {
this.type = type;
this.tick = tick;
this.stream = stream;
@ -6,11 +6,145 @@ var DataTable = function (type, tick, stream, length, match) {
this.match = match;
};
DataTable.prototype.parse = function () {
//while (this.stream.byteIndex < this.length) {
// console.log(this.stream.readASCIIString());
//}
return [];
DataTableParser.prototype.parse = function () {
// https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/engine/dt_common_eng.cpp#L356
// https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/engine/dt_recv_eng.cpp#L310
// https://github.com/PazerOP/DemoLib/blob/master/DemoLib/Commands/DemoDataTablesCommand.cs
var tables = [];
while (this.stream.readBoolean()) {
var needsDecoder = this.stream.readBoolean();
var tableName = this.stream.readASCIIString();
var numProps = this.stream.readBits(10);
var table = new SentTable(tableName);
// get props metadata
var arrayElementProp;
for (var i = 0; i < numProps; i++) {
var propType = this.stream.readBits(5);
var propName = this.stream.readASCIIString();
var nFlagsBits = 16; // might be 11 (old?), 13 (new?), 16(networked) or 17(??)
var flags = this.stream.readBits(nFlagsBits);
var prop = new SendProp(propType, propName, flags);
if (propType === SendProp.types.DPT_DataTable) {
prop.excludeDTName = this.stream.readASCIIString();
} else {
if (prop.isExcludeProp()) {
prop.excludeDTName = this.stream.readASCIIString();
} else if (prop.type === SendProp.types.DPT_Array) {
prop.numElements = this.stream.readBits(10);
} else {
prop.lowValue = this.stream.readFloat32();
prop.highValue = this.stream.readFloat32();
prop.bitCount = this.stream.readBits(7);
}
}
if (prop.hasFlag(SendProp.flags.SPROP_NOSCALE)) {
if (prop.type === SendProp.types.DPT_Float) {
prop.bitCount = 32;
} else if (prop.type === SendProp.types.DPT_Vector) {
if (!prop.hasFlag(SendProp.flags.SPROP_NORMAL)) {
prop.bitCount = 32 * 3;
}
}
}
if (arrayElementProp) {
if (!prop.type === SendProp.types.DPT_Array) {
throw "expected prop of type array";
}
prop.arrayProperty = arrayElementProp;
arrayElementProp = null;
}
if (prop.hasFlag(SendProp.flags.SPROP_INSIDEARRAY)) {
arrayElementProp = prop;
} else {
table.addProp(prop);
}
}
tables.push(table);
}
this.match.sendTables = tables;
return tables;
};
module.exports = DataTable;
var SentTable = function (name) {
this.name = name;
this.props = [];
};
SentTable.prototype.addProp = function (prop) {
this.props.push(prop);
};
var SendProp = function (type, name, flags) {
this.type = type;
this.name = name;
this.flags = flags;
this.excludeDTName = null;
this.lowValue = 0;
this.highValue = 0;
this.bits = 0;
};
SendProp.prototype.hasFlag = function (flag) {
return (this.flags & flag) != 0;
};
SendProp.prototype.isExcludeProp = function () {
return this.hasFlag(SendProp.flags.SPROP_EXCLUDE);
};
SendProp.types = {
DPT_Int : 0,
DPT_Float : 1,
DPT_Vector : 2,
DPT_VectorXY : 3,// Only encodes the XY of a vector, ignores Z
DPT_String : 4,
DPT_Array : 5,
DPT_DataTable : 6,
DPT_NUMSendPropTypes: 7
};
SendProp.flags = {
SPROP_UNSIGNED : (1 << 0),// Unsigned integer data.
SPROP_COORD : (1 << 1),// If this is set, the float/vector is treated like a world coordinate.
// Note that the bit count is ignored in this case.
SPROP_NOSCALE : (1 << 2),// For floating point, don't scale into range, just take value as is.
SPROP_ROUNDDOWN : (1 << 3),// For floating point, limit high value to range minus one bit unit
SPROP_ROUNDUP : (1 << 4),// For floating point, limit low value to range minus one bit unit
SPROP_NORMAL : (1 << 5),// If this is set, the vector is treated like a normal (only valid for vectors)
SPROP_EXCLUDE : (1 << 6),// This is an exclude prop (not excludED, but it points at another prop to be excluded).
SPROP_XYZE : (1 << 7),// Use XYZ/Exponent encoding for vectors.
SPROP_INSIDEARRAY : (1 << 8),// This tells us that the property is inside an array, so it shouldn't be put into the
// flattened property list. Its array will point at it when it needs to.
SPROP_PROXY_ALWAYS_YES : (1 << 9),// Set for datatable props using one of the default datatable proxies like
// SendProxy_DataTableToDataTable that always send the data to all clients.
SPROP_CHANGES_OFTEN : (1 << 10),// this is an often changed field, moved to head of sendtable so it gets a small index
SPROP_IS_A_VECTOR_ELEM : (1 << 11),// Set automatically if SPROP_VECTORELEM is used.
SPROP_COLLAPSIBLE : (1 << 12),// Set automatically if it's a datatable with an offset of 0 that doesn't change the pointer
// (ie: for all automatically-chained base classes).
// In this case, it can get rid of this SendPropDataTable altogether and spare the
// trouble of walking the hierarchy more than necessary.
SPROP_COORD_MP : (1 << 13),// Like SPROP_COORD, but special handling for multiplayer games
SPROP_COORD_MP_LOWPRECISION: (1 << 14),// Like SPROP_COORD, but special handling for multiplayer games where the fractional component only gets a 3 bits instead of 5
SPROP_COORD_MP_INTEGRAL : (1 << 15)// SPROP_COORD_MP, but coordinates are rounded to integral boundaries
};
SendProp.formatFlags = function (flags) {
var names = [];
for (var name in SendProp.flags) {
if (SendProp.flags.hasOwnProperty(name)) {
if (flags & SendProp.flags[name]) {
names.push(name);
}
}
}
return names;
};
function recvClassInfos(stream, needsDecoder) {
}
module.exports = DataTableParser;

View file

@ -18,7 +18,7 @@ function readIndex(stream, baseIndex) {
return baseIndex + encodedIndex + 1;
}
function readPVS(stream) {
function readPVSType(stream) {
// https://github.com/skadistats/smoke/blob/a2954fbe2fa3936d64aee5b5567be294fef228e6/smoke/io/stream/entity.pyx#L24
var pvs;
var hi = stream.readBoolean();
@ -35,8 +35,14 @@ function readPVS(stream) {
return pvs;
}
function readEnterPVS(stream, entityId) {
}
module.exports = function (stream, events, entities) { //26: packetEntities
// 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
// todo
var maxEntries = stream.readBits(11);
var isDelta = !!stream.readBits(1);
@ -55,9 +61,9 @@ module.exports = function (stream, events, entities) { //26: packetEntities
for (var i = 0; i < updatedEntries; i++) {
entityId = readIndex(stream, entityId);
var pvs = readPVS(stream);
var pvs = readPVSType(stream);
if (pvs = PVS.PRESERVE) {
var entity = readEnterPVS(stream, entityId)
}
}
stream._index = end;