baltica 0.0.6 → 0.0.8

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.
Files changed (43) hide show
  1. package/dist/bridge/bridge-options.d.ts +1 -1
  2. package/dist/bridge/bridge-player.d.ts +1 -1
  3. package/dist/bridge/bridge.js +14 -9
  4. package/dist/client/client-data.d.ts +5 -5
  5. package/dist/client/client-data.js +69 -53
  6. package/dist/client/client-options.d.ts +32 -5
  7. package/dist/client/client-options.js +15 -2
  8. package/dist/client/client.d.ts +0 -2
  9. package/dist/client/client.js +33 -52
  10. package/dist/client/types/payload.d.ts +1 -0
  11. package/dist/client/types/payload.js +11 -7
  12. package/dist/client/worker/WorkerClient.d.ts +1 -0
  13. package/dist/client/worker/WorkerClient.js +5 -0
  14. package/dist/client/worker/worker.js +3 -0
  15. package/dist/libs/emitter.d.ts +1 -0
  16. package/dist/libs/emitter.js +4 -0
  17. package/dist/network/auth.d.ts +6 -4
  18. package/dist/network/auth.js +62 -21
  19. package/dist/network/packet-compressor.js +1 -0
  20. package/dist/network/packet-encryptor.d.ts +2 -1
  21. package/dist/network/packet-encryptor.js +4 -0
  22. package/dist/network/{client-cache-status.d.ts → packets/client-cache-status.d.ts} +1 -1
  23. package/dist/network/{client-cache-status.js → packets/client-cache-status.js} +4 -4
  24. package/dist/network/packets/index.d.ts +8 -0
  25. package/dist/network/packets/index.js +8 -0
  26. package/dist/network/packets/motion-predict-hints.d.ts +6 -0
  27. package/dist/network/packets/motion-predict-hints.js +33 -0
  28. package/dist/network/packets/set-default-gamemode.d.ts +4 -0
  29. package/dist/network/packets/set-default-gamemode.js +25 -0
  30. package/dist/network/packets/set-last-hurt-by.d.ts +4 -0
  31. package/dist/network/packets/set-last-hurt-by.js +25 -0
  32. package/dist/network/packets/update-block-sync.d.ts +9 -0
  33. package/dist/network/packets/update-block-sync.js +45 -0
  34. package/dist/network/packets/update-player-game-type.d.ts +6 -0
  35. package/dist/network/packets/update-player-game-type.js +33 -0
  36. package/dist/network/packets/update-subchunk-blocks.d.ts +25 -0
  37. package/dist/network/packets/update-subchunk-blocks.js +83 -0
  38. package/dist/server/player.js +46 -14
  39. package/dist/server/server-options.d.ts +2 -2
  40. package/dist/server/server-options.js +1 -1
  41. package/package.json +4 -5
  42. /package/dist/network/{level-chunk-packet.d.ts → packets/level-chunk-packet.d.ts} +0 -0
  43. /package/dist/network/{level-chunk-packet.js → packets/level-chunk-packet.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  import type * as Protocol from "@serenityjs/protocol";
2
2
  import type { PacketNames } from "../client";
3
- import type { ClientCacheStatusPacket } from "../network/client-cache-status";
3
+ import type { ClientCacheStatusPacket } from "../network/packets/client-cache-status";
4
4
  import { type ServerOptions } from "../server/server-options";
5
5
  export type BridgePlayerEvents = {
6
6
  [K in PacketNames as `clientbound-${K}`]: [
@@ -1,4 +1,4 @@
1
- import type { LevelChunkPacket } from "../network/level-chunk-packet";
1
+ import type { LevelChunkPacket } from "../network/packets/level-chunk-packet";
2
2
  import type { Client } from "../client";
3
3
  import { Emitter } from "../libs";
4
4
  import type { Player } from "../server";
@@ -41,8 +41,7 @@ const raknet_1 = require("@sanctumterra/raknet");
41
41
  const protocol_1 = require("@serenityjs/protocol");
42
42
  const Protocol = __importStar(require("@serenityjs/protocol"));
43
43
  const client_1 = require("../client");
44
- const client_cache_status_1 = require("../network/client-cache-status");
45
- const level_chunk_packet_1 = require("../network/level-chunk-packet");
44
+ const level_chunk_packet_1 = require("../network/packets/level-chunk-packet");
46
45
  const server_1 = require("../server");
47
46
  const bridge_options_1 = require("./bridge-options");
48
47
  const bridge_player_1 = require("./bridge-player");
@@ -60,7 +59,7 @@ class Bridge extends server_1.Server {
60
59
  }
61
60
  initializePacketCache() {
62
61
  const CLIENT_CACHE_STATUS_ID = 129;
63
- this.packetClassCache.set(CLIENT_CACHE_STATUS_ID, client_cache_status_1.ClientCacheStatusPacket);
62
+ this.packetClassCache.set(CLIENT_CACHE_STATUS_ID, protocol_1.ClientCacheStatusPacket);
64
63
  const levelChunkId = level_chunk_packet_1.LevelChunkPacket.id;
65
64
  if (levelChunkId !== undefined) {
66
65
  this.packetClassCache.set(levelChunkId, level_chunk_packet_1.LevelChunkPacket);
@@ -105,8 +104,8 @@ class Bridge extends server_1.Server {
105
104
  let newBuffer = this.packetSerializationCache.get(cacheKey);
106
105
  if (!newBuffer) {
107
106
  const packet = new CachedPacketClass(buffer).deserialize();
108
- if (packet instanceof client_cache_status_1.ClientCacheStatusPacket) {
109
- packet.supported = false;
107
+ if (packet instanceof protocol_1.ClientCacheStatusPacket) {
108
+ packet.enabled = false;
110
109
  raknet_1.Logger.warn("Ignoring ClientCacheStatusPacket");
111
110
  return;
112
111
  }
@@ -157,7 +156,7 @@ class Bridge extends server_1.Server {
157
156
  this.clients.set(playerKey, bridgePlayer);
158
157
  this.emit("connect", bridgePlayer);
159
158
  bridgePlayer.player.once("ClientCacheStatusPacket", (packet) => {
160
- bridgePlayer.cacheStatus = packet.supported;
159
+ bridgePlayer.cacheStatus = packet.enabled;
161
160
  });
162
161
  bridgePlayer.player.on("ClientToServerHandshakePacket", () => {
163
162
  this.onLogin(bridgePlayer);
@@ -167,25 +166,31 @@ class Bridge extends server_1.Server {
167
166
  const client = new client_1.Client({
168
167
  host: this.options.destination.host,
169
168
  port: this.options.destination.port,
170
- version: "1.21.50",
169
+ version: this.options.version,
171
170
  tokensFolder: "tokens",
172
171
  viewDistance: 2,
173
172
  worker: true,
174
173
  offline: this.options.offline,
175
174
  });
175
+ console.log(this.options);
176
176
  player.client = client;
177
177
  client.cancelPastLogin = true;
178
178
  client.removeAllListeners("ResourcePackStackPacket");
179
179
  client.removeAllListeners("ResourcePacksInfoPacket");
180
180
  client.removeAllListeners("PlayStatusPacket");
181
181
  client.once("ResourcePacksInfoPacket", () => {
182
- client.send(client_cache_status_1.ClientCacheStatusPacket.create(false));
182
+ const packet = new protocol_1.ClientCacheStatusPacket();
183
+ packet.enabled = false;
184
+ client.send(packet.serialize());
183
185
  });
184
186
  player.once("serverbound-ResourcePackClientResponsePacket", () => {
185
- player.player.send(client_cache_status_1.ClientCacheStatusPacket.create(false));
187
+ const packet = new protocol_1.ClientCacheStatusPacket();
188
+ packet.enabled = false;
189
+ player.player.send(packet.serialize());
186
190
  });
187
191
  client.once("PlayStatusPacket", (packet) => {
188
192
  if (packet.status !== protocol_1.PlayStatus.LoginSuccess) {
193
+ console.log(packet);
189
194
  throw new Error("Login failed");
190
195
  }
191
196
  client.processPacket = (buffer) => {
@@ -1,9 +1,9 @@
1
- import { KeyObject } from "node:crypto";
2
1
  import { LoginPacket } from "@serenityjs/protocol";
3
- import type { Player } from "src/server/player";
4
2
  import type { Client } from "./client";
5
- import { type LoginData } from "./types/login-data";
6
3
  import { type Payload } from "./types/payload";
4
+ import { KeyObject } from "node:crypto";
5
+ import { type LoginData } from "./types/login-data";
6
+ import type { Player } from "../server/player";
7
7
  declare class ClientData {
8
8
  client: Client | Player;
9
9
  /** This Contains a lot of Data for the Login Packet */
@@ -21,8 +21,8 @@ declare class ClientData {
21
21
  createClientUserChain(privateKey: KeyObject): Promise<string>;
22
22
  createSharedSecret(privateKey: KeyObject, publicKey: KeyObject): Buffer;
23
23
  private validateKeys;
24
- static nextUUID(): string;
25
- static generateId(): number;
24
+ static nextUUID(username: string): string;
26
25
  static OnlineId(): string;
26
+ static generateId(): number;
27
27
  }
28
28
  export { ClientData };
@@ -1,13 +1,46 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.ClientData = void 0;
4
- const node_crypto_1 = require("node:crypto");
5
- const raknet_1 = require("@sanctumterra/raknet");
6
37
  const protocol_1 = require("@serenityjs/protocol");
7
- const fast_jwt_1 = require("fast-jwt");
8
38
  const uuid_1345_1 = require("uuid-1345");
9
- const login_data_1 = require("./types/login-data");
10
39
  const payload_1 = require("./types/payload");
40
+ const jose = __importStar(require("jose"));
41
+ const node_crypto_1 = require("node:crypto");
42
+ const login_data_1 = require("./types/login-data");
43
+ const raknet_1 = require("@sanctumterra/raknet");
11
44
  const PUBLIC_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAECRXueJeTDqNRRgJi/vlRufByu/2G0i2Ebt6YMar5QX/R0DIIyrJMcUpruK4QveTfJSTp3Shlq4Gk34cD/4GUWwkv0DVuzeuB+tXija7HBxii03NHDbPAD0AKnLr2wdAp";
12
45
  const algorithm = "ES384";
13
46
  const curve = "secp384r1";
@@ -34,24 +67,25 @@ class ClientData {
34
67
  async createClientChainInternal(mojangKey, offline) {
35
68
  const { clientX509, ecdhKeyPair } = this.loginData;
36
69
  let payload;
37
- let signOptions;
70
+ let header;
38
71
  if (offline) {
39
72
  payload = {
73
+ nbf: Math.floor(Date.now() / 1000),
74
+ randomNonce: Math.floor(Math.random() * 100000),
75
+ iat: Math.floor(Date.now() / 1000),
76
+ exp: Math.floor(Date.now() / 1000) + 3600,
40
77
  extraData: {
41
78
  displayName: this.client.profile.name,
42
79
  identity: this.client.profile.uuid,
43
80
  titleId: "89692877",
44
- XUID: "0",
81
+ XUID: "",
45
82
  },
46
83
  certificateAuthority: true,
47
84
  identityPublicKey: clientX509,
48
85
  };
49
- signOptions = {
50
- algorithm: algorithm,
51
- notBefore: 0,
52
- issuer: "self",
53
- expiresIn: 60 * 60,
54
- header: { alg: algorithm, x5u: clientX509, typ: undefined },
86
+ header = {
87
+ alg: algorithm,
88
+ x5u: clientX509,
55
89
  };
56
90
  }
57
91
  else {
@@ -59,20 +93,15 @@ class ClientData {
59
93
  identityPublicKey: mojangKey || PUBLIC_KEY,
60
94
  certificateAuthority: true,
61
95
  };
62
- signOptions = {
63
- algorithm: algorithm,
64
- header: { alg: algorithm, x5u: clientX509, typ: undefined },
96
+ header = {
97
+ alg: algorithm,
98
+ x5u: clientX509,
65
99
  };
66
100
  }
67
- const privateKeyPem = ecdhKeyPair.privateKey.export({
68
- format: "pem",
69
- type: "pkcs8",
70
- });
71
- const signer = (0, fast_jwt_1.createSigner)({
72
- ...signOptions,
73
- key: privateKeyPem,
74
- });
75
- return signer(payload);
101
+ const privateKey = await jose.importPKCS8(ecdhKeyPair.privateKey.export({ format: "pem", type: "pkcs8" }), algorithm);
102
+ return new jose.SignJWT(payload)
103
+ .setProtectedHeader(header)
104
+ .sign(privateKey);
76
105
  }
77
106
  async createClientUserChain(privateKey) {
78
107
  const { clientX509 } = this.loginData;
@@ -82,28 +111,16 @@ class ClientData {
82
111
  ...customPayload,
83
112
  ServerAddress: `${this.client.options.host}:${this.client.options.port}`,
84
113
  ClientRandomId: Date.now(),
85
- DeviceId: ClientData.nextUUID(),
86
- PlayFabId: ClientData.nextUUID().replace(/-/g, "").slice(0, 16),
87
- SelfSignedId: ClientData.nextUUID(),
114
+ DeviceId: ClientData.nextUUID(this.client.profile?.name),
115
+ PlayFabId: ClientData.nextUUID(this.client.profile?.name)
116
+ .replace(/-/g, "")
117
+ .slice(0, 16),
118
+ SelfSignedId: ClientData.nextUUID(this.client.profile?.name),
88
119
  };
89
- if (privateKey.asymmetricKeyDetails?.namedCurve === "p384")
90
- privateKey.asymmetricKeyDetails.namedCurve = "secp384r1";
91
- // Deno sucks.
92
- // Logger.info('Private Key details:', {
93
- // type: privateKey.type,
94
- // curve: privateKey.asymmetricKeyDetails?.namedCurve
95
- // });
96
- const privateKeyPem = privateKey.export({
97
- format: "pem",
98
- type: "pkcs8",
99
- });
100
- const signer = (0, fast_jwt_1.createSigner)({
101
- algorithm,
102
- header: { alg: algorithm, x5u: clientX509, typ: undefined },
103
- noTimestamp: true,
104
- key: privateKeyPem,
105
- });
106
- return signer(payload);
120
+ const josePrivateKey = await jose.importPKCS8(privateKey.export({ format: "pem", type: "pkcs8" }), algorithm);
121
+ return new jose.SignJWT(payload)
122
+ .setProtectedHeader({ alg: algorithm, x5u: clientX509 })
123
+ .sign(josePrivateKey);
107
124
  }
108
125
  createSharedSecret(privateKey, publicKey) {
109
126
  this.validateKeys(privateKey, publicKey);
@@ -112,8 +129,7 @@ class ClientData {
112
129
  throw new Error("Invalid private key format. Named curve is missing.");
113
130
  }
114
131
  try {
115
- const normalizedCurve = curve === "p384" ? "secp384r1" : curve;
116
- const ecdh = (0, node_crypto_1.createECDH)(normalizedCurve);
132
+ const ecdh = (0, node_crypto_1.createECDH)(curve);
117
133
  const privateKeyJwk = privateKey.export({ format: "jwk" });
118
134
  const publicKeyJwk = publicKey.export({ format: "jwk" });
119
135
  if (!privateKeyJwk.d || !publicKeyJwk.x || !publicKeyJwk.y) {
@@ -142,19 +158,19 @@ class ClientData {
142
158
  throw new Error("Invalid key types. Expected private and public keys.");
143
159
  }
144
160
  }
145
- static nextUUID() {
161
+ static nextUUID(username) {
146
162
  return (0, uuid_1345_1.v3)({
147
163
  namespace: "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
148
- name: Date.now().toString(),
164
+ name: username,
149
165
  });
150
166
  }
151
- static generateId() {
152
- const randomNum = Math.floor(Math.random() * 9000000000000000000) + 1000000000000000000;
153
- return -randomNum;
154
- }
155
167
  static OnlineId() {
156
168
  const randomNum = Math.floor(Math.random() * 9000000000000000000) + 1000000000000000000;
157
169
  return `${randomNum}`;
158
170
  }
171
+ static generateId() {
172
+ const randomNum = Math.floor(Math.random() * 9000000000000000000) + 1000000000000000000;
173
+ return -randomNum;
174
+ }
159
175
  }
160
176
  exports.ClientData = ClientData;
@@ -1,11 +1,13 @@
1
1
  import { CompressionMethod, InputMode } from "@serenityjs/protocol";
2
2
  import type * as Protocol from "@serenityjs/protocol";
3
- import type { ClientCacheStatusPacket } from "../network/client-cache-status";
3
+ import type { ClientCacheStatusPacket } from "../network/packets/client-cache-status";
4
4
  import type { Advertisement } from "@sanctumterra/raknet";
5
- import type { AddPaintingPacket } from "../network/packets";
5
+ import { AddPaintingPacket, UpdateSubchunkBlocksPacket, MotionPredictHintsPacket, SetLastHurtByPacket, SetDefaultGamemodePacket, UpdatePlayerGameTypePacket, UpdateBlockSyncPacket } from "../network/packets";
6
+ import { LevelChunkPacket } from "../network/packets/level-chunk-packet";
6
7
  export declare enum ProtocolList {
7
8
  "1.21.50" = 766,
8
- "1.21.60" = 776
9
+ "1.21.60" = 776,
10
+ "1.21.70" = 786
9
11
  }
10
12
  export declare enum DeviceOS {
11
13
  Undefined = 0,
@@ -55,10 +57,35 @@ type ClientEvents = {
55
57
  [K in PacketNames]: [packet: InstanceType<(typeof Protocol)[K]>];
56
58
  } & {
57
59
  session: [];
58
- ClientCacheStatus: [packet: ClientCacheStatusPacket];
59
- AddPaintingPacket: [packet: AddPaintingPacket];
60
+ ClientCacheStatusPacket: [
61
+ packet: InstanceType<typeof ClientCacheStatusPacket>
62
+ ];
63
+ UpdateSubchunkBlocksPacket: [
64
+ packet: InstanceType<typeof UpdateSubchunkBlocksPacket>
65
+ ];
66
+ MotionPredictHintsPacket: [
67
+ packet: InstanceType<typeof MotionPredictHintsPacket>
68
+ ];
69
+ SetLastHurtByPacket: [packet: InstanceType<typeof SetLastHurtByPacket>];
70
+ SetDefaultGamemodePacket: [
71
+ packet: InstanceType<typeof SetDefaultGamemodePacket>
72
+ ];
73
+ UpdatePlayerGameTypePacket: [
74
+ packet: InstanceType<typeof UpdatePlayerGameTypePacket>
75
+ ];
76
+ UpdateBlockSyncPacket: [packet: InstanceType<typeof UpdateBlockSyncPacket>];
60
77
  } & {
61
78
  packet: [packet: InstanceType<(typeof Protocol)[PacketNames]>];
62
79
  connect: [packet: Advertisement];
63
80
  };
64
81
  export { type ClientOptions, defaultClientOptions, type ClientEvents, type PacketNames, };
82
+ export declare const ExtraPackets: {
83
+ 58: typeof LevelChunkPacket;
84
+ 22: typeof AddPaintingPacket;
85
+ 172: typeof UpdateSubchunkBlocksPacket;
86
+ 157: typeof MotionPredictHintsPacket;
87
+ 96: typeof SetLastHurtByPacket;
88
+ 105: typeof SetDefaultGamemodePacket;
89
+ 151: typeof UpdatePlayerGameTypePacket;
90
+ 110: typeof UpdateBlockSyncPacket;
91
+ };
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultClientOptions = exports.DeviceOS = exports.ProtocolList = void 0;
3
+ exports.ExtraPackets = exports.defaultClientOptions = exports.DeviceOS = exports.ProtocolList = void 0;
4
4
  const protocol_1 = require("@serenityjs/protocol");
5
+ const packets_1 = require("../network/packets");
6
+ const level_chunk_packet_1 = require("../network/packets/level-chunk-packet");
5
7
  var ProtocolList;
6
8
  (function (ProtocolList) {
7
9
  ProtocolList[ProtocolList["1.21.50"] = 766] = "1.21.50";
8
10
  ProtocolList[ProtocolList["1.21.60"] = 776] = "1.21.60";
11
+ ProtocolList[ProtocolList["1.21.70"] = 786] = "1.21.70";
9
12
  })(ProtocolList || (exports.ProtocolList = ProtocolList = {}));
10
13
  var DeviceOS;
11
14
  (function (DeviceOS) {
@@ -33,7 +36,7 @@ const defaultClientOptions = {
33
36
  compressionMethod: protocol_1.CompressionMethod.Zlib,
34
37
  compressionLevel: 7,
35
38
  deviceOS: DeviceOS.NintendoSwitch,
36
- version: "1.21.60",
39
+ version: "1.21.70",
37
40
  username: "SanctumTerra",
38
41
  tokensFolder: "tokens",
39
42
  viewDistance: 10,
@@ -48,3 +51,13 @@ const defaultClientOptions = {
48
51
  betaAuth: false,
49
52
  };
50
53
  exports.defaultClientOptions = defaultClientOptions;
54
+ exports.ExtraPackets = {
55
+ [58]: level_chunk_packet_1.LevelChunkPacket,
56
+ [22]: packets_1.AddPaintingPacket,
57
+ [172]: packets_1.UpdateSubchunkBlocksPacket,
58
+ [157]: packets_1.MotionPredictHintsPacket,
59
+ [96]: packets_1.SetLastHurtByPacket,
60
+ [105]: packets_1.SetDefaultGamemodePacket,
61
+ [151]: packets_1.UpdatePlayerGameTypePacket,
62
+ [110]: packets_1.UpdateBlockSyncPacket,
63
+ };
@@ -27,14 +27,12 @@ declare class Client extends Emitter<ClientEvents> {
27
27
  constructor(options: Partial<ClientOptions>);
28
28
  connect(): Promise<[Advertisement, StartGamePacket]>;
29
29
  private handleStartGamePacket;
30
- private handleSetLocalPlayerAsInitializedPacket;
31
30
  private handleEncapsulated;
32
31
  private sendPacket;
33
32
  send(packet: DataPacket | Buffer): void;
34
33
  queue(packet: DataPacket | Buffer): void;
35
34
  /** Already decompressed packets */
36
35
  processPacket(buffer: Buffer): void;
37
- private handleSession;
38
36
  listen(): void;
39
37
  private handlePlayStatusPacket;
40
38
  private handleResourcePacksInfoPacket;
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Client = void 0;
7
4
  const node_crypto_1 = require("node:crypto");
@@ -10,14 +7,11 @@ const raknet_1 = require("@sanctumterra/raknet");
10
7
  const protocol_1 = require("@serenityjs/protocol");
11
8
  const emitter_1 = require("../libs/emitter");
12
9
  const network_1 = require("../network");
13
- const client_cache_status_1 = require("../network/client-cache-status");
14
- const level_chunk_packet_1 = require("../network/level-chunk-packet");
10
+ const client_cache_status_1 = require("../network/packets/client-cache-status");
15
11
  const packet_encryptor_1 = require("../network/packet-encryptor");
16
12
  const client_data_1 = require("./client-data");
17
13
  const client_options_1 = require("./client-options");
18
14
  const worker_1 = require("./worker");
19
- const packets_1 = require("../network/packets");
20
- const disconnect_1 = __importDefault(require("@sanctumterra/raknet/dist/proto/packets/disconnect"));
21
15
  class Client extends emitter_1.Emitter {
22
16
  constructor(options) {
23
17
  super();
@@ -38,7 +32,9 @@ class Client extends emitter_1.Emitter {
38
32
  this._compressionEnabled = false;
39
33
  this.cancelPastLogin = false;
40
34
  this.data = new client_data_1.ClientData(this);
41
- this.once("session", this.handleSession.bind(this));
35
+ this.once("session", () => {
36
+ this.sessionReady = true;
37
+ });
42
38
  this.options.offline ? (0, network_1.createOfflineSession)(this) : (0, network_1.authenticate)(this);
43
39
  }
44
40
  async connect() {
@@ -52,8 +48,9 @@ class Client extends emitter_1.Emitter {
52
48
  this.raknet.on("encapsulated", this.handleEncapsulated.bind(this));
53
49
  return new Promise((resolve, reject) => {
54
50
  this.once("StartGamePacket", this.handleStartGamePacket.bind(this));
55
- this.once("SetLocalPlayerAsInitializedPacket", this.handleSetLocalPlayerAsInitializedPacket.bind(this));
56
- this.once("AvailableCommandsPacket", () => { });
51
+ this.once("SetLocalPlayerAsInitializedPacket", () => {
52
+ this.status = raknet_1.Status.Connected;
53
+ });
57
54
  const interval = setInterval(() => {
58
55
  if (this.status === raknet_1.Status.Connected &&
59
56
  this.startGamePacket &&
@@ -75,9 +72,6 @@ class Client extends emitter_1.Emitter {
75
72
  radius.maxRadius = this.options.viewDistance;
76
73
  this.send(radius);
77
74
  }
78
- handleSetLocalPlayerAsInitializedPacket(packet) {
79
- this.status = raknet_1.Status.Connected;
80
- }
81
75
  handleEncapsulated(buffer) {
82
76
  try {
83
77
  const packets = this.packetCompressor.decompress(buffer);
@@ -115,47 +109,40 @@ class Client extends emitter_1.Emitter {
115
109
  processPacket(buffer) {
116
110
  const id = (0, protocol_1.getPacketId)(buffer);
117
111
  let PacketClass = protocol_1.Packets[id];
112
+ // Logger.info(`Processing packet ${PacketClass.name ?? "unknown"} - ${id}`);
118
113
  try {
119
- if (id === protocol_1.Packet.LevelChunk) {
120
- PacketClass = level_chunk_packet_1.LevelChunkPacket;
121
- }
122
- if (id === 22) {
123
- PacketClass = packets_1.AddPaintingPacket;
124
- }
125
- if (!protocol_1.Packets && !protocol_1.Packets[id])
114
+ // @ts-ignore
115
+ if (id in client_options_1.ExtraPackets)
116
+ PacketClass = client_options_1.ExtraPackets[id];
117
+ if ((!protocol_1.Packets && !protocol_1.Packets[id]) || !PacketClass || !PacketClass.name)
126
118
  return raknet_1.Logger.warn(`Unknown Game packet ${id}`);
127
- // console.log('X - ', PacketClass.name, readPacket(this.options.version, buffer));
128
- let deserializedPacket;
129
119
  const hasSpecificListener = this.hasListeners(PacketClass.name);
130
120
  const hasGenericListener = this.hasListeners("packet");
121
+ let deserializedPacket;
131
122
  if (hasSpecificListener || hasGenericListener) {
132
123
  deserializedPacket = new PacketClass(buffer).deserialize();
133
- if (hasSpecificListener) {
124
+ if (hasSpecificListener)
134
125
  this.emit(PacketClass.name, deserializedPacket);
135
- }
136
- if (hasGenericListener) {
126
+ if (hasGenericListener)
137
127
  this.emit("packet", deserializedPacket);
138
- }
139
128
  }
140
129
  }
141
130
  catch (error) {
142
131
  raknet_1.Logger.error(`Failed to process packet ${PacketClass.name}`, error);
143
132
  }
144
133
  }
145
- handleSession() {
146
- this.sessionReady = true;
147
- }
148
134
  listen() {
149
135
  this.raknet.once("connect", () => {
150
136
  const timer = setInterval(() => {
151
- if (this.sessionReady) {
152
- const request = new protocol_1.RequestNetworkSettingsPacket();
153
- request.protocol = this.protocol;
154
- this.send(request);
155
- clearInterval(timer);
156
- }
137
+ if (!this.sessionReady)
138
+ return;
139
+ const request = new protocol_1.RequestNetworkSettingsPacket();
140
+ request.protocol = this.protocol;
141
+ this.send(request);
142
+ clearInterval(timer);
157
143
  }, 50);
158
144
  });
145
+ this.raknet.on("close", () => this.disconnect());
159
146
  this.once("NetworkSettingsPacket", (packet) => {
160
147
  this._compressionEnabled = true;
161
148
  this.options.compressionMethod = this.packetCompressor.getMethod(packet.compressionMethod);
@@ -186,7 +173,6 @@ class Client extends emitter_1.Emitter {
186
173
  this.send(handshake);
187
174
  });
188
175
  this.once("ResourcePacksInfoPacket", this.handleResourcePacksInfoPacket.bind(this));
189
- // this.once("ResourcePackStackPacket", this.handleResourcePacksInfoPacket.bind(this));
190
176
  this.on("PlayStatusPacket", this.handlePlayStatusPacket.bind(this));
191
177
  }
192
178
  handlePlayStatusPacket(packet) {
@@ -202,6 +188,7 @@ class Client extends emitter_1.Emitter {
202
188
  protocol_1.ServerboundLoadingScreenType.EndLoadingScreen;
203
189
  ServerBoundLoadingScreen.hasScreenId = false;
204
190
  this.send(init);
191
+ this.send(ServerBoundLoadingScreen);
205
192
  this.emit("SetLocalPlayerAsInitializedPacket", init);
206
193
  }
207
194
  }
@@ -212,32 +199,26 @@ class Client extends emitter_1.Emitter {
212
199
  response.packs = [];
213
200
  response.response = protocol_1.ResourcePackResponse.Completed;
214
201
  this.send(response);
215
- if (packet instanceof protocol_1.ResourcePacksInfoPacket) {
202
+ if (packet instanceof protocol_1.ResourcePacksInfoPacket)
216
203
  this.send(client_cache_status_1.ClientCacheStatusPacket.create(false));
217
- }
218
204
  }
219
205
  startEncryption(iv) {
220
206
  this.packetEncryptor = new packet_encryptor_1.PacketEncryptor(this, iv);
221
207
  this._encryptionEnabled = true;
222
208
  }
223
209
  disconnect() {
224
- const rakDisconnect = new disconnect_1.default();
225
- const frame = new raknet_1.Frame();
226
- frame.orderChannel = 0;
227
- frame.payload = rakDisconnect.serialize();
228
- this.raknet.sendFrame(frame, raknet_1.Priority.Immediate);
229
210
  this.status = raknet_1.Status.Disconnected;
230
- this.removeAllListeners();
231
- this.raknet.cleanup();
232
- if (this.raknet instanceof raknet_1.Client) {
233
- this.raknet.removeAll();
234
- this.raknet.removeAllAfter();
235
- this.raknet.removeAllBefore();
211
+ try {
212
+ this.removeAllListeners();
213
+ this.destroy();
214
+ this.raknet.disconnect();
215
+ this.packetEncryptor.destroy();
216
+ this._encryptionEnabled = false;
217
+ raknet_1.Logger.cleanup();
236
218
  }
237
- else {
238
- this.raknet.dispose();
219
+ catch (error) {
220
+ raknet_1.Logger.error("Error during disconnect:", error);
239
221
  }
240
- return;
241
222
  }
242
223
  sendMessage(text) {
243
224
  const textPacket = new protocol_1.TextPacket();
@@ -46,5 +46,6 @@ export type Payload = {
46
46
  ThirdPartyNameOnly: boolean;
47
47
  TrustedSkin: boolean;
48
48
  UIProfile: number;
49
+ GraphicsMode: number;
49
50
  };
50
51
  export declare const createDefaultPayload: (client: Client | Player) => Payload;
@@ -38,7 +38,8 @@ const client_data_1 = require("../client-data");
38
38
  const client_options_1 = require("../client-options");
39
39
  const skin = __importStar(require("./skin/Skin.json"));
40
40
  const createDefaultPayload = (client) => {
41
- return {
41
+ const username = client.profile?.name ?? client.options.username;
42
+ const payload = {
42
43
  AnimatedImageData: skin.skinData.AnimatedImageData,
43
44
  ArmSize: skin.skinData.ArmSize,
44
45
  CapeData: skin.skinData.CapeData,
@@ -50,7 +51,7 @@ const createDefaultPayload = (client) => {
50
51
  CompatibleWithClientSideChunkGen: false,
51
52
  CurrentInputMode: client.options.loginOptions.CurrentInputMode,
52
53
  DefaultInputMode: client.options.loginOptions.DefaultInputMode,
53
- DeviceId: client_data_1.ClientData.nextUUID(),
54
+ DeviceId: client_data_1.ClientData.nextUUID(username),
54
55
  DeviceModel: client.options.loginOptions.DeviceModel,
55
56
  DeviceOS: client.options.deviceOS ?? client_options_1.DeviceOS.NintendoSwitch,
56
57
  GameVersion: client.options?.version,
@@ -63,27 +64,30 @@ const createDefaultPayload = (client) => {
63
64
  PersonaPieces: skin.skinData.PersonaPieces,
64
65
  PersonaSkin: skin.skinData.PersonaSkin,
65
66
  PieceTintColors: skin.skinData.PieceTintColors,
66
- PlatformOfflineId: client_data_1.ClientData.nextUUID().replace(/-/g, ""),
67
+ PlatformOfflineId: client_data_1.ClientData.nextUUID(username).replace(/-/g, ""),
67
68
  PlatformOnlineId: client_data_1.ClientData.OnlineId(),
68
69
  PlatformType: 2,
69
- PlayFabId: client_data_1.ClientData.nextUUID().replace(/-/g, "").slice(0, 16),
70
+ // PlatformUserId: "",
71
+ PlayFabId: client_data_1.ClientData.nextUUID(username).replace(/-/g, "").slice(0, 16),
70
72
  PremiumSkin: skin.skinData.PremiumSkin,
71
- SelfSignedId: client_data_1.ClientData.nextUUID(),
73
+ SelfSignedId: client_data_1.ClientData.nextUUID(username),
72
74
  ServerAddress: `${client.options.host}:${client.options.port}`,
73
75
  SkinAnimationData: skin.skinData.SkinAnimationData,
74
76
  SkinColor: skin.skinData.SkinColor,
75
- SkinGeometryDataEngineVersion: skin.skinData.SkinGeometryDataEngineVersion,
76
77
  SkinData: skin.skinData.SkinData,
77
78
  SkinGeometryData: skin.skinData.SkinGeometryData,
79
+ SkinGeometryDataEngineVersion: skin.skinData.SkinGeometryDataEngineVersion,
78
80
  SkinId: skin.skinData.SkinId,
79
81
  SkinImageHeight: skin.skinData.SkinImageHeight,
80
82
  SkinImageWidth: skin.skinData.SkinImageWidth,
81
83
  SkinResourcePatch: skin.skinData.SkinResourcePatch,
82
- ThirdPartyName: client.profile?.name || "Player",
84
+ ThirdPartyName: username,
83
85
  ThirdPartyNameOnly: false,
84
86
  TrustedSkin: skin.skinData.TrustedSkin,
85
87
  UIProfile: 0,
88
+ GraphicsMode: 0,
86
89
  };
90
+ return payload;
87
91
  };
88
92
  exports.createDefaultPayload = createDefaultPayload;
89
93
  const getRandomId = () => {
@@ -11,6 +11,7 @@ declare class WorkerClient extends Emitter<ClientEvents> {
11
11
  private handleEvents;
12
12
  connect(): Promise<Advertisement>;
13
13
  dispose(): void;
14
+ disconnect(): void;
14
15
  cleanup(): void;
15
16
  frameAndSend(payload: Buffer, priority?: Priority): void;
16
17
  sendFrame(frame: Frame, priority?: Priority): void;