mirror of
https://github.com/demostf/demo.js
synced 2026-06-03 16:44:12 +02:00
encoder for gameEventList
This commit is contained in:
parent
a0f471cf9a
commit
936ba2263f
6 changed files with 5551 additions and 25 deletions
|
|
@ -5,7 +5,7 @@ import {EncodeClassInfo, ParseClassInfo} from '../Packet/ClassInfo';
|
|||
import {ParseCmdKeyValues} from '../Packet/CmdKeyValues';
|
||||
import {EncodeCreateStringTable, ParseCreateStringTable} from '../Packet/CreateStringTable';
|
||||
import {ParseGameEvent} from '../Packet/GameEvent';
|
||||
import {ParseGameEventList} from '../Packet/GameEventList';
|
||||
import {EncodeGameEventList, ParseGameEventList} from '../Packet/GameEventList';
|
||||
import {ParseMenu} from '../Packet/Menu';
|
||||
import {ParsePacketEntities} from '../Packet/PacketEntities';
|
||||
import {PacketParserMap, voidEncoder} from '../Packet/Parser';
|
||||
|
|
@ -55,7 +55,7 @@ export class Packet extends Parser {
|
|||
27: {parser: ParseTempEntities, encoder: voidEncoder},
|
||||
28: make('preFetch', 'index{14}'),
|
||||
29: {parser: ParseMenu, encoder: voidEncoder},
|
||||
30: {parser: ParseGameEventList, encoder: voidEncoder},
|
||||
30: {parser: ParseGameEventList, encoder: EncodeGameEventList},
|
||||
31: make('getCvarValue', 'cookie{32}value{s}'),
|
||||
32: {parser: ParseCmdKeyValues, encoder: voidEncoder},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import {BitStream} from 'bit-buffer';
|
||||
import {GameEventDefinitionMap, GameEventEntry} from '../../Data/GameEvent';
|
||||
import {Match} from '../../Data/Match';
|
||||
import {GameEventDefinition, GameEventDefinitionMap, GameEventEntry} from '../../Data/GameEvent';
|
||||
import {GameEventListPacket} from '../../Data/Packet';
|
||||
|
||||
export function ParseGameEventList(stream: BitStream, match: Match): GameEventListPacket { // 30: gameEventList
|
||||
export function ParseGameEventList(stream: BitStream): GameEventListPacket { // 30: gameEventList
|
||||
const s = stream.index;
|
||||
|
||||
// list of game events and parameters
|
||||
const numEvents = stream.readBits(9);
|
||||
const length = stream.readBits(20);
|
||||
const numEvents = stream.readBits(9);
|
||||
const length = stream.readBits(20);
|
||||
const eventList: GameEventDefinitionMap = {};
|
||||
for (let i = 0; i < numEvents; i++) {
|
||||
const id = stream.readBits(9);
|
||||
const name = stream.readASCIIString();
|
||||
let type = stream.readBits(3);
|
||||
const id = stream.readBits(9);
|
||||
const name = stream.readASCIIString();
|
||||
let type = stream.readBits(3);
|
||||
const entries: GameEventEntry[] = [];
|
||||
while (type !== 0) {
|
||||
entries.push({
|
||||
|
|
@ -31,3 +32,41 @@ export function ParseGameEventList(stream: BitStream, match: Match): GameEventLi
|
|||
eventList,
|
||||
};
|
||||
}
|
||||
|
||||
export function EncodeGameEventList(packet: GameEventListPacket, stream: BitStream) {
|
||||
stream.writeBits(Object.keys(packet.eventList).length, 9);
|
||||
|
||||
const eventListBitLength = getEventListLength(Object.values(packet.eventList));
|
||||
const eventListStream = new BitStream(new ArrayBuffer(Math.ceil(eventListBitLength / 8)));
|
||||
|
||||
for (const id in packet.eventList) {
|
||||
const definition = packet.eventList[id] as GameEventDefinition;
|
||||
eventListStream.writeBits(definition.id, 9);
|
||||
eventListStream.writeASCIIString(definition.name);
|
||||
for (const entry of definition.entries) {
|
||||
eventListStream.writeBits(entry.type, 3);
|
||||
eventListStream.writeASCIIString(entry.name);
|
||||
}
|
||||
eventListStream.writeBits(0, 3);
|
||||
}
|
||||
|
||||
const finalLength = eventListStream.index;
|
||||
stream.writeBits(finalLength, 20);
|
||||
|
||||
eventListStream.index = 0;
|
||||
stream.writeBitStream(eventListStream);
|
||||
}
|
||||
|
||||
function getEventListLength(eventList: GameEventDefinition[]) {
|
||||
return eventList.reduce((length: number, entry: GameEventDefinition) => {
|
||||
return length +
|
||||
9 +
|
||||
(entry.name.length + 1) * 8 +
|
||||
3 +
|
||||
entry.entries.reduce((length: number, event: GameEventEntry) => {
|
||||
return length +
|
||||
3
|
||||
+ (event.name.length + 1) * 8;
|
||||
}, 0);
|
||||
}, 0);
|
||||
}
|
||||
|
|
|
|||
5396
src/tests/data/gameEventList.json
Normal file
5396
src/tests/data/gameEventList.json
Normal file
File diff suppressed because it is too large
Load diff
1
src/tests/data/gameEventListData.json
Normal file
1
src/tests/data/gameEventListData.json
Normal file
File diff suppressed because one or more lines are too long
89
src/tests/unit/Parser/Packet/GameEventListTest.ts
Normal file
89
src/tests/unit/Parser/Packet/GameEventListTest.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import {BitStream} from 'bit-buffer';
|
||||
import {assertEncoder, assertParser, getStream} from './PacketTest';
|
||||
import {readFileSync} from 'fs';
|
||||
import {EncodeGameEventList, ParseGameEventList} from '../../../../Parser/Packet/GameEventList';
|
||||
|
||||
const data = JSON.parse(readFileSync(__dirname + '/../../../data/gameEventListData.json', 'utf8'));
|
||||
const expected = JSON.parse(readFileSync(__dirname + '/../../../data/gameEventList.json', 'utf8'));
|
||||
|
||||
const eventList = {
|
||||
'packetType': 'gameEventList',
|
||||
'eventList': {
|
||||
'0': {
|
||||
'id': 0,
|
||||
'name': 'server_spawn',
|
||||
'entries': [
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'hostname'
|
||||
},
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'address'
|
||||
},
|
||||
{
|
||||
'type': 3,
|
||||
'name': 'ip'
|
||||
},
|
||||
{
|
||||
'type': 4,
|
||||
'name': 'port'
|
||||
},
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'game'
|
||||
},
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'mapname'
|
||||
},
|
||||
{
|
||||
'type': 3,
|
||||
'name': 'maxplayers'
|
||||
},
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'os'
|
||||
},
|
||||
{
|
||||
'type': 6,
|
||||
'name': 'dedicated'
|
||||
},
|
||||
{
|
||||
'type': 6,
|
||||
'name': 'password'
|
||||
}
|
||||
]
|
||||
},
|
||||
'1': {
|
||||
'id': 1,
|
||||
'name': 'server_changelevel_failed',
|
||||
'entries': [
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'levelname'
|
||||
}
|
||||
]
|
||||
},
|
||||
'2': {
|
||||
'id': 2,
|
||||
'name': 'server_shutdown',
|
||||
'entries': [
|
||||
{
|
||||
'type': 1,
|
||||
'name': 'reason'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
suite('GameEventList', () => {
|
||||
test('Parse gameEventList', () => {
|
||||
assertParser(ParseGameEventList, getStream(data), expected, 122783);
|
||||
});
|
||||
|
||||
test('Encode gameEventList', () => {
|
||||
assertEncoder(ParseGameEventList, EncodeGameEventList, eventList, 1245);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2015.promise",
|
||||
"es5"
|
||||
],
|
||||
"module": "commonjs",
|
||||
"target": "ES5",
|
||||
"outDir": "build",
|
||||
"rootDir": "src",
|
||||
"declaration": true,
|
||||
"strictNullChecks": true,
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2015.promise",
|
||||
"es5",
|
||||
"ES2017"
|
||||
],
|
||||
"module": "commonjs",
|
||||
"target": "ES5",
|
||||
"outDir": "build",
|
||||
"rootDir": "src",
|
||||
"declaration": true,
|
||||
"strictNullChecks": true,
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue