@@ -57,6 +57,9 @@ state_packets!(
57
57
field transaction_id: VarInt =,
58
58
field location: Position =,
59
59
}
60
+ packet SetDifficulty {
61
+ field new_difficulty: u8 =,
62
+ }
60
63
/// TabComplete is sent by the client when the client presses tab in
61
64
/// the chat box.
62
65
packet TabComplete {
@@ -202,6 +205,9 @@ state_packets!(
202
205
packet KeepAliveServerbound_i32 {
203
206
field id: i32 =,
204
207
}
208
+ packet LockDifficulty {
209
+ field locked: bool =,
210
+ }
205
211
/// PlayerPosition is used to update the player's position.
206
212
packet PlayerPosition {
207
213
field x: f64 =,
@@ -370,6 +376,12 @@ state_packets!(
370
376
field slot: i16 =,
371
377
field clicked_item: Option <item:: Stack > =,
372
378
}
379
+ packet UpdateJigsawBlock {
380
+ field location: Position =,
381
+ field attachment_type: String =,
382
+ field target_pool: String =,
383
+ field final_state: String =,
384
+ }
373
385
packet UpdateStructureBlock {
374
386
field location: Position =,
375
387
field action: VarInt =,
@@ -753,6 +765,10 @@ state_packets!(
753
765
packet ServerDifficulty {
754
766
field difficulty: u8 =,
755
767
}
768
+ packet ServerDifficulty_Locked {
769
+ field difficulty: u8 =,
770
+ field locked: bool =,
771
+ }
756
772
/// TabCompleteReply is sent as a reply to a tab completion request.
757
773
/// The matches should be possible completions for the command/chat the
758
774
/// player sent.
@@ -1055,6 +1071,23 @@ state_packets!(
1055
1071
}
1056
1072
/// JoinGame is sent after completing the login process. This
1057
1073
/// sets the initial state for the client.
1074
+ packet JoinGame_i32_ViewDistance {
1075
+ /// The entity id the client will be referenced by
1076
+ field entity_id: i32 =,
1077
+ /// The starting gamemode of the client
1078
+ field gamemode: u8 =,
1079
+ /// The dimension the client is starting in
1080
+ field dimension: i32 =,
1081
+ /// The max number of players on the server
1082
+ field max_players: u8 =,
1083
+ /// The level type of the server
1084
+ field level_type: String =,
1085
+ /// The render distance (2-32)
1086
+ field view_distance: VarInt =,
1087
+ /// Whether the client should reduce the amount of debug
1088
+ /// information it displays in F3 mode
1089
+ field reduced_debug_info: bool =,
1090
+ }
1058
1091
packet JoinGame_i32 {
1059
1092
/// The entity id the client will be referenced by
1060
1093
field entity_id: i32 =,
@@ -1377,6 +1410,15 @@ state_packets!(
1377
1410
packet SetCurrentHotbarSlot {
1378
1411
field slot: u8 =,
1379
1412
}
1413
+ /// UpdateViewPosition is used to determine what chunks should be remain loaded.
1414
+ packet UpdateViewPosition {
1415
+ field chunk_x: VarInt =,
1416
+ field chunk_z: VarInt =,
1417
+ }
1418
+ /// UpdateViewDistance is sent by the integrated server when changing render distance.
1419
+ packet UpdateViewDistance {
1420
+ field view_distance: VarInt =,
1421
+ }
1380
1422
/// ScoreboardDisplay is used to set the display position of a scoreboard.
1381
1423
packet ScoreboardDisplay {
1382
1424
field position: u8 =,
@@ -2396,6 +2438,11 @@ pub enum RecipeData {
2396
2438
experience : f32 ,
2397
2439
cooking_time : VarInt ,
2398
2440
} ,
2441
+ Stonecutting {
2442
+ group : String ,
2443
+ ingredient : RecipeIngredient ,
2444
+ result : Option < item:: Stack > ,
2445
+ } ,
2399
2446
}
2400
2447
2401
2448
impl Default for RecipeData {
@@ -2413,8 +2460,35 @@ pub struct Recipe {
2413
2460
2414
2461
impl Serializable for Recipe {
2415
2462
fn read_from < R : io:: Read > ( buf : & mut R ) -> Result < Self , Error > {
2416
- let id = String :: read_from ( buf) ?;
2417
- let ty = String :: read_from ( buf) ?;
2463
+ let ( id, ty, namespace) = {
2464
+ let a = String :: read_from ( buf) ?;
2465
+ let b = String :: read_from ( buf) ?;
2466
+
2467
+ let protocol_version = unsafe { crate :: protocol:: CURRENT_PROTOCOL_VERSION } ;
2468
+
2469
+ // 1.14+ swaps recipe identifier and type, and adds namespace to type
2470
+ if protocol_version >= 477 {
2471
+ let ty = a;
2472
+ let id = b;
2473
+
2474
+ if let Some ( at) = ty. find ( ':' ) {
2475
+ let ( namespace, ty) = ty. split_at ( at + 1 ) ;
2476
+ let ty: String = ty. into ( ) ;
2477
+ let namespace: String = namespace. into ( ) ;
2478
+ ( id, ty, namespace)
2479
+ } else {
2480
+ ( id, ty, "minecraft:" . to_string ( ) )
2481
+ }
2482
+ } else {
2483
+ let ty = b;
2484
+ let id = a;
2485
+ ( id, ty, "minecraft:" . to_string ( ) )
2486
+ }
2487
+ } ;
2488
+
2489
+ if namespace != "minecraft:" {
2490
+ panic ! ( "unrecognized recipe type namespace: {}" , namespace) ;
2491
+ }
2418
2492
2419
2493
let data =
2420
2494
match ty. as_ref ( ) {
@@ -2473,13 +2547,18 @@ impl Serializable for Recipe {
2473
2547
experience : Serializable :: read_from ( buf) ?,
2474
2548
cooking_time : Serializable :: read_from ( buf) ?,
2475
2549
} ,
2476
- "campfire" => RecipeData :: Campfire {
2550
+ "campfire" | "campfire_cooking" => RecipeData :: Campfire {
2477
2551
group : Serializable :: read_from ( buf) ?,
2478
2552
ingredient : Serializable :: read_from ( buf) ?,
2479
2553
result : Serializable :: read_from ( buf) ?,
2480
2554
experience : Serializable :: read_from ( buf) ?,
2481
2555
cooking_time : Serializable :: read_from ( buf) ?,
2482
2556
} ,
2557
+ "stonecutting" => RecipeData :: Stonecutting {
2558
+ group : Serializable :: read_from ( buf) ?,
2559
+ ingredient : Serializable :: read_from ( buf) ?,
2560
+ result : Serializable :: read_from ( buf) ?,
2561
+ } ,
2483
2562
_ => panic ! ( "unrecognized recipe type: {}" , ty)
2484
2563
} ;
2485
2564
0 commit comments