@sanctumterra/raknet 1.4.6 → 1.4.8

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.
@@ -5,6 +5,8 @@ import { type RemoteInfo } from "node:dgram";
5
5
  export declare class Client extends EventEmitter<ClientEvents> {
6
6
  private static readonly MTU_VALUES;
7
7
  private static readonly MTU_RETRY_INTERVAL;
8
+ private static readonly STALE_TIMEOUT_MS;
9
+ private static readonly PING_INTERVAL_TICKS;
8
10
  options: ClientOptions;
9
11
  private socket;
10
12
  private interval;
@@ -17,6 +19,8 @@ export declare class Client extends EventEmitter<ClientEvents> {
17
19
  private proxyRelayPort;
18
20
  private resolvedAddress;
19
21
  private proxyReady;
22
+ private lastPongTime;
23
+ private isDisconnected;
20
24
  constructor(options?: Partial<ClientOptions>);
21
25
  private setupProxy;
22
26
  private buildUdpAssociateRequest;
@@ -25,6 +29,9 @@ export declare class Client extends EventEmitter<ClientEvents> {
25
29
  private parseSocks5UdpHeader;
26
30
  connect(): Promise<void>;
27
31
  onTick(): void;
32
+ private sendConnectedPing;
33
+ private handleDisconnect;
34
+ private cleanup;
28
35
  onMessage(data: Buffer, rinfo: RemoteInfo): void;
29
36
  handleOnline(data: Buffer): void;
30
37
  sendFrame(frame: Frame, priority?: Priority): void;
@@ -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,EAIV,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;IAE1C,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;gBAEf,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;IAYd,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IA8DhD,YAAY,CAAC,IAAI,EAAE,MAAM;IAyCzB,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;CAQzB"}
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;IAgEhD,YAAY,CAAC,IAAI,EAAE,MAAM;IAgDzB,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"}
@@ -10,6 +10,8 @@ const promises_1 = require("node:dns/promises");
10
10
  class Client extends shared_1.EventEmitter {
11
11
  static MTU_VALUES = [1492, 1400, 1028, 1200, 576];
12
12
  static MTU_RETRY_INTERVAL = 500;
13
+ static STALE_TIMEOUT_MS = 10000; // 10 seconds without pong = stale
14
+ static PING_INTERVAL_TICKS = 100; // Send connected ping every ~2 seconds at 50 tick rate
13
15
  options;
14
16
  socket;
15
17
  interval;
@@ -22,6 +24,8 @@ class Client extends shared_1.EventEmitter {
22
24
  proxyRelayPort = null;
23
25
  resolvedAddress = null;
24
26
  proxyReady = false;
27
+ lastPongTime = Date.now();
28
+ isDisconnected = false;
25
29
  constructor(options = {}) {
26
30
  super();
27
31
  this.options = { ...client_options_1.defaultClientOptions, ...options };
@@ -241,14 +245,57 @@ class Client extends shared_1.EventEmitter {
241
245
  onTick() {
242
246
  const isDisconnected = this.status === shared_1.ConnectionStatus.Disconnected;
243
247
  const isDisconnecting = this.status === shared_1.ConnectionStatus.Disconnecting;
248
+ const isConnected = this.status === shared_1.ConnectionStatus.Connected;
244
249
  const canPing = isDisconnected && this.tick % this.options.pingRate === 0;
245
250
  if (canPing && (!this.options.proxy || this.proxyReady))
246
251
  this.ping();
252
+ // Send connected pings and check for stale connection when connected
253
+ if (isConnected) {
254
+ // Send connected ping periodically
255
+ if (this.tick % Client.PING_INTERVAL_TICKS === 0) {
256
+ this.sendConnectedPing();
257
+ }
258
+ // Check for stale connection
259
+ const timeSinceLastPong = Date.now() - this.lastPongTime;
260
+ if (timeSinceLastPong > Client.STALE_TIMEOUT_MS) {
261
+ this.handleDisconnect("Connection timed out (stale)");
262
+ return;
263
+ }
264
+ }
247
265
  if (!isDisconnecting || !isDisconnected) {
248
266
  this.session.onTick(this.tick);
249
267
  }
250
268
  this.tick++;
251
269
  }
270
+ sendConnectedPing() {
271
+ const ping = new shared_1.ConnectedPing();
272
+ ping.timestamp = BigInt(Date.now());
273
+ this.frameAndSend(ping.serialize(), shared_1.Priority.High);
274
+ }
275
+ handleDisconnect(reason) {
276
+ if (this.isDisconnected)
277
+ return;
278
+ this.isDisconnected = true;
279
+ this.status = shared_1.ConnectionStatus.Disconnected;
280
+ this.emit("disconnect", reason);
281
+ this.cleanup();
282
+ }
283
+ cleanup() {
284
+ if (this.interval) {
285
+ clearInterval(this.interval);
286
+ this.interval = null;
287
+ }
288
+ try {
289
+ this.socket.close();
290
+ }
291
+ catch {
292
+ // Socket may already be closed
293
+ }
294
+ if (this.proxySocket) {
295
+ this.proxySocket.destroy();
296
+ this.proxySocket = null;
297
+ }
298
+ }
252
299
  onMessage(data, rinfo) {
253
300
  let actualData = data;
254
301
  if (this.proxyRelayHost && this.proxyRelayPort) {
@@ -280,7 +327,9 @@ class Client extends shared_1.EventEmitter {
280
327
  break;
281
328
  }
282
329
  case shared_1.Packets.OpenConnectionReply2: {
283
- new shared_1.OpenConnectionReplyTwo(actualData).deserialize();
330
+ const reply2 = new shared_1.OpenConnectionReplyTwo(actualData).deserialize();
331
+ // Update session MTU with the negotiated value from server
332
+ this.session.mtu = reply2.mtu;
284
333
  const request = new shared_1.ConnectionRequest();
285
334
  request.guid = this.options.guid;
286
335
  request.timestamp = BigInt(Date.now());
@@ -316,6 +365,7 @@ class Client extends shared_1.EventEmitter {
316
365
  break;
317
366
  }
318
367
  case shared_1.Packets.ConnectedPong: {
368
+ this.lastPongTime = Date.now();
319
369
  break;
320
370
  }
321
371
  case shared_1.Packets.ConnectedPing: {
@@ -323,7 +373,11 @@ class Client extends shared_1.EventEmitter {
323
373
  const pong = new shared_1.ConnectedPong();
324
374
  pong.pingTimestamp = ping.timestamp;
325
375
  pong.pongTimestamp = BigInt(Date.now());
326
- this.frameAndSend(ping.serialize(), shared_1.Priority.High);
376
+ this.frameAndSend(pong.serialize(), shared_1.Priority.High);
377
+ break;
378
+ }
379
+ case shared_1.Packets.Disconnect: {
380
+ this.handleDisconnect("Server disconnected");
327
381
  break;
328
382
  }
329
383
  case shared_1.Packets.ConnectionRequestAccepted: {
@@ -334,6 +388,8 @@ class Client extends shared_1.EventEmitter {
334
388
  nic.incomingTimestamp = BigInt(Date.now());
335
389
  nic.serverTimestamp = accepted.timestamp;
336
390
  this.frameAndSend(nic.serialize(), shared_1.Priority.High);
391
+ this.status = shared_1.ConnectionStatus.Connected;
392
+ this.lastPongTime = Date.now(); // Reset stale timer on connect
337
393
  this.emit("connect");
338
394
  break;
339
395
  }
@@ -367,13 +423,14 @@ class Client extends shared_1.EventEmitter {
367
423
  }
368
424
  }
369
425
  disconnect() {
370
- this.socket.close();
371
- if (this.proxySocket) {
372
- this.proxySocket.destroy();
373
- this.proxySocket = null;
426
+ if (this.isDisconnected)
427
+ return;
428
+ // Send disconnect packet to server if connected
429
+ if (this.status === shared_1.ConnectionStatus.Connected) {
430
+ const disconnect = new shared_1.DisconnectMessage();
431
+ this.frameAndSend(disconnect.serialize(), shared_1.Priority.High);
374
432
  }
375
- if (this.interval)
376
- clearInterval(this.interval);
433
+ this.handleDisconnect("Client disconnected");
377
434
  }
378
435
  }
379
436
  exports.Client = Client;
@@ -3,6 +3,7 @@ export interface ClientEvents {
3
3
  unconnectedPong: UnconnectedPong;
4
4
  error: Error;
5
5
  connect: undefined;
6
+ disconnect: string;
6
7
  encapsulated: Buffer;
7
8
  }
8
9
  //# sourceMappingURL=client-events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-events.d.ts","sourceRoot":"","sources":["../../../src/client/types/client-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC5B,eAAe,EAAE,eAAe,CAAC;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,SAAS,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"client-events.d.ts","sourceRoot":"","sources":["../../../src/client/types/client-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC5B,eAAe,EAAE,eAAe,CAAC;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACrB"}
@@ -7,9 +7,15 @@ export declare class Connection extends EventEmitter<ConnectionEvents> {
7
7
  private rinfo;
8
8
  private mtu;
9
9
  private guid;
10
+ private static readonly STALE_TIMEOUT_MS;
11
+ private static readonly PING_INTERVAL_TICKS;
10
12
  private session;
13
+ private lastActivityTime;
14
+ private isDisconnected;
11
15
  constructor(server: Server, rinfo: RemoteInfo, mtu: number, guid: bigint);
12
16
  onTick(tick: number): void;
17
+ disconnect(reason?: string): void;
18
+ isStale(): boolean;
13
19
  onFrameSet(frameSet: FrameSet): void;
14
20
  getAddress(): RemoteInfo;
15
21
  onMessage(data: Buffer): void;
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/server/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EAMR,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;IAI5D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IANb,OAAO,CAAC,OAAO,CAAiB;gBAGvB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM;IAQd,MAAM,CAAC,IAAI,EAAE,MAAM;IAInB,UAAU,CAAC,QAAQ,EAAE,QAAQ;IAI7B,UAAU,IAAI,UAAU;IAIxB,SAAS,CAAC,IAAI,EAAE,MAAM;IAqDtB,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"}
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;IAQd,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;IA2DtB,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"}
@@ -7,7 +7,11 @@ class Connection extends shared_1.EventEmitter {
7
7
  rinfo;
8
8
  mtu;
9
9
  guid;
10
+ static STALE_TIMEOUT_MS = 10000; // 10 seconds without activity = stale
11
+ static PING_INTERVAL_TICKS = 100; // Send ping every ~2 seconds at 50 tick rate
10
12
  session;
13
+ lastActivityTime = Date.now();
14
+ isDisconnected = false;
11
15
  constructor(server, rinfo, mtu, guid) {
12
16
  super();
13
17
  this.server = server;
@@ -19,15 +23,44 @@ class Connection extends shared_1.EventEmitter {
19
23
  this.session.handle = this.onMessage.bind(this);
20
24
  }
21
25
  onTick(tick) {
26
+ if (this.isDisconnected)
27
+ return;
28
+ // Check for stale connection
29
+ const timeSinceLastActivity = Date.now() - this.lastActivityTime;
30
+ if (timeSinceLastActivity > Connection.STALE_TIMEOUT_MS) {
31
+ this.disconnect("Connection timed out (stale)");
32
+ return;
33
+ }
34
+ // Send connected ping periodically
35
+ if (tick % Connection.PING_INTERVAL_TICKS === 0) {
36
+ const ping = new shared_1.ConnectedPing();
37
+ ping.timestamp = BigInt(Date.now());
38
+ this.session.frameAndSend(ping.serialize(), shared_1.Priority.High);
39
+ }
22
40
  this.session.onTick(tick);
23
41
  }
42
+ disconnect(reason = "Disconnected") {
43
+ if (this.isDisconnected)
44
+ return;
45
+ this.isDisconnected = true;
46
+ // Send disconnect packet to client
47
+ const disconnect = new shared_1.DisconnectMessage();
48
+ this.session.frameAndSend(disconnect.serialize(), shared_1.Priority.High);
49
+ // Emit disconnect event
50
+ this.server.emit("disconnect", this);
51
+ }
52
+ isStale() {
53
+ return this.isDisconnected;
54
+ }
24
55
  onFrameSet(frameSet) {
56
+ this.lastActivityTime = Date.now();
25
57
  this.session.onFrameSet(frameSet);
26
58
  }
27
59
  getAddress() {
28
60
  return this.rinfo;
29
61
  }
30
62
  onMessage(data) {
63
+ this.lastActivityTime = Date.now();
31
64
  const id = data[0];
32
65
  switch (id) {
33
66
  case shared_1.Packets.ConnectionRequest: {
@@ -47,6 +80,7 @@ class Connection extends shared_1.EventEmitter {
47
80
  break;
48
81
  }
49
82
  case shared_1.Packets.Disconnect: {
83
+ this.isDisconnected = true;
50
84
  this.server.emit("disconnect", this);
51
85
  break;
52
86
  }
@@ -58,6 +92,10 @@ class Connection extends shared_1.EventEmitter {
58
92
  this.session.frameAndSend(pong.serialize(), shared_1.Priority.High);
59
93
  break;
60
94
  }
95
+ case shared_1.Packets.ConnectedPong: {
96
+ // Pong received, activity time already updated above
97
+ break;
98
+ }
61
99
  case 254: {
62
100
  this.emit("encapsulated", data);
63
101
  break;
@@ -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,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAa;IAC5D,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;gBAE9D,GAAG,EAAE,MAAM;IAUvB,MAAM,CAAC,IAAI,EAAE,MAAM;IAuBnB,KAAK,CAAC,GAAG,EAAE,GAAG;IAMd,MAAM,CAAC,IAAI,EAAE,GAAG;IAUT,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAA0B;IAO/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;IA6B7B,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAY/B,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAiCpC,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAcnC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CA8BxC"}
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,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAa;IAC5D,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;gBAE9D,GAAG,EAAE,MAAM;IAUvB,MAAM,CAAC,IAAI,EAAE,MAAM;IAuBnB,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;IA6B7B,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAY/B,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAiCpC,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAcnC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CA8BxC"}
@@ -63,14 +63,20 @@ class NetworkSession {
63
63
  onNack(nack) {
64
64
  for (let i = 0, len = nack.sequences.length; i < len; i++) {
65
65
  const seq = nack.sequences[i];
66
- const lostFrames = this.outputBackup.get(seq) || [];
67
- for (let j = 0, lostLen = lostFrames.length; j < lostLen; j++) {
68
- this.sendFrame(lostFrames[j], proto_1.Priority.High);
69
- }
66
+ const lostFrames = this.outputBackup.get(seq);
67
+ if (!lostFrames || lostFrames.length === 0)
68
+ continue;
69
+ // Resend the exact same frameset with the same sequence number
70
+ const frameset = new proto_1.FrameSet();
71
+ frameset.sequence = seq;
72
+ frameset.frames = lostFrames;
73
+ const buffer = frameset.serialize();
74
+ this.send(buffer);
70
75
  }
71
76
  }
72
77
  frameAndSend(data, priority = proto_1.Priority.Medium) {
73
78
  const frame = new proto_1.Frame();
79
+ frame.reliability = proto_1.Reliability.ReliableOrdered;
74
80
  frame.orderChannel = 0;
75
81
  frame.payload = data;
76
82
  this.sendFrame(frame, priority);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctumterra/raknet",
3
- "version": "1.4.6",
3
+ "version": "1.4.8",
4
4
  "description": "",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",