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:
parent
2d26dfdfb5
commit
c43627e3c1
11 changed files with 75 additions and 92 deletions
|
|
@ -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));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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 = {};
|
||||
|
|
|
|||
30
parser.js
30
parser.js
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
|
|
|
|||
30
usercmd.js
30
usercmd.js
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue