bedrock-portal 2.4.0 → 2.6.0

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.
@@ -5,7 +5,7 @@ exports.SessionConfig = {
5
5
  MinecraftTitleID: '896928775',
6
6
  MinecraftSCID: '4fc10100-5f7a-4470-899b-280835760c07',
7
7
  MinecraftTemplateName: 'MinecraftLobby',
8
- MinecraftProtocolVersion: 1001,
8
+ MinecraftProtocolVersion: 2169,
9
9
  };
10
10
  var Joinability;
11
11
  (function (Joinability) {
@@ -11,7 +11,7 @@ export declare const start_game: {
11
11
  x: number;
12
12
  z: number;
13
13
  };
14
- seed: never[];
14
+ seed: bigint;
15
15
  biome_type: number;
16
16
  biome_name: string;
17
17
  dimension: string;
@@ -46,7 +46,7 @@ export declare const start_game: {
46
46
  experiments_previously_used: boolean;
47
47
  bonus_chest: boolean;
48
48
  map_enabled: boolean;
49
- permission_level: number;
49
+ permission_level: string;
50
50
  server_chunk_tick_range: number;
51
51
  has_locked_behavior_pack: boolean;
52
52
  has_locked_resource_pack: boolean;
@@ -66,19 +66,18 @@ export declare const start_game: {
66
66
  button_name: string;
67
67
  link_uri: string;
68
68
  };
69
- is_logging_chat: boolean;
70
- allow_anonymous_block_drops_in_editor_worlds: boolean;
71
- server_editor_connection_policy: number;
72
69
  experimental_gameplay_override: boolean;
73
70
  chat_restriction_level: string;
74
71
  disable_player_interactions: boolean;
72
+ server_editor_connection_policy: number;
73
+ allow_anonymous_block_drops_in_editor_worlds: boolean;
75
74
  level_id: string;
76
75
  world_name: string;
77
76
  premium_world_template_id: string;
78
77
  is_trial: boolean;
79
78
  rewind_history_size: number;
80
79
  server_authoritative_block_breaking: boolean;
81
- current_tick: never[];
80
+ current_tick: bigint;
82
81
  enchantment_seed: number;
83
82
  block_properties: never[];
84
83
  multiplayer_correlation_id: string;
@@ -89,7 +88,7 @@ export declare const start_game: {
89
88
  name: string;
90
89
  value: {};
91
90
  };
92
- block_pallette_checksum: never[];
91
+ block_pallette_checksum: bigint;
93
92
  world_template_id: string;
94
93
  client_side_generation: boolean;
95
94
  block_network_ids_are_hashes: boolean;
@@ -14,7 +14,7 @@ exports.start_game = {
14
14
  x: 0,
15
15
  z: 0,
16
16
  },
17
- seed: [],
17
+ seed: 0n,
18
18
  biome_type: 0,
19
19
  biome_name: 'minecraft:plains',
20
20
  dimension: 'overworld',
@@ -40,8 +40,8 @@ exports.start_game = {
40
40
  has_confirmed_platform_locked_content: false,
41
41
  is_multiplayer: true,
42
42
  broadcast_to_lan: true,
43
- xbox_live_broadcast_mode: 6,
44
- platform_broadcast_mode: 6,
43
+ xbox_live_broadcast_mode: 3,
44
+ platform_broadcast_mode: 3,
45
45
  enable_commands: true,
46
46
  is_texturepacks_required: false,
47
47
  gamerules: [],
@@ -49,7 +49,7 @@ exports.start_game = {
49
49
  experiments_previously_used: false,
50
50
  bonus_chest: false,
51
51
  map_enabled: false,
52
- permission_level: 4,
52
+ permission_level: 'member',
53
53
  server_chunk_tick_range: 4,
54
54
  has_locked_behavior_pack: false,
55
55
  has_locked_resource_pack: false,
@@ -69,30 +69,29 @@ exports.start_game = {
69
69
  button_name: '',
70
70
  link_uri: '',
71
71
  },
72
- is_logging_chat: false,
73
- allow_anonymous_block_drops_in_editor_worlds: false,
74
- server_editor_connection_policy: 1,
75
72
  experimental_gameplay_override: false,
76
73
  chat_restriction_level: 'none',
77
74
  disable_player_interactions: false,
75
+ server_editor_connection_policy: 0,
76
+ allow_anonymous_block_drops_in_editor_worlds: false,
78
77
  level_id: 'Bedrock level',
79
78
  world_name: 'Bedrock level',
80
79
  premium_world_template_id: '00000000-0000-0000-0000-000000000000',
81
80
  is_trial: false,
82
81
  rewind_history_size: 40,
83
82
  server_authoritative_block_breaking: true,
84
- current_tick: [],
83
+ current_tick: 0n,
85
84
  enchantment_seed: 315714801,
86
85
  block_properties: [],
87
86
  multiplayer_correlation_id: '<raknet>b31f-884c-6f27-c0fb',
88
87
  server_authoritative_inventory: true,
89
- engine: '1.26.30',
88
+ engine: '1.26.40',
90
89
  property_data: {
91
90
  type: 'compound',
92
91
  name: '',
93
92
  value: {},
94
93
  },
95
- block_pallette_checksum: [],
94
+ block_pallette_checksum: 0n,
96
95
  world_template_id: '00000000-0000-0000-0000-000000000000',
97
96
  client_side_generation: false,
98
97
  block_network_ids_are_hashes: true,
@@ -10,8 +10,7 @@ exports.default = async (portal, event) => {
10
10
  if (!event.data.ncid)
11
11
  return;
12
12
  portal.emit('rtaEvent', event);
13
- const session = await portal.getSession();
14
- await portal.syncSessionNonces(session);
13
+ const session = await portal.syncSessionNonces();
15
14
  portal.emit('sessionUpdated', session);
16
15
  debug('Received RTA event, session has been updated', session);
17
16
  const sessionMembers = Object.values(session.members).filter(member => member.constants.system.xuid !== portal.host?.profile?.xuid);
package/dist/index.d.ts CHANGED
@@ -138,6 +138,7 @@ export declare class BedrockPortal extends TypedEmitter<PortalEvents> {
138
138
  peers: Map<string, Host>;
139
139
  modules: Map<string, Module>;
140
140
  server: Server;
141
+ private nonceSync;
141
142
  constructor(options?: Partial<Omit<BedrockPortalOptions, 'world'> & {
142
143
  world?: Partial<BedrockPortalOptions['world']>;
143
144
  }>);
@@ -174,8 +175,9 @@ export declare class BedrockPortal extends TypedEmitter<PortalEvents> {
174
175
  * Updates the current session of the BedrockPortal instance with the specified payload.
175
176
  * @param payload The payload to update the session with.
176
177
  */
177
- updateSession(payload: SessionRequest): Promise<void>;
178
- syncSessionNonces(session: RESTSessionResponse): Promise<void>;
178
+ updateSession(payload: SessionRequest): Promise<RESTSessionResponse>;
179
+ syncSessionNonces(): Promise<RESTSessionResponse>;
180
+ private syncSessionNoncesInternal;
179
181
  /**
180
182
  * Enables a module for the BedrockPortal instance.
181
183
  * @see [Modules](https://github.com/LucienHH/bedrock-portal#modules) for a list of available modules or to create your own.
package/dist/index.js CHANGED
@@ -45,6 +45,7 @@ class BedrockPortal extends tiny_typed_emitter_1.TypedEmitter {
45
45
  peers;
46
46
  modules = new Map();
47
47
  server = new bedrock_portal_nethernet_1.Server();
48
+ nonceSync = Promise.resolve();
48
49
  constructor(options = {}) {
49
50
  super();
50
51
  this.options = {
@@ -171,13 +172,19 @@ class BedrockPortal extends tiny_typed_emitter_1.TypedEmitter {
171
172
  * @param payload The payload to update the session with.
172
173
  */
173
174
  async updateSession(payload) {
174
- await this.host.rest.updateSession(this.session.name, payload);
175
+ return await this.host.rest.updateSession(this.session.name, payload);
175
176
  }
176
- async syncSessionNonces(session) {
177
+ async syncSessionNonces() {
178
+ const sync = this.nonceSync.then(() => this.syncSessionNoncesInternal());
179
+ this.nonceSync = sync.then(() => undefined, () => undefined);
180
+ return await sync;
181
+ }
182
+ async syncSessionNoncesInternal() {
177
183
  const hostProfile = this.host.profile;
178
184
  if (!hostProfile) {
179
- return;
185
+ throw new Error('No session owner');
180
186
  }
187
+ const session = await this.getSession();
181
188
  const activeXuids = [...new Set(Object.values(session.members)
182
189
  .map(member => member.constants.system.xuid)
183
190
  .filter(xuid => xuid !== hostProfile.xuid))].sort();
@@ -185,16 +192,17 @@ class BedrockPortal extends tiny_typed_emitter_1.TypedEmitter {
185
192
  const hasChanges = Object.keys(this.session.nonces).length !== activeXuids.length
186
193
  || activeXuids.some(xuid => this.session.nonces[xuid] !== nextNonces[xuid]);
187
194
  if (!hasChanges) {
188
- return;
195
+ return session;
189
196
  }
190
- this.session.nonces = nextNonces;
191
- await this.updateSession({
197
+ const updatedSession = await this.updateSession({
192
198
  properties: {
193
199
  custom: {
194
200
  nonces: nextNonces,
195
201
  },
196
202
  },
197
203
  });
204
+ this.session.nonces = nextNonces;
205
+ return updatedSession;
198
206
  }
199
207
  /**
200
208
  * Enables a module for the BedrockPortal instance.
@@ -219,7 +227,22 @@ class BedrockPortal extends tiny_typed_emitter_1.TypedEmitter {
219
227
  this.modules.set(constructed.name, constructed);
220
228
  }
221
229
  onServerConnection = (client) => {
230
+ let nonceValidated = false;
231
+ client.once('login', () => {
232
+ const xuid = client.profile?.xuid;
233
+ const nonce = client.skinData?.Nonce;
234
+ const expectedNonce = xuid ? this.session.nonces[xuid] : undefined;
235
+ nonceValidated = typeof nonce === 'string' && nonce.length > 0 && nonce === expectedNonce;
236
+ if (!nonceValidated) {
237
+ debug(`Rejected client with invalid session nonce, xuid: ${xuid ?? 'unknown'}`);
238
+ client.disconnect('Server authentication error');
239
+ }
240
+ });
222
241
  client.on('join', () => {
242
+ if (!nonceValidated) {
243
+ client.disconnect('Server authentication error');
244
+ return;
245
+ }
223
246
  client.write('resource_packs_info', {
224
247
  must_accept: false,
225
248
  has_addons: false,
@@ -231,20 +254,37 @@ class BedrockPortal extends tiny_typed_emitter_1.TypedEmitter {
231
254
  },
232
255
  texture_packs: [],
233
256
  });
234
- client.write('resource_pack_stack', {
235
- must_accept: false,
236
- resource_packs: [],
237
- game_version: '*',
238
- experiments: [],
239
- experiments_previously_used: false,
240
- has_editor_packs: false,
241
- });
242
- client.once('resource_pack_client_response', () => {
243
- client.write('start_game', start_game_1.start_game);
244
- client.once('set_player_game_type', () => {
245
- client.write('transfer', { server_address: this.options.ip, port: this.options.port });
257
+ const onResourcePackResponse = (response) => {
258
+ if (response.response_status === 'refused') {
259
+ client.off('resource_pack_client_response', onResourcePackResponse);
260
+ client.disconnect('Resource packs refused');
261
+ return;
262
+ }
263
+ if (response.response_status === 'send_packs' || response.response_status === 'have_all_packs') {
264
+ client.write('resource_pack_stack', {
265
+ must_accept: false,
266
+ resource_packs: [],
267
+ game_version: '*',
268
+ experiments: [],
269
+ experiments_previously_used: false,
270
+ has_editor_packs: false,
271
+ });
272
+ return;
273
+ }
274
+ if (response.response_status !== 'completed')
275
+ return;
276
+ client.off('resource_pack_client_response', onResourcePackResponse);
277
+ client.once('request_chunk_radius', () => {
278
+ client.write('transfer', {
279
+ server_address: this.options.ip,
280
+ port: this.options.port,
281
+ reload_world: false,
282
+ gatherings_configuration: undefined,
283
+ });
246
284
  });
247
- });
285
+ client.write('start_game', start_game_1.start_game);
286
+ };
287
+ client.on('resource_pack_client_response', onResourcePackResponse);
248
288
  });
249
289
  };
250
290
  async createAndPublishSession() {
@@ -56,6 +56,7 @@ export interface RESTSessionResponse {
56
56
  SupportedConnections: SessionConnection[];
57
57
  levelId: string;
58
58
  LanGame: boolean;
59
+ nonces?: Record<string, string>;
59
60
  };
60
61
  };
61
62
  members: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bedrock-portal",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Creates a joinable session in Minecraft Bedrock Edition that can route players to their a specified host",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",