@sanctumterra/raknet 1.0.8 → 1.0.10

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.
@@ -0,0 +1,11 @@
1
+ {
2
+ "files.exclude": {
3
+ "**/.git": true,
4
+ "**/.svn": true,
5
+ "**/.hg": true,
6
+ "**/CVS": true,
7
+ "**/.DS_Store": true,
8
+ "**/Thumbs.db": true
9
+ },
10
+ "hide-files.files": []
11
+ }
package/bun.lockb ADDED
Binary file
@@ -0,0 +1,11 @@
1
+ {
2
+ "files.exclude": {
3
+ "**/.git": true,
4
+ "**/.svn": true,
5
+ "**/.hg": true,
6
+ "**/CVS": true,
7
+ "**/.DS_Store": true,
8
+ "**/Thumbs.db": true
9
+ },
10
+ "hide-files.files": []
11
+ }
@@ -1,23 +1,13 @@
1
+ import { Frame } from "@serenityjs/raknet";
1
2
  import { RakNetClient } from "./RaknetClient";
2
- export declare class Queue<T> {
3
- private elements;
4
- enqueue(element: T): void;
5
- dequeue(): T | undefined;
6
- peek(): T | undefined;
7
- isEmpty(): boolean;
8
- size(): number;
9
- }
10
3
  export declare class FrameHandler {
11
- private fragmentedPackets;
12
- private reliablePackets;
13
- private orderedPackets;
14
- private highestSequence;
15
4
  private lastInputSequence;
16
5
  private receivedFrameSequences;
17
6
  private lostFrameSequences;
18
7
  private inputHighestSequenceIndex;
19
8
  private inputOrderIndex;
20
- private frameQueue;
9
+ protected inputOrderingQueue: Map<number, Map<number, Frame>>;
10
+ protected readonly fragmentsQueue: Map<number, Map<number, Frame>>;
21
11
  private raknet;
22
12
  constructor(raknet: RakNetClient);
23
13
  tick(): void;
@@ -25,12 +15,9 @@ export declare class FrameHandler {
25
15
  handleFrameSet(buffer: Buffer): void;
26
16
  private handleFrame;
27
17
  private processFrame;
28
- private processQueuedFrames;
29
- private handleFragmentedFrame;
30
- private handleSequencedFrame;
31
- private handleOrderedFrame;
32
- private handleReliableFrame;
33
- private processReliableFrames;
18
+ private handleFragment;
19
+ private handleSequenced;
20
+ private handleOrdered;
34
21
  private handleConnectedPing;
35
22
  private handleConnectionRequestAccepted;
36
23
  }
@@ -2,65 +2,33 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: all[name]
9
- });
10
- }
11
- _export(exports, {
12
- FrameHandler: function() {
5
+ Object.defineProperty(exports, "FrameHandler", {
6
+ enumerable: true,
7
+ get: function() {
13
8
  return FrameHandler;
14
- },
15
- Queue: function() {
16
- return Queue;
17
9
  }
18
10
  });
19
11
  const _raknet = require("@serenityjs/raknet");
20
12
  const _OhMyNewIncommingConnection = require("../packets/raknet/OhMyNewIncommingConnection");
21
13
  const _binarystream = require("@serenityjs/binarystream");
22
14
  const _Logger = require("../utils/Logger");
23
- class Queue {
24
- enqueue(element) {
25
- this.elements.push(element);
26
- }
27
- dequeue() {
28
- return this.elements.shift();
29
- }
30
- peek() {
31
- return this.elements[0];
32
- }
33
- isEmpty() {
34
- return this.elements.length === 0;
35
- }
36
- size() {
37
- return this.elements.length;
38
- }
39
- constructor(){
40
- this.elements = [];
41
- }
42
- }
43
15
  class FrameHandler {
44
16
  tick() {
45
17
  if (this.receivedFrameSequences.size > 0) {
46
18
  const ack = new _raknet.Ack();
47
19
  ack.sequences = [
48
20
  ...this.receivedFrameSequences
49
- ].map((x)=>{
50
- this.receivedFrameSequences.delete(x);
51
- return x;
52
- });
21
+ ];
22
+ for (const sequence of this.receivedFrameSequences)this.receivedFrameSequences.delete(sequence);
53
23
  this.send(ack.serialize());
54
24
  }
55
25
  if (this.lostFrameSequences.size > 0) {
56
- const pk = new _raknet.Nack();
57
- pk.sequences = [
26
+ const nack = new _raknet.Nack();
27
+ nack.sequences = [
58
28
  ...this.lostFrameSequences
59
- ].map((x)=>{
60
- this.lostFrameSequences.delete(x);
61
- return x;
62
- });
63
- this.send(pk.serialize());
29
+ ];
30
+ for (const sequence of this.lostFrameSequences)this.lostFrameSequences.delete(sequence);
31
+ this.send(nack.serialize());
64
32
  }
65
33
  }
66
34
  send(buffer) {
@@ -68,9 +36,12 @@ class FrameHandler {
68
36
  }
69
37
  handleFrameSet(buffer) {
70
38
  const frameSet = new _raknet.FrameSet(buffer).deserialize();
71
- if (frameSet.sequence <= this.highestSequence) {
72
- _Logger.Logger.debug(`Ignoring old or duplicate FrameSet: ${frameSet.sequence}`);
73
- return;
39
+ if (this.receivedFrameSequences.has(frameSet.sequence)) {
40
+ return _Logger.Logger.debug(`Received duplicate frameset ${frameSet.sequence}`);
41
+ }
42
+ this.lostFrameSequences.delete(frameSet.sequence);
43
+ if (frameSet.sequence < this.lastInputSequence || frameSet.sequence === this.lastInputSequence) {
44
+ _Logger.Logger.debug(`Received out of order frameset ${frameSet.sequence}!`);
74
45
  }
75
46
  this.receivedFrameSequences.add(frameSet.sequence);
76
47
  const diff = frameSet.sequence - this.lastInputSequence;
@@ -82,24 +53,16 @@ class FrameHandler {
82
53
  }
83
54
  }
84
55
  this.lastInputSequence = frameSet.sequence;
85
- this.highestSequence = frameSet.sequence;
56
+ this.lastInputSequence = frameSet.sequence;
86
57
  for (const frame of frameSet.frames){
87
- this.frameQueue.enqueue(frame);
58
+ this.handleFrame(frame);
88
59
  }
89
- this.processQueuedFrames();
90
60
  }
91
61
  handleFrame(frame) {
92
- if (frame.isFragmented()) {
93
- this.handleFragmentedFrame(frame);
94
- } else if (frame.isSequenced()) {
95
- this.handleSequencedFrame(frame);
96
- } else if (frame.isOrdered()) {
97
- this.handleOrderedFrame(frame);
98
- } else if (frame.isReliable()) {
99
- this.handleReliableFrame(frame);
100
- } else {
101
- this.processFrame(frame);
102
- }
62
+ if (frame.isSplit()) return this.handleFragment(frame);
63
+ else if (frame.isSequenced()) return this.handleSequenced(frame);
64
+ else if (frame.isOrdered()) this.handleOrdered(frame);
65
+ else this.processFrame(frame);
103
66
  }
104
67
  processFrame(frame) {
105
68
  const header = frame.payload[0];
@@ -115,78 +78,64 @@ class FrameHandler {
115
78
  break;
116
79
  }
117
80
  }
118
- processQueuedFrames() {
119
- while(!this.frameQueue.isEmpty()){
120
- const frame = this.frameQueue.dequeue();
121
- if (frame) {
122
- try {
123
- this.handleFrame(frame);
124
- } catch (error) {
125
- _Logger.Logger.error(`Error processing frame: ${error}`);
81
+ handleFragment(frame) {
82
+ if (this.fragmentsQueue.has(frame.splitId)) {
83
+ const fragment = this.fragmentsQueue.get(frame.splitId);
84
+ if (!fragment) return;
85
+ fragment.set(frame.splitIndex, frame);
86
+ if (fragment.size === frame.splitSize) {
87
+ const stream = new _binarystream.BinaryStream();
88
+ for(let index = 0; index < fragment.size; index++){
89
+ const sframe = fragment.get(index);
90
+ stream.writeBuffer(sframe.payload);
126
91
  }
92
+ const nframe = new _raknet.Frame();
93
+ nframe.reliability = frame.reliability;
94
+ nframe.reliableIndex = frame.reliableIndex;
95
+ nframe.sequenceIndex = frame.sequenceIndex;
96
+ nframe.orderIndex = frame.orderIndex;
97
+ nframe.orderChannel = frame.orderChannel;
98
+ nframe.payload = stream.getBuffer();
99
+ this.fragmentsQueue.delete(frame.splitId);
100
+ return this.handleFrame(nframe);
127
101
  }
102
+ } else {
103
+ this.fragmentsQueue.set(frame.splitId, new Map([
104
+ [
105
+ frame.splitIndex,
106
+ frame
107
+ ]
108
+ ]));
128
109
  }
129
110
  }
130
- handleFragmentedFrame(frame) {
131
- if (!this.fragmentedPackets.has(frame.fragmentId)) {
132
- this.fragmentedPackets.set(frame.fragmentId, new Map());
133
- }
134
- const fragments = this.fragmentedPackets.get(frame.fragmentId);
135
- fragments.set(frame.fragmentIndex, frame);
136
- if (fragments.size === frame.fragmentSize) {
137
- const stream = new _binarystream.BinaryStream();
138
- for(let index = 0; index < fragments.size; index++){
139
- const fragment = fragments.get(index);
140
- stream.writeBuffer(fragment.payload);
141
- }
142
- const reassembledFrame = new _raknet.Frame();
143
- Object.assign(reassembledFrame, frame);
144
- reassembledFrame.payload = stream.getBuffer();
145
- reassembledFrame.fragmentSize = 0;
146
- this.fragmentedPackets.delete(frame.fragmentId);
147
- this.handleFrame(reassembledFrame);
148
- }
149
- }
150
- handleSequencedFrame(frame) {
111
+ handleSequenced(frame) {
151
112
  if (frame.sequenceIndex < this.inputHighestSequenceIndex[frame.orderChannel] || frame.orderIndex < this.inputOrderIndex[frame.orderChannel]) {
152
- return _Logger.Logger.debug(`Received out of order frame ${frame.sequenceIndex}`);
113
+ return _Logger.Logger.debug(`Recieved out of order frame ${frame.sequenceIndex}!`);
153
114
  }
154
115
  this.inputHighestSequenceIndex[frame.orderChannel] = frame.sequenceIndex + 1;
155
- this.processFrame(frame);
116
+ return this.processFrame(frame);
156
117
  }
157
- handleOrderedFrame(frame) {
118
+ handleOrdered(frame) {
158
119
  if (frame.orderIndex === this.inputOrderIndex[frame.orderChannel]) {
159
120
  this.inputHighestSequenceIndex[frame.orderChannel] = 0;
160
121
  this.inputOrderIndex[frame.orderChannel] = frame.orderIndex + 1;
161
122
  this.processFrame(frame);
162
123
  let index = this.inputOrderIndex[frame.orderChannel];
163
- const outOfOrderQueue = this.orderedPackets.get(frame.orderChannel) || new Map();
164
- while(outOfOrderQueue.has(index)){
165
- const nextFrame = outOfOrderQueue.get(index);
166
- this.processFrame(nextFrame);
124
+ const outOfOrderQueue = this.inputOrderingQueue.get(frame.orderChannel);
125
+ for(; outOfOrderQueue.has(index); index++){
126
+ const frame = outOfOrderQueue.get(index);
127
+ if (!frame) break;
128
+ this.processFrame(frame);
167
129
  outOfOrderQueue.delete(index);
168
- index++;
169
130
  }
170
- this.orderedPackets.set(frame.orderChannel, outOfOrderQueue);
131
+ this.inputOrderingQueue.set(frame.orderChannel, outOfOrderQueue);
171
132
  this.inputOrderIndex[frame.orderChannel] = index;
172
133
  } else if (frame.orderIndex > this.inputOrderIndex[frame.orderChannel]) {
173
- const outOfOrderQueue = this.orderedPackets.get(frame.orderChannel) || new Map();
174
- outOfOrderQueue.set(frame.orderIndex, frame);
175
- this.orderedPackets.set(frame.orderChannel, outOfOrderQueue);
176
- }
177
- }
178
- handleReliableFrame(frame) {
179
- if (frame.reliableIndex > (this.reliablePackets.size > 0 ? Math.max(...this.reliablePackets.keys()) : -1)) {
180
- this.reliablePackets.set(frame.reliableIndex, frame);
181
- this.processReliableFrames();
182
- }
183
- }
184
- processReliableFrames() {
185
- const sortedReliableIndexes = Array.from(this.reliablePackets.keys()).sort((a, b)=>a - b);
186
- for (const index of sortedReliableIndexes){
187
- const frame = this.reliablePackets.get(index);
188
- this.processFrame(frame);
189
- this.reliablePackets.delete(index);
134
+ const unordered = this.inputOrderingQueue.get(frame.orderChannel);
135
+ if (!unordered) return;
136
+ unordered.set(frame.orderIndex, frame);
137
+ } else {
138
+ return this.processFrame(frame);
190
139
  }
191
140
  }
192
141
  handleConnectedPing(buffer) {
@@ -229,17 +178,17 @@ class FrameHandler {
229
178
  void this.raknet.emit("connect", {});
230
179
  }
231
180
  constructor(raknet){
232
- this.fragmentedPackets = new Map();
233
- this.reliablePackets = new Map();
234
- this.orderedPackets = new Map();
235
- this.highestSequence = -1;
236
181
  this.lastInputSequence = -1;
237
182
  this.receivedFrameSequences = new Set();
238
183
  this.lostFrameSequences = new Set();
239
184
  this.inputHighestSequenceIndex = new Array(32).fill(0);
240
185
  this.inputOrderIndex = new Array(32).fill(0);
241
- this.frameQueue = new Queue();
186
+ this.inputOrderingQueue = new Map();
187
+ this.fragmentsQueue = new Map();
242
188
  this.raknet = raknet;
189
+ for(let index = 0; index < 32; index++){
190
+ this.inputOrderingQueue.set(index, new Map());
191
+ }
243
192
  this.raknet.on("tick", ()=>{
244
193
  this.tick();
245
194
  });
@@ -1,16 +1,19 @@
1
1
  import { Frame, FrameSet, Priority } from '@serenityjs/raknet';
2
2
  import { RakNetClient } from './RaknetClient';
3
3
  export declare class Queue {
4
- private client;
5
4
  outputBackupQueue: Map<number, Frame[]>;
6
5
  outputOrderIndex: Array<number>;
7
6
  outputSequenceIndex: Array<number>;
8
7
  outputFrameQueue: FrameSet;
9
- outputSequence: number;
10
- outputReliableIndex: number;
11
- outputFragmentIndex: number;
12
8
  mtu: number;
9
+ protected outputSequence: number;
10
+ protected outputsplitIndex: number;
11
+ protected outputReliableIndex: number;
12
+ protected outputFrames: Set<Frame>;
13
+ protected outputBackup: Map<number, Frame[]>;
14
+ protected client: RakNetClient;
13
15
  constructor(client: RakNetClient);
16
+ onTick(): void;
14
17
  /**
15
18
  * Sends a frame to the connection.
16
19
  *
@@ -18,14 +21,6 @@ export declare class Queue {
18
21
  * @param priority - The priority of the frame
19
22
  */
20
23
  sendFrame(frame: Frame, priority: Priority): void;
21
- private addFrameToQueue;
22
- /**
23
- * Sends the output frame queue
24
- */
25
- sendFrameQueue(): void;
26
- /**
27
- * Sends a frame set to the connection
28
- * @param frameset The frame set
29
- */
30
- private sendFrameSet;
24
+ private queueFrame;
25
+ sendQueue(amount: number): void;
31
26
  }
@@ -10,6 +10,10 @@ Object.defineProperty(exports, "Queue", {
10
10
  });
11
11
  const _raknet = require("@serenityjs/raknet");
12
12
  class Queue {
13
+ onTick() {
14
+ if (this.client.status === _raknet.Status.Disconnecting || this.client.status === _raknet.Status.Disconnected) return;
15
+ return this.sendQueue(this.outputFrames.size);
16
+ }
13
17
  /**
14
18
  * Sends a frame to the connection.
15
19
  *
@@ -19,64 +23,59 @@ class Queue {
19
23
  if (frame.isSequenced()) {
20
24
  frame.orderIndex = this.outputOrderIndex[frame.orderChannel];
21
25
  frame.sequenceIndex = this.outputSequenceIndex[frame.orderChannel]++;
22
- } else if (frame.isOrderExclusive()) {
26
+ } else if (frame.isOrdered()) {
23
27
  frame.orderIndex = this.outputOrderIndex[frame.orderChannel]++;
24
28
  this.outputSequenceIndex[frame.orderChannel] = 0;
25
29
  }
26
- frame.reliableIndex = this.outputReliableIndex++;
27
- const maxSize = this.mtu - 6 - 23;
30
+ const maxSize = this.mtu - 36;
31
+ const splitSize = Math.ceil(frame.payload.byteLength / maxSize);
28
32
  if (frame.payload.byteLength > maxSize) {
29
- const buffer = Buffer.from(frame.payload);
30
- const fragmentId = this.outputFragmentIndex++ % 65_536;
31
- for(let index = 0; index < buffer.byteLength; index += maxSize){
32
- if (index !== 0) frame.reliableIndex = this.outputReliableIndex++;
33
- frame.payload = buffer.subarray(index, index + maxSize);
34
- frame.fragmentIndex = index / maxSize;
35
- frame.fragmentId = fragmentId;
36
- frame.fragmentSize = Math.ceil(buffer.byteLength / maxSize);
37
- this.addFrameToQueue(frame, priority || _raknet.Priority.Normal);
33
+ const splitId = this.outputsplitIndex++ % 65_536;
34
+ for(let index = 0; index < frame.payload.byteLength; index += maxSize){
35
+ const nframe = new _raknet.Frame();
36
+ if (frame.isReliable()) nframe.reliableIndex = this.outputReliableIndex++;
37
+ nframe.sequenceIndex = frame.sequenceIndex;
38
+ nframe.orderIndex = frame.orderIndex;
39
+ nframe.orderChannel = frame.orderChannel;
40
+ nframe.reliability = frame.reliability;
41
+ nframe.payload = frame.payload.subarray(index, index + maxSize);
42
+ nframe.splitIndex = index / maxSize;
43
+ nframe.splitId = splitId;
44
+ nframe.splitSize = splitSize;
45
+ this.queueFrame(nframe, priority);
38
46
  }
39
47
  } else {
40
- this.addFrameToQueue(frame, priority);
41
- }
42
- }
43
- addFrameToQueue(frame, priority) {
44
- let length = 4;
45
- for (const queuedFrame of this.outputFrameQueue.frames){
46
- length += queuedFrame.getByteLength();
47
- }
48
- if (length + frame.getByteLength() > this.mtu - 36) {
49
- this.sendFrameQueue();
50
- }
51
- this.outputFrameQueue.frames.push(frame);
52
- if (priority === _raknet.Priority.Immediate) {
53
- this.sendFrameQueue();
48
+ if (frame.isReliable()) frame.reliableIndex = this.outputReliableIndex++;
49
+ return this.queueFrame(frame, priority);
54
50
  }
55
51
  }
56
- /**
57
- * Sends the output frame queue
58
- */ sendFrameQueue() {
59
- if (this.outputFrameQueue.frames.length > 0) {
60
- this.outputFrameQueue.sequence = this.outputSequence++;
61
- this.sendFrameSet(this.outputFrameQueue);
62
- this.outputFrameQueue = new _raknet.FrameSet();
63
- this.outputFrameQueue.frames = [];
64
- }
52
+ queueFrame(frame, priority) {
53
+ let length = _raknet.DGRAM_HEADER_SIZE;
54
+ for (const frame of this.outputFrames)length += frame.getByteLength();
55
+ if (length + frame.getByteLength() > this.mtu - _raknet.DGRAM_MTU_OVERHEAD) this.sendQueue(this.outputFrames.size);
56
+ this.outputFrames.add(frame);
57
+ if (priority === _raknet.Priority.Immediate) return this.sendQueue(1);
65
58
  }
66
- /**
67
- * Sends a frame set to the connection
68
- * @param frameset The frame set
69
- */ sendFrameSet(frameset) {
70
- this.client.send(frameset.serialize());
71
- this.outputBackupQueue.set(frameset.sequence, frameset.frames.filter((frame)=>frame.isReliable()));
59
+ sendQueue(amount) {
60
+ if (this.outputFrames.size === 0) return;
61
+ const frameset = new _raknet.FrameSet();
62
+ frameset.sequence = this.outputSequence++;
63
+ frameset.frames = [
64
+ ...this.outputFrames
65
+ ].slice(0, amount);
66
+ this.outputBackup.set(frameset.sequence, frameset.frames);
67
+ for (const frame of frameset.frames)this.outputFrames.delete(frame);
68
+ return this.client.send(frameset.serialize());
72
69
  }
73
70
  constructor(client){
74
- this.client = client;
75
71
  this.outputBackupQueue = new Map();
72
+ this.mtu = 1492;
76
73
  this.outputSequence = 0;
74
+ this.outputsplitIndex = 0;
77
75
  this.outputReliableIndex = 0;
78
- this.outputFragmentIndex = 0;
79
- this.mtu = 1492;
76
+ this.outputFrames = new Set();
77
+ this.outputBackup = new Map();
78
+ this.client = client;
80
79
  this.outputFrameQueue = new _raknet.FrameSet();
81
80
  this.outputFrameQueue.frames = [];
82
81
  this.outputOrderIndex = Array.from({
@@ -85,5 +84,8 @@ class Queue {
85
84
  this.outputSequenceIndex = Array.from({
86
85
  length: 32
87
86
  }).fill(0);
87
+ this.client.on("tick", ()=>{
88
+ this.onTick();
89
+ });
88
90
  }
89
91
  }
@@ -79,7 +79,6 @@ class RakNetClient extends _events.EventEmitter {
79
79
  this.connected = false;
80
80
  this.protocol = 11;
81
81
  this.isBusy = false;
82
- this.status = _raknet.Status.Disconnected;
83
82
  this.clientAdress = new _raknet.Address('0.0.0.0', 0, 4);
84
83
  this.serverAddress = serverAddress;
85
84
  this.serverPort = serverPort;
@@ -88,6 +87,7 @@ class RakNetClient extends _events.EventEmitter {
88
87
  this.id = BigInt(Array.from({
89
88
  length: 20
90
89
  }, ()=>Math.floor(Math.random() * 10)).join(''));
90
+ this.status = _raknet.Status.Disconnected;
91
91
  this.packetHandler = new _PacketHandler.PacketHandler(this);
92
92
  this.queue = new _Queue.Queue(this);
93
93
  setInterval(()=>{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctumterra/raknet",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "emitDeclarationOnly": true,
@@ -18,13 +18,16 @@
18
18
  "devDependencies": {
19
19
  "@swc/core": "^1.6.13",
20
20
  "@swc/helpers": "^0.5.11",
21
+ "@types/bun": "^1.1.6",
21
22
  "@types/node": "^20.14.10",
22
23
  "typescript": "^5.5.3"
23
24
  },
24
25
  "dependencies": {
25
26
  "@serenityjs/binarystream": "^2.6.6",
26
- "@serenityjs/raknet": "^0.3.6",
27
+ "@serenityjs/raknet": "0.4.0-beta-20240715032912",
27
28
  "chalk": "^4.1.2",
29
+ "i": "^0.3.7",
30
+ "npm": "^10.8.2",
28
31
  "path": "^0.12.7"
29
32
  }
30
33
  }
package/tsconfig.json CHANGED
@@ -8,11 +8,16 @@
8
8
  "moduleResolution": "node",
9
9
  "outDir": "dist",
10
10
  "baseUrl": ".",
11
+ "skipLibCheck": true,
11
12
  "forceConsistentCasingInFileNames": true,
12
13
  "paths": {
13
14
  "*": ["./*"]
14
15
  }
15
16
  },
17
+ "exclude": [
18
+ "*/node_modules/",
19
+ "dist"
20
+ ],
16
21
  "ts-node": {
17
22
  "swc": true,
18
23
  "transpileOnly": true