baltica 0.1.26 → 0.1.28

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.
@@ -65,4 +65,6 @@ export declare class Client extends Emitter<ClientEvents> {
65
65
  private sendPacket;
66
66
  send(packet: DataPacket | Buffer): void;
67
67
  queue(packet: DataPacket | Buffer): void;
68
+ /** Fully destroy the client and clean up all resources */
69
+ destroy(): void;
68
70
  }
@@ -49,11 +49,18 @@ class Client extends shared_1.Emitter {
49
49
  /** Connect to the server and start sending/receiving packets. */
50
50
  async connect() {
51
51
  // Authenticate first before connecting to raknet
52
- if (this.options.offline) {
53
- await (0, shared_1.createOfflineSession)(this);
52
+ try {
53
+ if (this.options.offline) {
54
+ await (0, shared_1.createOfflineSession)(this);
55
+ }
56
+ else {
57
+ await (0, shared_1.authenticate)(this);
58
+ }
54
59
  }
55
- else {
56
- await (0, shared_1.authenticate)(this);
60
+ catch (error) {
61
+ // Clean up raknet on auth failure to prevent hanging process
62
+ this.destroy();
63
+ throw error;
57
64
  }
58
65
  this.sessionReady = true;
59
66
  await this.raknet.connect();
@@ -230,5 +237,22 @@ class Client extends shared_1.Emitter {
230
237
  raknet_1.Logger.debug(`Queueing packet ${packet instanceof protocol_1.DataPacket ? packet.constructor.name : "Buffer"}`);
231
238
  this.sendPacket(packet, raknet_1.Priority.High);
232
239
  }
240
+ /** Fully destroy the client and clean up all resources */
241
+ destroy() {
242
+ this.cleanup();
243
+ if (this.raknet instanceof worker_1.WorkerClient) {
244
+ this.raknet.dispose();
245
+ }
246
+ else {
247
+ // RaknetClient - call disconnect which should clean up internal timers
248
+ try {
249
+ this.raknet.disconnect();
250
+ }
251
+ catch {
252
+ // Ignore errors during cleanup
253
+ }
254
+ }
255
+ super.destroy();
256
+ }
233
257
  }
234
258
  exports.Client = Client;
@@ -8,6 +8,8 @@ type ClientEvents = {
8
8
  packet: [packet: InstanceType<(typeof Protocol)[PacketNames]>];
9
9
  connect: [];
10
10
  disconnect: [reason?: string];
11
+ error: [error: Error];
12
+ msa: [message: string];
11
13
  } & {
12
14
  [K in `${number}`]: [buffer: Buffer];
13
15
  };
@@ -60,6 +60,8 @@ export type ClientOptions = {
60
60
  /** Proxy Password */
61
61
  password?: string;
62
62
  };
63
+ /** Whether to log the auth messages */
64
+ authLogs: boolean;
63
65
  };
64
66
  /** Default Client Options */
65
67
  export declare const defaultClientOptions: ClientOptions;
@@ -44,6 +44,8 @@ exports.defaultClientOptions = {
44
44
  compressionThreshold: 1,
45
45
  /** Default Value: Zlib */
46
46
  compressionMethod: protocol_1.CompressionMethod.Zlib,
47
- /** Default Value: false */
48
- emitUnknownPackets: false,
47
+ /** Default Value: true */
48
+ emitUnknownPackets: true,
49
+ /** Default Value: true */
50
+ authLogs: true,
49
51
  };
@@ -4,4 +4,5 @@ export type ServerEvents = {
4
4
  connection: [Connection];
5
5
  playerConnect: [Player];
6
6
  disconnect: [string, Player];
7
+ error: [error: Error];
7
8
  };
@@ -52,7 +52,8 @@ async function createOfflineSession(client) {
52
52
  if (!client.options.username) {
53
53
  throw new Error("Must specify a valid username for offline session");
54
54
  }
55
- raknet_1.Logger.info("Creating offline session...");
55
+ if (client.options.authLogs)
56
+ raknet_1.Logger.info("Creating offline session...");
56
57
  const profile = {
57
58
  name: client.options.username,
58
59
  uuid: generateUUID(client.options.username),
@@ -61,10 +62,13 @@ async function createOfflineSession(client) {
61
62
  await setupClientProfile(client, profile, []);
62
63
  await setupClientChains(client, true);
63
64
  client.emit("session");
64
- raknet_1.Logger.info("Offline session created");
65
+ if (client.options.authLogs)
66
+ raknet_1.Logger.info("Offline session created");
65
67
  }
66
68
  catch (error) {
67
- raknet_1.Logger.error(`Error while creating offline session: ${error instanceof Error ? error.message : String(error)}`);
69
+ const err = error instanceof Error ? error : new Error(String(error));
70
+ raknet_1.Logger.error(`Error while creating offline session: ${err.message}`);
71
+ client.emit("error", err);
68
72
  throw error;
69
73
  }
70
74
  }
@@ -84,11 +88,14 @@ async function authenticate(client) {
84
88
  await setupClientProfile(client, profile, chains);
85
89
  await setupClientChains(client);
86
90
  const endTime = Date.now();
87
- raknet_1.Logger.info(`Authentication with Xbox took ${(endTime - startTime) / 1000}s.`);
91
+ if (client.options.authLogs)
92
+ raknet_1.Logger.info(`Authentication with Xbox took ${(endTime - startTime) / 1000}s.`);
88
93
  client.emit("session");
89
94
  }
90
95
  catch (error) {
91
- raknet_1.Logger.error(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
96
+ const err = error instanceof Error ? error : new Error(String(error));
97
+ raknet_1.Logger.error(`Authentication failed: ${err.message}`);
98
+ client.emit("error", err);
92
99
  throw error;
93
100
  }
94
101
  }
@@ -143,14 +150,17 @@ async function authenticateWithEmailPassword(client) {
143
150
  raknet_1.Logger.warn(`Failed to extract pfcd from session token: ${e instanceof Error ? e.message : String(e)}`);
144
151
  }
145
152
  const endTime = Date.now();
146
- raknet_1.Logger.info(`Authentication with Xbox (email/password) took ${(endTime - startTime) / 1000}s.`);
153
+ if (client.options.authLogs)
154
+ raknet_1.Logger.info(`Authentication with Xbox (email/password) took ${(endTime - startTime) / 1000}s.`);
147
155
  setupClientProfile(client, profile, tokens.chains);
148
156
  await setupClientChains(client);
149
157
  client.emit("session");
150
158
  }
151
159
  catch (error) {
152
- raknet_1.Logger.error(`Email/password authentication failed: ${error instanceof Error ? error.message : String(error)}`);
153
- raknet_1.Logger.warn("Make sure you have an xbox profile crated!");
160
+ const err = error instanceof Error ? error : new Error(String(error));
161
+ raknet_1.Logger.error(`Email/password authentication failed: ${err.message}`);
162
+ raknet_1.Logger.warn("Make sure you have an xbox profile created!");
163
+ client.emit("error", err);
154
164
  throw error;
155
165
  }
156
166
  }
@@ -359,7 +369,9 @@ function createAuthflow(client) {
359
369
  flow: "live",
360
370
  deviceType: "Nintendo",
361
371
  }, (res) => {
362
- raknet_1.Logger.info(res.message);
372
+ client.emit("msa", res.message);
373
+ if (client.options.authLogs)
374
+ raknet_1.Logger.info(res.message);
363
375
  });
364
376
  }
365
377
  async function getMinecraftBedrockToken(authflow, client) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "baltica",
3
3
  "description": "Library for Minecraft Bedrock Edition community developers.",
4
- "version": "0.1.26",
4
+ "version": "0.1.28",
5
5
  "minecraft": "1.21.130",
6
6
  "main": "dist/index.js",
7
7
  "license": "MIT",
@@ -22,17 +22,17 @@
22
22
  ],
23
23
  "dependencies": {
24
24
  "@sanctumterra/raknet": "latest",
25
- "@serenityjs/binarystream": "^3.0.10",
25
+ "@serenityjs/binarystream": "^3.1.0",
26
26
  "@serenityjs/protocol": "^0.8.17",
27
27
  "fetch-socks": "^1.3.2",
28
28
  "jose": "^5.10.0",
29
29
  "prismarine-auth": "^2.7.0",
30
- "undici": "^7.19.0",
30
+ "undici": "^7.20.0",
31
31
  "uuid-1345": "^1.0.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@biomejs/biome": "1.9.4",
35
- "@types/node": "^22.19.7",
35
+ "@types/node": "^22.19.9",
36
36
  "@types/pngjs": "^6.0.5",
37
37
  "@types/uuid-1345": "^0.99.25",
38
38
  "pngjs": "^7.0.0",