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

More robust userinfo handling

This commit is contained in:
Robin Appelman 2017-12-09 16:49:05 +01:00
commit 93151788ae
9 changed files with 88 additions and 73 deletions

View file

@ -1,4 +1,3 @@
import {BitStream} from 'bit-buffer';
import {handleGameEvent} from '../PacketHandler/GameEvent';
import {handlePacketEntities} from '../PacketHandler/PacketEntities';
import {handleSayText2} from '../PacketHandler/SayText2';
@ -11,7 +10,6 @@ import {ParserState} from './ParserState';
import {Player} from './Player';
import {PlayerResource} from './PlayerResource';
import {Round} from './Round';
import {StringTableEntry} from './StringTable';
import {Team, TeamNumber} from './Team';
import {UserInfo} from './UserInfo';
import {Weapon} from './Weapon';
@ -44,6 +42,9 @@ export class Match {
public getState() {
const users = {};
for (const userEntity of this.parserState.userInfo.values()) {
this.getUserInfo(userEntity.userId);
}
for (const [key, user] of this.users.entries()) {
users[key] = {
classes: user.classes,
@ -80,11 +81,6 @@ export class Match {
case 'serverInfo':
this.intervalPerTick = packet.intervalPerTick;
break;
case 'createStringTable':
if (packet.table.name === 'userinfo') {
this.calculateUserInfo();
}
break;
case 'userMessage':
switch (packet.userMessageType) {
case 'sayText2':
@ -105,62 +101,33 @@ export class Match {
userId -= 256;
}
const user = this.users.get(userId);
if (!user) {
if (!user) {
const entityInfo = this.parserState.getUserEntityInfo(userId);
const newUser = {
name: '',
userId,
steamId: '',
classes: {},
entityId: 0,
team: ''
team: '',
...entityInfo
};
this.users.set(userId, newUser);
return newUser;
} else if (!user.steamId) {
const entityInfo = this.parserState.getUserEntityInfo(userId);
if (entityInfo.steamId) {
user.steamId = entityInfo.steamId;
user.entityId = entityInfo.entityId;
user.name = entityInfo.name;
}
}
return user;
}
public getUserInfoForEntity(entity: PacketEntity): UserInfo | null {
for (const user of this.users.values()) {
if (user && user.entityId === entity.entityIndex) {
return user;
for (const userEntity of this.parserState.userInfo.values()) {
if (userEntity && userEntity.entityId === entity.entityIndex) {
return this.getUserInfo(userEntity.userId);
}
}
return this.calculateUserInfoByEntityId(entity.entityIndex);
}
private calculateUserInfo() {
for (const [text, extraData] of this.parserState.userInfoEntries.entries()) {
this.calculateUserInfoFromEntry(text, extraData);
}
}
private calculateUserInfoByEntityId(entityId: number) {
const text = `${entityId - 1}`;
const extraData = this.parserState.userInfoEntries.get(text);
if (!extraData) {
throw new Error(`No user info in stringtable for entity id ${entityId}`);
}
return this.calculateUserInfoFromEntry(text, extraData);
}
private calculateUserInfoFromEntry(text: string, extraData: BitStream): UserInfo {
if (extraData.bitsLeft > (32 * 8)) {
const name = extraData.readUTF8String(32);
const userId = extraData.readUint32();
const steamId = extraData.readUTF8String();
if (steamId) {
const userState = this.getUserInfo(userId);
userState.name = name;
userState.steamId = steamId;
userState.entityId = parseInt(text, 10) + 1;
return userState;
} else {
throw new Error(`No steamid for user info ${text}`);
}
} else {
throw new Error();
}
return null;
}
}

View file

@ -14,6 +14,7 @@ import {SendProp} from './SendProp';
import {SendTable, SendTableName} from './SendTable';
import {ServerClass, ServerClassId} from './ServerClass';
import {StringTable} from './StringTable';
import {UserEntityInfo, UserId} from './UserInfo';
export class ParserState {
public version: number = 0;
@ -27,7 +28,7 @@ export class ParserState {
public serverClasses: ServerClass[] = [];
public instanceBaselines: [Map<EntityId, SendProp[]>, Map<EntityId, SendProp[]>] = [new Map(), new Map()];
public skippedPackets: PacketTypeId[] = [];
public userInfoEntries: Map<string, BitStream> = new Map();
public userInfo: Map<UserId, UserEntityInfo> = new Map();
public tick: number = 0;
public handlePacket(packet: Packet) {
@ -87,6 +88,19 @@ export class ParserState {
handleTable(table, this);
}
}
public getUserEntityInfo(userId: number): UserEntityInfo {
const info = this.userInfo.get(userId);
if (info) {
return info;
}
return {
name: '',
userId,
steamId: '',
entityId: 0
};
}
}
export function getClassBits(state: ParserState) {

View file

@ -1,8 +1,13 @@
export interface UserInfo {
name: string;
userId: number;
steamId: string;
entityId: number;
export interface UserInfo extends UserEntityInfo {
classes: any;
team: string;
}
export type UserId = number;
export interface UserEntityInfo {
name: string;
userId: UserId;
steamId: string;
entityId: number;
}