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

updatestring tables wip

This commit is contained in:
Robin Appelman 2015-01-25 15:52:17 +01:00
commit 4736b8a79f
4 changed files with 222 additions and 146 deletions

310
packet.js
View file

@ -1,6 +1,7 @@
var ParserGenerator = require('./parsergenerator'); var ParserGenerator = require('./parsergenerator');
var StringTable = require('./stringtable');
function logBase2(num) { function logBase2 (num) {
var result = 0; var result = 0;
while ((num >>= 1) != 0) { while ((num >>= 1) != 0) {
result++; result++;
@ -50,8 +51,8 @@ Packet.parseGameEvent = function (eventId, stream) {
values[entry.name] = Packet.getGameEventValue(stream, entry); values[entry.name] = Packet.getGameEventValue(stream, entry);
} }
return { return {
name : eventDescription.name, name: eventDescription.name,
type : eventDescription.type, type: eventDescription.type,
values: values values: values
}; };
}; };
@ -76,12 +77,12 @@ Packet.getGameEventValue = function (stream, entry) {
}; };
Packet.parsers = { Packet.parsers = {
0 : function () { 0: function () {
}, },
2 : ParserGenerator.make('file', 'transferId{32}fileName{s}requested{b}'), 2: ParserGenerator.make('file', 'transferId{32}fileName{s}requested{b}'),
3 : ParserGenerator.make('netTick', 'tick{32}frameTime{16}stdDev{16}'), 3: ParserGenerator.make('netTick', 'tick{32}frameTime{16}stdDev{16}'),
4 : ParserGenerator.make('stringCmd', 'command{s}'), 4: ParserGenerator.make('stringCmd', 'command{s}'),
5 : function (stream) { 5: function (stream) {
var count = stream.readBits(8); var count = stream.readBits(8);
var vars = {}; var vars = {};
for (var i = 0; i < count; i++) { for (var i = 0; i < count; i++) {
@ -89,12 +90,12 @@ Packet.parsers = {
} }
return { return {
packetType: 'setConVar', packetType: 'setConVar',
vars : vars vars: vars
} }
}, },
6 : ParserGenerator.make('sigOnState', 'state{8}count{32}'), 6: ParserGenerator.make('sigOnState', 'state{8}count{32}'),
7 : ParserGenerator.make('print', 'value{s}'), 7: ParserGenerator.make('print', 'value{s}'),
8 : ParserGenerator.make('serverInfo', 8: ParserGenerator.make('serverInfo',
'version{16}serverCount{32}stv{b}dedicated{b}maxCrc{32}maxClasses{16}' + 'version{16}serverCount{32}stv{b}dedicated{b}maxCrc{32}maxClasses{16}' +
'mapHash{128}playerCount{8}maxPlayerCount{8}intervalPerTick{f32}platform{s1}' + 'mapHash{128}playerCount{8}maxPlayerCount{8}intervalPerTick{f32}platform{s1}' +
'game{s}map{s}skybox{s}serverName{s}replay{b}'), 'game{s}map{s}skybox{s}serverName{s}replay{b}'),
@ -106,8 +107,8 @@ Packet.parsers = {
var bits = logBase2(number) + 1; var bits = logBase2(number) + 1;
for (var i = 0; i < number; i++) { for (var i = 0; i < number; i++) {
var entry = { var entry = {
'classId' : stream.readBits(bits), 'classId': stream.readBits(bits),
'className' : stream.readASCIIString(), 'className': stream.readASCIIString(),
'dataTableName': stream.readASCIIString() 'dataTableName': stream.readASCIIString()
}; };
entries.push(entry); entries.push(entry);
@ -115,9 +116,9 @@ Packet.parsers = {
} }
return { return {
'packetType': 'classInfo', 'packetType': 'classInfo',
number : number, number: number,
create : create, create: create,
entries : entries entries: entries
} }
}, },
11: ParserGenerator.make('setPause', 'paused{b}'), 11: ParserGenerator.make('setPause', 'paused{b}'),
@ -129,31 +130,27 @@ Packet.parsers = {
var bits = Math.log(maxEntries) / Math.LN2; var bits = Math.log(maxEntries) / Math.LN2;
var numEntries = stream.readBits(bits + 1); var numEntries = stream.readBits(bits + 1);
var length = stream.readBits(20); var length = stream.readBits(20);
var userDataFixedSize = stream.readBits(1); var userDataFixedSize = !!stream.readBits(1);
if (userDataFixedSize) { if (userDataFixedSize) {
var userSize = stream.readBits(12); var userSize = stream.readBits(12);
var userDataBits = stream.readBits(4); var userDataBits = stream.readBits(4);
} }
var data = [];
var end = stream._index + length; var end = stream._index + length;
var stringTable = new PacketStringTable(name, maxEntries, bits, userDataFixedSize, userSize || -1, userDataBits || -1, numEntries);
stringTable.parse(stream);
//console.log(stringTable);
//console.log();
//console.log(length);
//console.log(end - stream._index);
//console.log();
//throw false;
for (var i = 0; i < numEntries; i++) {
data.push(stream.readASCIIString());
stream.readBits(7);
data.push(stream.readASCIIString());
//console.log(stream.readBits(bits + 1));
//stream.readBits(1);
//data.push(stream.readASCIIString());
}
stream._index = end; stream._index = end;
return {packetType: 'createStringTable'}; return {
//return { packetType: 'createStringTable',
// packetType: 'createStringTable', table: stringTable
// name : name, };
// entries : numEntries,
// data : data
//}
}, },
13: function (stream) { 13: function (stream) {
var tableId = stream.readBits(5); var tableId = stream.readBits(5);
@ -161,20 +158,41 @@ Packet.parsers = {
var length = stream.readBits(20); var length = stream.readBits(20);
var end = stream._index + length; var end = stream._index + length;
stream.readBits(7); stream.readBits(7);
var strings = []; var strings = {};
for (var i = 0; i < changeEntries; i++) { //var table = StringTable.tables[tableId];
// // todo cleanup the 8/16 bits that get read in the string here
strings.push(stream.readASCIIString()); // no idea why but it mostly works
var a = stream.readBits(1);
var b = stream.readBits(1);
if (a && !b) {
stream.readBits(12);
} else if (!b) {
stream.readBits(16);
} else {
stream.readBits(6);
} }
//console.log(a ? 'a' : '!a')
//console.log('table: ' + table.name);
//console.log(' ' + table.entries.length + ' entries');
for (var i = 0; i < changeEntries; i++) {
//console.log(stream.readBits(2));
var string = stream.readASCIIString();
stream.readBits(16);
//todo last entry overflows by 13 (3 bits at the end 13 before next entry?)
strings[i] = string;
}
//throw false;
//console.log(changeEntries);
//console.log(strings); //console.log(strings);
//console.log(end - stream._index);
stream._index = end; stream._index = end;
//throw false; //throw false;
return { return {
packetType : 'updateStringTables', packetType: 'updateStringTables',
tableId : tableId, tableId: tableId,
changedEntries: changeEntries, changedEntries: changeEntries,
length : length, length: length,
strings : strings strings: strings
} }
}, },
14: ParserGenerator.make('voiceInit', 'coded{s}quality{8}'), 14: ParserGenerator.make('voiceInit', 'coded{s}quality{8}'),
@ -186,9 +204,9 @@ Packet.parsers = {
stream._index += length; stream._index += length;
return { return {
packetType: 'parseSounds', packetType: 'parseSounds',
reliable : reliable, reliable: reliable,
num : num, num: num,
length : length length: length
} }
}, },
18: ParserGenerator.make('setView', 'index{11}'), 18: ParserGenerator.make('setView', 'index{11}'),
@ -230,12 +248,12 @@ Packet.parsers = {
} }
var lowPriority = !!stream.readBits(1); var lowPriority = !!stream.readBits(1);
return { return {
packetType : 'BSPDecal', packetType: 'BSPDecal',
postition : position, position: position,
textureIndex: textureIndex, textureIndex: textureIndex,
entIndex : entIndex, entIndex: entIndex,
modelIndex : modelIndex, modelIndex: modelIndex,
lowPriority : lowPriority lowPriority: lowPriority
} }
}, },
23: function (stream) { 23: function (stream) {
@ -248,7 +266,7 @@ Packet.parsers = {
} else { } else {
result = { result = {
packetType: 'unknownUserMessage', packetType: 'unknownUserMessage',
type : type type: type
} }
} }
stream._index = pos + length; stream._index = pos + length;
@ -263,7 +281,7 @@ Packet.parsers = {
stream._index = end; stream._index = end;
return { return {
packetType: 'gameEvent', packetType: 'gameEvent',
event : event event: event
} }
}, },
26: function (stream) { 26: function (stream) {
@ -280,19 +298,19 @@ Packet.parsers = {
var updatedBaseLink = !!stream.readBits(1); var updatedBaseLink = !!stream.readBits(1);
stream._index += length; stream._index += length;
return { return {
packetType : 'packetEntities', packetType: 'packetEntities',
maxEntries : maxEntries, maxEntries: maxEntries,
isDelta : isDelta, isDelta: isDelta,
delta : delta, delta: delta,
baseLink : baseLink, baseLink: baseLink,
updatedEntries : updatedEntries, updatedEntries: updatedEntries,
length : length, length: length,
updatedBaseLink: updatedBaseLink updatedBaseLink: updatedBaseLink
} }
}, },
27: ParserGenerator.make('tempEntities', 'count{8}length{17}data{$length}'), 27: ParserGenerator.make('tempEntities', 'count{8}length{17}_{$length}'),
28: ParserGenerator.make('preFetch', 'index{14}'), 28: ParserGenerator.make('preFetch', 'index{14}'),
29: ParserGenerator.make('menu', 'type{16}length{16}data{$length}data{$length}data{$length}data{$length}data{$length}data{$length}data{$length}'),//length*8 29: ParserGenerator.make('menu', 'type{16}length{16}_{$length}_{$length}_{$length}_{$length}_{$length}_{$length}_{$length}'),//length*8
30: function (stream) { 30: function (stream) {
// list of game events and parameters // list of game events and parameters
var numEvents = stream.readBits(9); var numEvents = stream.readBits(9);
@ -312,16 +330,16 @@ Packet.parsers = {
type = stream.readBits(3); type = stream.readBits(3);
} }
events[id] = { events[id] = {
id : id, id: id,
name : name, name: name,
type : type, type: type,
entries: entries entries: entries
}; };
} }
Packet.gameEventMap = events; Packet.gameEventMap = events;
return { return {
packetType: 'gameEventList', packetType: 'gameEventList',
events : events events: events
} }
}, },
31: ParserGenerator.make('getCvarValue', 'cookie{32}value{s}'), 31: ParserGenerator.make('getCvarValue', 'cookie{32}value{s}'),
@ -334,64 +352,114 @@ Packet.userMessageParsers = {
}; };
var UserMessageType = { var UserMessageType = {
Geiger : 0, Geiger: 0,
Train : 1, Train: 1,
HudText : 2, HudText: 2,
SayText : 3, SayText: 3,
SayText2 : 4, SayText2: 4,
TextMsg : 5, TextMsg: 5,
ResetHUD : 6, ResetHUD: 6,
GameTitle : 7, GameTitle: 7,
ItemPickup : 8, ItemPickup: 8,
ShowMenu : 9, ShowMenu: 9,
Shake : 10, Shake: 10,
Fade : 11, Fade: 11,
VGUIMenu : 12, VGUIMenu: 12,
Rumble : 13, Rumble: 13,
CloseCaption : 14, CloseCaption: 14,
SendAudio : 15, SendAudio: 15,
VoiceMask : 16, VoiceMask: 16,
RequestState : 17, RequestState: 17,
Damage : 18, Damage: 18,
HintText : 19, HintText: 19,
KeyHintText : 20, KeyHintText: 20,
HudMsg : 21, HudMsg: 21,
AmmoDenied : 22, AmmoDenied: 22,
AchievementEvent : 23, AchievementEvent: 23,
UpdateRadar : 24, UpdateRadar: 24,
VoiceSubtitle : 25, VoiceSubtitle: 25,
HudNotify : 26, HudNotify: 26,
HudNotifyCustom : 27, HudNotifyCustom: 27,
PlayerStatsUpdate : 28, PlayerStatsUpdate: 28,
PlayerIgnited : 29, PlayerIgnited: 29,
PlayerIgnitedInv : 30, PlayerIgnitedInv: 30,
HudArenaNotify : 31, HudArenaNotify: 31,
UpdateAchievement : 32, UpdateAchievement: 32,
TrainingMsg : 33, TrainingMsg: 33,
TrainingObjective : 34, TrainingObjective: 34,
DamageDodged : 35, DamageDodged: 35,
PlayerJarated : 36, PlayerJarated: 36,
PlayerExtinguished : 37, PlayerExtinguished: 37,
PlayerJaratedFade : 38, PlayerJaratedFade: 38,
PlayerShieldBlocked: 39, PlayerShieldBlocked: 39,
BreakModel : 40, BreakModel: 40,
CheapBreakModel : 41, CheapBreakModel: 41,
BreakModel_Pumpkin : 42, BreakModel_Pumpkin: 42,
BreakModelRocketDud: 43, BreakModelRocketDud: 43,
CallVoteFailed : 44, CallVoteFailed: 44,
VoteStart : 45, VoteStart: 45,
VotePass : 46, VotePass: 46,
VoteFailed : 47, VoteFailed: 47,
VoteSetup : 48, VoteSetup: 48,
PlayerBonusPoints : 49, PlayerBonusPoints: 49,
SpawnFlyingBird : 50, SpawnFlyingBird: 50,
PlayerGodRayEffect : 51, PlayerGodRayEffect: 51,
SPHapWeapEvent : 52, SPHapWeapEvent: 52,
HapDmg : 53, HapDmg: 53,
HapPunch : 54, HapPunch: 54,
HapSetDrag : 55, HapSetDrag: 55,
HapSet : 56, HapSet: 56,
HapMeleeContact : 57 HapMeleeContact: 57
}; };
var PacketStringTable = function (name, maxEntries, entryBits, userDataFixedSize, userDataSize, userDataSizeBits, numEntries) {
this.name = name;
this.maxEntries = maxEntries;
this.entryBits = entryBits;
this.userDataFixedSize = userDataFixedSize;
this.userDataSize = userDataSize;
this.userDataSizeBits = userDataSizeBits;
this.numEntries = numEntries;
this.id = PacketStringTable.tables.length;
this.strings = [];
PacketStringTable.tables.push(this);
};
PacketStringTable.prototype.parse = function (stream) {
var entryIndex, lastEntry = -1;
for (var i = 0; i < this.numEntries; i++) {
entryIndex = lastEntry + 1;
this.strings.push(stream.readASCIIString());
//if (!stream.readBits(1)) {
// entryIndex = stream.readBits(this.entryBits);
//}
//lastEntry = entryIndex;
//if (entryIndex < 0 || entryIndex >= this.maxEntries) {
// throw 'invalid index';
//}
//var string = '';
//if (stream.readBits(1)) {
// if (stream.readBits(1)) {
// throw 'substr not implented';
// } else {
// string = stream.readASCIIString();
// }
//}
if (stream.readBits(1)) { //user data
if (this.userDataFixedSize) {
var userData = stream.readBits(this.userDataSizeBits)
} else {
var bits = stream.readBits(14);
userData = stream.readBits(bits);
}
console.log('userdata: ' + userData);
}
//this.strings.push(string);
}
};
PacketStringTable.tables = [];
module.exports = Packet; module.exports = Packet;

View file

@ -11,7 +11,10 @@ Generator.make = function (name, string) {
}; };
try { try {
for (var i = 0; i < items.length; i++) { for (var i = 0; i < items.length; i++) {
result[items[i][0]] = Generator.readItem(stream, items[i][1], result); var value = Generator.readItem(stream, items[i][1], result);
if(items[i][0] !== '_'){
result[items[i][0]] = value;
}
} }
} catch (e) { } catch (e) {
throw 'Failed reading pattern ' + string; throw 'Failed reading pattern ' + string;

View file

@ -5,39 +5,44 @@ var StringTable = function (type, tick, stream, length) {
this.length = length;//length in bytes this.length = length;//length in bytes
}; };
StringTable.tables = [];
StringTable.prototype.parse = function () { StringTable.prototype.parse = function () {
var tableCount = this.stream.readBits(8); var tableCount = this.stream.readBits(8);
var tables = {}; var tables = {};
try { for (var i = 0; i < tableCount; i++) {
for (var i = 0; i < tableCount; i++) { var entries = [];
var entries = []; var tableName = this.stream.readASCIIString();
var tableName = this.stream.readASCIIString(); var entryCount = this.stream.readBits(16);
var entryCount = this.stream.readBits(16); for (var j = 0; j < entryCount; j++) {
for (var j = 0; j < entryCount; j++) { var entry = {
var entry = { text: this.stream.readASCIIString()
text: this.stream.readASCIIString() };
};
if (this.stream.readBits(1)) {
var extraDataLength = this.stream.readBits(16);
entry.extraData = this.stream.readASCIIString(extraDataLength);
}
entries.push(entry);
}
tables[tableName] = entries;
if (this.stream.readBits(1)) { if (this.stream.readBits(1)) {
this.stream.readASCIIString(); var extraDataLength = this.stream.readBits(16);
if (this.stream.readBits(1)) { entry.extraData = this.stream.readASCIIString(extraDataLength);
//throw 'more extra data not implemented'; //console.log(entry.extraData.length-extraDataLength);
var extraDataLength = this.stream.readBits(16); }
this.stream.readBits(extraDataLength); entries.push(entry);
} }
tables[tableName] = entries;
//console.log(tables);
StringTable.tables.push({
name: tableName,
entries: entries
});
if (this.stream.readBits(1)) {
this.stream.readASCIIString();
if (this.stream.readBits(1)) {
//throw 'more extra data not implemented';
var extraDataLength = this.stream.readBits(16);
this.stream.readBits(extraDataLength);
} }
} }
}catch(e){} }
//console.log(tables);
return [{ return [{
packetType: 'stringTable', packetType: 'stringTable',
tables : tables tables: tables
}]; }];
}; };

View file

@ -1,7 +1,7 @@
var Demo = require('./demo'); var Demo = require('./demo');
var fs = require('fs'); var fs = require('fs');
fs.readFile("upward.dem", function (err, data) { fs.readFile("gully.dem", function (err, data) {
if (err) throw err; if (err) throw err;
var demo = Demo.fromNodeBuffer(data); var demo = Demo.fromNodeBuffer(data);
var parser = demo.getParser(); var parser = demo.getParser();