@sanctumterra/raknet 1.1.10 → 1.2.0

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.
Files changed (160) hide show
  1. package/dist/client/client-evens.d.ts +21 -0
  2. package/dist/client/client-evens.d.ts.map +1 -0
  3. package/dist/client/client-options.d.ts +12 -0
  4. package/dist/client/client-options.d.ts.map +1 -0
  5. package/dist/client/client-options.js +13 -0
  6. package/dist/client/client.d.ts +22 -22
  7. package/dist/client/client.d.ts.map +1 -0
  8. package/dist/client/client.js +159 -42
  9. package/dist/client/framer.d.ts +38 -0
  10. package/dist/client/framer.d.ts.map +1 -0
  11. package/dist/client/framer.js +265 -0
  12. package/dist/client/index.d.ts +4 -0
  13. package/dist/client/index.d.ts.map +1 -0
  14. package/dist/client/index.js +19 -0
  15. package/dist/index.d.ts +4 -4
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +3 -4
  18. package/dist/proto/decorators/create.d.ts +8 -0
  19. package/dist/proto/decorators/create.d.ts.map +1 -0
  20. package/dist/proto/decorators/create.js +79 -0
  21. package/dist/proto/decorators/index.d.ts +3 -0
  22. package/dist/proto/decorators/index.d.ts.map +1 -0
  23. package/dist/proto/decorators/index.js +18 -0
  24. package/dist/proto/decorators/serialize.d.ts +4 -0
  25. package/dist/proto/decorators/serialize.d.ts.map +1 -0
  26. package/dist/proto/decorators/serialize.js +12 -0
  27. package/dist/proto/enums/flags.d.ts +7 -0
  28. package/dist/proto/enums/flags.d.ts.map +1 -0
  29. package/dist/proto/enums/flags.js +10 -0
  30. package/dist/proto/enums/index.d.ts +5 -0
  31. package/dist/proto/enums/index.d.ts.map +1 -0
  32. package/dist/proto/enums/index.js +20 -0
  33. package/dist/proto/enums/packet.d.ts +122 -0
  34. package/dist/proto/enums/packet.d.ts.map +1 -0
  35. package/dist/proto/enums/packet.js +125 -0
  36. package/dist/proto/enums/priority.d.ts +5 -0
  37. package/dist/proto/enums/priority.d.ts.map +1 -0
  38. package/dist/proto/enums/priority.js +8 -0
  39. package/dist/proto/enums/reliability.d.ts +11 -0
  40. package/dist/proto/enums/reliability.d.ts.map +1 -0
  41. package/dist/proto/enums/reliability.js +14 -0
  42. package/dist/proto/index.d.ts +5 -0
  43. package/dist/proto/index.d.ts.map +1 -0
  44. package/dist/proto/index.js +20 -0
  45. package/dist/proto/packets/ack.d.ts +10 -0
  46. package/dist/proto/packets/ack.d.ts.map +1 -0
  47. package/dist/proto/packets/ack.js +89 -0
  48. package/dist/proto/packets/base-packet.d.ts +26 -0
  49. package/dist/proto/packets/base-packet.d.ts.map +1 -0
  50. package/dist/proto/packets/base-packet.js +37 -0
  51. package/dist/proto/packets/connected-ping.d.ts +5 -0
  52. package/dist/proto/packets/connected-ping.d.ts.map +1 -0
  53. package/dist/{packets → proto/packets}/connected-ping.js +7 -4
  54. package/dist/proto/packets/connected-pong.d.ts +6 -0
  55. package/dist/proto/packets/connected-pong.d.ts.map +1 -0
  56. package/dist/{packets → proto/packets}/connected-pong.js +9 -5
  57. package/dist/proto/packets/connection-request-accepted.d.ts +10 -0
  58. package/dist/proto/packets/connection-request-accepted.d.ts.map +1 -0
  59. package/dist/{packets → proto/packets}/connection-request-accepted.js +17 -9
  60. package/dist/proto/packets/connection-request.d.ts +7 -0
  61. package/dist/proto/packets/connection-request.d.ts.map +1 -0
  62. package/dist/{packets → proto/packets}/connection-request.js +13 -8
  63. package/dist/proto/packets/frameset.d.ts +11 -0
  64. package/dist/proto/packets/frameset.d.ts.map +1 -0
  65. package/dist/{packets/open-connection-first-request.js → proto/packets/frameset.js} +21 -16
  66. package/dist/proto/packets/index.d.ts +15 -0
  67. package/dist/proto/packets/index.d.ts.map +1 -0
  68. package/dist/{packets → proto/packets}/index.js +11 -9
  69. package/dist/proto/packets/nack.d.ts +8 -0
  70. package/dist/proto/packets/nack.d.ts.map +1 -0
  71. package/dist/proto/packets/nack.js +88 -0
  72. package/dist/proto/packets/new-incoming-connection.d.ts +9 -0
  73. package/dist/proto/packets/new-incoming-connection.d.ts.map +1 -0
  74. package/dist/{packets → proto/packets}/new-incoming-connection.js +15 -12
  75. package/dist/proto/packets/open-connection-reply-one.d.ts +8 -0
  76. package/dist/proto/packets/open-connection-reply-one.d.ts.map +1 -0
  77. package/dist/proto/packets/open-connection-reply-one.js +43 -0
  78. package/dist/proto/packets/open-connection-reply-two.d.ts +10 -0
  79. package/dist/proto/packets/open-connection-reply-two.d.ts.map +1 -0
  80. package/dist/proto/packets/open-connection-reply-two.js +48 -0
  81. package/dist/proto/packets/open-connection-request-one.d.ts +7 -0
  82. package/dist/proto/packets/open-connection-request-one.d.ts.map +1 -0
  83. package/dist/{packets/open-connection-first-reply.js → proto/packets/open-connection-request-one.js} +21 -19
  84. package/dist/proto/packets/open-connection-request-two.d.ts +9 -0
  85. package/dist/proto/packets/open-connection-request-two.d.ts.map +1 -0
  86. package/dist/proto/packets/open-connection-request-two.js +43 -0
  87. package/dist/proto/packets/types/address.d.ts +48 -0
  88. package/dist/proto/packets/types/address.d.ts.map +1 -0
  89. package/dist/proto/packets/types/address.js +94 -0
  90. package/dist/proto/packets/types/data-type.d.ts +21 -0
  91. package/dist/proto/packets/types/data-type.d.ts.map +1 -0
  92. package/dist/proto/packets/types/data-type.js +29 -0
  93. package/dist/proto/packets/types/frame.d.ts +23 -0
  94. package/dist/proto/packets/types/frame.d.ts.map +1 -0
  95. package/dist/proto/packets/types/frame.js +94 -0
  96. package/dist/proto/packets/types/index.d.ts +7 -0
  97. package/dist/proto/packets/types/index.d.ts.map +1 -0
  98. package/dist/proto/packets/types/index.js +22 -0
  99. package/dist/proto/packets/types/magic.d.ts +7 -0
  100. package/dist/proto/packets/types/magic.d.ts.map +1 -0
  101. package/dist/proto/packets/types/magic.js +14 -0
  102. package/dist/proto/packets/types/mtu.d.ts +9 -0
  103. package/dist/proto/packets/types/mtu.d.ts.map +1 -0
  104. package/dist/proto/packets/types/mtu.js +18 -0
  105. package/dist/proto/packets/types/sys-address.d.ts +10 -0
  106. package/dist/proto/packets/types/sys-address.d.ts.map +1 -0
  107. package/dist/proto/packets/types/sys-address.js +27 -0
  108. package/dist/proto/packets/unconnected-ping.d.ts +7 -0
  109. package/dist/proto/packets/unconnected-ping.d.ts.map +1 -0
  110. package/dist/{packets → proto/packets}/unconnected-ping.js +15 -9
  111. package/dist/proto/packets/unconnected-pong.d.ts +8 -0
  112. package/dist/proto/packets/unconnected-pong.d.ts.map +1 -0
  113. package/dist/{packets → proto/packets}/unconnected-pong.js +17 -10
  114. package/dist/{client/types/Advertisement.d.ts → proto/types/advertisement.d.ts} +1 -0
  115. package/dist/proto/types/advertisement.d.ts.map +1 -0
  116. package/dist/{client/types/Advertisement.js → proto/types/advertisement.js} +1 -2
  117. package/dist/proto/types/index.d.ts +3 -0
  118. package/dist/proto/types/index.d.ts.map +1 -0
  119. package/dist/proto/types/index.js +18 -0
  120. package/dist/proto/types/valid.d.ts +4 -0
  121. package/dist/proto/types/valid.d.ts.map +1 -0
  122. package/dist/proto/types/valid.js +2 -0
  123. package/dist/utils/Logger.d.ts +14 -0
  124. package/dist/utils/Logger.d.ts.map +1 -0
  125. package/dist/utils/Logger.js +98 -0
  126. package/dist/utils/index.d.ts +2 -0
  127. package/dist/utils/index.d.ts.map +1 -0
  128. package/dist/{client/types → utils}/index.js +1 -1
  129. package/package.json +17 -14
  130. package/tsconfig.json +9 -23
  131. package/README.md +0 -26
  132. package/dist/client/client-events.d.ts +0 -15
  133. package/dist/client/options.d.ts +0 -16
  134. package/dist/client/options.js +0 -14
  135. package/dist/client/receiver.d.ts +0 -32
  136. package/dist/client/receiver.js +0 -291
  137. package/dist/client/sender.d.ts +0 -31
  138. package/dist/client/sender.js +0 -191
  139. package/dist/client/types/index.d.ts +0 -1
  140. package/dist/packets/connected-ping.d.ts +0 -5
  141. package/dist/packets/connected-pong.d.ts +0 -6
  142. package/dist/packets/connection-request-accepted.d.ts +0 -9
  143. package/dist/packets/connection-request.d.ts +0 -7
  144. package/dist/packets/disconnect.d.ts +0 -4
  145. package/dist/packets/disconnect.js +0 -16
  146. package/dist/packets/incompatible-protocol.d.ts +0 -7
  147. package/dist/packets/incompatible-protocol.js +0 -32
  148. package/dist/packets/index.d.ts +0 -12
  149. package/dist/packets/new-incoming-connection.d.ts +0 -8
  150. package/dist/packets/open-connection-first-reply.d.ts +0 -8
  151. package/dist/packets/open-connection-first-request.d.ts +0 -7
  152. package/dist/packets/open-connection-second-reply.d.ts +0 -9
  153. package/dist/packets/open-connection-second-reply.js +0 -40
  154. package/dist/packets/open-connection-second-request.d.ts +0 -8
  155. package/dist/packets/open-connection-second-request.js +0 -36
  156. package/dist/packets/unconnected-ping.d.ts +0 -7
  157. package/dist/packets/unconnected-pong.d.ts +0 -8
  158. package/dist/tools/test.d.ts +0 -1
  159. package/dist/tools/test.js +0 -13
  160. /package/dist/client/{client-events.js → client-evens.js} +0 -0
@@ -0,0 +1,21 @@
1
+ import type { Ack, ConnectedPing, ConnectionRequest, NewIncomingConnection, OpenConnectionReplyOne, OpenConnectionReplyTwo, OpenConnectionRequestOne, OpenConnectionRequestTwo, UnconnectedPing, UnconnectedPong } from "../proto";
2
+ import type { Frameset } from "../proto/packets/frameset";
3
+ export interface ClientEvents {
4
+ "open-connection-reply-one": [OpenConnectionReplyOne];
5
+ "open-connection-reply-two": [OpenConnectionReplyTwo];
6
+ "open-connection-request-one": [OpenConnectionRequestOne];
7
+ "open-connection-request-two": [OpenConnectionRequestTwo];
8
+ "unconnected-ping": [UnconnectedPing];
9
+ "unconnected-pong": [UnconnectedPong];
10
+ frameset: [Frameset];
11
+ "connected-ping": [ConnectedPing];
12
+ "connection-request": [ConnectionRequest];
13
+ "new-incoming-connection": [NewIncomingConnection];
14
+ encapsulated: [Buffer];
15
+ ack: [Ack];
16
+ error: [Error];
17
+ close: [];
18
+ connect: [];
19
+ tick: [];
20
+ }
21
+ //# sourceMappingURL=client-evens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-evens.d.ts","sourceRoot":"","sources":["../../src/client/client-evens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,GAAG,EACH,aAAa,EACb,iBAAiB,EACjB,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,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,EAAE,CAAC;IACZ,IAAI,EAAE,EAAE,CAAC;CACT"}
@@ -0,0 +1,12 @@
1
+ type ClientOptions = {
2
+ address: string;
3
+ port: number;
4
+ protocolVersion: number;
5
+ mtuSize: number;
6
+ clientId: bigint;
7
+ debug: boolean;
8
+ timeout: number;
9
+ };
10
+ declare const defaultClientOptions: ClientOptions;
11
+ export { type ClientOptions, defaultClientOptions };
12
+ //# sourceMappingURL=client-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-options.d.ts","sourceRoot":"","sources":["../../src/client/client-options.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,QAAA,MAAM,oBAAoB,EAAE,aAQ3B,CAAC;AAEF,OAAO,EAAE,KAAK,aAAa,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultClientOptions = void 0;
4
+ const defaultClientOptions = {
5
+ address: "127.0.0.1",
6
+ port: 19132,
7
+ protocolVersion: 11,
8
+ mtuSize: 1492,
9
+ clientId: BigInt(Math.floor(Math.random() * 1000000000000000000)),
10
+ debug: false,
11
+ timeout: 5000,
12
+ };
13
+ exports.defaultClientOptions = defaultClientOptions;
@@ -1,26 +1,26 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { type Options } from "./options";
1
+ import { Emitter } from "@serenityjs/emitter";
2
+ import type { ClientEvents } from "./client-evens";
4
3
  import { type Socket } from "node:dgram";
5
- import { Sender } from "./sender";
6
- import Emitter from "@serenityjs/emitter";
7
- import type { ClientEvents } from "./client-events";
8
- import { Receiver } from "./receiver";
9
- import type { Advertisement } from "./types/Advertisement";
10
- import { Status } from "@serenityjs/raknet";
11
- declare class Client extends Emitter<ClientEvents> {
12
- options: Options;
13
- tick: number;
4
+ import { Framer } from "./framer";
5
+ import { Address, type Advertisement, type Frame, Priority } from "../proto";
6
+ import { type ClientOptions } from "./client-options";
7
+ export declare class Client extends Emitter<ClientEvents> {
14
8
  socket: Socket;
15
- status: Status;
16
- receiver: Receiver;
17
- sender: Sender;
18
- private ticker;
19
- constructor(options?: Partial<Options>);
9
+ framer: Framer;
10
+ options: ClientOptions;
11
+ private timer;
12
+ private timeout;
13
+ serverAddress: Address;
14
+ private waitingForReplyTwo;
15
+ private waitingForReplyOne;
16
+ constructor(options?: Partial<ClientOptions>);
17
+ initSocket(): void;
18
+ ping(): Promise<Advertisement | null>;
20
19
  connect(): Promise<Advertisement>;
21
- ping(): Promise<Advertisement>;
22
- send(packet: Buffer): void;
23
- close(): void;
24
- disconnect(): void;
20
+ sendFrame(frame: Frame, priority: Priority): void;
21
+ send(buffer: Buffer): void;
22
+ private waitForReply2;
23
+ private onMessage;
24
+ private waitForReply1;
25
25
  }
26
- export { Client };
26
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +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,gBAAgB,CAAC;AACnD,OAAO,EAAmB,KAAK,MAAM,EAAe,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAO,OAAO,EAAE,KAAK,aAAa,EAAqB,KAAK,KAAK,EAA0H,QAAQ,EAAoC,MAAM,UAAU,CAAC;AAC/P,OAAO,EAAE,KAAK,aAAa,EAAwB,MAAM,kBAAkB,CAAC;AAI5E,qBACM,MAAO,SAAQ,OAAO,CAAC,YAAY,CAAC;IAC/B,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAkB;IAClC,OAAO,CAAC,OAAO,CAAkB;IACvB,aAAa,EAAG,OAAO,CAAC;IAE/B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,OAAO,GAAE,OAAO,CAAC,aAAa,CAAwB;IAK3D,UAAU;IAUJ,IAAI,IAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAgBtC,OAAO,IAAK,OAAO,CAAC,aAAa,CAAC;IA+BxC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIjD,IAAI,CAAC,MAAM,EAAE,MAAM;IAK1B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,SAAS;IAoDjB,OAAO,CAAC,aAAa;CAaxB"}
@@ -1,54 +1,171 @@
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.Client = void 0;
7
- const options_1 = require("./options");
4
+ const emitter_1 = require("@serenityjs/emitter");
8
5
  const node_dgram_1 = require("node:dgram");
9
- const sender_1 = require("./sender");
10
- const emitter_1 = __importDefault(require("@serenityjs/emitter"));
11
- const receiver_1 = require("./receiver");
12
- const raknet_1 = require("@serenityjs/raknet");
13
- const packets_1 = require("../packets");
14
- class Client extends emitter_1.default {
15
- constructor(options = {}) {
6
+ const framer_1 = require("./framer");
7
+ const proto_1 = require("../proto");
8
+ const client_options_1 = require("./client-options");
9
+ const utils_1 = require("../utils");
10
+ const frameset_1 = require("../proto/packets/frameset");
11
+ class Client extends emitter_1.Emitter {
12
+ socket;
13
+ framer;
14
+ options;
15
+ timer;
16
+ timeout;
17
+ serverAddress;
18
+ waitingForReplyTwo = false;
19
+ waitingForReplyOne = false;
20
+ constructor(options = client_options_1.defaultClientOptions) {
16
21
  super();
17
- this.tick = 0;
18
- this.status = raknet_1.Status.Disconnected;
19
- this.options = { ...options_1.defaultOptions, ...options };
20
- this.socket = options.socket ?? (0, node_dgram_1.createSocket)("udp4");
21
- this.receiver = new receiver_1.Receiver(this);
22
- this.sender = new sender_1.Sender(this);
22
+ this.options = { ...client_options_1.defaultClientOptions, ...options };
23
+ }
24
+ initSocket() {
25
+ try {
26
+ this.socket = (0, node_dgram_1.createSocket)("udp4");
27
+ this.framer = new framer_1.Framer(this);
28
+ this.socket.on("message", this.onMessage.bind(this));
29
+ }
30
+ catch (error) {
31
+ utils_1.Logger.error(`Failed to create socket: ${error}`);
32
+ }
33
+ }
34
+ async ping() {
35
+ return new Promise((resolve) => {
36
+ this.on("unconnected-pong", (packet) => {
37
+ resolve((0, proto_1.fromString)(packet.message));
38
+ });
39
+ setTimeout(() => {
40
+ resolve(null);
41
+ }, this.options.timeout);
42
+ const unconnectedPing = new proto_1.UnconnectedPing();
43
+ unconnectedPing.guid = this.options.clientId;
44
+ unconnectedPing.clientTimestamp = BigInt(Date.now());
45
+ this.send(unconnectedPing.serialize());
46
+ });
23
47
  }
24
48
  async connect() {
25
- this.ticker = setInterval(() => {
26
- this.tick++;
49
+ this.initSocket();
50
+ this.timer = setInterval(() => {
27
51
  this.emit("tick");
28
- }, 50).unref();
29
- this.tick++;
30
- this.status = raknet_1.Status.Connecting;
52
+ }, 50);
53
+ const request = new proto_1.OpenConnectionRequestOne();
54
+ request.mtu = this.options.mtuSize;
55
+ request.protocol = this.options.protocolVersion;
56
+ this.emit("open-connection-request-one", request);
31
57
  const advertisement = await this.ping();
32
- await sender_1.Sender.connect(this);
33
- return advertisement;
34
- }
35
- ping() {
36
- return sender_1.Sender.ping(this);
37
- }
38
- send(packet) {
39
- this.socket.send([packet], this.options.port, this.options.host);
40
- }
41
- close() {
42
- this.emit("close");
43
- this.socket.close();
44
- // @ts-ignore
45
- clearInterval(this.ticker);
46
- }
47
- disconnect() {
48
- const packet = new packets_1.Disconnect();
49
- this.sender.frameAndSend(packet.serialize(), raknet_1.Priority.Immediate);
50
- this.on("ack", () => {
51
- this.close();
58
+ return new Promise((resolve, reject) => {
59
+ if (this.timeout)
60
+ clearInterval(this.timeout);
61
+ this.timeout = setTimeout(() => {
62
+ this.removeAll();
63
+ this.socket.removeAllListeners();
64
+ this.socket.close();
65
+ clearInterval(this.timer);
66
+ clearInterval(this.timeout);
67
+ reject(new Error("Failed to connect, timed out."));
68
+ }, this.options.timeout);
69
+ this.once("ack", (packet) => {
70
+ if (advertisement) {
71
+ clearInterval(this.timeout);
72
+ resolve(advertisement);
73
+ }
74
+ });
75
+ this.waitForReply1();
76
+ this.send(request.serialize());
77
+ });
78
+ }
79
+ sendFrame(frame, priority) {
80
+ this.framer.sendFrame(frame, priority);
81
+ }
82
+ send(buffer) {
83
+ if (this.options.debug)
84
+ utils_1.Logger.debug(`Sending ${buffer[0]}, ${buffer.length} bytes to ${this.options.address}:${this.options.port}`);
85
+ this.socket.send(buffer, 0, buffer.length, this.options.port, this.options.address);
86
+ }
87
+ waitForReply2() {
88
+ if (this.waitingForReplyTwo)
89
+ return;
90
+ this.waitingForReplyTwo = true;
91
+ const timeout = setTimeout(() => {
92
+ this.waitingForReplyTwo = false;
93
+ if (this.options.debug)
94
+ utils_1.Logger.debug("Failed to receive OpenConnectionReplyTwo");
95
+ this.connect();
96
+ }, 500);
97
+ this.on("open-connection-reply-two", () => {
98
+ clearTimeout(timeout);
99
+ this.waitingForReplyTwo = false;
100
+ });
101
+ }
102
+ onMessage(msg, rinfo) {
103
+ try {
104
+ let packetId = msg.readUint8();
105
+ if ((msg[0] & 0xf0) === 0x80)
106
+ packetId = 0x80;
107
+ if (this.options.debug)
108
+ utils_1.Logger.debug(`Received packet ${packetId} from ${rinfo.address}:${rinfo.port}`);
109
+ switch (packetId) {
110
+ case proto_1.Packet.Ack: {
111
+ const packet = new proto_1.Ack(msg).deserialize();
112
+ // this.emit("ack", packet);
113
+ break;
114
+ }
115
+ case proto_1.Packet.UnconnectedPong: {
116
+ const packet = new proto_1.UnconnectedPong(msg).deserialize();
117
+ this.emit("unconnected-pong", packet);
118
+ break;
119
+ }
120
+ case proto_1.Packet.OpenConnectionReplyOne: {
121
+ const packet = new proto_1.OpenConnectionReplyOne(msg).deserialize();
122
+ this.emit("open-connection-reply-one", packet);
123
+ this.serverAddress = new proto_1.Address(rinfo.address, rinfo.port, rinfo.family === "IPv4" ? 4 : 6);
124
+ const request = new proto_1.OpenConnectionRequestTwo();
125
+ request.mtu = packet.mtu;
126
+ request.address = this.serverAddress;
127
+ request.clientGuid = this.options.clientId;
128
+ this.waitForReply2();
129
+ this.emit("open-connection-request-two", request);
130
+ this.send(request.serialize());
131
+ break;
132
+ }
133
+ case proto_1.Packet.OpenConnectionReplyTwo: {
134
+ const packet = new proto_1.OpenConnectionReplyTwo(msg).deserialize();
135
+ this.emit("open-connection-reply-two", packet);
136
+ const conReq = new proto_1.ConnectionRequest();
137
+ conReq.clientGuid = this.options.clientId;
138
+ conReq.timestamp = BigInt(Date.now());
139
+ conReq.useSecurity = false;
140
+ this.emit("connection-request", conReq);
141
+ this.framer.frameAndSend(conReq.serialize(), proto_1.Priority.Immediate);
142
+ break;
143
+ }
144
+ case proto_1.Packet.FrameSet: {
145
+ const frameset = new frameset_1.Frameset(msg).deserialize();
146
+ this.emit("frameset", frameset);
147
+ this.framer.handle(frameset);
148
+ break;
149
+ }
150
+ }
151
+ }
152
+ catch (error) {
153
+ utils_1.Logger.error(`Failed to handle packet: ${error}`);
154
+ }
155
+ }
156
+ waitForReply1() {
157
+ if (this.waitingForReplyOne)
158
+ return;
159
+ this.waitingForReplyOne = true;
160
+ const timeout = setTimeout(() => {
161
+ this.waitingForReplyOne = false;
162
+ if (this.options.debug)
163
+ utils_1.Logger.debug("Failed to receive OpenConnectionReplyOne");
164
+ this.connect();
165
+ }, 500);
166
+ this.once("open-connection-reply-one", () => {
167
+ clearTimeout(timeout);
168
+ this.waitingForReplyOne = false;
52
169
  });
53
170
  }
54
171
  }
@@ -0,0 +1,38 @@
1
+ import { Frame, Priority } from "../proto";
2
+ import { Frameset } from "../proto";
3
+ import type { Client } from "./client";
4
+ export declare class Framer {
5
+ private client;
6
+ private lastInputSequence;
7
+ private receivedFrameSequences;
8
+ private lostFrameSequences;
9
+ private inputHighestSequenceIndex;
10
+ private inputOrderIndex;
11
+ protected inputOrderingQueue: Map<number, Map<number, Frame>>;
12
+ protected readonly fragmentsQueue: Map<number, Map<number, Frame>>;
13
+ outputOrderIndex: number[];
14
+ outputSequenceIndex: number[];
15
+ outputFrameQueue: Frameset;
16
+ protected outputSequence: number;
17
+ protected outputSplitIndex: number;
18
+ protected outputReliableIndex: number;
19
+ protected outputFrames: Set<Frame>;
20
+ outputBackup: Map<number, Frame[]>;
21
+ constructor(client: Client);
22
+ tick(): void;
23
+ private processFrame;
24
+ handle(frameSet: Frameset): void;
25
+ private handleFrame;
26
+ private handleOrdered;
27
+ private processOrderedFrames;
28
+ private handleSequenced;
29
+ private handleSplit;
30
+ private reassembleAndProcessFragment;
31
+ frameAndSend(payload: Buffer, priority?: Priority): void;
32
+ sendFrame(frame: Frame, priority: Priority): void;
33
+ private handleLargePayload;
34
+ private createSplitFrame;
35
+ private queueFrame;
36
+ sendQueue(amount: number): void;
37
+ }
38
+ //# sourceMappingURL=framer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framer.d.ts","sourceRoot":"","sources":["../../src/client/framer.ts"],"names":[],"mappings":"AACA,OAAO,EAKN,KAAK,EAGL,QAAQ,EAER,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIvC,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,CAAa;IAExE,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;gBAErC,MAAM,EAAE,MAAM;IAcnB,IAAI;IAIX,OAAO,CAAC,YAAY;IAkCb,MAAM,CAAC,QAAQ,EAAE,QAAQ;IAsChC,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,WAAW;IAenB,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;IAsBxB,OAAO,CAAC,UAAU;IAiBX,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAStC"}
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Framer = void 0;
4
+ const proto_1 = require("../proto");
5
+ const proto_2 = require("../proto");
6
+ const utils_1 = require("../utils");
7
+ const binarystream_1 = require("@serenityjs/binarystream");
8
+ const connection_request_accepted_1 = require("../proto/packets/connection-request-accepted");
9
+ class Framer {
10
+ client;
11
+ lastInputSequence = -1;
12
+ receivedFrameSequences = new Set();
13
+ lostFrameSequences = new Set();
14
+ inputHighestSequenceIndex = new Array(64).fill(0);
15
+ inputOrderIndex = new Array(64).fill(0);
16
+ inputOrderingQueue = new Map();
17
+ fragmentsQueue = new Map();
18
+ outputOrderIndex;
19
+ outputSequenceIndex;
20
+ outputFrameQueue;
21
+ outputSequence = 0;
22
+ outputSplitIndex = 0;
23
+ outputReliableIndex = 0;
24
+ outputFrames = new Set();
25
+ outputBackup = new Map();
26
+ constructor(client) {
27
+ this.client = client;
28
+ this.outputFrameQueue = new proto_2.Frameset();
29
+ this.outputFrameQueue.frames = [];
30
+ this.outputOrderIndex = Array.from({ length: 32 }).fill(0);
31
+ this.outputSequenceIndex = Array.from({ length: 32 }).fill(0);
32
+ for (let index = 0; index < 64; index++) {
33
+ this.inputOrderingQueue.set(index, new Map());
34
+ }
35
+ this.client.on("tick", () => this.tick());
36
+ }
37
+ tick() {
38
+ this.sendQueue(this.outputFrames.size);
39
+ }
40
+ processFrame(frame) {
41
+ const header = frame.payload[0];
42
+ if (this.client.options.debug)
43
+ utils_1.Logger.debug(`Received FrameSet Packet ${header}`);
44
+ switch (header) {
45
+ case proto_1.Packet.ConnectedPing: {
46
+ const packet = new proto_1.ConnectedPing(frame.payload).deserialize();
47
+ this.client.emit("connected-ping", packet);
48
+ const pong = new proto_1.ConnectedPong();
49
+ pong.pongTime = BigInt(Date.now());
50
+ pong.pingTime = packet.timestamp;
51
+ this.frameAndSend(pong.serialize(), proto_1.Priority.Immediate);
52
+ break;
53
+ }
54
+ case proto_1.Packet.ConnectionRequestAccepted: {
55
+ const packet = new connection_request_accepted_1.ConnectionRequestAccepted(frame.payload).deserialize();
56
+ const newI = new proto_1.NewIncomingConnection();
57
+ newI.serverAddress = this.client.serverAddress;
58
+ newI.internalAddresses = packet.systemAddresses;
59
+ newI.incomingTimestamp = BigInt(Date.now());
60
+ newI.serverTimestamp = packet.timestamp;
61
+ this.client.emit("new-incoming-connection", newI);
62
+ this.frameAndSend(newI.serialize(), proto_1.Priority.Immediate);
63
+ break;
64
+ }
65
+ case 254: {
66
+ this.client.emit("encapsulated", frame.payload);
67
+ break;
68
+ }
69
+ }
70
+ }
71
+ handle(frameSet) {
72
+ if (this.receivedFrameSequences.has(frameSet.sequence)) {
73
+ if (this.client.options.debug)
74
+ utils_1.Logger.debug(`Received duplicate frameset ${frameSet.sequence}`);
75
+ return;
76
+ }
77
+ this.lostFrameSequences.delete(frameSet.sequence);
78
+ if (frameSet.sequence < this.lastInputSequence ||
79
+ frameSet.sequence === this.lastInputSequence) {
80
+ if (this.client.options.debug)
81
+ utils_1.Logger.debug(`Received out of order frameset ${frameSet.sequence}!`);
82
+ return;
83
+ }
84
+ this.receivedFrameSequences.add(frameSet.sequence);
85
+ const diff = frameSet.sequence - this.lastInputSequence;
86
+ if (diff !== 1) {
87
+ for (let index = this.lastInputSequence + 1; index < frameSet.sequence; index++) {
88
+ if (!this.receivedFrameSequences.has(index)) {
89
+ this.lostFrameSequences.add(index);
90
+ }
91
+ }
92
+ }
93
+ this.lastInputSequence = frameSet.sequence;
94
+ for (const frame of frameSet.frames) {
95
+ this.handleFrame(frame);
96
+ }
97
+ }
98
+ handleFrame(frame) {
99
+ if (frame.isSplit) {
100
+ this.handleSplit(frame);
101
+ }
102
+ else if (frame.isSequenced) {
103
+ this.handleSequenced(frame);
104
+ }
105
+ else if (frame.isOrdered) {
106
+ this.handleOrdered(frame);
107
+ }
108
+ else {
109
+ this.processFrame(frame);
110
+ }
111
+ }
112
+ handleOrdered(frame) {
113
+ const expectedOrderIndex = this.inputOrderIndex[frame.orderChannel];
114
+ const outOfOrderQueue = this.inputOrderingQueue.get(frame.orderChannel);
115
+ if (frame.orderedFrameIndex === expectedOrderIndex) {
116
+ this.processOrderedFrames(frame, outOfOrderQueue);
117
+ }
118
+ else if (frame.orderedFrameIndex > expectedOrderIndex) {
119
+ if (this.client.options.debug)
120
+ utils_1.Logger.debug(`Queuing out-of-order frame: ${frame.orderedFrameIndex}`);
121
+ outOfOrderQueue.set(frame.orderedFrameIndex, frame);
122
+ }
123
+ else {
124
+ if (this.client.options.debug)
125
+ utils_1.Logger.debug(`Discarding old frame: ${frame.orderedFrameIndex}`);
126
+ }
127
+ }
128
+ processOrderedFrames(frame, outOfOrderQueue) {
129
+ this.processFrame(frame);
130
+ this.inputOrderIndex[frame.orderChannel]++;
131
+ let nextOrderIndex = this.inputOrderIndex[frame.orderChannel];
132
+ while (outOfOrderQueue.has(nextOrderIndex)) {
133
+ const nextFrame = outOfOrderQueue.get(nextOrderIndex);
134
+ if (nextFrame) {
135
+ if (this.client.options.debug)
136
+ console.debug(`Processing queued frame: ${nextOrderIndex}`);
137
+ this.processFrame(nextFrame);
138
+ outOfOrderQueue.delete(nextOrderIndex);
139
+ this.inputOrderIndex[frame.orderChannel]++;
140
+ nextOrderIndex++;
141
+ }
142
+ }
143
+ }
144
+ handleSequenced(frame) {
145
+ const currentHighestSequence = this.inputHighestSequenceIndex[frame.orderChannel];
146
+ if (this.client.options.debug)
147
+ utils_1.Logger.debug(`Handling sequenced frame: sequenceFrameIndex=${frame.sequenceFrameIndex}, currentHighest=${currentHighestSequence}`);
148
+ if (frame.sequenceFrameIndex > currentHighestSequence) {
149
+ this.inputHighestSequenceIndex[frame.orderChannel] =
150
+ frame.sequenceFrameIndex;
151
+ this.processFrame(frame);
152
+ }
153
+ else {
154
+ if (this.client.options.debug)
155
+ utils_1.Logger.debug(`Discarding old sequenced frame: ${frame.sequenceFrameIndex}`);
156
+ }
157
+ }
158
+ handleSplit(frame) {
159
+ if (!this.fragmentsQueue.has(frame.splitId)) {
160
+ this.fragmentsQueue.set(frame.splitId, new Map());
161
+ }
162
+ const fragment = this.fragmentsQueue.get(frame.splitId);
163
+ if (!fragment)
164
+ return;
165
+ fragment.set(frame.splitFrameIndex, frame);
166
+ if (fragment.size === frame.splitCount) {
167
+ this.reassembleAndProcessFragment(frame, fragment);
168
+ }
169
+ }
170
+ reassembleAndProcessFragment(frame, fragment) {
171
+ const stream = new binarystream_1.BinaryStream();
172
+ for (let index = 0; index < fragment.size; index++) {
173
+ const sframe = fragment.get(index);
174
+ if (sframe) {
175
+ stream.writeBuffer(sframe.payload);
176
+ }
177
+ else {
178
+ utils_1.Logger.error(`Missing fragment at index ${index} for splitId=${frame.splitId}`);
179
+ return;
180
+ }
181
+ }
182
+ const reassembledFrame = new proto_1.Frame();
183
+ reassembledFrame.reliability = frame.reliability;
184
+ reassembledFrame.reliableFrameIndex = frame.reliableFrameIndex;
185
+ reassembledFrame.sequenceFrameIndex = frame.sequenceFrameIndex;
186
+ reassembledFrame.orderedFrameIndex = frame.orderedFrameIndex;
187
+ reassembledFrame.orderChannel = frame.orderChannel;
188
+ reassembledFrame.payload = stream.getBuffer();
189
+ this.fragmentsQueue.delete(frame.splitId);
190
+ this.handleFrame(reassembledFrame);
191
+ }
192
+ frameAndSend(payload, priority = proto_1.Priority.Normal) {
193
+ const frame = new proto_1.Frame();
194
+ frame.reliability = proto_1.Reliability.ReliableOrdered;
195
+ frame.orderChannel = 0;
196
+ frame.payload = payload;
197
+ this.sendFrame(frame, priority);
198
+ }
199
+ sendFrame(frame, priority) {
200
+ if (frame.isSequenced) {
201
+ frame.orderedFrameIndex = this.outputOrderIndex[frame.orderChannel];
202
+ frame.sequenceFrameIndex = this.outputSequenceIndex[frame.orderChannel]++;
203
+ }
204
+ else if (frame.isOrdered) {
205
+ frame.orderedFrameIndex = this.outputOrderIndex[frame.orderChannel]++;
206
+ this.outputSequenceIndex[frame.orderChannel] = 0;
207
+ }
208
+ const maxSize = this.client.options.mtuSize - 36;
209
+ const splitSize = Math.ceil(frame.payload.byteLength / maxSize);
210
+ if (frame.payload.byteLength > maxSize) {
211
+ this.handleLargePayload(frame, maxSize, splitSize);
212
+ }
213
+ else {
214
+ if (frame.isReliable)
215
+ frame.reliableFrameIndex = this.outputReliableIndex++;
216
+ this.queueFrame(frame, priority);
217
+ }
218
+ }
219
+ handleLargePayload(frame, maxSize, splitSize) {
220
+ const splitId = this.outputSplitIndex++ % 65_536;
221
+ for (let index = 0; index < frame.payload.byteLength; index += maxSize) {
222
+ const nframe = this.createSplitFrame(frame, index, maxSize, splitId, splitSize);
223
+ this.queueFrame(nframe, proto_1.Priority.Immediate);
224
+ }
225
+ }
226
+ createSplitFrame(originalFrame, index, maxSize, splitId, splitSize) {
227
+ const nframe = new proto_1.Frame();
228
+ nframe.reliability = originalFrame.reliability;
229
+ nframe.sequenceFrameIndex = originalFrame.sequenceFrameIndex;
230
+ nframe.orderedFrameIndex = originalFrame.orderedFrameIndex;
231
+ nframe.orderChannel = originalFrame.orderChannel;
232
+ nframe.payload = originalFrame.payload.subarray(index, index + maxSize);
233
+ nframe.splitId = splitId;
234
+ nframe.splitCount = splitSize;
235
+ if (nframe.isReliable) {
236
+ nframe.reliableFrameIndex = this.outputReliableIndex++;
237
+ }
238
+ return nframe;
239
+ }
240
+ queueFrame(frame, priority) {
241
+ let length = 4;
242
+ for (const queuedFrame of this.outputFrames) {
243
+ length += queuedFrame.getByteLength();
244
+ }
245
+ if (length + frame.getByteLength() > this.client.options.mtuSize - 36) {
246
+ this.sendQueue(this.outputFrames.size);
247
+ }
248
+ this.outputFrames.add(frame);
249
+ if (priority === proto_1.Priority.Immediate) {
250
+ this.sendQueue(1);
251
+ }
252
+ }
253
+ sendQueue(amount) {
254
+ if (this.outputFrames.size === 0)
255
+ return;
256
+ const frameset = new proto_2.Frameset();
257
+ frameset.sequence = this.outputSequence++;
258
+ frameset.frames = [...this.outputFrames].slice(0, amount);
259
+ this.outputBackup.set(frameset.sequence, frameset.frames);
260
+ for (const frame of frameset.frames)
261
+ this.outputFrames.delete(frame);
262
+ this.client.send(frameset.serialize());
263
+ }
264
+ }
265
+ exports.Framer = Framer;
@@ -0,0 +1,4 @@
1
+ export * from "./client-evens";
2
+ export * from "./client";
3
+ export * from "./client-options";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./client-evens"), exports);
18
+ __exportStar(require("./client"), exports);
19
+ __exportStar(require("./client-options"), exports);