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.
- package/.extra/logo.png +0 -0
- package/README.md +304 -0
- package/dist/client/client-options.d.ts +2 -1
- package/dist/client/client-options.js +2 -1
- package/dist/network/packets/level-chunk-packet.d.ts +6 -13
- package/dist/network/packets/level-chunk-packet.js +17 -25
- package/dist/server/server-options.d.ts +1 -1
- package/dist/server/server-options.js +1 -1
- package/package.json +5 -3
package/.extra/logo.png
ADDED
|
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.
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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.
|
|
20
|
-
if (this.
|
|
21
|
-
this.writeUint16(this.
|
|
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.
|
|
24
|
-
if (this.
|
|
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.
|
|
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.
|
|
41
|
-
if (this.
|
|
42
|
-
this.
|
|
43
|
-
if (this.
|
|
44
|
-
this.
|
|
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.
|
|
47
|
-
if (this.
|
|
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
|
-
|
|
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
|
} & {
|
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.
|
|
5
|
-
"minecraft": "1.21.
|
|
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/
|
|
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",
|