-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathPacket.ts
More file actions
executable file
·124 lines (107 loc) · 3.81 KB
/
Packet.ts
File metadata and controls
executable file
·124 lines (107 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { handlePlaceholders } from "./utilities/handlePlaceholders";
import { ProtobufHandler } from "@externaladdress4401/beatstar-protobuf/ProtobufHandler";
import { ClientServerMessageHeaderMap } from "@externaladdress4401/beatstar-protobuf/protos/ClientServerMessageHeader";
import { ServerClientMessageHeaderMap } from "@externaladdress4401/beatstar-protobuf/protos/ServerClientMessageHeader";
import { ErrorResp } from "@externaladdress4401/beatstar-protobuf/protos/ErrorResp";
import {
createErrorResp,
createServerClientMessageHeader,
} from "@externaladdress4401/beatstar-protobuf/responses";
export class Packet {
buffer: Buffer;
private _header: ProtobufHandler;
private _payload: ProtobufHandler;
header: Record<string, any> = {};
payload: Record<string, any> = {};
constructor(data: Buffer) {
this.buffer = data;
const handler = new ProtobufHandler("READ", data);
const packetLength = handler.readIntBE();
const headerLength = handler.readIntBE();
const payloadLength = packetLength - 4 - headerLength;
this._header = new ProtobufHandler("READ", handler.slice(headerLength));
this._payload = new ProtobufHandler("READ", handler.slice(payloadLength));
}
process(data: Buffer) {
this.buffer = Buffer.concat([this.buffer, data]);
}
parseHeader(
proto:
| typeof ClientServerMessageHeaderMap
| typeof ServerClientMessageHeaderMap,
) {
if (Object.keys(this.header).length === 0) {
this._header.process();
}
this.header = this._header.parseProto(proto);
return this.header;
}
parsePayload(proto: any) {
if (Object.keys(this.payload).length === 0) {
const processResult = this._payload.process();
if (processResult === null) {
throw new Error(`Unparsable payload found`);
}
}
this.payload = this._payload.parseProto(proto);
return this.payload;
}
async buildResponse(
headerJson: any,
responseJson: any,
payloadProto: any,
compress: boolean = false,
) {
headerJson.version = "1";
headerJson.timestamp = Date.now();
headerJson.tokenId = this.header.rpc;
if (compress) {
headerJson.compressed = true;
}
responseJson.serverTime = Date.now();
const preparedHeader = await new ProtobufHandler("WRITE").writeProto(
headerJson,
ServerClientMessageHeaderMap,
);
const preparedPayload = await new ProtobufHandler("WRITE").writeProto(
responseJson,
payloadProto,
compress,
);
const packetHandler = new ProtobufHandler("WRITE");
packetHandler.writeIntBE(
preparedHeader.length + preparedPayload.length + 4,
);
packetHandler.writeIntBE(preparedHeader.length);
packetHandler.writeBuffer(preparedHeader);
packetHandler.writeBuffer(preparedPayload);
return packetHandler.getUsed();
}
async buildErrorResponse(payloadReplacements?: Record<string, any> | null) {
const headerJson: any = createServerClientMessageHeader({});
const responseJson = createErrorResp({});
headerJson.version = "1";
headerJson.timestamp = Date.now();
headerJson.tokenId = this.header.rpc;
responseJson.serverTime = Date.now();
if (payloadReplacements) {
handlePlaceholders(responseJson, payloadReplacements);
}
const preparedHeader = await new ProtobufHandler("WRITE").writeProto(
headerJson,
ServerClientMessageHeaderMap,
);
const preparedPayload = await new ProtobufHandler("WRITE").writeProto(
responseJson,
ErrorResp,
);
const packetHandler = new ProtobufHandler("WRITE");
packetHandler.writeIntBE(
preparedHeader.length + preparedPayload.length + 4,
);
packetHandler.writeIntBE(preparedHeader.length);
packetHandler.writeBuffer(preparedHeader);
packetHandler.writeBuffer(preparedPayload);
return packetHandler.getUsed();
}
}