@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.
- package/dist/client/client-events.d.ts +2 -1
- package/dist/client/client-events.d.ts.map +1 -1
- package/dist/client/client.d.ts +2 -1
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +56 -10
- package/dist/client/framer.d.ts +3 -3
- package/dist/client/framer.d.ts.map +1 -1
- package/dist/client/framer.js +67 -63
- package/dist/tests/server.js +1 -1
- package/dist/utils/Logger.d.ts +1 -1
- package/dist/utils/Logger.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -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"}
|
package/dist/client/client.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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"}
|
package/dist/client/client.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
125
|
-
utils_1.Logger.
|
|
126
|
-
|
|
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.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.status = proto_1.Status.
|
|
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;
|
package/dist/client/framer.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare class Framer {
|
|
|
9
9
|
private lostFrameSequences;
|
|
10
10
|
private inputHighestSequenceIndex;
|
|
11
11
|
private inputOrderIndex;
|
|
12
|
-
protected inputOrderingQueue:
|
|
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
|
-
|
|
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;
|
|
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"}
|
package/dist/client/framer.js
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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
|
}
|
package/dist/tests/server.js
CHANGED
|
@@ -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
|
|
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
|
});
|
package/dist/utils/Logger.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|