1
0
Fork 0
mirror of https://github.com/demostf/demo.js synced 2026-06-03 16:44:12 +02:00

refactor state handling a bit

+ some random other changes I forgot to commit earlier
This commit is contained in:
Robin Appelman 2016-04-23 15:41:56 +02:00
commit c43627e3c1
11 changed files with 75 additions and 92 deletions

View file

@ -1,12 +1,11 @@
var util = require('util');
var Parser = require('./parser');
var State = require('./state');
var BitStream = require('bit-buffer').BitStream;
var StreamParser = function (stream) {
this.stream = stream;
this.state = new State();
this.on('packet', this.state.updateState.bind(this.state));
this.match = new Match();
this.on('packet', this, match.handlePacket.bind(this.match));
this.header = null;
this.buffer = new Buffer(0);
};
@ -27,7 +26,7 @@ StreamParser.prototype.eatBuffer = function (length) {
StreamParser.prototype.start = function () {
this.stream.on('data', this.handleData.bind(this));
this.stream.on('end', function () {
this.emit('done', this.state.get());
this.emit('done', this.match);
}.bind(this));
};

View file

@ -30,12 +30,12 @@ fs.readFile(argv._[0], function (err, data) {
echo(head);
return;
}
var body = parser.parseBody();
var match = parser.parseBody();
if (argv.dump) {
echo(parser.packets);
echo(parser.match.packets);
} else if (argv.strings) {
echo(parser.strings);
echo(parser.match.strings);
} else {
echo(body);
echo(match.getState());
}
});

View file

@ -1,8 +1,9 @@
var ConsoleCmd = function (type, tick, stream, length) {
var ConsoleCmd = function (type, tick, stream, length, match) {
this.type = type;
this.tick = tick;
this.stream = stream;
this.length = length;//length in bytes
this.match = match;
};
ConsoleCmd.prototype.parse = function () {

View file

@ -1,8 +1,9 @@
var DataTable = function (type, tick, stream, length) {
var DataTable = function (type, tick, stream, length, match) {
this.type = type;
this.tick = tick;
this.stream = stream;
this.length = length;//length in bytes
this.match = match;
};
DataTable.prototype.parse = function () {

View file

@ -3,5 +3,7 @@ var ParserGenerator = require('../../parsergenerator');
var baseParser = ParserGenerator.make('entityMessage', 'index{11}classId{9}length{11}data{$length}');
module.exports = function (stream) { // 24: entityMessage
return baseParser(stream); //todo parse data further?
var data = baseParser(stream); //todo parse data further?
// console.log(data.index);
return data;
};

View file

@ -36,6 +36,7 @@ function readPVS(stream) {
}
module.exports = function (stream, events, entities) { //26: packetEntities
// https://github.com/skadistats/smoke/blob/master/smoke/replay/handler/svc_packetentities.pyx
// todo
var maxEntries = stream.readBits(11);
var isDelta = !!stream.readBits(1);
@ -50,15 +51,15 @@ module.exports = function (stream, events, entities) { //26: packetEntities
var updatedBaseLink = !!stream.readBits(1);
var end = stream._index + length;
//console.log('max: ' + maxEntries);
//var entityId = -1;
//
//for (var i = 0; i < updatedEntries; i++) {
// entityId = readIndex(stream, entityId);
// var pvs = readPVS(stream);
// if (pvs = PVS.PRESERVE) {
//
// }
//}
var entityId = -1;
for (var i = 0; i < updatedEntries; i++) {
entityId = readIndex(stream, entityId);
var pvs = readPVS(stream);
if (pvs = PVS.PRESERVE) {
}
}
stream._index = end;
//var ent = {
// packetType : 'packetEntities',

View file

@ -1,33 +1,40 @@
var State = function () {
var Match = function () {
this.tick = 0;
this.state = {
chat : [],
users : {},
deaths : [],
rounds : [],
startTick : 0,
intervalPerTick: 0
this.chat = [];
this.users = {};
this.deaths = [];
this.rounds = [];
this.startTick = 0;
this.intervalPerTick = 0;
this.entities = [];
this.stringTables = [];
};
Match.prototype.getState = function () {
return {
'chat' : this.chat,
'users' : this.users,
'deaths' : this.deaths,
'rounds' : this.rounds,
'startTick' : this.startTick,
'intervalPerTick': this.intervalPerTick
};
};
State.prototype.get = function () {
return this.state;
};
State.prototype.updateState = function (packet) {
Match.prototype.handlePacket = function (packet) {
var userState;
switch (packet.packetType) {
case 'netTick':
if (this.state.startTick === 0) {
this.state.startTick = packet.tick;
if (this.startTick === 0) {
this.startTick = packet.tick;
}
this.tick = packet.tick;
break;
case 'serverInfo':
this.state.intervalPerTick = packet.intervalPerTick;
this.intervalPerTick = packet.intervalPerTick;
break;
case 'sayText2':
this.state.chat.push({
this.chat.push({
kind: packet.kind,
from: packet.from,
text: packet.text,
@ -62,7 +69,7 @@ State.prototype.updateState = function (packet) {
while (packet.event.values.userid > 256) {
packet.event.values.userid -= 256;
}
this.state.deaths.push({
this.deaths.push({
killer : packet.event.values.attacker,
assister: assister,
victim : packet.event.values.userid,
@ -72,7 +79,7 @@ State.prototype.updateState = function (packet) {
break;
case 'teamplay_round_win':
if (packet.event.values.winreason !== 6) {// 6 = timelimit
this.state.rounds.push({
this.rounds.push({
winner : packet.event.values.team === 2 ? 'red' : 'blue',
length : packet.event.values.round_time,
end_tick: this.tick
@ -96,21 +103,21 @@ State.prototype.updateState = function (packet) {
}
};
State.prototype.getUserState = function (userId) {
Match.prototype.getUserState = function (userId) {
// no clue why it does this
// only seems to be the case with per user ready
while (userId > 256) {
userId -= 256;
}
if (!this.state.users[userId]) {
this.state.users[userId] = {
if (!this.users[userId]) {
this.users[userId] = {
name : null,
userId : userId,
steamId: null,
classes: {}
}
}
return this.state.users[userId];
return this.users[userId];
};
module.exports = State;
module.exports = Match;

View file

@ -5,12 +5,13 @@ var ParserGenerator = require('./parsergenerator');
// https://github.com/stgn/netdecode/blob/master/Packet.cs
// https://github.com/LestaD/SourceEngine2007/blob/master/src_main/common/netmessages.cpp
var Packet = function (type, tick, stream, length, viewOrigin) {
var Packet = function (type, tick, stream, length, viewOrigin, match) {
this.type = type;
this.tick = tick;
this.stream = stream;
this.length = length;//length in bytes
this.viewOrigin = viewOrigin;
this.match = match;
};
Packet.gameEventMap = {};

View file

@ -1,19 +1,18 @@
var util = require('util');
var Packet = require('./packet');
var State = require('./state');
var ConsoleCmd = require('./consolecmd');
var StringTable = require('./stringtable');
var DataTable = require('./datatable');
var UserCmd = require('./usercmd');
var BitStream = require('bit-buffer').BitStream;
var EventEmitter = require('events').EventEmitter;
var Match = require('./match');
var Parser = function (stream) {
this.stream = stream;
this.state = new State();
this.packets = [];
this.strings = {};
this.on('packet', this.state.updateState.bind(this.state));
this.match = new Match();
this.on('packet', this.match.handlePacket.bind(this.match));
this.on('packet', function (packet) {
this.packets.push(packet);
});
@ -54,29 +53,28 @@ Parser.prototype.parseHeader = function (stream) {
Parser.prototype.parseBody = function () {
var message;
while (message = this.readMessage(this.stream)) {
while (message = this.readMessage(this.stream, this.match)) {
this.handleMessage(message);
}
this.strings = StringTable.tables;
this.emit('done', this.state.get());
return this.state.get();
this.emit('done', this.match);
return this.match;
};
Parser.prototype.parseMessage = function (buffer, type, tick, length, viewOrigin) {
Parser.prototype.parseMessage = function (buffer, type, tick, length, viewOrigin, match) {
var data = new BitStream(buffer);
switch (type) {
case Parser.MessageType.Sigon:
case Parser.MessageType.Packet:
return new Packet(type, tick, data, length, viewOrigin);
return new Packet(type, tick, data, length, viewOrigin, match);
case Parser.MessageType.ConsoleCmd:
return new ConsoleCmd(type, tick, data, length);
return new ConsoleCmd(type, tick, data, length, match);
case Parser.MessageType.UserCmd:
return new UserCmd(type, tick, data, length, this.viewOrigin, this.viewAngles);
return new UserCmd(type, tick, data, length, match);
case Parser.MessageType.DataTables:
return new DataTable(type, tick, data, length);
return new DataTable(type, tick, data, length, match);
case Parser.MessageType.StringTables:
return new StringTable(type, tick, data, length);
return new StringTable(type, tick, data, length, match);
default:
return true;
}
@ -94,7 +92,7 @@ Parser.prototype.handleMessage = function (message) {
}
};
Parser.prototype.readMessage = function (stream) {
Parser.prototype.readMessage = function (stream, match) {
var type = stream.readBits(8);
if (type === Parser.MessageType.Stop) {
return null;
@ -138,7 +136,7 @@ Parser.prototype.readMessage = function (stream) {
start = stream.byteIndex;
buffer = stream.buffer.slice(start, start + length);
stream.byteIndex += length;
return this.parseMessage(buffer, type, tick, length, viewOrigin);
return this.parseMessage(buffer, type, tick, length, viewOrigin, match);
};
module.exports = Parser;

View file

@ -1,12 +1,11 @@
var StringTable = function (type, tick, stream, length) {
var StringTable = function (type, tick, stream, length, match) {
this.type = type;
this.tick = tick;
this.stream = stream;
this.length = length;//length in bytes
this.match = match;
};
StringTable.tables = [];
StringTable.prototype.parse = function () {
var tableCount = this.stream.readBits(8);
var tables = {};
@ -33,7 +32,7 @@ StringTable.prototype.parse = function () {
entries.push(entry);
}
tables[tableName] = entries;
StringTable.tables.push({
this.match.stringTables.push({
name : tableName,
entries: entries
});

View file

@ -1,39 +1,13 @@
var UserCMD = function (type, tick, stream, length, viewOrigin, viewAngles) {
var UserCMD = function (type, tick, stream, length, match) {
this.type = type;
this.tick = tick;
this.stream = stream;
this.length = length;//length in bytes
this.viewOrigin = viewOrigin;
this.viewAngles = viewAngles;
this.match = match;
};
UserCMD.prototype.parse = function () {
return [];
var divSize = Math.floor((this.length + 2) / 4);
var byteShift = new Array(3);
var lastByte = this.stream.readBits(8);
var TempUCMD = 0;
for (var i = 1; i < divSize; i++) {
var byte = this.stream.readBits(8);
if (i <= 4) {
byteShift[0] = lastByte >> i;
byteShift[1] = byte << 32 - i;
} else {
byteShift[0] = lastByte >> 9;
byteShift[1] = byte << 32 - i;
}
byteShift[2] = byteShift[0] | byteShift[0];
if (i == divSize - 1) {
if (byteShift[2] > 0 && byteShift[2] < 1321100) {
TempUCMD = byteShift[2];
} else {
TempUCMD = null;
}
}
lastByte = byte;
}
// console.log('move', this.tick, this.viewOrigin[0][0], this.viewOrigin[0][1], this.viewAngles[0][0], this.viewAngles[0][1], TempUCMD);
return [];
};
module.exports = UserCMD;