baltica 0.1.23 → 0.1.25
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
CHANGED
package/dist/client/client.js
CHANGED
|
@@ -45,20 +45,22 @@ class Client extends shared_1.Emitter {
|
|
|
45
45
|
/** Create ClientData to store and handle auth data */
|
|
46
46
|
this.data = new types_2.ClientData(this);
|
|
47
47
|
this.raknet.on("disconnect", () => this.cleanup());
|
|
48
|
-
this.once("session", () => {
|
|
49
|
-
this.sessionReady = true;
|
|
50
|
-
});
|
|
51
|
-
this.options.offline ? (0, shared_1.createOfflineSession)(this) : (0, shared_1.authenticate)(this);
|
|
52
48
|
}
|
|
53
49
|
/** Connect to the server and start sending/receiving packets. */
|
|
54
50
|
async connect() {
|
|
51
|
+
// Authenticate first before connecting to raknet
|
|
52
|
+
if (this.options.offline) {
|
|
53
|
+
await (0, shared_1.createOfflineSession)(this);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
await (0, shared_1.authenticate)(this);
|
|
57
|
+
}
|
|
58
|
+
this.sessionReady = true;
|
|
55
59
|
await this.raknet.connect();
|
|
56
60
|
this.status = raknet_1.ConnectionStatus.Connecting;
|
|
57
61
|
this.packetCompressor = new shared_1.PacketCompressor(this);
|
|
58
62
|
this.handleGamePackets();
|
|
59
63
|
this.raknet.on("encapsulated", this.handleEncapsulated.bind(this));
|
|
60
|
-
// Wait for authentication to complete before sending network settings request
|
|
61
|
-
await this.waitForSessionReady();
|
|
62
64
|
const request = new protocol_1.RequestNetworkSettingsPacket();
|
|
63
65
|
request.protocol = types_1.ProtocolList[types_1.CurrentVersionConst];
|
|
64
66
|
this.send(request);
|
|
@@ -118,7 +120,6 @@ class Client extends shared_1.Emitter {
|
|
|
118
120
|
this._compressionEnabled = true;
|
|
119
121
|
this.options.compressionMethod = this.packetCompressor.getMethod(packet.compressionMethod);
|
|
120
122
|
this.options.compressionThreshold = packet.compressionThreshold;
|
|
121
|
-
await this.waitForSessionReady();
|
|
122
123
|
const loginPacket = this.data.createLoginPacket();
|
|
123
124
|
this.send(loginPacket);
|
|
124
125
|
});
|
|
@@ -205,11 +206,6 @@ class Client extends shared_1.Emitter {
|
|
|
205
206
|
this.packetEncryptor = new shared_1.PacketEncryptor(this, iv);
|
|
206
207
|
this._encryptionEnabled = true;
|
|
207
208
|
}
|
|
208
|
-
async waitForSessionReady() {
|
|
209
|
-
while (!this.sessionReady) {
|
|
210
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
209
|
/**
|
|
214
210
|
* Sends Packets to the server.
|
|
215
211
|
*
|
|
@@ -231,9 +231,10 @@ async function getMicrosoftAccessToken(email, password, proxiedFetch) {
|
|
|
231
231
|
});
|
|
232
232
|
// Check for access token in redirect
|
|
233
233
|
let location = loginResp.headers.get("location") || "";
|
|
234
|
+
const allCookies = `${cookies}; ${extractCookies(loginResp.headers)}`;
|
|
234
235
|
// Follow redirects manually to find the access token
|
|
235
236
|
let attempts = 0;
|
|
236
|
-
while (attempts <
|
|
237
|
+
while (attempts < 10 && !location.includes("access_token=")) {
|
|
237
238
|
if (!location) {
|
|
238
239
|
// Check if we got an error page
|
|
239
240
|
const responseText = await loginResp.text();
|
|
@@ -245,12 +246,28 @@ async function getMicrosoftAccessToken(email, password, proxiedFetch) {
|
|
|
245
246
|
responseText.includes("idA_PWD_SwitchToCredPicker")) {
|
|
246
247
|
throw new Error("2FA is enabled on this account. Direct login requires 2FA to be disabled.");
|
|
247
248
|
}
|
|
249
|
+
if (responseText.includes("identity/confirm")) {
|
|
250
|
+
throw new Error("Microsoft requires identity confirmation. Please log in via browser first.");
|
|
251
|
+
}
|
|
252
|
+
if (responseText.includes("recover?") ||
|
|
253
|
+
responseText.includes("account.live.com/recover")) {
|
|
254
|
+
throw new Error("Microsoft requires account recovery. Please verify your account via browser.");
|
|
255
|
+
}
|
|
248
256
|
// Try to extract access token from response body (some flows embed it)
|
|
249
257
|
const tokenMatch = responseText.match(/access_token=([^&"']+)/);
|
|
250
258
|
if (tokenMatch) {
|
|
251
259
|
return decodeURIComponent(tokenMatch[1]);
|
|
252
260
|
}
|
|
253
|
-
|
|
261
|
+
// Check for urlPost redirect in response (sometimes login returns another form)
|
|
262
|
+
const urlPostMatch = responseText.match(/urlPost:\s*'([^']+)'/);
|
|
263
|
+
if (urlPostMatch) {
|
|
264
|
+
location = urlPostMatch[1];
|
|
265
|
+
attempts++;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
throw new Error("Failed to get redirect URL from login response. " +
|
|
269
|
+
"This can happen due to rate limiting, CAPTCHA, or security challenges. " +
|
|
270
|
+
"Try again in a few minutes or log in via browser first.");
|
|
254
271
|
}
|
|
255
272
|
if (location.includes("access_token=")) {
|
|
256
273
|
break;
|
|
@@ -258,11 +275,20 @@ async function getMicrosoftAccessToken(email, password, proxiedFetch) {
|
|
|
258
275
|
const redirectResp = await proxiedFetch(location, {
|
|
259
276
|
headers: {
|
|
260
277
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
261
|
-
Cookie:
|
|
278
|
+
Cookie: allCookies,
|
|
262
279
|
},
|
|
263
280
|
redirect: "manual",
|
|
264
281
|
});
|
|
265
|
-
|
|
282
|
+
// Check response body for token if no redirect
|
|
283
|
+
const newLocation = redirectResp.headers.get("location") || "";
|
|
284
|
+
if (!newLocation && !newLocation.includes("access_token=")) {
|
|
285
|
+
const body = await redirectResp.text();
|
|
286
|
+
const tokenMatch = body.match(/access_token=([^&"']+)/);
|
|
287
|
+
if (tokenMatch) {
|
|
288
|
+
return decodeURIComponent(tokenMatch[1]);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
location = newLocation;
|
|
266
292
|
attempts++;
|
|
267
293
|
}
|
|
268
294
|
// Extract access token from URL fragment
|
package/dist/shared/auth.js
CHANGED
|
@@ -81,12 +81,11 @@ async function authenticate(client) {
|
|
|
81
81
|
const profile = extractProfile(chains[1]);
|
|
82
82
|
const sessionToken = await getMultiplayerSessionToken(authflow, client);
|
|
83
83
|
client.data.loginToken = sessionToken;
|
|
84
|
+
await setupClientProfile(client, profile, chains);
|
|
85
|
+
await setupClientChains(client);
|
|
84
86
|
const endTime = Date.now();
|
|
85
87
|
raknet_1.Logger.info(`Authentication with Xbox took ${(endTime - startTime) / 1000}s.`);
|
|
86
|
-
|
|
87
|
-
setupClientChains(client).then((value) => {
|
|
88
|
-
client.emit("session");
|
|
89
|
-
});
|
|
88
|
+
client.emit("session");
|
|
90
89
|
}
|
|
91
90
|
catch (error) {
|
|
92
91
|
raknet_1.Logger.error(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
|
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.
|
|
4
|
+
"version": "0.1.25",
|
|
5
5
|
"minecraft": "1.21.130",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"license": "MIT",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
}
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@sanctumterra/raknet": "^1.4.
|
|
24
|
+
"@sanctumterra/raknet": "^1.4.12",
|
|
25
25
|
"@serenityjs/binarystream": "^3.0.10",
|
|
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.
|
|
30
|
+
"undici": "^7.19.0",
|
|
31
31
|
"uuid-1345": "^1.0.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|