1
0
Fork 0
mirror of https://github.com/demostf/demo.js synced 2026-06-03 16:44:12 +02:00

add encoder for usermessage

This commit is contained in:
Robin Appelman 2017-09-03 22:50:46 +02:00
commit 55abaaff7a
5 changed files with 109 additions and 12 deletions

View file

@ -62,7 +62,7 @@ export enum UserMessageType {
HapMeleeContact = 57,
}
export interface BaseDataUserPacket {
export interface BaseDataUserPacket extends BasePacket {
data: number;
}
@ -75,9 +75,16 @@ export interface SayText2Packet extends BasePacket {
text: string;
}
export enum HudTextLocation {
HUD_PRINTNOTIFY = 1,
HUD_PRINTCONSOLE = 2,
HUD_PRINTTALK = 3,
HUD_PRINTCENTER = 4
}
export interface TextMessagePacket extends BasePacket {
packetType: 'textMsg';
destType: number;
destType: HudTextLocation;
text: string;
}
@ -137,14 +144,15 @@ export type UserMessageTypeMap = {
voiceSubtitle: VoiceSubtitlePacket;
breakModelPumpkin: BreakModelPumpkinPacket;
resetHUD: ResetHUDPacket;
shake: ShakePacket;
}
export const UserMessagePacketTypeMap: Map<UserMessagePacket['packetType'], UserMessageType> = new Map<UserMessagePacket['packetType'], UserMessageType>([
['unknownUserMessage', 0],
['sayText2', UserMessageType.SayText2],
['textMsg', UserMessageType.TextMsg],
['train', UserMessageType.Train],
['voiceSubtitle', UserMessageType.VoiceSubtitle],
['breakModelPumpkin', UserMessageType.BreakModel_Pumpkin],
['resetHUD', UserMessageType.ResetHUD]
['resetHUD', UserMessageType.ResetHUD],
['shake', UserMessageType.Shake]
]);

View file

@ -10,15 +10,17 @@ import {EncodeParseSounds, ParseParseSounds} from '../Packet/ParseSounds';
import {EncodeSetConVar, ParseSetConVar} from '../Packet/SetConVar';
import {ParseTempEntities} from '../Packet/TempEntities';
import {EncodeUpdateStringTable, ParseUpdateStringTable} from '../Packet/UpdateStringTable';
import {ParseUserMessage} from '../Packet/UserMessage';
import {EncodeUserMessage, ParseUserMessage} from '../Packet/UserMessage';
import {EncodeVoiceData, ParseVoiceData} from '../Packet/VoiceData';
import {EncodeVoiceInit, ParseVoiceInit} from '../Packet/VoiceInit';
import {Parser} from './Parser';
import {Packet as IPacket, PacketTypeId} from '../../Data/Packet';
type PacketHandlerMap = Map<PacketTypeId, PacketHandler<IPacket>>;
export class Packet extends Parser {
private static parsers: Map<PacketTypeId, PacketHandler<IPacket>> = new Map<PacketTypeId, PacketHandler<IPacket>>([
private static handlers: PacketHandlerMap = new Map<PacketTypeId, PacketHandler<IPacket>>([
[PacketTypeId.file,
make('file', 'transferId{32}fileName{s}requested{b}')],
[PacketTypeId.netTick,
@ -57,7 +59,7 @@ export class Packet extends Parser {
[PacketTypeId.bspDecal,
{parser: ParseBSPDecal, encoder: EncodeBSPDecal}],
[PacketTypeId.userMessage,
{parser: ParseUserMessage, encoder: voidEncoder}],
{parser: ParseUserMessage, encoder: EncodeUserMessage}],
[PacketTypeId.entityMessage,
make('entityMessage', 'index{11}classId{9}length{11}data{$length}')],
[PacketTypeId.gameEvent,
@ -84,7 +86,7 @@ export class Packet extends Parser {
while (this.bitsLeft > 6) { // last 6 bits for NOOP
const type = this.stream.readBits(6) as PacketTypeId;
if (type !== 0) {
const parser = Packet.parsers.get(type);
const parser = Packet.handlers.get(type);
if (parser) {
const skip = this.skippedPackets.indexOf(type) !== -1;
const packet = parser.parser(this.stream, this.match, skip);

View file

@ -1,4 +1,4 @@
import {Packet, PacketMapType, PacketType} from '../../Data/Packet';
import {PacketMapType, PacketType} from '../../Data/Packet';
import {Encoder, PacketHandler, Parser} from './Parser';
import {BitStream} from 'bit-buffer';

View file

@ -22,8 +22,6 @@ function unknownPacketHandler<T extends UnknownUserMessagePacket['packetType']>(
},
encoder: (packet: UnknownUserMessageBasePacket, data: BitStream) => {
packet.data.index = 0;
data.writeUint8(packet.type);
data.writeBits(packet.data.length, 11);
data.writeBitStream(packet.data);
packet.data.index = 0;
}
@ -32,7 +30,7 @@ function unknownPacketHandler<T extends UnknownUserMessagePacket['packetType']>(
const userMessageParsers: Map<UserMessageType, PacketHandler<UserMessagePacket>> = new Map<UserMessageType, PacketHandler<UserMessagePacket>>([
[UserMessageType.SayText2, {parser: ParseSayText2, encoder: EncodeSayText2}],
[UserMessageType.TextMsg, make('textMsg', 'destType{8}text{s}')],
[UserMessageType.TextMsg, make('textMsg', 'destType{8}text{s}substitute1{s}substitute2{s}substitute3{s}substitute4{s}')],
[UserMessageType.ResetHUD, make('resetHUD', 'data{8}')],
[UserMessageType.Train, make('train', 'data{8}')],
[UserMessageType.VoiceSubtitle, make('voiceSubtitle', 'client{8}menu{8}item{8}')],
@ -41,6 +39,7 @@ const userMessageParsers: Map<UserMessageType, PacketHandler<UserMessagePacket>>
]);
export function ParseUserMessage(stream: BitStream): UserMessagePacket { // 23: user message
const s = stream.index;
const type = stream.readUint8();
const length = stream.readBits(11);
const messageData = stream.readBitStream(length);
@ -57,3 +56,37 @@ export function ParseUserMessage(stream: BitStream): UserMessagePacket { // 23:
return handler.parser(messageData);
}
}
export function EncodeUserMessage(packet: UserMessagePacket, stream: BitStream) {
if (packet.packetType === 'unknownUserMessage') {
stream.writeUint8(packet.type);
stream.writeBits(packet.data.length, 11);
packet.data.index = 0;
stream.writeBitStream(packet.data);
packet.data.index = 0;
} else {
const messageType = UserMessagePacketTypeMap.get(packet.packetType);
if (!messageType) {
throw new Error(`Unknown userMessage type ${messageType}`);
}
stream.writeUint8(messageType);
const lengthStart = stream.index;
stream.index += 11;
const messageDataStart = stream.index;
const handler = userMessageParsers.get(messageType);
if (!handler) {
throw new Error(`No encoder for userMessage ${packet.packetType}(${messageType})`);
}
handler.encoder(packet, stream);
const messageDataEnd = stream.index;
stream.index = lengthStart;
stream.writeBits(messageDataEnd - messageDataStart, 11);
stream.index = messageDataEnd;
}
}

View file

@ -0,0 +1,54 @@
import {BitStream} from 'bit-buffer';
import {assertEncoder, assertParser, getStream} from './PacketTest';
import {EncodeUserMessage, ParseUserMessage} from '../../../../Parser/Packet/UserMessage';
import {HudTextLocation} from '../../../../Data/UserMessage';
const data = [
5,
200,
8,
24,
57,
10,
107,
43,
251,
26,
123,
115,
115,
43,
27,
163,
43,
35,
3,
152,
43,
91,
147,
3,
0,
0,
0,
24];
const expected = {
packetType: 'textMsg',
destType: HudTextLocation.HUD_PRINTNOTIFY,
text: '#Game_connected',
substitute1: 'sekr',
substitute2: '',
substitute3: '',
substitute4: '',
};
suite('SayText2', () => {
test('Parse sayText2', () => {
assertParser(ParseUserMessage, getStream(data), expected, 219);
});
test('Encode sayText2', () => {
assertEncoder(ParseUserMessage, EncodeUserMessage, expected, 219);
});
});