@sanctumterra/raknet 1.3.70 → 1.3.72

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;IAOvD,IAAI,CAAC,MAAM,EAAE,MAAM;IAwBnB,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,59 @@ 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.payload = payload;
138
+ frame.orderChannel = 0;
139
+ this.sendFrame(frame, priority);
122
140
  }
123
141
  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);
142
+ if (this.status === proto_1.Status.Disconnected) {
143
+ utils_1.Logger.warn("[Client] Attempting to send packet while disconnected");
144
+ return;
145
+ }
146
+ utils_1.Logger.debug(`[Client] Sending packet ${buffer[0]}, ${buffer.length} bytes to ${this.options.address}:${this.options.port}`);
147
+ try {
148
+ this.socket.send(buffer, 0, buffer.length, this.options.port, this.options.address);
149
+ }
150
+ catch (error) {
151
+ utils_1.Logger.error("[Client] Failed to send packet", error);
152
+ // this.cleanup();
153
+ }
127
154
  }
128
155
  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;
156
+ if (this.status === proto_1.Status.Disconnected) {
157
+ return;
158
+ }
159
+ utils_1.Logger.info("[Client] Cleaning up connection and resources");
160
+ const wasConnected = this.status === proto_1.Status.Connected;
161
+ this.status = proto_1.Status.Disconnecting;
162
+ try {
163
+ // Send disconnect notification if we were connected
164
+ if (wasConnected) {
165
+ const disconnect = new disconnect_1.default();
166
+ this.send(disconnect.serialize());
167
+ }
168
+ this.removeAll();
169
+ this.socket.removeAllListeners();
170
+ this.socket.close();
171
+ clearInterval(this.timer);
172
+ clearTimeout(this.timeout);
173
+ }
174
+ catch (error) {
175
+ utils_1.Logger.error("[Client] Error during cleanup", error);
176
+ }
177
+ finally {
178
+ this.status = proto_1.Status.Disconnected;
179
+ utils_1.Logger.info("[Client] Cleanup complete, status set to Disconnected");
180
+ }
135
181
  }
136
182
  }
137
183
  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,7 +17,8 @@ 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;
23
24
  constructor(client: Client);
@@ -33,7 +34,6 @@ export declare class Framer {
33
34
  private reassembleAndProcessFragment;
34
35
  frameAndSend(payload: Buffer, priority?: Priority): void;
35
36
  sendFrame(frame: Frame, priority: Priority): void;
36
- private handleLargePayload;
37
37
  private createSplitFrame;
38
38
  private queueFrame;
39
39
  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;gBAEV,MAAM,EAAE,MAAM;IAQnB,IAAI;IA2CJ,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAgF1D,OAAO,CAAC,YAAY;IAqEb,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;IAOA,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,7 +21,8 @@ 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;
31
28
  constructor(client) {
@@ -34,47 +31,48 @@ class Framer {
34
31
  this.outputFrameQueue.frames = [];
35
32
  this.outputOrderIndex = Array.from({ length: 32 }).fill(0);
36
33
  this.outputSequenceIndex = Array.from({ length: 32 }).fill(0);
37
- for (let index = 0; index < 64; index++) {
38
- this.inputOrderingQueue.set(index, new Map());
39
- }
40
34
  }
41
35
  tick() {
42
36
  this._tickCount++;
43
37
  if (this.client.status === proto_1.Status.Disconnected ||
44
- this.client.status === proto_1.Status.Disconnecting)
38
+ this.client.status === proto_1.Status.Disconnecting) {
39
+ utils_1.Logger.debug(`[Framer] Skipping tick - client status: ${proto_1.Status[this.client.status]}`);
45
40
  return;
46
- if (this.receivedFrameSequences.size > 0) {
41
+ }
42
+ if (this._tickCount % 50 === 0) {
43
+ const now = Date.now();
44
+ const ping = new proto_1.ConnectedPing();
45
+ ping.timestamp = BigInt(now);
46
+ this.frameAndSend(ping.serialize(), proto_1.Priority.Immediate);
47
+ }
48
+ const ackSeqs = this.receivedFrameSequences;
49
+ if (ackSeqs.size > 0) {
50
+ this.receivedFrameSequences = new Set();
51
+ utils_1.Logger.debug(`[Framer] Sending ACK for ${ackSeqs.size} sequences`);
47
52
  const ack = new proto_1.Ack();
48
- ack.sequences = Array.from(this.receivedFrameSequences).map((seq) => {
49
- this.receivedFrameSequences.delete(seq);
50
- return seq;
51
- });
53
+ ack.sequences = Array.from(ackSeqs);
52
54
  this.client.send(ack.serialize());
53
55
  }
54
- if (this.lostFrameSequences.size > 0) {
56
+ const nackSeqs = this.lostFrameSequences;
57
+ if (nackSeqs.size > 0) {
58
+ this.lostFrameSequences = new Set();
59
+ utils_1.Logger.debug(`[Framer] Sending NACK for ${nackSeqs.size} sequences`);
55
60
  const pk = new proto_1.Nack();
56
- pk.sequences = Array.from(this.lostFrameSequences).map((seq) => {
57
- this.lostFrameSequences.delete(seq);
58
- return seq;
59
- });
61
+ pk.sequences = Array.from(nackSeqs);
60
62
  this.client.send(pk.serialize());
61
63
  }
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);
64
+ utils_1.Logger.debug(`[Framer] Queue state - Frames: ${this.outputFrames.length}, Backup: ${this.outputBackup.size}`);
65
+ this.sendQueue(this.outputFrames.length);
68
66
  }
69
67
  incommingMessage(payload, rinfo) {
70
68
  let header = payload.readUint8();
71
69
  if ((header & 0xf0) === 0x80)
72
70
  header = 0x80;
73
- if (this.client.options.debug)
74
- utils_1.Logger.debug(`Received packet ${header} from ${rinfo.address}:${rinfo.port}`);
71
+ utils_1.Logger.debug(`[Framer] Received packet ${header} from ${rinfo.address}:${rinfo.port}`);
75
72
  switch (header) {
76
73
  case proto_1.Packet.Ack: {
77
74
  const ack = new proto_1.Ack(payload).deserialize();
75
+ utils_1.Logger.debug(`[Framer] Processing ACK with ${ack.sequences.length} sequences`);
78
76
  for (const seq of ack.sequences) {
79
77
  this.outputBackup.delete(seq);
80
78
  }
@@ -82,12 +80,13 @@ class Framer {
82
80
  }
83
81
  case proto_1.Packet.Nack: {
84
82
  const nack = new proto_1.Nack(payload).deserialize();
83
+ utils_1.Logger.debug(`[Framer] Processing NACK with ${nack.sequences.length} sequences`);
85
84
  for (const seq of nack.sequences) {
86
85
  const lostFrames = this.outputBackup.get(seq) ?? [];
86
+ utils_1.Logger.debug(`[Framer] Resending ${lostFrames.length} lost frames for sequence ${seq}`);
87
87
  for (const lostFrame of lostFrames) {
88
88
  this.sendFrame(lostFrame, proto_1.Priority.Immediate);
89
89
  }
90
- // this.outputBackup.delete(seq);
91
90
  }
92
91
  break;
93
92
  }
@@ -133,8 +132,7 @@ class Framer {
133
132
  }
134
133
  processFrame(frame) {
135
134
  const header = frame.payload[0];
136
- if (this.client.options.debug)
137
- utils_1.Logger.debug(`Received FrameSet Packet ${header}`);
135
+ utils_1.Logger.debug(`[Framer] Processing frame with header ${header}`);
138
136
  if (this.client.status === proto_1.Status.Connecting) {
139
137
  switch (header) {
140
138
  case proto_1.Packet.ConnectionRequest: {
@@ -155,7 +153,7 @@ class Framer {
155
153
  break;
156
154
  }
157
155
  case proto_1.Packet.DisconnectionNotification: {
158
- const packet = new disconnect_1.default(frame.payload).deserialize();
156
+ utils_1.Logger.info("[Framer] Received disconnection notification while connecting");
159
157
  this.client.cleanup();
160
158
  break;
161
159
  }
@@ -172,12 +170,18 @@ class Framer {
172
170
  this.frameAndSend(pong.serialize(), proto_1.Priority.Immediate);
173
171
  break;
174
172
  }
173
+ case proto_1.Packet.ConnectedPong: {
174
+ const packet = new proto_1.ConnectedPong(frame.payload).deserialize();
175
+ utils_1.Logger.debug(`[Framer] Received pong, latency: ${Date.now() - Number(packet.pingTime)}ms`);
176
+ this.client.emit("connected-pong", packet);
177
+ break;
178
+ }
175
179
  case 0xfe: {
176
180
  this.client.emit("encapsulated", frame.payload);
177
181
  break;
178
182
  }
179
183
  case proto_1.Packet.DisconnectionNotification: {
180
- const packet = new disconnect_1.default(frame.payload).deserialize();
184
+ utils_1.Logger.info("[Framer] Received disconnection notification");
181
185
  this.client.cleanup();
182
186
  break;
183
187
  }
@@ -187,20 +191,19 @@ class Framer {
187
191
  handle(frameSet) {
188
192
  try {
189
193
  if (this.receivedFrameSequences.has(frameSet.sequence)) {
190
- if (this.client.options.debug)
191
- utils_1.Logger.debug(`Received duplicate frameset ${frameSet.sequence}`);
194
+ utils_1.Logger.debug(`[Framer] Received duplicate frameset ${frameSet.sequence}`);
192
195
  return;
193
196
  }
194
197
  this.lostFrameSequences.delete(frameSet.sequence);
195
198
  if (frameSet.sequence < this.lastInputSequence ||
196
199
  frameSet.sequence === this.lastInputSequence) {
197
- if (this.client.options.debug)
198
- utils_1.Logger.debug(`Received out of order frameset ${frameSet.sequence}!`);
200
+ utils_1.Logger.debug(`[Framer] Received out of order frameset ${frameSet.sequence}!`);
199
201
  return;
200
202
  }
201
203
  this.receivedFrameSequences.add(frameSet.sequence);
202
204
  const diff = frameSet.sequence - this.lastInputSequence;
203
205
  if (diff > 1) {
206
+ utils_1.Logger.debug(`[Framer] Detected ${diff - 1} missing sequences between ${this.lastInputSequence} and ${frameSet.sequence}`);
204
207
  for (let index = this.lastInputSequence + 1; index < frameSet.sequence; index++) {
205
208
  this.lostFrameSequences.add(index);
206
209
  }
@@ -211,15 +214,18 @@ class Framer {
211
214
  this.handleFrame(frame);
212
215
  }
213
216
  catch (err) {
214
- utils_1.Logger.error("Error handling frame", err);
217
+ utils_1.Logger.error("[Framer] Error handling frame", err);
215
218
  }
216
219
  }
217
220
  }
218
221
  catch (err) {
219
- utils_1.Logger.error("Error handling frameset", err);
222
+ utils_1.Logger.error("[Framer] Error handling frameset", err);
220
223
  }
221
224
  }
222
225
  handleFrame(frame) {
226
+ if (this.client.options.debug) {
227
+ utils_1.Logger.debug(`[Framer] Handling frame - Split: ${frame.isSplit}, Sequenced: ${frame.isSequenced}, Ordered: ${frame.isOrdered}`);
228
+ }
223
229
  if (frame.isSplit) {
224
230
  this.handleSplit(frame);
225
231
  }
@@ -241,7 +247,7 @@ class Framer {
241
247
  else if (frame.orderedFrameIndex > expectedOrderIndex) {
242
248
  if (this.client.options.debug)
243
249
  utils_1.Logger.debug(`Queuing out-of-order frame: ${frame.orderedFrameIndex}`);
244
- const unorderedQueue = this.inputOrderingQueue.get(frame.orderChannel);
250
+ const unorderedQueue = this.inputOrderingQueue[frame.orderChannel];
245
251
  if (!unorderedQueue)
246
252
  return;
247
253
  unorderedQueue.set(frame.orderedFrameIndex, frame);
@@ -255,7 +261,7 @@ class Framer {
255
261
  this.inputOrderIndex[frame.orderChannel] = frame.orderedFrameIndex + 1;
256
262
  this.inputHighestSequenceIndex[frame.orderChannel] = 0;
257
263
  this.processFrame(frame);
258
- const outOfOrderQueue = this.inputOrderingQueue.get(frame.orderChannel);
264
+ const outOfOrderQueue = this.inputOrderingQueue[frame.orderChannel];
259
265
  let nextOrderIndex = this.inputOrderIndex[frame.orderChannel];
260
266
  for (; outOfOrderQueue.has(nextOrderIndex); nextOrderIndex++) {
261
267
  const nextFrame = outOfOrderQueue.get(nextOrderIndex);
@@ -264,7 +270,6 @@ class Framer {
264
270
  outOfOrderQueue.delete(nextOrderIndex);
265
271
  }
266
272
  }
267
- this.inputOrderingQueue.set(frame.orderChannel, outOfOrderQueue);
268
273
  this.inputOrderIndex[frame.orderChannel] = nextOrderIndex;
269
274
  }
270
275
  handleSequenced(frame) {
@@ -318,7 +323,6 @@ class Framer {
318
323
  }
319
324
  frameAndSend(payload, priority = proto_1.Priority.Normal) {
320
325
  const frame = new proto_1.Frame();
321
- frame.reliability = proto_1.Reliability.ReliableOrdered;
322
326
  frame.orderChannel = 0;
323
327
  frame.payload = payload;
324
328
  this.sendFrame(frame, priority);
@@ -335,7 +339,11 @@ class Framer {
335
339
  const maxSize = this.client.options.mtuSize - 36;
336
340
  const splitSize = Math.ceil(frame.payload.byteLength / maxSize);
337
341
  if (frame.payload.byteLength > maxSize) {
338
- this.handleLargePayload(frame, maxSize, splitSize);
342
+ const splitId = this.outputSplitIndex++ & 0xffff;
343
+ for (let index = 0; index < frame.payload.byteLength; index += maxSize) {
344
+ const nframe = this.createSplitFrame(frame, index, maxSize, splitId, splitSize);
345
+ this.queueFrame(nframe, proto_1.Priority.Immediate);
346
+ }
339
347
  }
340
348
  else {
341
349
  if (frame.isReliable)
@@ -343,13 +351,6 @@ class Framer {
343
351
  this.queueFrame(frame, priority);
344
352
  }
345
353
  }
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
354
  createSplitFrame(originalFrame, index, maxSize, splitId, splitSize) {
354
355
  const nframe = new proto_1.Frame();
355
356
  nframe.reliableFrameIndex = this.outputReliableIndex++;
@@ -367,27 +368,30 @@ class Framer {
367
368
  return nframe;
368
369
  }
369
370
  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);
371
+ const frameLength = frame.getByteLength();
372
+ const totalLength = 4 + this.outputFramesByteLength + frameLength;
373
+ if (totalLength > this.client.options.mtuSize - 36) {
374
+ this.sendQueue(this.outputFrames.length);
376
375
  }
377
- this.outputFrames.add(frame);
376
+ this.outputFrames.push(frame);
377
+ this.outputFramesByteLength += frameLength;
378
378
  if (priority === proto_1.Priority.Immediate) {
379
379
  this.sendQueue(1);
380
380
  }
381
381
  }
382
382
  sendQueue(amount) {
383
- if (this.outputFrames.size === 0)
383
+ if (this.outputFrames.length === 0)
384
384
  return;
385
+ utils_1.Logger.debug(`[Framer] Sending queue with ${amount} frames, total queued: ${this.outputFrames.length}`);
385
386
  const frameset = new proto_2.Frameset();
386
387
  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);
388
+ const framesToSend = this.outputFrames.slice(0, amount);
389
+ frameset.frames = framesToSend;
390
+ this.outputFrames = this.outputFrames.slice(amount);
391
+ const sentLength = framesToSend.reduce((sum, f) => sum + f.getByteLength(), 0);
392
+ this.outputFramesByteLength -= sentLength;
393
+ this.outputBackup.set(frameset.sequence, framesToSend);
394
+ utils_1.Logger.debug(`[Framer] Frameset sequence: ${frameset.sequence}, remaining in queue: ${this.outputFrames.length}`);
391
395
  this.client.send(frameset.serialize());
392
396
  }
393
397
  }
@@ -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.72",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {