baltica 0.0.8 → 0.0.9

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.
Binary file
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # Baltica
2
+
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/SanctumTerra/Baltica/master/.extra/logo.png" alt="Baltica Logo" width="200"/>
5
+ </p>
6
+
7
+ Baltica is a high-performance Minecraft Bedrock Edition networking toolkit built with TypeScript. It serves three main purposes:
8
+ 1. A powerful bridge/proxy that can modify, intercept, and manipulate network traffic between Minecraft Bedrock clients and servers
9
+ 2. A robust client library for creating Minecraft Bedrock bots and automated players
10
+ 3. A flexible server implementation for creating custom Minecraft Bedrock servers
11
+
12
+ ## Features
13
+
14
+ - 🚀 High-performance packet handling and forwarding
15
+ - 🤖 Bot creation and automation
16
+ - 🔒 Support for encryption and compression
17
+ - 🎮 Multiple protocol version support (1.21.50 - 1.21.80)
18
+ - 🌐 Customizable packet manipulation
19
+ - 🔄 Packet caching for improved performance
20
+ - 📦 Resource pack handling
21
+ - 🎯 Event-driven architecture
22
+ - 🤝 Multi-client support for running multiple bots
23
+ - 🖥️ Custom server implementation
24
+ - ⚡ Bun runtime support for enhanced performance
25
+
26
+ ## Prerequisites
27
+
28
+ - Node.js (v16 or higher recommended) or Bun runtime
29
+ - TypeScript
30
+ - npm, yarn, or bun
31
+
32
+ ## Installation
33
+
34
+ ### Using Package Manager (Recommended)
35
+
36
+ ```bash
37
+ # Using npm
38
+ npm install baltica
39
+
40
+ # Using yarn
41
+ yarn add baltica
42
+
43
+ # Using bun
44
+ bun add baltica
45
+ ```
46
+
47
+ ### From Source
48
+
49
+ If you want to contribute or modify the source code:
50
+
51
+ 1. Clone the repository:
52
+ ```bash
53
+ git clone https://github.com/yourusername/baltica.git
54
+ cd baltica
55
+ ```
56
+
57
+ 2. Install dependencies:
58
+ ```bash
59
+ # Using npm
60
+ npm install
61
+
62
+ # Using yarn
63
+ yarn install
64
+
65
+ # Using bun
66
+ bun install
67
+ ```
68
+
69
+ 3. Build the project:
70
+ ```bash
71
+ # Using npm
72
+ npm run build
73
+
74
+ # Using yarn
75
+ yarn build
76
+
77
+ # Using bun
78
+ bun run build
79
+ ```
80
+
81
+ ## Quick Start
82
+
83
+ ```typescript
84
+ import { Client, Server, Bridge } from 'baltica';
85
+
86
+ // Create a bot
87
+ const bot = new Client({
88
+ host: 'server-address',
89
+ port: 19132,
90
+ version: '1.21.80',
91
+ username: 'MyBot'
92
+ });
93
+
94
+ // Create a server
95
+ const server = new Server({
96
+ host: '0.0.0.0',
97
+ port: 19132,
98
+ maxPlayers: 20
99
+ });
100
+
101
+ // Create a bridge
102
+ const bridge = new Bridge({
103
+ host: '0.0.0.0',
104
+ port: 19132,
105
+ destination: {
106
+ host: 'target-server.com',
107
+ port: 19132
108
+ }
109
+ });
110
+ ```
111
+
112
+ ## Usage
113
+
114
+ ### Creating a Custom Server
115
+
116
+ ```typescript
117
+ import { Server } from './src/server/server';
118
+
119
+ const server = new Server({
120
+ host: '0.0.0.0',
121
+ port: 19132,
122
+ version: '1.21.80',
123
+ maxPlayers: 20
124
+ });
125
+
126
+ // Handle player connections
127
+ server.on('playerConnect', (player) => {
128
+ console.log(`Player ${player.profile.name} connected!`);
129
+
130
+ // Handle player packets
131
+ player.on('TextPacket', (packet) => {
132
+ // Broadcast chat messages
133
+ if (packet.type === TextPacketType.Chat) {
134
+ server.broadcast(`${player.profile.name}: ${packet.message}`);
135
+ }
136
+ });
137
+ });
138
+
139
+ // Handle disconnections
140
+ server.on('disconnect', (displayName, player) => {
141
+ console.log(`Player ${displayName} disconnected`);
142
+ });
143
+
144
+ server.start();
145
+ ```
146
+
147
+ ### Creating Minecraft Bots
148
+
149
+ ```typescript
150
+ import { Client } from './src/client/client';
151
+
152
+ // Create a basic bot
153
+ const bot = new Client({
154
+ host: 'server-address',
155
+ port: 19132,
156
+ version: '1.21.80',
157
+ username: 'MyBot',
158
+ tokensFolder: 'tokens',
159
+ viewDistance: 10
160
+ });
161
+
162
+ // Connect and handle events
163
+ await bot.connect();
164
+
165
+ // Listen for chat messages
166
+ bot.on('TextPacket', (packet) => {
167
+ if (packet.type === TextPacketType.Chat) {
168
+ console.log(`${packet.source}: ${packet.message}`);
169
+
170
+ // Respond to messages
171
+ if (packet.message.startsWith('!hello')) {
172
+ bot.sendMessage('Hello there!');
173
+ }
174
+ }
175
+ });
176
+
177
+ // Handle player movement
178
+ bot.on('MovePlayerPacket', (packet) => {
179
+ // React to player movements
180
+ console.log(`Player ${packet.runtimeEntityId} moved to ${packet.position}`);
181
+ });
182
+ ```
183
+
184
+ ### Running Multiple Bots
185
+
186
+ ```typescript
187
+ async function createBots(count: number) {
188
+ const bots = [];
189
+
190
+ for (let i = 0; i < count; i++) {
191
+ const bot = new Client({
192
+ host: 'server-address',
193
+ port: 19132,
194
+ version: '1.21.80',
195
+ username: `Bot${i}`,
196
+ tokensFolder: 'tokens',
197
+ viewDistance: 2, // Lower view distance for better performance
198
+ worker: true // Enable worker mode for better performance
199
+ });
200
+
201
+ await bot.connect();
202
+ bots.push(bot);
203
+ }
204
+
205
+ return bots;
206
+ }
207
+
208
+ // Create 5 bots
209
+ const myBots = await createBots(5);
210
+ ```
211
+
212
+ ### Basic Bridge Setup
213
+
214
+ ```typescript
215
+ import { Bridge } from './src/bridge/bridge';
216
+
217
+ const bridge = new Bridge({
218
+ host: '0.0.0.0',
219
+ port: 19132,
220
+ destination: {
221
+ host: 'target-server.com',
222
+ port: 19132
223
+ },
224
+ version: '1.21.80',
225
+ maxPlayers: 20
226
+ });
227
+
228
+ bridge.start();
229
+ ```
230
+
231
+ ## Configuration Options
232
+
233
+ ### Server Options
234
+ - `host`: The IP address to bind the server to
235
+ - `port`: The port to listen on
236
+ - `version`: Minecraft protocol version
237
+ - `maxPlayers`: Maximum number of concurrent players
238
+ - `motd`: Message of the day
239
+
240
+ ### Client/Bot Options
241
+ - `host`: Target server address
242
+ - `port`: Target server port
243
+ - `version`: Protocol version
244
+ - `username`: Bot username
245
+ - `tokensFolder`: Directory for authentication tokens
246
+ - `viewDistance`: Render distance (lower values improve performance)
247
+ - `offline`: Enable offline mode
248
+ - `worker`: Enable worker mode for improved performance with multiple bots
249
+ - `deviceOS`: Device OS to emulate (defaults to Nintendo Switch)
250
+ - `skinData`: Custom skin data for the bot
251
+
252
+ ### Bridge Options
253
+ - `host`: The IP address to bind the bridge server to
254
+ - `port`: The port to listen on
255
+ - `destination`: Target server configuration (host and port)
256
+ - `version`: Minecraft protocol version
257
+ - `maxPlayers`: Maximum number of concurrent players
258
+
259
+ ## Events
260
+
261
+ Baltica uses an event-driven architecture across all its components. Each component (Server, Client/Bot, Bridge) emits events that you can listen to for various game events and packet handling.
262
+
263
+ ```typescript
264
+ // Example of event handling
265
+ client.on('packet', (packet) => {
266
+ // Handle any packet
267
+ });
268
+
269
+ bridge.on('connect', (player) => {
270
+ // Handle player connection
271
+ });
272
+
273
+ server.on('playerConnect', (player) => {
274
+ // Handle new player
275
+ });
276
+ ```
277
+
278
+ For detailed event documentation, please refer to our [API Documentation](https://github.com/SanctumTerra/Baltica/wiki).
279
+
280
+ ## Performance
281
+
282
+ Baltica supports both Node.js and Bun runtimes, with Bun offering significant performance improvements:
283
+ - Faster startup times
284
+ - Lower memory usage
285
+ - Better packet processing performance
286
+ - Improved concurrent connections handling
287
+
288
+ To run with Bun:
289
+ ```bash
290
+ bun run start
291
+ ```
292
+
293
+ ## Contributing
294
+
295
+ Contributions are welcome! Please feel free to submit a Pull Request.
296
+
297
+ ## License
298
+
299
+ This project is licensed under the MIT License - see the LICENSE file for details.
300
+
301
+ ## Acknowledgments
302
+
303
+ - Built with [@serenityjs/protocol](https://github.com/SerenityJS/protocol) for Minecraft protocol implementation
304
+ - Uses [@sanctumterra/raknet](https://github.com/sanctumterra/raknet) for RakNet networking
@@ -7,7 +7,8 @@ import { LevelChunkPacket } from "../network/packets/level-chunk-packet";
7
7
  export declare enum ProtocolList {
8
8
  "1.21.50" = 766,
9
9
  "1.21.60" = 776,
10
- "1.21.70" = 786
10
+ "1.21.70" = 786,
11
+ "1.21.80" = 800
11
12
  }
12
13
  export declare enum DeviceOS {
13
14
  Undefined = 0,
@@ -9,6 +9,7 @@ var ProtocolList;
9
9
  ProtocolList[ProtocolList["1.21.50"] = 766] = "1.21.50";
10
10
  ProtocolList[ProtocolList["1.21.60"] = 776] = "1.21.60";
11
11
  ProtocolList[ProtocolList["1.21.70"] = 786] = "1.21.70";
12
+ ProtocolList[ProtocolList["1.21.80"] = 800] = "1.21.80";
12
13
  })(ProtocolList || (exports.ProtocolList = ProtocolList = {}));
13
14
  var DeviceOS;
14
15
  (function (DeviceOS) {
@@ -36,7 +37,7 @@ const defaultClientOptions = {
36
37
  compressionMethod: protocol_1.CompressionMethod.Zlib,
37
38
  compressionLevel: 7,
38
39
  deviceOS: DeviceOS.NintendoSwitch,
39
- version: "1.21.70",
40
+ version: "1.21.80",
40
41
  username: "SanctumTerra",
41
42
  tokensFolder: "tokens",
42
43
  viewDistance: 10,
@@ -1,23 +1,16 @@
1
+ import type { Buffer } from "node:buffer";
1
2
  import { DataPacket, type DimensionType } from "@serenityjs/protocol";
2
3
  declare class LevelChunkPacket extends DataPacket {
3
4
  private static readonly MAX_BLOB_HASHES;
4
- private static readonly CLIENT_REQUEST_FULL_COLUMN_FAKE_COUNT;
5
- private static readonly CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT;
6
5
  x: number;
7
6
  z: number;
8
7
  dimension: DimensionType;
9
- client_needs_to_request_subchunks: boolean;
10
- client_request_subchunk_limit?: number;
11
- sub_chunk_count: number;
12
- partial_subchunk_count_when_requesting?: number;
13
- subchunk_count_when_requesting?: number;
14
- highest_subchunk_count?: number;
15
- cache_enabled: boolean;
16
- blobs?: Array<bigint>;
17
- payload: Buffer;
8
+ highestSubChunkCount: number;
9
+ subChunkCount: number;
10
+ cacheEnabled: boolean;
11
+ blobs: Array<bigint>;
12
+ data: Buffer;
18
13
  serialize(): Buffer;
19
14
  deserialize(): this;
20
- private writeByteArray;
21
- private readByteArray;
22
15
  }
23
16
  export { LevelChunkPacket };
@@ -8,20 +8,20 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var LevelChunkPacket_1;
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.LevelChunkPacket = void 0;
11
- const protocol_1 = require("@serenityjs/protocol");
12
11
  const raknet_1 = require("@serenityjs/raknet");
12
+ const protocol_1 = require("@serenityjs/protocol");
13
13
  let LevelChunkPacket = LevelChunkPacket_1 = class LevelChunkPacket extends protocol_1.DataPacket {
14
14
  serialize() {
15
15
  this.writeVarInt(protocol_1.Packet.LevelChunk);
16
16
  this.writeZigZag(this.x);
17
17
  this.writeZigZag(this.z);
18
18
  this.writeZigZag(this.dimension);
19
- this.writeVarInt(this.sub_chunk_count);
20
- if (this.sub_chunk_count === -2) {
21
- this.writeUint16(this.highest_subchunk_count ?? 0, 1 /* Endianness.Little */);
19
+ this.writeVarInt(this.subChunkCount);
20
+ if (this.subChunkCount === -2) {
21
+ this.writeUint16(this.highestSubChunkCount ?? 0, 1 /* Endianness.Little */);
22
22
  }
23
- this.writeBool(this.cache_enabled);
24
- if (this.cache_enabled) {
23
+ this.writeBool(this.cacheEnabled);
24
+ if (this.cacheEnabled) {
25
25
  if (!this.blobs)
26
26
  throw new Error("Blobs required when cache_enabled is true");
27
27
  this.writeVarInt(this.blobs.length);
@@ -29,7 +29,8 @@ let LevelChunkPacket = LevelChunkPacket_1 = class LevelChunkPacket extends proto
29
29
  this.writeUint64(hash, 1 /* Endianness.Little */);
30
30
  }
31
31
  }
32
- this.writeByteArray(this.payload);
32
+ this.writeVarInt(this.data.length);
33
+ this.writeBuffer(this.data);
33
34
  return this.getBuffer();
34
35
  }
35
36
  deserialize() {
@@ -37,14 +38,14 @@ let LevelChunkPacket = LevelChunkPacket_1 = class LevelChunkPacket extends proto
37
38
  this.x = this.readZigZag();
38
39
  this.z = this.readZigZag();
39
40
  this.dimension = this.readZigZag();
40
- this.sub_chunk_count = this.readVarInt();
41
- if (this.sub_chunk_count === 4294967294)
42
- this.sub_chunk_count = -2;
43
- if (this.sub_chunk_count === -2) {
44
- this.highest_subchunk_count = this.readUint16(1 /* Endianness.Little */);
41
+ this.subChunkCount = this.readVarInt();
42
+ if (this.subChunkCount === 4294967294)
43
+ this.subChunkCount = -2;
44
+ if (this.subChunkCount === -2) {
45
+ this.highestSubChunkCount = this.readUint16(1 /* Endianness.Little */);
45
46
  }
46
- this.cache_enabled = this.readBool();
47
- if (this.cache_enabled) {
47
+ this.cacheEnabled = this.readBool();
48
+ if (this.cacheEnabled) {
48
49
  const blobCount = this.readVarInt();
49
50
  if (blobCount > LevelChunkPacket_1.MAX_BLOB_HASHES) {
50
51
  throw new Error(`Too many blob hashes: ${blobCount}`);
@@ -54,22 +55,13 @@ let LevelChunkPacket = LevelChunkPacket_1 = class LevelChunkPacket extends proto
54
55
  this.blobs.push(this.readLong(1 /* Endianness.Little */));
55
56
  }
56
57
  }
57
- this.payload = this.readByteArray();
58
+ const dataLength = this.readVarInt();
59
+ this.data = this.readBuffer(dataLength);
58
60
  return this;
59
61
  }
60
- writeByteArray(buffer) {
61
- this.writeVarInt(buffer.length);
62
- this.writeBuffer(buffer);
63
- }
64
- readByteArray() {
65
- const length = this.readVarInt();
66
- return this.readBuffer(length);
67
- }
68
62
  };
69
63
  exports.LevelChunkPacket = LevelChunkPacket;
70
64
  LevelChunkPacket.MAX_BLOB_HASHES = 64;
71
- LevelChunkPacket.CLIENT_REQUEST_FULL_COLUMN_FAKE_COUNT = 0xffffffff;
72
- LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT = 0xfffffffe;
73
65
  exports.LevelChunkPacket = LevelChunkPacket = LevelChunkPacket_1 = __decorate([
74
66
  (0, raknet_1.Proto)(protocol_1.Packet.LevelChunk)
75
67
  ], LevelChunkPacket);
@@ -2,7 +2,7 @@ import { CompressionMethod, type DataPacket } from "@serenityjs/protocol";
2
2
  import type * as Protocol from "@serenityjs/protocol";
3
3
  import type { PacketNames } from "../client";
4
4
  import type { ClientCacheStatusPacket } from "../network/packets/client-cache-status";
5
- type Version = "1.21.50" | "1.21.60" | "1.21.70";
5
+ type Version = "1.21.50" | "1.21.60" | "1.21.70" | "1.21.80";
6
6
  export type PlayerEvents = {
7
7
  [K in PacketNames]: [packet: InstanceType<(typeof Protocol)[K]>];
8
8
  } & {
@@ -6,7 +6,7 @@ exports.defaultServerOptions = {
6
6
  host: "127.0.0.1",
7
7
  port: 19132,
8
8
  offline: true,
9
- version: "1.21.70",
9
+ version: "1.21.80",
10
10
  worker: true,
11
11
  maxPlayers: 100,
12
12
  compressionMethod: protocol_1.CompressionMethod.Zlib,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "baltica",
3
3
  "description": "A MCBE Utility Library",
4
- "version": "0.0.08",
5
- "minecraft": "1.21.70",
4
+ "version": "0.0.09",
5
+ "minecraft": "1.21.80",
6
6
  "type": "commonjs",
7
7
  "main": "dist/index.js",
8
8
  "license": "MIT",
@@ -23,7 +23,9 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@sanctumterra/raknet": "^1.3.77",
26
- "@serenityjs/protocol": "^0.7.0",
26
+ "@serenityjs/binarystream": "^2.7.0",
27
+ "@serenityjs/core": "^0.8.2",
28
+ "@serenityjs/protocol": "0.8.2",
27
29
  "axios": "^1.7.9",
28
30
  "elliptic": "^6.6.1",
29
31
  "jose": "^5.2.3",