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

better handling of user messages

This commit is contained in:
Robin Appelman 2017-09-27 01:26:27 +02:00
commit 171b5c4049
6 changed files with 86 additions and 45 deletions

View file

@ -1,16 +1,20 @@
import {BitStream} from 'bit-buffer';
import {PacketMapType, PacketType} from '../../Data/Packet';
import {Packet, PacketMapType, PacketType} from '../../Data/Packet';
import {Encoder, PacketHandler, Parser} from './Parser';
import {UserMessagePacketType} from '../../Data/UserMessage';
export function make<T extends PacketType>(name: T, definition: string): PacketHandler<PacketMapType[T]> {
export interface NamedPacketHandler<P extends Packet, N extends PacketType | UserMessagePacketType> extends PacketHandler<P> {
name: N;
}
export function make<T extends PacketType | UserMessagePacketType>(name: T, definition: string, nameKey: string = 'packetType', extraData: any = {}): NamedPacketHandler<PacketMapType[T], T> {
const parts = definition.split('}');
const items = parts.map((part) => {
return part.split('{');
}).filter((part) => part[0]);
const parser: Parser<PacketMapType[T]> = (stream: BitStream) => {
const result = {
packetType: name
};
const result = Object.assign({}, extraData);
result[nameKey] = name;
try {
for (const group of items) {
const value = readItem(stream, group[1], result);
@ -28,7 +32,7 @@ export function make<T extends PacketType>(name: T, definition: string): PacketH
writeItem(stream, group[1], packet, packet[group[0]]);
}
};
return {parser, encoder};
return {parser, encoder, name};
}
function readItem(stream: BitStream, description: string, data) {

View file

@ -2,21 +2,21 @@ import {BitStream} from 'bit-buffer';
import {
UnknownUserMessageBasePacket,
UnknownUserMessagePacket,
UserMessagePacket,
UserMessagePacket, UserMessagePacketType,
UserMessagePacketTypeMap,
UserMessageType,
UserMessageTypeMap
} from '../../Data/UserMessage';
import {EncodeSayText2, ParseSayText2} from '../UserMessage/SayText2';
import {PacketHandler} from './Parser';
import {make} from './ParserGenerator';
import {make, NamedPacketHandler} from './ParserGenerator';
function unknownPacketHandler<T extends UnknownUserMessagePacket['packetType']>(packetType: T): PacketHandler<UserMessageTypeMap[T]> {
function unknownPacketHandler<T extends UnknownUserMessagePacket['userMessageType']>(userMessageType: T): NamedPacketHandler<UserMessageTypeMap[T], UserMessagePacketType> {
return {
parser: (data: BitStream) => {
return {
packetType,
type: UserMessagePacketTypeMap.get(packetType),
packetType: 'userMessage',
userMessageType,
type: UserMessagePacketTypeMap.get(userMessageType),
data
} as UserMessageTypeMap[T];
},
@ -24,23 +24,38 @@ function unknownPacketHandler<T extends UnknownUserMessagePacket['packetType']>(
packet.data.index = 0;
data.writeBitStream(packet.data);
packet.data.index = 0;
}
},
name: userMessageType
};
}
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}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}')],
const userMessageParsers: Map<UserMessageType, NamedPacketHandler<UserMessagePacket, UserMessagePacketType>> =
new Map<UserMessageType, NamedPacketHandler<UserMessagePacket, UserMessagePacketType>>([
[UserMessageType.SayText2, {parser: ParseSayText2, encoder: EncodeSayText2, name: 'sayText2'}],
[UserMessageType.TextMsg,
make('textMsg', 'destType{8}text{s}substitute1{s}substitute2{s}substitute3{s}substitute4{s}', 'userMessageType', {
packetType: 'userMessage'
})],
[UserMessageType.ResetHUD,
make('resetHUD', 'data{8}', 'userMessageType', {
packetType: 'userMessage'
})],
[UserMessageType.Train,
make('train', 'data{8}', 'userMessageType', {
packetType: 'userMessage'
})],
[UserMessageType.VoiceSubtitle,
make('voiceSubtitle', 'client{8}menu{8}item{8}', 'userMessageType', {
packetType: 'userMessage'
})],
[UserMessageType.BreakModel_Pumpkin, unknownPacketHandler('breakModelPumpkin')],
[UserMessageType.Shake, make('shake', 'command{8}amplitude{f32}frequency{f32}duration{f32}')]
[UserMessageType.Shake,
make('shake', 'command{8}amplitude{f32}frequency{f32}duration{f32}', 'userMessageType', {
packetType: 'userMessage'
})]
]);
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);
@ -49,7 +64,8 @@ export function ParseUserMessage(stream: BitStream): UserMessagePacket { // 23:
if (!handler) {
return {
packetType: 'unknownUserMessage',
packetType: 'userMessage',
userMessageType: 'unknownUserMessage',
type,
data: messageData
};
@ -59,14 +75,14 @@ export function ParseUserMessage(stream: BitStream): UserMessagePacket { // 23:
}
export function EncodeUserMessage(packet: UserMessagePacket, stream: BitStream) {
if (packet.packetType === 'unknownUserMessage') {
if (packet.userMessageType === '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);
const messageType = UserMessagePacketTypeMap.get(packet.userMessageType);
if (!messageType) {
throw new Error(`Unknown userMessage type ${messageType}`);
}
@ -78,7 +94,7 @@ export function EncodeUserMessage(packet: UserMessagePacket, stream: BitStream)
const handler = userMessageParsers.get(messageType);
if (!handler) {
throw new Error(`No encoder for userMessage ${packet.packetType}(${messageType})`);
throw new Error(`No encoder for userMessage ${packet.userMessageType}(${messageType})`);
}
handler.encoder(packet, stream);