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

add encoder for gameEvent

This commit is contained in:
Robin Appelman 2017-09-04 00:42:11 +02:00
commit 2e43f5bb7f
9 changed files with 802 additions and 118 deletions

View file

@ -3,23 +3,19 @@ import {
GameEventDefinition, GameEventEntry,
GameEventValue, GameEventValueType,
} from '../../Data/GameEvent';
import {GameEvent, GameEventType} from '../../Data/GameEventTypes';
import {GameEvent, GameEventType, GameEventTypeIdMap, GameEventTypeMap} from '../../Data/GameEventTypes';
import {Match} from '../../Data/Match';
import {GameEventPacket} from '../../Data/Packet';
function parseGameEvent(eventId: number, stream: BitStream, events: Map<number, GameEventDefinition<GameEventType>>) {
const eventDescription = events.get(eventId);
if (!eventDescription) {
throw new Error('unknown event type');
}
const values: GameEvent['values'] = {};
for (const entry of eventDescription.entries) {
function parseGameEvent<T extends GameEventType>(definition: GameEventDefinition<T>, stream: BitStream) {
const values: GameEventTypeMap[T]['values'] = {};
for (const entry of definition.entries) {
const value = getGameEventValue(stream, entry);
if (value) {
values[entry.name] = value;
}
}
const name = eventDescription.name;
const name = definition.name as T;
return {
name,
@ -27,6 +23,15 @@ function parseGameEvent(eventId: number, stream: BitStream, events: Map<number,
};
}
function encodeGameEvent<T extends GameEventType>(event: GameEventTypeMap[T], definition: GameEventDefinition<T>, stream: BitStream) {
for (const entry of definition.entries) {
const value = event.values[entry.name];
if (value !== null) {
encodeGameEventValue(value, stream, entry);
}
}
}
function getGameEventValue(stream: BitStream, entry: GameEventEntry): GameEventValue | null {
switch (entry.type) {
case GameEventValueType.STRING:
@ -46,14 +51,77 @@ function getGameEventValue(stream: BitStream, entry: GameEventEntry): GameEventV
}
}
function encodeGameEventValue(value: GameEventValue | null, stream: BitStream, entry: GameEventEntry) {
switch (entry.type) {
case GameEventValueType.STRING:
if (typeof value !== 'string') {
throw new Error('Invalid value for game event');
}
return stream.writeASCIIString(value);
case GameEventValueType.FLOAT:
if (typeof value !== 'number') {
throw new Error('Invalid value for game event');
}
return stream.writeFloat32(value);
case GameEventValueType.LONG:
if (typeof value !== 'number') {
throw new Error('Invalid value for game event');
}
return stream.writeUint32(value);
case GameEventValueType.SHORT:
if (typeof value !== 'number') {
throw new Error('Invalid value for game event');
}
return stream.writeUint16(value);
case GameEventValueType.BYTE:
if (typeof value !== 'number') {
throw new Error('Invalid value for game event');
}
return stream.writeUint8(value);
case GameEventValueType.BOOLEAN:
if (typeof value !== 'boolean') {
throw new Error('Invalid value for game event');
}
return stream.writeBoolean(value);
}
}
export function ParseGameEvent(stream: BitStream, match: Match): GameEventPacket { // 25: game event
const length = stream.readBits(11);
const end = stream.index + length;
const eventId = stream.readBits(9);
const event = parseGameEvent(eventId, stream, match.eventDefinitions);
stream.index = end;
const eventData = stream.readBitStream(length);
const eventType = eventData.readBits(9);
const definition = match.eventDefinitions.get(eventType);
if (!definition) {
throw new Error(`Unknown game event type ${eventType}`);
}
const event = parseGameEvent(definition, eventData);
return {
packetType: 'gameEvent',
event: event as GameEvent,
};
}
export function EncodeGameEvent(packet: GameEventPacket, stream: BitStream, match: Match) {
const lengthStart = stream.index;
stream.index += 11;
const eventId = GameEventTypeIdMap.get(packet.event.name);
if (typeof eventId === 'undefined') {
throw new Error(`Unknown game event type ${packet.event.name}`);
}
const eventDataStart = stream.index;
stream.writeBits(eventId, 9);
const definition = match.eventDefinitions.get(eventId);
if (typeof definition === 'undefined') {
throw new Error(`Unknown game event type ${packet.event.name}`);
}
encodeGameEvent(packet.event, definition, stream);
const eventDataEnd = stream.index;
stream.index = lengthStart;
stream.writeBits(eventDataEnd - eventDataStart, 11);
stream.index = eventDataEnd;
}

View file

@ -1,7 +1,7 @@
import {BitStream} from 'bit-buffer';
import {GameEventDefinition, GameEventEntry} from '../../Data/GameEvent';
import {GameEventListPacket} from '../../Data/Packet';
import {GameEvent} from '../../Data/GameEventTypes';
import {GameEvent, GameEventType} from '../../Data/GameEventTypes';
export function ParseGameEventList(stream: BitStream): GameEventListPacket { // 30: gameEventList
const s = stream.index;
@ -9,7 +9,7 @@ export function ParseGameEventList(stream: BitStream): GameEventListPacket { //
// list of game events and parameters
const numEvents = stream.readBits(9);
const length = stream.readBits(20);
const eventList: Map<number, GameEventDefinition<GameEvent['name']>> = new Map();
const eventList: Map<number, GameEventDefinition<GameEventType>> = new Map();
for (let i = 0; i < numEvents; i++) {
const id = stream.readBits(9);
const name = stream.readASCIIString() as GameEvent['name'];
@ -58,8 +58,8 @@ export function EncodeGameEventList(packet: GameEventListPacket, stream: BitStre
stream.writeBitStream(eventListStream);
}
function getEventListLength(eventList: GameEventDefinition<GameEvent['name']>[]) {
return eventList.reduce((length: number, entry: GameEventDefinition<GameEvent['name']>) => {
function getEventListLength(eventList: GameEventDefinition<GameEventType>[]) {
return eventList.reduce((length: number, entry: GameEventDefinition<GameEventType>) => {
return length +
9 +
(entry.name.length + 1) * 8 +