@sanctumterra/raknet 1.4.11 → 1.4.13
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/dist/client/client.d.ts +1 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +12 -13
- package/dist/client/types/client-options.d.ts +1 -0
- package/dist/client/types/client-options.d.ts.map +1 -1
- package/dist/client/types/client-options.js +1 -0
- package/dist/server/connection.d.ts.map +1 -1
- package/dist/server/connection.js +8 -12
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +2 -5
- package/dist/server/types/server-events.d.ts +5 -1
- package/dist/server/types/server-events.d.ts.map +1 -1
- package/dist/shared/network_session.d.ts +14 -3
- package/dist/shared/network_session.d.ts.map +1 -1
- package/dist/shared/network_session.js +144 -61
- package/package.json +1 -1
package/dist/client/client.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare class Client extends EventEmitter<ClientEvents> {
|
|
|
20
20
|
private resolvedAddress;
|
|
21
21
|
private proxyReady;
|
|
22
22
|
private lastPongTime;
|
|
23
|
+
private lastActivityTime;
|
|
23
24
|
private isDisconnected;
|
|
24
25
|
constructor(options?: Partial<ClientOptions>);
|
|
25
26
|
private setupProxy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,YAAY,EAWZ,QAAQ,EAIR,KAAK,KAAK,EAKV,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACN,KAAK,aAAa,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAgB,KAAK,UAAU,EAAe,MAAM,YAAY,CAAC;AAKxE,qBAAa,MAAO,SAAQ,YAAY,CAAC,YAAY,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAiC;IACnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAE3C,OAAO,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,MAAM,CAAmB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;YAmBlC,UAAU;IAoGxB,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,oBAAoB;IA2Bf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD9B,MAAM,IAAI,IAAI;IA6BrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,OAAO;IAgBR,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,YAAY,EAWZ,QAAQ,EAIR,KAAK,KAAK,EAKV,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACN,KAAK,aAAa,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAgB,KAAK,UAAU,EAAe,MAAM,YAAY,CAAC;AAKxE,qBAAa,MAAO,SAAQ,YAAY,CAAC,YAAY,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAiC;IACnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAE3C,OAAO,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,MAAM,CAAmB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;YAmBlC,UAAU;IAoGxB,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,oBAAoB;IA2Bf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD9B,MAAM,IAAI,IAAI;IA6BrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,OAAO;IAgBR,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAmEhD,YAAY,CAAC,IAAI,EAAE,MAAM;IAkDzB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAE,QAA0B;IAI5D,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAA0B;IAI/D,IAAI,IAAI,IAAI;IAOZ,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWxB,UAAU,IAAI,IAAI;CAWzB"}
|
package/dist/client/client.js
CHANGED
|
@@ -25,6 +25,7 @@ class Client extends shared_1.EventEmitter {
|
|
|
25
25
|
resolvedAddress = null;
|
|
26
26
|
proxyReady = false;
|
|
27
27
|
lastPongTime = Date.now();
|
|
28
|
+
lastActivityTime = Date.now();
|
|
28
29
|
isDisconnected = false;
|
|
29
30
|
constructor(options = {}) {
|
|
30
31
|
super();
|
|
@@ -35,7 +36,7 @@ class Client extends shared_1.EventEmitter {
|
|
|
35
36
|
this.socket.bind();
|
|
36
37
|
this.interval = setInterval(this.onTick.bind(this), 1000 / this.options.tickRate);
|
|
37
38
|
this.socket.on("message", this.onMessage.bind(this));
|
|
38
|
-
this.session = new shared_1.NetworkSession(this.options.mtu);
|
|
39
|
+
this.session = new shared_1.NetworkSession(this.options.mtu, this.options.debug);
|
|
39
40
|
this.session.send = this.send.bind(this);
|
|
40
41
|
this.session.handle = (data) => {
|
|
41
42
|
this.handleOnline(data);
|
|
@@ -255,9 +256,9 @@ class Client extends shared_1.EventEmitter {
|
|
|
255
256
|
if (this.tick % Client.PING_INTERVAL_TICKS === 0) {
|
|
256
257
|
this.sendConnectedPing();
|
|
257
258
|
}
|
|
258
|
-
// Check for stale connection
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
259
|
+
// Check for stale connection (no activity at all)
|
|
260
|
+
const timeSinceLastActivity = Date.now() - this.lastActivityTime;
|
|
261
|
+
if (timeSinceLastActivity > Client.STALE_TIMEOUT_MS) {
|
|
261
262
|
this.handleDisconnect("Connection timed out (stale)");
|
|
262
263
|
return;
|
|
263
264
|
}
|
|
@@ -337,23 +338,19 @@ class Client extends shared_1.EventEmitter {
|
|
|
337
338
|
break;
|
|
338
339
|
}
|
|
339
340
|
case shared_1.Packets.FrameSet: {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
catch (error) {
|
|
345
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
346
|
-
shared_2.Logger.error(`Frame set error: ${message}`);
|
|
347
|
-
this.handleDisconnect(`Frame set error: ${message}`);
|
|
348
|
-
}
|
|
341
|
+
this.lastActivityTime = Date.now();
|
|
342
|
+
const frameSet = new shared_1.FrameSet(actualData).deserialize();
|
|
343
|
+
this.session.onFrameSet(frameSet);
|
|
349
344
|
break;
|
|
350
345
|
}
|
|
351
346
|
case shared_1.Packets.Ack: {
|
|
347
|
+
this.lastActivityTime = Date.now();
|
|
352
348
|
const ack = new shared_1.Ack(actualData).deserialize();
|
|
353
349
|
this.session.onAck(ack);
|
|
354
350
|
break;
|
|
355
351
|
}
|
|
356
352
|
case shared_1.Packets.Nack: {
|
|
353
|
+
this.lastActivityTime = Date.now();
|
|
357
354
|
const nack = new shared_1.Ack(actualData).deserialize();
|
|
358
355
|
this.session.onNack(nack);
|
|
359
356
|
break;
|
|
@@ -397,7 +394,9 @@ class Client extends shared_1.EventEmitter {
|
|
|
397
394
|
this.frameAndSend(nic.serialize(), shared_1.Priority.High);
|
|
398
395
|
this.status = shared_1.ConnectionStatus.Connected;
|
|
399
396
|
this.lastPongTime = Date.now(); // Reset stale timer on connect
|
|
397
|
+
this.lastActivityTime = Date.now();
|
|
400
398
|
this.emit("connect");
|
|
399
|
+
console.log("Raknet Connected");
|
|
401
400
|
break;
|
|
402
401
|
}
|
|
403
402
|
default: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-options.d.ts","sourceRoot":"","sources":["../../../src/client/types/client-options.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client-options.d.ts","sourceRoot":"","sources":["../../../src/client/types/client-options.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,MAC0B,CAAC;AAE3D,eAAO,MAAM,0BAA0B,QAAO,aAS5C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/server/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EAOR,YAAY,EACZ,KAAK,KAAK,EACV,KAAK,QAAQ,EAIb,QAAQ,EACR,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,UAAW,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IAS5D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IAXb,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAElD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,cAAc,CAAS;gBAGtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/server/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EAOR,YAAY,EACZ,KAAK,KAAK,EACV,KAAK,QAAQ,EAIb,QAAQ,EACR,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,UAAW,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IAS5D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IAXb,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAElD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,cAAc,CAAS;gBAGtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM;IAWd,MAAM,CAAC,IAAI,EAAE,MAAM;IAoBnB,UAAU,CAAC,MAAM,SAAiB,GAAG,IAAI;IAYzC,OAAO,IAAI,OAAO;IAIlB,UAAU,CAAC,QAAQ,EAAE,QAAQ;IAK7B,UAAU,IAAI,UAAU;IAIxB,SAAS,CAAC,IAAI,EAAE,MAAM;IA8DtB,KAAK,CAAC,OAAO,EAAE,GAAG;IAIzB,uFAAuF;IAChF,MAAM,CAAC,OAAO,EAAE,GAAG;IAInB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAE,QAAwB;IAI1D,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAwB;IAIhE,IAAI,CAAC,IAAI,EAAE,MAAM;CAGxB"}
|
|
@@ -18,7 +18,7 @@ class Connection extends shared_1.EventEmitter {
|
|
|
18
18
|
this.rinfo = rinfo;
|
|
19
19
|
this.mtu = mtu;
|
|
20
20
|
this.guid = guid;
|
|
21
|
-
this.session = new shared_1.NetworkSession(this.mtu);
|
|
21
|
+
this.session = new shared_1.NetworkSession(this.mtu, this.server.options.enableServerLogs);
|
|
22
22
|
this.session.send = this.send.bind(this);
|
|
23
23
|
this.session.handle = this.onMessage.bind(this);
|
|
24
24
|
}
|
|
@@ -46,22 +46,15 @@ class Connection extends shared_1.EventEmitter {
|
|
|
46
46
|
// Send disconnect packet to client
|
|
47
47
|
const disconnect = new shared_1.DisconnectMessage();
|
|
48
48
|
this.session.frameAndSend(disconnect.serialize(), shared_1.Priority.High);
|
|
49
|
-
// Emit disconnect event
|
|
50
|
-
this.server.emit("disconnect", this);
|
|
49
|
+
// Emit disconnect event with reason
|
|
50
|
+
this.server.emit("disconnect", { connection: this, reason });
|
|
51
51
|
}
|
|
52
52
|
isStale() {
|
|
53
53
|
return this.isDisconnected;
|
|
54
54
|
}
|
|
55
55
|
onFrameSet(frameSet) {
|
|
56
56
|
this.lastActivityTime = Date.now();
|
|
57
|
-
|
|
58
|
-
this.session.onFrameSet(frameSet);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
62
|
-
shared_1.Logger.error(`Frame set error: ${message}`);
|
|
63
|
-
this.disconnect(`Frame set error: ${message}`);
|
|
64
|
-
}
|
|
57
|
+
this.session.onFrameSet(frameSet);
|
|
65
58
|
}
|
|
66
59
|
getAddress() {
|
|
67
60
|
return this.rinfo;
|
|
@@ -88,7 +81,10 @@ class Connection extends shared_1.EventEmitter {
|
|
|
88
81
|
}
|
|
89
82
|
case shared_1.Packets.Disconnect: {
|
|
90
83
|
this.isDisconnected = true;
|
|
91
|
-
this.server.emit("disconnect",
|
|
84
|
+
this.server.emit("disconnect", {
|
|
85
|
+
connection: this,
|
|
86
|
+
reason: "Client disconnected",
|
|
87
|
+
});
|
|
92
88
|
break;
|
|
93
89
|
}
|
|
94
90
|
case shared_1.Packets.ConnectedPing: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,YAAY,EAQZ,MAAM,WAAW,CAAC;AAEnB,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAExB,MAAM,SAAS,CAAC;AAGjB,qBAAa,MAAO,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAC3D,OAAO,CAAC,MAAM,CAAS;IACvB,SAAgB,OAAO,EAAE,mBAAmB,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IACpC,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAiB;gBAEzB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAuB/C,IAAI;IAOJ,MAAM;IAab,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,YAAY,EAQZ,MAAM,WAAW,CAAC;AAEnB,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAExB,MAAM,SAAS,CAAC;AAGjB,qBAAa,MAAO,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAC3D,OAAO,CAAC,MAAM,CAAS;IACvB,SAAgB,OAAO,EAAE,mBAAmB,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IACpC,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAiB;gBAEzB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAuB/C,IAAI;IAOJ,MAAM;IAab,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,SAAS;IA6EV,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAGzD"}
|
package/dist/server/server.js
CHANGED
|
@@ -47,15 +47,12 @@ class Server extends shared_1.EventEmitter {
|
|
|
47
47
|
this.socket.on("message", this.onMessage.bind(this));
|
|
48
48
|
this.on("disconnect", this.onDisconnect.bind(this));
|
|
49
49
|
}
|
|
50
|
-
onDisconnect(connection,
|
|
50
|
+
onDisconnect({ connection, reason, }) {
|
|
51
51
|
const address = connection.getAddress();
|
|
52
52
|
this.connections.delete(`${address.address}:${address.port}`);
|
|
53
53
|
this.advertisement.playerCount = this.connections.size;
|
|
54
|
-
if (executedByServer) {
|
|
55
|
-
this.emit("disconnect", connection);
|
|
56
|
-
}
|
|
57
54
|
if (this.options.enableServerLogs) {
|
|
58
|
-
shared_1.Logger.info(`Client disconnected ${address.address}:${address.port}`);
|
|
55
|
+
shared_1.Logger.info(`Client disconnected ${address.address}:${address.port} - ${reason}`);
|
|
59
56
|
}
|
|
60
57
|
}
|
|
61
58
|
onMessage(message, rinfo) {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { Connection } from "../connection";
|
|
2
|
+
export interface DisconnectEvent {
|
|
3
|
+
connection: Connection;
|
|
4
|
+
reason: string;
|
|
5
|
+
}
|
|
2
6
|
export interface RaknetServerEvents {
|
|
3
7
|
listening: undefined;
|
|
4
8
|
connect: Connection;
|
|
5
|
-
disconnect:
|
|
9
|
+
disconnect: DisconnectEvent;
|
|
6
10
|
}
|
|
7
11
|
//# sourceMappingURL=server-events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-events.d.ts","sourceRoot":"","sources":["../../../src/server/types/server-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"server-events.d.ts","sourceRoot":"","sources":["../../../src/server/types/server-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;CAC5B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Ack, Frame, FrameSet, Priority } from "./proto";
|
|
2
2
|
export declare class NetworkSession {
|
|
3
3
|
mtu: number;
|
|
4
|
+
debug: boolean;
|
|
4
5
|
send: (data: Buffer) => void;
|
|
5
6
|
handle: (data: Buffer) => void;
|
|
6
7
|
outputReliableIndex: number;
|
|
@@ -12,13 +13,23 @@ export declare class NetworkSession {
|
|
|
12
13
|
outputBackup: Map<number, Frame[]>;
|
|
13
14
|
receivedFrameSequences: Set<number>;
|
|
14
15
|
lostFrameSequences: Set<number>;
|
|
16
|
+
pendingAcks: Set<number>;
|
|
15
17
|
lastInputSequence: number;
|
|
16
|
-
fragmentsQueue: Map<number,
|
|
18
|
+
fragmentsQueue: Map<number, {
|
|
19
|
+
frames: Map<number, Frame>;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
}>;
|
|
17
22
|
inputHighestSequenceIndex: Array<number>;
|
|
18
23
|
inputOrderIndex: Array<number>;
|
|
19
24
|
protected inputOrderingQueue: Map<number, Map<number, Frame>>;
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
private receivedReliableFrameIndices;
|
|
26
|
+
private highestReliableIndex;
|
|
27
|
+
private static readonly RECEIVE_WINDOW_SIZE;
|
|
28
|
+
private static readonly RELIABLE_WINDOW_SIZE;
|
|
29
|
+
private static readonly FRAGMENT_TIMEOUT_MS;
|
|
30
|
+
private static readonly ORDER_QUEUE_MAX_SIZE;
|
|
31
|
+
constructor(mtu: number, debug?: boolean);
|
|
32
|
+
onTick(_tick?: number): void;
|
|
22
33
|
onAck(ack: Ack): void;
|
|
23
34
|
onNack(nack: Ack): void;
|
|
24
35
|
frameAndSend(data: Buffer, priority?: Priority): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network_session.d.ts","sourceRoot":"","sources":["../../src/shared/network_session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAW,QAAQ,EAAe,MAAM,SAAS,CAAC;AAK/E,qBAAa,cAAc;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,MAAM,EAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAGhC,mBAAmB,SAAK;IACxB,gBAAgB,SAAK;IAC5B,SAAS,CAAC,cAAc,SAAK;IACtB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,CAAa;IACrC,YAAY,uBAA8B;IAG1C,sBAAsB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAChD,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAC5C,iBAAiB,SAAM;IACvB,cAAc,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"network_session.d.ts","sourceRoot":"","sources":["../../src/shared/network_session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAW,QAAQ,EAAe,MAAM,SAAS,CAAC;AAK/E,qBAAa,cAAc;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,MAAM,EAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAGhC,mBAAmB,SAAK;IACxB,gBAAgB,SAAK;IAC5B,SAAS,CAAC,cAAc,SAAK;IACtB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,CAAa;IACrC,YAAY,uBAA8B;IAG1C,sBAAsB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAChD,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAC5C,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IACrC,iBAAiB,SAAM;IACvB,cAAc,EAAE,GAAG,CACzB,MAAM,EACN;QAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CACjD,CAAa;IACP,yBAAyB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAa;IAE1E,OAAO,CAAC,4BAA4B,CAA0B;IAC9D,OAAO,CAAC,oBAAoB,CAAM;IAGlC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAQ;IACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAO;gBAEvC,GAAG,EAAE,MAAM,EAAE,KAAK,UAAQ;IAWtC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM;IAuDrB,KAAK,CAAC,GAAG,EAAE,GAAG;IAMd,MAAM,CAAC,IAAI,EAAE,GAAG;IAeT,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAA0B;IAQ/D,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAE,QAA0B;IA8C5D,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ;IAW3C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAiB/B,UAAU,CAAC,QAAQ,EAAE,QAAQ;IAkD7B,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAwB/B,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IA2CpC,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAenC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAyCxC"}
|
|
@@ -7,6 +7,7 @@ const logger_1 = require("./logger");
|
|
|
7
7
|
const MTU_HEADER_SIZE = 36;
|
|
8
8
|
class NetworkSession {
|
|
9
9
|
mtu;
|
|
10
|
+
debug;
|
|
10
11
|
send;
|
|
11
12
|
handle;
|
|
12
13
|
// Output
|
|
@@ -20,13 +21,22 @@ class NetworkSession {
|
|
|
20
21
|
// Input
|
|
21
22
|
receivedFrameSequences = new Set();
|
|
22
23
|
lostFrameSequences = new Set();
|
|
24
|
+
pendingAcks = new Set();
|
|
23
25
|
lastInputSequence = -1;
|
|
24
26
|
fragmentsQueue = new Map();
|
|
25
27
|
inputHighestSequenceIndex;
|
|
26
28
|
inputOrderIndex;
|
|
27
29
|
inputOrderingQueue = new Map();
|
|
28
|
-
|
|
30
|
+
receivedReliableFrameIndices = new Set();
|
|
31
|
+
highestReliableIndex = -1;
|
|
32
|
+
// goofy ahh geyser stuff
|
|
33
|
+
static RECEIVE_WINDOW_SIZE = 2048;
|
|
34
|
+
static RELIABLE_WINDOW_SIZE = 4096;
|
|
35
|
+
static FRAGMENT_TIMEOUT_MS = 30000;
|
|
36
|
+
static ORDER_QUEUE_MAX_SIZE = 256;
|
|
37
|
+
constructor(mtu, debug = false) {
|
|
29
38
|
this.mtu = mtu;
|
|
39
|
+
this.debug = debug;
|
|
30
40
|
this.outputOrderIndex = new Array(32).fill(0);
|
|
31
41
|
this.outputSequenceIndex = new Array(32).fill(0);
|
|
32
42
|
this.inputHighestSequenceIndex = Array.from({ length: 32 }).fill(0);
|
|
@@ -34,10 +44,36 @@ class NetworkSession {
|
|
|
34
44
|
for (let index = 0; index < 32; index++)
|
|
35
45
|
this.inputOrderingQueue.set(index, new Map());
|
|
36
46
|
}
|
|
37
|
-
onTick() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
onTick(_tick) {
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
const windowStart = this.lastInputSequence - NetworkSession.RECEIVE_WINDOW_SIZE;
|
|
50
|
+
if (windowStart > 0) {
|
|
51
|
+
for (const seq of this.receivedFrameSequences) {
|
|
52
|
+
if (seq < windowStart)
|
|
53
|
+
this.receivedFrameSequences.delete(seq);
|
|
54
|
+
}
|
|
55
|
+
for (const seq of this.lostFrameSequences) {
|
|
56
|
+
if (seq < windowStart)
|
|
57
|
+
this.lostFrameSequences.delete(seq);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const reliableWindowStart = this.highestReliableIndex - NetworkSession.RELIABLE_WINDOW_SIZE;
|
|
61
|
+
if (reliableWindowStart > 0) {
|
|
62
|
+
for (const idx of this.receivedReliableFrameIndices) {
|
|
63
|
+
if (idx < reliableWindowStart)
|
|
64
|
+
this.receivedReliableFrameIndices.delete(idx);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const [splitId, entry] of this.fragmentsQueue) {
|
|
68
|
+
if (now - entry.timestamp > NetworkSession.FRAGMENT_TIMEOUT_MS) {
|
|
69
|
+
if (this.debug)
|
|
70
|
+
logger_1.Logger.warn(`Fragment queue ${splitId} timed out, dropping ${entry.frames.size} fragments`);
|
|
71
|
+
this.fragmentsQueue.delete(splitId);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (this.pendingAcks.size > 0) {
|
|
75
|
+
const ackSeqs = Array.from(this.pendingAcks);
|
|
76
|
+
this.pendingAcks.clear();
|
|
41
77
|
const ack = new proto_1.Ack();
|
|
42
78
|
ack.sequences = ackSeqs;
|
|
43
79
|
this.send(ack.serialize());
|
|
@@ -145,27 +181,53 @@ class NetworkSession {
|
|
|
145
181
|
this.send(buffer);
|
|
146
182
|
}
|
|
147
183
|
onFrameSet(frameSet) {
|
|
184
|
+
// Already received this exact sequence so ignore duplicate
|
|
148
185
|
if (this.receivedFrameSequences.has(frameSet.sequence)) {
|
|
149
|
-
|
|
186
|
+
if (this.debug)
|
|
187
|
+
logger_1.Logger.warn(`Duplicate frame set received: sequence ${frameSet.sequence}`);
|
|
188
|
+
return;
|
|
150
189
|
}
|
|
190
|
+
// Remove from lost if we finally got it
|
|
151
191
|
this.lostFrameSequences.delete(frameSet.sequence);
|
|
152
|
-
|
|
153
|
-
const isEqual = frameSet.sequence === this.lastInputSequence;
|
|
154
|
-
if (isLess || isEqual) {
|
|
155
|
-
throw new Error("Frame set received is out of order");
|
|
156
|
-
}
|
|
192
|
+
// Track this sequence as received and queue ACK
|
|
157
193
|
this.receivedFrameSequences.add(frameSet.sequence);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
194
|
+
this.pendingAcks.add(frameSet.sequence);
|
|
195
|
+
// If this is a newer sequence than we've seen, update tracking
|
|
196
|
+
if (frameSet.sequence > this.lastInputSequence) {
|
|
197
|
+
const diff = frameSet.sequence - this.lastInputSequence;
|
|
198
|
+
// Mark any gaps as lost (for NACK)
|
|
199
|
+
if (diff > 1) {
|
|
200
|
+
for (let index = this.lastInputSequence + 1; index < frameSet.sequence; index++) {
|
|
201
|
+
// Only mark as lost if we haven't already received it
|
|
202
|
+
if (!this.receivedFrameSequences.has(index)) {
|
|
203
|
+
this.lostFrameSequences.add(index);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
this.lastInputSequence = frameSet.sequence;
|
|
162
208
|
}
|
|
163
|
-
|
|
209
|
+
else {
|
|
210
|
+
// zOut-of-order packet (arrived late but still valid)
|
|
211
|
+
if (this.debug)
|
|
212
|
+
logger_1.Logger.warn(`Out-of-order frame set received: sequence ${frameSet.sequence} (expected > ${this.lastInputSequence})`);
|
|
213
|
+
}
|
|
214
|
+
// Process all frames
|
|
164
215
|
for (const frame of frameSet.frames) {
|
|
165
216
|
this.handleFrame(frame);
|
|
166
217
|
}
|
|
167
218
|
}
|
|
168
219
|
handleFrame(frame) {
|
|
220
|
+
// Duplicate detection for reliable frames
|
|
221
|
+
if (frame.isReliable()) {
|
|
222
|
+
if (this.receivedReliableFrameIndices.has(frame.reliableFrameIndex)) {
|
|
223
|
+
// Already processed tsis reliable frame, skip
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
this.receivedReliableFrameIndices.add(frame.reliableFrameIndex);
|
|
227
|
+
if (frame.reliableFrameIndex > this.highestReliableIndex) {
|
|
228
|
+
this.highestReliableIndex = frame.reliableFrameIndex;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
169
231
|
if (frame.isSplit()) {
|
|
170
232
|
this.handleSplitFrame(frame);
|
|
171
233
|
}
|
|
@@ -183,38 +245,49 @@ class NetworkSession {
|
|
|
183
245
|
const splitId = frame.splitId;
|
|
184
246
|
let entry = this.fragmentsQueue.get(splitId);
|
|
185
247
|
if (!entry) {
|
|
186
|
-
entry = new Map();
|
|
248
|
+
entry = { frames: new Map(), timestamp: Date.now() };
|
|
187
249
|
this.fragmentsQueue.set(splitId, entry);
|
|
188
250
|
}
|
|
189
|
-
entry.set(frame.splitFrameIndex, frame);
|
|
190
|
-
if (entry.size === frame.splitSize) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
251
|
+
entry.frames.set(frame.splitFrameIndex, frame);
|
|
252
|
+
if (entry.frames.size === frame.splitSize) {
|
|
253
|
+
const stream = new binarystream_1.BinaryStream();
|
|
254
|
+
for (let index = 0; index < frame.splitSize; index++) {
|
|
255
|
+
const sframe = entry.frames.get(index);
|
|
256
|
+
if (!sframe) {
|
|
257
|
+
if (this.debug)
|
|
258
|
+
logger_1.Logger.warn(`Missing fragment at index ${index} for splitId=${frame.splitId}`);
|
|
259
|
+
this.fragmentsQueue.delete(splitId);
|
|
260
|
+
return;
|
|
199
261
|
}
|
|
200
|
-
|
|
201
|
-
reassembledFrame.reliability = frame.reliability;
|
|
202
|
-
reassembledFrame.reliableFrameIndex = frame.reliableFrameIndex;
|
|
203
|
-
reassembledFrame.sequenceFrameIndex = frame.sequenceFrameIndex;
|
|
204
|
-
reassembledFrame.orderedFrameIndex = frame.orderedFrameIndex;
|
|
205
|
-
reassembledFrame.orderChannel = frame.orderChannel;
|
|
206
|
-
reassembledFrame.payload = stream.getBuffer();
|
|
207
|
-
this.handleFrame(reassembledFrame);
|
|
262
|
+
stream.write(sframe.payload);
|
|
208
263
|
}
|
|
264
|
+
const reassembledFrame = new proto_1.Frame();
|
|
265
|
+
reassembledFrame.reliability = frame.reliability;
|
|
266
|
+
reassembledFrame.reliableFrameIndex = frame.reliableFrameIndex;
|
|
267
|
+
reassembledFrame.sequenceFrameIndex = frame.sequenceFrameIndex;
|
|
268
|
+
reassembledFrame.orderedFrameIndex = frame.orderedFrameIndex;
|
|
269
|
+
reassembledFrame.orderChannel = frame.orderChannel;
|
|
270
|
+
reassembledFrame.payload = stream.getBuffer();
|
|
209
271
|
this.fragmentsQueue.delete(splitId);
|
|
272
|
+
// Process the reassembled frame (but skip split handling since it's no longer split)
|
|
273
|
+
if (reassembledFrame.isSequenced()) {
|
|
274
|
+
this.handleSequenced(reassembledFrame);
|
|
275
|
+
}
|
|
276
|
+
else if (reassembledFrame.isOrdered()) {
|
|
277
|
+
this.handleOrdered(reassembledFrame);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
this.handle(reassembledFrame.payload);
|
|
281
|
+
}
|
|
210
282
|
}
|
|
211
283
|
}
|
|
212
284
|
handleSequenced(frame) {
|
|
213
285
|
const channel = frame.orderChannel;
|
|
214
|
-
const currentHighestSequence = this.inputHighestSequenceIndex[channel];
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
286
|
+
const currentHighestSequence = this.inputHighestSequenceIndex[channel] ?? 0;
|
|
287
|
+
// Sequenced frames: drop if older than what we've seen, otherwise process immediately
|
|
288
|
+
// They don't need ordering, just drop stale ones
|
|
289
|
+
if (frame.sequenceFrameIndex < currentHighestSequence) {
|
|
290
|
+
// Old sequenced frame, drop it
|
|
218
291
|
return;
|
|
219
292
|
}
|
|
220
293
|
this.inputHighestSequenceIndex[channel] = frame.sequenceFrameIndex + 1;
|
|
@@ -222,32 +295,42 @@ class NetworkSession {
|
|
|
222
295
|
}
|
|
223
296
|
handleOrdered(frame) {
|
|
224
297
|
const channel = frame.orderChannel;
|
|
225
|
-
const expectedOrderIndex = this.inputOrderIndex[channel];
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
298
|
+
const expectedOrderIndex = this.inputOrderIndex[channel] ?? 0;
|
|
299
|
+
if (frame.orderedFrameIndex === expectedOrderIndex) {
|
|
300
|
+
// This is the frame we're waiting for - process it
|
|
301
|
+
this.inputHighestSequenceIndex[channel] = 0;
|
|
302
|
+
this.inputOrderIndex[channel] = expectedOrderIndex + 1;
|
|
303
|
+
this.handle(frame.payload);
|
|
304
|
+
// Now flush any queued frames that are now in order
|
|
305
|
+
const outOfOrderQueue = this.inputOrderingQueue.get(channel);
|
|
306
|
+
if (outOfOrderQueue) {
|
|
307
|
+
let nextIndex = expectedOrderIndex + 1;
|
|
308
|
+
while (outOfOrderQueue.has(nextIndex)) {
|
|
309
|
+
const queuedFrame = outOfOrderQueue.get(nextIndex);
|
|
310
|
+
if (queuedFrame) {
|
|
311
|
+
this.handle(queuedFrame.payload);
|
|
312
|
+
outOfOrderQueue.delete(nextIndex);
|
|
313
|
+
}
|
|
314
|
+
nextIndex++;
|
|
315
|
+
}
|
|
316
|
+
this.inputOrderIndex[channel] = nextIndex;
|
|
232
317
|
}
|
|
233
|
-
unordered.set(frame.orderedFrameIndex, frame);
|
|
234
318
|
}
|
|
235
|
-
else if (
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
319
|
+
else if (frame.orderedFrameIndex > expectedOrderIndex) {
|
|
320
|
+
// Future frame n queue it for later
|
|
321
|
+
const outOfOrderQueue = this.inputOrderingQueue.get(channel);
|
|
322
|
+
if (outOfOrderQueue) {
|
|
323
|
+
// Prevent unbounded queue growth
|
|
324
|
+
if (outOfOrderQueue.size < NetworkSession.ORDER_QUEUE_MAX_SIZE) {
|
|
325
|
+
outOfOrderQueue.set(frame.orderedFrameIndex, frame);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
if (this.debug)
|
|
329
|
+
logger_1.Logger.debug(`Order queue for channel ${channel} is full, dropping frame ${frame.orderedFrameIndex}`);
|
|
330
|
+
}
|
|
247
331
|
}
|
|
248
|
-
this.inputOrderingQueue.set(frame.orderChannel, outOfOrderQueue);
|
|
249
|
-
this.inputOrderIndex[frame.orderChannel] = index;
|
|
250
332
|
}
|
|
333
|
+
// If frame.orderedFrameIndex < expectedOrderIndex, it's a duplicate/old frame - ignore it
|
|
251
334
|
}
|
|
252
335
|
}
|
|
253
336
|
exports.NetworkSession = NetworkSession;
|