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

fix some typings

This commit is contained in:
Robin Appelman 2017-02-12 16:32:38 +01:00
commit ba7ce734e3
7 changed files with 146 additions and 95 deletions

View file

@ -1,7 +1,7 @@
export interface Death {
weapon: string;
victim: number;
assister: number;
assister: number|null;
killer: number;
tick: number;
}

View file

@ -6,7 +6,7 @@ export interface GameEventDefinition {
export interface GameEvent {
name: string;
values: GameEventValueMap;
values: GameEventValues;
}
export interface GameEventEntry {
@ -15,13 +15,32 @@ export interface GameEventEntry {
}
export enum GameEventType {
STRING = 1,
FLOAT = 2,
LONG = 3,
SHORT = 4,
BYTE = 5,
STRING = 1,
FLOAT = 2,
LONG = 3,
SHORT = 4,
BYTE = 5,
BOOLEAN = 6,
LOCAL = 7
LOCAL = 7
}
export interface DeathEventValues {
attacker: number;
userid: number;
assister: number;
weapon: string;
}
export interface RoundWinEventValues {
winreason: number;
team: number;
round_time: number;
}
export interface PlayerSpawnEventValues {
userid: number;
team: number;
'class': number
}
export type GameEventValue = string|number|boolean;
@ -30,6 +49,11 @@ export type GameEventValueMap = {
[name: string]: GameEventValue;
}
export type GameEventValues = GameEventValueMap |
DeathEventValues |
RoundWinEventValues |
PlayerSpawnEventValues;
export type GameEventDefinitionMap = {
[id: number]: GameEventDefinition;
}

View file

@ -17,7 +17,7 @@ import {handlePacketEntities} from "../PacketHandler/PacketEntities";
export class Match {
tick: number;
chat: any[];
users: UserInfo[];
users: {[id: string]: UserInfo};
deaths: Death[];
rounds: any[];
startTick: number;
@ -36,7 +36,7 @@ export class Match {
constructor() {
this.tick = 0;
this.chat = [];
this.users = [];
this.users = {};
this.deaths = [];
this.rounds = [];
this.startTick = 0;
@ -76,9 +76,25 @@ export class Match {
}
getState() {
const users = {};
for (const key in this.users) {
const user = this.users[key];
if (this.users.hasOwnProperty(key)) {
users[key] = {
classes: user.classes,
name: user.name,
steamId: user.steamId,
userId: user.userId,
};
if (user.team) {
users[key].team = user.team;
}
}
}
return {
'chat': this.chat,
'users': this.users,
'users': users,
'deaths': this.deaths,
'rounds': this.rounds,
'startTick': this.startTick,
@ -132,7 +148,8 @@ export class Match {
}
getUserInfoForEntity(entity: Entity): UserInfo {
for (const user of this.users) {
for (const id of Object.keys(this.users)) {
const user = this.users[id];
if (user && user.entityId === entity.entityIndex) {
return user;
}

View file

@ -1,51 +1,58 @@
import {GameEventPacket} from "../Data/Packet";
import {Match} from "../Data/Match";
import {DeathEventValues, RoundWinEventValues, PlayerSpawnEventValues} from "../Data/GameEvent";
export function handleGameEvent(packet: GameEventPacket, match: Match) {
switch (packet.event.name) {
case 'player_death':
while (packet.event.values.assister > 256 && packet.event.values.assister < (1024 * 16)) {
packet.event.values.assister -= 256;
case 'player_death': {
const values = <DeathEventValues>packet.event.values;
while (values.assister > 256 && values.assister < (1024 * 16)) {
values.assister -= 256;
}
const assister = packet.event.values.assister < 256 ? packet.event.values.assister : null;
// todo get player names, not same id as the name string table (entity id)
while (packet.event.values.attacker > 256) {
packet.event.values.attacker -= 256;
const assister = values.assister < 256 ? values.assister : null;
// todo get player names, not same id as the name string table (entity id?)
while (values.attacker > 256) {
values.attacker -= 256;
}
while (packet.event.values.userid > 256) {
packet.event.values.userid -= 256;
while (values.userid > 256) {
values.userid -= 256;
}
match.deaths.push({
killer: packet.event.values.attacker,
killer: values.attacker,
assister: assister,
victim: packet.event.values.userid,
weapon: packet.event.values.weapon,
victim: values.userid,
weapon: values.weapon,
tick: match.tick
});
}
break;
case 'teamplay_round_win':
if (packet.event.values.winreason !== 6) {// 6 = timelimit
case 'teamplay_round_win': {
const values = <RoundWinEventValues>packet.event.values;
if (values.winreason !== 6) {// 6 = timelimit
match.rounds.push({
winner: packet.event.values.team === 2 ? 'red' : 'blue',
length: packet.event.values.round_time,
winner: values.team === 2 ? 'red' : 'blue',
length: values.round_time,
end_tick: match.tick
});
}
}
break;
case 'player_spawn':
const userId = packet.event.values.userid;
case 'player_spawn': {
const values = <PlayerSpawnEventValues>packet.event.values;
const userId = values.userid;
const userState = match.getUserInfo(userId);
const player = match.playerMap[userState.entityId];
userState.team = packet.event.values.team === 2 ? 'red' : 'blue';
const classId = packet.event.values.class;
userState.team = values.team === 2 ? 'red' : 'blue';
const classId = values.class;
if (player) {
player.classId = classId;
player.team = packet.event.values.team;
player.team = values.team;
}
if (!userState.classes[classId]) {
userState.classes[classId] = 0;
}
userState.classes[classId]++;
}
break;
}
}

View file

@ -1,75 +1,77 @@
import {Parser} from './Parser';
import {StringTableEntry} from "../../Data/StringTable";
import {RemoteInfo} from "dgram";
import {StringTablePacket} from "../../Data/Packet";
export class StringTable extends Parser {
parse() {
parse(): StringTablePacket[] {
// we get the tables from the packets
return [{
packetType: 'stringTable',
tables: []
}];
// https://github.com/StatsHelix/demoinfo/blob/3d28ea917c3d44d987b98bb8f976f1a3fcc19821/DemoInfo/ST/StringTableParser.cs
const tableCount = this.stream.readUint8();
let tables = {};
let extraDataLength;
for (let i = 0; i < tableCount; i++) {
let entries:StringTableEntry[] = [];
const tableName = this.stream.readASCIIString();
const entryCount = this.stream.readUint16();
for (let j = 0; j < entryCount; j++) {
let entry;
try {
entry = {
text: this.stream.readUTF8String()
};
} catch (e) {
return [{
packetType: 'stringTable',
tables: tables
}];
}
if (this.stream.readBoolean()) {
extraDataLength = this.stream.readUint16();
if ((extraDataLength * 8) > this.stream.bitsLeft) {
// extradata to long, can't continue parsing the tables
// seems to happen in POV demos after the MyM update
return [{
packetType: 'stringTable',
tables: tables
}];
}
if (tableName === 'instancebaseline') {
this.match.staticBaseLines[parseInt(entry.text, 10)] = this.stream.readBitStream(8 * extraDataLength);
} else {
entry.extraData = this.readExtraData(extraDataLength);
}
}
entries.push(entry);
}
tables[tableName] = entries;
this.match.stringTables.push({
name: tableName,
entries: entries
});
if (this.stream.readBits(1)) {
this.stream.readASCIIString();
if (this.stream.readBits(1)) {
//throw 'more extra data not implemented';
extraDataLength = this.stream.readBits(16);
this.stream.readBits(extraDataLength);
}
}
}
return [{
packetType: 'stringTable',
tables: tables
}];
// const tableCount = this.stream.readUint8();
// let tables = {};
// let extraDataLength;
// for (let i = 0; i < tableCount; i++) {
// let entries: StringTableEntry[] = [];
// const tableName = this.stream.readASCIIString();
// const entryCount = this.stream.readUint16();
// for (let j = 0; j < entryCount; j++) {
// let entry;
// try {
// entry = {
// text: this.stream.readUTF8String()
// };
// } catch (e) {
// return [{
// packetType: 'stringTable',
// tables: tables
// }];
// }
// if (this.stream.readBoolean()) {
// extraDataLength = this.stream.readUint16();
// if ((extraDataLength * 8) > this.stream.bitsLeft) {
// // extradata to long, can't continue parsing the tables
// // seems to happen in POV demos after the MyM update
// return [{
// packetType: 'stringTable',
// tables: tables
// }];
// }
// if (tableName === 'instancebaseline') {
// this.match.staticBaseLines[parseInt(entry.text, 10)] = this.stream.readBitStream(8 * extraDataLength);
// } else {
// entry.extraData = this.readExtraData(extraDataLength);
// }
// }
// entries.push(entry);
// }
// tables[tableName] = entries;
// this.match.stringTables.push({
// name: tableName,
// entries: entries,
// maxEntries: 0
// });
// if (this.stream.readBits(1)) {
// this.stream.readASCIIString();
// if (this.stream.readBits(1)) {
// //throw 'more extra data not implemented';
// extraDataLength = this.stream.readBits(16);
// this.stream.readBits(extraDataLength);
// }
// }
// }
// return [{
// packetType: 'stringTable',
// tables: tables
// }];
}
readExtraData(length):string[] {
const end = this.stream.index + (length * 8);
let data:string[] = [];
readExtraData(length): string[] {
const end = this.stream.index + (length * 8);
let data: string[] = [];
//console.log(this.stream.readUTF8String());
data.push(this.stream.readUTF8String());
while (this.stream.index < end && this.stream.index < (this.stream.length - 7)) { // -7 because we need a full byte

View file

@ -1,11 +1,12 @@
import {Parser} from './Parser';
import {Packet} from "../../Data/Packet";
export function make(name: string, definition: string): Parser {
const parts = definition.substr(0, definition.length - 1).split('}');//remove leading } to prevent empty part
const items = parts.map(function (part) {
return part.split('{');
});
return function (stream) {
return function (stream):Packet {
let result = {
'packetType': name
};
@ -19,7 +20,7 @@ export function make(name: string, definition: string): Parser {
} catch (e) {
throw new Error('Failed reading pattern ' + definition + '. ' + e);
}
return result;
return <Packet>result;
}
}

View file

@ -80,7 +80,7 @@ export function UserMessage(stream: BitStream): UserMessagePacket { // 23: user
result = {
packetType: 'unknownUserMessage',
type: type
}
};
}
stream.index = pos + length;
return result;