@jsprismarine/client 0.1.0-rc.53 → 0.1.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.
@@ -0,0 +1,266 @@
1
+ import { InetAddress, Protocol, ConnectionPriority, MessageIdentifiers, RakNetSession } from '@jsprismarine/raknet';
2
+ import Dgram from 'node:dgram';
3
+ import { Logger, Protocol as Protocol$1 } from '@jsprismarine/prismarine';
4
+ import Crypto, { randomBytes } from 'node:crypto';
5
+ import { EventEmitter } from 'node:events';
6
+
7
+ var clearIntervalAsync$1 = {};
8
+
9
+ var setIntervalAsyncTimer = {};
10
+
11
+ Object.defineProperty(setIntervalAsyncTimer, "__esModule", { value: true });
12
+ setIntervalAsyncTimer.SetIntervalAsyncTimer = void 0;
13
+ const MIN_INTERVAL_MS = 10;
14
+ const MAX_INTERVAL_MS = 2147483647;
15
+ class SetIntervalAsyncTimer {
16
+ #timeout = undefined;
17
+ #promise = undefined;
18
+ #stopped = false;
19
+ static startTimer(strategy, handler, intervalMs, ...handlerArgs) {
20
+ intervalMs = Math.min(Math.max(Math.trunc(intervalMs), MIN_INTERVAL_MS), MAX_INTERVAL_MS);
21
+ const timer = new SetIntervalAsyncTimer();
22
+ timer.#scheduleTimeout(strategy, handler, intervalMs, intervalMs, ...handlerArgs);
23
+ return timer;
24
+ }
25
+ static async stopTimer(timer) {
26
+ timer.#stopped = true;
27
+ if (timer.#timeout) {
28
+ clearTimeout(timer.#timeout);
29
+ }
30
+ if (timer.#promise) {
31
+ await timer.#promise;
32
+ }
33
+ }
34
+ #scheduleTimeout(strategy, handler, intervalMs, delayMs, ...handlerArgs) {
35
+ this.#timeout = setTimeout(async () => {
36
+ this.#timeout = undefined;
37
+ this.#promise = this.#runHandlerAndScheduleTimeout(strategy, handler, intervalMs, ...handlerArgs);
38
+ await this.#promise;
39
+ this.#promise = undefined;
40
+ }, delayMs);
41
+ }
42
+ async #runHandlerAndScheduleTimeout(strategy, handler, intervalMs, ...handlerArgs) {
43
+ const startTimeMs = new Date().getTime();
44
+ try {
45
+ await handler(...handlerArgs);
46
+ }
47
+ finally {
48
+ if (!this.#stopped) {
49
+ const executionTimeMs = new Date().getTime() - startTimeMs;
50
+ const delayMs = strategy === "dynamic"
51
+ ? intervalMs > executionTimeMs
52
+ ? intervalMs - executionTimeMs
53
+ : 0
54
+ : intervalMs;
55
+ this.#scheduleTimeout(strategy, handler, intervalMs, delayMs, ...handlerArgs);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ setIntervalAsyncTimer.SetIntervalAsyncTimer = SetIntervalAsyncTimer;
61
+
62
+ Object.defineProperty(clearIntervalAsync$1, "__esModule", { value: true });
63
+ var clearIntervalAsync_2 = clearIntervalAsync$1.clearIntervalAsync = void 0;
64
+ const set_interval_async_timer_cjs_1 = setIntervalAsyncTimer;
65
+ /**
66
+ * Stops an execution cycle started by setIntervalAsync.
67
+ * Any ongoing function executions will run until completion,
68
+ * but all future ones will be cancelled.
69
+ */
70
+ async function clearIntervalAsync(timer) {
71
+ if (!(timer instanceof set_interval_async_timer_cjs_1.SetIntervalAsyncTimer)) {
72
+ throw new TypeError("First argument is not an instance of SetIntervalAsyncTimer");
73
+ }
74
+ await set_interval_async_timer_cjs_1.SetIntervalAsyncTimer.stopTimer(timer);
75
+ }
76
+ clearIntervalAsync_2 = clearIntervalAsync$1.clearIntervalAsync = clearIntervalAsync;
77
+
78
+ var setIntervalAsync = {};
79
+
80
+ (function (exports) {
81
+ Object.defineProperty(exports, "__esModule", { value: true });
82
+ exports.setIntervalAsync = exports.clearIntervalAsync = void 0;
83
+ const clear_interval_async_cjs_1 = clearIntervalAsync$1;
84
+ Object.defineProperty(exports, "clearIntervalAsync", { enumerable: true, get: function () { return clear_interval_async_cjs_1.clearIntervalAsync; } });
85
+ const set_interval_async_timer_cjs_1 = setIntervalAsyncTimer;
86
+ /**
87
+ * Executes the given handler at fixed intervals, while preventing
88
+ * multiple concurrent executions. The handler will never be executed
89
+ * concurrently more than once in any given moment, providing a fixed
90
+ * time interval between the end of a given execution and the start of
91
+ * the following one.
92
+ */
93
+ function setIntervalAsync(handler, intervalMs, ...handlerArgs) {
94
+ if (!(typeof handler === "function")) {
95
+ throw new TypeError("First argument is not a function");
96
+ }
97
+ if (!(typeof intervalMs === "number")) {
98
+ throw new TypeError("Second argument is not a number");
99
+ }
100
+ return set_interval_async_timer_cjs_1.SetIntervalAsyncTimer.startTimer("dynamic", handler, intervalMs, ...handlerArgs);
101
+ }
102
+ exports.setIntervalAsync = setIntervalAsync;
103
+ } (setIntervalAsync));
104
+
105
+ const getRandomInt = (min, max) => {
106
+ min = Math.ceil(min);
107
+ max = Math.floor(max);
108
+ return Math.floor(Math.random() * (max - min + 1)) + min;
109
+ };
110
+ const PROTOCOL = 10;
111
+ const DEF_MTU_SIZE = 1455;
112
+ const RAKNET_TPS = 100;
113
+ const RAKNET_TICK_LENGTH = 1 / RAKNET_TPS;
114
+ class Client extends EventEmitter {
115
+ clientGUID = Crypto.randomBytes(8).readBigInt64BE();
116
+ logger = new Logger();
117
+ address;
118
+ targetAddress;
119
+ connection = null;
120
+ socket = Dgram.createSocket({ type: "udp4" });
121
+ get closed() {
122
+ return false;
123
+ }
124
+ connecting = false;
125
+ connected = false;
126
+ offlineHandled = false;
127
+ loginHandled = false;
128
+ constructor() {
129
+ super();
130
+ this.address = new InetAddress("0.0.0.0", getRandomInt(46e3, 49999));
131
+ this.socket.bind(this.address.getPort(), this.address.getAddress());
132
+ }
133
+ /**
134
+ * Creates a packet listener on given address and port.
135
+ */
136
+ async connect(address = "0.0.0.0", port = 19132) {
137
+ this.targetAddress = new InetAddress(address, port);
138
+ this.socket.on("message", (buffer) => {
139
+ void this.handle(buffer);
140
+ });
141
+ if (this.connection)
142
+ throw new Error("Already connected/connecting to server.");
143
+ this.logger.info("JSPrismarine client is now attempting to connect...");
144
+ const timer = setIntervalAsync.setIntervalAsync(async () => {
145
+ if (this.closed) {
146
+ await clearIntervalAsync_2(timer);
147
+ return;
148
+ }
149
+ if (!this.connecting) {
150
+ const pk = new Protocol.UnconnectedPing();
151
+ pk.timestamp = BigInt(Date.now());
152
+ pk.encode();
153
+ await this.sendBuffer(pk.getBuffer());
154
+ }
155
+ if (this.connected && !this.loginHandled) {
156
+ const pk = new Protocol$1.Packets.LoginPacket();
157
+ pk.encode();
158
+ const sendPk = new Protocol.Frame();
159
+ sendPk.reliability = 0;
160
+ sendPk.content = pk.getBuffer();
161
+ this.connection.sendFrame(sendPk, ConnectionPriority.NORMAL);
162
+ this.loginHandled = true;
163
+ }
164
+ this.connection?.update(Date.now());
165
+ }, RAKNET_TICK_LENGTH * 1e3);
166
+ return this;
167
+ }
168
+ async handle(buffer) {
169
+ const header = buffer.readUInt8();
170
+ if (this.connection && this.offlineHandled) {
171
+ return this.connection.handle(buffer);
172
+ }
173
+ let buf;
174
+ switch (header) {
175
+ case MessageIdentifiers.UNCONNECTED_PONG:
176
+ buf = this.handleUnconnectedPong(buffer);
177
+ await this.sendBuffer(buf);
178
+ break;
179
+ case MessageIdentifiers.OPEN_CONNECTION_REPLY_1:
180
+ buf = this.handleOpenConnectionReply1(buffer);
181
+ await this.sendBuffer(buf);
182
+ break;
183
+ case MessageIdentifiers.OPEN_CONNECTION_REPLY_2:
184
+ this.handleOpenConnectionReply2(buffer);
185
+ break;
186
+ default:
187
+ this.logger.warn(`Unhandled offline packet ID: ${header}`, "Client/handle");
188
+ }
189
+ }
190
+ handleUnconnectedPong(buffer) {
191
+ const decodedPacket = new Protocol.UnconnectedPong(buffer);
192
+ decodedPacket.decode();
193
+ if (!decodedPacket.isValid()) {
194
+ throw new Error("Received an invalid offline message");
195
+ }
196
+ const packet = new Protocol.OpenConnectionRequest1();
197
+ packet.protocol = PROTOCOL;
198
+ packet.mtuSize = DEF_MTU_SIZE;
199
+ packet.encode();
200
+ return packet.getBuffer();
201
+ }
202
+ handleOpenConnectionReply1(buffer) {
203
+ const decodedPacket = new Protocol.OpenConnectionReply1(buffer);
204
+ decodedPacket.decode();
205
+ if (!decodedPacket.isValid()) {
206
+ throw new Error("Received an invalid offline message");
207
+ }
208
+ const packet = new Protocol.OpenConnectionRequest2();
209
+ packet.serverAddress = this.targetAddress;
210
+ packet.mtuSize = DEF_MTU_SIZE;
211
+ packet.clientGUID = this.clientGUID;
212
+ packet.encode();
213
+ this.connecting = true;
214
+ this.connection = new RakNetSession(
215
+ this,
216
+ DEF_MTU_SIZE,
217
+ {
218
+ address: this.address.getAddress(),
219
+ port: this.address.getPort(),
220
+ family: "IPv4",
221
+ size: 0
222
+ },
223
+ randomBytes(8).readBigInt64BE()
224
+ );
225
+ return packet.getBuffer();
226
+ }
227
+ handleOpenConnectionReply2(buffer) {
228
+ const decodedPacket = new Protocol.OpenConnectionReply2(buffer);
229
+ decodedPacket.decode();
230
+ if (!decodedPacket.isValid()) {
231
+ throw new Error("Received an invalid offline message");
232
+ }
233
+ const packet = new Protocol.ConnectionRequest();
234
+ packet.clientGUID = this.clientGUID;
235
+ packet.requestTimestamp = BigInt(Date.now());
236
+ packet.encode();
237
+ const sendPacket = new Protocol.Frame();
238
+ sendPacket.reliability = 0;
239
+ sendPacket.content = packet.getBuffer();
240
+ this.connection?.sendFrame(sendPacket, ConnectionPriority.NORMAL);
241
+ this.offlineHandled = true;
242
+ this.connected = true;
243
+ }
244
+ /**
245
+ * Sends the buffer to the server
246
+ *
247
+ * @param buffer
248
+ * @param address
249
+ * @param port
250
+ */
251
+ async sendBuffer(buffer) {
252
+ this.socket.send(buffer, 0, buffer.byteLength, this.targetAddress.getPort(), this.targetAddress.getAddress());
253
+ }
254
+ getSocket() {
255
+ return this.socket;
256
+ }
257
+ getAddress() {
258
+ return this.address;
259
+ }
260
+ async removeConnection(_connection, _reason) {
261
+ throw new Error("Method not implemented.");
262
+ }
263
+ }
264
+
265
+ export { Client as default };
266
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZXMuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9zZXQtaW50ZXJ2YWwtYXN5bmNAMy4wLjMvbm9kZV9tb2R1bGVzL3NldC1pbnRlcnZhbC1hc3luYy9kaXN0L3NldC1pbnRlcnZhbC1hc3luYy10aW1lci5janMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vc2V0LWludGVydmFsLWFzeW5jQDMuMC4zL25vZGVfbW9kdWxlcy9zZXQtaW50ZXJ2YWwtYXN5bmMvZGlzdC9jbGVhci1pbnRlcnZhbC1hc3luYy5janMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vc2V0LWludGVydmFsLWFzeW5jQDMuMC4zL25vZGVfbW9kdWxlcy9zZXQtaW50ZXJ2YWwtYXN5bmMvZGlzdC9keW5hbWljL3NldC1pbnRlcnZhbC1hc3luYy5janMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlNldEludGVydmFsQXN5bmNUaW1lciA9IHZvaWQgMDtcbmNvbnN0IE1JTl9JTlRFUlZBTF9NUyA9IDEwO1xuY29uc3QgTUFYX0lOVEVSVkFMX01TID0gMjE0NzQ4MzY0NztcbmNsYXNzIFNldEludGVydmFsQXN5bmNUaW1lciB7XG4gICAgI3RpbWVvdXQgPSB1bmRlZmluZWQ7XG4gICAgI3Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgI3N0b3BwZWQgPSBmYWxzZTtcbiAgICBzdGF0aWMgc3RhcnRUaW1lcihzdHJhdGVneSwgaGFuZGxlciwgaW50ZXJ2YWxNcywgLi4uaGFuZGxlckFyZ3MpIHtcbiAgICAgICAgaW50ZXJ2YWxNcyA9IE1hdGgubWluKE1hdGgubWF4KE1hdGgudHJ1bmMoaW50ZXJ2YWxNcyksIE1JTl9JTlRFUlZBTF9NUyksIE1BWF9JTlRFUlZBTF9NUyk7XG4gICAgICAgIGNvbnN0IHRpbWVyID0gbmV3IFNldEludGVydmFsQXN5bmNUaW1lcigpO1xuICAgICAgICB0aW1lci4jc2NoZWR1bGVUaW1lb3V0KHN0cmF0ZWd5LCBoYW5kbGVyLCBpbnRlcnZhbE1zLCBpbnRlcnZhbE1zLCAuLi5oYW5kbGVyQXJncyk7XG4gICAgICAgIHJldHVybiB0aW1lcjtcbiAgICB9XG4gICAgc3RhdGljIGFzeW5jIHN0b3BUaW1lcih0aW1lcikge1xuICAgICAgICB0aW1lci4jc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0aW1lci4jdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyLiN0aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGltZXIuI3Byb21pc2UpIHtcbiAgICAgICAgICAgIGF3YWl0IHRpbWVyLiNwcm9taXNlO1xuICAgICAgICB9XG4gICAgfVxuICAgICNzY2hlZHVsZVRpbWVvdXQoc3RyYXRlZ3ksIGhhbmRsZXIsIGludGVydmFsTXMsIGRlbGF5TXMsIC4uLmhhbmRsZXJBcmdzKSB7XG4gICAgICAgIHRoaXMuI3RpbWVvdXQgPSBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuI3RpbWVvdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLiNwcm9taXNlID0gdGhpcy4jcnVuSGFuZGxlckFuZFNjaGVkdWxlVGltZW91dChzdHJhdGVneSwgaGFuZGxlciwgaW50ZXJ2YWxNcywgLi4uaGFuZGxlckFyZ3MpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy4jcHJvbWlzZTtcbiAgICAgICAgICAgIHRoaXMuI3Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIH0sIGRlbGF5TXMpO1xuICAgIH1cbiAgICBhc3luYyAjcnVuSGFuZGxlckFuZFNjaGVkdWxlVGltZW91dChzdHJhdGVneSwgaGFuZGxlciwgaW50ZXJ2YWxNcywgLi4uaGFuZGxlckFyZ3MpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lTXMgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGhhbmRsZXIoLi4uaGFuZGxlckFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLiNzdG9wcGVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXhlY3V0aW9uVGltZU1zID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydFRpbWVNcztcbiAgICAgICAgICAgICAgICBjb25zdCBkZWxheU1zID0gc3RyYXRlZ3kgPT09IFwiZHluYW1pY1wiXG4gICAgICAgICAgICAgICAgICAgID8gaW50ZXJ2YWxNcyA+IGV4ZWN1dGlvblRpbWVNc1xuICAgICAgICAgICAgICAgICAgICAgICAgPyBpbnRlcnZhbE1zIC0gZXhlY3V0aW9uVGltZU1zXG4gICAgICAgICAgICAgICAgICAgICAgICA6IDBcbiAgICAgICAgICAgICAgICAgICAgOiBpbnRlcnZhbE1zO1xuICAgICAgICAgICAgICAgIHRoaXMuI3NjaGVkdWxlVGltZW91dChzdHJhdGVneSwgaGFuZGxlciwgaW50ZXJ2YWxNcywgZGVsYXlNcywgLi4uaGFuZGxlckFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0cy5TZXRJbnRlcnZhbEFzeW5jVGltZXIgPSBTZXRJbnRlcnZhbEFzeW5jVGltZXI7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuY2xlYXJJbnRlcnZhbEFzeW5jID0gdm9pZCAwO1xuY29uc3Qgc2V0X2ludGVydmFsX2FzeW5jX3RpbWVyX2Nqc18xID0gcmVxdWlyZShcIi4vc2V0LWludGVydmFsLWFzeW5jLXRpbWVyLmNqc1wiKTtcbi8qKlxuICogU3RvcHMgYW4gZXhlY3V0aW9uIGN5Y2xlIHN0YXJ0ZWQgYnkgc2V0SW50ZXJ2YWxBc3luYy5cbiAqIEFueSBvbmdvaW5nIGZ1bmN0aW9uIGV4ZWN1dGlvbnMgd2lsbCBydW4gdW50aWwgY29tcGxldGlvbixcbiAqIGJ1dCBhbGwgZnV0dXJlIG9uZXMgd2lsbCBiZSBjYW5jZWxsZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNsZWFySW50ZXJ2YWxBc3luYyh0aW1lcikge1xuICAgIGlmICghKHRpbWVyIGluc3RhbmNlb2Ygc2V0X2ludGVydmFsX2FzeW5jX3RpbWVyX2Nqc18xLlNldEludGVydmFsQXN5bmNUaW1lcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZpcnN0IGFyZ3VtZW50IGlzIG5vdCBhbiBpbnN0YW5jZSBvZiBTZXRJbnRlcnZhbEFzeW5jVGltZXJcIik7XG4gICAgfVxuICAgIGF3YWl0IHNldF9pbnRlcnZhbF9hc3luY190aW1lcl9janNfMS5TZXRJbnRlcnZhbEFzeW5jVGltZXIuc3RvcFRpbWVyKHRpbWVyKTtcbn1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbEFzeW5jID0gY2xlYXJJbnRlcnZhbEFzeW5jO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnNldEludGVydmFsQXN5bmMgPSBleHBvcnRzLmNsZWFySW50ZXJ2YWxBc3luYyA9IHZvaWQgMDtcbmNvbnN0IGNsZWFyX2ludGVydmFsX2FzeW5jX2Nqc18xID0gcmVxdWlyZShcIi4uL2NsZWFyLWludGVydmFsLWFzeW5jLmNqc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImNsZWFySW50ZXJ2YWxBc3luY1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY2xlYXJfaW50ZXJ2YWxfYXN5bmNfY2pzXzEuY2xlYXJJbnRlcnZhbEFzeW5jOyB9IH0pO1xuY29uc3Qgc2V0X2ludGVydmFsX2FzeW5jX3RpbWVyX2Nqc18xID0gcmVxdWlyZShcIi4uL3NldC1pbnRlcnZhbC1hc3luYy10aW1lci5janNcIik7XG4vKipcbiAqIEV4ZWN1dGVzIHRoZSBnaXZlbiBoYW5kbGVyIGF0IGZpeGVkIGludGVydmFscywgd2hpbGUgcHJldmVudGluZ1xuICogbXVsdGlwbGUgY29uY3VycmVudCBleGVjdXRpb25zLiBUaGUgaGFuZGxlciB3aWxsIG5ldmVyIGJlIGV4ZWN1dGVkXG4gKiBjb25jdXJyZW50bHkgbW9yZSB0aGFuIG9uY2UgaW4gYW55IGdpdmVuIG1vbWVudCwgcHJvdmlkaW5nIGEgZml4ZWRcbiAqIHRpbWUgaW50ZXJ2YWwgYmV0d2VlbiB0aGUgZW5kIG9mIGEgZ2l2ZW4gZXhlY3V0aW9uIGFuZCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBmb2xsb3dpbmcgb25lLlxuICovXG5mdW5jdGlvbiBzZXRJbnRlcnZhbEFzeW5jKGhhbmRsZXIsIGludGVydmFsTXMsIC4uLmhhbmRsZXJBcmdzKSB7XG4gICAgaWYgKCEodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZpcnN0IGFyZ3VtZW50IGlzIG5vdCBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cbiAgICBpZiAoISh0eXBlb2YgaW50ZXJ2YWxNcyA9PT0gXCJudW1iZXJcIikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlNlY29uZCBhcmd1bWVudCBpcyBub3QgYSBudW1iZXJcIik7XG4gICAgfVxuICAgIHJldHVybiBzZXRfaW50ZXJ2YWxfYXN5bmNfdGltZXJfY2pzXzEuU2V0SW50ZXJ2YWxBc3luY1RpbWVyLnN0YXJ0VGltZXIoXCJkeW5hbWljXCIsIGhhbmRsZXIsIGludGVydmFsTXMsIC4uLmhhbmRsZXJBcmdzKTtcbn1cbmV4cG9ydHMuc2V0SW50ZXJ2YWxBc3luYyA9IHNldEludGVydmFsQXN5bmM7XG4iLCJpbXBvcnQgeyBDb25uZWN0aW9uUHJpb3JpdHksIEluZXRBZGRyZXNzLCBQcm90b2NvbCwgUmFrTmV0U2Vzc2lvbiwgTWVzc2FnZUlkZW50aWZpZXJzIH0gZnJvbSAnQGpzcHJpc21hcmluZS9yYWtuZXQnO1xuaW1wb3J0IERncmFtLCB7IHR5cGUgU29ja2V0IH0gZnJvbSAnbm9kZTpkZ3JhbSc7XG5pbXBvcnQgeyBQcm90b2NvbCBhcyBKU1BQcm90b2NvbCwgTG9nZ2VyIH0gZnJvbSAnQGpzcHJpc21hcmluZS9wcmlzbWFyaW5lJztcbmltcG9ydCB7IGNsZWFySW50ZXJ2YWxBc3luYywgc2V0SW50ZXJ2YWxBc3luYyB9IGZyb20gJ3NldC1pbnRlcnZhbC1hc3luYy9keW5hbWljJztcbmltcG9ydCBDcnlwdG8sIHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdub2RlOmV2ZW50cyc7XG5cbi8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNTI3ODIwLzMxNDI1NTNcbmNvbnN0IGdldFJhbmRvbUludCA9IChtaW46IG51bWJlciwgbWF4OiBudW1iZXIpID0+IHtcbiAgICBtaW4gPSBNYXRoLmNlaWwobWluKTtcbiAgICBtYXggPSBNYXRoLmZsb29yKG1heCk7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSkgKyBtaW47XG59O1xuXG4vLyBNaW5lY3JhZnQgcmVsYXRlZCBwcm90b2NvbFxuY29uc3QgUFJPVE9DT0wgPSAxMDtcblxuLy8gTWF4IG5ldCB0cmFuc2ZlciB1bml0XG5jb25zdCBERUZfTVRVX1NJWkUgPSAxNDU1O1xuXG4vLyBSYWtuZXQgdGlja3NcbmNvbnN0IFJBS05FVF9UUFMgPSAxMDA7XG5jb25zdCBSQUtORVRfVElDS19MRU5HVEggPSAxIC8gUkFLTkVUX1RQUztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xpZW50IGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgICBwcml2YXRlIGNsaWVudEdVSUQgPSBDcnlwdG8ucmFuZG9tQnl0ZXMoOCkucmVhZEJpZ0ludDY0QkUoKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlciA9IG5ldyBMb2dnZXIoKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFkZHJlc3M6IEluZXRBZGRyZXNzO1xuICAgIHByaXZhdGUgdGFyZ2V0QWRkcmVzcyE6IEluZXRBZGRyZXNzO1xuICAgIHByaXZhdGUgY29ubmVjdGlvbjogUmFrTmV0U2Vzc2lvbiB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgc29ja2V0ID0gRGdyYW0uY3JlYXRlU29ja2V0KHsgdHlwZTogJ3VkcDQnIH0pO1xuICAgIHByaXZhdGUgZ2V0IGNsb3NlZCgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29ubmVjdGluZyA9IGZhbHNlO1xuICAgIHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBvZmZsaW5lSGFuZGxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgbG9naW5IYW5kbGVkID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuYWRkcmVzcyA9IG5ldyBJbmV0QWRkcmVzcygnMC4wLjAuMCcsIGdldFJhbmRvbUludCg0NjAwMCwgNDk5OTkpKTtcbiAgICAgICAgdGhpcy5zb2NrZXQuYmluZCh0aGlzLmFkZHJlc3MuZ2V0UG9ydCgpLCB0aGlzLmFkZHJlc3MuZ2V0QWRkcmVzcygpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGFja2V0IGxpc3RlbmVyIG9uIGdpdmVuIGFkZHJlc3MgYW5kIHBvcnQuXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIGNvbm5lY3QoYWRkcmVzcyA9ICcwLjAuMC4wJywgcG9ydCA9IDE5MTMyKSB7XG4gICAgICAgIHRoaXMudGFyZ2V0QWRkcmVzcyA9IG5ldyBJbmV0QWRkcmVzcyhhZGRyZXNzLCBwb3J0KTtcblxuICAgICAgICB0aGlzLnNvY2tldC5vbignbWVzc2FnZScsIChidWZmZXI6IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgdm9pZCB0aGlzLmhhbmRsZShidWZmZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uKSB0aHJvdyBuZXcgRXJyb3IoJ0FscmVhZHkgY29ubmVjdGVkL2Nvbm5lY3RpbmcgdG8gc2VydmVyLicpO1xuXG4gICAgICAgIHRoaXMubG9nZ2VyLmluZm8oJ0pTUHJpc21hcmluZSBjbGllbnQgaXMgbm93IGF0dGVtcHRpbmcgdG8gY29ubmVjdC4uLicpO1xuXG4gICAgICAgIGNvbnN0IHRpbWVyID0gc2V0SW50ZXJ2YWxBc3luYyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjbGVhckludGVydmFsQXN5bmModGltZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gU2VuZCBhIGNsaWVudCBwYWNrZXQgdG8gdGhlIHNlcnZlclxuICAgICAgICAgICAgLy8gc28gdGhlIHNlcnZlciBnb2VzIGluIHRhcmdldCBtb2RlXG4gICAgICAgICAgICAvLyBhbmQgdGhlIGxvZ2luIHByb2Nlc3Mgc3RhcnRzXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBrID0gbmV3IFByb3RvY29sLlVuY29ubmVjdGVkUGluZygpO1xuICAgICAgICAgICAgICAgIHBrLnRpbWVzdGFtcCA9IEJpZ0ludChEYXRlLm5vdygpKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBjYW4gYmUgb21pdHRlZC4uLiBway4gPSB0aGlzLmNsaWVudEdVSUQ7XG4gICAgICAgICAgICAgICAgcGsuZW5jb2RlKCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZW5kQnVmZmVyKHBrLmdldEJ1ZmZlcigpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkICYmICF0aGlzLmxvZ2luSGFuZGxlZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBrID0gbmV3IEpTUFByb3RvY29sLlBhY2tldHMuTG9naW5QYWNrZXQoKTtcbiAgICAgICAgICAgICAgICBway5lbmNvZGUoKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlbmRQayA9IG5ldyBQcm90b2NvbC5GcmFtZSgpO1xuICAgICAgICAgICAgICAgIHNlbmRQay5yZWxpYWJpbGl0eSA9IDA7XG4gICAgICAgICAgICAgICAgc2VuZFBrLmNvbnRlbnQgPSBway5nZXRCdWZmZXIoKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbiEuc2VuZEZyYW1lKHNlbmRQaywgQ29ubmVjdGlvblByaW9yaXR5Lk5PUk1BTCk7IC8vIFBhY2tldCBuZWVkcyB0byBiZSBzcGxpdHRlZFxuICAgICAgICAgICAgICAgIHRoaXMubG9naW5IYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uPy51cGRhdGUoRGF0ZS5ub3coKSk7XG4gICAgICAgIH0sIFJBS05FVF9USUNLX0xFTkdUSCAqIDEwMDApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGhhbmRsZShidWZmZXI6IEJ1ZmZlcikge1xuICAgICAgICBjb25zdCBoZWFkZXIgPSBidWZmZXIucmVhZFVJbnQ4KCk7IC8vIFJlYWQgcGFja2V0IGhlYWRlclxuXG4gICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb24gJiYgdGhpcy5vZmZsaW5lSGFuZGxlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbi5oYW5kbGUoYnVmZmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBidWY7XG4gICAgICAgIHN3aXRjaCAoaGVhZGVyKSB7XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VJZGVudGlmaWVycy5VTkNPTk5FQ1RFRF9QT05HOlxuICAgICAgICAgICAgICAgIGJ1ZiA9IHRoaXMuaGFuZGxlVW5jb25uZWN0ZWRQb25nKGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZW5kQnVmZmVyKGJ1Zik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VJZGVudGlmaWVycy5PUEVOX0NPTk5FQ1RJT05fUkVQTFlfMTpcbiAgICAgICAgICAgICAgICBidWYgPSB0aGlzLmhhbmRsZU9wZW5Db25uZWN0aW9uUmVwbHkxKGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZW5kQnVmZmVyKGJ1Zik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VJZGVudGlmaWVycy5PUEVOX0NPTk5FQ1RJT05fUkVQTFlfMjpcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZU9wZW5Db25uZWN0aW9uUmVwbHkyKGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oYFVuaGFuZGxlZCBvZmZsaW5lIHBhY2tldCBJRDogJHtoZWFkZXJ9YCwgJ0NsaWVudC9oYW5kbGUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVVbmNvbm5lY3RlZFBvbmcoYnVmZmVyOiBCdWZmZXIpIHtcbiAgICAgICAgLy8gRGVjb2RlIHNlcnZlciBwYWNrZXRcbiAgICAgICAgY29uc3QgZGVjb2RlZFBhY2tldCA9IG5ldyBQcm90b2NvbC5VbmNvbm5lY3RlZFBvbmcoYnVmZmVyKTtcbiAgICAgICAgZGVjb2RlZFBhY2tldC5kZWNvZGUoKTtcblxuICAgICAgICAvLyBDaGVjayBwYWNrZXQgdmFsaWRpdHlcbiAgICAgICAgLy8gVG8gcmVmYWN0b3JcbiAgICAgICAgaWYgKCFkZWNvZGVkUGFja2V0LmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWNlaXZlZCBhbiBpbnZhbGlkIG9mZmxpbmUgbWVzc2FnZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRW5jb2RlIHJlc3BvbnNlXG4gICAgICAgIGNvbnN0IHBhY2tldCA9IG5ldyBQcm90b2NvbC5PcGVuQ29ubmVjdGlvblJlcXVlc3QxKCk7XG4gICAgICAgIHBhY2tldC5wcm90b2NvbCA9IFBST1RPQ09MO1xuICAgICAgICBwYWNrZXQubXR1U2l6ZSA9IERFRl9NVFVfU0laRTtcbiAgICAgICAgcGFja2V0LmVuY29kZSgpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBzZXNzaW9uIHN0YXR1c1xuICAgICAgICAvLyB0aGlzLnN0YXR1cyA9IENvbm5lY3Rpb25TdGF0dXMuVGFyZ2V0dGVkO1xuXG4gICAgICAgIHJldHVybiBwYWNrZXQuZ2V0QnVmZmVyKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGhhbmRsZU9wZW5Db25uZWN0aW9uUmVwbHkxKGJ1ZmZlcjogQnVmZmVyKSB7XG4gICAgICAgIC8vIERlY29kZSBzZXJ2ZXIgcGFja2V0XG4gICAgICAgIGNvbnN0IGRlY29kZWRQYWNrZXQgPSBuZXcgUHJvdG9jb2wuT3BlbkNvbm5lY3Rpb25SZXBseTEoYnVmZmVyKTtcbiAgICAgICAgZGVjb2RlZFBhY2tldC5kZWNvZGUoKTtcblxuICAgICAgICAvLyBDaGVjayBwYWNrZXQgdmFsaWRpdHlcbiAgICAgICAgLy8gVG8gcmVmYWN0b3JcbiAgICAgICAgaWYgKCFkZWNvZGVkUGFja2V0LmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWNlaXZlZCBhbiBpbnZhbGlkIG9mZmxpbmUgbWVzc2FnZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRW5jb2RlIHJlc3BvbnNlXG4gICAgICAgIGNvbnN0IHBhY2tldCA9IG5ldyBQcm90b2NvbC5PcGVuQ29ubmVjdGlvblJlcXVlc3QyKCk7XG4gICAgICAgIHBhY2tldC5zZXJ2ZXJBZGRyZXNzID0gdGhpcy50YXJnZXRBZGRyZXNzO1xuICAgICAgICBwYWNrZXQubXR1U2l6ZSA9IERFRl9NVFVfU0laRTtcbiAgICAgICAgcGFja2V0LmNsaWVudEdVSUQgPSB0aGlzLmNsaWVudEdVSUQ7XG4gICAgICAgIHBhY2tldC5lbmNvZGUoKTtcblxuICAgICAgICAvLyBVcGRhdGUgc2Vzc2lvbiBzdGF0dXNcbiAgICAgICAgdGhpcy5jb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gVGhpcy5zdGF0dXMgPSBDb25uZWN0aW9uU3RhdHVzLkNvbm5lY3RlZDtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gbmV3IFJha05ldFNlc3Npb24oXG4gICAgICAgICAgICB0aGlzIGFzIGFueSxcbiAgICAgICAgICAgIERFRl9NVFVfU0laRSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhZGRyZXNzOiB0aGlzLmFkZHJlc3MuZ2V0QWRkcmVzcygpLFxuICAgICAgICAgICAgICAgIHBvcnQ6IHRoaXMuYWRkcmVzcy5nZXRQb3J0KCksXG4gICAgICAgICAgICAgICAgZmFtaWx5OiAnSVB2NCcsXG4gICAgICAgICAgICAgICAgc2l6ZTogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJhbmRvbUJ5dGVzKDgpLnJlYWRCaWdJbnQ2NEJFKClcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gcGFja2V0LmdldEJ1ZmZlcigpO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVPcGVuQ29ubmVjdGlvblJlcGx5MihidWZmZXI6IEJ1ZmZlcikge1xuICAgICAgICAvLyBEZWNvZGUgc2VydmVyIHBhY2tldFxuICAgICAgICBjb25zdCBkZWNvZGVkUGFja2V0ID0gbmV3IFByb3RvY29sLk9wZW5Db25uZWN0aW9uUmVwbHkyKGJ1ZmZlcik7XG4gICAgICAgIGRlY29kZWRQYWNrZXQuZGVjb2RlKCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgcGFja2V0IHZhbGlkaXR5XG4gICAgICAgIC8vIFRvIHJlZmFjdG9yXG4gICAgICAgIGlmICghZGVjb2RlZFBhY2tldC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUmVjZWl2ZWQgYW4gaW52YWxpZCBvZmZsaW5lIG1lc3NhZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEVuY29kZSByZXNwb25zZSAoZW5jYXBzdWxhdGVkKVxuICAgICAgICBjb25zdCBwYWNrZXQgPSBuZXcgUHJvdG9jb2wuQ29ubmVjdGlvblJlcXVlc3QoKTtcbiAgICAgICAgcGFja2V0LmNsaWVudEdVSUQgPSB0aGlzLmNsaWVudEdVSUQ7XG4gICAgICAgIHBhY2tldC5yZXF1ZXN0VGltZXN0YW1wID0gQmlnSW50KERhdGUubm93KCkpO1xuICAgICAgICBwYWNrZXQuZW5jb2RlKCk7XG5cbiAgICAgICAgY29uc3Qgc2VuZFBhY2tldCA9IG5ldyBQcm90b2NvbC5GcmFtZSgpO1xuICAgICAgICBzZW5kUGFja2V0LnJlbGlhYmlsaXR5ID0gMDtcbiAgICAgICAgc2VuZFBhY2tldC5jb250ZW50ID0gcGFja2V0LmdldEJ1ZmZlcigpO1xuXG4gICAgICAgIHRoaXMuY29ubmVjdGlvbj8uc2VuZEZyYW1lKHNlbmRQYWNrZXQsIENvbm5lY3Rpb25Qcmlvcml0eS5OT1JNQUwpO1xuXG4gICAgICAgIHRoaXMub2ZmbGluZUhhbmRsZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmNvbm5lY3RlZCA9IHRydWU7IC8vIFNob3VsZCBiZS4uLiB3ZSBjYW4ndCByZWx5IG9uIGl0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhlIGJ1ZmZlciB0byB0aGUgc2VydmVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYnVmZmVyXG4gICAgICogQHBhcmFtIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gcG9ydFxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBzZW5kQnVmZmVyKGJ1ZmZlcjogQnVmZmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuc29ja2V0LnNlbmQoYnVmZmVyLCAwLCBidWZmZXIuYnl0ZUxlbmd0aCwgdGhpcy50YXJnZXRBZGRyZXNzLmdldFBvcnQoKSwgdGhpcy50YXJnZXRBZGRyZXNzLmdldEFkZHJlc3MoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNvY2tldCgpOiBTb2NrZXQge1xuICAgICAgICByZXR1cm4gdGhpcy5zb2NrZXQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEFkZHJlc3MoKTogSW5ldEFkZHJlc3Mge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRyZXNzO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZW1vdmVDb25uZWN0aW9uKF9jb25uZWN0aW9uOiBSYWtOZXRTZXNzaW9uLCBfcmVhc29uPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgICB9XG59XG4iXSwibmFtZXMiOlsiY2xlYXJJbnRlcnZhbEFzeW5jXzEiLCJyZXF1aXJlJCQwIiwicmVxdWlyZSQkMSIsInNldEludGVydmFsQXN5bmMiLCJjbGVhckludGVydmFsQXN5bmMiLCJKU1BQcm90b2NvbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUNBLE1BQU0sQ0FBQyxjQUFjLENBQUMscUJBQU8sRUFBRSxZQUFZLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUNqQyxxQkFBQSxDQUFBLHFCQUFBLEdBQUcsS0FBSyxFQUFFO0FBQ3ZDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQztBQUMzQixNQUFNLGVBQWUsR0FBRyxVQUFVLENBQUM7QUFDbkMsTUFBTSxxQkFBcUIsQ0FBQztBQUM1QixJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUM7QUFDekIs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
package/package.json CHANGED
@@ -1,33 +1,55 @@
1
1
  {
2
- "name": "@jsprismarine/client",
3
- "version": "0.1.0-rc.53",
4
- "description": "Minecraft: Bedrock Edition RakNet client",
5
- "main": "./dist/Client.js",
6
- "types": "./dist/Client.d.ts",
7
- "type": "module",
8
- "funding": "https://github.com/sponsors/JSPrismarine",
9
- "scripts": {
10
- "build": "tsc --build src"
2
+ "name": "@jsprismarine/client",
3
+ "version": "0.1.0",
4
+ "description": "Minecraft: Bedrock Edition RakNet client",
5
+ "sideEffects": false,
6
+ "type": "module",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "module": "./dist/index.es.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.es.js",
15
+ "module": "./dist/index.es.js",
16
+ "require": "./dist/index.cjs.js",
17
+ "types": "./dist/index.d.ts"
11
18
  },
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/JSPrismarine/JSPrismarine.git"
19
+ "./*": {
20
+ "import": "./dist/*.es.js",
21
+ "module": "./dist/*.es.js",
22
+ "require": "./dist/*.cjs.js",
23
+ "types": "./dist/*.d.ts"
15
24
  },
16
- "keywords": [
17
- "nodejs",
18
- "raknet"
19
- ],
20
- "author": "JSPrismarine",
21
- "license": "MIT",
22
- "homepage": "https://github.com/JSPrismarine/JSPrismarine/tree/master/packages/client",
23
- "devDependencies": {
24
- "@types/set-interval-async": "1.0.3",
25
- "typescript": "5.3.3"
26
- },
27
- "dependencies": {
28
- "@jsprismarine/prismarine": "0.1.0-rc.53",
29
- "@jsprismarine/raknet": "0.1.0-rc.53",
30
- "set-interval-async": "3.0.3"
31
- },
32
- "gitHead": "d5c024aee5aa3dfd06ed5cde11d9ac39a4c35bb0"
33
- }
25
+ "./package.json": "./package.json"
26
+ },
27
+ "funding": "https://github.com/sponsors/JSPrismarine",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/JSPrismarine/JSPrismarine.git"
31
+ },
32
+ "keywords": [
33
+ "nodejs",
34
+ "raknet"
35
+ ],
36
+ "author": "JSPrismarine",
37
+ "license": "MIT",
38
+ "homepage": "https://github.com/JSPrismarine/JSPrismarine/tree/master/packages/client",
39
+ "devDependencies": {
40
+ "@types/node": "20.11.30",
41
+ "glob": "10.3.10",
42
+ "typescript": "5.4.3",
43
+ "vite": "5.2.3",
44
+ "vitest": "1.4.0"
45
+ },
46
+ "dependencies": {
47
+ "set-interval-async": "3.0.3",
48
+ "@jsprismarine/prismarine": "0.1.0",
49
+ "@jsprismarine/raknet": "0.1.0"
50
+ },
51
+ "scripts": {
52
+ "build": "vite build",
53
+ "typecheck": "tsc -noEmit"
54
+ }
55
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../src/Client.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAsB,WAAW,EAAY,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAc,EAAE,KAAK,MAAM,EAAE,MAAM,OAAO,CAAC;AAK3C,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAoBtC,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,YAAY;IAC5C,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAS;;IAQ7B;;OAEG;IACU,OAAO,CAAC,OAAO,SAAY,EAAE,IAAI,SAAQ;YA6CxC,MAAM;IAyBb,qBAAqB,CAAC,MAAM,EAAE,MAAM;IAuBpC,0BAA0B,CAAC,MAAM,EAAE,MAAM;IAoCzC,0BAA0B,CAAC,MAAM,EAAE,MAAM;IA2BhD;;;;;;OAMG;IACU,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,SAAS,IAAI,MAAM;IAInB,UAAU,IAAI,WAAW;IAInB,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG7F"}
package/dist/Client.js DELETED
@@ -1,186 +0,0 @@
1
- import { ConnectionPriority, InetAddress, Protocol, RakNetSession } from '@jsprismarine/raknet';
2
- import Dgram from 'dgram';
3
- import { Protocol as JSPProtocol, Logger } from '@jsprismarine/prismarine';
4
- import { clearIntervalAsync, setIntervalAsync } from 'set-interval-async/dynamic';
5
- import Crypto, { randomBytes } from 'crypto';
6
- import { EventEmitter } from 'events';
7
- import { RakNetPriority } from '@jsprismarine/raknet/src/Session.js';
8
- // https://stackoverflow.com/a/1527820/3142553
9
- const getRandomInt = (min, max) => {
10
- min = Math.ceil(min);
11
- max = Math.floor(max);
12
- return Math.floor(Math.random() * (max - min + 1)) + min;
13
- };
14
- // Minecraft related protocol
15
- const PROTOCOL = 10;
16
- // Max net transfer unit
17
- const DEF_MTU_SIZE = 1455;
18
- // Raknet ticks
19
- const RAKNET_TPS = 100;
20
- const RAKNET_TICK_LENGTH = 1 / RAKNET_TPS;
21
- export default class Client extends EventEmitter {
22
- clientGUID = Crypto.randomBytes(8).readBigInt64BE();
23
- logger = new Logger();
24
- address;
25
- targetAddress;
26
- connection = null;
27
- socket = Dgram.createSocket({ type: 'udp4' });
28
- get closed() {
29
- return false;
30
- }
31
- connecting = false;
32
- connected = false;
33
- offlineHandled = false;
34
- loginHandled = false;
35
- constructor() {
36
- super();
37
- this.address = new InetAddress('0.0.0.0', getRandomInt(46000, 49999));
38
- this.socket.bind(this.address.getPort(), this.address.getAddress());
39
- }
40
- /**
41
- * Creates a packet listener on given address and port.
42
- */
43
- async connect(address = '0.0.0.0', port = 19132) {
44
- this.targetAddress = new InetAddress(address, port);
45
- this.socket.on('message', (buffer) => {
46
- void this.handle(buffer);
47
- });
48
- if (this.connection)
49
- throw new Error('Already connected/connecting to server.');
50
- this.logger.info('JSPrismarine client is now attempting to connect...');
51
- const timer = setIntervalAsync(async () => {
52
- if (this.closed) {
53
- await clearIntervalAsync(timer);
54
- return;
55
- }
56
- // Send a client packet to the server
57
- // so the server goes in target mode
58
- // and the login process starts
59
- if (!this.connecting) {
60
- const pk = new Protocol.UnconnectedPing();
61
- pk.timestamp = BigInt(Date.now());
62
- // TODO: can be omitted... pk. = this.clientGUID;
63
- pk.encode();
64
- await this.sendBuffer(pk.getBuffer());
65
- }
66
- if (this.connected && !this.loginHandled) {
67
- const pk = new JSPProtocol.Packets.LoginPacket();
68
- pk.encode();
69
- const sendPk = new Protocol.Frame();
70
- sendPk.reliability = 0;
71
- sendPk.content = pk.getBuffer();
72
- this.connection.sendFrame(sendPk, ConnectionPriority.NORMAL); // Packet needs to be splitted
73
- this.loginHandled = true;
74
- }
75
- this.connection?.update(Date.now());
76
- }, RAKNET_TICK_LENGTH * 1000);
77
- return this;
78
- }
79
- async handle(buffer) {
80
- const header = buffer.readUInt8(); // Read packet header
81
- if (this.connection && this.offlineHandled) {
82
- return this.connection.handle(buffer);
83
- }
84
- let buf;
85
- switch (header) {
86
- case Protocol.MessageIdentifiers.UNCONNECTED_PONG:
87
- buf = this.handleUnconnectedPong(buffer);
88
- await this.sendBuffer(buf);
89
- break;
90
- case Protocol.MessageIdentifiers.OPEN_CONNECTION_REPLY_1:
91
- buf = this.handleOpenConnectionReply1(buffer);
92
- await this.sendBuffer(buf);
93
- break;
94
- case Protocol.MessageIdentifiers.OPEN_CONNECTION_REPLY_2:
95
- this.handleOpenConnectionReply2(buffer);
96
- break;
97
- default:
98
- this.logger.warn(`Unhandled offline packet ID: ${header}`, 'Client/handle');
99
- }
100
- }
101
- handleUnconnectedPong(buffer) {
102
- // Decode server packet
103
- const decodedPacket = new Protocol.UnconnectedPong(buffer);
104
- decodedPacket.decode();
105
- // Check packet validity
106
- // To refactor
107
- if (!decodedPacket.isValid()) {
108
- throw new Error('Received an invalid offline message');
109
- }
110
- // Encode response
111
- const packet = new Protocol.OpenConnectionRequest1();
112
- packet.protocol = PROTOCOL;
113
- packet.mtuSize = DEF_MTU_SIZE;
114
- packet.encode();
115
- // Update session status
116
- // this.status = ConnectionStatus.Targetted;
117
- return packet.getBuffer();
118
- }
119
- handleOpenConnectionReply1(buffer) {
120
- // Decode server packet
121
- const decodedPacket = new Protocol.OpenConnectionReply1(buffer);
122
- decodedPacket.decode();
123
- // Check packet validity
124
- // To refactor
125
- if (!decodedPacket.isValid()) {
126
- throw new Error('Received an invalid offline message');
127
- }
128
- // Encode response
129
- const packet = new Protocol.OpenConnectionRequest2();
130
- packet.serverAddress = this.targetAddress;
131
- packet.mtuSize = DEF_MTU_SIZE;
132
- packet.clientGUID = this.clientGUID;
133
- packet.encode();
134
- // Update session status
135
- this.connecting = true;
136
- // This.status = ConnectionStatus.Connected;
137
- this.connection = new RakNetSession(this, DEF_MTU_SIZE, {
138
- address: this.address.getAddress(),
139
- port: this.address.getPort(),
140
- family: 'IPv4',
141
- size: 0
142
- }, randomBytes(8).readBigInt64BE());
143
- return packet.getBuffer();
144
- }
145
- handleOpenConnectionReply2(buffer) {
146
- // Decode server packet
147
- const decodedPacket = new Protocol.OpenConnectionReply2(buffer);
148
- decodedPacket.decode();
149
- // Check packet validity
150
- // To refactor
151
- if (!decodedPacket.isValid()) {
152
- throw new Error('Received an invalid offline message');
153
- }
154
- // Encode response (encapsulated)
155
- const packet = new Protocol.ConnectionRequest();
156
- packet.clientGUID = this.clientGUID;
157
- packet.requestTimestamp = BigInt(Date.now());
158
- packet.encode();
159
- const sendPacket = new Protocol.Frame();
160
- sendPacket.reliability = 0;
161
- sendPacket.content = packet.getBuffer();
162
- this.connection?.sendFrame(sendPacket, RakNetPriority.NORMAL);
163
- this.offlineHandled = true;
164
- this.connected = true; // Should be... we can't rely on it
165
- }
166
- /**
167
- * Sends the buffer to the server
168
- *
169
- * @param buffer
170
- * @param address
171
- * @param port
172
- */
173
- async sendBuffer(buffer) {
174
- this.socket.send(buffer, 0, buffer.byteLength, this.targetAddress.getPort(), this.targetAddress.getAddress());
175
- }
176
- getSocket() {
177
- return this.socket;
178
- }
179
- getAddress() {
180
- return this.address;
181
- }
182
- async removeConnection(_connection, _reason) {
183
- throw new Error('Method not implemented.');
184
- }
185
- }
186
- //# sourceMappingURL=Client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Client.js","sourceRoot":"","sources":["../src/Client.ts"],"names":[],"mappings":"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"}