@sanctumterra/raknet 1.3.70 → 1.3.71

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.
@@ -1,4 +1,4 @@
1
- import type { Ack, Advertisement, ConnectedPing, ConnectionRequest, ConnectionRequestAccepted, NewIncomingConnection, OpenConnectionReplyOne, OpenConnectionReplyTwo, OpenConnectionRequestOne, OpenConnectionRequestTwo, UnconnectedPing, UnconnectedPong } from "../proto";
1
+ import type { Ack, Advertisement, ConnectedPing, ConnectedPong, ConnectionRequest, ConnectionRequestAccepted, NewIncomingConnection, OpenConnectionReplyOne, OpenConnectionReplyTwo, OpenConnectionRequestOne, OpenConnectionRequestTwo, UnconnectedPing, UnconnectedPong } from "../proto";
2
2
  import type { Frameset } from "../proto/packets/frameset";
3
3
  export interface ClientEvents {
4
4
  "open-connection-reply-one": [OpenConnectionReplyOne];
@@ -9,6 +9,7 @@ export interface ClientEvents {
9
9
  "unconnected-pong": [UnconnectedPong];
10
10
  frameset: [Frameset];
11
11
  "connected-ping": [ConnectedPing];
12
+ "connected-pong": [ConnectedPong];
12
13
  "connection-request": [ConnectionRequest];
13
14
  "connection-request-accepted": [ConnectionRequestAccepted];
14
15
  "new-incoming-connection": [NewIncomingConnection];
@@ -1 +1 @@
1
- {"version":3,"file":"client-events.d.ts","sourceRoot":"","sources":["../../src/client/client-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,GAAG,EACH,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC5B,2BAA2B,EAAE,CAAC,sBAAsB,CAAC,CAAC;IACtD,2BAA2B,EAAE,CAAC,sBAAsB,CAAC,CAAC;IACtD,6BAA6B,EAAE,CAAC,wBAAwB,CAAC,CAAC;IAC1D,6BAA6B,EAAE,CAAC,wBAAwB,CAAC,CAAC;IAC1D,kBAAkB,EAAE,CAAC,eAAe,CAAC,CAAC;IACtC,kBAAkB,EAAE,CAAC,eAAe,CAAC,CAAC;IACtC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IACrB,gBAAgB,EAAE,CAAC,aAAa,CAAC,CAAC;IAClC,oBAAoB,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAC1C,6BAA6B,EAAE,CAAC,yBAAyB,CAAC,CAAC;IAC3D,yBAAyB,EAAE,CAAC,qBAAqB,CAAC,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC;IACvB,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACX,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;IACf,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;IACzB,IAAI,EAAE,EAAE,CAAC;CACT"}
1
+ {"version":3,"file":"client-events.d.ts","sourceRoot":"","sources":["../../src/client/client-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,GAAG,EACH,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC5B,2BAA2B,EAAE,CAAC,sBAAsB,CAAC,CAAC;IACtD,2BAA2B,EAAE,CAAC,sBAAsB,CAAC,CAAC;IACtD,6BAA6B,EAAE,CAAC,wBAAwB,CAAC,CAAC;IAC1D,6BAA6B,EAAE,CAAC,wBAAwB,CAAC,CAAC;IAC1D,kBAAkB,EAAE,CAAC,eAAe,CAAC,CAAC;IACtC,kBAAkB,EAAE,CAAC,eAAe,CAAC,CAAC;IACtC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IACrB,gBAAgB,EAAE,CAAC,aAAa,CAAC,CAAC;IAClC,gBAAgB,EAAE,CAAC,aAAa,CAAC,CAAC;IAClC,oBAAoB,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAC1C,6BAA6B,EAAE,CAAC,yBAAyB,CAAC,CAAC;IAC3D,yBAAyB,EAAE,CAAC,qBAAqB,CAAC,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC;IACvB,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACX,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;IACf,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;IACzB,IAAI,EAAE,EAAE,CAAC;CACT"}
@@ -2,7 +2,7 @@ import { Emitter } from "@serenityjs/emitter";
2
2
  import type { ClientEvents } from "./client-events";
3
3
  import { type Socket } from "node:dgram";
4
4
  import { Framer } from "./framer";
5
- import { type Address, type Advertisement, type Frame, type Priority, Status } from "../proto";
5
+ import { type Address, type Advertisement, Frame, type Priority, Status } from "../proto";
6
6
  import { type ClientOptions } from "./client-options";
7
7
  export declare class Client extends Emitter<ClientEvents> {
8
8
  socket: Socket;
@@ -17,6 +17,7 @@ export declare class Client extends Emitter<ClientEvents> {
17
17
  ping(): Promise<Advertisement | null>;
18
18
  connect(): Promise<Advertisement>;
19
19
  sendFrame(frame: Frame, priority: Priority): void;
20
+ frameAndSend(payload: Buffer, priority: Priority): void;
20
21
  send(buffer: Buffer): void;
21
22
  cleanup(): void;
22
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAmB,KAAK,MAAM,EAAgB,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAEN,KAAK,OAAO,EACZ,KAAK,aAAa,EAElB,KAAK,KAAK,EAOV,KAAK,QAAQ,EACb,MAAM,EAGN,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,kBAAkB,CAAC;AAI5E,qBAAa,MAAO,SAAQ,OAAO,CAAC,YAAY,CAAC;IACzC,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,OAAO,CAAkB;IAC1B,aAAa,EAAG,OAAO,CAAC;IAExB,MAAM,SAAuB;gBAExB,OAAO,GAAE,OAAO,CAAC,aAAa,CAAwB;IAO3D,UAAU;IAiBJ,IAAI,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkBrC,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IA2EvC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIjD,IAAI,CAAC,MAAM,EAAE,MAAM;IAcnB,OAAO,IAAI,IAAI;CAQtB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAmB,KAAK,MAAM,EAAgB,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAEN,KAAK,OAAO,EACZ,KAAK,aAAa,EAElB,KAAK,EAOL,KAAK,QAAQ,EAEb,MAAM,EAGN,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,kBAAkB,CAAC;AAI5E,qBAAa,MAAO,SAAQ,OAAO,CAAC,YAAY,CAAC;IACzC,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,OAAO,CAAkB;IAC1B,aAAa,EAAG,OAAO,CAAC;IAExB,MAAM,SAAuB;gBAExB,OAAO,GAAE,OAAO,CAAC,aAAa,CAAwB;IAO3D,UAAU;IAgBJ,IAAI,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkBrC,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IA8EvC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAQjD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAQvD,IAAI,CAAC,MAAM,EAAE,MAAM;IAyBnB,OAAO,IAAI,IAAI;CA4BtB"}
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.Client = void 0;
4
7
  const emitter_1 = require("@serenityjs/emitter");
5
8
  const node_dgram_1 = require("node:dgram");
6
9
  const framer_1 = require("./framer");
7
10
  const proto_1 = require("../proto");
11
+ const disconnect_1 = __importDefault(require("../proto/packets/disconnect"));
8
12
  const client_options_1 = require("./client-options");
9
13
  const utils_1 = require("../utils");
10
14
  class Client extends emitter_1.Emitter {
@@ -56,6 +60,9 @@ class Client extends emitter_1.Emitter {
56
60
  if (this.status === proto_1.Status.Connecting) {
57
61
  throw new Error("Connection attempt already in progress");
58
62
  }
63
+ if (this.status === proto_1.Status.Connected) {
64
+ throw new Error("Already connected");
65
+ }
59
66
  this.status = proto_1.Status.Connecting;
60
67
  this.initSocket();
61
68
  this.timer = setInterval(() => this.emit("tick"), 50);
@@ -118,20 +125,61 @@ class Client extends emitter_1.Emitter {
118
125
  }
119
126
  }
120
127
  sendFrame(frame, priority) {
121
- this.framer.sendFrame(frame, priority);
128
+ try {
129
+ this.framer.sendFrame(frame, priority);
130
+ }
131
+ catch (error) {
132
+ utils_1.Logger.error("[Raknet] Failed to send frame", error);
133
+ }
134
+ }
135
+ frameAndSend(payload, priority) {
136
+ const frame = new proto_1.Frame();
137
+ frame.reliability = proto_1.Reliability.ReliableOrdered;
138
+ frame.payload = payload;
139
+ frame.orderChannel = 0;
140
+ this.sendFrame(frame, priority);
122
141
  }
123
142
  send(buffer) {
124
- if (this.options.debug)
125
- utils_1.Logger.debug(`Sending ${buffer[0]}, ${buffer.length} bytes to ${this.options.address}:${this.options.port}`);
126
- this.socket.send(buffer, 0, buffer.length, this.options.port, this.options.address);
143
+ if (this.status === proto_1.Status.Disconnected) {
144
+ utils_1.Logger.warn("[Client] Attempting to send packet while disconnected");
145
+ return;
146
+ }
147
+ utils_1.Logger.debug(`[Client] Sending packet ${buffer[0]}, ${buffer.length} bytes to ${this.options.address}:${this.options.port}`);
148
+ utils_1.Logger.debug(`[Client] Current connection status: ${proto_1.Status[this.status]}`);
149
+ try {
150
+ this.socket.send(buffer, 0, buffer.length, this.options.port, this.options.address);
151
+ }
152
+ catch (error) {
153
+ utils_1.Logger.error("[Client] Failed to send packet", error);
154
+ this.cleanup();
155
+ }
127
156
  }
128
157
  cleanup() {
129
- this.removeAll();
130
- this.socket.removeAllListeners();
131
- this.socket.close();
132
- clearInterval(this.timer);
133
- clearTimeout(this.timeout);
134
- this.status = proto_1.Status.Disconnected;
158
+ if (this.status === proto_1.Status.Disconnected) {
159
+ return;
160
+ }
161
+ utils_1.Logger.info("[Client] Cleaning up connection and resources");
162
+ const wasConnected = this.status === proto_1.Status.Connected;
163
+ this.status = proto_1.Status.Disconnecting;
164
+ try {
165
+ // Send disconnect notification if we were connected
166
+ if (wasConnected) {
167
+ const disconnect = new disconnect_1.default();
168
+ this.send(disconnect.serialize());
169
+ }
170
+ this.removeAll();
171
+ this.socket.removeAllListeners();
172
+ this.socket.close();
173
+ clearInterval(this.timer);
174
+ clearTimeout(this.timeout);
175
+ }
176
+ catch (error) {
177
+ utils_1.Logger.error("[Client] Error during cleanup", error);
178
+ }
179
+ finally {
180
+ this.status = proto_1.Status.Disconnected;
181
+ utils_1.Logger.info("[Client] Cleanup complete, status set to Disconnected");
182
+ }
135
183
  }
136
184
  }
137
185
  exports.Client = Client;
@@ -9,7 +9,7 @@ export declare class Framer {
9
9
  private lostFrameSequences;
10
10
  private inputHighestSequenceIndex;
11
11
  private inputOrderIndex;
12
- protected inputOrderingQueue: Map<number, Map<number, Frame>>;
12
+ protected inputOrderingQueue: Array<Map<number, Frame>>;
13
13
  protected readonly fragmentsQueue: Map<number, Map<number, Frame>>;
14
14
  outputOrderIndex: number[];
15
15
  outputSequenceIndex: number[];
@@ -17,9 +17,12 @@ export declare class Framer {
17
17
  protected outputSequence: number;
18
18
  protected outputSplitIndex: number;
19
19
  protected outputReliableIndex: number;
20
- protected outputFrames: Set<Frame>;
20
+ outputFrames: Frame[];
21
+ private outputFramesByteLength;
21
22
  outputBackup: Map<number, Frame[]>;
22
23
  _tickCount: number;
24
+ private lastPingSent;
25
+ private lastPongReceived;
23
26
  constructor(client: Client);
24
27
  tick(): void;
25
28
  incommingMessage(payload: Buffer, rinfo: RemoteInfo): void;
@@ -33,7 +36,6 @@ export declare class Framer {
33
36
  private reassembleAndProcessFragment;
34
37
  frameAndSend(payload: Buffer, priority?: Priority): void;
35
38
  sendFrame(frame: Frame, priority: Priority): void;
36
- private handleLargePayload;
37
39
  private createSplitFrame;
38
40
  private queueFrame;
39
41
  sendQueue(amount: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"framer.d.ts","sourceRoot":"","sources":["../../src/client/framer.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,EAGL,QAAQ,EAWR,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,qBAAa,MAAM;IAClB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,kBAAkB,CAA0B;IACpD,OAAO,CAAC,yBAAyB,CAAmC;IACpE,OAAO,CAAC,eAAe,CAAmC;IAC1D,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAa;IAC1E,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CACvD;IAEJ,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,QAAQ,CAAC;IAClC,SAAS,CAAC,cAAc,SAAK;IAC7B,SAAS,CAAC,gBAAgB,SAAK;IAC/B,SAAS,CAAC,mBAAmB,SAAK;IAClC,SAAS,CAAC,YAAY,aAAoB;IACnC,YAAY,uBAA8B;IAC1C,UAAU,SAAK;gBAEV,MAAM,EAAE,MAAM;IAYnB,IAAI;IAiCJ,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAyE1D,OAAO,CAAC,YAAY;IA8Db,MAAM,CAAC,QAAQ,EAAE,QAAQ;IA6ChC,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,4BAA4B;IA6B7B,YAAY,CAClB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,QAA0B,GAClC,IAAI;IAQA,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAuBxD,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,gBAAgB;IAwBxB,OAAO,CAAC,UAAU;IAiBX,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAStC"}
1
+ {"version":3,"file":"framer.d.ts","sourceRoot":"","sources":["../../src/client/framer.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,EAGL,QAAQ,EAWR,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,qBAAa,MAAM;IAClB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,kBAAkB,CAA0B;IACpD,OAAO,CAAC,yBAAyB,CAAmC;IACpE,OAAO,CAAC,eAAe,CAAmC;IAC1D,SAAS,CAAC,kBAAkB,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAGrD;IACF,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CACvD;IAEJ,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,QAAQ,CAAC;IAClC,SAAS,CAAC,cAAc,SAAK;IAC7B,SAAS,CAAC,gBAAgB,SAAK;IAC/B,SAAS,CAAC,mBAAmB,SAAK;IAC3B,YAAY,EAAE,KAAK,EAAE,CAAM;IAClC,OAAO,CAAC,sBAAsB,CAAK;IAC5B,YAAY,uBAA8B;IAC1C,UAAU,SAAK;IACtB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAAK;gBAEjB,MAAM,EAAE,MAAM;IASnB,IAAI;IA2DJ,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAgF1D,OAAO,CAAC,YAAY;IAsEb,MAAM,CAAC,QAAQ,EAAE,QAAQ;IAoDhC,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,4BAA4B;IA6B7B,YAAY,CAClB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,QAA0B,GAClC,IAAI;IAQA,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAiCxD,OAAO,CAAC,gBAAgB;IAwBxB,OAAO,CAAC,UAAU;IAgBX,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CA2BtC"}
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Framer = void 0;
7
4
  const proto_1 = require("../proto");
@@ -9,7 +6,6 @@ const proto_2 = require("../proto");
9
6
  const utils_1 = require("../utils");
10
7
  const binarystream_1 = require("@serenityjs/binarystream");
11
8
  const connection_request_accepted_1 = require("../proto/packets/connection-request-accepted");
12
- const disconnect_1 = __importDefault(require("../proto/packets/disconnect"));
13
9
  class Framer {
14
10
  client;
15
11
  lastInputSequence = -1;
@@ -17,7 +13,7 @@ class Framer {
17
13
  lostFrameSequences = new Set();
18
14
  inputHighestSequenceIndex = new Array(64).fill(0);
19
15
  inputOrderIndex = new Array(64).fill(0);
20
- inputOrderingQueue = new Map();
16
+ inputOrderingQueue = Array.from({ length: 64 }, () => new Map());
21
17
  fragmentsQueue = new Map();
22
18
  outputOrderIndex;
23
19
  outputSequenceIndex;
@@ -25,56 +21,69 @@ class Framer {
25
21
  outputSequence = 0;
26
22
  outputSplitIndex = 0;
27
23
  outputReliableIndex = 0;
28
- outputFrames = new Set();
24
+ outputFrames = [];
25
+ outputFramesByteLength = 0;
29
26
  outputBackup = new Map();
30
27
  _tickCount = 0;
28
+ lastPingSent = 0;
29
+ lastPongReceived = 0;
31
30
  constructor(client) {
32
31
  this.client = client;
33
32
  this.outputFrameQueue = new proto_2.Frameset();
34
33
  this.outputFrameQueue.frames = [];
35
34
  this.outputOrderIndex = Array.from({ length: 32 }).fill(0);
36
35
  this.outputSequenceIndex = Array.from({ length: 32 }).fill(0);
37
- for (let index = 0; index < 64; index++) {
38
- this.inputOrderingQueue.set(index, new Map());
39
- }
36
+ this.lastPongReceived = Date.now();
40
37
  }
41
38
  tick() {
42
39
  this._tickCount++;
43
40
  if (this.client.status === proto_1.Status.Disconnected ||
44
- this.client.status === proto_1.Status.Disconnecting)
41
+ this.client.status === proto_1.Status.Disconnecting) {
42
+ utils_1.Logger.debug(`[Framer] Skipping tick - client status: ${proto_1.Status[this.client.status]}`);
43
+ return;
44
+ }
45
+ const now = Date.now();
46
+ if (now - this.lastPongReceived > 30000 &&
47
+ this.client.status === proto_1.Status.Connected) {
48
+ utils_1.Logger.warn("[Framer] No pong received in last 30 seconds, disconnecting");
49
+ this.client.cleanup();
45
50
  return;
46
- if (this.receivedFrameSequences.size > 0) {
51
+ }
52
+ if (this._tickCount % 50 === 0) {
53
+ this.lastPingSent = now;
54
+ const ping = new proto_1.ConnectedPing();
55
+ ping.timestamp = BigInt(now);
56
+ this.frameAndSend(ping.serialize(), proto_1.Priority.Immediate);
57
+ utils_1.Logger.debug(`[Framer] Sent ping at ${now}, last pong received: ${this.lastPongReceived}`);
58
+ }
59
+ const ackSeqs = this.receivedFrameSequences;
60
+ if (ackSeqs.size > 0) {
61
+ this.receivedFrameSequences = new Set();
62
+ utils_1.Logger.debug(`[Framer] Sending ACK for ${ackSeqs.size} sequences`);
47
63
  const ack = new proto_1.Ack();
48
- ack.sequences = Array.from(this.receivedFrameSequences).map((seq) => {
49
- this.receivedFrameSequences.delete(seq);
50
- return seq;
51
- });
64
+ ack.sequences = Array.from(ackSeqs);
52
65
  this.client.send(ack.serialize());
53
66
  }
54
- if (this.lostFrameSequences.size > 0) {
67
+ const nackSeqs = this.lostFrameSequences;
68
+ if (nackSeqs.size > 0) {
69
+ this.lostFrameSequences = new Set();
70
+ utils_1.Logger.debug(`[Framer] Sending NACK for ${nackSeqs.size} sequences`);
55
71
  const pk = new proto_1.Nack();
56
- pk.sequences = Array.from(this.lostFrameSequences).map((seq) => {
57
- this.lostFrameSequences.delete(seq);
58
- return seq;
59
- });
72
+ pk.sequences = Array.from(nackSeqs);
60
73
  this.client.send(pk.serialize());
61
74
  }
62
- if (this._tickCount % 10 === 0) {
63
- const ping = new proto_1.ConnectedPing();
64
- ping.timestamp = BigInt(Date.now());
65
- this.frameAndSend(ping.serialize(), proto_1.Priority.Normal);
66
- }
67
- this.sendQueue(this.outputFrames.size);
75
+ utils_1.Logger.debug(`[Framer] Queue state - Frames: ${this.outputFrames.length}, Backup: ${this.outputBackup.size}`);
76
+ this.sendQueue(this.outputFrames.length);
68
77
  }
69
78
  incommingMessage(payload, rinfo) {
70
79
  let header = payload.readUint8();
71
80
  if ((header & 0xf0) === 0x80)
72
81
  header = 0x80;
73
- if (this.client.options.debug)
74
- utils_1.Logger.debug(`Received packet ${header} from ${rinfo.address}:${rinfo.port}`);
82
+ utils_1.Logger.debug(`[Framer] Received packet ${header} from ${rinfo.address}:${rinfo.port}`);
75
83
  switch (header) {
76
84
  case proto_1.Packet.Ack: {
77
85
  const ack = new proto_1.Ack(payload).deserialize();
86
+ utils_1.Logger.debug(`[Framer] Processing ACK with ${ack.sequences.length} sequences`);
78
87
  for (const seq of ack.sequences) {
79
88
  this.outputBackup.delete(seq);
80
89
  }
@@ -82,12 +91,13 @@ class Framer {
82
91
  }
83
92
  case proto_1.Packet.Nack: {
84
93
  const nack = new proto_1.Nack(payload).deserialize();
94
+ utils_1.Logger.debug(`[Framer] Processing NACK with ${nack.sequences.length} sequences`);
85
95
  for (const seq of nack.sequences) {
86
96
  const lostFrames = this.outputBackup.get(seq) ?? [];
97
+ utils_1.Logger.debug(`[Framer] Resending ${lostFrames.length} lost frames for sequence ${seq}`);
87
98
  for (const lostFrame of lostFrames) {
88
99
  this.sendFrame(lostFrame, proto_1.Priority.Immediate);
89
100
  }
90
- // this.outputBackup.delete(seq);
91
101
  }
92
102
  break;
93
103
  }
@@ -133,8 +143,7 @@ class Framer {
133
143
  }
134
144
  processFrame(frame) {
135
145
  const header = frame.payload[0];
136
- if (this.client.options.debug)
137
- utils_1.Logger.debug(`Received FrameSet Packet ${header}`);
146
+ utils_1.Logger.debug(`[Framer] Processing frame with header ${header}`);
138
147
  if (this.client.status === proto_1.Status.Connecting) {
139
148
  switch (header) {
140
149
  case proto_1.Packet.ConnectionRequest: {
@@ -155,7 +164,7 @@ class Framer {
155
164
  break;
156
165
  }
157
166
  case proto_1.Packet.DisconnectionNotification: {
158
- const packet = new disconnect_1.default(frame.payload).deserialize();
167
+ utils_1.Logger.info("[Framer] Received disconnection notification while connecting");
159
168
  this.client.cleanup();
160
169
  break;
161
170
  }
@@ -172,12 +181,19 @@ class Framer {
172
181
  this.frameAndSend(pong.serialize(), proto_1.Priority.Immediate);
173
182
  break;
174
183
  }
184
+ case proto_1.Packet.ConnectedPong: {
185
+ const packet = new proto_1.ConnectedPong(frame.payload).deserialize();
186
+ this.lastPongReceived = Date.now();
187
+ utils_1.Logger.debug(`[Framer] Received pong, latency: ${Date.now() - Number(packet.pingTime)}ms`);
188
+ this.client.emit("connected-pong", packet);
189
+ break;
190
+ }
175
191
  case 0xfe: {
176
192
  this.client.emit("encapsulated", frame.payload);
177
193
  break;
178
194
  }
179
195
  case proto_1.Packet.DisconnectionNotification: {
180
- const packet = new disconnect_1.default(frame.payload).deserialize();
196
+ utils_1.Logger.info("[Framer] Received disconnection notification");
181
197
  this.client.cleanup();
182
198
  break;
183
199
  }
@@ -187,20 +203,19 @@ class Framer {
187
203
  handle(frameSet) {
188
204
  try {
189
205
  if (this.receivedFrameSequences.has(frameSet.sequence)) {
190
- if (this.client.options.debug)
191
- utils_1.Logger.debug(`Received duplicate frameset ${frameSet.sequence}`);
206
+ utils_1.Logger.debug(`[Framer] Received duplicate frameset ${frameSet.sequence}`);
192
207
  return;
193
208
  }
194
209
  this.lostFrameSequences.delete(frameSet.sequence);
195
210
  if (frameSet.sequence < this.lastInputSequence ||
196
211
  frameSet.sequence === this.lastInputSequence) {
197
- if (this.client.options.debug)
198
- utils_1.Logger.debug(`Received out of order frameset ${frameSet.sequence}!`);
212
+ utils_1.Logger.debug(`[Framer] Received out of order frameset ${frameSet.sequence}!`);
199
213
  return;
200
214
  }
201
215
  this.receivedFrameSequences.add(frameSet.sequence);
202
216
  const diff = frameSet.sequence - this.lastInputSequence;
203
217
  if (diff > 1) {
218
+ utils_1.Logger.debug(`[Framer] Detected ${diff - 1} missing sequences between ${this.lastInputSequence} and ${frameSet.sequence}`);
204
219
  for (let index = this.lastInputSequence + 1; index < frameSet.sequence; index++) {
205
220
  this.lostFrameSequences.add(index);
206
221
  }
@@ -211,15 +226,18 @@ class Framer {
211
226
  this.handleFrame(frame);
212
227
  }
213
228
  catch (err) {
214
- utils_1.Logger.error("Error handling frame", err);
229
+ utils_1.Logger.error("[Framer] Error handling frame", err);
215
230
  }
216
231
  }
217
232
  }
218
233
  catch (err) {
219
- utils_1.Logger.error("Error handling frameset", err);
234
+ utils_1.Logger.error("[Framer] Error handling frameset", err);
220
235
  }
221
236
  }
222
237
  handleFrame(frame) {
238
+ if (this.client.options.debug) {
239
+ utils_1.Logger.debug(`[Framer] Handling frame - Split: ${frame.isSplit}, Sequenced: ${frame.isSequenced}, Ordered: ${frame.isOrdered}`);
240
+ }
223
241
  if (frame.isSplit) {
224
242
  this.handleSplit(frame);
225
243
  }
@@ -241,7 +259,7 @@ class Framer {
241
259
  else if (frame.orderedFrameIndex > expectedOrderIndex) {
242
260
  if (this.client.options.debug)
243
261
  utils_1.Logger.debug(`Queuing out-of-order frame: ${frame.orderedFrameIndex}`);
244
- const unorderedQueue = this.inputOrderingQueue.get(frame.orderChannel);
262
+ const unorderedQueue = this.inputOrderingQueue[frame.orderChannel];
245
263
  if (!unorderedQueue)
246
264
  return;
247
265
  unorderedQueue.set(frame.orderedFrameIndex, frame);
@@ -255,7 +273,7 @@ class Framer {
255
273
  this.inputOrderIndex[frame.orderChannel] = frame.orderedFrameIndex + 1;
256
274
  this.inputHighestSequenceIndex[frame.orderChannel] = 0;
257
275
  this.processFrame(frame);
258
- const outOfOrderQueue = this.inputOrderingQueue.get(frame.orderChannel);
276
+ const outOfOrderQueue = this.inputOrderingQueue[frame.orderChannel];
259
277
  let nextOrderIndex = this.inputOrderIndex[frame.orderChannel];
260
278
  for (; outOfOrderQueue.has(nextOrderIndex); nextOrderIndex++) {
261
279
  const nextFrame = outOfOrderQueue.get(nextOrderIndex);
@@ -264,7 +282,6 @@ class Framer {
264
282
  outOfOrderQueue.delete(nextOrderIndex);
265
283
  }
266
284
  }
267
- this.inputOrderingQueue.set(frame.orderChannel, outOfOrderQueue);
268
285
  this.inputOrderIndex[frame.orderChannel] = nextOrderIndex;
269
286
  }
270
287
  handleSequenced(frame) {
@@ -335,7 +352,11 @@ class Framer {
335
352
  const maxSize = this.client.options.mtuSize - 36;
336
353
  const splitSize = Math.ceil(frame.payload.byteLength / maxSize);
337
354
  if (frame.payload.byteLength > maxSize) {
338
- this.handleLargePayload(frame, maxSize, splitSize);
355
+ const splitId = this.outputSplitIndex++ & 0xffff;
356
+ for (let index = 0; index < frame.payload.byteLength; index += maxSize) {
357
+ const nframe = this.createSplitFrame(frame, index, maxSize, splitId, splitSize);
358
+ this.queueFrame(nframe, proto_1.Priority.Immediate);
359
+ }
339
360
  }
340
361
  else {
341
362
  if (frame.isReliable)
@@ -343,13 +364,6 @@ class Framer {
343
364
  this.queueFrame(frame, priority);
344
365
  }
345
366
  }
346
- handleLargePayload(frame, maxSize, splitSize) {
347
- const splitId = this.outputSplitIndex++ % 65_536;
348
- for (let index = 0; index < frame.payload.byteLength; index += maxSize) {
349
- const nframe = this.createSplitFrame(frame, index, maxSize, splitId, splitSize);
350
- this.queueFrame(nframe, proto_1.Priority.Immediate);
351
- }
352
- }
353
367
  createSplitFrame(originalFrame, index, maxSize, splitId, splitSize) {
354
368
  const nframe = new proto_1.Frame();
355
369
  nframe.reliableFrameIndex = this.outputReliableIndex++;
@@ -367,27 +381,30 @@ class Framer {
367
381
  return nframe;
368
382
  }
369
383
  queueFrame(frame, priority) {
370
- let length = 4;
371
- for (const queuedFrame of this.outputFrames) {
372
- length += queuedFrame.getByteLength();
373
- }
374
- if (length + frame.getByteLength() > this.client.options.mtuSize - 36) {
375
- this.sendQueue(this.outputFrames.size);
384
+ const frameLength = frame.getByteLength();
385
+ const totalLength = 4 + this.outputFramesByteLength + frameLength;
386
+ if (totalLength > this.client.options.mtuSize - 36) {
387
+ this.sendQueue(this.outputFrames.length);
376
388
  }
377
- this.outputFrames.add(frame);
389
+ this.outputFrames.push(frame);
390
+ this.outputFramesByteLength += frameLength;
378
391
  if (priority === proto_1.Priority.Immediate) {
379
392
  this.sendQueue(1);
380
393
  }
381
394
  }
382
395
  sendQueue(amount) {
383
- if (this.outputFrames.size === 0)
396
+ if (this.outputFrames.length === 0)
384
397
  return;
398
+ utils_1.Logger.debug(`[Framer] Sending queue with ${amount} frames, total queued: ${this.outputFrames.length}`);
385
399
  const frameset = new proto_2.Frameset();
386
400
  frameset.sequence = this.outputSequence++;
387
- frameset.frames = [...this.outputFrames].slice(0, amount);
388
- this.outputBackup.set(frameset.sequence, frameset.frames);
389
- for (const frame of frameset.frames)
390
- this.outputFrames.delete(frame);
401
+ const framesToSend = this.outputFrames.slice(0, amount);
402
+ frameset.frames = framesToSend;
403
+ this.outputFrames = this.outputFrames.slice(amount);
404
+ const sentLength = framesToSend.reduce((sum, f) => sum + f.getByteLength(), 0);
405
+ this.outputFramesByteLength -= sentLength;
406
+ this.outputBackup.set(frameset.sequence, framesToSend);
407
+ utils_1.Logger.debug(`[Framer] Frameset sequence: ${frameset.sequence}, remaining in queue: ${this.outputFrames.length}`);
391
408
  this.client.send(frameset.serialize());
392
409
  }
393
410
  }
@@ -11,7 +11,7 @@ const server = new server_1.Server({
11
11
  });
12
12
  server.start();
13
13
  server.on("connect", (connection) => {
14
- utils_1.Logger.info(`Connection from ${connection.remoteInfo.address}:${connection.remoteInfo.port} established in ${connection.getConnectionTime()}ms`);
14
+ utils_1.Logger.info(`Connection from ${connection.remoteInfo.address}:${connection.remoteInfo.port} established in unknown ms`);
15
15
  connection.on("encapsulated", (packet) => {
16
16
  utils_1.Logger.info(`Received Encapsulated packet: ${packet.toString("hex")}`);
17
17
  });
@@ -1,4 +1,4 @@
1
- type LogData = string | number | boolean | null | undefined | object;
1
+ type LogData = string | number | boolean | null | undefined | object | unknown;
2
2
  declare const Logger: {
3
3
  disabled: boolean;
4
4
  debugEnabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/utils/Logger.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;AAuCrE,QAAA,MAAM,MAAM;;;kBAIG,OAAO,EAAE,GAAG,IAAI;mBAIf,OAAO,EAAE,GAAG,IAAI;kBAIjB,OAAO,EAAE,GAAG,IAAI;mBAIf,OAAO,EAAE,GAAG,IAAI;kBAKjB,OAAO,EAAE,GAAG,IAAI;YAItB,MAAM;iBAOD,OAAO,EAAE,GAAG,IAAI;kBAKf,OAAO,EAAE,GAAG,IAAI;sBAIZ,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE;CAkClD,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/utils/Logger.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAuC/E,QAAA,MAAM,MAAM;;;kBAIG,OAAO,EAAE,GAAG,IAAI;mBAIf,OAAO,EAAE,GAAG,IAAI;kBAIjB,OAAO,EAAE,GAAG,IAAI;mBAIf,OAAO,EAAE,GAAG,IAAI;kBAKjB,OAAO,EAAE,GAAG,IAAI;YAItB,MAAM;iBAOD,OAAO,EAAE,GAAG,IAAI;kBAKf,OAAO,EAAE,GAAG,IAAI;sBAIZ,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE;CAkClD,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctumterra/raknet",
3
- "version": "1.3.70",
3
+ "version": "1.3.71",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {