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

parse deaths and strictly type packet types

This commit is contained in:
Robin Appelman 2017-02-12 15:09:03 +01:00
commit cb02fdee9b
18 changed files with 217 additions and 119 deletions

7
src/Data/Death.ts Normal file
View file

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

View file

@ -9,11 +9,13 @@ import {UserInfo} from "./UserInfo";
import {World} from "./World";
import {Vector} from "./Vector";
import {Player} from "./Player";
import {Death} from "./Death";
import {HandlerMap} from "../PacketHandler/Handler";
export class Match {
tick: number;
chat: any[];
users: UserInfo[];
deaths: any[];
deaths: Death[];
rounds: any[];
startTick: number;
intervalPerTick: number;
@ -53,18 +55,18 @@ export class Match {
}
getSendTable(name) {
for (var i = 0; i < this.sendTables.length; i++) {
if (this.sendTables[i].name === name) {
return this.sendTables[i];
for (const table of this.sendTables) {
if (table.name === name) {
return table;
}
}
throw new Error("unknown SendTable " + name);
}
getStringTable(name) {
for (var i = 0; i < this.stringTables.length; i++) {
if (this.stringTables[i].name === name) {
return this.stringTables[i];
for (const table of this.stringTables) {
if (table.name === name) {
return table;
}
}
return null;
@ -112,10 +114,10 @@ export class Match {
if (table.name === 'userinfo') {
for (const userData of table.entries) {
if (userData.extraData) {
if (userData.extraData.bitsLeft > (32*8)) {
const name = userData.extraData.readUTF8String(32);
const userId = userData.extraData.readUint32();
const steamId = userData.extraData.readUTF8String();
if (userData.extraData.bitsLeft > (32 * 8)) {
const name = userData.extraData.readUTF8String(32);
const userId = userData.extraData.readUint32();
const steamId = userData.extraData.readUTF8String();
if (steamId) {
const userState = this.getUserInfo(userId);
userState.name = name;
@ -163,13 +165,12 @@ export class Match {
case 'player_spawn':
const userId = packet.event.values.userid;
const userState = this.getUserInfo(userId);
const player = this.playerMap[userState.entityId];
if (!userState.team) { //only register first spawn
userState.team = packet.event.values.team === 2 ? 'red' : 'blue'
}
const classId = packet.event.values.class;
const player = this.playerMap[userState.entityId];
userState.team = packet.event.values.team === 2 ? 'red' : 'blue';
const classId = packet.event.values.class;
if (player) {
player.classId = classId;
player.team = packet.event.values.team;
}
if (!userState.classes[classId]) {
userState.classes[classId] = 0;
@ -209,6 +210,15 @@ export class Match {
throw new Error('User not found for entity ' + entity.entityIndex);
}
getPlayerByUserId(userId: number): Player {
for (const player of this.players) {
if (player.user.userId === userId) {
return player;
}
}
throw new Error('player not found for user id');
}
get classBits() {
return Math.ceil(Math.log(this.serverClasses.length) * Math.LOG2E)
}
@ -220,42 +230,48 @@ export class Match {
this.world.boundaryMax = <Vector>entity.getProperty('DT_WORLD', 'm_WorldMaxs').value;
break;
case 'CTFPlayer':
const player: Player = (this.playerMap[entity.entityIndex]) ? this.playerMap[entity.entityIndex] : {
user: this.getUserInfoForEntity(entity),
position: new Vector(0, 0, 0),
maxHealth: 0,
health: 0,
};
if (!this.playerMap[entity.entityIndex]) {
this.playerMap[entity.entityIndex] = player;
this.players.push(player);
}
for (const prop of entity.updatedProps) {
const propName = prop.definition.ownerTableName + '.' + prop.definition.name;
// console.log(propName, prop.value);
switch (propName) {
case 'DT_BasePlayer.m_iHealth':
player.health = <number>prop.value;
break;
case 'DT_BasePlayer.m_iMaxHealth':
player.maxHealth = <number>prop.value;
break;
case 'DT_TFLocalPlayerExclusive.m_vecOrigin':
player.position.x = (<Vector>prop.value).x;
player.position.y = (<Vector>prop.value).y;
break;
case 'DT_TFNonLocalPlayerExclusive.m_vecOrigin':
player.position.x = (<Vector>prop.value).x;
player.position.y = (<Vector>prop.value).y;
break;
case 'DT_TFLocalPlayerExclusive.m_vecOrigin[2]':
player.position.z = <number>prop.value;
break;
case 'DT_TFNonLocalPlayerExclusive.m_vecOrigin[2]':
player.position.z = <number>prop.value;
break;
try {
const player: Player = (this.playerMap[entity.entityIndex]) ? this.playerMap[entity.entityIndex] : {
user: this.getUserInfoForEntity(entity),
position: new Vector(0, 0, 0),
maxHealth: 0,
health: 0,
classId: 0,
team: 0
};
if (!this.playerMap[entity.entityIndex]) {
this.playerMap[entity.entityIndex] = player;
this.players.push(player);
}
for (const prop of entity.updatedProps) {
const propName = prop.definition.ownerTableName + '.' + prop.definition.name;
// console.log(propName, prop.value);
switch (propName) {
case 'DT_BasePlayer.m_iHealth':
player.health = <number>prop.value;
break;
case 'DT_BasePlayer.m_iMaxHealth':
player.maxHealth = <number>prop.value;
break;
case 'DT_TFLocalPlayerExclusive.m_vecOrigin':
player.position.x = (<Vector>prop.value).x;
player.position.y = (<Vector>prop.value).y;
break;
case 'DT_TFNonLocalPlayerExclusive.m_vecOrigin':
player.position.x = (<Vector>prop.value).x;
player.position.y = (<Vector>prop.value).y;
break;
case 'DT_TFLocalPlayerExclusive.m_vecOrigin[2]':
player.position.z = <number>prop.value;
break;
case 'DT_TFNonLocalPlayerExclusive.m_vecOrigin[2]':
player.position.z = <number>prop.value;
break;
}
}
} catch (e) {
}
}

View file

@ -1,4 +1,93 @@
export interface Packet {
packetType: string;
[name: string]: any;
import {StringTable} from "./StringTable";
import {Vector} from "./Vector";
import {GameEvent} from "./GameEvent";
export interface StringTablePacket {
packetType: 'stringTable';
tables: StringTable[];
}
export interface BSPDecalPacket {
packetType: 'bspDecal';
position: Vector;
textureIndex: number;
entIndex: number;
modelIndex: number;
lowPriority: boolean;
}
export interface ClassInfoPacket {
packetType: 'classInfo';
number: number;
create: boolean;
entries: {
classId: number;
className: string;
dataTableName: string;
}[]
}
export interface EntityMessagePacket {
packetType: 'entityMessage';
classId: number;
length: number;
data: string;
}
export interface GameEventPacket {
packetType: 'gameEvent';
event: GameEvent;
}
export interface GameEventListPacket {
packetType: 'gameEventList';
}
export interface PacketEntitiesPacket {
packetType: 'packetEntities';
}
export interface ParseSoundsPacket {
packetType: 'parseSounds';
reliable: boolean;
num: number;
length: number;
}
export interface SetConVarPacket {
packetType: 'setConVar';
vars: {[key: string]: string};
}
export interface SayText2Packet {
packetType: 'sayText2';
client: number;
raw: number;
kind: string;
from: string;
text: string;
}
export interface TextMessagePacket {
packetType: 'textMsg';
destType: number;
text: string;
}
export interface UnknownUserMessagePacket {
packetType: 'unknownUserMessage';
type: number;
}
export type UserMessagePacket = SayText2Packet | TextMessagePacket | UnknownUserMessagePacket;
export type Packet = BSPDecalPacket |
StringTablePacket |
ClassInfoPacket |
EntityMessagePacket |
GameEventPacket |
GameEventListPacket |
PacketEntitiesPacket |
ParseSoundsPacket |
SetConVarPacket |
UserMessagePacket;

View file

@ -6,4 +6,5 @@ export interface Player {
health: number;
maxHealth: number;
classId: number;
team: number;
}