@baltica/raknet 0.0.1

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.
Files changed (95) hide show
  1. package/dist/client/client.d.ts +20 -0
  2. package/dist/client/client.js +122 -0
  3. package/dist/client/index.d.ts +2 -0
  4. package/dist/client/index.js +18 -0
  5. package/dist/client/types/client-events.d.ts +6 -0
  6. package/dist/client/types/client-events.js +2 -0
  7. package/dist/client/types/client-options.d.ts +12 -0
  8. package/dist/client/types/client-options.js +11 -0
  9. package/dist/client/types/index.d.ts +2 -0
  10. package/dist/client/types/index.js +18 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.js +19 -0
  13. package/dist/server/connection.d.ts +16 -0
  14. package/dist/server/connection.js +30 -0
  15. package/dist/server/index.d.ts +3 -0
  16. package/dist/server/index.js +19 -0
  17. package/dist/server/server.d.ts +19 -0
  18. package/dist/server/server.js +119 -0
  19. package/dist/server/types/index.d.ts +2 -0
  20. package/dist/server/types/index.js +18 -0
  21. package/dist/server/types/server-events.d.ts +6 -0
  22. package/dist/server/types/server-events.js +2 -0
  23. package/dist/server/types/server-options.d.ts +10 -0
  24. package/dist/server/types/server-options.js +11 -0
  25. package/dist/shared/index.d.ts +3 -0
  26. package/dist/shared/index.js +19 -0
  27. package/dist/shared/network-session.d.ts +63 -0
  28. package/dist/shared/network-session.js +480 -0
  29. package/dist/shared/proto/enums/index.d.ts +4 -0
  30. package/dist/shared/proto/enums/index.js +20 -0
  31. package/dist/shared/proto/enums/packet.d.ts +21 -0
  32. package/dist/shared/proto/enums/packet.js +25 -0
  33. package/dist/shared/proto/enums/priority.d.ts +6 -0
  34. package/dist/shared/proto/enums/priority.js +8 -0
  35. package/dist/shared/proto/enums/reliability.d.ts +10 -0
  36. package/dist/shared/proto/enums/reliability.js +14 -0
  37. package/dist/shared/proto/enums/status.d.ts +6 -0
  38. package/dist/shared/proto/enums/status.js +10 -0
  39. package/dist/shared/proto/index.d.ts +3 -0
  40. package/dist/shared/proto/index.js +19 -0
  41. package/dist/shared/proto/packets/data-packet.d.ts +7 -0
  42. package/dist/shared/proto/packets/data-packet.js +14 -0
  43. package/dist/shared/proto/packets/index.d.ts +3 -0
  44. package/dist/shared/proto/packets/index.js +19 -0
  45. package/dist/shared/proto/packets/offline/index.d.ts +6 -0
  46. package/dist/shared/proto/packets/offline/index.js +22 -0
  47. package/dist/shared/proto/packets/offline/open-connection-reply-one.d.ts +13 -0
  48. package/dist/shared/proto/packets/offline/open-connection-reply-one.js +46 -0
  49. package/dist/shared/proto/packets/offline/open-connection-reply-two.d.ts +12 -0
  50. package/dist/shared/proto/packets/offline/open-connection-reply-two.js +32 -0
  51. package/dist/shared/proto/packets/offline/open-connection-request-one.d.ts +9 -0
  52. package/dist/shared/proto/packets/offline/open-connection-request-one.js +26 -0
  53. package/dist/shared/proto/packets/offline/open-connection-request-two.d.ts +13 -0
  54. package/dist/shared/proto/packets/offline/open-connection-request-two.js +43 -0
  55. package/dist/shared/proto/packets/offline/unconnected-ping.d.ts +9 -0
  56. package/dist/shared/proto/packets/offline/unconnected-ping.js +25 -0
  57. package/dist/shared/proto/packets/offline/unconnected-pong.d.ts +10 -0
  58. package/dist/shared/proto/packets/offline/unconnected-pong.js +28 -0
  59. package/dist/shared/proto/packets/online/ack.d.ts +5 -0
  60. package/dist/shared/proto/packets/online/ack.js +9 -0
  61. package/dist/shared/proto/packets/online/acknowledgement.d.ts +6 -0
  62. package/dist/shared/proto/packets/online/acknowledgement.js +72 -0
  63. package/dist/shared/proto/packets/online/connected-ping.d.ts +8 -0
  64. package/dist/shared/proto/packets/online/connected-ping.js +19 -0
  65. package/dist/shared/proto/packets/online/connected-pong.d.ts +9 -0
  66. package/dist/shared/proto/packets/online/connected-pong.js +22 -0
  67. package/dist/shared/proto/packets/online/connection-request-accepted.d.ts +13 -0
  68. package/dist/shared/proto/packets/online/connection-request-accepted.js +41 -0
  69. package/dist/shared/proto/packets/online/connection-request.d.ts +10 -0
  70. package/dist/shared/proto/packets/online/connection-request.js +25 -0
  71. package/dist/shared/proto/packets/online/disconnect.d.ts +7 -0
  72. package/dist/shared/proto/packets/online/disconnect.js +16 -0
  73. package/dist/shared/proto/packets/online/frame-set.d.ts +10 -0
  74. package/dist/shared/proto/packets/online/frame-set.js +24 -0
  75. package/dist/shared/proto/packets/online/index.d.ts +10 -0
  76. package/dist/shared/proto/packets/online/index.js +26 -0
  77. package/dist/shared/proto/packets/online/nack.d.ts +5 -0
  78. package/dist/shared/proto/packets/online/nack.js +9 -0
  79. package/dist/shared/proto/packets/online/new-incoming-connection.d.ts +12 -0
  80. package/dist/shared/proto/packets/online/new-incoming-connection.js +33 -0
  81. package/dist/shared/proto/types/address.d.ts +11 -0
  82. package/dist/shared/proto/types/address.js +61 -0
  83. package/dist/shared/proto/types/data-type.d.ts +5 -0
  84. package/dist/shared/proto/types/data-type.js +9 -0
  85. package/dist/shared/proto/types/frame.d.ts +22 -0
  86. package/dist/shared/proto/types/frame.js +113 -0
  87. package/dist/shared/proto/types/index.d.ts +5 -0
  88. package/dist/shared/proto/types/index.js +21 -0
  89. package/dist/shared/proto/types/magic.d.ts +7 -0
  90. package/dist/shared/proto/types/magic.js +17 -0
  91. package/dist/shared/proto/types/mtu.d.ts +5 -0
  92. package/dist/shared/proto/types/mtu.js +12 -0
  93. package/dist/shared/socks5.d.ts +16 -0
  94. package/dist/shared/socks5.js +166 -0
  95. package/package.json +26 -0
@@ -0,0 +1,480 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkSession = void 0;
4
+ const binarystream_1 = require("@serenityjs/binarystream");
5
+ const proto_1 = require("./proto");
6
+ const utils_1 = require("@baltica/utils");
7
+ const MTU_HEADER_SIZE = 36;
8
+ const RECEIVE_WINDOW = 2048;
9
+ const RELIABLE_WINDOW = 4096;
10
+ const FRAGMENT_TIMEOUT = 30_000;
11
+ const ORDER_QUEUE_MAX = 1024;
12
+ const ORDER_SKIP_THRESHOLD = 512;
13
+ const RAKNET_PROTOCOL = 11;
14
+ const GAME_PACKET_ID = 0xfe;
15
+ class NetworkSession extends utils_1.Emitter {
16
+ mtu;
17
+ client;
18
+ guid;
19
+ remoteGuid;
20
+ status = proto_1.Status.Disconnected;
21
+ address;
22
+ send;
23
+ serverMessage;
24
+ maxRetransmit = 3;
25
+ retransmitInterval = 1000;
26
+ outputReliableIndex = 0;
27
+ outputSplitIndex = 0;
28
+ outputSequence = 0;
29
+ outputSequenceIndex = new Array(32).fill(0);
30
+ outputOrderIndex = new Array(32).fill(0);
31
+ outputFrames = new Set();
32
+ outputBackup = new Map();
33
+ receivedFrameSequences = new Set();
34
+ lostFrameSequences = new Set();
35
+ pendingAcks = new Set();
36
+ lastInputSequence = -1;
37
+ fragmentsQueue = new Map();
38
+ inputHighestSequenceIndex = new Array(32).fill(0);
39
+ inputOrderIndex = new Array(32).fill(0);
40
+ inputOrderingQueue = new Map();
41
+ receivedReliableFrameIndices = new Set();
42
+ highestReliableIndex = -1;
43
+ offlineRetry = null;
44
+ outputBackupTimestamps = new Map();
45
+ constructor(mtu, client) {
46
+ super();
47
+ this.mtu = mtu;
48
+ this.client = client;
49
+ for (let i = 0; i < 32; i++)
50
+ this.inputOrderingQueue.set(i, new Map());
51
+ }
52
+ sendOfflineWithRetry(data) {
53
+ this.offlineRetry = { data, attempts: 1, maxAttempts: this.maxRetransmit, lastSent: Date.now(), interval: this.retransmitInterval };
54
+ this.send(data);
55
+ }
56
+ clearOfflineRetry() {
57
+ this.offlineRetry = null;
58
+ }
59
+ receive(buffer) {
60
+ const id = buffer[0];
61
+ const payload = buffer.subarray(1);
62
+ if (id === proto_1.Packet.Ack)
63
+ return this.onAck(new proto_1.Ack(payload).deserialize());
64
+ if (id === proto_1.Packet.Nack)
65
+ return this.onNack(new proto_1.Nack(payload).deserialize());
66
+ if (id >= proto_1.Packet.FrameSetMin && id <= proto_1.Packet.FrameSetMax)
67
+ return this.onFrameSet(new proto_1.FrameSet(payload).deserialize());
68
+ if (this.client)
69
+ this.handleClientOffline(id, buffer);
70
+ else
71
+ this.handleServerOffline(id, buffer);
72
+ }
73
+ handleClientOffline(id, buffer) {
74
+ const payload = buffer.subarray(1);
75
+ switch (id) {
76
+ case proto_1.Packet.UnconnectedPong: {
77
+ this.clearOfflineRetry();
78
+ const pong = new proto_1.UnconnectedPong(payload).deserialize();
79
+ this.serverMessage = pong.message;
80
+ this.remoteGuid = pong.guid;
81
+ this.emit("pong", pong.message);
82
+ break;
83
+ }
84
+ case proto_1.Packet.OpenConnectionReply1: {
85
+ this.clearOfflineRetry();
86
+ const reply = new proto_1.OpenConnectionReplyOne(payload).deserialize();
87
+ this.remoteGuid = reply.guid;
88
+ this.mtu = Math.min(this.mtu, reply.mtu);
89
+ const req = new proto_1.OpenConnectionRequestTwo();
90
+ req.address = this.address;
91
+ req.mtu = this.mtu;
92
+ req.guid = this.guid;
93
+ req.cookie = reply.cookie;
94
+ req.clientSupportsecurity = false;
95
+ this.sendOfflineWithRetry(req.serialize());
96
+ break;
97
+ }
98
+ case proto_1.Packet.OpenConnectionReply2: {
99
+ this.clearOfflineRetry();
100
+ const reply = new proto_1.OpenConnectionReplyTwo(payload).deserialize();
101
+ this.mtu = Math.min(this.mtu, reply.mtu);
102
+ this.status = proto_1.Status.Connecting;
103
+ const req = new proto_1.ConnectionRequest();
104
+ req.guid = this.guid;
105
+ req.timestamp = BigInt(Date.now());
106
+ req.useSecurity = false;
107
+ this.frameAndSend(req.serialize(), proto_1.Priority.High);
108
+ break;
109
+ }
110
+ case proto_1.Packet.AlreadyConnected: {
111
+ this.clearOfflineRetry();
112
+ this.status = proto_1.Status.Disconnected;
113
+ this.emit("disconnect");
114
+ break;
115
+ }
116
+ case proto_1.Packet.IncompatibleProtocolVersion: {
117
+ this.clearOfflineRetry();
118
+ this.status = proto_1.Status.Disconnected;
119
+ this.emit("error", new Error("Incompatible protocol version"));
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ handleServerOffline(id, buffer) {
125
+ const payload = buffer.subarray(1);
126
+ switch (id) {
127
+ case proto_1.Packet.UnconnectedPing:
128
+ case proto_1.Packet.UnconnectedPingOpenConnections: {
129
+ const ping = new proto_1.UnconnectedPing(payload).deserialize();
130
+ const pong = new proto_1.UnconnectedPong();
131
+ pong.timestamp = ping.timestamp;
132
+ pong.guid = this.guid;
133
+ pong.message = this.serverMessage ?? "";
134
+ this.send(pong.serialize());
135
+ break;
136
+ }
137
+ case proto_1.Packet.OpenConnectionRequest1: {
138
+ const req = new proto_1.OpenConnectionRequestOne(payload).deserialize();
139
+ const reply = new proto_1.OpenConnectionReplyOne();
140
+ reply.guid = this.guid;
141
+ reply.security = false;
142
+ reply.cookie = null;
143
+ reply.hasCookie = false;
144
+ reply.serverPublicKey = null;
145
+ reply.mtu = Math.min(this.mtu, req.mtu);
146
+ this.send(reply.serialize());
147
+ break;
148
+ }
149
+ case proto_1.Packet.OpenConnectionRequest2: {
150
+ const req = new proto_1.OpenConnectionRequestTwo(payload).deserialize();
151
+ this.mtu = Math.min(this.mtu, req.mtu);
152
+ this.remoteGuid = req.guid;
153
+ this.address = req.address;
154
+ const reply = new proto_1.OpenConnectionReplyTwo();
155
+ reply.guid = this.guid;
156
+ reply.address = req.address;
157
+ reply.mtu = this.mtu;
158
+ reply.encryptionEnabled = false;
159
+ this.send(reply.serialize());
160
+ this.status = proto_1.Status.Connecting;
161
+ break;
162
+ }
163
+ }
164
+ }
165
+ handleOnlinePacket(payload) {
166
+ const id = payload[0];
167
+ const data = payload.subarray(1);
168
+ switch (id) {
169
+ case proto_1.Packet.ConnectionRequestAccepted: {
170
+ if (!this.client)
171
+ break;
172
+ const accepted = new proto_1.ConnectionRequestAccepted(data).deserialize();
173
+ const nic = new proto_1.NewIncomingConnection();
174
+ nic.address = this.address;
175
+ nic.internalAddress = new proto_1.Address("0.0.0.0", 0, 4);
176
+ nic.incomingTimestamp = accepted.requestTimestamp;
177
+ nic.serverTimestamp = BigInt(Date.now());
178
+ this.frameAndSend(nic.serialize(), proto_1.Priority.High);
179
+ this.status = proto_1.Status.Connected;
180
+ this.emit("connect");
181
+ break;
182
+ }
183
+ case proto_1.Packet.ConnectionRequest: {
184
+ if (this.client)
185
+ break;
186
+ const req = new proto_1.ConnectionRequest(data).deserialize();
187
+ const accepted = new proto_1.ConnectionRequestAccepted();
188
+ accepted.address = this.address;
189
+ accepted.systemIndex = 0;
190
+ accepted.addresses = Array.from({ length: 20 }, () => new proto_1.Address("0.0.0.0", 0, 4));
191
+ accepted.requestTimestamp = req.timestamp;
192
+ accepted.timestamp = BigInt(Date.now());
193
+ this.frameAndSend(accepted.serialize(), proto_1.Priority.High);
194
+ break;
195
+ }
196
+ case proto_1.Packet.NewIncomingConnection: {
197
+ if (this.client)
198
+ break;
199
+ this.status = proto_1.Status.Connected;
200
+ this.emit("connect");
201
+ break;
202
+ }
203
+ case proto_1.Packet.ConnectedPing: {
204
+ const ping = new proto_1.ConnectedPing(data).deserialize();
205
+ const pong = new proto_1.ConnectedPong();
206
+ pong.pingTimestamp = ping.timestamp;
207
+ pong.pongTimestamp = BigInt(Date.now());
208
+ this.frameAndSend(pong.serialize(), proto_1.Priority.High);
209
+ break;
210
+ }
211
+ case proto_1.Packet.ConnectedPong:
212
+ break;
213
+ case proto_1.Packet.DisconnectionNotification:
214
+ this.status = proto_1.Status.Disconnected;
215
+ this.emit("disconnect");
216
+ break;
217
+ default:
218
+ if (id === GAME_PACKET_ID)
219
+ this.emit("encapsulated", payload);
220
+ break;
221
+ }
222
+ }
223
+ tick() {
224
+ const now = Date.now();
225
+ if (this.offlineRetry) {
226
+ const r = this.offlineRetry;
227
+ if (now - r.lastSent >= r.interval) {
228
+ if (r.attempts >= r.maxAttempts) {
229
+ this.offlineRetry = null;
230
+ this.status = proto_1.Status.Disconnected;
231
+ this.emit("error", new Error("Connection timed out after " + r.maxAttempts + " attempts"));
232
+ }
233
+ else {
234
+ r.attempts++;
235
+ r.lastSent = now;
236
+ this.send(r.data);
237
+ }
238
+ }
239
+ }
240
+ const windowStart = this.lastInputSequence - RECEIVE_WINDOW;
241
+ if (windowStart > 0) {
242
+ for (const s of this.receivedFrameSequences)
243
+ if (s < windowStart)
244
+ this.receivedFrameSequences.delete(s);
245
+ for (const s of this.lostFrameSequences)
246
+ if (s < windowStart)
247
+ this.lostFrameSequences.delete(s);
248
+ }
249
+ const relStart = this.highestReliableIndex - RELIABLE_WINDOW;
250
+ if (relStart > 0) {
251
+ for (const i of this.receivedReliableFrameIndices)
252
+ if (i < relStart)
253
+ this.receivedReliableFrameIndices.delete(i);
254
+ }
255
+ for (const [id, entry] of this.fragmentsQueue) {
256
+ if (now - entry.timestamp > FRAGMENT_TIMEOUT)
257
+ this.fragmentsQueue.delete(id);
258
+ }
259
+ if (this.pendingAcks.size > 0) {
260
+ const ack = new proto_1.Ack();
261
+ ack.sequences = [...this.pendingAcks];
262
+ this.pendingAcks.clear();
263
+ this.send(ack.serialize());
264
+ }
265
+ if (this.lostFrameSequences.size > 0) {
266
+ const nack = new proto_1.Nack();
267
+ nack.sequences = [...this.lostFrameSequences];
268
+ this.lostFrameSequences.clear();
269
+ this.send(nack.serialize());
270
+ }
271
+ // Retransmit unacked frame sets that are older than the retry interval
272
+ for (const [seq, sentAt] of this.outputBackupTimestamps) {
273
+ if (now - sentAt >= this.retransmitInterval) {
274
+ const frames = this.outputBackup.get(seq);
275
+ if (frames) {
276
+ const fs = new proto_1.FrameSet();
277
+ fs.sequence = seq;
278
+ fs.frames = frames;
279
+ this.send(fs.serialize());
280
+ this.outputBackupTimestamps.set(seq, now);
281
+ }
282
+ else {
283
+ this.outputBackupTimestamps.delete(seq);
284
+ }
285
+ }
286
+ }
287
+ if (this.outputFrames.size > 0)
288
+ this.flush();
289
+ }
290
+ onAck(ack) {
291
+ for (const seq of ack.sequences) {
292
+ this.outputBackup.delete(seq);
293
+ this.outputBackupTimestamps.delete(seq);
294
+ }
295
+ }
296
+ onNack(nack) {
297
+ for (const seq of nack.sequences) {
298
+ const frames = this.outputBackup.get(seq);
299
+ if (!frames)
300
+ continue;
301
+ const fs = new proto_1.FrameSet();
302
+ fs.sequence = seq;
303
+ fs.frames = frames;
304
+ this.send(fs.serialize());
305
+ }
306
+ }
307
+ frameAndSend(data, priority = proto_1.Priority.Medium) {
308
+ const frame = new proto_1.Frame();
309
+ frame.reliability = proto_1.Reliability.ReliableOrdered;
310
+ frame.orderChannel = 0;
311
+ frame.payload = data;
312
+ this.sendFrame(frame, priority);
313
+ }
314
+ sendFrame(frame, priority = proto_1.Priority.Medium) {
315
+ const channel = frame.orderChannel;
316
+ if (frame.isSequenced()) {
317
+ frame.orderedFrameIndex = this.outputOrderIndex[channel];
318
+ frame.sequenceFrameIndex = this.outputSequenceIndex[channel]++;
319
+ }
320
+ else if (frame.isOrdered()) {
321
+ frame.orderedFrameIndex = this.outputOrderIndex[channel]++;
322
+ this.outputSequenceIndex[channel] = 0;
323
+ }
324
+ const maxSize = this.mtu - MTU_HEADER_SIZE;
325
+ if (frame.payload.byteLength > maxSize) {
326
+ this.sendSplit(frame, maxSize, priority);
327
+ }
328
+ else {
329
+ if (frame.isReliable())
330
+ frame.reliableFrameIndex = this.outputReliableIndex++;
331
+ this.queueFrame(frame, priority);
332
+ }
333
+ }
334
+ sendSplit(frame, maxSize, priority) {
335
+ const payload = frame.payload;
336
+ const splitSize = Math.ceil(payload.byteLength / maxSize);
337
+ const splitId = this.outputSplitIndex++ & 0xffff;
338
+ for (let i = 0; i < splitSize; i++) {
339
+ const nf = new proto_1.Frame();
340
+ nf.reliability = frame.reliability;
341
+ nf.sequenceFrameIndex = frame.sequenceFrameIndex;
342
+ nf.orderedFrameIndex = frame.orderedFrameIndex;
343
+ nf.orderChannel = frame.orderChannel;
344
+ if (nf.isReliable())
345
+ nf.reliableFrameIndex = this.outputReliableIndex++;
346
+ nf.payload = payload.subarray(i * maxSize, Math.min((i + 1) * maxSize, payload.byteLength));
347
+ nf.splitFrameIndex = i;
348
+ nf.splitId = splitId;
349
+ nf.splitSize = splitSize;
350
+ this.queueFrame(nf, priority);
351
+ }
352
+ }
353
+ queueFrame(frame, priority) {
354
+ let length = 4;
355
+ for (const f of this.outputFrames)
356
+ length += f.getByteLength();
357
+ if (length + frame.getByteLength() > this.mtu - MTU_HEADER_SIZE)
358
+ this.flush();
359
+ this.outputFrames.add(frame);
360
+ if (priority === proto_1.Priority.High)
361
+ this.flush();
362
+ }
363
+ flush() {
364
+ if (this.outputFrames.size === 0)
365
+ return;
366
+ const fs = new proto_1.FrameSet();
367
+ fs.sequence = this.outputSequence++;
368
+ fs.frames = [...this.outputFrames];
369
+ this.outputBackup.set(fs.sequence, fs.frames);
370
+ this.outputBackupTimestamps.set(fs.sequence, Date.now());
371
+ this.outputFrames.clear();
372
+ const serialized = fs.serialize();
373
+ this.send(serialized);
374
+ }
375
+ onFrameSet(fs) {
376
+ if (this.receivedFrameSequences.has(fs.sequence))
377
+ return;
378
+ this.lostFrameSequences.delete(fs.sequence);
379
+ this.receivedFrameSequences.add(fs.sequence);
380
+ this.pendingAcks.add(fs.sequence);
381
+ if (fs.sequence > this.lastInputSequence) {
382
+ for (let i = this.lastInputSequence + 1; i < fs.sequence; i++) {
383
+ if (!this.receivedFrameSequences.has(i))
384
+ this.lostFrameSequences.add(i);
385
+ }
386
+ this.lastInputSequence = fs.sequence;
387
+ }
388
+ for (const frame of fs.frames)
389
+ this.handleFrame(frame);
390
+ }
391
+ handleFrame(frame) {
392
+ if (frame.isReliable()) {
393
+ if (this.receivedReliableFrameIndices.has(frame.reliableFrameIndex))
394
+ return;
395
+ this.receivedReliableFrameIndices.add(frame.reliableFrameIndex);
396
+ if (frame.reliableFrameIndex > this.highestReliableIndex)
397
+ this.highestReliableIndex = frame.reliableFrameIndex;
398
+ }
399
+ if (frame.isSplit())
400
+ this.handleSplit(frame);
401
+ else if (frame.isSequenced())
402
+ this.handleSequenced(frame);
403
+ else if (frame.isOrdered())
404
+ this.handleOrdered(frame);
405
+ else
406
+ this.handleOnlinePacket(frame.payload);
407
+ }
408
+ handleSplit(frame) {
409
+ let entry = this.fragmentsQueue.get(frame.splitId);
410
+ if (!entry) {
411
+ entry = { frames: new Map(), timestamp: Date.now() };
412
+ this.fragmentsQueue.set(frame.splitId, entry);
413
+ }
414
+ entry.frames.set(frame.splitFrameIndex, frame);
415
+ if (entry.frames.size !== frame.splitSize)
416
+ return;
417
+ const stream = new binarystream_1.BinaryStream();
418
+ for (let i = 0; i < frame.splitSize; i++) {
419
+ const f = entry.frames.get(i);
420
+ if (!f) {
421
+ this.fragmentsQueue.delete(frame.splitId);
422
+ return;
423
+ }
424
+ stream.write(f.payload);
425
+ }
426
+ this.fragmentsQueue.delete(frame.splitId);
427
+ const reassembled = new proto_1.Frame();
428
+ reassembled.reliability = frame.reliability;
429
+ reassembled.reliableFrameIndex = frame.reliableFrameIndex;
430
+ reassembled.sequenceFrameIndex = frame.sequenceFrameIndex;
431
+ reassembled.orderedFrameIndex = frame.orderedFrameIndex;
432
+ reassembled.orderChannel = frame.orderChannel;
433
+ reassembled.splitSize = 0;
434
+ reassembled.payload = stream.getBuffer();
435
+ if (reassembled.isSequenced())
436
+ this.handleSequenced(reassembled);
437
+ else if (reassembled.isOrdered())
438
+ this.handleOrdered(reassembled);
439
+ else
440
+ this.handleOnlinePacket(reassembled.payload);
441
+ }
442
+ handleSequenced(frame) {
443
+ const ch = frame.orderChannel;
444
+ if (frame.sequenceFrameIndex < this.inputHighestSequenceIndex[ch])
445
+ return;
446
+ this.inputHighestSequenceIndex[ch] = frame.sequenceFrameIndex + 1;
447
+ this.handleOnlinePacket(frame.payload);
448
+ }
449
+ handleOrdered(frame) {
450
+ const ch = frame.orderChannel;
451
+ const expected = this.inputOrderIndex[ch];
452
+ if (frame.orderedFrameIndex === expected) {
453
+ this.inputHighestSequenceIndex[ch] = 0;
454
+ this.inputOrderIndex[ch] = expected + 1;
455
+ this.handleOnlinePacket(frame.payload);
456
+ const queue = this.inputOrderingQueue.get(ch);
457
+ let next = expected + 1;
458
+ while (queue.has(next)) {
459
+ this.handleOnlinePacket(queue.get(next).payload);
460
+ queue.delete(next);
461
+ next++;
462
+ }
463
+ this.inputOrderIndex[ch] = next;
464
+ }
465
+ else if (frame.orderedFrameIndex > expected) {
466
+ if (frame.orderedFrameIndex - expected > ORDER_SKIP_THRESHOLD) {
467
+ const queue = this.inputOrderingQueue.get(ch);
468
+ if (queue)
469
+ queue.clear();
470
+ this.inputOrderIndex[ch] = frame.orderedFrameIndex + 1;
471
+ this.handleOnlinePacket(frame.payload);
472
+ return;
473
+ }
474
+ const queue = this.inputOrderingQueue.get(ch);
475
+ if (queue.size < ORDER_QUEUE_MAX)
476
+ queue.set(frame.orderedFrameIndex, frame);
477
+ }
478
+ }
479
+ }
480
+ exports.NetworkSession = NetworkSession;
@@ -0,0 +1,4 @@
1
+ export * from "./packet";
2
+ export * from "./reliability";
3
+ export * from "./priority";
4
+ export * from "./status";
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./packet"), exports);
18
+ __exportStar(require("./reliability"), exports);
19
+ __exportStar(require("./priority"), exports);
20
+ __exportStar(require("./status"), exports);
@@ -0,0 +1,21 @@
1
+ export declare enum Packet {
2
+ UnconnectedPing = 1,
3
+ UnconnectedPingOpenConnections = 2,
4
+ UnconnectedPong = 28,
5
+ ConnectedPing = 0,
6
+ ConnectedPong = 3,
7
+ OpenConnectionRequest1 = 5,
8
+ OpenConnectionReply1 = 6,
9
+ OpenConnectionRequest2 = 7,
10
+ OpenConnectionReply2 = 8,
11
+ ConnectionRequest = 9,
12
+ ConnectionRequestAccepted = 16,
13
+ NewIncomingConnection = 19,
14
+ DisconnectionNotification = 21,
15
+ IncompatibleProtocolVersion = 25,
16
+ AlreadyConnected = 18,
17
+ Ack = 192,
18
+ Nack = 160,
19
+ FrameSetMin = 128,
20
+ FrameSetMax = 141
21
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Packet = void 0;
4
+ var Packet;
5
+ (function (Packet) {
6
+ Packet[Packet["UnconnectedPing"] = 1] = "UnconnectedPing";
7
+ Packet[Packet["UnconnectedPingOpenConnections"] = 2] = "UnconnectedPingOpenConnections";
8
+ Packet[Packet["UnconnectedPong"] = 28] = "UnconnectedPong";
9
+ Packet[Packet["ConnectedPing"] = 0] = "ConnectedPing";
10
+ Packet[Packet["ConnectedPong"] = 3] = "ConnectedPong";
11
+ Packet[Packet["OpenConnectionRequest1"] = 5] = "OpenConnectionRequest1";
12
+ Packet[Packet["OpenConnectionReply1"] = 6] = "OpenConnectionReply1";
13
+ Packet[Packet["OpenConnectionRequest2"] = 7] = "OpenConnectionRequest2";
14
+ Packet[Packet["OpenConnectionReply2"] = 8] = "OpenConnectionReply2";
15
+ Packet[Packet["ConnectionRequest"] = 9] = "ConnectionRequest";
16
+ Packet[Packet["ConnectionRequestAccepted"] = 16] = "ConnectionRequestAccepted";
17
+ Packet[Packet["NewIncomingConnection"] = 19] = "NewIncomingConnection";
18
+ Packet[Packet["DisconnectionNotification"] = 21] = "DisconnectionNotification";
19
+ Packet[Packet["IncompatibleProtocolVersion"] = 25] = "IncompatibleProtocolVersion";
20
+ Packet[Packet["AlreadyConnected"] = 18] = "AlreadyConnected";
21
+ Packet[Packet["Ack"] = 192] = "Ack";
22
+ Packet[Packet["Nack"] = 160] = "Nack";
23
+ Packet[Packet["FrameSetMin"] = 128] = "FrameSetMin";
24
+ Packet[Packet["FrameSetMax"] = 141] = "FrameSetMax";
25
+ })(Packet || (exports.Packet = Packet = {}));
@@ -0,0 +1,6 @@
1
+ export declare const Priority: {
2
+ readonly Low: 0;
3
+ readonly Medium: 1;
4
+ readonly High: 2;
5
+ };
6
+ export type Priority = (typeof Priority)[keyof typeof Priority];
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Priority = void 0;
4
+ exports.Priority = {
5
+ Low: 0,
6
+ Medium: 1,
7
+ High: 2,
8
+ };
@@ -0,0 +1,10 @@
1
+ export declare enum Reliability {
2
+ Unreliable = 0,
3
+ UnreliableSequenced = 1,
4
+ Reliable = 2,
5
+ ReliableOrdered = 3,
6
+ ReliableSequenced = 4,
7
+ UnreliableWithAckReceipt = 5,
8
+ ReliableWithAckReceipt = 6,
9
+ ReliableOrderedWithAckReceipt = 7
10
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Reliability = void 0;
4
+ var Reliability;
5
+ (function (Reliability) {
6
+ Reliability[Reliability["Unreliable"] = 0] = "Unreliable";
7
+ Reliability[Reliability["UnreliableSequenced"] = 1] = "UnreliableSequenced";
8
+ Reliability[Reliability["Reliable"] = 2] = "Reliable";
9
+ Reliability[Reliability["ReliableOrdered"] = 3] = "ReliableOrdered";
10
+ Reliability[Reliability["ReliableSequenced"] = 4] = "ReliableSequenced";
11
+ Reliability[Reliability["UnreliableWithAckReceipt"] = 5] = "UnreliableWithAckReceipt";
12
+ Reliability[Reliability["ReliableWithAckReceipt"] = 6] = "ReliableWithAckReceipt";
13
+ Reliability[Reliability["ReliableOrderedWithAckReceipt"] = 7] = "ReliableOrderedWithAckReceipt";
14
+ })(Reliability || (exports.Reliability = Reliability = {}));
@@ -0,0 +1,6 @@
1
+ export declare enum Status {
2
+ Connecting = 0,
3
+ Connected = 1,
4
+ Disconnecting = 2,
5
+ Disconnected = 3
6
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Status = void 0;
4
+ var Status;
5
+ (function (Status) {
6
+ Status[Status["Connecting"] = 0] = "Connecting";
7
+ Status[Status["Connected"] = 1] = "Connected";
8
+ Status[Status["Disconnecting"] = 2] = "Disconnecting";
9
+ Status[Status["Disconnected"] = 3] = "Disconnected";
10
+ })(Status || (exports.Status = Status = {}));
@@ -0,0 +1,3 @@
1
+ export * from "./packets";
2
+ export * from "./types";
3
+ export * from "./enums";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./packets"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ __exportStar(require("./enums"), exports);
@@ -0,0 +1,7 @@
1
+ import { BinaryStream } from "@serenityjs/binarystream";
2
+ import { Packet } from "../enums/packet";
3
+ export declare class DataPacket extends BinaryStream {
4
+ static ID: Packet;
5
+ serialize(): Buffer;
6
+ deserialize(): this;
7
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataPacket = void 0;
4
+ const binarystream_1 = require("@serenityjs/binarystream");
5
+ class DataPacket extends binarystream_1.BinaryStream {
6
+ static ID;
7
+ serialize() {
8
+ throw new Error(`${this.constructor.name}.serialize is not implemented!`);
9
+ }
10
+ deserialize() {
11
+ throw new Error(`${this.constructor.name}.deserialize is not implemented!`);
12
+ }
13
+ }
14
+ exports.DataPacket = DataPacket;
@@ -0,0 +1,3 @@
1
+ export * from "./data-packet";
2
+ export * from "./offline";
3
+ export * from "./online";