@serenityjs/raknet 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.d.ts +829 -0
- package/dist/index.js +1743 -0
- package/package.json +36 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1743 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
20
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
21
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
22
|
+
if (decorator = decorators[i])
|
|
23
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
24
|
+
if (kind && result)
|
|
25
|
+
__defProp(target, key, result);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/index.ts
|
|
30
|
+
var src_exports = {};
|
|
31
|
+
__export(src_exports, {
|
|
32
|
+
Ack: () => Ack,
|
|
33
|
+
Address: () => Address,
|
|
34
|
+
BasePacket: () => BasePacket,
|
|
35
|
+
Bitflags: () => Bitflags,
|
|
36
|
+
ConnectedPing: () => ConnectedPing,
|
|
37
|
+
ConnectedPong: () => ConnectedPong,
|
|
38
|
+
Connection: () => Connection,
|
|
39
|
+
ConnectionRequest: () => ConnectionRequest,
|
|
40
|
+
ConnectionRequestAccepted: () => ConnectionRequestAccepted,
|
|
41
|
+
DataType: () => DataType,
|
|
42
|
+
Disconnect: () => Disconnect,
|
|
43
|
+
Frame: () => Frame,
|
|
44
|
+
FrameSet: () => FrameSet,
|
|
45
|
+
MTU: () => MTU,
|
|
46
|
+
Magic: () => Magic,
|
|
47
|
+
MaxMtuSize: () => MaxMtuSize,
|
|
48
|
+
MinMtuSize: () => MinMtuSize,
|
|
49
|
+
Nack: () => Nack,
|
|
50
|
+
Offline: () => Offline,
|
|
51
|
+
OpenConnectionReply1: () => OpenConnectionReply1,
|
|
52
|
+
OpenConnectionReply2: () => OpenConnectionReply2,
|
|
53
|
+
OpenConnectionRequest1: () => OpenConnectionRequest1,
|
|
54
|
+
OpenConnectionRequest2: () => OpenConnectionRequest2,
|
|
55
|
+
Packet: () => Packet,
|
|
56
|
+
Priority: () => Priority,
|
|
57
|
+
Proto: () => Proto,
|
|
58
|
+
Protocol: () => Protocol,
|
|
59
|
+
RaknetServer: () => RaknetServer,
|
|
60
|
+
RaknetTPS: () => RaknetTPS,
|
|
61
|
+
RaknetTickLength: () => RaknetTickLength,
|
|
62
|
+
Reliability: () => Reliability,
|
|
63
|
+
Serialize: () => Serialize,
|
|
64
|
+
Status: () => Status,
|
|
65
|
+
SystemAddress: () => SystemAddress,
|
|
66
|
+
UnconnectedPing: () => UnconnectedPing,
|
|
67
|
+
UnconnectedPong: () => UnconnectedPong,
|
|
68
|
+
udpHeaderSize: () => udpHeaderSize
|
|
69
|
+
});
|
|
70
|
+
module.exports = __toCommonJS(src_exports);
|
|
71
|
+
var import_reflect_metadata = require("reflect-metadata");
|
|
72
|
+
|
|
73
|
+
// src/decorators/proto.ts
|
|
74
|
+
function Proto(id) {
|
|
75
|
+
return function(target) {
|
|
76
|
+
target.id = id;
|
|
77
|
+
const metadata = Reflect.getOwnMetadata(
|
|
78
|
+
"properties",
|
|
79
|
+
target.prototype
|
|
80
|
+
);
|
|
81
|
+
const properties = Object.getOwnPropertyNames(target.prototype);
|
|
82
|
+
if (!properties.includes("serialize"))
|
|
83
|
+
target.prototype.serialize = function() {
|
|
84
|
+
this.flush();
|
|
85
|
+
target.id_type.write(this, target.id);
|
|
86
|
+
if (!metadata)
|
|
87
|
+
return this.getBuffer();
|
|
88
|
+
for (const { name, type, endian, parameter } of metadata) {
|
|
89
|
+
if (parameter) {
|
|
90
|
+
const value = this[parameter];
|
|
91
|
+
type.write(this, this[name], endian, value);
|
|
92
|
+
} else {
|
|
93
|
+
type.write(this, this[name], endian);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return this.getBuffer();
|
|
97
|
+
};
|
|
98
|
+
if (!properties.includes("deserialize"))
|
|
99
|
+
target.prototype.deserialize = function() {
|
|
100
|
+
if (this.binary.length === 0)
|
|
101
|
+
return this;
|
|
102
|
+
target.id_type.read(this);
|
|
103
|
+
if (!metadata)
|
|
104
|
+
return this;
|
|
105
|
+
for (const { name, type, endian, parameter } of metadata) {
|
|
106
|
+
if (parameter) {
|
|
107
|
+
const value = this[parameter];
|
|
108
|
+
this[name] = type.read(
|
|
109
|
+
this,
|
|
110
|
+
endian,
|
|
111
|
+
value
|
|
112
|
+
);
|
|
113
|
+
} else {
|
|
114
|
+
this[name] = type.read(
|
|
115
|
+
this,
|
|
116
|
+
endian
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return this;
|
|
121
|
+
};
|
|
122
|
+
if (!properties.includes("getId"))
|
|
123
|
+
target.prototype.getId = function() {
|
|
124
|
+
return target.id;
|
|
125
|
+
};
|
|
126
|
+
if (!properties.includes("getIdType"))
|
|
127
|
+
target.prototype.getIdType = function() {
|
|
128
|
+
return target.id_type;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/decorators/serialize.ts
|
|
134
|
+
var import_binarystream = require("@serenityjs/binarystream");
|
|
135
|
+
function Serialize(type, endian = import_binarystream.Endianness.Big, parameter) {
|
|
136
|
+
if (!type)
|
|
137
|
+
throw new Error("@Serialize() failed, no type provided.");
|
|
138
|
+
return function(target, name) {
|
|
139
|
+
const properties = Reflect.getMetadata("properties", target) || [];
|
|
140
|
+
properties.push({ name, type, endian, parameter });
|
|
141
|
+
Reflect.defineMetadata("properties", properties, target);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/proto/data/type.ts
|
|
146
|
+
var import_binarystream2 = require("@serenityjs/binarystream");
|
|
147
|
+
var DataType = class {
|
|
148
|
+
/**
|
|
149
|
+
* Creates a new data type.
|
|
150
|
+
*/
|
|
151
|
+
constructor(..._arguments_) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Reads the data type from a binary stream.
|
|
156
|
+
* @param _stream The binary stream to read from.
|
|
157
|
+
* @param _endian The endianness to use.
|
|
158
|
+
* @param _parameter An optional parameter.
|
|
159
|
+
* @returns The data type.
|
|
160
|
+
*/
|
|
161
|
+
static read(_stream, _endian = import_binarystream2.Endianness.Big, _parameter) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Writes the data type to a binary stream.
|
|
166
|
+
* @param _stream The binary stream to write to.
|
|
167
|
+
* @param _value The data type to write.
|
|
168
|
+
* @param _endian The endianness to use.
|
|
169
|
+
* @param _parameter An optional parameter.
|
|
170
|
+
*/
|
|
171
|
+
static write(_stream, _value, _endian = import_binarystream2.Endianness.Big, _parameter) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/proto/data/magic.ts
|
|
177
|
+
var MagicBuffer = Buffer.from(
|
|
178
|
+
"\0\xFF\xFF\0\xFE\xFE\xFE\xFE\xFD\xFD\xFD\xFD4Vx",
|
|
179
|
+
"binary"
|
|
180
|
+
);
|
|
181
|
+
var Magic = class extends DataType {
|
|
182
|
+
/**
|
|
183
|
+
* Reads the magic data type from a binary stream.
|
|
184
|
+
* @param stream The binary stream to read from.
|
|
185
|
+
* @returns The magic data type.
|
|
186
|
+
*/
|
|
187
|
+
static read(stream) {
|
|
188
|
+
return stream.readBuffer(MagicBuffer.length);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Writes the magic data type to a binary stream.
|
|
192
|
+
* @param stream The binary stream to write to.
|
|
193
|
+
*/
|
|
194
|
+
static write(stream) {
|
|
195
|
+
stream.writeBuffer(MagicBuffer);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// src/proto/data/mtu.ts
|
|
200
|
+
var MTU = class extends DataType {
|
|
201
|
+
/**
|
|
202
|
+
* Reads the mtu data type from a binary stream.
|
|
203
|
+
* @param stream The binary stream to read from.
|
|
204
|
+
* @returns The mtu data type.
|
|
205
|
+
*/
|
|
206
|
+
static read(stream) {
|
|
207
|
+
return stream.getBuffer().byteLength;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Writes the mtu data type to a binary stream.
|
|
211
|
+
* @param stream The binary stream to write to.
|
|
212
|
+
* @param value The value to write.
|
|
213
|
+
*/
|
|
214
|
+
static write(stream, value) {
|
|
215
|
+
stream.writeBuffer(Buffer.alloc(value - stream.getBuffer().length));
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// src/proto/data/address.ts
|
|
220
|
+
var Address = class _Address extends DataType {
|
|
221
|
+
/**
|
|
222
|
+
* The address of the data type.
|
|
223
|
+
*/
|
|
224
|
+
address;
|
|
225
|
+
/**
|
|
226
|
+
* The port of the data type.
|
|
227
|
+
*/
|
|
228
|
+
port;
|
|
229
|
+
/**
|
|
230
|
+
* The version of the data type.
|
|
231
|
+
*/
|
|
232
|
+
version;
|
|
233
|
+
/**
|
|
234
|
+
* Initializes a new instance of the Address data type.
|
|
235
|
+
* @param address The address of the data type.
|
|
236
|
+
* @param port The port of the data type.
|
|
237
|
+
* @param version The version of the data type.
|
|
238
|
+
*/
|
|
239
|
+
constructor(address, port, version) {
|
|
240
|
+
super();
|
|
241
|
+
this.address = address;
|
|
242
|
+
this.port = port;
|
|
243
|
+
this.version = version;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Converts the Address data type to a NetworkIdentifier.
|
|
247
|
+
*
|
|
248
|
+
* @param identifier The NetworkIdentifier.
|
|
249
|
+
* @returns The NetworkIdentifier.
|
|
250
|
+
*/
|
|
251
|
+
static fromIdentifier(identifier) {
|
|
252
|
+
return new _Address(identifier.address, identifier.port, identifier.version);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Reads the Address data type from a binary stream.
|
|
256
|
+
* @param stream The binary stream to read from.
|
|
257
|
+
* @returns The Address data type.
|
|
258
|
+
*/
|
|
259
|
+
static read(stream) {
|
|
260
|
+
const version = stream.readUint8();
|
|
261
|
+
if (version === 4) {
|
|
262
|
+
const addressBuffer = stream.read(4);
|
|
263
|
+
const address = addressBuffer.map((byte) => -byte - 1 & 255).join(".");
|
|
264
|
+
const port = stream.readUShort();
|
|
265
|
+
return new _Address(address, port, version);
|
|
266
|
+
} else {
|
|
267
|
+
stream.skip(2);
|
|
268
|
+
const port = stream.readUShort();
|
|
269
|
+
stream.skip(16);
|
|
270
|
+
const addressBuffer = stream.read(4);
|
|
271
|
+
const address = addressBuffer.filter((byte) => byte !== 255).join(".");
|
|
272
|
+
stream.skip(4);
|
|
273
|
+
return new _Address(address, port, version);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Writes the Address data type to a binary stream.
|
|
278
|
+
* @param stream The binary stream to write to.
|
|
279
|
+
* @param value The value to write.
|
|
280
|
+
*/
|
|
281
|
+
static write(stream, value) {
|
|
282
|
+
const { address, port, version } = value;
|
|
283
|
+
stream.writeUint8(version);
|
|
284
|
+
const addressBits = address.split(".", 4);
|
|
285
|
+
for (const bit of addressBits) {
|
|
286
|
+
stream.writeUint8(Number(bit));
|
|
287
|
+
}
|
|
288
|
+
stream.writeUShort(port);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/proto/data/frame.ts
|
|
293
|
+
var import_binarystream3 = require("@serenityjs/binarystream");
|
|
294
|
+
|
|
295
|
+
// src/enums/packet.ts
|
|
296
|
+
var Packet = /* @__PURE__ */ ((Packet2) => {
|
|
297
|
+
Packet2[Packet2["ConnectedPing"] = 0] = "ConnectedPing";
|
|
298
|
+
Packet2[Packet2["UnconnectedPing"] = 1] = "UnconnectedPing";
|
|
299
|
+
Packet2[Packet2["ConnectedPong"] = 3] = "ConnectedPong";
|
|
300
|
+
Packet2[Packet2["OpenConnectionRequest1"] = 5] = "OpenConnectionRequest1";
|
|
301
|
+
Packet2[Packet2["OpenConnectionReply1"] = 6] = "OpenConnectionReply1";
|
|
302
|
+
Packet2[Packet2["OpenConnectionRequest2"] = 7] = "OpenConnectionRequest2";
|
|
303
|
+
Packet2[Packet2["OpenConnectionReply2"] = 8] = "OpenConnectionReply2";
|
|
304
|
+
Packet2[Packet2["ConnectionRequest"] = 9] = "ConnectionRequest";
|
|
305
|
+
Packet2[Packet2["ConnectionRequestAccepted"] = 16] = "ConnectionRequestAccepted";
|
|
306
|
+
Packet2[Packet2["NewIncomingConnection"] = 19] = "NewIncomingConnection";
|
|
307
|
+
Packet2[Packet2["Disconnect"] = 21] = "Disconnect";
|
|
308
|
+
Packet2[Packet2["IncompatibleProtocolVersion"] = 25] = "IncompatibleProtocolVersion";
|
|
309
|
+
Packet2[Packet2["UnconnectedPong"] = 28] = "UnconnectedPong";
|
|
310
|
+
Packet2[Packet2["FrameSet"] = 128] = "FrameSet";
|
|
311
|
+
Packet2[Packet2["Nack"] = 160] = "Nack";
|
|
312
|
+
Packet2[Packet2["Ack"] = 192] = "Ack";
|
|
313
|
+
return Packet2;
|
|
314
|
+
})(Packet || {});
|
|
315
|
+
|
|
316
|
+
// src/enums/bit-flags.ts
|
|
317
|
+
var Bitflags = /* @__PURE__ */ ((Bitflags2) => {
|
|
318
|
+
Bitflags2[Bitflags2["Valid"] = 128] = "Valid";
|
|
319
|
+
Bitflags2[Bitflags2["Ack"] = 64] = "Ack";
|
|
320
|
+
Bitflags2[Bitflags2["Nak"] = 32] = "Nak";
|
|
321
|
+
Bitflags2[Bitflags2["Split"] = 16] = "Split";
|
|
322
|
+
return Bitflags2;
|
|
323
|
+
})(Bitflags || {});
|
|
324
|
+
|
|
325
|
+
// src/enums/priority.ts
|
|
326
|
+
var Priority = /* @__PURE__ */ ((Priority2) => {
|
|
327
|
+
Priority2[Priority2["Normal"] = 0] = "Normal";
|
|
328
|
+
Priority2[Priority2["Immediate"] = 1] = "Immediate";
|
|
329
|
+
return Priority2;
|
|
330
|
+
})(Priority || {});
|
|
331
|
+
|
|
332
|
+
// src/enums/status.ts
|
|
333
|
+
var Status = /* @__PURE__ */ ((Status2) => {
|
|
334
|
+
Status2[Status2["Connecting"] = 0] = "Connecting";
|
|
335
|
+
Status2[Status2["Connected"] = 1] = "Connected";
|
|
336
|
+
Status2[Status2["Disconnecting"] = 2] = "Disconnecting";
|
|
337
|
+
Status2[Status2["Disconnected"] = 3] = "Disconnected";
|
|
338
|
+
return Status2;
|
|
339
|
+
})(Status || {});
|
|
340
|
+
|
|
341
|
+
// src/enums/reliability.ts
|
|
342
|
+
var Reliability = /* @__PURE__ */ ((Reliability2) => {
|
|
343
|
+
Reliability2[Reliability2["Unreliable"] = 0] = "Unreliable";
|
|
344
|
+
Reliability2[Reliability2["UnreliableSequenced"] = 1] = "UnreliableSequenced";
|
|
345
|
+
Reliability2[Reliability2["Reliable"] = 2] = "Reliable";
|
|
346
|
+
Reliability2[Reliability2["ReliableOrdered"] = 3] = "ReliableOrdered";
|
|
347
|
+
Reliability2[Reliability2["ReliableSequenced"] = 4] = "ReliableSequenced";
|
|
348
|
+
Reliability2[Reliability2["UnreliableWithAckReceipt"] = 5] = "UnreliableWithAckReceipt";
|
|
349
|
+
Reliability2[Reliability2["ReliableWithAckReceipt"] = 6] = "ReliableWithAckReceipt";
|
|
350
|
+
Reliability2[Reliability2["ReliableOrderedWithAckReceipt"] = 7] = "ReliableOrderedWithAckReceipt";
|
|
351
|
+
return Reliability2;
|
|
352
|
+
})(Reliability || {});
|
|
353
|
+
|
|
354
|
+
// src/proto/data/frame.ts
|
|
355
|
+
var Frame = class _Frame extends DataType {
|
|
356
|
+
/**
|
|
357
|
+
* The reliability of the frame.
|
|
358
|
+
*/
|
|
359
|
+
reliability;
|
|
360
|
+
/**
|
|
361
|
+
* The reliable index of the frame.
|
|
362
|
+
*/
|
|
363
|
+
reliableIndex;
|
|
364
|
+
/**
|
|
365
|
+
* The sequence index of the frame.
|
|
366
|
+
*/
|
|
367
|
+
sequenceIndex;
|
|
368
|
+
/**
|
|
369
|
+
* The order index of the frame.
|
|
370
|
+
*/
|
|
371
|
+
orderIndex;
|
|
372
|
+
/**
|
|
373
|
+
* The order channel of the frame.
|
|
374
|
+
*/
|
|
375
|
+
orderChannel;
|
|
376
|
+
/**
|
|
377
|
+
* The fragment size of the frame.
|
|
378
|
+
*/
|
|
379
|
+
fragmentSize;
|
|
380
|
+
/**
|
|
381
|
+
* The fragment id of the frame.
|
|
382
|
+
*/
|
|
383
|
+
fragmentId;
|
|
384
|
+
/**
|
|
385
|
+
* The fragment index of the frame.
|
|
386
|
+
*/
|
|
387
|
+
fragmentIndex;
|
|
388
|
+
/**
|
|
389
|
+
* The payload of the frame.
|
|
390
|
+
*/
|
|
391
|
+
payload;
|
|
392
|
+
/**
|
|
393
|
+
* Checks if the frame is fragmented.
|
|
394
|
+
* @returns True if the frame is fragmented; otherwise, false.
|
|
395
|
+
*/
|
|
396
|
+
isFragmented() {
|
|
397
|
+
return this.fragmentSize > 0;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Checks if the frame is reliable.
|
|
401
|
+
* @returns True if the frame is reliable; otherwise, false.
|
|
402
|
+
*/
|
|
403
|
+
isReliable() {
|
|
404
|
+
const values = [
|
|
405
|
+
2 /* Reliable */,
|
|
406
|
+
3 /* ReliableOrdered */,
|
|
407
|
+
4 /* ReliableSequenced */,
|
|
408
|
+
6 /* ReliableWithAckReceipt */,
|
|
409
|
+
7 /* ReliableOrderedWithAckReceipt */
|
|
410
|
+
];
|
|
411
|
+
return values.includes(this.reliability);
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Checks if the frame is sequenced.
|
|
415
|
+
* @returns True if the frame is sequenced; otherwise, false.
|
|
416
|
+
*/
|
|
417
|
+
isSequenced() {
|
|
418
|
+
const values = [
|
|
419
|
+
4 /* ReliableSequenced */,
|
|
420
|
+
1 /* UnreliableSequenced */
|
|
421
|
+
];
|
|
422
|
+
return values.includes(this.reliability);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Checks if the frame is ordered.
|
|
426
|
+
* @returns True if the frame is ordered; otherwise, false.
|
|
427
|
+
*/
|
|
428
|
+
isOrdered() {
|
|
429
|
+
const values = [
|
|
430
|
+
1 /* UnreliableSequenced */,
|
|
431
|
+
3 /* ReliableOrdered */,
|
|
432
|
+
4 /* ReliableSequenced */,
|
|
433
|
+
7 /* ReliableOrderedWithAckReceipt */
|
|
434
|
+
];
|
|
435
|
+
return values.includes(this.reliability);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Checks if the frame is order exclusive.
|
|
439
|
+
* @returns True if the frame is order exclusive; otherwise, false.
|
|
440
|
+
*/
|
|
441
|
+
isOrderExclusive() {
|
|
442
|
+
const values = [
|
|
443
|
+
3 /* ReliableOrdered */,
|
|
444
|
+
7 /* ReliableOrderedWithAckReceipt */
|
|
445
|
+
];
|
|
446
|
+
return values.includes(this.reliability);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Gets the byte length of the frame.
|
|
450
|
+
* @returns The byte length of the frame.
|
|
451
|
+
*/
|
|
452
|
+
getByteLength() {
|
|
453
|
+
return 3 + this.payload.byteLength + (this.isReliable() ? 3 : 0) + (this.isSequenced() ? 3 : 0) + (this.isOrdered() ? 4 : 0) + (this.isFragmented() ? 10 : 0);
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Reads the Frame data type from a binary stream.
|
|
457
|
+
* @param stream The binary stream to read from.
|
|
458
|
+
* @returns The Frame data type.
|
|
459
|
+
*/
|
|
460
|
+
static read(stream) {
|
|
461
|
+
const frames = [];
|
|
462
|
+
do {
|
|
463
|
+
const frame = new _Frame();
|
|
464
|
+
const header = stream.readByte();
|
|
465
|
+
frame.reliability = (header & 224) >> 5;
|
|
466
|
+
const length = Math.ceil(stream.readShort() / 8);
|
|
467
|
+
if (frame.isReliable()) {
|
|
468
|
+
frame.reliableIndex = stream.readUint24(import_binarystream3.Endianness.Little);
|
|
469
|
+
}
|
|
470
|
+
if (frame.isSequenced()) {
|
|
471
|
+
frame.sequenceIndex = stream.readUint24(import_binarystream3.Endianness.Little);
|
|
472
|
+
}
|
|
473
|
+
if (frame.isOrdered()) {
|
|
474
|
+
frame.orderIndex = stream.readUint24(import_binarystream3.Endianness.Little);
|
|
475
|
+
frame.orderChannel = stream.readByte();
|
|
476
|
+
}
|
|
477
|
+
if ((header & 16 /* Split */) > 0) {
|
|
478
|
+
frame.fragmentSize = stream.readInt32();
|
|
479
|
+
frame.fragmentId = stream.readShort();
|
|
480
|
+
frame.fragmentIndex = stream.readInt32();
|
|
481
|
+
}
|
|
482
|
+
frame.payload = stream.readBuffer(length);
|
|
483
|
+
frames.push(frame);
|
|
484
|
+
} while (!stream.cursorAtEnd());
|
|
485
|
+
return frames;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Writes the Frame data type to a binary stream.
|
|
489
|
+
* @param stream The binary stream to write to.
|
|
490
|
+
*/
|
|
491
|
+
static write(stream, value) {
|
|
492
|
+
for (const frame of value) {
|
|
493
|
+
stream.writeByte(
|
|
494
|
+
frame.reliability << 5 | (frame.isFragmented() ? 16 /* Split */ : 0)
|
|
495
|
+
);
|
|
496
|
+
stream.writeShort(frame.payload.byteLength << 3);
|
|
497
|
+
if (frame.isReliable()) {
|
|
498
|
+
stream.writeUint24(frame.reliableIndex, import_binarystream3.Endianness.Little);
|
|
499
|
+
}
|
|
500
|
+
if (frame.isSequenced()) {
|
|
501
|
+
stream.writeUint24(frame.sequenceIndex, import_binarystream3.Endianness.Little);
|
|
502
|
+
}
|
|
503
|
+
if (frame.isOrdered()) {
|
|
504
|
+
stream.writeUint24(frame.orderIndex, import_binarystream3.Endianness.Little);
|
|
505
|
+
stream.writeByte(frame.orderChannel);
|
|
506
|
+
}
|
|
507
|
+
if (frame.isFragmented()) {
|
|
508
|
+
stream.writeInt32(frame.fragmentSize);
|
|
509
|
+
stream.writeShort(frame.fragmentId);
|
|
510
|
+
stream.writeInt32(frame.fragmentIndex);
|
|
511
|
+
}
|
|
512
|
+
stream.writeBuffer(frame.payload);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
// src/proto/data/system-address.ts
|
|
518
|
+
var SystemAddress = class extends DataType {
|
|
519
|
+
/**
|
|
520
|
+
* Converts the Address data type to a NetworkIdentifier.
|
|
521
|
+
*
|
|
522
|
+
* @param identifier The NetworkIdentifier.
|
|
523
|
+
* @returns The NetworkIdentifier.
|
|
524
|
+
*/
|
|
525
|
+
static fromIdentifier(identifier) {
|
|
526
|
+
return new Address(identifier.address, identifier.port, identifier.version);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Reads the Address data type from a binary stream.
|
|
530
|
+
* @param stream The binary stream to read from.
|
|
531
|
+
* @returns The Address data type.
|
|
532
|
+
*/
|
|
533
|
+
static read(stream) {
|
|
534
|
+
const addresses = [];
|
|
535
|
+
for (let index = 0; index < 20; index++) {
|
|
536
|
+
const address = Address.read(stream);
|
|
537
|
+
addresses.push(address);
|
|
538
|
+
}
|
|
539
|
+
return addresses;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Writes the Address data type to a binary stream.
|
|
543
|
+
* @param stream The binary stream to write to.
|
|
544
|
+
* @param value The value to write.
|
|
545
|
+
*/
|
|
546
|
+
static write(stream) {
|
|
547
|
+
const addresses = [
|
|
548
|
+
{ address: "127.0.0.1", port: 0, version: 4 }
|
|
549
|
+
];
|
|
550
|
+
for (let index = 0; index < 20; index++) {
|
|
551
|
+
Address.write(
|
|
552
|
+
stream,
|
|
553
|
+
addresses[index] || { address: "0.0.0.0", port: 0, version: 4 }
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// src/proto/packet/base.ts
|
|
560
|
+
var import_binarystream4 = require("@serenityjs/binarystream");
|
|
561
|
+
var BasePacket = class extends import_binarystream4.BinaryStream {
|
|
562
|
+
/**
|
|
563
|
+
* The packet id.
|
|
564
|
+
*/
|
|
565
|
+
static id;
|
|
566
|
+
/**
|
|
567
|
+
* The packet id data type.
|
|
568
|
+
*/
|
|
569
|
+
static id_type = import_binarystream4.Uint8;
|
|
570
|
+
/**
|
|
571
|
+
* Flushes the binary stream.
|
|
572
|
+
*/
|
|
573
|
+
flush() {
|
|
574
|
+
this.binary = [];
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Gets the packet id.
|
|
578
|
+
* @returns The packet id.
|
|
579
|
+
*/
|
|
580
|
+
getId() {
|
|
581
|
+
throw new Error("BasePacket.getId() is not implemented.");
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Gets the packet id data type.
|
|
585
|
+
* @returns The packet id data type.
|
|
586
|
+
*/
|
|
587
|
+
getIdType() {
|
|
588
|
+
throw new Error("BasePacket.getIdType() is not implemented.");
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Serializes the packet.
|
|
592
|
+
* @returns The serialized packet.
|
|
593
|
+
*/
|
|
594
|
+
serialize() {
|
|
595
|
+
throw new Error("BasePacket.serialize() is not implemented.");
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Deserializes the packet.
|
|
599
|
+
*/
|
|
600
|
+
deserialize() {
|
|
601
|
+
throw new Error("BasePacket.deserialize() is not implemented.");
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
// src/proto/packet/unconnected-ping.ts
|
|
606
|
+
var import_binarystream5 = require("@serenityjs/binarystream");
|
|
607
|
+
var UnconnectedPing = class extends BasePacket {
|
|
608
|
+
timestamp;
|
|
609
|
+
magic;
|
|
610
|
+
client;
|
|
611
|
+
};
|
|
612
|
+
__decorateClass([
|
|
613
|
+
Serialize(import_binarystream5.Long)
|
|
614
|
+
], UnconnectedPing.prototype, "timestamp", 2);
|
|
615
|
+
__decorateClass([
|
|
616
|
+
Serialize(Magic)
|
|
617
|
+
], UnconnectedPing.prototype, "magic", 2);
|
|
618
|
+
__decorateClass([
|
|
619
|
+
Serialize(import_binarystream5.Long)
|
|
620
|
+
], UnconnectedPing.prototype, "client", 2);
|
|
621
|
+
UnconnectedPing = __decorateClass([
|
|
622
|
+
Proto(1 /* UnconnectedPing */)
|
|
623
|
+
], UnconnectedPing);
|
|
624
|
+
|
|
625
|
+
// src/proto/packet/unconnected-pong.ts
|
|
626
|
+
var import_binarystream6 = require("@serenityjs/binarystream");
|
|
627
|
+
var UnconnectedPong = class extends BasePacket {
|
|
628
|
+
timestamp;
|
|
629
|
+
guid;
|
|
630
|
+
magic;
|
|
631
|
+
message;
|
|
632
|
+
};
|
|
633
|
+
__decorateClass([
|
|
634
|
+
Serialize(import_binarystream6.Long)
|
|
635
|
+
], UnconnectedPong.prototype, "timestamp", 2);
|
|
636
|
+
__decorateClass([
|
|
637
|
+
Serialize(import_binarystream6.Long)
|
|
638
|
+
], UnconnectedPong.prototype, "guid", 2);
|
|
639
|
+
__decorateClass([
|
|
640
|
+
Serialize(Magic)
|
|
641
|
+
], UnconnectedPong.prototype, "magic", 2);
|
|
642
|
+
__decorateClass([
|
|
643
|
+
Serialize(import_binarystream6.String16)
|
|
644
|
+
], UnconnectedPong.prototype, "message", 2);
|
|
645
|
+
UnconnectedPong = __decorateClass([
|
|
646
|
+
Proto(28 /* UnconnectedPong */)
|
|
647
|
+
], UnconnectedPong);
|
|
648
|
+
|
|
649
|
+
// src/proto/packet/open-connection-request-1.ts
|
|
650
|
+
var import_binarystream7 = require("@serenityjs/binarystream");
|
|
651
|
+
var OpenConnectionRequest1 = class extends BasePacket {
|
|
652
|
+
magic;
|
|
653
|
+
protocol;
|
|
654
|
+
mtu;
|
|
655
|
+
};
|
|
656
|
+
__decorateClass([
|
|
657
|
+
Serialize(Magic)
|
|
658
|
+
], OpenConnectionRequest1.prototype, "magic", 2);
|
|
659
|
+
__decorateClass([
|
|
660
|
+
Serialize(import_binarystream7.Uint8)
|
|
661
|
+
], OpenConnectionRequest1.prototype, "protocol", 2);
|
|
662
|
+
__decorateClass([
|
|
663
|
+
Serialize(MTU)
|
|
664
|
+
], OpenConnectionRequest1.prototype, "mtu", 2);
|
|
665
|
+
OpenConnectionRequest1 = __decorateClass([
|
|
666
|
+
Proto(5 /* OpenConnectionRequest1 */)
|
|
667
|
+
], OpenConnectionRequest1);
|
|
668
|
+
|
|
669
|
+
// src/proto/packet/open-connection-reply-1.ts
|
|
670
|
+
var import_binarystream8 = require("@serenityjs/binarystream");
|
|
671
|
+
var OpenConnectionReply1 = class extends BasePacket {
|
|
672
|
+
magic;
|
|
673
|
+
guid;
|
|
674
|
+
security;
|
|
675
|
+
mtu;
|
|
676
|
+
};
|
|
677
|
+
__decorateClass([
|
|
678
|
+
Serialize(Magic)
|
|
679
|
+
], OpenConnectionReply1.prototype, "magic", 2);
|
|
680
|
+
__decorateClass([
|
|
681
|
+
Serialize(import_binarystream8.Long)
|
|
682
|
+
], OpenConnectionReply1.prototype, "guid", 2);
|
|
683
|
+
__decorateClass([
|
|
684
|
+
Serialize(import_binarystream8.Bool)
|
|
685
|
+
], OpenConnectionReply1.prototype, "security", 2);
|
|
686
|
+
__decorateClass([
|
|
687
|
+
Serialize(import_binarystream8.Short)
|
|
688
|
+
], OpenConnectionReply1.prototype, "mtu", 2);
|
|
689
|
+
OpenConnectionReply1 = __decorateClass([
|
|
690
|
+
Proto(6 /* OpenConnectionReply1 */)
|
|
691
|
+
], OpenConnectionReply1);
|
|
692
|
+
|
|
693
|
+
// src/proto/packet/open-connection-request-2.ts
|
|
694
|
+
var import_binarystream9 = require("@serenityjs/binarystream");
|
|
695
|
+
var OpenConnectionRequest2 = class extends BasePacket {
|
|
696
|
+
magic;
|
|
697
|
+
address;
|
|
698
|
+
mtu;
|
|
699
|
+
client;
|
|
700
|
+
};
|
|
701
|
+
__decorateClass([
|
|
702
|
+
Serialize(Magic)
|
|
703
|
+
], OpenConnectionRequest2.prototype, "magic", 2);
|
|
704
|
+
__decorateClass([
|
|
705
|
+
Serialize(Address)
|
|
706
|
+
], OpenConnectionRequest2.prototype, "address", 2);
|
|
707
|
+
__decorateClass([
|
|
708
|
+
Serialize(import_binarystream9.Short)
|
|
709
|
+
], OpenConnectionRequest2.prototype, "mtu", 2);
|
|
710
|
+
__decorateClass([
|
|
711
|
+
Serialize(import_binarystream9.Long)
|
|
712
|
+
], OpenConnectionRequest2.prototype, "client", 2);
|
|
713
|
+
OpenConnectionRequest2 = __decorateClass([
|
|
714
|
+
Proto(7 /* OpenConnectionRequest2 */)
|
|
715
|
+
], OpenConnectionRequest2);
|
|
716
|
+
|
|
717
|
+
// src/proto/packet/open-connection-reply-2.ts
|
|
718
|
+
var import_binarystream10 = require("@serenityjs/binarystream");
|
|
719
|
+
var OpenConnectionReply2 = class extends BasePacket {
|
|
720
|
+
magic;
|
|
721
|
+
guid;
|
|
722
|
+
address;
|
|
723
|
+
mtu;
|
|
724
|
+
encryption;
|
|
725
|
+
};
|
|
726
|
+
__decorateClass([
|
|
727
|
+
Serialize(Magic)
|
|
728
|
+
], OpenConnectionReply2.prototype, "magic", 2);
|
|
729
|
+
__decorateClass([
|
|
730
|
+
Serialize(import_binarystream10.Long)
|
|
731
|
+
], OpenConnectionReply2.prototype, "guid", 2);
|
|
732
|
+
__decorateClass([
|
|
733
|
+
Serialize(Address)
|
|
734
|
+
], OpenConnectionReply2.prototype, "address", 2);
|
|
735
|
+
__decorateClass([
|
|
736
|
+
Serialize(import_binarystream10.Short)
|
|
737
|
+
], OpenConnectionReply2.prototype, "mtu", 2);
|
|
738
|
+
__decorateClass([
|
|
739
|
+
Serialize(import_binarystream10.Bool)
|
|
740
|
+
], OpenConnectionReply2.prototype, "encryption", 2);
|
|
741
|
+
OpenConnectionReply2 = __decorateClass([
|
|
742
|
+
Proto(8 /* OpenConnectionReply2 */)
|
|
743
|
+
], OpenConnectionReply2);
|
|
744
|
+
|
|
745
|
+
// src/proto/packet/connected-pong.ts
|
|
746
|
+
var import_binarystream11 = require("@serenityjs/binarystream");
|
|
747
|
+
var ConnectedPong = class extends BasePacket {
|
|
748
|
+
pingTimestamp;
|
|
749
|
+
timestamp;
|
|
750
|
+
};
|
|
751
|
+
__decorateClass([
|
|
752
|
+
Serialize(import_binarystream11.Long)
|
|
753
|
+
], ConnectedPong.prototype, "pingTimestamp", 2);
|
|
754
|
+
__decorateClass([
|
|
755
|
+
Serialize(import_binarystream11.Long)
|
|
756
|
+
], ConnectedPong.prototype, "timestamp", 2);
|
|
757
|
+
ConnectedPong = __decorateClass([
|
|
758
|
+
Proto(3 /* ConnectedPong */)
|
|
759
|
+
], ConnectedPong);
|
|
760
|
+
|
|
761
|
+
// src/proto/packet/connected-ping.ts
|
|
762
|
+
var import_binarystream12 = require("@serenityjs/binarystream");
|
|
763
|
+
var ConnectedPing = class extends BasePacket {
|
|
764
|
+
timestamp;
|
|
765
|
+
};
|
|
766
|
+
__decorateClass([
|
|
767
|
+
Serialize(import_binarystream12.Long)
|
|
768
|
+
], ConnectedPing.prototype, "timestamp", 2);
|
|
769
|
+
ConnectedPing = __decorateClass([
|
|
770
|
+
Proto(0 /* ConnectedPing */)
|
|
771
|
+
], ConnectedPing);
|
|
772
|
+
|
|
773
|
+
// src/proto/packet/connection-request.ts
|
|
774
|
+
var import_binarystream13 = require("@serenityjs/binarystream");
|
|
775
|
+
var ConnectionRequest = class extends BasePacket {
|
|
776
|
+
client;
|
|
777
|
+
timestamp;
|
|
778
|
+
};
|
|
779
|
+
__decorateClass([
|
|
780
|
+
Serialize(import_binarystream13.Long)
|
|
781
|
+
], ConnectionRequest.prototype, "client", 2);
|
|
782
|
+
__decorateClass([
|
|
783
|
+
Serialize(import_binarystream13.Long)
|
|
784
|
+
], ConnectionRequest.prototype, "timestamp", 2);
|
|
785
|
+
ConnectionRequest = __decorateClass([
|
|
786
|
+
Proto(9 /* ConnectionRequest */)
|
|
787
|
+
], ConnectionRequest);
|
|
788
|
+
|
|
789
|
+
// src/proto/packet/frame-set.ts
|
|
790
|
+
var import_binarystream14 = require("@serenityjs/binarystream");
|
|
791
|
+
var FrameSet = class extends BasePacket {
|
|
792
|
+
sequence;
|
|
793
|
+
frames;
|
|
794
|
+
};
|
|
795
|
+
__decorateClass([
|
|
796
|
+
Serialize(import_binarystream14.Uint24, import_binarystream14.Endianness.Little)
|
|
797
|
+
], FrameSet.prototype, "sequence", 2);
|
|
798
|
+
__decorateClass([
|
|
799
|
+
Serialize(Frame)
|
|
800
|
+
], FrameSet.prototype, "frames", 2);
|
|
801
|
+
FrameSet = __decorateClass([
|
|
802
|
+
Proto(128 /* FrameSet */)
|
|
803
|
+
], FrameSet);
|
|
804
|
+
|
|
805
|
+
// src/proto/packet/ack.ts
|
|
806
|
+
var import_binarystream15 = require("@serenityjs/binarystream");
|
|
807
|
+
var Ack = class extends BasePacket {
|
|
808
|
+
sequences = [];
|
|
809
|
+
// Override encode due to custom logic, maybe move into own type?
|
|
810
|
+
serialize() {
|
|
811
|
+
this.writeUint8(Ack.id);
|
|
812
|
+
const stream = new import_binarystream15.BinaryStream();
|
|
813
|
+
const count = this.sequences.length;
|
|
814
|
+
let records = 0;
|
|
815
|
+
if (count > 0) {
|
|
816
|
+
let cursor = 0;
|
|
817
|
+
let start = this.sequences[0];
|
|
818
|
+
let last = this.sequences[0];
|
|
819
|
+
while (cursor < count) {
|
|
820
|
+
const current = this.sequences[cursor++];
|
|
821
|
+
const diff = current - last;
|
|
822
|
+
if (diff === 1) {
|
|
823
|
+
last = current;
|
|
824
|
+
} else if (diff > 1) {
|
|
825
|
+
if (start === last) {
|
|
826
|
+
stream.writeBool(true);
|
|
827
|
+
stream.writeUint24(start, import_binarystream15.Endianness.Little);
|
|
828
|
+
start = last = current;
|
|
829
|
+
} else {
|
|
830
|
+
stream.writeBool(false);
|
|
831
|
+
stream.writeUint24(start, import_binarystream15.Endianness.Little);
|
|
832
|
+
stream.writeUint24(last, import_binarystream15.Endianness.Little);
|
|
833
|
+
start = last = current;
|
|
834
|
+
}
|
|
835
|
+
++records;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
if (start === last) {
|
|
839
|
+
stream.writeBool(true);
|
|
840
|
+
stream.writeUint24(start, import_binarystream15.Endianness.Little);
|
|
841
|
+
} else {
|
|
842
|
+
stream.writeBool(false);
|
|
843
|
+
stream.writeUint24(start, import_binarystream15.Endianness.Little);
|
|
844
|
+
stream.writeUint24(last, import_binarystream15.Endianness.Little);
|
|
845
|
+
}
|
|
846
|
+
++records;
|
|
847
|
+
this.writeUShort(records);
|
|
848
|
+
this.writeBuffer(stream.getBuffer());
|
|
849
|
+
}
|
|
850
|
+
return this.getBuffer();
|
|
851
|
+
}
|
|
852
|
+
// Override decode due to custom logic, maybe move into own type?
|
|
853
|
+
deserialize() {
|
|
854
|
+
this.readUint8();
|
|
855
|
+
this.sequences = [];
|
|
856
|
+
const recordCount = this.readUShort();
|
|
857
|
+
for (let index = 0; index < recordCount; index++) {
|
|
858
|
+
const range = this.readBool();
|
|
859
|
+
if (range) {
|
|
860
|
+
this.sequences.push(this.readUint24(import_binarystream15.Endianness.Little));
|
|
861
|
+
} else {
|
|
862
|
+
const start = this.readUint24(import_binarystream15.Endianness.Little);
|
|
863
|
+
const end = this.readUint24(import_binarystream15.Endianness.Little);
|
|
864
|
+
for (let index2 = start; index2 <= end; index2++) {
|
|
865
|
+
this.sequences.push(index2);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
return this;
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
Ack = __decorateClass([
|
|
873
|
+
Proto(192 /* Ack */)
|
|
874
|
+
], Ack);
|
|
875
|
+
|
|
876
|
+
// src/proto/packet/nack.ts
|
|
877
|
+
var import_binarystream16 = require("@serenityjs/binarystream");
|
|
878
|
+
var Nack = class extends BasePacket {
|
|
879
|
+
sequences = [];
|
|
880
|
+
// Override encode due to custom logic, maybe move into own type?
|
|
881
|
+
serialize() {
|
|
882
|
+
this.writeUint8(Nack.id);
|
|
883
|
+
const stream = new import_binarystream16.BinaryStream();
|
|
884
|
+
const count = this.sequences.length;
|
|
885
|
+
let records = 0;
|
|
886
|
+
if (count > 0) {
|
|
887
|
+
let cursor = 0;
|
|
888
|
+
let start = this.sequences[0];
|
|
889
|
+
let last = this.sequences[0];
|
|
890
|
+
while (cursor < count) {
|
|
891
|
+
const current = this.sequences[cursor++];
|
|
892
|
+
const diff = current - last;
|
|
893
|
+
if (diff === 1) {
|
|
894
|
+
last = current;
|
|
895
|
+
} else if (diff > 1) {
|
|
896
|
+
if (start === last) {
|
|
897
|
+
stream.writeBool(true);
|
|
898
|
+
stream.writeUint24(start, import_binarystream16.Endianness.Little);
|
|
899
|
+
start = last = current;
|
|
900
|
+
} else {
|
|
901
|
+
stream.writeBool(false);
|
|
902
|
+
stream.writeUint24(start, import_binarystream16.Endianness.Little);
|
|
903
|
+
stream.writeUint24(last, import_binarystream16.Endianness.Little);
|
|
904
|
+
start = last = current;
|
|
905
|
+
}
|
|
906
|
+
++records;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
if (start === last) {
|
|
910
|
+
stream.writeBool(true);
|
|
911
|
+
stream.writeUint24(start, import_binarystream16.Endianness.Little);
|
|
912
|
+
} else {
|
|
913
|
+
stream.writeBool(false);
|
|
914
|
+
stream.writeUint24(start, import_binarystream16.Endianness.Little);
|
|
915
|
+
stream.writeUint24(last, import_binarystream16.Endianness.Little);
|
|
916
|
+
}
|
|
917
|
+
++records;
|
|
918
|
+
this.writeUShort(records);
|
|
919
|
+
this.writeBuffer(stream.getBuffer());
|
|
920
|
+
}
|
|
921
|
+
return this.getBuffer();
|
|
922
|
+
}
|
|
923
|
+
// Override decode due to custom logic, maybe move into own type?
|
|
924
|
+
deserialize() {
|
|
925
|
+
this.readUint8();
|
|
926
|
+
this.sequences = [];
|
|
927
|
+
const recordCount = this.readUShort();
|
|
928
|
+
for (let index = 0; index < recordCount; index++) {
|
|
929
|
+
const range = this.readBool();
|
|
930
|
+
if (range) {
|
|
931
|
+
this.sequences.push(this.readUint24(import_binarystream16.Endianness.Little));
|
|
932
|
+
} else {
|
|
933
|
+
const start = this.readUint24(import_binarystream16.Endianness.Little);
|
|
934
|
+
const end = this.readUint24(import_binarystream16.Endianness.Little);
|
|
935
|
+
for (let index2 = start; index2 <= end; index2++) {
|
|
936
|
+
this.sequences.push(index2);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
return this;
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
Nack = __decorateClass([
|
|
944
|
+
Proto(160 /* Nack */)
|
|
945
|
+
], Nack);
|
|
946
|
+
|
|
947
|
+
// src/proto/packet/disconnect.ts
|
|
948
|
+
var Disconnect = class extends BasePacket {
|
|
949
|
+
};
|
|
950
|
+
Disconnect = __decorateClass([
|
|
951
|
+
Proto(21 /* Disconnect */)
|
|
952
|
+
], Disconnect);
|
|
953
|
+
|
|
954
|
+
// src/proto/packet/connection-request-accepted.ts
|
|
955
|
+
var import_binarystream17 = require("@serenityjs/binarystream");
|
|
956
|
+
var ConnectionRequestAccepted = class extends BasePacket {
|
|
957
|
+
address;
|
|
958
|
+
systemIndex;
|
|
959
|
+
systemAddress;
|
|
960
|
+
requestTimestamp;
|
|
961
|
+
timestamp;
|
|
962
|
+
};
|
|
963
|
+
__decorateClass([
|
|
964
|
+
Serialize(Address)
|
|
965
|
+
], ConnectionRequestAccepted.prototype, "address", 2);
|
|
966
|
+
__decorateClass([
|
|
967
|
+
Serialize(import_binarystream17.Short)
|
|
968
|
+
], ConnectionRequestAccepted.prototype, "systemIndex", 2);
|
|
969
|
+
__decorateClass([
|
|
970
|
+
Serialize(SystemAddress)
|
|
971
|
+
], ConnectionRequestAccepted.prototype, "systemAddress", 2);
|
|
972
|
+
__decorateClass([
|
|
973
|
+
Serialize(import_binarystream17.Long)
|
|
974
|
+
], ConnectionRequestAccepted.prototype, "requestTimestamp", 2);
|
|
975
|
+
__decorateClass([
|
|
976
|
+
Serialize(import_binarystream17.Long)
|
|
977
|
+
], ConnectionRequestAccepted.prototype, "timestamp", 2);
|
|
978
|
+
ConnectionRequestAccepted = __decorateClass([
|
|
979
|
+
Proto(16 /* ConnectionRequestAccepted */)
|
|
980
|
+
], ConnectionRequestAccepted);
|
|
981
|
+
|
|
982
|
+
// src/server/raknet.ts
|
|
983
|
+
var import_node_dgram = require("dgram");
|
|
984
|
+
var import_emitter = require("@serenityjs/emitter");
|
|
985
|
+
var import_logger = require("@serenityjs/logger");
|
|
986
|
+
|
|
987
|
+
// src/constants/raknet.ts
|
|
988
|
+
var Protocol = 11;
|
|
989
|
+
var RaknetTPS = 100;
|
|
990
|
+
var RaknetTickLength = 1 / RaknetTPS;
|
|
991
|
+
var udpHeaderSize = 28;
|
|
992
|
+
var MinMtuSize = 400;
|
|
993
|
+
var MaxMtuSize = 1492;
|
|
994
|
+
|
|
995
|
+
// src/server/connection.ts
|
|
996
|
+
var import_binarystream18 = require("@serenityjs/binarystream");
|
|
997
|
+
var Connection = class {
|
|
998
|
+
/**
|
|
999
|
+
* The server instance
|
|
1000
|
+
*/
|
|
1001
|
+
server;
|
|
1002
|
+
/**
|
|
1003
|
+
* The status of the connection
|
|
1004
|
+
*/
|
|
1005
|
+
status = 0 /* Connecting */;
|
|
1006
|
+
/**
|
|
1007
|
+
* The network identifier of the connection
|
|
1008
|
+
*/
|
|
1009
|
+
identifier;
|
|
1010
|
+
/**
|
|
1011
|
+
* The GUID of the connection
|
|
1012
|
+
*/
|
|
1013
|
+
guid;
|
|
1014
|
+
/**
|
|
1015
|
+
* The maximum transmission unit of the connection
|
|
1016
|
+
*/
|
|
1017
|
+
mtu;
|
|
1018
|
+
// Inputs
|
|
1019
|
+
receivedFrameSequences = /* @__PURE__ */ new Set();
|
|
1020
|
+
lostFrameSequences = /* @__PURE__ */ new Set();
|
|
1021
|
+
inputHighestSequenceIndex;
|
|
1022
|
+
fragmentsQueue = /* @__PURE__ */ new Map();
|
|
1023
|
+
inputOrderIndex;
|
|
1024
|
+
inputOrderingQueue = /* @__PURE__ */ new Map();
|
|
1025
|
+
lastInputSequence = -1;
|
|
1026
|
+
// Outputs
|
|
1027
|
+
outputBackupQueue = /* @__PURE__ */ new Map();
|
|
1028
|
+
outputOrderIndex;
|
|
1029
|
+
outputSequenceIndex;
|
|
1030
|
+
outputFrameQueue;
|
|
1031
|
+
outputSequence = 0;
|
|
1032
|
+
outputReliableIndex = 0;
|
|
1033
|
+
outputFragmentIndex = 0;
|
|
1034
|
+
/**
|
|
1035
|
+
* Creates a new connection
|
|
1036
|
+
* @param server The server instance
|
|
1037
|
+
* @param identifier The network identifier
|
|
1038
|
+
* @param guid The GUID
|
|
1039
|
+
* @param mtu The maximum transmission unit
|
|
1040
|
+
*/
|
|
1041
|
+
constructor(server, identifier, guid, mtu) {
|
|
1042
|
+
this.server = server;
|
|
1043
|
+
this.identifier = identifier;
|
|
1044
|
+
this.guid = guid;
|
|
1045
|
+
this.mtu = mtu;
|
|
1046
|
+
this.inputOrderIndex = Array.from({ length: 32 }).fill(0);
|
|
1047
|
+
for (let index = 0; index < 32; index++) {
|
|
1048
|
+
this.inputOrderingQueue.set(index, /* @__PURE__ */ new Map());
|
|
1049
|
+
}
|
|
1050
|
+
this.inputHighestSequenceIndex = Array.from({ length: 32 }).fill(0);
|
|
1051
|
+
this.outputFrameQueue = new FrameSet();
|
|
1052
|
+
this.outputFrameQueue.frames = [];
|
|
1053
|
+
this.outputOrderIndex = Array.from({ length: 32 }).fill(0);
|
|
1054
|
+
this.outputSequenceIndex = Array.from({ length: 32 }).fill(0);
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Ticks the connection
|
|
1058
|
+
*/
|
|
1059
|
+
tick() {
|
|
1060
|
+
if (this.status === 2 /* Disconnecting */ || this.status === 3 /* Disconnected */)
|
|
1061
|
+
return;
|
|
1062
|
+
if (this.receivedFrameSequences.size > 0) {
|
|
1063
|
+
const ack = new Ack();
|
|
1064
|
+
ack.sequences = [...this.receivedFrameSequences].map((x) => {
|
|
1065
|
+
this.receivedFrameSequences.delete(x);
|
|
1066
|
+
return x;
|
|
1067
|
+
});
|
|
1068
|
+
this.send(ack.serialize());
|
|
1069
|
+
}
|
|
1070
|
+
if (this.lostFrameSequences.size > 0) {
|
|
1071
|
+
const pk = new Nack();
|
|
1072
|
+
pk.sequences = [...this.lostFrameSequences].map((x) => {
|
|
1073
|
+
this.lostFrameSequences.delete(x);
|
|
1074
|
+
return x;
|
|
1075
|
+
});
|
|
1076
|
+
this.send(pk.serialize());
|
|
1077
|
+
}
|
|
1078
|
+
return this.sendFrameQueue();
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Sends a buffer to the connection
|
|
1082
|
+
*/
|
|
1083
|
+
send(buffer) {
|
|
1084
|
+
this.server.send(buffer, this.identifier);
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Disconnects the connection
|
|
1088
|
+
*/
|
|
1089
|
+
disconnect() {
|
|
1090
|
+
this.status = 2 /* Disconnecting */;
|
|
1091
|
+
const disconnect = new Disconnect();
|
|
1092
|
+
const frame = new Frame();
|
|
1093
|
+
frame.reliability = 0 /* Unreliable */;
|
|
1094
|
+
frame.orderChannel = 0;
|
|
1095
|
+
frame.payload = disconnect.serialize();
|
|
1096
|
+
this.sendFrame(frame, 1 /* Immediate */);
|
|
1097
|
+
void this.server.emit("disconnect", this);
|
|
1098
|
+
const key = `${this.identifier.address}:${this.identifier.port}:${this.identifier.version}`;
|
|
1099
|
+
this.server.connections.delete(key);
|
|
1100
|
+
this.status = 3 /* Disconnected */;
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Handles incoming packets
|
|
1104
|
+
* @param buffer The packet buffer
|
|
1105
|
+
*/
|
|
1106
|
+
incoming(buffer) {
|
|
1107
|
+
const header = buffer[0] & 240;
|
|
1108
|
+
switch (header) {
|
|
1109
|
+
default: {
|
|
1110
|
+
const id = header.toString(16).length === 1 ? "0" + header.toString(16) : header.toString(16);
|
|
1111
|
+
this.server.logger.debug(
|
|
1112
|
+
`Received unknown online packet 0x${id} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1113
|
+
);
|
|
1114
|
+
return void this.server.emit(
|
|
1115
|
+
"error",
|
|
1116
|
+
new Error(
|
|
1117
|
+
`Received unknown online packet 0x${id} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1118
|
+
)
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
case 192 /* Ack */: {
|
|
1122
|
+
this.handleIncomingAck(buffer);
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
case 160 /* Nack */: {
|
|
1126
|
+
this.handleIncomingNack(buffer);
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
1129
|
+
case 128 /* Valid */: {
|
|
1130
|
+
this.handleIncomingFrameSet(buffer);
|
|
1131
|
+
break;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Handles incoming batch packets
|
|
1137
|
+
* @param buffer The packet buffer
|
|
1138
|
+
*/
|
|
1139
|
+
incomingBatch(buffer) {
|
|
1140
|
+
const header = buffer[0];
|
|
1141
|
+
if (this.status === 0 /* Connecting */) {
|
|
1142
|
+
switch (header) {
|
|
1143
|
+
default: {
|
|
1144
|
+
const id = header.toString(16).length === 1 ? "0" + header.toString(16) : header.toString(16);
|
|
1145
|
+
this.server.logger.debug(
|
|
1146
|
+
`Received unknown online packet 0x${id} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1147
|
+
);
|
|
1148
|
+
return void this.server.emit(
|
|
1149
|
+
"error",
|
|
1150
|
+
new Error(
|
|
1151
|
+
`Received unknown online packet 0x${id} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1152
|
+
)
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
case 21 /* Disconnect */: {
|
|
1156
|
+
this.status = 2 /* Disconnecting */;
|
|
1157
|
+
const key = `${this.identifier.address}:${this.identifier.port}:${this.identifier.version}`;
|
|
1158
|
+
this.server.connections.delete(key);
|
|
1159
|
+
this.status = 3 /* Disconnected */;
|
|
1160
|
+
break;
|
|
1161
|
+
}
|
|
1162
|
+
case 9 /* ConnectionRequest */: {
|
|
1163
|
+
this.handleIncomingConnectionRequest(buffer);
|
|
1164
|
+
break;
|
|
1165
|
+
}
|
|
1166
|
+
case 19 /* NewIncomingConnection */: {
|
|
1167
|
+
this.status = 1 /* Connected */;
|
|
1168
|
+
void this.server.emit("connect", this);
|
|
1169
|
+
break;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
switch (header) {
|
|
1175
|
+
default: {
|
|
1176
|
+
const id = header.toString(16).length === 1 ? "0" + header.toString(16) : header.toString(16);
|
|
1177
|
+
this.server.logger.debug(
|
|
1178
|
+
`Received unknown online packet 0x${id} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1179
|
+
);
|
|
1180
|
+
return void this.server.emit(
|
|
1181
|
+
"error",
|
|
1182
|
+
new Error(
|
|
1183
|
+
`Received unknown online packet 0x${id} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1184
|
+
)
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
case 21 /* Disconnect */: {
|
|
1188
|
+
this.status = 2 /* Disconnecting */;
|
|
1189
|
+
void this.server.emit("disconnect", this);
|
|
1190
|
+
const key = `${this.identifier.address}:${this.identifier.port}:${this.identifier.version}`;
|
|
1191
|
+
this.server.connections.delete(key);
|
|
1192
|
+
this.status = 3 /* Disconnected */;
|
|
1193
|
+
break;
|
|
1194
|
+
}
|
|
1195
|
+
case 0 /* ConnectedPing */: {
|
|
1196
|
+
return this.handleIncomingConnectedPing(buffer);
|
|
1197
|
+
}
|
|
1198
|
+
case 254: {
|
|
1199
|
+
void this.server.emit("encapsulated", this, buffer);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Handles incoming acks
|
|
1205
|
+
* @param buffer The packet buffer
|
|
1206
|
+
*/
|
|
1207
|
+
handleIncomingAck(buffer) {
|
|
1208
|
+
const ack = new Ack(buffer).deserialize();
|
|
1209
|
+
if (ack.sequences.length > 0) {
|
|
1210
|
+
for (const sequence of ack.sequences) {
|
|
1211
|
+
this.outputBackupQueue.delete(sequence);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Handles incoming nacks
|
|
1217
|
+
* @param buffer The packet buffer
|
|
1218
|
+
*/
|
|
1219
|
+
handleIncomingNack(buffer) {
|
|
1220
|
+
const nack = new Nack(buffer).deserialize();
|
|
1221
|
+
if (nack.sequences.length > 0) {
|
|
1222
|
+
for (const sequence of nack.sequences) {
|
|
1223
|
+
if (this.outputBackupQueue.has(sequence)) {
|
|
1224
|
+
const frames = this.outputBackupQueue.get(sequence);
|
|
1225
|
+
for (const frame of frames) {
|
|
1226
|
+
this.sendFrame(frame, 1 /* Immediate */);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Handles incoming framesets
|
|
1234
|
+
* @param buffer The packet buffer
|
|
1235
|
+
*/
|
|
1236
|
+
handleIncomingFrameSet(buffer) {
|
|
1237
|
+
const frameset = new FrameSet(buffer).deserialize();
|
|
1238
|
+
if (this.receivedFrameSequences.has(frameset.sequence)) {
|
|
1239
|
+
this.server.logger.debug(
|
|
1240
|
+
`Received duplicate frameset ${frameset.sequence} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1241
|
+
);
|
|
1242
|
+
return void this.server.emit(
|
|
1243
|
+
"error",
|
|
1244
|
+
new Error(
|
|
1245
|
+
`Recieved duplicate frameset ${frameset.sequence} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1246
|
+
)
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
this.lostFrameSequences.delete(frameset.sequence);
|
|
1250
|
+
if (frameset.sequence < this.lastInputSequence || frameset.sequence === this.lastInputSequence) {
|
|
1251
|
+
this.server.logger.debug(
|
|
1252
|
+
`Received out of order frameset ${frameset.sequence} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1253
|
+
);
|
|
1254
|
+
return void this.server.emit(
|
|
1255
|
+
"error",
|
|
1256
|
+
new Error(
|
|
1257
|
+
`Recieved out of order frameset ${frameset.sequence} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1258
|
+
)
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1261
|
+
this.receivedFrameSequences.add(frameset.sequence);
|
|
1262
|
+
const diff = frameset.sequence - this.lastInputSequence;
|
|
1263
|
+
if (diff !== 1) {
|
|
1264
|
+
for (let index = this.lastInputSequence + 1; index < frameset.sequence; index++) {
|
|
1265
|
+
if (!this.receivedFrameSequences.has(index)) {
|
|
1266
|
+
this.lostFrameSequences.add(index);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
this.lastInputSequence = frameset.sequence;
|
|
1271
|
+
for (const frame of frameset.frames) {
|
|
1272
|
+
this.handleFrame(frame);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Handles incoming frames
|
|
1277
|
+
* @param frame The frame
|
|
1278
|
+
*/
|
|
1279
|
+
handleFrame(frame) {
|
|
1280
|
+
if (frame.isFragmented())
|
|
1281
|
+
return this.handleFragment(frame);
|
|
1282
|
+
if (frame.isSequenced()) {
|
|
1283
|
+
if (frame.sequenceIndex < this.inputHighestSequenceIndex[frame.orderChannel] || frame.orderIndex < this.inputOrderIndex[frame.orderChannel]) {
|
|
1284
|
+
this.server.logger.debug(
|
|
1285
|
+
`Recieved out of order frame ${frame.sequenceIndex} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1286
|
+
);
|
|
1287
|
+
return void this.server.emit(
|
|
1288
|
+
"error",
|
|
1289
|
+
new Error(
|
|
1290
|
+
`Recieved out of order frame ${frame.sequenceIndex} from ${this.identifier.address}:${this.identifier.port}!`
|
|
1291
|
+
)
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
this.inputHighestSequenceIndex[frame.orderChannel] = frame.sequenceIndex + 1;
|
|
1295
|
+
return this.incomingBatch(frame.payload);
|
|
1296
|
+
} else if (frame.isOrdered()) {
|
|
1297
|
+
if (frame.orderIndex === this.inputOrderIndex[frame.orderChannel]) {
|
|
1298
|
+
this.inputHighestSequenceIndex[frame.orderChannel] = 0;
|
|
1299
|
+
this.inputOrderIndex[frame.orderChannel] = frame.orderIndex + 1;
|
|
1300
|
+
this.incomingBatch(frame.payload);
|
|
1301
|
+
let index = this.inputOrderIndex[frame.orderChannel];
|
|
1302
|
+
const outOfOrderQueue = this.inputOrderingQueue.get(
|
|
1303
|
+
frame.orderChannel
|
|
1304
|
+
);
|
|
1305
|
+
for (; outOfOrderQueue.has(index); index++) {
|
|
1306
|
+
this.incomingBatch(outOfOrderQueue.get(index).payload);
|
|
1307
|
+
outOfOrderQueue.delete(index);
|
|
1308
|
+
}
|
|
1309
|
+
this.inputOrderingQueue.set(frame.orderChannel, outOfOrderQueue);
|
|
1310
|
+
this.inputOrderIndex[frame.orderChannel] = index;
|
|
1311
|
+
} else if (frame.orderIndex > this.inputOrderIndex[frame.orderChannel]) {
|
|
1312
|
+
const unordered = this.inputOrderingQueue.get(frame.orderChannel);
|
|
1313
|
+
unordered.set(frame.orderIndex, frame);
|
|
1314
|
+
}
|
|
1315
|
+
} else {
|
|
1316
|
+
return this.incomingBatch(frame.payload);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Handles fragmented frames
|
|
1321
|
+
* @param frame The frame
|
|
1322
|
+
*/
|
|
1323
|
+
handleFragment(frame) {
|
|
1324
|
+
if (this.fragmentsQueue.has(frame.fragmentId)) {
|
|
1325
|
+
const value = this.fragmentsQueue.get(frame.fragmentId);
|
|
1326
|
+
value.set(frame.fragmentIndex, frame);
|
|
1327
|
+
if (value.size === frame.fragmentSize) {
|
|
1328
|
+
const stream = new import_binarystream18.BinaryStream();
|
|
1329
|
+
for (let index = 0; index < value.size; index++) {
|
|
1330
|
+
const splitPacket = value.get(index);
|
|
1331
|
+
stream.writeBuffer(splitPacket.payload);
|
|
1332
|
+
}
|
|
1333
|
+
const newFrame = new Frame();
|
|
1334
|
+
newFrame.reliability = frame.reliability;
|
|
1335
|
+
newFrame.reliableIndex = frame.reliableIndex;
|
|
1336
|
+
newFrame.sequenceIndex = frame.sequenceIndex;
|
|
1337
|
+
newFrame.orderIndex = frame.orderIndex;
|
|
1338
|
+
newFrame.orderChannel = frame.orderChannel;
|
|
1339
|
+
newFrame.payload = stream.getBuffer();
|
|
1340
|
+
this.fragmentsQueue.delete(frame.fragmentId);
|
|
1341
|
+
return this.handleFrame(newFrame);
|
|
1342
|
+
}
|
|
1343
|
+
} else {
|
|
1344
|
+
this.fragmentsQueue.set(
|
|
1345
|
+
frame.fragmentId,
|
|
1346
|
+
/* @__PURE__ */ new Map([[frame.fragmentIndex, frame]])
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Sends a frame to the connection.
|
|
1352
|
+
*
|
|
1353
|
+
* @param frame - The frame to send
|
|
1354
|
+
* @param priority - The priority of the frame
|
|
1355
|
+
*/
|
|
1356
|
+
sendFrame(frame, priority) {
|
|
1357
|
+
if (frame.isSequenced()) {
|
|
1358
|
+
frame.orderIndex = this.outputOrderIndex[frame.orderChannel];
|
|
1359
|
+
frame.sequenceIndex = this.outputSequenceIndex[frame.orderChannel]++;
|
|
1360
|
+
} else if (frame.isOrderExclusive()) {
|
|
1361
|
+
frame.orderIndex = this.outputOrderIndex[frame.orderChannel]++;
|
|
1362
|
+
this.outputSequenceIndex[frame.orderChannel] = 0;
|
|
1363
|
+
}
|
|
1364
|
+
frame.reliableIndex = this.outputReliableIndex++;
|
|
1365
|
+
const maxSize = this.mtu - 6 - 23;
|
|
1366
|
+
if (frame.payload.byteLength > maxSize) {
|
|
1367
|
+
const buffer = Buffer.from(frame.payload);
|
|
1368
|
+
const fragmentId = this.outputFragmentIndex++ % 65536;
|
|
1369
|
+
for (let index = 0; index < buffer.byteLength; index += maxSize) {
|
|
1370
|
+
if (index !== 0)
|
|
1371
|
+
frame.reliableIndex = this.outputReliableIndex++;
|
|
1372
|
+
frame.payload = buffer.subarray(index, index + maxSize);
|
|
1373
|
+
frame.fragmentIndex = index / maxSize;
|
|
1374
|
+
frame.fragmentId = fragmentId;
|
|
1375
|
+
frame.fragmentSize = Math.ceil(buffer.byteLength / maxSize);
|
|
1376
|
+
this.addFrameToQueue(frame, priority | 0 /* Normal */);
|
|
1377
|
+
}
|
|
1378
|
+
} else {
|
|
1379
|
+
return this.addFrameToQueue(frame, priority);
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
/**
|
|
1383
|
+
* Adds a frame to the output queue
|
|
1384
|
+
* @param frame The frame
|
|
1385
|
+
* @param priority The priority
|
|
1386
|
+
*/
|
|
1387
|
+
addFrameToQueue(frame, priority) {
|
|
1388
|
+
let length = 4;
|
|
1389
|
+
for (const queuedFrame of this.outputFrameQueue.frames) {
|
|
1390
|
+
length += queuedFrame.getByteLength();
|
|
1391
|
+
}
|
|
1392
|
+
if (length + frame.getByteLength() > this.mtu - 36) {
|
|
1393
|
+
this.sendFrameQueue();
|
|
1394
|
+
}
|
|
1395
|
+
this.outputFrameQueue.frames.push(frame);
|
|
1396
|
+
if (priority === 1 /* Immediate */)
|
|
1397
|
+
return this.sendFrameQueue();
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Sends the output frame queue
|
|
1401
|
+
*/
|
|
1402
|
+
sendFrameQueue() {
|
|
1403
|
+
if (this.outputFrameQueue.frames.length > 0) {
|
|
1404
|
+
this.outputFrameQueue.sequence = this.outputSequence++;
|
|
1405
|
+
this.sendFrameSet(this.outputFrameQueue);
|
|
1406
|
+
this.outputFrameQueue = new FrameSet();
|
|
1407
|
+
this.outputFrameQueue.frames = [];
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
/**
|
|
1411
|
+
* Sends a frame set to the connection
|
|
1412
|
+
* @param frameset The frame set
|
|
1413
|
+
*/
|
|
1414
|
+
sendFrameSet(frameset) {
|
|
1415
|
+
this.send(frameset.serialize());
|
|
1416
|
+
this.outputBackupQueue.set(
|
|
1417
|
+
frameset.sequence,
|
|
1418
|
+
frameset.frames.filter((frame) => frame.isReliable())
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* Handles an incoming connection request
|
|
1423
|
+
* @param buffer The packet buffer
|
|
1424
|
+
*/
|
|
1425
|
+
handleIncomingConnectionRequest(buffer) {
|
|
1426
|
+
const request = new ConnectionRequest(buffer).deserialize();
|
|
1427
|
+
const accepted = new ConnectionRequestAccepted();
|
|
1428
|
+
accepted.address = Address.fromIdentifier(this.identifier);
|
|
1429
|
+
accepted.systemIndex = 0;
|
|
1430
|
+
accepted.systemAddress = [];
|
|
1431
|
+
accepted.requestTimestamp = request.timestamp;
|
|
1432
|
+
accepted.timestamp = BigInt(Date.now());
|
|
1433
|
+
const frame = new Frame();
|
|
1434
|
+
frame.reliability = 0 /* Unreliable */;
|
|
1435
|
+
frame.orderChannel = 0;
|
|
1436
|
+
frame.payload = accepted.serialize();
|
|
1437
|
+
return this.sendFrame(frame, 0 /* Normal */);
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Handles an incoming connected ping
|
|
1441
|
+
* @param buffer The packet buffer
|
|
1442
|
+
*/
|
|
1443
|
+
handleIncomingConnectedPing(buffer) {
|
|
1444
|
+
const ping = new ConnectedPing(buffer).deserialize();
|
|
1445
|
+
const pong = new ConnectedPong();
|
|
1446
|
+
pong.timestamp = ping.timestamp;
|
|
1447
|
+
pong.pingTimestamp = ping.timestamp;
|
|
1448
|
+
pong.timestamp = BigInt(Date.now());
|
|
1449
|
+
const frame = new Frame();
|
|
1450
|
+
frame.reliability = 0 /* Unreliable */;
|
|
1451
|
+
frame.orderChannel = 0;
|
|
1452
|
+
frame.payload = pong.serialize();
|
|
1453
|
+
this.sendFrame(frame, 0 /* Normal */);
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1456
|
+
|
|
1457
|
+
// src/server/offline.ts
|
|
1458
|
+
var Offline = class {
|
|
1459
|
+
/**
|
|
1460
|
+
* The server instance
|
|
1461
|
+
*/
|
|
1462
|
+
static server;
|
|
1463
|
+
/**
|
|
1464
|
+
* Handles all incoming offline packets
|
|
1465
|
+
* @param buffer The packet buffer
|
|
1466
|
+
* @param identifier The network identifier
|
|
1467
|
+
*/
|
|
1468
|
+
static incoming(buffer, identifier) {
|
|
1469
|
+
const header = buffer[0];
|
|
1470
|
+
switch (header) {
|
|
1471
|
+
default: {
|
|
1472
|
+
const id = header.toString(16).length === 1 ? "0" + header.toString(16) : header.toString(16);
|
|
1473
|
+
return void this.server.emit(
|
|
1474
|
+
"error",
|
|
1475
|
+
new Error(
|
|
1476
|
+
`Unknown packet header "0x${id}" from ${identifier.address}:${identifier.port}`
|
|
1477
|
+
)
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
case 1 /* UnconnectedPing */: {
|
|
1481
|
+
this.handleUnconnectedPing(buffer, identifier);
|
|
1482
|
+
break;
|
|
1483
|
+
}
|
|
1484
|
+
case 5 /* OpenConnectionRequest1 */: {
|
|
1485
|
+
this.handleOpenConnectionRequest1(buffer, identifier);
|
|
1486
|
+
break;
|
|
1487
|
+
}
|
|
1488
|
+
case 7 /* OpenConnectionRequest2 */: {
|
|
1489
|
+
this.handleOpenConnectionRequest2(buffer, identifier);
|
|
1490
|
+
break;
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Handles an unconnected ping
|
|
1496
|
+
* @param buffer The packet buffer
|
|
1497
|
+
* @param identifier The network identifier
|
|
1498
|
+
*/
|
|
1499
|
+
static handleUnconnectedPing(buffer, identifier) {
|
|
1500
|
+
const ping = new UnconnectedPing(buffer).deserialize();
|
|
1501
|
+
const pong = new UnconnectedPong();
|
|
1502
|
+
pong.timestamp = ping.timestamp;
|
|
1503
|
+
pong.guid = this.server.guid;
|
|
1504
|
+
pong.message = [
|
|
1505
|
+
"MCPE",
|
|
1506
|
+
// MCEE = Minecraft: Education Edition
|
|
1507
|
+
this.server.message ?? "Raknet Server",
|
|
1508
|
+
this.server.protocol ?? 100,
|
|
1509
|
+
this.server.version ?? "1.0.0",
|
|
1510
|
+
this.server.connections.size,
|
|
1511
|
+
this.server.maxConnections ?? 10,
|
|
1512
|
+
this.server.guid,
|
|
1513
|
+
"SerenityJS",
|
|
1514
|
+
"Survival",
|
|
1515
|
+
1,
|
|
1516
|
+
this.server.port,
|
|
1517
|
+
this.server.port + 1
|
|
1518
|
+
].join(";") + ";";
|
|
1519
|
+
return this.server.send(pong.serialize(), identifier);
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Handles an open connection request 1
|
|
1523
|
+
* @param buffer The packet buffer
|
|
1524
|
+
* @param identifier The network identifier
|
|
1525
|
+
*/
|
|
1526
|
+
static handleOpenConnectionRequest1(buffer, identifier) {
|
|
1527
|
+
const request = new OpenConnectionRequest1(buffer).deserialize();
|
|
1528
|
+
if (request.protocol !== Protocol) {
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
const reply = new OpenConnectionReply1();
|
|
1532
|
+
reply.guid = this.server.guid;
|
|
1533
|
+
reply.security = false;
|
|
1534
|
+
const size = request.getBuffer().byteLength + udpHeaderSize;
|
|
1535
|
+
reply.mtu = size > MaxMtuSize ? MaxMtuSize : size;
|
|
1536
|
+
return this.server.send(reply.serialize(), identifier);
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Handles an open connection request 2
|
|
1540
|
+
* @param buffer The packet buffer
|
|
1541
|
+
* @param identifier The network identifier
|
|
1542
|
+
*/
|
|
1543
|
+
static handleOpenConnectionRequest2(buffer, identifier) {
|
|
1544
|
+
const request = new OpenConnectionRequest2(buffer).deserialize();
|
|
1545
|
+
const key = `${identifier.address}:${identifier.port}:${identifier.version}`;
|
|
1546
|
+
const reply = new OpenConnectionReply2();
|
|
1547
|
+
reply.guid = this.server.guid;
|
|
1548
|
+
reply.address = Address.fromIdentifier(identifier);
|
|
1549
|
+
reply.mtu = request.mtu;
|
|
1550
|
+
reply.encryption = false;
|
|
1551
|
+
const connection = new Connection(
|
|
1552
|
+
this.server,
|
|
1553
|
+
identifier,
|
|
1554
|
+
request.client,
|
|
1555
|
+
request.mtu
|
|
1556
|
+
);
|
|
1557
|
+
this.server.connections.set(key, connection);
|
|
1558
|
+
return this.server.send(reply.serialize(), identifier);
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
// src/server/raknet.ts
|
|
1563
|
+
var RaknetServer = class extends import_emitter.Emitter {
|
|
1564
|
+
/**
|
|
1565
|
+
* The server tick interval
|
|
1566
|
+
*/
|
|
1567
|
+
interval = null;
|
|
1568
|
+
/**
|
|
1569
|
+
* The raknet server logger
|
|
1570
|
+
*/
|
|
1571
|
+
logger;
|
|
1572
|
+
/**
|
|
1573
|
+
* The server socket
|
|
1574
|
+
*/
|
|
1575
|
+
socket;
|
|
1576
|
+
/**
|
|
1577
|
+
* The server address
|
|
1578
|
+
*/
|
|
1579
|
+
address;
|
|
1580
|
+
/**
|
|
1581
|
+
* The server port
|
|
1582
|
+
*/
|
|
1583
|
+
port;
|
|
1584
|
+
/**
|
|
1585
|
+
* The server guid
|
|
1586
|
+
*/
|
|
1587
|
+
guid;
|
|
1588
|
+
/**
|
|
1589
|
+
* The server connections
|
|
1590
|
+
*/
|
|
1591
|
+
connections;
|
|
1592
|
+
/**
|
|
1593
|
+
* The server protocol
|
|
1594
|
+
*/
|
|
1595
|
+
protocol = null;
|
|
1596
|
+
/**
|
|
1597
|
+
* The server version
|
|
1598
|
+
*/
|
|
1599
|
+
version = null;
|
|
1600
|
+
/**
|
|
1601
|
+
* The server message
|
|
1602
|
+
*/
|
|
1603
|
+
message = null;
|
|
1604
|
+
/**
|
|
1605
|
+
* The server max connections
|
|
1606
|
+
*/
|
|
1607
|
+
maxConnections = null;
|
|
1608
|
+
/**
|
|
1609
|
+
* Creates a new raknet server
|
|
1610
|
+
* @param address the server address
|
|
1611
|
+
* @param port the server port
|
|
1612
|
+
*/
|
|
1613
|
+
constructor(address, port = 19132) {
|
|
1614
|
+
super();
|
|
1615
|
+
this.logger = new import_logger.Logger("Raknet", import_logger.LoggerColors.CyanBright);
|
|
1616
|
+
this.socket = (0, import_node_dgram.createSocket)("udp4");
|
|
1617
|
+
this.address = address;
|
|
1618
|
+
this.port = port;
|
|
1619
|
+
this.guid = BigInt(Math.floor(Math.random() * 2 ** 64));
|
|
1620
|
+
this.connections = /* @__PURE__ */ new Map();
|
|
1621
|
+
Offline.server = this;
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Starts the server
|
|
1625
|
+
*/
|
|
1626
|
+
start() {
|
|
1627
|
+
try {
|
|
1628
|
+
this.socket.bind(this.port, this.address);
|
|
1629
|
+
this.socket.on("message", this.incoming.bind(this));
|
|
1630
|
+
this.socket.on("error", (error) => this.emit("error", error));
|
|
1631
|
+
const tick = () => setTimeout(() => {
|
|
1632
|
+
for (const [, connection] of this.connections) {
|
|
1633
|
+
connection.tick();
|
|
1634
|
+
}
|
|
1635
|
+
tick();
|
|
1636
|
+
}, RaknetTickLength);
|
|
1637
|
+
this.interval = tick().unref();
|
|
1638
|
+
} catch {
|
|
1639
|
+
this.logger.error(
|
|
1640
|
+
`Failed to bind to the address and port, make sure the address and port are not in use.`
|
|
1641
|
+
);
|
|
1642
|
+
void this.emit(
|
|
1643
|
+
"error",
|
|
1644
|
+
new Error(
|
|
1645
|
+
"Failed to bind to the address and port, make sure the address and port are not in use."
|
|
1646
|
+
)
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Stops the server
|
|
1652
|
+
*/
|
|
1653
|
+
stop() {
|
|
1654
|
+
try {
|
|
1655
|
+
if (this.interval)
|
|
1656
|
+
clearInterval(this.interval);
|
|
1657
|
+
this.socket.close();
|
|
1658
|
+
} catch {
|
|
1659
|
+
void this.emit("error", new Error("Failed to close the server"));
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Sends a buffer to the specified network identifier
|
|
1664
|
+
* @param buffer the buffer to send
|
|
1665
|
+
* @param identifier the network identifier to send the buffer to
|
|
1666
|
+
*/
|
|
1667
|
+
send(buffer, identifier) {
|
|
1668
|
+
this.socket.send(buffer, identifier.port, identifier.address);
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Handles incoming packets
|
|
1672
|
+
* @param buffer the packet buffer
|
|
1673
|
+
* @param rinfo the remote info
|
|
1674
|
+
*/
|
|
1675
|
+
incoming(buffer, rinfo) {
|
|
1676
|
+
try {
|
|
1677
|
+
const { address, port, family } = rinfo;
|
|
1678
|
+
const version = family === "IPv4" ? 4 : 6;
|
|
1679
|
+
const identifier = { address, port, version };
|
|
1680
|
+
const key = `${address}:${port}:${version}`;
|
|
1681
|
+
const connection = this.connections.get(key);
|
|
1682
|
+
if (connection && (buffer[0] & 128 /* Valid */) !== 0)
|
|
1683
|
+
return connection.incoming(buffer);
|
|
1684
|
+
if ((buffer[0] & 128 /* Valid */) !== 0) {
|
|
1685
|
+
this.logger.debug(
|
|
1686
|
+
`Received a valid packet without a valid connection from ${key}`
|
|
1687
|
+
);
|
|
1688
|
+
return void this.emit(
|
|
1689
|
+
"error",
|
|
1690
|
+
new Error(
|
|
1691
|
+
"Received a valid packet without a valid connection from " + key
|
|
1692
|
+
)
|
|
1693
|
+
);
|
|
1694
|
+
}
|
|
1695
|
+
return Offline.incoming(buffer, identifier);
|
|
1696
|
+
} catch (reason) {
|
|
1697
|
+
this.logger.error(
|
|
1698
|
+
`Failed to handle incoming packet from ${rinfo.address}:${rinfo.port}, "${reason.message}"`
|
|
1699
|
+
);
|
|
1700
|
+
void this.emit("error", reason);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1705
|
+
0 && (module.exports = {
|
|
1706
|
+
Ack,
|
|
1707
|
+
Address,
|
|
1708
|
+
BasePacket,
|
|
1709
|
+
Bitflags,
|
|
1710
|
+
ConnectedPing,
|
|
1711
|
+
ConnectedPong,
|
|
1712
|
+
Connection,
|
|
1713
|
+
ConnectionRequest,
|
|
1714
|
+
ConnectionRequestAccepted,
|
|
1715
|
+
DataType,
|
|
1716
|
+
Disconnect,
|
|
1717
|
+
Frame,
|
|
1718
|
+
FrameSet,
|
|
1719
|
+
MTU,
|
|
1720
|
+
Magic,
|
|
1721
|
+
MaxMtuSize,
|
|
1722
|
+
MinMtuSize,
|
|
1723
|
+
Nack,
|
|
1724
|
+
Offline,
|
|
1725
|
+
OpenConnectionReply1,
|
|
1726
|
+
OpenConnectionReply2,
|
|
1727
|
+
OpenConnectionRequest1,
|
|
1728
|
+
OpenConnectionRequest2,
|
|
1729
|
+
Packet,
|
|
1730
|
+
Priority,
|
|
1731
|
+
Proto,
|
|
1732
|
+
Protocol,
|
|
1733
|
+
RaknetServer,
|
|
1734
|
+
RaknetTPS,
|
|
1735
|
+
RaknetTickLength,
|
|
1736
|
+
Reliability,
|
|
1737
|
+
Serialize,
|
|
1738
|
+
Status,
|
|
1739
|
+
SystemAddress,
|
|
1740
|
+
UnconnectedPing,
|
|
1741
|
+
UnconnectedPong,
|
|
1742
|
+
udpHeaderSize
|
|
1743
|
+
});
|