@sanctumterra/raknet 1.4.4 → 1.4.6
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.d.ts +10 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +204 -18
- package/dist/client/types/client-options.d.ts +7 -0
- package/dist/client/types/client-options.d.ts.map +1 -1
- package/dist/shared/proto/offline/open-connection-reply-one.d.ts +2 -0
- package/dist/shared/proto/offline/open-connection-reply-one.d.ts.map +1 -1
- package/dist/shared/proto/offline/open-connection-reply-one.js +19 -5
- package/dist/shared/proto/offline/open-connection-request-two.d.ts +1 -0
- package/dist/shared/proto/offline/open-connection-request-two.d.ts.map +1 -1
- package/dist/shared/proto/offline/open-connection-request-two.js +12 -7
- package/dist/tests/client-once.js +3 -1
- package/package.json +4 -9
package/dist/client/client.d.ts
CHANGED
|
@@ -12,7 +12,17 @@ export declare class Client extends EventEmitter<ClientEvents> {
|
|
|
12
12
|
tick: number;
|
|
13
13
|
private session;
|
|
14
14
|
private gotReply1;
|
|
15
|
+
private proxySocket;
|
|
16
|
+
private proxyRelayHost;
|
|
17
|
+
private proxyRelayPort;
|
|
18
|
+
private resolvedAddress;
|
|
19
|
+
private proxyReady;
|
|
15
20
|
constructor(options?: Partial<ClientOptions>);
|
|
21
|
+
private setupProxy;
|
|
22
|
+
private buildUdpAssociateRequest;
|
|
23
|
+
private parseRelayAddress;
|
|
24
|
+
private createSocks5UdpHeader;
|
|
25
|
+
private parseSocks5UdpHeader;
|
|
16
26
|
connect(): Promise<void>;
|
|
17
27
|
onTick(): void;
|
|
18
28
|
onMessage(data: Buffer, rinfo: RemoteInfo): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,YAAY,EAWZ,QAAQ,EAIR,KAAK,KAAK,EAIV,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACN,KAAK,aAAa,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAgB,KAAK,UAAU,EAAe,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,YAAY,EAWZ,QAAQ,EAIR,KAAK,KAAK,EAIV,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACN,KAAK,aAAa,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAgB,KAAK,UAAU,EAAe,MAAM,YAAY,CAAC;AAKxE,qBAAa,MAAO,SAAQ,YAAY,CAAC,YAAY,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAiC;IACnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAE1C,OAAO,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,MAAM,CAAmB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;YAmBlC,UAAU;IAoGxB,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,oBAAoB;IA2Bf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD9B,MAAM,IAAI,IAAI;IAYd,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IA8DhD,YAAY,CAAC,IAAI,EAAE,MAAM;IAyCzB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAE,QAA0B;IAI5D,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAA0B;IAI/D,IAAI,IAAI,IAAI;IAOZ,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWxB,UAAU,IAAI,IAAI;CAQzB"}
|
package/dist/client/client.js
CHANGED
|
@@ -5,8 +5,10 @@ const shared_1 = require("../shared");
|
|
|
5
5
|
const client_options_1 = require("./types/client-options");
|
|
6
6
|
const node_dgram_1 = require("node:dgram");
|
|
7
7
|
const shared_2 = require("../shared");
|
|
8
|
+
const node_net_1 = require("node:net");
|
|
9
|
+
const promises_1 = require("node:dns/promises");
|
|
8
10
|
class Client extends shared_1.EventEmitter {
|
|
9
|
-
static MTU_VALUES = [1492, 1400, 1200, 576];
|
|
11
|
+
static MTU_VALUES = [1492, 1400, 1028, 1200, 576];
|
|
10
12
|
static MTU_RETRY_INTERVAL = 500;
|
|
11
13
|
options;
|
|
12
14
|
socket;
|
|
@@ -15,6 +17,11 @@ class Client extends shared_1.EventEmitter {
|
|
|
15
17
|
tick;
|
|
16
18
|
session;
|
|
17
19
|
gotReply1 = false;
|
|
20
|
+
proxySocket = null;
|
|
21
|
+
proxyRelayHost = null;
|
|
22
|
+
proxyRelayPort = null;
|
|
23
|
+
resolvedAddress = null;
|
|
24
|
+
proxyReady = false;
|
|
18
25
|
constructor(options = {}) {
|
|
19
26
|
super();
|
|
20
27
|
this.options = { ...client_options_1.defaultClientOptions, ...options };
|
|
@@ -30,10 +37,172 @@ class Client extends shared_1.EventEmitter {
|
|
|
30
37
|
this.handleOnline(data);
|
|
31
38
|
};
|
|
32
39
|
}
|
|
33
|
-
|
|
40
|
+
async setupProxy() {
|
|
41
|
+
if (!this.options.proxy)
|
|
42
|
+
return;
|
|
43
|
+
const proxy = this.options.proxy;
|
|
44
|
+
const isIPv4 = /^\d{1,3}(\.\d{1,3}){3}$/.test(this.options.address);
|
|
45
|
+
if (!isIPv4) {
|
|
46
|
+
const result = await (0, promises_1.lookup)(this.options.address, 4);
|
|
47
|
+
this.resolvedAddress = result.address;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.resolvedAddress = this.options.address;
|
|
51
|
+
}
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const socket = (0, node_net_1.connect)(proxy.port, proxy.host, () => {
|
|
54
|
+
const authMethods = proxy.userId && proxy.password ? [0x00, 0x02] : [0x00];
|
|
55
|
+
socket.write(Buffer.from([0x05, authMethods.length, ...authMethods]));
|
|
56
|
+
});
|
|
57
|
+
let state = "greeting";
|
|
58
|
+
socket.on("data", (data) => {
|
|
59
|
+
if (state === "greeting") {
|
|
60
|
+
if (data[0] !== 0x05) {
|
|
61
|
+
reject(new Error("Invalid SOCKS5 response"));
|
|
62
|
+
socket.destroy();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const method = data[1];
|
|
66
|
+
if (method === 0x02 && proxy.userId && proxy.password) {
|
|
67
|
+
const userBuf = Buffer.from(proxy.userId, "utf8");
|
|
68
|
+
const passBuf = Buffer.from(proxy.password, "utf8");
|
|
69
|
+
socket.write(Buffer.concat([
|
|
70
|
+
Buffer.from([0x01, userBuf.length]),
|
|
71
|
+
userBuf,
|
|
72
|
+
Buffer.from([passBuf.length]),
|
|
73
|
+
passBuf,
|
|
74
|
+
]));
|
|
75
|
+
state = "auth";
|
|
76
|
+
}
|
|
77
|
+
else if (method === 0x00) {
|
|
78
|
+
socket.write(this.buildUdpAssociateRequest());
|
|
79
|
+
state = "request";
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
reject(new Error("SOCKS5 auth method not supported"));
|
|
83
|
+
socket.destroy();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (state === "auth") {
|
|
87
|
+
if (data[1] !== 0x00) {
|
|
88
|
+
reject(new Error("SOCKS5 authentication failed"));
|
|
89
|
+
socket.destroy();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
socket.write(this.buildUdpAssociateRequest());
|
|
93
|
+
state = "request";
|
|
94
|
+
}
|
|
95
|
+
else if (state === "request") {
|
|
96
|
+
if (data[0] !== 0x05 || data[1] !== 0x00) {
|
|
97
|
+
reject(new Error(`SOCKS5 UDP ASSOCIATE failed: ${data[1]}`));
|
|
98
|
+
socket.destroy();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const relay = this.parseRelayAddress(data);
|
|
102
|
+
if (!relay) {
|
|
103
|
+
reject(new Error("Failed to parse relay address"));
|
|
104
|
+
socket.destroy();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.proxySocket = socket;
|
|
108
|
+
this.proxyRelayHost =
|
|
109
|
+
relay.host === "0.0.0.0"
|
|
110
|
+
? (this.resolvedAddress ?? proxy.host)
|
|
111
|
+
: relay.host;
|
|
112
|
+
this.proxyRelayPort = relay.port;
|
|
113
|
+
this.proxyReady = true;
|
|
114
|
+
state = "done";
|
|
115
|
+
resolve();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
socket.on("close", () => {
|
|
119
|
+
if (state !== "done") {
|
|
120
|
+
reject(new Error("SOCKS5 connection closed unexpectedly"));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
this.proxySocket = null;
|
|
124
|
+
this.proxyRelayHost = null;
|
|
125
|
+
this.proxyRelayPort = null;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
socket.on("error", (err) => {
|
|
129
|
+
reject(new Error(`SOCKS5 proxy error: ${err.message}`));
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
buildUdpAssociateRequest() {
|
|
134
|
+
return Buffer.from([0x05, 0x03, 0x00, 0x01, 0, 0, 0, 0, 0, 0]);
|
|
135
|
+
}
|
|
136
|
+
parseRelayAddress(data) {
|
|
137
|
+
const atyp = data[3];
|
|
138
|
+
if (atyp === 0x01) {
|
|
139
|
+
return {
|
|
140
|
+
host: `${data[4]}.${data[5]}.${data[6]}.${data[7]}`,
|
|
141
|
+
port: data.readUInt16BE(8),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (atyp === 0x03) {
|
|
145
|
+
const len = data[4] ?? 0;
|
|
146
|
+
return {
|
|
147
|
+
host: data.subarray(5, 5 + len).toString("utf8"),
|
|
148
|
+
port: data.readUInt16BE(5 + len),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
createSocks5UdpHeader(host, port) {
|
|
154
|
+
const isIPv4 = /^\d{1,3}(\.\d{1,3}){3}$/.test(host);
|
|
155
|
+
if (isIPv4) {
|
|
156
|
+
const header = Buffer.alloc(10);
|
|
157
|
+
header.writeUInt16BE(0, 0);
|
|
158
|
+
header.writeUInt8(0, 2);
|
|
159
|
+
header.writeUInt8(1, 3);
|
|
160
|
+
const parts = host.split(".").map(Number);
|
|
161
|
+
header.writeUInt8(parts[0] ?? 0, 4);
|
|
162
|
+
header.writeUInt8(parts[1] ?? 0, 5);
|
|
163
|
+
header.writeUInt8(parts[2] ?? 0, 6);
|
|
164
|
+
header.writeUInt8(parts[3] ?? 0, 7);
|
|
165
|
+
header.writeUInt16BE(port, 8);
|
|
166
|
+
return header;
|
|
167
|
+
}
|
|
168
|
+
const domainBuffer = Buffer.from(host, "utf8");
|
|
169
|
+
const header = Buffer.alloc(7 + domainBuffer.length);
|
|
170
|
+
header.writeUInt16BE(0, 0);
|
|
171
|
+
header.writeUInt8(0, 2);
|
|
172
|
+
header.writeUInt8(3, 3);
|
|
173
|
+
header.writeUInt8(domainBuffer.length, 4);
|
|
174
|
+
domainBuffer.copy(header, 5);
|
|
175
|
+
header.writeUInt16BE(port, 5 + domainBuffer.length);
|
|
176
|
+
return header;
|
|
177
|
+
}
|
|
178
|
+
parseSocks5UdpHeader(data) {
|
|
179
|
+
if (data.length < 10)
|
|
180
|
+
return null;
|
|
181
|
+
const atyp = data.readUInt8(3);
|
|
182
|
+
if (atyp === 1) {
|
|
183
|
+
return {
|
|
184
|
+
host: `${data.readUInt8(4)}.${data.readUInt8(5)}.${data.readUInt8(6)}.${data.readUInt8(7)}`,
|
|
185
|
+
port: data.readUInt16BE(8),
|
|
186
|
+
dataOffset: 10,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (atyp === 3) {
|
|
190
|
+
const domainLen = data.readUInt8(4);
|
|
191
|
+
return {
|
|
192
|
+
host: data.subarray(5, 5 + domainLen).toString("utf8"),
|
|
193
|
+
port: data.readUInt16BE(5 + domainLen),
|
|
194
|
+
dataOffset: 7 + domainLen,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
async connect() {
|
|
200
|
+
if (this.options.proxy) {
|
|
201
|
+
await this.setupProxy();
|
|
202
|
+
}
|
|
203
|
+
this.status = shared_1.ConnectionStatus.Connecting;
|
|
204
|
+
this.gotReply1 = false;
|
|
34
205
|
return new Promise((resolve, reject) => {
|
|
35
|
-
this.status = shared_1.ConnectionStatus.Connecting;
|
|
36
|
-
this.gotReply1 = false;
|
|
37
206
|
let mtuIndex = 0;
|
|
38
207
|
let retryTimeout = null;
|
|
39
208
|
const sendRequest = () => {
|
|
@@ -42,7 +211,6 @@ class Client extends shared_1.EventEmitter {
|
|
|
42
211
|
return;
|
|
43
212
|
}
|
|
44
213
|
const mtu = Client.MTU_VALUES[mtuIndex];
|
|
45
|
-
// Should not happen but for the linter sake
|
|
46
214
|
if (!mtu)
|
|
47
215
|
throw new Error("MTU value is undefined");
|
|
48
216
|
const request = new shared_1.OpenConnectionRequestOne();
|
|
@@ -74,7 +242,7 @@ class Client extends shared_1.EventEmitter {
|
|
|
74
242
|
const isDisconnected = this.status === shared_1.ConnectionStatus.Disconnected;
|
|
75
243
|
const isDisconnecting = this.status === shared_1.ConnectionStatus.Disconnecting;
|
|
76
244
|
const canPing = isDisconnected && this.tick % this.options.pingRate === 0;
|
|
77
|
-
if (canPing)
|
|
245
|
+
if (canPing && (!this.options.proxy || this.proxyReady))
|
|
78
246
|
this.ping();
|
|
79
247
|
if (!isDisconnecting || !isDisconnected) {
|
|
80
248
|
this.session.onTick(this.tick);
|
|
@@ -82,48 +250,55 @@ class Client extends shared_1.EventEmitter {
|
|
|
82
250
|
this.tick++;
|
|
83
251
|
}
|
|
84
252
|
onMessage(data, rinfo) {
|
|
85
|
-
let
|
|
253
|
+
let actualData = data;
|
|
254
|
+
if (this.proxyRelayHost && this.proxyRelayPort) {
|
|
255
|
+
const parsed = this.parseSocks5UdpHeader(data);
|
|
256
|
+
if (parsed) {
|
|
257
|
+
actualData = data.subarray(parsed.dataOffset);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
let id = actualData[0];
|
|
86
261
|
const isOnline = (id & 0xf0) === 0x80;
|
|
87
262
|
if (isOnline)
|
|
88
263
|
id = 0x80;
|
|
89
264
|
switch (id) {
|
|
90
265
|
case shared_1.Packets.UnconnectedPong: {
|
|
91
|
-
const pong = new shared_1.UnconnectedPong(
|
|
266
|
+
const pong = new shared_1.UnconnectedPong(actualData).deserialize();
|
|
92
267
|
this.emit("unconnectedPong", pong);
|
|
93
268
|
break;
|
|
94
269
|
}
|
|
95
270
|
case shared_1.Packets.OpenConnectionReply1: {
|
|
96
271
|
this.gotReply1 = true;
|
|
97
|
-
const reply = new shared_1.OpenConnectionReplyOne(
|
|
272
|
+
const reply = new shared_1.OpenConnectionReplyOne(actualData).deserialize();
|
|
98
273
|
const request = new shared_1.OpenConnectionRequestTwo();
|
|
99
274
|
request.address = shared_1.Address.fromIdentifier(rinfo);
|
|
100
275
|
request.mtu = reply.mtu;
|
|
101
276
|
request.guid = this.options.guid;
|
|
102
277
|
request.cookie = reply.cookie;
|
|
278
|
+
request.clientSupportsecurity = false;
|
|
103
279
|
this.send(request.serialize());
|
|
104
280
|
break;
|
|
105
281
|
}
|
|
106
282
|
case shared_1.Packets.OpenConnectionReply2: {
|
|
107
|
-
|
|
283
|
+
new shared_1.OpenConnectionReplyTwo(actualData).deserialize();
|
|
108
284
|
const request = new shared_1.ConnectionRequest();
|
|
109
285
|
request.guid = this.options.guid;
|
|
110
286
|
request.timestamp = BigInt(Date.now());
|
|
111
|
-
|
|
112
|
-
this.frameAndSend(serialized, shared_1.Priority.High);
|
|
287
|
+
this.frameAndSend(request.serialize(), shared_1.Priority.High);
|
|
113
288
|
break;
|
|
114
289
|
}
|
|
115
290
|
case shared_1.Packets.FrameSet: {
|
|
116
|
-
const frameSet = new shared_1.FrameSet(
|
|
291
|
+
const frameSet = new shared_1.FrameSet(actualData).deserialize();
|
|
117
292
|
this.session.onFrameSet(frameSet);
|
|
118
293
|
break;
|
|
119
294
|
}
|
|
120
295
|
case shared_1.Packets.Ack: {
|
|
121
|
-
const ack = new shared_1.Ack(
|
|
296
|
+
const ack = new shared_1.Ack(actualData).deserialize();
|
|
122
297
|
this.session.onAck(ack);
|
|
123
298
|
break;
|
|
124
299
|
}
|
|
125
300
|
case shared_1.Packets.Nack: {
|
|
126
|
-
const nack = new shared_1.Ack(
|
|
301
|
+
const nack = new shared_1.Ack(actualData).deserialize();
|
|
127
302
|
this.session.onNack(nack);
|
|
128
303
|
break;
|
|
129
304
|
}
|
|
@@ -178,14 +353,25 @@ class Client extends shared_1.EventEmitter {
|
|
|
178
353
|
const ping = new shared_1.UnconnectedPing();
|
|
179
354
|
ping.guid = this.options.guid;
|
|
180
355
|
ping.timestamp = BigInt(Date.now());
|
|
181
|
-
|
|
182
|
-
this.send(serialized);
|
|
356
|
+
this.send(ping.serialize());
|
|
183
357
|
}
|
|
184
358
|
send(data) {
|
|
185
|
-
|
|
359
|
+
if (this.proxyRelayHost && this.proxyRelayPort) {
|
|
360
|
+
const destAddr = this.resolvedAddress || this.options.address;
|
|
361
|
+
const header = this.createSocks5UdpHeader(destAddr, this.options.port);
|
|
362
|
+
const packet = Buffer.concat([header, data]);
|
|
363
|
+
this.socket.send(packet, this.proxyRelayPort, this.proxyRelayHost);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
this.socket.send(data, this.options.port, this.options.address);
|
|
367
|
+
}
|
|
186
368
|
}
|
|
187
369
|
disconnect() {
|
|
188
370
|
this.socket.close();
|
|
371
|
+
if (this.proxySocket) {
|
|
372
|
+
this.proxySocket.destroy();
|
|
373
|
+
this.proxySocket = null;
|
|
374
|
+
}
|
|
189
375
|
if (this.interval)
|
|
190
376
|
clearInterval(this.interval);
|
|
191
377
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export type ProxyOptions = {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
userId?: string;
|
|
5
|
+
password?: string;
|
|
6
|
+
};
|
|
1
7
|
export type ClientOptions = {
|
|
2
8
|
mtu: number;
|
|
3
9
|
address: string;
|
|
@@ -6,6 +12,7 @@ export type ClientOptions = {
|
|
|
6
12
|
tickRate: number;
|
|
7
13
|
pingRate: number;
|
|
8
14
|
timeout: number;
|
|
15
|
+
proxy?: ProxyOptions;
|
|
9
16
|
};
|
|
10
17
|
export declare const getRandomGuid: () => bigint;
|
|
11
18
|
export declare const defaultClientOptions: ClientOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-options.d.ts","sourceRoot":"","sources":["../../../src/client/types/client-options.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"client-options.d.ts","sourceRoot":"","sources":["../../../src/client/types/client-options.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,YAAY,CAAC;CACrB,CAAC;AACF,eAAO,MAAM,aAAa,cACgC,CAAC;AAE3D,eAAO,MAAM,oBAAoB,EAAE,aAQlC,CAAC"}
|
|
@@ -2,7 +2,9 @@ import { BinaryStream } from "@serenityjs/binarystream";
|
|
|
2
2
|
export declare class OpenConnectionReplyOne extends BinaryStream {
|
|
3
3
|
guid: bigint;
|
|
4
4
|
security: boolean;
|
|
5
|
+
hasCookie: boolean;
|
|
5
6
|
cookie: number | null;
|
|
7
|
+
serverPublicKey: Buffer | null;
|
|
6
8
|
mtu: number;
|
|
7
9
|
serialize(): Buffer;
|
|
8
10
|
deserialize(): OpenConnectionReplyOne;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-connection-reply-one.d.ts","sourceRoot":"","sources":["../../../../src/shared/proto/offline/open-connection-reply-one.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,
|
|
1
|
+
{"version":3,"file":"open-connection-reply-one.d.ts","sourceRoot":"","sources":["../../../../src/shared/proto/offline/open-connection-reply-one.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EAKZ,MAAM,0BAA0B,CAAC;AAIlC,qBAAa,sBAAuB,SAAQ,YAAY;IAChD,IAAI,EAAG,MAAM,CAAC;IACd,QAAQ,EAAG,OAAO,CAAC;IACnB,SAAS,EAAG,OAAO,CAAC;IACpB,MAAM,EAAG,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAG,MAAM,GAAG,IAAI,CAAC;IAChC,GAAG,EAAG,MAAM,CAAC;IAEb,SAAS,IAAI,MAAM;IAYnB,WAAW,IAAI,sBAAsB;CAyB5C"}
|
|
@@ -7,7 +7,9 @@ const types_1 = require("../types");
|
|
|
7
7
|
class OpenConnectionReplyOne extends binarystream_1.BinaryStream {
|
|
8
8
|
guid;
|
|
9
9
|
security;
|
|
10
|
+
hasCookie;
|
|
10
11
|
cookie;
|
|
12
|
+
serverPublicKey;
|
|
11
13
|
mtu;
|
|
12
14
|
serialize() {
|
|
13
15
|
binarystream_1.Uint8.write(this, enums_1.Packets.OpenConnectionReply1);
|
|
@@ -15,21 +17,33 @@ class OpenConnectionReplyOne extends binarystream_1.BinaryStream {
|
|
|
15
17
|
binarystream_1.Int64.write(this, this.guid);
|
|
16
18
|
binarystream_1.Bool.write(this, this.security);
|
|
17
19
|
if (this.security && this.cookie != null) {
|
|
18
|
-
|
|
20
|
+
this.writeUint32(this.cookie);
|
|
19
21
|
}
|
|
20
|
-
|
|
22
|
+
this.writeUint16(this.mtu);
|
|
21
23
|
return this.getBuffer();
|
|
22
24
|
}
|
|
23
25
|
deserialize() {
|
|
24
26
|
binarystream_1.Uint8.read(this);
|
|
25
27
|
types_1.Magic.read(this);
|
|
26
|
-
this.guid = binarystream_1.
|
|
28
|
+
this.guid = this.readInt64(binarystream_1.Endianness.Little);
|
|
27
29
|
this.security = binarystream_1.Bool.read(this);
|
|
28
30
|
this.cookie = null;
|
|
31
|
+
this.hasCookie = false;
|
|
32
|
+
this.serverPublicKey = null;
|
|
29
33
|
if (this.security) {
|
|
30
|
-
|
|
34
|
+
const remaining = this.buffer.byteLength - this.offset;
|
|
35
|
+
// Full security format: has_cookie (1) + cookie (4) + public_key (294) + mtu (2) = 301
|
|
36
|
+
if (remaining >= 1 + 4 + 294 + 2) {
|
|
37
|
+
this.hasCookie = binarystream_1.Bool.read(this);
|
|
38
|
+
this.cookie = this.readUint32();
|
|
39
|
+
this.serverPublicKey = this.read(294);
|
|
40
|
+
}
|
|
41
|
+
else if (remaining >= 4 + 2) {
|
|
42
|
+
// Simple security format: cookie (4) + mtu (2)
|
|
43
|
+
this.cookie = this.readUint32();
|
|
44
|
+
}
|
|
31
45
|
}
|
|
32
|
-
this.mtu =
|
|
46
|
+
this.mtu = this.readUint16();
|
|
33
47
|
return this;
|
|
34
48
|
}
|
|
35
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-connection-request-two.d.ts","sourceRoot":"","sources":["../../../../src/shared/proto/offline/open-connection-request-two.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"open-connection-request-two.d.ts","sourceRoot":"","sources":["../../../../src/shared/proto/offline/open-connection-request-two.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAsB,MAAM,0BAA0B,CAAC;AAE5E,OAAO,EAAE,OAAO,EAAS,MAAM,UAAU,CAAC;AAE1C,qBAAa,wBAAyB,SAAQ,YAAY;IAClD,OAAO,EAAG,OAAO,CAAC;IAClB,GAAG,EAAG,MAAM,CAAC;IACb,IAAI,EAAG,MAAM,CAAC;IACd,MAAM,EAAG,MAAM,GAAG,IAAI,CAAC;IACvB,qBAAqB,EAAG,OAAO,CAAC;IAEhC,SAAS,IAAI,MAAM;IAcnB,WAAW,IAAI,wBAAwB;CAc9C"}
|
|
@@ -9,26 +9,31 @@ class OpenConnectionRequestTwo extends binarystream_1.BinaryStream {
|
|
|
9
9
|
mtu;
|
|
10
10
|
guid;
|
|
11
11
|
cookie;
|
|
12
|
+
clientSupportsecurity;
|
|
12
13
|
serialize() {
|
|
13
14
|
binarystream_1.Uint8.write(this, enums_1.Packets.OpenConnectionRequest2);
|
|
14
15
|
types_1.Magic.write(this);
|
|
15
16
|
if (this.cookie != null) {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
this.writeUint32(this.cookie);
|
|
18
|
+
// client_supports_security should be false if we don't support libcat encryption
|
|
19
|
+
binarystream_1.Bool.write(this, this.clientSupportsecurity ?? false);
|
|
18
20
|
}
|
|
19
21
|
types_1.Address.write(this, this.address);
|
|
20
|
-
|
|
22
|
+
this.writeUint16(this.mtu);
|
|
21
23
|
binarystream_1.Int64.write(this, this.guid);
|
|
22
24
|
return this.getBuffer();
|
|
23
25
|
}
|
|
24
26
|
deserialize() {
|
|
25
27
|
binarystream_1.Uint8.read(this);
|
|
26
28
|
types_1.Magic.read(this);
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
29
|
+
// Check if there's enough data for cookie + clientSupportsecurity before address
|
|
30
|
+
// Cookie format: cookie (4) + clientSupportsecurity (1) = 5 bytes minimum before address
|
|
31
|
+
// We need to peek ahead to determine if security data is present
|
|
32
|
+
// For now, assume no security on deserialize (server-side typically doesn't need this)
|
|
33
|
+
this.cookie = null;
|
|
34
|
+
this.clientSupportsecurity = false;
|
|
30
35
|
this.address = types_1.Address.read(this);
|
|
31
|
-
this.mtu =
|
|
36
|
+
this.mtu = this.readUint16();
|
|
32
37
|
this.guid = binarystream_1.Int64.read(this);
|
|
33
38
|
return this;
|
|
34
39
|
}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const client_1 = require("../client");
|
|
4
4
|
const client = new client_1.Client({
|
|
5
|
-
address: "donutsmp.net",
|
|
5
|
+
// address: "donutsmp.net",
|
|
6
|
+
// address: "127.0.0.1",
|
|
7
|
+
address: "geo.hivebedrock.network",
|
|
6
8
|
});
|
|
7
9
|
client.on("unconnectedPong", (packet) => {
|
|
8
10
|
console.log(packet);
|
package/package.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanctumterra/raknet",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.6",
|
|
4
4
|
"description": "",
|
|
5
|
-
|
|
6
5
|
"types": "dist/index.d.ts",
|
|
7
6
|
"main": "dist/index.js",
|
|
8
|
-
|
|
9
7
|
"module": "commonjs",
|
|
10
|
-
|
|
11
8
|
"scripts": {
|
|
12
9
|
"build": "tsc",
|
|
13
10
|
"watch": "tsc --watch",
|
|
@@ -16,18 +13,16 @@
|
|
|
16
13
|
"lint:write": "npx @biomejs/biome lint --write ./src",
|
|
17
14
|
"format:write": "npx @biomejs/biome format --write ./src"
|
|
18
15
|
},
|
|
19
|
-
|
|
20
16
|
"keywords": [],
|
|
21
17
|
"author": "",
|
|
22
18
|
"license": "ISC",
|
|
23
|
-
|
|
24
19
|
"dependencies": {
|
|
25
20
|
"@serenityjs/binarystream": "^3.0.10"
|
|
26
21
|
},
|
|
27
22
|
"devDependencies": {
|
|
28
|
-
"@types/bun": "^1.2.21",
|
|
29
|
-
"typescript": "^5.9.2",
|
|
30
23
|
"@biomejs/biome": "^1.9.4",
|
|
31
|
-
"@types/
|
|
24
|
+
"@types/bun": "^1.2.21",
|
|
25
|
+
"@types/node": "^24.3.0",
|
|
26
|
+
"typescript": "^5.9.2"
|
|
32
27
|
}
|
|
33
28
|
}
|