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:
parent
55abaaff7a
commit
2e43f5bb7f
9 changed files with 802 additions and 118 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 +
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue