From 49360e53ef070b2ec1fe23823d41eba07319fe00 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sat, 8 Aug 2026 13:44:51 +0200 Subject: [PATCH] chore: clippy enforce `unwrap_used`, `expect_used` and `panic` release is not far --- Cargo.toml | 3 + crates/pumpkin-api-macros/src/lib.rs | 2 + crates/pumpkin-codecs/src/codec/either.rs | 4 +- crates/pumpkin-codecs/src/data_result.rs | 13 +- crates/pumpkin-codecs/src/json_ops.rs | 27 +- crates/pumpkin-codecs/src/lib.rs | 3 + crates/pumpkin-config/src/lib.rs | 107 +- .../pumpkin-config/src/networking/bedrock.rs | 11 +- crates/pumpkin-config/src/networking/java.rs | 11 +- crates/pumpkin-data/src/advancement_data.rs | 6 +- crates/pumpkin-data/src/block_state.rs | 1 - crates/pumpkin-data/src/blocks.rs | 1 - .../src/data_component_impl/basic.rs | 2 +- .../src/data_component_impl/block_entity.rs | 2 +- .../src/data_component_impl/book.rs | 2 +- .../src/data_component_impl/combat.rs | 4 +- .../src/data_component_impl/entity_variant.rs | 2 +- .../src/data_component_impl/food.rs | 4 +- .../src/data_component_impl/mod.rs | 17 +- .../src/data_component_impl/utility.rs | 4 +- .../pumpkin-data/src/generated/advancement.rs | 2 +- crates/pumpkin-data/src/generated/biome.rs | 1 - crates/pumpkin-data/src/generated/block.rs | 3 +- crates/pumpkin-data/src/generated/carver.rs | 3 +- .../src/generated/chunk_gen_settings.rs | 3 - .../pumpkin-data/src/generated/damage_type.rs | 2 +- .../src/generated/data_component.rs | 1 - .../pumpkin-data/src/generated/dimension.rs | 4 +- .../pumpkin-data/src/generated/game_rules.rs | 2 +- crates/pumpkin-data/src/generated/item.rs | 25 +- crates/pumpkin-data/src/generated/potion.rs | 1 - crates/pumpkin-data/src/generated/recipes.rs | 2 +- .../pumpkin-data/src/generated/structures.rs | 4 +- crates/pumpkin-data/src/item_stack/mod.rs | 12 +- crates/pumpkin-data/src/lib.rs | 6 +- .../src/crafting/crafting_screen_handler.rs | 40 +- crates/pumpkin-inventory/src/lib.rs | 3 + .../src/player/player_inventory.rs | 14 +- .../pumpkin-inventory/src/screen_handler.rs | 17 +- .../src/stonecutter_screen_handler.rs | 3 +- crates/pumpkin-macros/src/lib.rs | 2 + crates/pumpkin-nbt/benches/nbt.rs | 2 + crates/pumpkin-nbt/src/lib.rs | 32 +- crates/pumpkin-nbt/src/nbt_ops.rs | 20 +- crates/pumpkin-nbt/src/tag.rs | 5 +- crates/pumpkin-plugin-api/src/commands.rs | 4 +- crates/pumpkin-plugin-api/src/events/mod.rs | 2 + crates/pumpkin-plugin-api/src/forms.rs | 12 +- crates/pumpkin-plugin-api/src/lib.rs | 31 +- crates/pumpkin-plugin-api/src/logging.rs | 6 +- crates/pumpkin-plugin-api/src/scheduler.rs | 10 +- crates/pumpkin-protocol/src/codec/recipe.rs | 4 +- crates/pumpkin-protocol/src/codec/var_int.rs | 1 + crates/pumpkin-protocol/src/codec/var_long.rs | 1 + crates/pumpkin-protocol/src/codec/var_uint.rs | 1 + .../pumpkin-protocol/src/codec/var_ulong.rs | 1 + crates/pumpkin-protocol/src/lib.rs | 3 + .../src/serial/deserializer.rs | 45 +- crates/pumpkin-util/src/jwt/mod.rs | 2 +- crates/pumpkin-util/src/lib.rs | 23 +- crates/pumpkin-util/src/math/int_provider.rs | 4 +- crates/pumpkin-util/src/noise/perlin.rs | 7 +- crates/pumpkin-util/src/noise/simplex.rs | 11 +- crates/pumpkin-util/src/permission.rs | 5 +- crates/pumpkin-util/src/random/mod.rs | 5 +- .../pumpkin-util/src/random/xoroshiro128.rs | 4 +- crates/pumpkin-util/src/translation.rs | 95 +- crates/pumpkin-world/benches/chunk.rs | 2 + crates/pumpkin-world/benches/chunk_gen.rs | 2 + .../benches/chunk_gen_concurrent.rs | 2 + crates/pumpkin-world/benches/chunk_io.rs | 2 + crates/pumpkin-world/benches/noise_router.rs | 2 + crates/pumpkin-world/build.rs | 2 + .../pumpkin-world/src/chunk/format/anvil.rs | 35 +- crates/pumpkin-world/src/chunk/format/mod.rs | 27 +- crates/pumpkin-world/src/chunk/mod.rs | 56 +- crates/pumpkin-world/src/chunk/palette.rs | 14 +- .../pumpkin-world/src/chunk_system/channel.rs | 30 +- .../src/chunk_system/chunk_listener.rs | 20 +- .../src/chunk_system/chunk_loading.rs | 32 +- crates/pumpkin-world/src/chunk_system/dag.rs | 13 +- .../src/chunk_system/generation_cache.rs | 17 +- crates/pumpkin-world/src/chunk_system/mod.rs | 2 + .../src/chunk_system/schedule.rs | 64 +- .../src/chunk_system/worker_logic.rs | 12 +- .../src/generation/block_predicate.rs | 14 +- .../src/generation/block_state_provider.rs | 6 +- .../generation/feature/features/coral/mod.rs | 10 +- .../feature/features/tree/trunk/fancy.rs | 5 +- .../src/generation/feature/placed_features.rs | 23 +- .../generation/generator/structure_finder.rs | 2 +- .../noise/router/chunk_noise_router.rs | 9 +- .../noise/router/density_function/spline.rs | 8 +- .../src/generation/proto_chunk.rs | 33 +- .../src/generation/structure/mod.rs | 23 +- .../structure/structures/mansion/mod.rs | 6 +- .../generation/structure/structures/mod.rs | 7 +- .../pumpkin-world/src/inventory/inventory.rs | 32 +- crates/pumpkin-world/src/level.rs | 49 +- crates/pumpkin-world/src/lib.rs | 1 + crates/pumpkin-world/src/lighting/storage.rs | 10 +- crates/pumpkin-world/src/world_info/anvil.rs | 4 +- .../pumpkin/src/block/blocks/bubble_column.rs | 3 +- crates/pumpkin/src/block/blocks/cake.rs | 4 +- .../pumpkin/src/block/blocks/candle_cakes.rs | 10 +- crates/pumpkin/src/block/blocks/command.rs | 16 +- .../src/block/blocks/coral/coral_block.rs | 14 +- .../src/block/blocks/coral/coral_fan.rs | 27 +- crates/pumpkin/src/block/blocks/fire/mod.rs | 2 +- crates/pumpkin/src/block/blocks/ladder.rs | 9 +- .../pumpkin/src/block/blocks/piston/piston.rs | 9 +- .../blocks/plant/crop/sweet_berry_bush.rs | 10 +- .../block/blocks/redstone/redstone_torch.rs | 6 +- .../block/blocks/redstone/redstone_wire.rs | 18 +- .../src/block/blocks/redstone/tripwire.rs | 6 +- .../src/block/blocks/redstone/turbo.rs | 13 +- crates/pumpkin/src/block/blocks/signs.rs | 2 +- crates/pumpkin/src/block/blocks/torches.rs | 6 +- crates/pumpkin/src/block/entities/barrel.rs | 8 +- .../src/block/entities/brewing_stand.rs | 10 +- .../block/entities/chest_like_block_entity.rs | 17 +- .../src/block/entities/chiseled_bookshelf.rs | 4 +- .../pumpkin/src/block/entities/dispenser.rs | 4 +- crates/pumpkin/src/block/entities/dropper.rs | 4 +- .../entities/furnace_like_block_entity.rs | 36 +- crates/pumpkin/src/block/entities/hopper.rs | 4 +- .../src/block/entities/jigsaw_block.rs | 8 +- crates/pumpkin/src/block/entities/mod.rs | 22 +- crates/pumpkin/src/block/entities/shelf.rs | 4 +- .../pumpkin/src/block/entities/shulker_box.rs | 4 +- crates/pumpkin/src/block/entities/sign.rs | 2 +- .../pumpkin/src/block/fluid/flowing_trait.rs | 7 +- .../src/command/argument_types/attribute.rs | 2 +- .../pumpkin/src/command/commands/attribute.rs | 21 +- crates/pumpkin/src/command/commands/clone.rs | 2 +- .../pumpkin/src/command/commands/forceload.rs | 25 +- crates/pumpkin/src/command/commands/place.rs | 15 +- crates/pumpkin/src/command/commands/plugin.rs | 12 +- .../pumpkin/src/command/commands/plugins.rs | 14 +- .../pumpkin/src/command/commands/pumpkin.rs | 8 +- crates/pumpkin/src/command/mod.rs | 2 + crates/pumpkin/src/crash.rs | 4 +- crates/pumpkin/src/data/advancement_data.rs | 2 +- crates/pumpkin/src/data/banlist_serializer.rs | 8 +- crates/pumpkin/src/data/mod.rs | 47 +- crates/pumpkin/src/data/player_server.rs | 14 +- .../src/entity/ai/goal/avoid_entity.rs | 18 +- crates/pumpkin/src/entity/ai/goal/beg.rs | 6 +- .../src/entity/ai/goal/blaze_attack.rs | 2 +- crates/pumpkin/src/entity/ai/goal/breed.rs | 16 +- .../src/entity/ai/goal/chase_player.rs | 12 +- .../src/entity/ai/goal/creeper_ignite.rs | 6 +- .../pumpkin/src/entity/ai/goal/eat_grass.rs | 6 +- .../src/entity/ai/goal/escape_danger.rs | 12 +- .../src/entity/ai/goal/follow_owner.rs | 29 +- .../src/entity/ai/goal/follow_parent.rs | 6 +- .../pumpkin/src/entity/ai/goal/look_around.rs | 5 +- .../src/entity/ai/goal/look_at_entity.rs | 11 +- .../src/entity/ai/goal/melee_attack.rs | 20 +- .../src/entity/ai/goal/move_to_target_pos.rs | 6 +- .../entity/ai/goal/step_and_destroy_block.rs | 8 +- .../entity/ai/goal/teleport_towards_player.rs | 6 +- crates/pumpkin/src/entity/ai/goal/tempt.rs | 21 +- .../src/entity/ai/goal/wander_around.rs | 12 +- crates/pumpkin/src/entity/attributes.rs | 7 +- .../pumpkin/src/entity/boss/ender_dragon.rs | 5 +- crates/pumpkin/src/entity/boss/wither.rs | 6 +- crates/pumpkin/src/entity/living.rs | 53 +- crates/pumpkin/src/entity/mob/blaze.rs | 12 +- crates/pumpkin/src/entity/mob/breeze.rs | 12 +- crates/pumpkin/src/entity/mob/creaking.rs | 12 +- crates/pumpkin/src/entity/mob/creeper.rs | 12 +- .../pumpkin/src/entity/mob/elder_guardian.rs | 12 +- crates/pumpkin/src/entity/mob/enderman.rs | 24 +- crates/pumpkin/src/entity/mob/endermite.rs | 12 +- crates/pumpkin/src/entity/mob/equipment.rs | 7 +- crates/pumpkin/src/entity/mob/evoker.rs | 12 +- crates/pumpkin/src/entity/mob/ghast.rs | 11 +- crates/pumpkin/src/entity/mob/giant.rs | 12 +- crates/pumpkin/src/entity/mob/guardian.rs | 12 +- crates/pumpkin/src/entity/mob/hoglin.rs | 12 +- crates/pumpkin/src/entity/mob/illusioner.rs | 12 +- crates/pumpkin/src/entity/mob/mod.rs | 63 +- crates/pumpkin/src/entity/mob/phantom.rs | 6 +- crates/pumpkin/src/entity/mob/piglin.rs | 12 +- crates/pumpkin/src/entity/mob/piglin_brute.rs | 12 +- crates/pumpkin/src/entity/mob/pillager.rs | 12 +- crates/pumpkin/src/entity/mob/ravager.rs | 12 +- crates/pumpkin/src/entity/mob/shulker.rs | 12 +- crates/pumpkin/src/entity/mob/silverfish.rs | 12 +- crates/pumpkin/src/entity/mob/skeleton/mod.rs | 12 +- crates/pumpkin/src/entity/mob/slime.rs | 25 +- crates/pumpkin/src/entity/mob/spider.rs | 12 +- crates/pumpkin/src/entity/mob/vex.rs | 12 +- crates/pumpkin/src/entity/mob/vindicator.rs | 12 +- crates/pumpkin/src/entity/mob/warden.rs | 12 +- crates/pumpkin/src/entity/mob/witch.rs | 12 +- crates/pumpkin/src/entity/mob/zoglin.rs | 12 +- .../pumpkin/src/entity/mob/zombie/drowned.rs | 2 +- crates/pumpkin/src/entity/mob/zombie/mod.rs | 12 +- .../src/entity/mob/zombified_piglin.rs | 12 +- crates/pumpkin/src/entity/mod.rs | 127 +- crates/pumpkin/src/entity/passive/allay.rs | 6 +- .../pumpkin/src/entity/passive/armadillo.rs | 6 +- crates/pumpkin/src/entity/passive/axolotl.rs | 6 +- crates/pumpkin/src/entity/passive/bee.rs | 6 +- crates/pumpkin/src/entity/passive/camel.rs | 6 +- crates/pumpkin/src/entity/passive/cat.rs | 6 +- crates/pumpkin/src/entity/passive/chicken.rs | 6 +- crates/pumpkin/src/entity/passive/cod.rs | 6 +- crates/pumpkin/src/entity/passive/cow.rs | 6 +- crates/pumpkin/src/entity/passive/dolphin.rs | 6 +- crates/pumpkin/src/entity/passive/donkey.rs | 6 +- crates/pumpkin/src/entity/passive/fox.rs | 6 +- crates/pumpkin/src/entity/passive/frog.rs | 6 +- .../pumpkin/src/entity/passive/glow_squid.rs | 6 +- crates/pumpkin/src/entity/passive/goat.rs | 6 +- crates/pumpkin/src/entity/passive/horse.rs | 6 +- .../pumpkin/src/entity/passive/iron_golem.rs | 12 +- crates/pumpkin/src/entity/passive/llama.rs | 6 +- .../pumpkin/src/entity/passive/mooshroom.rs | 6 +- crates/pumpkin/src/entity/passive/mule.rs | 6 +- crates/pumpkin/src/entity/passive/ocelot.rs | 6 +- crates/pumpkin/src/entity/passive/panda.rs | 6 +- crates/pumpkin/src/entity/passive/parrot.rs | 6 +- crates/pumpkin/src/entity/passive/pig.rs | 6 +- .../pumpkin/src/entity/passive/polar_bear.rs | 12 +- .../pumpkin/src/entity/passive/pufferfish.rs | 6 +- crates/pumpkin/src/entity/passive/rabbit.rs | 6 +- crates/pumpkin/src/entity/passive/salmon.rs | 6 +- crates/pumpkin/src/entity/passive/sheep.rs | 6 +- .../src/entity/passive/skeleton_horse.rs | 6 +- crates/pumpkin/src/entity/passive/sniffer.rs | 6 +- .../pumpkin/src/entity/passive/snow_golem.rs | 12 +- crates/pumpkin/src/entity/passive/squid.rs | 6 +- crates/pumpkin/src/entity/passive/strider.rs | 6 +- crates/pumpkin/src/entity/passive/tadpole.rs | 6 +- .../src/entity/passive/trader_llama.rs | 6 +- .../src/entity/passive/tropical_fish.rs | 6 +- crates/pumpkin/src/entity/passive/turtle.rs | 6 +- .../src/entity/passive/villager/mod.rs | 80 +- .../src/entity/passive/wandering_trader.rs | 6 +- crates/pumpkin/src/entity/passive/wolf.rs | 6 +- .../src/entity/passive/zombie_horse.rs | 6 +- crates/pumpkin/src/entity/player.rs | 67 +- .../pumpkin/src/entity/player/advancement.rs | 21 +- crates/pumpkin/src/entity/projectile/arrow.rs | 6 +- .../pumpkin/src/entity/projectile/trident.rs | 5 +- crates/pumpkin/src/item/items/bucket.rs | 5 +- crates/pumpkin/src/item/items/ender_eye.rs | 32 +- crates/pumpkin/src/item/items/map.rs | 4 +- crates/pumpkin/src/lib.rs | 91 +- crates/pumpkin/src/logging.rs | 5 +- crates/pumpkin/src/main.rs | 14 +- crates/pumpkin/src/net/authentication.rs | 8 +- crates/pumpkin/src/net/bedrock/mod.rs | 17 +- crates/pumpkin/src/net/bedrock/play.rs | 22 +- crates/pumpkin/src/net/java/config.rs | 3 +- crates/pumpkin/src/net/java/login.rs | 8 +- crates/pumpkin/src/net/java/mod.rs | 28 +- crates/pumpkin/src/net/java/pending.rs | 7 +- crates/pumpkin/src/net/java/play.rs | 5 +- crates/pumpkin/src/net/lan_broadcast.rs | 23 +- crates/pumpkin/src/net/mod.rs | 6 +- crates/pumpkin/src/net/proxy/velocity.rs | 5 +- crates/pumpkin/src/net/query.rs | 34 +- crates/pumpkin/src/net/rcon/mod.rs | 8 +- crates/pumpkin/src/net/rcon/packet.rs | 16 +- crates/pumpkin/src/plugin/api/context.rs | 2 +- crates/pumpkin/src/plugin/cache.rs | 11 +- .../src/plugin/loader/wasm/wasm_host/mod.rs | 2 + .../plugin/loader/wasm/wasm_host/signature.rs | 40 +- .../wasm/wasm_host/wit/v0_1/block_entity.rs | 28 +- .../wasm_host/wit/v0_1/commands/executor.rs | 15 +- .../loader/wasm/wasm_host/wit/v0_1/entity.rs | 64 +- .../wasm/wasm_host/wit/v0_1/events/mod.rs | 23 +- .../loader/wasm/wasm_host/wit/v0_1/forms.rs | 6 +- .../wasm_host/wit/v0_1/generated_packets.rs | 1082 +++++++++-------- .../wasm/wasm_host/wit/v0_1/item_stack.rs | 14 +- .../loader/wasm/wasm_host/wit/v0_1/player.rs | 10 +- .../loader/wasm/wasm_host/wit/v0_1/world.rs | 20 +- crates/pumpkin/src/plugin/mod.rs | 5 +- crates/pumpkin/src/server/connection_cache.rs | 2 +- crates/pumpkin/src/server/key_store.rs | 15 +- crates/pumpkin/src/server/mod.rs | 62 +- crates/pumpkin/src/world/chunker.rs | 7 +- crates/pumpkin/src/world/loot.rs | 13 +- crates/pumpkin/src/world/mod.rs | 62 +- crates/pumpkin/src/world/natural_spawner.rs | 60 +- crates/pumpkin/src/world/portal/nether.rs | 7 +- wepif.yml | 46 + 291 files changed, 3200 insertions(+), 1783 deletions(-) create mode 100644 wepif.yml diff --git a/Cargo.toml b/Cargo.toml index 14a5d9911..484575ba3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,9 @@ print_stderr = "deny" todo = "deny" unreachable = "deny" unimplemented = "deny" +unwrap_used = "deny" +expect_used = "deny" +panic = "deny" # Safety & Soundness undocumented_unsafe_blocks = "deny" diff --git a/crates/pumpkin-api-macros/src/lib.rs b/crates/pumpkin-api-macros/src/lib.rs index 0bc8eb7b6..4883d18f0 100644 --- a/crates/pumpkin-api-macros/src/lib.rs +++ b/crates/pumpkin-api-macros/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used)] + use proc_macro::TokenStream; use proc_macro_error2::{abort, proc_macro_error}; use proc_macro2::Ident; diff --git a/crates/pumpkin-codecs/src/codec/either.rs b/crates/pumpkin-codecs/src/codec/either.rs index 2140a446a..e8c667b7b 100644 --- a/crates/pumpkin-codecs/src/codec/either.rs +++ b/crates/pumpkin-codecs/src/codec/either.rs @@ -67,8 +67,8 @@ impl Decode for Either { DataResult::new_error(format!( "Failed to parse either. First: {}; Second: {}", - left.get_message().unwrap(), - right.get_message().unwrap() + left.get_message().as_deref().unwrap_or("unknown error"), + right.get_message().as_deref().unwrap_or("unknown error") )) } } diff --git a/crates/pumpkin-codecs/src/data_result.rs b/crates/pumpkin-codecs/src/data_result.rs index 197d8bfba..990550bfb 100644 --- a/crates/pumpkin-codecs/src/data_result.rs +++ b/crates/pumpkin-codecs/src/data_result.rs @@ -26,9 +26,10 @@ macro_rules! impl_apply { let result_1 = $self; if !(result_1.is_error() $(|| $result.is_error())+) { // All n results are successful. + #[allow(clippy::expect_used)] return DataResult::new_success($f( - result_1.into_result().unwrap() - $( , $result.into_result().unwrap() )+ + result_1.into_result().expect("checked is_error") + $( , $result.into_result().expect("checked is_error") )+ )); } let mut messages: Vec = vec![]; @@ -231,21 +232,25 @@ impl DataResult { } /// Tries to get a complete result from this `DataResult`. If no such result exists, this function panics. + #[allow(clippy::unwrap_used, clippy::expect_used)] pub fn unwrap(self) -> R { self.expect("No complete result found for DataResult") } /// Tries to get a complete or partial result from this `DataResult`. If no such result exists, this function panics. + #[allow(clippy::unwrap_used, clippy::expect_used)] pub fn unwrap_or_partial(self) -> R { self.expect_or_partial("No complete or partial result found for DataResult") } /// Tries to get a complete result from this `DataResult`. If no such result exists, this function panics with a custom message. + #[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] pub fn expect(self, message: &str) -> R { self.into_result().unwrap_or_else(|| panic!("{}", message)) } /// Tries to get a complete or partial result from this `DataResult`. If no such result exists, this function panics with a custom message. + #[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] pub fn expect_or_partial(self, message: &str) -> R { self.into_result_or_partial() .unwrap_or_else(|| panic!("{}", message)) @@ -614,7 +619,7 @@ macro_rules! assert_success { result ); assert_eq!( - result.unwrap(), + result.into_result().expect("DataResult success"), $right, "`DataResult` was successful but the value doesn't match" ); @@ -632,7 +637,7 @@ macro_rules! assert_encode_success { result ); assert_eq!( - result.unwrap(), + result.into_result().expect("DataResult success"), $right, "`DataResult` was successful but the value doesn't match" ); diff --git a/crates/pumpkin-codecs/src/json_ops.rs b/crates/pumpkin-codecs/src/json_ops.rs index 6f1d2548f..c42bcc5e8 100644 --- a/crates/pumpkin-codecs/src/json_ops.rs +++ b/crates/pumpkin-codecs/src/json_ops.rs @@ -106,9 +106,8 @@ impl DynamicOps for JsonOps { } fn get_string(&self, input: &Self::Value) -> DataResult { - if let Value::String(_) = input { - // Unwrapping is fine as only strings are possible here. - DataResult::new_success(Self::get_as_string(input).unwrap()) + if let Value::String(s) = input { + DataResult::new_success(s.clone()) } else { DataResult::new_error(format!("Not a string: {input}")) } @@ -194,13 +193,14 @@ impl DynamicOps for JsonOps { if !Self::is_valid_key(&key) { return DataResult::new_partial_error(format!("Key is not a string: {key}"), map); } - let mut output_map = Map::new(); if let Value::Object(mut m) = map { output_map.append(&mut m); } - output_map.insert(Self::get_as_string(&key).unwrap(), value); + if let Some(key_str) = Self::get_as_string(&key) { + output_map.insert(key_str, value); + } DataResult::new_success(Value::Object(output_map)) } @@ -225,23 +225,19 @@ impl DynamicOps for JsonOps { let mut missed = vec![]; for entry in other_map_like.iter() { - if Self::is_valid_key(&entry.0) { - output_map.insert(Self::get_as_string(&entry.0).unwrap(), entry.1.clone()); + if let Some(key_str) = Self::get_as_string(&entry.0) { + output_map.insert(key_str, entry.1.clone()); } else { missed.push(entry.0); } } let object = Value::Object(output_map); - let pretty_missed = serde_json::to_string_pretty(&missed); if missed.is_empty() { DataResult::new_success(object) } else { DataResult::new_partial_error( - format!( - "Some keys are not strings{}", - pretty_missed.map_or_else(|_| String::new(), |r| format!(": {r}")) - ), + format!("Some keys are not valid: {missed:?}"), object, ) } @@ -375,10 +371,9 @@ impl StructBuilder for JsonStructBuilder { impl StringStructBuilder for JsonStructBuilder { fn append(&self, key: &str, value: Self::Value, mut builder: Self::Result) -> Self::Result { - builder - .as_object_mut() - .unwrap() - .insert(key.to_string(), value); + if let Some(obj) = builder.as_object_mut() { + obj.insert(key.to_string(), value); + } builder } } diff --git a/crates/pumpkin-codecs/src/lib.rs b/crates/pumpkin-codecs/src/lib.rs index 37f4c8b2d..81a571392 100644 --- a/crates/pumpkin-codecs/src/lib.rs +++ b/crates/pumpkin-codecs/src/lib.rs @@ -1,3 +1,6 @@ +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] + mod data_result; mod dynamic_ops; pub mod json_ops; diff --git a/crates/pumpkin-config/src/lib.rs b/crates/pumpkin-config/src/lib.rs index 5fad1cb2b..1f5d073f0 100644 --- a/crates/pumpkin-config/src/lib.rs +++ b/crates/pumpkin-config/src/lib.rs @@ -1,7 +1,10 @@ //! Configuration management and serialization for the Pumpkin Minecraft server. #![deny(missing_docs)] +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] use fun::FunConfig; + use logging::LoggingConfig; use pumpkin_util::world_seed::Seed; use pumpkin_util::{Difficulty, GameMode, PermissionLvl, random}; @@ -10,7 +13,7 @@ use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::path::PathBuf; use std::{fs, num::NonZeroU8, path::Path}; -use tracing::{debug, warn}; +use tracing::{debug, error, warn}; /// Fun and experimental configuration options. pub mod fun; @@ -84,8 +87,10 @@ impl LoadConfiguration for PumpkinConfig { self.basic.validate(); self.advanced.validate(); - let min_vd = NonZeroU8::new(2).unwrap(); - let max_vd = NonZeroU8::new(64).unwrap(); + let min_vd = NonZeroU8::MIN; + let Some(max_vd) = NonZeroU8::new(64) else { + return; + }; // Validate Java assert!( @@ -257,48 +262,83 @@ pub trait LoadConfiguration { { if !config_dir.exists() { debug!("creating new config root folder"); - fs::create_dir(config_dir).expect("Failed to create config root folder"); + let _ = fs::create_dir(config_dir); } let path = config_dir.join(Self::get_path()); let config = if path.exists() { - let file_content = fs::read_to_string(&path).unwrap_or_else(|_| { - panic!("Couldn't read configuration file at {}", path.display()) - }); + let file_content = match fs::read_to_string(&path) { + Ok(content) => content, + Err(err) => { + error!( + "Couldn't read configuration file at {}: {err}", + path.display() + ); + return Self::default(); + } + }; - let parsed_toml_value: toml::Value = toml::from_str(&file_content) - .unwrap_or_else(|err| { - panic!( - "Couldn't parse TOML at {}. Reason: {}. This is probably caused by invalid TOML syntax", - path.display(), err - ) - }); + let parsed_toml_value: toml::Value = match toml::from_str(&file_content) { + Ok(val) => val, + Err(err) => { + error!( + "Couldn't parse TOML at {}. Reason: {err}. Using default config.", + path.display() + ); + return Self::default(); + } + }; let (merged_config, changed) = Self::merge_with_default_toml(parsed_toml_value); if changed { - println!( - "{} changed because values were missing. The missing values were filled with default values.", - path.file_name().unwrap().display() + let file_name = path.file_name().map_or_else( + || path.display().to_string(), + |f| f.to_string_lossy().into_owned(), ); - if let Err(err) = fs::write(&path, toml::to_string(&merged_config).unwrap()) { - warn!( - "Couldn't write merged config to {}. Reason: {}", - path.display(), - err - ); + println!( + "{file_name} changed because values were missing. The missing values were filled with default values." + ); + match toml::to_string(&merged_config) { + Ok(toml_str) => { + if let Err(err) = fs::write(&path, toml_str) { + warn!( + "Couldn't write merged config to {}. Reason: {}", + path.display(), + err + ); + } + } + Err(err) => { + warn!( + "Couldn't serialize merged config for {}. Reason: {}", + path.display(), + err + ); + } } } merged_config } else { let content = Self::default(); - if let Err(err) = fs::write(&path, toml::to_string(&content).unwrap()) { - warn!( - "Couldn't write default config to {:?}. Reason: {}", - path.display(), - err - ); + match toml::to_string(&content) { + Ok(toml_str) => { + if let Err(err) = fs::write(&path, toml_str) { + warn!( + "Couldn't write default config to {:?}. Reason: {}", + path.display(), + err + ); + } + } + Err(err) => { + warn!( + "Couldn't serialize default config for {:?}. Reason: {}", + path.display(), + err + ); + } } content @@ -318,14 +358,13 @@ pub trait LoadConfiguration { { let default_config = Self::default(); - let default_toml_value = - toml::Value::try_from(default_config).expect("Failed to parse default config"); + let Ok(default_toml_value) = toml::Value::try_from(&default_config) else { + return (default_config, false); + }; let (merged_value, changed) = Self::merge_toml_values(default_toml_value, parsed_toml); - let config = merged_value - .try_into() - .expect("Failed to convert merged config"); + let config = merged_value.try_into().unwrap_or_else(|_| Self::default()); (config, changed) } diff --git a/crates/pumpkin-config/src/networking/bedrock.rs b/crates/pumpkin-config/src/networking/bedrock.rs index 93cb9f4c6..373f4d02e 100644 --- a/crates/pumpkin-config/src/networking/bedrock.rs +++ b/crates/pumpkin-config/src/networking/bedrock.rs @@ -34,9 +34,12 @@ pub struct NetherNetConfig { impl Default for NetherNetConfig { fn default() -> Self { + let address = "0.0.0.0:19132" + .parse() + .unwrap_or_else(|_| std::net::SocketAddr::from(([0, 0, 0, 0], 19132))); Self { enabled: true, - address: "0.0.0.0:19132".parse().unwrap(), + address, identity_key: "nethernet-key.der".into(), stun_servers: Vec::new(), } @@ -80,12 +83,14 @@ pub struct BedrockConfig { impl Default for BedrockConfig { fn default() -> Self { + let view_distance = NonZeroU8::new(16).unwrap_or(NonZeroU8::MIN); + let simulation_distance = NonZeroU8::new(10).unwrap_or(NonZeroU8::MIN); Self { enabled: true, online_mode: true, max_players: 1000, - view_distance: NonZeroU8::new(16).unwrap(), - simulation_distance: NonZeroU8::new(10).unwrap(), + view_distance, + simulation_distance, compression: CompressionConfig::default(), motd: "A blazingly fast Pumpkin server!".to_string(), authentication: BedrockAuthenticationConfig::default(), diff --git a/crates/pumpkin-config/src/networking/java.rs b/crates/pumpkin-config/src/networking/java.rs index 10f45264e..18cb9153b 100644 --- a/crates/pumpkin-config/src/networking/java.rs +++ b/crates/pumpkin-config/src/networking/java.rs @@ -31,14 +31,19 @@ pub struct JavaConfig { impl Default for JavaConfig { fn default() -> Self { + let address = "0.0.0.0:25565" + .parse() + .unwrap_or_else(|_| std::net::SocketAddr::from(([0, 0, 0, 0], 25565))); + let view_distance = NonZeroU8::new(16).unwrap_or(NonZeroU8::MIN); + let simulation_distance = NonZeroU8::new(10).unwrap_or(NonZeroU8::MIN); Self { enabled: true, - address: "0.0.0.0:25565".parse().unwrap(), + address, encryption: true, online_mode: true, max_players: 1000, - view_distance: NonZeroU8::new(16).unwrap(), - simulation_distance: NonZeroU8::new(10).unwrap(), + view_distance, + simulation_distance, compression: CompressionConfig::default(), motd: "A blazingly fast Pumpkin server!".to_string(), authentication: AuthenticationConfig::default(), diff --git a/crates/pumpkin-data/src/advancement_data.rs b/crates/pumpkin-data/src/advancement_data.rs index 4f4259aec..48fb0cd4f 100644 --- a/crates/pumpkin-data/src/advancement_data.rs +++ b/crates/pumpkin-data/src/advancement_data.rs @@ -5,11 +5,9 @@ use crate::translation::java::{ }; use crate::{ADVANCEMENT_TREE, Advancement}; use pumpkin_util::identifier::Identifier; -use pumpkin_util::resource_location::ResourceLocation; use pumpkin_util::text::TextComponent; -use pumpkin_util::text::color::{Color, NamedColor}; -use serde::ser::SerializeStruct; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use pumpkin_util::text::color::NamedColor; +use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::fmt::Display; use std::hash::{Hash, Hasher}; diff --git a/crates/pumpkin-data/src/block_state.rs b/crates/pumpkin-data/src/block_state.rs index a8545d8ba..e8e00a11f 100644 --- a/crates/pumpkin-data/src/block_state.rs +++ b/crates/pumpkin-data/src/block_state.rs @@ -250,7 +250,6 @@ impl Default for BlockStateId { impl std::fmt::Display for BlockStateId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use std::fmt::Write; write!( f, "BlockStateId({} = \"{}\")", diff --git a/crates/pumpkin-data/src/blocks.rs b/crates/pumpkin-data/src/blocks.rs index c52c65388..b4d39bdf1 100644 --- a/crates/pumpkin-data/src/blocks.rs +++ b/crates/pumpkin-data/src/blocks.rs @@ -255,7 +255,6 @@ impl Default for BlockId { impl std::fmt::Display for BlockId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use std::fmt::Write; write!( f, "BlockId({} = \"{}\")", diff --git a/crates/pumpkin-data/src/data_component_impl/basic.rs b/crates/pumpkin-data/src/data_component_impl/basic.rs index 4c86556e2..cfc204e37 100644 --- a/crates/pumpkin-data/src/data_component_impl/basic.rs +++ b/crates/pumpkin-data/src/data_component_impl/basic.rs @@ -1,4 +1,4 @@ -use crate::data_component_impl::{DataComponentImpl, default_impl, get_i32_hash, get_str_hash}; +use crate::data_component_impl::{DataComponentImpl, get_i32_hash, get_str_hash}; use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::tag::NbtTag; use pumpkin_util::text::TextComponent; diff --git a/crates/pumpkin-data/src/data_component_impl/block_entity.rs b/crates/pumpkin-data/src/data_component_impl/block_entity.rs index fa22e331a..e6ede78bd 100644 --- a/crates/pumpkin-data/src/data_component_impl/block_entity.rs +++ b/crates/pumpkin-data/src/data_component_impl/block_entity.rs @@ -1,4 +1,4 @@ -use crate::data_component_impl::{DataComponentImpl, default_impl, get_i32_hash, get_str_hash}; +use crate::data_component_impl::DataComponentImpl; use crc_fast::CrcAlgorithm::Crc32Iscsi; use crc_fast::Digest; use pumpkin_nbt::compound::NbtCompound; diff --git a/crates/pumpkin-data/src/data_component_impl/book.rs b/crates/pumpkin-data/src/data_component_impl/book.rs index a1a54a1f5..caffc9015 100644 --- a/crates/pumpkin-data/src/data_component_impl/book.rs +++ b/crates/pumpkin-data/src/data_component_impl/book.rs @@ -1,4 +1,4 @@ -use crate::data_component_impl::{DataComponentImpl, default_impl}; +use crate::data_component_impl::DataComponentImpl; use pumpkin_nbt::tag::NbtTag; #[derive(Clone, Debug, Hash, PartialEq, Eq)] diff --git a/crates/pumpkin-data/src/data_component_impl/combat.rs b/crates/pumpkin-data/src/data_component_impl/combat.rs index fe8961f80..ea8c2bf05 100644 --- a/crates/pumpkin-data/src/data_component_impl/combat.rs +++ b/crates/pumpkin-data/src/data_component_impl/combat.rs @@ -3,8 +3,8 @@ use crate::Enchantment; use crate::attributes::Attributes; use crate::data_component_impl::basic::SoundEvent; use crate::data_component_impl::{ - DataComponentImpl, EquipmentSlot, IDSet, IDSetContent, IdOr, default_impl, get_f32_hash, - get_i32_hash, get_idor, get_idor_hash, get_idset_hash, get_str_hash, put_idor, + DataComponentImpl, EquipmentSlot, IDSet, IdOr, get_i32_hash, get_idor, get_idor_hash, + get_idset_hash, get_str_hash, put_idor, }; use crate::entity_type::EntityType; use crate::sound::Sound; diff --git a/crates/pumpkin-data/src/data_component_impl/entity_variant.rs b/crates/pumpkin-data/src/data_component_impl/entity_variant.rs index 8337f6eaf..5bc5876f1 100644 --- a/crates/pumpkin-data/src/data_component_impl/entity_variant.rs +++ b/crates/pumpkin-data/src/data_component_impl/entity_variant.rs @@ -1,4 +1,4 @@ -use crate::data_component_impl::{DataComponentImpl, default_impl}; +use crate::data_component_impl::DataComponentImpl; use pumpkin_nbt::tag::NbtTag; use std::borrow::Cow; diff --git a/crates/pumpkin-data/src/data_component_impl/food.rs b/crates/pumpkin-data/src/data_component_impl/food.rs index 1999eb956..033de720e 100644 --- a/crates/pumpkin-data/src/data_component_impl/food.rs +++ b/crates/pumpkin-data/src/data_component_impl/food.rs @@ -1,7 +1,7 @@ use crate::data_component_impl::basic::SoundEvent; use crate::data_component_impl::{ - DataComponentImpl, IDSet, IdOr, default_impl, get_f32_hash, get_i32_hash, get_idor, - get_idor_hash, get_idset_hash, get_str_hash, put_idor, + DataComponentImpl, IDSet, IdOr, get_f32_hash, get_i32_hash, get_idor, get_idor_hash, + get_idset_hash, get_str_hash, put_idor, }; use crate::effect::StatusEffect; use crate::sound::Sound; diff --git a/crates/pumpkin-data/src/data_component_impl/mod.rs b/crates/pumpkin-data/src/data_component_impl/mod.rs index 4c476beea..6b1a59b58 100644 --- a/crates/pumpkin-data/src/data_component_impl/mod.rs +++ b/crates/pumpkin-data/src/data_component_impl/mod.rs @@ -3,7 +3,6 @@ use crate::Block; use crate::BlockId; use crate::data_component::DataComponent; -use crate::effect::StatusEffect; use crate::entity_type::EntityType; use crate::sound::Sound; use crate::tag::Taggable; @@ -52,7 +51,13 @@ pub fn get(value: &dyn DataComponentImpl) -> &T #[inline] pub fn get_mut(value: &mut dyn DataComponentImpl) -> &mut T { - value.as_mut_any().downcast_mut::().unwrap() + let name = value.get_self_enum().to_name(); + value.as_mut_any().downcast_mut::().unwrap_or_else(|| { + panic!( + "you are trying to cast {name} to {}", + T::get_enum().to_name() + ) + }) } macro_rules! default_impl { @@ -85,8 +90,6 @@ macro_rules! default_impl { }; } -pub(crate) use default_impl; - pub fn get_str_hash(val: &str) -> u32 { let mut digest = Digest::new(Crc32Iscsi); digest.update(&[12u8]); @@ -154,9 +157,9 @@ pub fn get_idor(nbt: &NbtCompound, key: &str, default: Sound) -> IdOr = phf::phf_map! { "air" => Block :: AIR , "stone" => Block :: STONE , "granite" => Block :: GRANITE , "polished_granite" => Block :: POLISHED_GRANITE , "diorite" => Block :: DIORITE , "polished_diorite" => Block :: POLISHED_DIORITE , "andesite" => Block :: ANDESITE , "polished_andesite" => Block :: POLISHED_ANDESITE , "grass_block" => Block :: GRASS_BLOCK , "dirt" => Block :: DIRT , "coarse_dirt" => Block :: COARSE_DIRT , "podzol" => Block :: PODZOL , "cobblestone" => Block :: COBBLESTONE , "oak_planks" => Block :: OAK_PLANKS , "spruce_planks" => Block :: SPRUCE_PLANKS , "birch_planks" => Block :: BIRCH_PLANKS , "jungle_planks" => Block :: JUNGLE_PLANKS , "acacia_planks" => Block :: ACACIA_PLANKS , "cherry_planks" => Block :: CHERRY_PLANKS , "dark_oak_planks" => Block :: DARK_OAK_PLANKS , "pale_oak_wood" => Block :: PALE_OAK_WOOD , "pale_oak_planks" => Block :: PALE_OAK_PLANKS , "mangrove_planks" => Block :: MANGROVE_PLANKS , "bamboo_planks" => Block :: BAMBOO_PLANKS , "bamboo_mosaic" => Block :: BAMBOO_MOSAIC , "oak_sapling" => Block :: OAK_SAPLING , "spruce_sapling" => Block :: SPRUCE_SAPLING , "birch_sapling" => Block :: BIRCH_SAPLING , "jungle_sapling" => Block :: JUNGLE_SAPLING , "acacia_sapling" => Block :: ACACIA_SAPLING , "cherry_sapling" => Block :: CHERRY_SAPLING , "dark_oak_sapling" => Block :: DARK_OAK_SAPLING , "pale_oak_sapling" => Block :: PALE_OAK_SAPLING , "mangrove_propagule" => Block :: MANGROVE_PROPAGULE , "bedrock" => Block :: BEDROCK , "water" => Block :: WATER , "lava" => Block :: LAVA , "sand" => Block :: SAND , "suspicious_sand" => Block :: SUSPICIOUS_SAND , "red_sand" => Block :: RED_SAND , "gravel" => Block :: GRAVEL , "suspicious_gravel" => Block :: SUSPICIOUS_GRAVEL , "gold_ore" => Block :: GOLD_ORE , "deepslate_gold_ore" => Block :: DEEPSLATE_GOLD_ORE , "iron_ore" => Block :: IRON_ORE , "deepslate_iron_ore" => Block :: DEEPSLATE_IRON_ORE , "coal_ore" => Block :: COAL_ORE , "deepslate_coal_ore" => Block :: DEEPSLATE_COAL_ORE , "nether_gold_ore" => Block :: NETHER_GOLD_ORE , "oak_log" => Block :: OAK_LOG , "spruce_log" => Block :: SPRUCE_LOG , "birch_log" => Block :: BIRCH_LOG , "jungle_log" => Block :: JUNGLE_LOG , "acacia_log" => Block :: ACACIA_LOG , "cherry_log" => Block :: CHERRY_LOG , "dark_oak_log" => Block :: DARK_OAK_LOG , "pale_oak_log" => Block :: PALE_OAK_LOG , "mangrove_log" => Block :: MANGROVE_LOG , "mangrove_roots" => Block :: MANGROVE_ROOTS , "muddy_mangrove_roots" => Block :: MUDDY_MANGROVE_ROOTS , "bamboo_block" => Block :: BAMBOO_BLOCK , "stripped_spruce_log" => Block :: STRIPPED_SPRUCE_LOG , "stripped_birch_log" => Block :: STRIPPED_BIRCH_LOG , "stripped_jungle_log" => Block :: STRIPPED_JUNGLE_LOG , "stripped_acacia_log" => Block :: STRIPPED_ACACIA_LOG , "stripped_cherry_log" => Block :: STRIPPED_CHERRY_LOG , "stripped_dark_oak_log" => Block :: STRIPPED_DARK_OAK_LOG , "stripped_pale_oak_log" => Block :: STRIPPED_PALE_OAK_LOG , "stripped_oak_log" => Block :: STRIPPED_OAK_LOG , "stripped_mangrove_log" => Block :: STRIPPED_MANGROVE_LOG , "stripped_bamboo_block" => Block :: STRIPPED_BAMBOO_BLOCK , "oak_wood" => Block :: OAK_WOOD , "spruce_wood" => Block :: SPRUCE_WOOD , "birch_wood" => Block :: BIRCH_WOOD , "jungle_wood" => Block :: JUNGLE_WOOD , "acacia_wood" => Block :: ACACIA_WOOD , "cherry_wood" => Block :: CHERRY_WOOD , "dark_oak_wood" => Block :: DARK_OAK_WOOD , "mangrove_wood" => Block :: MANGROVE_WOOD , "stripped_oak_wood" => Block :: STRIPPED_OAK_WOOD , "stripped_spruce_wood" => Block :: STRIPPED_SPRUCE_WOOD , "stripped_birch_wood" => Block :: STRIPPED_BIRCH_WOOD , "stripped_jungle_wood" => Block :: STRIPPED_JUNGLE_WOOD , "stripped_acacia_wood" => Block :: STRIPPED_ACACIA_WOOD , "stripped_cherry_wood" => Block :: STRIPPED_CHERRY_WOOD , "stripped_dark_oak_wood" => Block :: STRIPPED_DARK_OAK_WOOD , "stripped_pale_oak_wood" => Block :: STRIPPED_PALE_OAK_WOOD , "stripped_mangrove_wood" => Block :: STRIPPED_MANGROVE_WOOD , "oak_leaves" => Block :: OAK_LEAVES , "spruce_leaves" => Block :: SPRUCE_LEAVES , "birch_leaves" => Block :: BIRCH_LEAVES , "jungle_leaves" => Block :: JUNGLE_LEAVES , "acacia_leaves" => Block :: ACACIA_LEAVES , "cherry_leaves" => Block :: CHERRY_LEAVES , "dark_oak_leaves" => Block :: DARK_OAK_LEAVES , "pale_oak_leaves" => Block :: PALE_OAK_LEAVES , "mangrove_leaves" => Block :: MANGROVE_LEAVES , "azalea_leaves" => Block :: AZALEA_LEAVES , "flowering_azalea_leaves" => Block :: FLOWERING_AZALEA_LEAVES , "sponge" => Block :: SPONGE , "wet_sponge" => Block :: WET_SPONGE , "glass" => Block :: GLASS , "lapis_ore" => Block :: LAPIS_ORE , "deepslate_lapis_ore" => Block :: DEEPSLATE_LAPIS_ORE , "lapis_block" => Block :: LAPIS_BLOCK , "dispenser" => Block :: DISPENSER , "sandstone" => Block :: SANDSTONE , "chiseled_sandstone" => Block :: CHISELED_SANDSTONE , "cut_sandstone" => Block :: CUT_SANDSTONE , "note_block" => Block :: NOTE_BLOCK , "white_bed" => Block :: WHITE_BED , "orange_bed" => Block :: ORANGE_BED , "magenta_bed" => Block :: MAGENTA_BED , "light_blue_bed" => Block :: LIGHT_BLUE_BED , "yellow_bed" => Block :: YELLOW_BED , "lime_bed" => Block :: LIME_BED , "pink_bed" => Block :: PINK_BED , "gray_bed" => Block :: GRAY_BED , "light_gray_bed" => Block :: LIGHT_GRAY_BED , "cyan_bed" => Block :: CYAN_BED , "purple_bed" => Block :: PURPLE_BED , "blue_bed" => Block :: BLUE_BED , "brown_bed" => Block :: BROWN_BED , "green_bed" => Block :: GREEN_BED , "red_bed" => Block :: RED_BED , "black_bed" => Block :: BLACK_BED , "powered_rail" => Block :: POWERED_RAIL , "detector_rail" => Block :: DETECTOR_RAIL , "sticky_piston" => Block :: STICKY_PISTON , "cobweb" => Block :: COBWEB , "short_grass" => Block :: SHORT_GRASS , "fern" => Block :: FERN , "dead_bush" => Block :: DEAD_BUSH , "bush" => Block :: BUSH , "short_dry_grass" => Block :: SHORT_DRY_GRASS , "tall_dry_grass" => Block :: TALL_DRY_GRASS , "seagrass" => Block :: SEAGRASS , "tall_seagrass" => Block :: TALL_SEAGRASS , "piston" => Block :: PISTON , "piston_head" => Block :: PISTON_HEAD , "white_wool" => Block :: WHITE_WOOL , "orange_wool" => Block :: ORANGE_WOOL , "magenta_wool" => Block :: MAGENTA_WOOL , "light_blue_wool" => Block :: LIGHT_BLUE_WOOL , "yellow_wool" => Block :: YELLOW_WOOL , "lime_wool" => Block :: LIME_WOOL , "pink_wool" => Block :: PINK_WOOL , "gray_wool" => Block :: GRAY_WOOL , "light_gray_wool" => Block :: LIGHT_GRAY_WOOL , "cyan_wool" => Block :: CYAN_WOOL , "purple_wool" => Block :: PURPLE_WOOL , "blue_wool" => Block :: BLUE_WOOL , "brown_wool" => Block :: BROWN_WOOL , "green_wool" => Block :: GREEN_WOOL , "red_wool" => Block :: RED_WOOL , "black_wool" => Block :: BLACK_WOOL , "moving_piston" => Block :: MOVING_PISTON , "dandelion" => Block :: DANDELION , "golden_dandelion" => Block :: GOLDEN_DANDELION , "torchflower" => Block :: TORCHFLOWER , "poppy" => Block :: POPPY , "blue_orchid" => Block :: BLUE_ORCHID , "allium" => Block :: ALLIUM , "azure_bluet" => Block :: AZURE_BLUET , "red_tulip" => Block :: RED_TULIP , "orange_tulip" => Block :: ORANGE_TULIP , "white_tulip" => Block :: WHITE_TULIP , "pink_tulip" => Block :: PINK_TULIP , "oxeye_daisy" => Block :: OXEYE_DAISY , "cornflower" => Block :: CORNFLOWER , "wither_rose" => Block :: WITHER_ROSE , "lily_of_the_valley" => Block :: LILY_OF_THE_VALLEY , "brown_mushroom" => Block :: BROWN_MUSHROOM , "red_mushroom" => Block :: RED_MUSHROOM , "gold_block" => Block :: GOLD_BLOCK , "iron_block" => Block :: IRON_BLOCK , "bricks" => Block :: BRICKS , "tnt" => Block :: TNT , "bookshelf" => Block :: BOOKSHELF , "chiseled_bookshelf" => Block :: CHISELED_BOOKSHELF , "acacia_shelf" => Block :: ACACIA_SHELF , "bamboo_shelf" => Block :: BAMBOO_SHELF , "birch_shelf" => Block :: BIRCH_SHELF , "cherry_shelf" => Block :: CHERRY_SHELF , "crimson_shelf" => Block :: CRIMSON_SHELF , "dark_oak_shelf" => Block :: DARK_OAK_SHELF , "jungle_shelf" => Block :: JUNGLE_SHELF , "mangrove_shelf" => Block :: MANGROVE_SHELF , "oak_shelf" => Block :: OAK_SHELF , "pale_oak_shelf" => Block :: PALE_OAK_SHELF , "spruce_shelf" => Block :: SPRUCE_SHELF , "warped_shelf" => Block :: WARPED_SHELF , "mossy_cobblestone" => Block :: MOSSY_COBBLESTONE , "obsidian" => Block :: OBSIDIAN , "torch" => Block :: TORCH , "wall_torch" => Block :: WALL_TORCH , "fire" => Block :: FIRE , "soul_fire" => Block :: SOUL_FIRE , "spawner" => Block :: SPAWNER , "creaking_heart" => Block :: CREAKING_HEART , "oak_stairs" => Block :: OAK_STAIRS , "chest" => Block :: CHEST , "redstone_wire" => Block :: REDSTONE_WIRE , "diamond_ore" => Block :: DIAMOND_ORE , "deepslate_diamond_ore" => Block :: DEEPSLATE_DIAMOND_ORE , "diamond_block" => Block :: DIAMOND_BLOCK , "crafting_table" => Block :: CRAFTING_TABLE , "wheat" => Block :: WHEAT , "farmland" => Block :: FARMLAND , "furnace" => Block :: FURNACE , "oak_sign" => Block :: OAK_SIGN , "spruce_sign" => Block :: SPRUCE_SIGN , "birch_sign" => Block :: BIRCH_SIGN , "acacia_sign" => Block :: ACACIA_SIGN , "cherry_sign" => Block :: CHERRY_SIGN , "jungle_sign" => Block :: JUNGLE_SIGN , "dark_oak_sign" => Block :: DARK_OAK_SIGN , "pale_oak_sign" => Block :: PALE_OAK_SIGN , "mangrove_sign" => Block :: MANGROVE_SIGN , "bamboo_sign" => Block :: BAMBOO_SIGN , "oak_door" => Block :: OAK_DOOR , "ladder" => Block :: LADDER , "rail" => Block :: RAIL , "cobblestone_stairs" => Block :: COBBLESTONE_STAIRS , "oak_wall_sign" => Block :: OAK_WALL_SIGN , "spruce_wall_sign" => Block :: SPRUCE_WALL_SIGN , "birch_wall_sign" => Block :: BIRCH_WALL_SIGN , "acacia_wall_sign" => Block :: ACACIA_WALL_SIGN , "cherry_wall_sign" => Block :: CHERRY_WALL_SIGN , "jungle_wall_sign" => Block :: JUNGLE_WALL_SIGN , "dark_oak_wall_sign" => Block :: DARK_OAK_WALL_SIGN , "pale_oak_wall_sign" => Block :: PALE_OAK_WALL_SIGN , "mangrove_wall_sign" => Block :: MANGROVE_WALL_SIGN , "bamboo_wall_sign" => Block :: BAMBOO_WALL_SIGN , "oak_hanging_sign" => Block :: OAK_HANGING_SIGN , "spruce_hanging_sign" => Block :: SPRUCE_HANGING_SIGN , "birch_hanging_sign" => Block :: BIRCH_HANGING_SIGN , "acacia_hanging_sign" => Block :: ACACIA_HANGING_SIGN , "cherry_hanging_sign" => Block :: CHERRY_HANGING_SIGN , "jungle_hanging_sign" => Block :: JUNGLE_HANGING_SIGN , "dark_oak_hanging_sign" => Block :: DARK_OAK_HANGING_SIGN , "pale_oak_hanging_sign" => Block :: PALE_OAK_HANGING_SIGN , "crimson_hanging_sign" => Block :: CRIMSON_HANGING_SIGN , "warped_hanging_sign" => Block :: WARPED_HANGING_SIGN , "mangrove_hanging_sign" => Block :: MANGROVE_HANGING_SIGN , "bamboo_hanging_sign" => Block :: BAMBOO_HANGING_SIGN , "oak_wall_hanging_sign" => Block :: OAK_WALL_HANGING_SIGN , "spruce_wall_hanging_sign" => Block :: SPRUCE_WALL_HANGING_SIGN , "birch_wall_hanging_sign" => Block :: BIRCH_WALL_HANGING_SIGN , "acacia_wall_hanging_sign" => Block :: ACACIA_WALL_HANGING_SIGN , "cherry_wall_hanging_sign" => Block :: CHERRY_WALL_HANGING_SIGN , "jungle_wall_hanging_sign" => Block :: JUNGLE_WALL_HANGING_SIGN , "dark_oak_wall_hanging_sign" => Block :: DARK_OAK_WALL_HANGING_SIGN , "pale_oak_wall_hanging_sign" => Block :: PALE_OAK_WALL_HANGING_SIGN , "mangrove_wall_hanging_sign" => Block :: MANGROVE_WALL_HANGING_SIGN , "crimson_wall_hanging_sign" => Block :: CRIMSON_WALL_HANGING_SIGN , "warped_wall_hanging_sign" => Block :: WARPED_WALL_HANGING_SIGN , "bamboo_wall_hanging_sign" => Block :: BAMBOO_WALL_HANGING_SIGN , "lever" => Block :: LEVER , "stone_pressure_plate" => Block :: STONE_PRESSURE_PLATE , "iron_door" => Block :: IRON_DOOR , "oak_pressure_plate" => Block :: OAK_PRESSURE_PLATE , "spruce_pressure_plate" => Block :: SPRUCE_PRESSURE_PLATE , "birch_pressure_plate" => Block :: BIRCH_PRESSURE_PLATE , "jungle_pressure_plate" => Block :: JUNGLE_PRESSURE_PLATE , "acacia_pressure_plate" => Block :: ACACIA_PRESSURE_PLATE , "cherry_pressure_plate" => Block :: CHERRY_PRESSURE_PLATE , "dark_oak_pressure_plate" => Block :: DARK_OAK_PRESSURE_PLATE , "pale_oak_pressure_plate" => Block :: PALE_OAK_PRESSURE_PLATE , "mangrove_pressure_plate" => Block :: MANGROVE_PRESSURE_PLATE , "bamboo_pressure_plate" => Block :: BAMBOO_PRESSURE_PLATE , "redstone_ore" => Block :: REDSTONE_ORE , "deepslate_redstone_ore" => Block :: DEEPSLATE_REDSTONE_ORE , "redstone_torch" => Block :: REDSTONE_TORCH , "redstone_wall_torch" => Block :: REDSTONE_WALL_TORCH , "stone_button" => Block :: STONE_BUTTON , "snow" => Block :: SNOW , "ice" => Block :: ICE , "snow_block" => Block :: SNOW_BLOCK , "cactus" => Block :: CACTUS , "cactus_flower" => Block :: CACTUS_FLOWER , "clay" => Block :: CLAY , "sugar_cane" => Block :: SUGAR_CANE , "jukebox" => Block :: JUKEBOX , "oak_fence" => Block :: OAK_FENCE , "netherrack" => Block :: NETHERRACK , "soul_sand" => Block :: SOUL_SAND , "soul_soil" => Block :: SOUL_SOIL , "basalt" => Block :: BASALT , "polished_basalt" => Block :: POLISHED_BASALT , "soul_torch" => Block :: SOUL_TORCH , "soul_wall_torch" => Block :: SOUL_WALL_TORCH , "copper_torch" => Block :: COPPER_TORCH , "copper_wall_torch" => Block :: COPPER_WALL_TORCH , "glowstone" => Block :: GLOWSTONE , "nether_portal" => Block :: NETHER_PORTAL , "carved_pumpkin" => Block :: CARVED_PUMPKIN , "jack_o_lantern" => Block :: JACK_O_LANTERN , "cake" => Block :: CAKE , "repeater" => Block :: REPEATER , "white_stained_glass" => Block :: WHITE_STAINED_GLASS , "orange_stained_glass" => Block :: ORANGE_STAINED_GLASS , "magenta_stained_glass" => Block :: MAGENTA_STAINED_GLASS , "light_blue_stained_glass" => Block :: LIGHT_BLUE_STAINED_GLASS , "yellow_stained_glass" => Block :: YELLOW_STAINED_GLASS , "lime_stained_glass" => Block :: LIME_STAINED_GLASS , "pink_stained_glass" => Block :: PINK_STAINED_GLASS , "gray_stained_glass" => Block :: GRAY_STAINED_GLASS , "light_gray_stained_glass" => Block :: LIGHT_GRAY_STAINED_GLASS , "cyan_stained_glass" => Block :: CYAN_STAINED_GLASS , "purple_stained_glass" => Block :: PURPLE_STAINED_GLASS , "blue_stained_glass" => Block :: BLUE_STAINED_GLASS , "brown_stained_glass" => Block :: BROWN_STAINED_GLASS , "green_stained_glass" => Block :: GREEN_STAINED_GLASS , "red_stained_glass" => Block :: RED_STAINED_GLASS , "black_stained_glass" => Block :: BLACK_STAINED_GLASS , "oak_trapdoor" => Block :: OAK_TRAPDOOR , "spruce_trapdoor" => Block :: SPRUCE_TRAPDOOR , "birch_trapdoor" => Block :: BIRCH_TRAPDOOR , "jungle_trapdoor" => Block :: JUNGLE_TRAPDOOR , "acacia_trapdoor" => Block :: ACACIA_TRAPDOOR , "cherry_trapdoor" => Block :: CHERRY_TRAPDOOR , "dark_oak_trapdoor" => Block :: DARK_OAK_TRAPDOOR , "pale_oak_trapdoor" => Block :: PALE_OAK_TRAPDOOR , "mangrove_trapdoor" => Block :: MANGROVE_TRAPDOOR , "bamboo_trapdoor" => Block :: BAMBOO_TRAPDOOR , "stone_bricks" => Block :: STONE_BRICKS , "mossy_stone_bricks" => Block :: MOSSY_STONE_BRICKS , "cracked_stone_bricks" => Block :: CRACKED_STONE_BRICKS , "chiseled_stone_bricks" => Block :: CHISELED_STONE_BRICKS , "packed_mud" => Block :: PACKED_MUD , "mud_bricks" => Block :: MUD_BRICKS , "infested_stone" => Block :: INFESTED_STONE , "infested_cobblestone" => Block :: INFESTED_COBBLESTONE , "infested_stone_bricks" => Block :: INFESTED_STONE_BRICKS , "infested_mossy_stone_bricks" => Block :: INFESTED_MOSSY_STONE_BRICKS , "infested_cracked_stone_bricks" => Block :: INFESTED_CRACKED_STONE_BRICKS , "infested_chiseled_stone_bricks" => Block :: INFESTED_CHISELED_STONE_BRICKS , "brown_mushroom_block" => Block :: BROWN_MUSHROOM_BLOCK , "red_mushroom_block" => Block :: RED_MUSHROOM_BLOCK , "mushroom_stem" => Block :: MUSHROOM_STEM , "iron_bars" => Block :: IRON_BARS , "copper_bars" => Block :: COPPER_BARS , "exposed_copper_bars" => Block :: EXPOSED_COPPER_BARS , "weathered_copper_bars" => Block :: WEATHERED_COPPER_BARS , "oxidized_copper_bars" => Block :: OXIDIZED_COPPER_BARS , "waxed_copper_bars" => Block :: WAXED_COPPER_BARS , "waxed_exposed_copper_bars" => Block :: WAXED_EXPOSED_COPPER_BARS , "waxed_weathered_copper_bars" => Block :: WAXED_WEATHERED_COPPER_BARS , "waxed_oxidized_copper_bars" => Block :: WAXED_OXIDIZED_COPPER_BARS , "iron_chain" => Block :: IRON_CHAIN , "copper_chain" => Block :: COPPER_CHAIN , "exposed_copper_chain" => Block :: EXPOSED_COPPER_CHAIN , "weathered_copper_chain" => Block :: WEATHERED_COPPER_CHAIN , "oxidized_copper_chain" => Block :: OXIDIZED_COPPER_CHAIN , "waxed_copper_chain" => Block :: WAXED_COPPER_CHAIN , "waxed_exposed_copper_chain" => Block :: WAXED_EXPOSED_COPPER_CHAIN , "waxed_weathered_copper_chain" => Block :: WAXED_WEATHERED_COPPER_CHAIN , "waxed_oxidized_copper_chain" => Block :: WAXED_OXIDIZED_COPPER_CHAIN , "glass_pane" => Block :: GLASS_PANE , "pumpkin" => Block :: PUMPKIN , "melon" => Block :: MELON , "attached_pumpkin_stem" => Block :: ATTACHED_PUMPKIN_STEM , "attached_melon_stem" => Block :: ATTACHED_MELON_STEM , "pumpkin_stem" => Block :: PUMPKIN_STEM , "melon_stem" => Block :: MELON_STEM , "vine" => Block :: VINE , "glow_lichen" => Block :: GLOW_LICHEN , "resin_clump" => Block :: RESIN_CLUMP , "oak_fence_gate" => Block :: OAK_FENCE_GATE , "brick_stairs" => Block :: BRICK_STAIRS , "stone_brick_stairs" => Block :: STONE_BRICK_STAIRS , "mud_brick_stairs" => Block :: MUD_BRICK_STAIRS , "mycelium" => Block :: MYCELIUM , "lily_pad" => Block :: LILY_PAD , "resin_block" => Block :: RESIN_BLOCK , "resin_bricks" => Block :: RESIN_BRICKS , "resin_brick_stairs" => Block :: RESIN_BRICK_STAIRS , "resin_brick_slab" => Block :: RESIN_BRICK_SLAB , "resin_brick_wall" => Block :: RESIN_BRICK_WALL , "chiseled_resin_bricks" => Block :: CHISELED_RESIN_BRICKS , "nether_bricks" => Block :: NETHER_BRICKS , "nether_brick_fence" => Block :: NETHER_BRICK_FENCE , "nether_brick_stairs" => Block :: NETHER_BRICK_STAIRS , "nether_wart" => Block :: NETHER_WART , "enchanting_table" => Block :: ENCHANTING_TABLE , "brewing_stand" => Block :: BREWING_STAND , "cauldron" => Block :: CAULDRON , "water_cauldron" => Block :: WATER_CAULDRON , "lava_cauldron" => Block :: LAVA_CAULDRON , "powder_snow_cauldron" => Block :: POWDER_SNOW_CAULDRON , "end_portal" => Block :: END_PORTAL , "end_portal_frame" => Block :: END_PORTAL_FRAME , "end_stone" => Block :: END_STONE , "dragon_egg" => Block :: DRAGON_EGG , "redstone_lamp" => Block :: REDSTONE_LAMP , "cocoa" => Block :: COCOA , "sandstone_stairs" => Block :: SANDSTONE_STAIRS , "emerald_ore" => Block :: EMERALD_ORE , "deepslate_emerald_ore" => Block :: DEEPSLATE_EMERALD_ORE , "ender_chest" => Block :: ENDER_CHEST , "tripwire_hook" => Block :: TRIPWIRE_HOOK , "tripwire" => Block :: TRIPWIRE , "emerald_block" => Block :: EMERALD_BLOCK , "spruce_stairs" => Block :: SPRUCE_STAIRS , "birch_stairs" => Block :: BIRCH_STAIRS , "jungle_stairs" => Block :: JUNGLE_STAIRS , "command_block" => Block :: COMMAND_BLOCK , "beacon" => Block :: BEACON , "cobblestone_wall" => Block :: COBBLESTONE_WALL , "mossy_cobblestone_wall" => Block :: MOSSY_COBBLESTONE_WALL , "flower_pot" => Block :: FLOWER_POT , "potted_torchflower" => Block :: POTTED_TORCHFLOWER , "potted_oak_sapling" => Block :: POTTED_OAK_SAPLING , "potted_spruce_sapling" => Block :: POTTED_SPRUCE_SAPLING , "potted_birch_sapling" => Block :: POTTED_BIRCH_SAPLING , "potted_jungle_sapling" => Block :: POTTED_JUNGLE_SAPLING , "potted_acacia_sapling" => Block :: POTTED_ACACIA_SAPLING , "potted_cherry_sapling" => Block :: POTTED_CHERRY_SAPLING , "potted_dark_oak_sapling" => Block :: POTTED_DARK_OAK_SAPLING , "potted_pale_oak_sapling" => Block :: POTTED_PALE_OAK_SAPLING , "potted_mangrove_propagule" => Block :: POTTED_MANGROVE_PROPAGULE , "potted_fern" => Block :: POTTED_FERN , "potted_dandelion" => Block :: POTTED_DANDELION , "potted_golden_dandelion" => Block :: POTTED_GOLDEN_DANDELION , "potted_poppy" => Block :: POTTED_POPPY , "potted_blue_orchid" => Block :: POTTED_BLUE_ORCHID , "potted_allium" => Block :: POTTED_ALLIUM , "potted_azure_bluet" => Block :: POTTED_AZURE_BLUET , "potted_red_tulip" => Block :: POTTED_RED_TULIP , "potted_orange_tulip" => Block :: POTTED_ORANGE_TULIP , "potted_white_tulip" => Block :: POTTED_WHITE_TULIP , "potted_pink_tulip" => Block :: POTTED_PINK_TULIP , "potted_oxeye_daisy" => Block :: POTTED_OXEYE_DAISY , "potted_cornflower" => Block :: POTTED_CORNFLOWER , "potted_lily_of_the_valley" => Block :: POTTED_LILY_OF_THE_VALLEY , "potted_wither_rose" => Block :: POTTED_WITHER_ROSE , "potted_red_mushroom" => Block :: POTTED_RED_MUSHROOM , "potted_brown_mushroom" => Block :: POTTED_BROWN_MUSHROOM , "potted_dead_bush" => Block :: POTTED_DEAD_BUSH , "potted_cactus" => Block :: POTTED_CACTUS , "carrots" => Block :: CARROTS , "potatoes" => Block :: POTATOES , "oak_button" => Block :: OAK_BUTTON , "spruce_button" => Block :: SPRUCE_BUTTON , "birch_button" => Block :: BIRCH_BUTTON , "jungle_button" => Block :: JUNGLE_BUTTON , "acacia_button" => Block :: ACACIA_BUTTON , "cherry_button" => Block :: CHERRY_BUTTON , "dark_oak_button" => Block :: DARK_OAK_BUTTON , "pale_oak_button" => Block :: PALE_OAK_BUTTON , "mangrove_button" => Block :: MANGROVE_BUTTON , "bamboo_button" => Block :: BAMBOO_BUTTON , "skeleton_skull" => Block :: SKELETON_SKULL , "skeleton_wall_skull" => Block :: SKELETON_WALL_SKULL , "wither_skeleton_skull" => Block :: WITHER_SKELETON_SKULL , "wither_skeleton_wall_skull" => Block :: WITHER_SKELETON_WALL_SKULL , "zombie_head" => Block :: ZOMBIE_HEAD , "zombie_wall_head" => Block :: ZOMBIE_WALL_HEAD , "player_head" => Block :: PLAYER_HEAD , "player_wall_head" => Block :: PLAYER_WALL_HEAD , "creeper_head" => Block :: CREEPER_HEAD , "creeper_wall_head" => Block :: CREEPER_WALL_HEAD , "dragon_head" => Block :: DRAGON_HEAD , "dragon_wall_head" => Block :: DRAGON_WALL_HEAD , "piglin_head" => Block :: PIGLIN_HEAD , "piglin_wall_head" => Block :: PIGLIN_WALL_HEAD , "anvil" => Block :: ANVIL , "chipped_anvil" => Block :: CHIPPED_ANVIL , "damaged_anvil" => Block :: DAMAGED_ANVIL , "trapped_chest" => Block :: TRAPPED_CHEST , "light_weighted_pressure_plate" => Block :: LIGHT_WEIGHTED_PRESSURE_PLATE , "heavy_weighted_pressure_plate" => Block :: HEAVY_WEIGHTED_PRESSURE_PLATE , "comparator" => Block :: COMPARATOR , "daylight_detector" => Block :: DAYLIGHT_DETECTOR , "redstone_block" => Block :: REDSTONE_BLOCK , "nether_quartz_ore" => Block :: NETHER_QUARTZ_ORE , "hopper" => Block :: HOPPER , "quartz_block" => Block :: QUARTZ_BLOCK , "chiseled_quartz_block" => Block :: CHISELED_QUARTZ_BLOCK , "quartz_pillar" => Block :: QUARTZ_PILLAR , "quartz_stairs" => Block :: QUARTZ_STAIRS , "activator_rail" => Block :: ACTIVATOR_RAIL , "dropper" => Block :: DROPPER , "white_terracotta" => Block :: WHITE_TERRACOTTA , "orange_terracotta" => Block :: ORANGE_TERRACOTTA , "magenta_terracotta" => Block :: MAGENTA_TERRACOTTA , "light_blue_terracotta" => Block :: LIGHT_BLUE_TERRACOTTA , "yellow_terracotta" => Block :: YELLOW_TERRACOTTA , "lime_terracotta" => Block :: LIME_TERRACOTTA , "pink_terracotta" => Block :: PINK_TERRACOTTA , "gray_terracotta" => Block :: GRAY_TERRACOTTA , "light_gray_terracotta" => Block :: LIGHT_GRAY_TERRACOTTA , "cyan_terracotta" => Block :: CYAN_TERRACOTTA , "purple_terracotta" => Block :: PURPLE_TERRACOTTA , "blue_terracotta" => Block :: BLUE_TERRACOTTA , "brown_terracotta" => Block :: BROWN_TERRACOTTA , "green_terracotta" => Block :: GREEN_TERRACOTTA , "red_terracotta" => Block :: RED_TERRACOTTA , "black_terracotta" => Block :: BLACK_TERRACOTTA , "white_stained_glass_pane" => Block :: WHITE_STAINED_GLASS_PANE , "orange_stained_glass_pane" => Block :: ORANGE_STAINED_GLASS_PANE , "magenta_stained_glass_pane" => Block :: MAGENTA_STAINED_GLASS_PANE , "light_blue_stained_glass_pane" => Block :: LIGHT_BLUE_STAINED_GLASS_PANE , "yellow_stained_glass_pane" => Block :: YELLOW_STAINED_GLASS_PANE , "lime_stained_glass_pane" => Block :: LIME_STAINED_GLASS_PANE , "pink_stained_glass_pane" => Block :: PINK_STAINED_GLASS_PANE , "gray_stained_glass_pane" => Block :: GRAY_STAINED_GLASS_PANE , "light_gray_stained_glass_pane" => Block :: LIGHT_GRAY_STAINED_GLASS_PANE , "cyan_stained_glass_pane" => Block :: CYAN_STAINED_GLASS_PANE , "purple_stained_glass_pane" => Block :: PURPLE_STAINED_GLASS_PANE , "blue_stained_glass_pane" => Block :: BLUE_STAINED_GLASS_PANE , "brown_stained_glass_pane" => Block :: BROWN_STAINED_GLASS_PANE , "green_stained_glass_pane" => Block :: GREEN_STAINED_GLASS_PANE , "red_stained_glass_pane" => Block :: RED_STAINED_GLASS_PANE , "black_stained_glass_pane" => Block :: BLACK_STAINED_GLASS_PANE , "acacia_stairs" => Block :: ACACIA_STAIRS , "cherry_stairs" => Block :: CHERRY_STAIRS , "dark_oak_stairs" => Block :: DARK_OAK_STAIRS , "pale_oak_stairs" => Block :: PALE_OAK_STAIRS , "mangrove_stairs" => Block :: MANGROVE_STAIRS , "bamboo_stairs" => Block :: BAMBOO_STAIRS , "bamboo_mosaic_stairs" => Block :: BAMBOO_MOSAIC_STAIRS , "slime_block" => Block :: SLIME_BLOCK , "barrier" => Block :: BARRIER , "light" => Block :: LIGHT , "iron_trapdoor" => Block :: IRON_TRAPDOOR , "prismarine" => Block :: PRISMARINE , "prismarine_bricks" => Block :: PRISMARINE_BRICKS , "dark_prismarine" => Block :: DARK_PRISMARINE , "prismarine_stairs" => Block :: PRISMARINE_STAIRS , "prismarine_brick_stairs" => Block :: PRISMARINE_BRICK_STAIRS , "dark_prismarine_stairs" => Block :: DARK_PRISMARINE_STAIRS , "prismarine_slab" => Block :: PRISMARINE_SLAB , "prismarine_brick_slab" => Block :: PRISMARINE_BRICK_SLAB , "dark_prismarine_slab" => Block :: DARK_PRISMARINE_SLAB , "sea_lantern" => Block :: SEA_LANTERN , "hay_block" => Block :: HAY_BLOCK , "white_carpet" => Block :: WHITE_CARPET , "orange_carpet" => Block :: ORANGE_CARPET , "magenta_carpet" => Block :: MAGENTA_CARPET , "light_blue_carpet" => Block :: LIGHT_BLUE_CARPET , "yellow_carpet" => Block :: YELLOW_CARPET , "lime_carpet" => Block :: LIME_CARPET , "pink_carpet" => Block :: PINK_CARPET , "gray_carpet" => Block :: GRAY_CARPET , "light_gray_carpet" => Block :: LIGHT_GRAY_CARPET , "cyan_carpet" => Block :: CYAN_CARPET , "purple_carpet" => Block :: PURPLE_CARPET , "blue_carpet" => Block :: BLUE_CARPET , "brown_carpet" => Block :: BROWN_CARPET , "green_carpet" => Block :: GREEN_CARPET , "red_carpet" => Block :: RED_CARPET , "black_carpet" => Block :: BLACK_CARPET , "terracotta" => Block :: TERRACOTTA , "coal_block" => Block :: COAL_BLOCK , "packed_ice" => Block :: PACKED_ICE , "sunflower" => Block :: SUNFLOWER , "lilac" => Block :: LILAC , "rose_bush" => Block :: ROSE_BUSH , "peony" => Block :: PEONY , "tall_grass" => Block :: TALL_GRASS , "large_fern" => Block :: LARGE_FERN , "white_banner" => Block :: WHITE_BANNER , "orange_banner" => Block :: ORANGE_BANNER , "magenta_banner" => Block :: MAGENTA_BANNER , "light_blue_banner" => Block :: LIGHT_BLUE_BANNER , "yellow_banner" => Block :: YELLOW_BANNER , "lime_banner" => Block :: LIME_BANNER , "pink_banner" => Block :: PINK_BANNER , "gray_banner" => Block :: GRAY_BANNER , "light_gray_banner" => Block :: LIGHT_GRAY_BANNER , "cyan_banner" => Block :: CYAN_BANNER , "purple_banner" => Block :: PURPLE_BANNER , "blue_banner" => Block :: BLUE_BANNER , "brown_banner" => Block :: BROWN_BANNER , "green_banner" => Block :: GREEN_BANNER , "red_banner" => Block :: RED_BANNER , "black_banner" => Block :: BLACK_BANNER , "white_wall_banner" => Block :: WHITE_WALL_BANNER , "orange_wall_banner" => Block :: ORANGE_WALL_BANNER , "magenta_wall_banner" => Block :: MAGENTA_WALL_BANNER , "light_blue_wall_banner" => Block :: LIGHT_BLUE_WALL_BANNER , "yellow_wall_banner" => Block :: YELLOW_WALL_BANNER , "lime_wall_banner" => Block :: LIME_WALL_BANNER , "pink_wall_banner" => Block :: PINK_WALL_BANNER , "gray_wall_banner" => Block :: GRAY_WALL_BANNER , "light_gray_wall_banner" => Block :: LIGHT_GRAY_WALL_BANNER , "cyan_wall_banner" => Block :: CYAN_WALL_BANNER , "purple_wall_banner" => Block :: PURPLE_WALL_BANNER , "blue_wall_banner" => Block :: BLUE_WALL_BANNER , "brown_wall_banner" => Block :: BROWN_WALL_BANNER , "green_wall_banner" => Block :: GREEN_WALL_BANNER , "red_wall_banner" => Block :: RED_WALL_BANNER , "black_wall_banner" => Block :: BLACK_WALL_BANNER , "red_sandstone" => Block :: RED_SANDSTONE , "chiseled_red_sandstone" => Block :: CHISELED_RED_SANDSTONE , "cut_red_sandstone" => Block :: CUT_RED_SANDSTONE , "red_sandstone_stairs" => Block :: RED_SANDSTONE_STAIRS , "oak_slab" => Block :: OAK_SLAB , "spruce_slab" => Block :: SPRUCE_SLAB , "birch_slab" => Block :: BIRCH_SLAB , "jungle_slab" => Block :: JUNGLE_SLAB , "acacia_slab" => Block :: ACACIA_SLAB , "cherry_slab" => Block :: CHERRY_SLAB , "dark_oak_slab" => Block :: DARK_OAK_SLAB , "pale_oak_slab" => Block :: PALE_OAK_SLAB , "mangrove_slab" => Block :: MANGROVE_SLAB , "bamboo_slab" => Block :: BAMBOO_SLAB , "bamboo_mosaic_slab" => Block :: BAMBOO_MOSAIC_SLAB , "stone_slab" => Block :: STONE_SLAB , "smooth_stone_slab" => Block :: SMOOTH_STONE_SLAB , "sandstone_slab" => Block :: SANDSTONE_SLAB , "cut_sandstone_slab" => Block :: CUT_SANDSTONE_SLAB , "petrified_oak_slab" => Block :: PETRIFIED_OAK_SLAB , "cobblestone_slab" => Block :: COBBLESTONE_SLAB , "brick_slab" => Block :: BRICK_SLAB , "stone_brick_slab" => Block :: STONE_BRICK_SLAB , "mud_brick_slab" => Block :: MUD_BRICK_SLAB , "nether_brick_slab" => Block :: NETHER_BRICK_SLAB , "quartz_slab" => Block :: QUARTZ_SLAB , "red_sandstone_slab" => Block :: RED_SANDSTONE_SLAB , "cut_red_sandstone_slab" => Block :: CUT_RED_SANDSTONE_SLAB , "purpur_slab" => Block :: PURPUR_SLAB , "smooth_stone" => Block :: SMOOTH_STONE , "smooth_sandstone" => Block :: SMOOTH_SANDSTONE , "smooth_quartz" => Block :: SMOOTH_QUARTZ , "smooth_red_sandstone" => Block :: SMOOTH_RED_SANDSTONE , "spruce_fence_gate" => Block :: SPRUCE_FENCE_GATE , "birch_fence_gate" => Block :: BIRCH_FENCE_GATE , "jungle_fence_gate" => Block :: JUNGLE_FENCE_GATE , "acacia_fence_gate" => Block :: ACACIA_FENCE_GATE , "cherry_fence_gate" => Block :: CHERRY_FENCE_GATE , "dark_oak_fence_gate" => Block :: DARK_OAK_FENCE_GATE , "pale_oak_fence_gate" => Block :: PALE_OAK_FENCE_GATE , "mangrove_fence_gate" => Block :: MANGROVE_FENCE_GATE , "bamboo_fence_gate" => Block :: BAMBOO_FENCE_GATE , "spruce_fence" => Block :: SPRUCE_FENCE , "birch_fence" => Block :: BIRCH_FENCE , "jungle_fence" => Block :: JUNGLE_FENCE , "acacia_fence" => Block :: ACACIA_FENCE , "cherry_fence" => Block :: CHERRY_FENCE , "dark_oak_fence" => Block :: DARK_OAK_FENCE , "pale_oak_fence" => Block :: PALE_OAK_FENCE , "mangrove_fence" => Block :: MANGROVE_FENCE , "bamboo_fence" => Block :: BAMBOO_FENCE , "spruce_door" => Block :: SPRUCE_DOOR , "birch_door" => Block :: BIRCH_DOOR , "jungle_door" => Block :: JUNGLE_DOOR , "acacia_door" => Block :: ACACIA_DOOR , "cherry_door" => Block :: CHERRY_DOOR , "dark_oak_door" => Block :: DARK_OAK_DOOR , "pale_oak_door" => Block :: PALE_OAK_DOOR , "mangrove_door" => Block :: MANGROVE_DOOR , "bamboo_door" => Block :: BAMBOO_DOOR , "end_rod" => Block :: END_ROD , "chorus_plant" => Block :: CHORUS_PLANT , "chorus_flower" => Block :: CHORUS_FLOWER , "purpur_block" => Block :: PURPUR_BLOCK , "purpur_pillar" => Block :: PURPUR_PILLAR , "purpur_stairs" => Block :: PURPUR_STAIRS , "end_stone_bricks" => Block :: END_STONE_BRICKS , "torchflower_crop" => Block :: TORCHFLOWER_CROP , "pitcher_crop" => Block :: PITCHER_CROP , "pitcher_plant" => Block :: PITCHER_PLANT , "beetroots" => Block :: BEETROOTS , "dirt_path" => Block :: DIRT_PATH , "end_gateway" => Block :: END_GATEWAY , "repeating_command_block" => Block :: REPEATING_COMMAND_BLOCK , "chain_command_block" => Block :: CHAIN_COMMAND_BLOCK , "frosted_ice" => Block :: FROSTED_ICE , "magma_block" => Block :: MAGMA_BLOCK , "nether_wart_block" => Block :: NETHER_WART_BLOCK , "red_nether_bricks" => Block :: RED_NETHER_BRICKS , "bone_block" => Block :: BONE_BLOCK , "structure_void" => Block :: STRUCTURE_VOID , "observer" => Block :: OBSERVER , "shulker_box" => Block :: SHULKER_BOX , "white_shulker_box" => Block :: WHITE_SHULKER_BOX , "orange_shulker_box" => Block :: ORANGE_SHULKER_BOX , "magenta_shulker_box" => Block :: MAGENTA_SHULKER_BOX , "light_blue_shulker_box" => Block :: LIGHT_BLUE_SHULKER_BOX , "yellow_shulker_box" => Block :: YELLOW_SHULKER_BOX , "lime_shulker_box" => Block :: LIME_SHULKER_BOX , "pink_shulker_box" => Block :: PINK_SHULKER_BOX , "gray_shulker_box" => Block :: GRAY_SHULKER_BOX , "light_gray_shulker_box" => Block :: LIGHT_GRAY_SHULKER_BOX , "cyan_shulker_box" => Block :: CYAN_SHULKER_BOX , "purple_shulker_box" => Block :: PURPLE_SHULKER_BOX , "blue_shulker_box" => Block :: BLUE_SHULKER_BOX , "brown_shulker_box" => Block :: BROWN_SHULKER_BOX , "green_shulker_box" => Block :: GREEN_SHULKER_BOX , "red_shulker_box" => Block :: RED_SHULKER_BOX , "black_shulker_box" => Block :: BLACK_SHULKER_BOX , "white_glazed_terracotta" => Block :: WHITE_GLAZED_TERRACOTTA , "orange_glazed_terracotta" => Block :: ORANGE_GLAZED_TERRACOTTA , "magenta_glazed_terracotta" => Block :: MAGENTA_GLAZED_TERRACOTTA , "light_blue_glazed_terracotta" => Block :: LIGHT_BLUE_GLAZED_TERRACOTTA , "yellow_glazed_terracotta" => Block :: YELLOW_GLAZED_TERRACOTTA , "lime_glazed_terracotta" => Block :: LIME_GLAZED_TERRACOTTA , "pink_glazed_terracotta" => Block :: PINK_GLAZED_TERRACOTTA , "gray_glazed_terracotta" => Block :: GRAY_GLAZED_TERRACOTTA , "light_gray_glazed_terracotta" => Block :: LIGHT_GRAY_GLAZED_TERRACOTTA , "cyan_glazed_terracotta" => Block :: CYAN_GLAZED_TERRACOTTA , "purple_glazed_terracotta" => Block :: PURPLE_GLAZED_TERRACOTTA , "blue_glazed_terracotta" => Block :: BLUE_GLAZED_TERRACOTTA , "brown_glazed_terracotta" => Block :: BROWN_GLAZED_TERRACOTTA , "green_glazed_terracotta" => Block :: GREEN_GLAZED_TERRACOTTA , "red_glazed_terracotta" => Block :: RED_GLAZED_TERRACOTTA , "black_glazed_terracotta" => Block :: BLACK_GLAZED_TERRACOTTA , "white_concrete" => Block :: WHITE_CONCRETE , "orange_concrete" => Block :: ORANGE_CONCRETE , "magenta_concrete" => Block :: MAGENTA_CONCRETE , "light_blue_concrete" => Block :: LIGHT_BLUE_CONCRETE , "yellow_concrete" => Block :: YELLOW_CONCRETE , "lime_concrete" => Block :: LIME_CONCRETE , "pink_concrete" => Block :: PINK_CONCRETE , "gray_concrete" => Block :: GRAY_CONCRETE , "light_gray_concrete" => Block :: LIGHT_GRAY_CONCRETE , "cyan_concrete" => Block :: CYAN_CONCRETE , "purple_concrete" => Block :: PURPLE_CONCRETE , "blue_concrete" => Block :: BLUE_CONCRETE , "brown_concrete" => Block :: BROWN_CONCRETE , "green_concrete" => Block :: GREEN_CONCRETE , "red_concrete" => Block :: RED_CONCRETE , "black_concrete" => Block :: BLACK_CONCRETE , "white_concrete_powder" => Block :: WHITE_CONCRETE_POWDER , "orange_concrete_powder" => Block :: ORANGE_CONCRETE_POWDER , "magenta_concrete_powder" => Block :: MAGENTA_CONCRETE_POWDER , "light_blue_concrete_powder" => Block :: LIGHT_BLUE_CONCRETE_POWDER , "yellow_concrete_powder" => Block :: YELLOW_CONCRETE_POWDER , "lime_concrete_powder" => Block :: LIME_CONCRETE_POWDER , "pink_concrete_powder" => Block :: PINK_CONCRETE_POWDER , "gray_concrete_powder" => Block :: GRAY_CONCRETE_POWDER , "light_gray_concrete_powder" => Block :: LIGHT_GRAY_CONCRETE_POWDER , "cyan_concrete_powder" => Block :: CYAN_CONCRETE_POWDER , "purple_concrete_powder" => Block :: PURPLE_CONCRETE_POWDER , "blue_concrete_powder" => Block :: BLUE_CONCRETE_POWDER , "brown_concrete_powder" => Block :: BROWN_CONCRETE_POWDER , "green_concrete_powder" => Block :: GREEN_CONCRETE_POWDER , "red_concrete_powder" => Block :: RED_CONCRETE_POWDER , "black_concrete_powder" => Block :: BLACK_CONCRETE_POWDER , "kelp" => Block :: KELP , "kelp_plant" => Block :: KELP_PLANT , "dried_kelp_block" => Block :: DRIED_KELP_BLOCK , "turtle_egg" => Block :: TURTLE_EGG , "sniffer_egg" => Block :: SNIFFER_EGG , "dried_ghast" => Block :: DRIED_GHAST , "dead_tube_coral_block" => Block :: DEAD_TUBE_CORAL_BLOCK , "dead_brain_coral_block" => Block :: DEAD_BRAIN_CORAL_BLOCK , "dead_bubble_coral_block" => Block :: DEAD_BUBBLE_CORAL_BLOCK , "dead_fire_coral_block" => Block :: DEAD_FIRE_CORAL_BLOCK , "dead_horn_coral_block" => Block :: DEAD_HORN_CORAL_BLOCK , "tube_coral_block" => Block :: TUBE_CORAL_BLOCK , "brain_coral_block" => Block :: BRAIN_CORAL_BLOCK , "bubble_coral_block" => Block :: BUBBLE_CORAL_BLOCK , "fire_coral_block" => Block :: FIRE_CORAL_BLOCK , "horn_coral_block" => Block :: HORN_CORAL_BLOCK , "dead_tube_coral" => Block :: DEAD_TUBE_CORAL , "dead_brain_coral" => Block :: DEAD_BRAIN_CORAL , "dead_bubble_coral" => Block :: DEAD_BUBBLE_CORAL , "dead_fire_coral" => Block :: DEAD_FIRE_CORAL , "dead_horn_coral" => Block :: DEAD_HORN_CORAL , "tube_coral" => Block :: TUBE_CORAL , "brain_coral" => Block :: BRAIN_CORAL , "bubble_coral" => Block :: BUBBLE_CORAL , "fire_coral" => Block :: FIRE_CORAL , "horn_coral" => Block :: HORN_CORAL , "dead_tube_coral_fan" => Block :: DEAD_TUBE_CORAL_FAN , "dead_brain_coral_fan" => Block :: DEAD_BRAIN_CORAL_FAN , "dead_bubble_coral_fan" => Block :: DEAD_BUBBLE_CORAL_FAN , "dead_fire_coral_fan" => Block :: DEAD_FIRE_CORAL_FAN , "dead_horn_coral_fan" => Block :: DEAD_HORN_CORAL_FAN , "tube_coral_fan" => Block :: TUBE_CORAL_FAN , "brain_coral_fan" => Block :: BRAIN_CORAL_FAN , "bubble_coral_fan" => Block :: BUBBLE_CORAL_FAN , "fire_coral_fan" => Block :: FIRE_CORAL_FAN , "horn_coral_fan" => Block :: HORN_CORAL_FAN , "dead_tube_coral_wall_fan" => Block :: DEAD_TUBE_CORAL_WALL_FAN , "dead_brain_coral_wall_fan" => Block :: DEAD_BRAIN_CORAL_WALL_FAN , "dead_bubble_coral_wall_fan" => Block :: DEAD_BUBBLE_CORAL_WALL_FAN , "dead_fire_coral_wall_fan" => Block :: DEAD_FIRE_CORAL_WALL_FAN , "dead_horn_coral_wall_fan" => Block :: DEAD_HORN_CORAL_WALL_FAN , "tube_coral_wall_fan" => Block :: TUBE_CORAL_WALL_FAN , "brain_coral_wall_fan" => Block :: BRAIN_CORAL_WALL_FAN , "bubble_coral_wall_fan" => Block :: BUBBLE_CORAL_WALL_FAN , "fire_coral_wall_fan" => Block :: FIRE_CORAL_WALL_FAN , "horn_coral_wall_fan" => Block :: HORN_CORAL_WALL_FAN , "sea_pickle" => Block :: SEA_PICKLE , "blue_ice" => Block :: BLUE_ICE , "conduit" => Block :: CONDUIT , "bamboo_sapling" => Block :: BAMBOO_SAPLING , "bamboo" => Block :: BAMBOO , "potted_bamboo" => Block :: POTTED_BAMBOO , "void_air" => Block :: VOID_AIR , "cave_air" => Block :: CAVE_AIR , "bubble_column" => Block :: BUBBLE_COLUMN , "polished_granite_stairs" => Block :: POLISHED_GRANITE_STAIRS , "smooth_red_sandstone_stairs" => Block :: SMOOTH_RED_SANDSTONE_STAIRS , "mossy_stone_brick_stairs" => Block :: MOSSY_STONE_BRICK_STAIRS , "polished_diorite_stairs" => Block :: POLISHED_DIORITE_STAIRS , "mossy_cobblestone_stairs" => Block :: MOSSY_COBBLESTONE_STAIRS , "end_stone_brick_stairs" => Block :: END_STONE_BRICK_STAIRS , "stone_stairs" => Block :: STONE_STAIRS , "smooth_sandstone_stairs" => Block :: SMOOTH_SANDSTONE_STAIRS , "smooth_quartz_stairs" => Block :: SMOOTH_QUARTZ_STAIRS , "granite_stairs" => Block :: GRANITE_STAIRS , "andesite_stairs" => Block :: ANDESITE_STAIRS , "red_nether_brick_stairs" => Block :: RED_NETHER_BRICK_STAIRS , "polished_andesite_stairs" => Block :: POLISHED_ANDESITE_STAIRS , "diorite_stairs" => Block :: DIORITE_STAIRS , "polished_granite_slab" => Block :: POLISHED_GRANITE_SLAB , "smooth_red_sandstone_slab" => Block :: SMOOTH_RED_SANDSTONE_SLAB , "mossy_stone_brick_slab" => Block :: MOSSY_STONE_BRICK_SLAB , "polished_diorite_slab" => Block :: POLISHED_DIORITE_SLAB , "mossy_cobblestone_slab" => Block :: MOSSY_COBBLESTONE_SLAB , "end_stone_brick_slab" => Block :: END_STONE_BRICK_SLAB , "smooth_sandstone_slab" => Block :: SMOOTH_SANDSTONE_SLAB , "smooth_quartz_slab" => Block :: SMOOTH_QUARTZ_SLAB , "granite_slab" => Block :: GRANITE_SLAB , "andesite_slab" => Block :: ANDESITE_SLAB , "red_nether_brick_slab" => Block :: RED_NETHER_BRICK_SLAB , "polished_andesite_slab" => Block :: POLISHED_ANDESITE_SLAB , "diorite_slab" => Block :: DIORITE_SLAB , "brick_wall" => Block :: BRICK_WALL , "prismarine_wall" => Block :: PRISMARINE_WALL , "red_sandstone_wall" => Block :: RED_SANDSTONE_WALL , "mossy_stone_brick_wall" => Block :: MOSSY_STONE_BRICK_WALL , "granite_wall" => Block :: GRANITE_WALL , "stone_brick_wall" => Block :: STONE_BRICK_WALL , "mud_brick_wall" => Block :: MUD_BRICK_WALL , "nether_brick_wall" => Block :: NETHER_BRICK_WALL , "andesite_wall" => Block :: ANDESITE_WALL , "red_nether_brick_wall" => Block :: RED_NETHER_BRICK_WALL , "sandstone_wall" => Block :: SANDSTONE_WALL , "end_stone_brick_wall" => Block :: END_STONE_BRICK_WALL , "diorite_wall" => Block :: DIORITE_WALL , "scaffolding" => Block :: SCAFFOLDING , "loom" => Block :: LOOM , "barrel" => Block :: BARREL , "smoker" => Block :: SMOKER , "blast_furnace" => Block :: BLAST_FURNACE , "cartography_table" => Block :: CARTOGRAPHY_TABLE , "fletching_table" => Block :: FLETCHING_TABLE , "grindstone" => Block :: GRINDSTONE , "lectern" => Block :: LECTERN , "smithing_table" => Block :: SMITHING_TABLE , "stonecutter" => Block :: STONECUTTER , "bell" => Block :: BELL , "lantern" => Block :: LANTERN , "soul_lantern" => Block :: SOUL_LANTERN , "copper_lantern" => Block :: COPPER_LANTERN , "exposed_copper_lantern" => Block :: EXPOSED_COPPER_LANTERN , "weathered_copper_lantern" => Block :: WEATHERED_COPPER_LANTERN , "oxidized_copper_lantern" => Block :: OXIDIZED_COPPER_LANTERN , "waxed_copper_lantern" => Block :: WAXED_COPPER_LANTERN , "waxed_exposed_copper_lantern" => Block :: WAXED_EXPOSED_COPPER_LANTERN , "waxed_weathered_copper_lantern" => Block :: WAXED_WEATHERED_COPPER_LANTERN , "waxed_oxidized_copper_lantern" => Block :: WAXED_OXIDIZED_COPPER_LANTERN , "campfire" => Block :: CAMPFIRE , "soul_campfire" => Block :: SOUL_CAMPFIRE , "sweet_berry_bush" => Block :: SWEET_BERRY_BUSH , "warped_stem" => Block :: WARPED_STEM , "stripped_warped_stem" => Block :: STRIPPED_WARPED_STEM , "warped_hyphae" => Block :: WARPED_HYPHAE , "stripped_warped_hyphae" => Block :: STRIPPED_WARPED_HYPHAE , "warped_nylium" => Block :: WARPED_NYLIUM , "warped_fungus" => Block :: WARPED_FUNGUS , "warped_wart_block" => Block :: WARPED_WART_BLOCK , "warped_roots" => Block :: WARPED_ROOTS , "nether_sprouts" => Block :: NETHER_SPROUTS , "crimson_stem" => Block :: CRIMSON_STEM , "stripped_crimson_stem" => Block :: STRIPPED_CRIMSON_STEM , "crimson_hyphae" => Block :: CRIMSON_HYPHAE , "stripped_crimson_hyphae" => Block :: STRIPPED_CRIMSON_HYPHAE , "crimson_nylium" => Block :: CRIMSON_NYLIUM , "crimson_fungus" => Block :: CRIMSON_FUNGUS , "shroomlight" => Block :: SHROOMLIGHT , "weeping_vines" => Block :: WEEPING_VINES , "weeping_vines_plant" => Block :: WEEPING_VINES_PLANT , "twisting_vines" => Block :: TWISTING_VINES , "twisting_vines_plant" => Block :: TWISTING_VINES_PLANT , "crimson_roots" => Block :: CRIMSON_ROOTS , "crimson_planks" => Block :: CRIMSON_PLANKS , "warped_planks" => Block :: WARPED_PLANKS , "crimson_slab" => Block :: CRIMSON_SLAB , "warped_slab" => Block :: WARPED_SLAB , "crimson_pressure_plate" => Block :: CRIMSON_PRESSURE_PLATE , "warped_pressure_plate" => Block :: WARPED_PRESSURE_PLATE , "crimson_fence" => Block :: CRIMSON_FENCE , "warped_fence" => Block :: WARPED_FENCE , "crimson_trapdoor" => Block :: CRIMSON_TRAPDOOR , "warped_trapdoor" => Block :: WARPED_TRAPDOOR , "crimson_fence_gate" => Block :: CRIMSON_FENCE_GATE , "warped_fence_gate" => Block :: WARPED_FENCE_GATE , "crimson_stairs" => Block :: CRIMSON_STAIRS , "warped_stairs" => Block :: WARPED_STAIRS , "crimson_button" => Block :: CRIMSON_BUTTON , "warped_button" => Block :: WARPED_BUTTON , "crimson_door" => Block :: CRIMSON_DOOR , "warped_door" => Block :: WARPED_DOOR , "crimson_sign" => Block :: CRIMSON_SIGN , "warped_sign" => Block :: WARPED_SIGN , "crimson_wall_sign" => Block :: CRIMSON_WALL_SIGN , "warped_wall_sign" => Block :: WARPED_WALL_SIGN , "structure_block" => Block :: STRUCTURE_BLOCK , "jigsaw" => Block :: JIGSAW , "test_block" => Block :: TEST_BLOCK , "test_instance_block" => Block :: TEST_INSTANCE_BLOCK , "composter" => Block :: COMPOSTER , "target" => Block :: TARGET , "bee_nest" => Block :: BEE_NEST , "beehive" => Block :: BEEHIVE , "honey_block" => Block :: HONEY_BLOCK , "honeycomb_block" => Block :: HONEYCOMB_BLOCK , "netherite_block" => Block :: NETHERITE_BLOCK , "ancient_debris" => Block :: ANCIENT_DEBRIS , "crying_obsidian" => Block :: CRYING_OBSIDIAN , "respawn_anchor" => Block :: RESPAWN_ANCHOR , "potted_crimson_fungus" => Block :: POTTED_CRIMSON_FUNGUS , "potted_warped_fungus" => Block :: POTTED_WARPED_FUNGUS , "potted_crimson_roots" => Block :: POTTED_CRIMSON_ROOTS , "potted_warped_roots" => Block :: POTTED_WARPED_ROOTS , "lodestone" => Block :: LODESTONE , "blackstone" => Block :: BLACKSTONE , "blackstone_stairs" => Block :: BLACKSTONE_STAIRS , "blackstone_wall" => Block :: BLACKSTONE_WALL , "blackstone_slab" => Block :: BLACKSTONE_SLAB , "polished_blackstone" => Block :: POLISHED_BLACKSTONE , "polished_blackstone_bricks" => Block :: POLISHED_BLACKSTONE_BRICKS , "cracked_polished_blackstone_bricks" => Block :: CRACKED_POLISHED_BLACKSTONE_BRICKS , "chiseled_polished_blackstone" => Block :: CHISELED_POLISHED_BLACKSTONE , "polished_blackstone_brick_slab" => Block :: POLISHED_BLACKSTONE_BRICK_SLAB , "polished_blackstone_brick_stairs" => Block :: POLISHED_BLACKSTONE_BRICK_STAIRS , "polished_blackstone_brick_wall" => Block :: POLISHED_BLACKSTONE_BRICK_WALL , "gilded_blackstone" => Block :: GILDED_BLACKSTONE , "polished_blackstone_stairs" => Block :: POLISHED_BLACKSTONE_STAIRS , "polished_blackstone_slab" => Block :: POLISHED_BLACKSTONE_SLAB , "polished_blackstone_pressure_plate" => Block :: POLISHED_BLACKSTONE_PRESSURE_PLATE , "polished_blackstone_button" => Block :: POLISHED_BLACKSTONE_BUTTON , "polished_blackstone_wall" => Block :: POLISHED_BLACKSTONE_WALL , "chiseled_nether_bricks" => Block :: CHISELED_NETHER_BRICKS , "cracked_nether_bricks" => Block :: CRACKED_NETHER_BRICKS , "quartz_bricks" => Block :: QUARTZ_BRICKS , "candle" => Block :: CANDLE , "white_candle" => Block :: WHITE_CANDLE , "orange_candle" => Block :: ORANGE_CANDLE , "magenta_candle" => Block :: MAGENTA_CANDLE , "light_blue_candle" => Block :: LIGHT_BLUE_CANDLE , "yellow_candle" => Block :: YELLOW_CANDLE , "lime_candle" => Block :: LIME_CANDLE , "pink_candle" => Block :: PINK_CANDLE , "gray_candle" => Block :: GRAY_CANDLE , "light_gray_candle" => Block :: LIGHT_GRAY_CANDLE , "cyan_candle" => Block :: CYAN_CANDLE , "purple_candle" => Block :: PURPLE_CANDLE , "blue_candle" => Block :: BLUE_CANDLE , "brown_candle" => Block :: BROWN_CANDLE , "green_candle" => Block :: GREEN_CANDLE , "red_candle" => Block :: RED_CANDLE , "black_candle" => Block :: BLACK_CANDLE , "candle_cake" => Block :: CANDLE_CAKE , "white_candle_cake" => Block :: WHITE_CANDLE_CAKE , "orange_candle_cake" => Block :: ORANGE_CANDLE_CAKE , "magenta_candle_cake" => Block :: MAGENTA_CANDLE_CAKE , "light_blue_candle_cake" => Block :: LIGHT_BLUE_CANDLE_CAKE , "yellow_candle_cake" => Block :: YELLOW_CANDLE_CAKE , "lime_candle_cake" => Block :: LIME_CANDLE_CAKE , "pink_candle_cake" => Block :: PINK_CANDLE_CAKE , "gray_candle_cake" => Block :: GRAY_CANDLE_CAKE , "light_gray_candle_cake" => Block :: LIGHT_GRAY_CANDLE_CAKE , "cyan_candle_cake" => Block :: CYAN_CANDLE_CAKE , "purple_candle_cake" => Block :: PURPLE_CANDLE_CAKE , "blue_candle_cake" => Block :: BLUE_CANDLE_CAKE , "brown_candle_cake" => Block :: BROWN_CANDLE_CAKE , "green_candle_cake" => Block :: GREEN_CANDLE_CAKE , "red_candle_cake" => Block :: RED_CANDLE_CAKE , "black_candle_cake" => Block :: BLACK_CANDLE_CAKE , "amethyst_block" => Block :: AMETHYST_BLOCK , "budding_amethyst" => Block :: BUDDING_AMETHYST , "amethyst_cluster" => Block :: AMETHYST_CLUSTER , "large_amethyst_bud" => Block :: LARGE_AMETHYST_BUD , "medium_amethyst_bud" => Block :: MEDIUM_AMETHYST_BUD , "small_amethyst_bud" => Block :: SMALL_AMETHYST_BUD , "tuff" => Block :: TUFF , "tuff_slab" => Block :: TUFF_SLAB , "tuff_stairs" => Block :: TUFF_STAIRS , "tuff_wall" => Block :: TUFF_WALL , "polished_tuff" => Block :: POLISHED_TUFF , "polished_tuff_slab" => Block :: POLISHED_TUFF_SLAB , "polished_tuff_stairs" => Block :: POLISHED_TUFF_STAIRS , "polished_tuff_wall" => Block :: POLISHED_TUFF_WALL , "chiseled_tuff" => Block :: CHISELED_TUFF , "tuff_bricks" => Block :: TUFF_BRICKS , "tuff_brick_slab" => Block :: TUFF_BRICK_SLAB , "tuff_brick_stairs" => Block :: TUFF_BRICK_STAIRS , "tuff_brick_wall" => Block :: TUFF_BRICK_WALL , "chiseled_tuff_bricks" => Block :: CHISELED_TUFF_BRICKS , "sulfur" => Block :: SULFUR , "potent_sulfur" => Block :: POTENT_SULFUR , "sulfur_slab" => Block :: SULFUR_SLAB , "sulfur_stairs" => Block :: SULFUR_STAIRS , "sulfur_wall" => Block :: SULFUR_WALL , "polished_sulfur" => Block :: POLISHED_SULFUR , "polished_sulfur_slab" => Block :: POLISHED_SULFUR_SLAB , "polished_sulfur_stairs" => Block :: POLISHED_SULFUR_STAIRS , "polished_sulfur_wall" => Block :: POLISHED_SULFUR_WALL , "sulfur_bricks" => Block :: SULFUR_BRICKS , "sulfur_brick_slab" => Block :: SULFUR_BRICK_SLAB , "sulfur_brick_stairs" => Block :: SULFUR_BRICK_STAIRS , "sulfur_brick_wall" => Block :: SULFUR_BRICK_WALL , "chiseled_sulfur" => Block :: CHISELED_SULFUR , "cinnabar" => Block :: CINNABAR , "cinnabar_slab" => Block :: CINNABAR_SLAB , "cinnabar_stairs" => Block :: CINNABAR_STAIRS , "cinnabar_wall" => Block :: CINNABAR_WALL , "polished_cinnabar" => Block :: POLISHED_CINNABAR , "polished_cinnabar_slab" => Block :: POLISHED_CINNABAR_SLAB , "polished_cinnabar_stairs" => Block :: POLISHED_CINNABAR_STAIRS , "polished_cinnabar_wall" => Block :: POLISHED_CINNABAR_WALL , "cinnabar_bricks" => Block :: CINNABAR_BRICKS , "cinnabar_brick_slab" => Block :: CINNABAR_BRICK_SLAB , "cinnabar_brick_stairs" => Block :: CINNABAR_BRICK_STAIRS , "cinnabar_brick_wall" => Block :: CINNABAR_BRICK_WALL , "chiseled_cinnabar" => Block :: CHISELED_CINNABAR , "calcite" => Block :: CALCITE , "tinted_glass" => Block :: TINTED_GLASS , "powder_snow" => Block :: POWDER_SNOW , "sculk_sensor" => Block :: SCULK_SENSOR , "calibrated_sculk_sensor" => Block :: CALIBRATED_SCULK_SENSOR , "sculk" => Block :: SCULK , "sculk_vein" => Block :: SCULK_VEIN , "sculk_catalyst" => Block :: SCULK_CATALYST , "sculk_shrieker" => Block :: SCULK_SHRIEKER , "copper_block" => Block :: COPPER_BLOCK , "exposed_copper" => Block :: EXPOSED_COPPER , "weathered_copper" => Block :: WEATHERED_COPPER , "oxidized_copper" => Block :: OXIDIZED_COPPER , "waxed_copper_block" => Block :: WAXED_COPPER_BLOCK , "waxed_exposed_copper" => Block :: WAXED_EXPOSED_COPPER , "waxed_weathered_copper" => Block :: WAXED_WEATHERED_COPPER , "waxed_oxidized_copper" => Block :: WAXED_OXIDIZED_COPPER , "copper_ore" => Block :: COPPER_ORE , "deepslate_copper_ore" => Block :: DEEPSLATE_COPPER_ORE , "cut_copper" => Block :: CUT_COPPER , "exposed_cut_copper" => Block :: EXPOSED_CUT_COPPER , "weathered_cut_copper" => Block :: WEATHERED_CUT_COPPER , "oxidized_cut_copper" => Block :: OXIDIZED_CUT_COPPER , "waxed_cut_copper" => Block :: WAXED_CUT_COPPER , "waxed_exposed_cut_copper" => Block :: WAXED_EXPOSED_CUT_COPPER , "waxed_weathered_cut_copper" => Block :: WAXED_WEATHERED_CUT_COPPER , "waxed_oxidized_cut_copper" => Block :: WAXED_OXIDIZED_CUT_COPPER , "chiseled_copper" => Block :: CHISELED_COPPER , "exposed_chiseled_copper" => Block :: EXPOSED_CHISELED_COPPER , "weathered_chiseled_copper" => Block :: WEATHERED_CHISELED_COPPER , "oxidized_chiseled_copper" => Block :: OXIDIZED_CHISELED_COPPER , "waxed_chiseled_copper" => Block :: WAXED_CHISELED_COPPER , "waxed_exposed_chiseled_copper" => Block :: WAXED_EXPOSED_CHISELED_COPPER , "waxed_weathered_chiseled_copper" => Block :: WAXED_WEATHERED_CHISELED_COPPER , "waxed_oxidized_chiseled_copper" => Block :: WAXED_OXIDIZED_CHISELED_COPPER , "cut_copper_stairs" => Block :: CUT_COPPER_STAIRS , "exposed_cut_copper_stairs" => Block :: EXPOSED_CUT_COPPER_STAIRS , "weathered_cut_copper_stairs" => Block :: WEATHERED_CUT_COPPER_STAIRS , "oxidized_cut_copper_stairs" => Block :: OXIDIZED_CUT_COPPER_STAIRS , "waxed_cut_copper_stairs" => Block :: WAXED_CUT_COPPER_STAIRS , "waxed_exposed_cut_copper_stairs" => Block :: WAXED_EXPOSED_CUT_COPPER_STAIRS , "waxed_weathered_cut_copper_stairs" => Block :: WAXED_WEATHERED_CUT_COPPER_STAIRS , "waxed_oxidized_cut_copper_stairs" => Block :: WAXED_OXIDIZED_CUT_COPPER_STAIRS , "cut_copper_slab" => Block :: CUT_COPPER_SLAB , "exposed_cut_copper_slab" => Block :: EXPOSED_CUT_COPPER_SLAB , "weathered_cut_copper_slab" => Block :: WEATHERED_CUT_COPPER_SLAB , "oxidized_cut_copper_slab" => Block :: OXIDIZED_CUT_COPPER_SLAB , "waxed_cut_copper_slab" => Block :: WAXED_CUT_COPPER_SLAB , "waxed_exposed_cut_copper_slab" => Block :: WAXED_EXPOSED_CUT_COPPER_SLAB , "waxed_weathered_cut_copper_slab" => Block :: WAXED_WEATHERED_CUT_COPPER_SLAB , "waxed_oxidized_cut_copper_slab" => Block :: WAXED_OXIDIZED_CUT_COPPER_SLAB , "copper_door" => Block :: COPPER_DOOR , "exposed_copper_door" => Block :: EXPOSED_COPPER_DOOR , "weathered_copper_door" => Block :: WEATHERED_COPPER_DOOR , "oxidized_copper_door" => Block :: OXIDIZED_COPPER_DOOR , "waxed_copper_door" => Block :: WAXED_COPPER_DOOR , "waxed_exposed_copper_door" => Block :: WAXED_EXPOSED_COPPER_DOOR , "waxed_weathered_copper_door" => Block :: WAXED_WEATHERED_COPPER_DOOR , "waxed_oxidized_copper_door" => Block :: WAXED_OXIDIZED_COPPER_DOOR , "copper_trapdoor" => Block :: COPPER_TRAPDOOR , "exposed_copper_trapdoor" => Block :: EXPOSED_COPPER_TRAPDOOR , "weathered_copper_trapdoor" => Block :: WEATHERED_COPPER_TRAPDOOR , "oxidized_copper_trapdoor" => Block :: OXIDIZED_COPPER_TRAPDOOR , "waxed_copper_trapdoor" => Block :: WAXED_COPPER_TRAPDOOR , "waxed_exposed_copper_trapdoor" => Block :: WAXED_EXPOSED_COPPER_TRAPDOOR , "waxed_weathered_copper_trapdoor" => Block :: WAXED_WEATHERED_COPPER_TRAPDOOR , "waxed_oxidized_copper_trapdoor" => Block :: WAXED_OXIDIZED_COPPER_TRAPDOOR , "copper_grate" => Block :: COPPER_GRATE , "exposed_copper_grate" => Block :: EXPOSED_COPPER_GRATE , "weathered_copper_grate" => Block :: WEATHERED_COPPER_GRATE , "oxidized_copper_grate" => Block :: OXIDIZED_COPPER_GRATE , "waxed_copper_grate" => Block :: WAXED_COPPER_GRATE , "waxed_exposed_copper_grate" => Block :: WAXED_EXPOSED_COPPER_GRATE , "waxed_weathered_copper_grate" => Block :: WAXED_WEATHERED_COPPER_GRATE , "waxed_oxidized_copper_grate" => Block :: WAXED_OXIDIZED_COPPER_GRATE , "copper_bulb" => Block :: COPPER_BULB , "exposed_copper_bulb" => Block :: EXPOSED_COPPER_BULB , "weathered_copper_bulb" => Block :: WEATHERED_COPPER_BULB , "oxidized_copper_bulb" => Block :: OXIDIZED_COPPER_BULB , "waxed_copper_bulb" => Block :: WAXED_COPPER_BULB , "waxed_exposed_copper_bulb" => Block :: WAXED_EXPOSED_COPPER_BULB , "waxed_weathered_copper_bulb" => Block :: WAXED_WEATHERED_COPPER_BULB , "waxed_oxidized_copper_bulb" => Block :: WAXED_OXIDIZED_COPPER_BULB , "copper_chest" => Block :: COPPER_CHEST , "exposed_copper_chest" => Block :: EXPOSED_COPPER_CHEST , "weathered_copper_chest" => Block :: WEATHERED_COPPER_CHEST , "oxidized_copper_chest" => Block :: OXIDIZED_COPPER_CHEST , "waxed_copper_chest" => Block :: WAXED_COPPER_CHEST , "waxed_exposed_copper_chest" => Block :: WAXED_EXPOSED_COPPER_CHEST , "waxed_weathered_copper_chest" => Block :: WAXED_WEATHERED_COPPER_CHEST , "waxed_oxidized_copper_chest" => Block :: WAXED_OXIDIZED_COPPER_CHEST , "copper_golem_statue" => Block :: COPPER_GOLEM_STATUE , "exposed_copper_golem_statue" => Block :: EXPOSED_COPPER_GOLEM_STATUE , "weathered_copper_golem_statue" => Block :: WEATHERED_COPPER_GOLEM_STATUE , "oxidized_copper_golem_statue" => Block :: OXIDIZED_COPPER_GOLEM_STATUE , "waxed_copper_golem_statue" => Block :: WAXED_COPPER_GOLEM_STATUE , "waxed_exposed_copper_golem_statue" => Block :: WAXED_EXPOSED_COPPER_GOLEM_STATUE , "waxed_weathered_copper_golem_statue" => Block :: WAXED_WEATHERED_COPPER_GOLEM_STATUE , "waxed_oxidized_copper_golem_statue" => Block :: WAXED_OXIDIZED_COPPER_GOLEM_STATUE , "lightning_rod" => Block :: LIGHTNING_ROD , "exposed_lightning_rod" => Block :: EXPOSED_LIGHTNING_ROD , "weathered_lightning_rod" => Block :: WEATHERED_LIGHTNING_ROD , "oxidized_lightning_rod" => Block :: OXIDIZED_LIGHTNING_ROD , "waxed_lightning_rod" => Block :: WAXED_LIGHTNING_ROD , "waxed_exposed_lightning_rod" => Block :: WAXED_EXPOSED_LIGHTNING_ROD , "waxed_weathered_lightning_rod" => Block :: WAXED_WEATHERED_LIGHTNING_ROD , "waxed_oxidized_lightning_rod" => Block :: WAXED_OXIDIZED_LIGHTNING_ROD , "dripstone_block" => Block :: DRIPSTONE_BLOCK , "pointed_dripstone" => Block :: POINTED_DRIPSTONE , "sulfur_spike" => Block :: SULFUR_SPIKE , "cave_vines" => Block :: CAVE_VINES , "cave_vines_plant" => Block :: CAVE_VINES_PLANT , "spore_blossom" => Block :: SPORE_BLOSSOM , "azalea" => Block :: AZALEA , "flowering_azalea" => Block :: FLOWERING_AZALEA , "moss_carpet" => Block :: MOSS_CARPET , "pink_petals" => Block :: PINK_PETALS , "wildflowers" => Block :: WILDFLOWERS , "leaf_litter" => Block :: LEAF_LITTER , "moss_block" => Block :: MOSS_BLOCK , "big_dripleaf" => Block :: BIG_DRIPLEAF , "big_dripleaf_stem" => Block :: BIG_DRIPLEAF_STEM , "small_dripleaf" => Block :: SMALL_DRIPLEAF , "hanging_roots" => Block :: HANGING_ROOTS , "rooted_dirt" => Block :: ROOTED_DIRT , "mud" => Block :: MUD , "deepslate" => Block :: DEEPSLATE , "cobbled_deepslate" => Block :: COBBLED_DEEPSLATE , "cobbled_deepslate_stairs" => Block :: COBBLED_DEEPSLATE_STAIRS , "cobbled_deepslate_slab" => Block :: COBBLED_DEEPSLATE_SLAB , "cobbled_deepslate_wall" => Block :: COBBLED_DEEPSLATE_WALL , "polished_deepslate" => Block :: POLISHED_DEEPSLATE , "polished_deepslate_stairs" => Block :: POLISHED_DEEPSLATE_STAIRS , "polished_deepslate_slab" => Block :: POLISHED_DEEPSLATE_SLAB , "polished_deepslate_wall" => Block :: POLISHED_DEEPSLATE_WALL , "deepslate_tiles" => Block :: DEEPSLATE_TILES , "deepslate_tile_stairs" => Block :: DEEPSLATE_TILE_STAIRS , "deepslate_tile_slab" => Block :: DEEPSLATE_TILE_SLAB , "deepslate_tile_wall" => Block :: DEEPSLATE_TILE_WALL , "deepslate_bricks" => Block :: DEEPSLATE_BRICKS , "deepslate_brick_stairs" => Block :: DEEPSLATE_BRICK_STAIRS , "deepslate_brick_slab" => Block :: DEEPSLATE_BRICK_SLAB , "deepslate_brick_wall" => Block :: DEEPSLATE_BRICK_WALL , "chiseled_deepslate" => Block :: CHISELED_DEEPSLATE , "cracked_deepslate_bricks" => Block :: CRACKED_DEEPSLATE_BRICKS , "cracked_deepslate_tiles" => Block :: CRACKED_DEEPSLATE_TILES , "infested_deepslate" => Block :: INFESTED_DEEPSLATE , "smooth_basalt" => Block :: SMOOTH_BASALT , "raw_iron_block" => Block :: RAW_IRON_BLOCK , "raw_copper_block" => Block :: RAW_COPPER_BLOCK , "raw_gold_block" => Block :: RAW_GOLD_BLOCK , "potted_azalea_bush" => Block :: POTTED_AZALEA_BUSH , "potted_flowering_azalea_bush" => Block :: POTTED_FLOWERING_AZALEA_BUSH , "ochre_froglight" => Block :: OCHRE_FROGLIGHT , "verdant_froglight" => Block :: VERDANT_FROGLIGHT , "pearlescent_froglight" => Block :: PEARLESCENT_FROGLIGHT , "frogspawn" => Block :: FROGSPAWN , "reinforced_deepslate" => Block :: REINFORCED_DEEPSLATE , "decorated_pot" => Block :: DECORATED_POT , "crafter" => Block :: CRAFTER , "trial_spawner" => Block :: TRIAL_SPAWNER , "vault" => Block :: VAULT , "heavy_core" => Block :: HEAVY_CORE , "pale_moss_block" => Block :: PALE_MOSS_BLOCK , "pale_moss_carpet" => Block :: PALE_MOSS_CARPET , "pale_hanging_moss" => Block :: PALE_HANGING_MOSS , "open_eyeblossom" => Block :: OPEN_EYEBLOSSOM , "closed_eyeblossom" => Block :: CLOSED_EYEBLOSSOM , "potted_open_eyeblossom" => Block :: POTTED_OPEN_EYEBLOSSOM , "potted_closed_eyeblossom" => Block :: POTTED_CLOSED_EYEBLOSSOM , "firefly_bush" => Block :: FIREFLY_BUSH , }; pub(super) static BLOCK_ID_FROM_STATE_ID: [BlockId; 32366usize] = [ diff --git a/crates/pumpkin-data/src/generated/carver.rs b/crates/pumpkin-data/src/generated/carver.rs index fb5e6d6b7..d87d711e1 100644 --- a/crates/pumpkin-data/src/generated/carver.rs +++ b/crates/pumpkin-data/src/generated/carver.rs @@ -1,6 +1,6 @@ /* This file is generated. Do not edit manually. */ use pumpkin_util::math::float_provider::{ - ClampedNormalFloatProvider, ConstantFloatProvider, FloatProvider, NormalFloatProvider, + FloatProvider, NormalFloatProvider, TrapezoidFloatProvider, UniformFloatProvider, }; use pumpkin_util::y_offset::{AboveBottom, Absolute, BelowTop, YOffset}; @@ -63,7 +63,6 @@ pub struct CarverConfig { pub replaceable: crate::tag::Tag, pub additional: CarverAdditionalConfig, } -use super::*; pub const CANYON: CarverConfig = CarverConfig { probability: 0.01f32, y: HeightProvider::Uniform(UniformHeightProvider { diff --git a/crates/pumpkin-data/src/generated/chunk_gen_settings.rs b/crates/pumpkin-data/src/generated/chunk_gen_settings.rs index a6bd1fcb8..8cd3982f2 100644 --- a/crates/pumpkin-data/src/generated/chunk_gen_settings.rs +++ b/crates/pumpkin-data/src/generated/chunk_gen_settings.rs @@ -3,10 +3,7 @@ use crate::BlockState; use crate::biome::Biome; use crate::chunk::DoublePerlinNoiseParameters; use crate::dimension::Dimension; -use pumpkin_util::random::RandomDeriver; -use pumpkin_util::y_offset::Absolute; use pumpkin_util::y_offset::YOffset; -use std::{cell::RefCell, num::NonZeroUsize}; pub struct GenerationSettings { pub aquifers_enabled: bool, pub ore_veins_enabled: bool, diff --git a/crates/pumpkin-data/src/generated/damage_type.rs b/crates/pumpkin-data/src/generated/damage_type.rs index a4d1dc0e6..61d318a39 100644 --- a/crates/pumpkin-data/src/generated/damage_type.rs +++ b/crates/pumpkin-data/src/generated/damage_type.rs @@ -1,5 +1,5 @@ /* This file is generated. Do not edit manually. */ -use crate::tag::{RegistryKey, Tag, Taggable}; +use crate::tag::{RegistryKey, Taggable}; #[derive(Clone, Copy, PartialEq)] pub struct DamageType { pub death_message_type: DeathMessageType, diff --git a/crates/pumpkin-data/src/generated/data_component.rs b/crates/pumpkin-data/src/generated/data_component.rs index f863a94d7..c266d4ff5 100644 --- a/crates/pumpkin-data/src/generated/data_component.rs +++ b/crates/pumpkin-data/src/generated/data_component.rs @@ -1,5 +1,4 @@ /* This file is generated. Do not edit manually. */ -use crate::data_component_impl::*; #[derive(Copy, Clone, Hash, PartialEq, Eq)] #[repr(u8)] pub enum DataComponent { diff --git a/crates/pumpkin-data/src/generated/dimension.rs b/crates/pumpkin-data/src/generated/dimension.rs index dd2e0ea77..b460faf31 100644 --- a/crates/pumpkin-data/src/generated/dimension.rs +++ b/crates/pumpkin-data/src/generated/dimension.rs @@ -1,8 +1,6 @@ /* This file is generated. Do not edit manually. */ use pumpkin_util::math::int_provider::{ - BiasedToBottomIntProvider, ClampedIntProvider, ClampedNormalIntProvider, ConstantIntProvider, - IntProvider, NormalIntProvider, TrapezoidIntProvider, UniformIntProvider, WeightedEntry, - WeightedListIntProvider, + IntProvider, NormalIntProvider, UniformIntProvider, }; #[derive(Debug, Clone)] pub struct Dimension { diff --git a/crates/pumpkin-data/src/generated/game_rules.rs b/crates/pumpkin-data/src/generated/game_rules.rs index 012e92b74..33842ca6d 100644 --- a/crates/pumpkin-data/src/generated/game_rules.rs +++ b/crates/pumpkin-data/src/generated/game_rules.rs @@ -883,7 +883,7 @@ fn default_water_source_conversion() -> bool { GameRuleRegistry::default().water_source_conversion } mod as_string { - use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde::{Deserialize, Deserializer, Serializer}; use std::{fmt::Display, str::FromStr}; pub fn serialize( value: &T, diff --git a/crates/pumpkin-data/src/generated/item.rs b/crates/pumpkin-data/src/generated/item.rs index 4cbfb98fd..2cf417e8b 100644 --- a/crates/pumpkin-data/src/generated/item.rs +++ b/crates/pumpkin-data/src/generated/item.rs @@ -13,8 +13,7 @@ use crate::data_component_impl::*; use crate::effect::StatusEffect; use crate::sound::Sound; use crate::tag::{RegistryKey, Taggable}; -use crate::{AttributeModifierSlot, tag}; -use pumpkin_nbt::{compound::NbtCompound, tag::NbtTag}; +use crate::AttributeModifierSlot; use pumpkin_util::text::TextComponent; use std::borrow::Cow; use std::hash::{Hash, Hasher}; @@ -64240,16 +64239,18 @@ impl Item { }; #[must_use] pub fn translated_name(&self) -> TextComponent { - TextComponent::translate( - self.components - .iter() - .find_map(|(id, data)| { - (id == &ItemName) - .then(|| data.as_any().downcast_ref::().unwrap().name) - }) - .unwrap(), - &[], - ) + let name = self + .components + .iter() + .find_map(|(id, data)| { + if id == &ItemName { + data.as_any().downcast_ref::().map(|n| n.name) + } else { + None + } + }) + .unwrap_or(self.registry_key); + TextComponent::translate(name, &[]) } #[doc = "Try to parse an item from a resource location string."] #[must_use] diff --git a/crates/pumpkin-data/src/generated/potion.rs b/crates/pumpkin-data/src/generated/potion.rs index 94f4247f1..f3fba00e9 100644 --- a/crates/pumpkin-data/src/generated/potion.rs +++ b/crates/pumpkin-data/src/generated/potion.rs @@ -1,6 +1,5 @@ /* This file is generated. Do not edit manually. */ use crate::effect::StatusEffect; -use std::hash::Hash; pub struct Potion { pub id: u8, pub name: &'static str, diff --git a/crates/pumpkin-data/src/generated/recipes.rs b/crates/pumpkin-data/src/generated/recipes.rs index 427fc4b84..84790cdfc 100644 --- a/crates/pumpkin-data/src/generated/recipes.rs +++ b/crates/pumpkin-data/src/generated/recipes.rs @@ -1,7 +1,7 @@ /* This file is generated. Do not edit manually. */ use crate::item::Item; use crate::tag::Taggable; -use serde::{Deserialize, Serialize}; +use serde::Serialize; #[derive(Clone, Debug, Serialize)] pub enum CraftingRecipeTypes { CraftingShaped { diff --git a/crates/pumpkin-data/src/generated/structures.rs b/crates/pumpkin-data/src/generated/structures.rs index 84de0f865..1492aef38 100644 --- a/crates/pumpkin-data/src/generated/structures.rs +++ b/crates/pumpkin-data/src/generated/structures.rs @@ -1,8 +1,6 @@ /* This file is generated. Do not edit manually. */ -use pumpkin_util::math::floor_div; use pumpkin_util::random::{ - RandomGenerator, RandomImpl, get_carver_seed, get_region_seed, legacy_rand::LegacyRand, - xoroshiro128::Xoroshiro, + RandomGenerator, RandomImpl, }; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub enum StructureKeys { diff --git a/crates/pumpkin-data/src/item_stack/mod.rs b/crates/pumpkin-data/src/item_stack/mod.rs index f0f6ecd49..123c1cc04 100644 --- a/crates/pumpkin-data/src/item_stack/mod.rs +++ b/crates/pumpkin-data/src/item_stack/mod.rs @@ -133,7 +133,10 @@ impl ItemStack { item, patch: Vec::new(), - uid: NonZeroI32::new(1).unwrap(), + uid: match NonZeroI32::new(1) { + Some(v) => v, + None => panic!("1 is non-zero"), + }, } } @@ -176,8 +179,7 @@ impl ItemStack { self.patch.push((id, component)); return self .patch - .last_mut() - .unwrap() + .last_mut()? .1 .as_mut() .map(|c| get_mut::(c.as_mut())); @@ -209,7 +211,7 @@ impl ItemStack { item: &Item::AIR, patch: Vec::new(), - uid: NonZeroI32::new(i32::MIN).unwrap(), // white lie - Bedrock `uid` is never sent if the stack is empty + uid: NonZeroI32::MIN, // white lie - Bedrock `uid` is never sent if the stack is empty }; #[must_use] @@ -731,7 +733,7 @@ impl From<&RecipeResultStruct> for ItemStack { Self::new( value.count, Item::from_registry_key(value.id.strip_prefix("minecraft:").unwrap_or(value.id)) - .expect("Crafting recipe gives invalid item"), + .unwrap_or(&Item::AIR), ) } } diff --git a/crates/pumpkin-data/src/lib.rs b/crates/pumpkin-data/src/lib.rs index 69004c268..b9c4525fd 100644 --- a/crates/pumpkin-data/src/lib.rs +++ b/crates/pumpkin-data/src/lib.rs @@ -1,11 +1,13 @@ -#![allow(unused_imports)] #![allow( clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo, clippy::undocumented_unsafe_blocks, - clippy::if_then_some_else_none + clippy::if_then_some_else_none, + clippy::unwrap_used, + clippy::expect_used, + clippy::panic )] #[rustfmt::skip] diff --git a/crates/pumpkin-inventory/src/crafting/crafting_screen_handler.rs b/crates/pumpkin-inventory/src/crafting/crafting_screen_handler.rs index b2e867a94..a0837b453 100644 --- a/crates/pumpkin-inventory/src/crafting/crafting_screen_handler.rs +++ b/crates/pumpkin-inventory/src/crafting/crafting_screen_handler.rs @@ -90,7 +90,10 @@ async fn recipe_matches( result, .. }) => { - if pattern.len() != input_height || pattern.first().unwrap().len() != input_width { + #[allow(clippy::redundant_closure_for_method_calls)] + if pattern.len() != input_height + || pattern.first().map_or(0, |f| f.len()) != input_width + { return None; } @@ -120,10 +123,13 @@ async fn recipe_matches( continue; } - let ingredient = key + let Some(ingredient) = key .iter() .find_map(|(k, v)| (*k == current_key).then_some(v)) - .expect("Crafting recipe used invalid key"); + else { + matched = false; + break 'outer; + }; if !ingredient.match_item(slot.item) { matched = false; @@ -136,7 +142,10 @@ async fn recipe_matches( matched = true; 'outer: for y in 0..pattern.len() { for x in 0..pattern[y].len() { - let current_key = pattern[y].chars().nth(x).unwrap(); + let Some(current_key) = pattern[y].chars().nth(x) else { + matched = false; + break 'outer; + }; let slot = inventory .get_stack( (y + y_offset) * inventory.get_height() @@ -150,10 +159,13 @@ async fn recipe_matches( } continue; } - let ingredient = key + let Some(ingredient) = key .iter() .find_map(|(k, v)| (*k == current_key).then_some(v)) - .expect("Crafting recipe used invalid key"); + else { + matched = false; + break 'outer; + }; if !ingredient.match_item(slot.item) { matched = false; break 'outer; @@ -242,7 +254,10 @@ async fn recipe_matches( result, .. }) => { - if pattern.len() != input_height || pattern.first().unwrap().len() != input_width { + #[allow(clippy::redundant_closure_for_method_calls)] + if pattern.len() != input_height + || pattern.first().map_or(0, |f| f.len()) != input_width + { return None; } if count @@ -268,11 +283,12 @@ async fn recipe_matches( } continue; } - let ingredient = key - .iter() - .find(|(k, _)| *k == current_key) - .map(|(_, v)| v) - .expect("Crafting recipe used invalid key"); + let Some(ingredient) = + key.iter().find(|(k, _)| *k == current_key).map(|(_, v)| v) + else { + matched = false; + break 'outer; + }; if !ingredient.match_item(slot.item) { matched = false; break 'outer; diff --git a/crates/pumpkin-inventory/src/lib.rs b/crates/pumpkin-inventory/src/lib.rs index 865cf2c1b..9c94bd891 100644 --- a/crates/pumpkin-inventory/src/lib.rs +++ b/crates/pumpkin-inventory/src/lib.rs @@ -13,6 +13,9 @@ //! - [`SyncHandler`] - Synchronizes inventory state between server and client //! //! # Module Structure + +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] //! //! - [`player`] - Player inventory and screen handler implementations //! - [`crafting`] - Crafting table and inventory crafting mechanics diff --git a/crates/pumpkin-inventory/src/player/player_inventory.rs b/crates/pumpkin-inventory/src/player/player_inventory.rs index 565cb206c..f98cdf9bd 100644 --- a/crates/pumpkin-inventory/src/player/player_inventory.rs +++ b/crates/pumpkin-inventory/src/player/player_inventory.rs @@ -116,7 +116,9 @@ impl PlayerInventory { match hand { Hand::Right => self.set_held_item(stack).await, Hand::Left => { - let slot = self.equipment_slots.get(&Self::OFF_HAND_SLOT).unwrap(); + let Some(slot) = self.equipment_slots.get(&Self::OFF_HAND_SLOT) else { + return; + }; self.entity_equipment.lock().await.put(slot, stack); } } @@ -137,7 +139,9 @@ impl PlayerInventory { /// /// Mojang name: `getOffHandStack` pub async fn off_hand_item(&self) -> ItemStack { - let slot = self.equipment_slots.get(&Self::OFF_HAND_SLOT).unwrap(); + let Some(slot) = self.equipment_slots.get(&Self::OFF_HAND_SLOT) else { + return ItemStack::EMPTY.clone(); + }; self.entity_equipment.lock().await.get(slot) } @@ -146,7 +150,9 @@ impl PlayerInventory { /// # Returns /// The new main hand item and new off-hand item. pub async fn swap_item(&self) -> (ItemStack, ItemStack) { - let slot = self.equipment_slots.get(&Self::OFF_HAND_SLOT).unwrap(); + let Some(slot) = self.equipment_slots.get(&Self::OFF_HAND_SLOT) else { + return (ItemStack::EMPTY.clone(), ItemStack::EMPTY.clone()); + }; let mut equipment = self.entity_equipment.lock().await; let selected = self.get_selected_slot() as usize; let mut main_inv = self.main_inventory.write().await; @@ -514,8 +520,6 @@ impl PlayerInventory { pub fn set_selected_slot(&self, slot: u8) { if Self::is_valid_hotbar_index(slot as usize) { self.selected_slot.store(slot, Ordering::Relaxed); - } else { - panic!("Invalid hotbar slot: {slot}"); } } diff --git a/crates/pumpkin-inventory/src/screen_handler.rs b/crates/pumpkin-inventory/src/screen_handler.rs index e8c046007..510da0425 100644 --- a/crates/pumpkin-inventory/src/screen_handler.rs +++ b/crates/pumpkin-inventory/src/screen_handler.rs @@ -917,15 +917,14 @@ pub trait ScreenHandler: Send + Sync { if (stack.are_items_and_components_equal(&cursor_stack) || stack.is_empty()) && slot.can_insert(&cursor_stack).await { - let mut inserting_count = if drag_button == 0 { - initial_count / behaviour.drag_slots.len() as u8 - } else if drag_button == 1 { - 1 - } else if drag_button == 2 { - cursor_stack.item_count = cursor_stack.get_max_stack_size(); - cursor_stack.item_count - } else { - panic!("Invalid drag button: {drag_button}"); + let mut inserting_count = match drag_button { + 0 => initial_count / behaviour.drag_slots.len() as u8, + 1 => 1, + 2 => { + cursor_stack.item_count = cursor_stack.get_max_stack_size(); + cursor_stack.item_count + } + _ => 0, }; inserting_count = inserting_count .min(max( diff --git a/crates/pumpkin-inventory/src/stonecutter_screen_handler.rs b/crates/pumpkin-inventory/src/stonecutter_screen_handler.rs index e50eb0765..7f9c9e6e8 100644 --- a/crates/pumpkin-inventory/src/stonecutter_screen_handler.rs +++ b/crates/pumpkin-inventory/src/stonecutter_screen_handler.rs @@ -70,8 +70,7 @@ impl StonecutterScreenHandler { if recipe_index != u8::MAX && (recipe_index as usize) < available_recipes.len() { let recipe = available_recipes[recipe_index as usize]; - let item = - Item::from_registry_key(recipe.result.id).expect("Invalid recipe result item"); + let item = Item::from_registry_key(recipe.result.id).unwrap_or(&Item::AIR); let result = ItemStack::new(recipe.result.count, item); self.output_inventory.set_stack(0, result).await; } else { diff --git a/crates/pumpkin-macros/src/lib.rs b/crates/pumpkin-macros/src/lib.rs index 971275384..a17e9a42a 100644 --- a/crates/pumpkin-macros/src/lib.rs +++ b/crates/pumpkin-macros/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used)] + use heck::ToShoutySnakeCase; use proc_macro::TokenStream; use proc_macro_error2::{abort, abort_call_site}; diff --git a/crates/pumpkin-nbt/benches/nbt.rs b/crates/pumpkin-nbt/benches/nbt.rs index 829fe0cc0..04b0f9149 100644 --- a/crates/pumpkin-nbt/benches/nbt.rs +++ b/crates/pumpkin-nbt/benches/nbt.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used)] + use criterion::{Criterion, criterion_group, criterion_main}; use pumpkin_nbt::{Nbt, NbtCompound, deserializer, tag::NbtTag}; use std::io::Cursor; diff --git a/crates/pumpkin-nbt/src/lib.rs b/crates/pumpkin-nbt/src/lib.rs index 28b6dd5ae..4c4c5f76d 100644 --- a/crates/pumpkin-nbt/src/lib.rs +++ b/crates/pumpkin-nbt/src/lib.rs @@ -4,6 +4,9 @@ //! NBT, Bedrock network NBT, and gzip-compressed NBT. Data is handled directly //! via [`Nbt`], [`NbtCompound`], and [`NbtTag`]. +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] + use std::{ io::{self, Write}, ops::Deref, @@ -156,11 +159,13 @@ impl Nbt { pub fn write(self) -> Bytes { let mut bytes = Vec::new(); let mut writer = NbtWriteHelperJava::new(&mut bytes); - writer.write_u8(COMPOUND_ID).unwrap(); - NbtTag::String(self.name.into()) - .serialize_data(&mut writer) - .unwrap(); - self.root_tag.serialize_content(&mut writer).unwrap(); + if writer.write_u8(COMPOUND_ID).is_ok() + && NbtTag::String(self.name.into()) + .serialize_data(&mut writer) + .is_ok() + { + let _ = self.root_tag.serialize_content(&mut writer); + } bytes.into() } @@ -170,11 +175,13 @@ impl Nbt { pub fn write_bedrock(self) -> Bytes { let mut bytes = Vec::new(); let mut writer = NbtWriteHelperBedrock::new(&mut bytes); - writer.write_u8(COMPOUND_ID).unwrap(); - NbtTag::String(self.name.into()) - .serialize_data(&mut writer) - .unwrap(); - self.root_tag.serialize_content(&mut writer).unwrap(); + if writer.write_u8(COMPOUND_ID).is_ok() + && NbtTag::String(self.name.into()) + .serialize_data(&mut writer) + .is_ok() + { + let _ = self.root_tag.serialize_content(&mut writer); + } bytes.into() } @@ -197,8 +204,9 @@ impl Nbt { let mut bytes = Vec::new(); let mut writer = NbtWriteHelperJava::new(&mut bytes); - writer.write_u8(COMPOUND_ID).unwrap(); - self.root_tag.serialize_content(&mut writer).unwrap(); + if writer.write_u8(COMPOUND_ID).is_ok() { + let _ = self.root_tag.serialize_content(&mut writer); + } bytes.into() } diff --git a/crates/pumpkin-nbt/src/nbt_ops.rs b/crates/pumpkin-nbt/src/nbt_ops.rs index da699573b..c9f5e8124 100644 --- a/crates/pumpkin-nbt/src/nbt_ops.rs +++ b/crates/pumpkin-nbt/src/nbt_ops.rs @@ -141,14 +141,12 @@ impl DynamicOps for NbtOps { NbtTag::List(l) => { // Check the type of this list. // If the list contains compounds, we try unwrapping them. - if !l.is_empty() - && let NbtTag::Compound(_) = l.first().unwrap() - { + if let Some(NbtTag::Compound(_)) = l.first() { DataResult::new_success(NbtIter::CompoundList(l.into_iter().map(|c| { if let NbtTag::Compound(compound) = c { Self::try_unwrap(compound) } else { - c.clone() + c } }))) } else { @@ -242,8 +240,13 @@ impl DynamicOps for NbtOps { } else { NbtCompound::new() }; - compound.put(key.extract_string().unwrap(), value); - DataResult::new_success(compound.into()) + key.extract_string().map_or_else( + || DataResult::new_error(format!("Key is not a string: {key}")), + |key_str| { + compound.put(key_str, value); + DataResult::new_success(compound.into()) + }, + ) } } @@ -334,7 +337,10 @@ impl NbtOps { fn try_unwrap(mut compound: NbtCompound) -> NbtTag { if compound.child_tags.len() == 1 && compound.has("") { // Remove the element to own the contained tag. - compound.child_tags.remove("").unwrap() + compound + .child_tags + .remove("") + .unwrap_or_else(|| NbtTag::from(compound)) } else { NbtTag::from(compound) } diff --git a/crates/pumpkin-nbt/src/tag.rs b/crates/pumpkin-nbt/src/tag.rs index 55dc35cfb..3de53c66b 100644 --- a/crates/pumpkin-nbt/src/tag.rs +++ b/crates/pumpkin-nbt/src/tag.rs @@ -83,7 +83,10 @@ impl NbtTag { if let Self::Compound(mut compound) = tag { // Try to get the wrapped tag, stored by "". if Self::is_wrapper_compound(&compound) { - compound.child_tags.remove("").unwrap() + compound + .child_tags + .remove("") + .unwrap_or(Self::Compound(compound)) } else { Self::Compound(compound) } diff --git a/crates/pumpkin-plugin-api/src/commands.rs b/crates/pumpkin-plugin-api/src/commands.rs index 9c7c0ef6c..a43c2fb49 100644 --- a/crates/pumpkin-plugin-api/src/commands.rs +++ b/crates/pumpkin-plugin-api/src/commands.rs @@ -47,7 +47,7 @@ impl Command { COMMAND_HANDLERS .lock() - .unwrap() + .unwrap_or_else(|e| e.into_inner()) .insert(id, Box::new(handler)); self.execute_with_handler_id(id); @@ -67,7 +67,7 @@ impl CommandNode { COMMAND_HANDLERS .lock() - .unwrap() + .unwrap_or_else(|e| e.into_inner()) .insert(id, Box::new(handler)); self.execute_with_handler_id(id); diff --git a/crates/pumpkin-plugin-api/src/events/mod.rs b/crates/pumpkin-plugin-api/src/events/mod.rs index 70ce03379..42f9a5e5b 100644 --- a/crates/pumpkin-plugin-api/src/events/mod.rs +++ b/crates/pumpkin-plugin-api/src/events/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::panic)] + use std::{ collections::BTreeMap, marker::PhantomData, diff --git a/crates/pumpkin-plugin-api/src/forms.rs b/crates/pumpkin-plugin-api/src/forms.rs index ece8b469f..2816e7692 100644 --- a/crates/pumpkin-plugin-api/src/forms.rs +++ b/crates/pumpkin-plugin-api/src/forms.rs @@ -213,12 +213,12 @@ impl FormResponse { None => Self::Closed, Some(s) => { if let Ok(val) = serde_json::from_str::(&s) { - if val.is_u64() { - Self::Simple(val.as_u64().unwrap() as u32) - } else if val.is_boolean() { - Self::Modal(val.as_bool().unwrap()) - } else if val.is_array() { - Self::Custom(val.as_array().unwrap().clone()) + if let Some(num) = val.as_u64() { + Self::Simple(num as u32) + } else if let Some(b) = val.as_bool() { + Self::Modal(b) + } else if let Some(arr) = val.as_array() { + Self::Custom(arr.clone()) } else { Self::Closed // Or some error state } diff --git a/crates/pumpkin-plugin-api/src/lib.rs b/crates/pumpkin-plugin-api/src/lib.rs index a05b2f2ea..700a5b039 100644 --- a/crates/pumpkin-plugin-api/src/lib.rs +++ b/crates/pumpkin-plugin-api/src/lib.rs @@ -7,8 +7,10 @@ clippy::all, clippy::pedantic, clippy::nursery, - clippy::cargo + clippy::cargo, + clippy::panic )] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] //! //! This crate provides everything needed to write a Pumpkin server plugin compiled //! to WebAssembly. A plugin consists of a type that implements [`Plugin`], registered @@ -149,7 +151,7 @@ impl wit::Guest for Component { /// /// Returns the event unchanged if no handler is registered for the given id. fn handle_event(event_id: u32, server: Server, event: events::Event) -> events::Event { - let handlers = EVENT_HANDLERS.lock().unwrap(); + let handlers = EVENT_HANDLERS.lock().unwrap_or_else(|e| e.into_inner()); if let Some(handler) = handlers.get(&event_id) { handler.handle_erased(server, event) } else { @@ -166,7 +168,7 @@ impl wit::Guest for Component { server: Server, args: command::ConsumedArgs, ) -> Result { - let handlers = COMMAND_HANDLERS.lock().unwrap(); + let handlers = COMMAND_HANDLERS.lock().unwrap_or_else(|e| e.into_inner()); handlers.get(&command_id).map_or_else( || { Err(command::CommandError::CommandFailed(TextComponent::text( @@ -179,12 +181,14 @@ impl wit::Guest for Component { /// WIT entry point — dispatches a scheduled task invocation to the registered handler for `handler_id`. fn handle_task(handler_id: u32, server: Server) { - let mut handlers = TASK_HANDLERS.lock().unwrap(); + let mut handlers = TASK_HANDLERS.lock().unwrap_or_else(|e| e.into_inner()); handlers.handle(handler_id, server); } fn handle_ai_goal_can_start(goal_id: u32, server: Server, entity: entity::Entity) -> bool { - let mut handlers = crate::ai::AI_GOAL_HANDLERS.lock().unwrap(); + let mut handlers = crate::ai::AI_GOAL_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()); if let Some(goal) = handlers.handlers.get_mut(&goal_id) { goal.can_start(server, entity) } else { @@ -197,7 +201,9 @@ impl wit::Guest for Component { server: Server, entity: entity::Entity, ) -> bool { - let mut handlers = crate::ai::AI_GOAL_HANDLERS.lock().unwrap(); + let mut handlers = crate::ai::AI_GOAL_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()); if let Some(goal) = handlers.handlers.get_mut(&goal_id) { goal.should_continue(server, entity) } else { @@ -206,21 +212,27 @@ impl wit::Guest for Component { } fn handle_ai_goal_start(goal_id: u32, server: Server, entity: entity::Entity) { - let mut handlers = crate::ai::AI_GOAL_HANDLERS.lock().unwrap(); + let mut handlers = crate::ai::AI_GOAL_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()); if let Some(goal) = handlers.handlers.get_mut(&goal_id) { goal.start(server, entity); } } fn handle_ai_goal_tick(goal_id: u32, server: Server, entity: entity::Entity) { - let mut handlers = crate::ai::AI_GOAL_HANDLERS.lock().unwrap(); + let mut handlers = crate::ai::AI_GOAL_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()); if let Some(goal) = handlers.handlers.get_mut(&goal_id) { goal.tick(server, entity); } } fn handle_ai_goal_stop(goal_id: u32, server: Server, entity: entity::Entity) { - let mut handlers = crate::ai::AI_GOAL_HANDLERS.lock().unwrap(); + let mut handlers = crate::ai::AI_GOAL_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()); if let Some(goal) = handlers.handlers.get_mut(&goal_id) { goal.stop(server, entity); } @@ -271,6 +283,7 @@ pub fn register_plugin(build_plugin: fn() -> Box) { /// If called before [`register_plugin`] has initialized `PLUGIN`. fn plugin() -> &'static mut dyn Plugin { #[expect(static_mut_refs)] + #[allow(clippy::unwrap_used)] unsafe { PLUGIN.as_deref_mut().unwrap() } diff --git a/crates/pumpkin-plugin-api/src/logging.rs b/crates/pumpkin-plugin-api/src/logging.rs index 768fc387d..bd9cc8538 100644 --- a/crates/pumpkin-plugin-api/src/logging.rs +++ b/crates/pumpkin-plugin-api/src/logging.rs @@ -40,9 +40,9 @@ impl tracing::Subscriber for WitSubscriber { /// Serialises the tracing event with `postcard` and sends it to the host via WIT. fn event(&self, event: &tracing::Event<'_>) { - let serialized = - postcard::to_allocvec(&event.as_serde()).expect("failed to serialize tracing event"); - wit::pumpkin::plugin::logging::log_tracing(&serialized); + if let Ok(serialized) = postcard::to_allocvec(&event.as_serde()) { + wit::pumpkin::plugin::logging::log_tracing(&serialized); + } } /// No-op — span entry is not tracked. diff --git a/crates/pumpkin-plugin-api/src/scheduler.rs b/crates/pumpkin-plugin-api/src/scheduler.rs index df439b8a6..9b44b1bfe 100644 --- a/crates/pumpkin-plugin-api/src/scheduler.rs +++ b/crates/pumpkin-plugin-api/src/scheduler.rs @@ -114,7 +114,10 @@ pub fn schedule_delayed_task(delay_ticks: u64, handler: F) -> u32 where F: FnMut(Server) + Send + 'static, { - let handler_id = TASK_HANDLERS.lock().unwrap().register(Box::new(handler)); + let handler_id = TASK_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()) + .register(Box::new(handler)); scheduler::schedule_delayed_task(handler_id, delay_ticks) } @@ -124,7 +127,10 @@ pub fn schedule_repeating_task(delay_ticks: u64, period_ticks: u64, handler: where F: FnMut(Server) + Send + 'static, { - let handler_id = TASK_HANDLERS.lock().unwrap().register(Box::new(handler)); + let handler_id = TASK_HANDLERS + .lock() + .unwrap_or_else(|e| e.into_inner()) + .register(Box::new(handler)); scheduler::schedule_repeating_task(handler_id, delay_ticks, period_ticks) } diff --git a/crates/pumpkin-protocol/src/codec/recipe.rs b/crates/pumpkin-protocol/src/codec/recipe.rs index 3aeea46c5..2a6014231 100644 --- a/crates/pumpkin-protocol/src/codec/recipe.rs +++ b/crates/pumpkin-protocol/src/codec/recipe.rs @@ -18,9 +18,7 @@ impl OwnedRecipeIngredient { let name = format!("minecraft:{}", item.registry_key); name == *id } - Self::Tagged(tag) => item - .is_tagged_with(tag) - .expect("Crafting recipe used invalid tag"), + Self::Tagged(tag) => item.is_tagged_with(tag).unwrap_or(false), Self::OneOf(ids) => { let name = format!("minecraft:{}", item.registry_key); ids.contains(&name) diff --git a/crates/pumpkin-protocol/src/codec/var_int.rs b/crates/pumpkin-protocol/src/codec/var_int.rs index 5986bf745..734d090d8 100644 --- a/crates/pumpkin-protocol/src/codec/var_int.rs +++ b/crates/pumpkin-protocol/src/codec/var_int.rs @@ -21,6 +21,7 @@ pub struct VarInt(pub VarIntType); impl VarInt { /// The maximum number of bytes a `VarInt` can occupy. + #[allow(clippy::unwrap_used)] pub const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(5).unwrap(); #[must_use] diff --git a/crates/pumpkin-protocol/src/codec/var_long.rs b/crates/pumpkin-protocol/src/codec/var_long.rs index 71ed1f82c..4d97e1116 100644 --- a/crates/pumpkin-protocol/src/codec/var_long.rs +++ b/crates/pumpkin-protocol/src/codec/var_long.rs @@ -20,6 +20,7 @@ pub struct VarLong(pub VarLongType); impl VarLong { /// The maximum number of bytes a `VarLong` can occupy. + #[allow(clippy::unwrap_used)] pub const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(10).unwrap(); #[must_use] diff --git a/crates/pumpkin-protocol/src/codec/var_uint.rs b/crates/pumpkin-protocol/src/codec/var_uint.rs index 3831d1028..0475037aa 100644 --- a/crates/pumpkin-protocol/src/codec/var_uint.rs +++ b/crates/pumpkin-protocol/src/codec/var_uint.rs @@ -20,6 +20,7 @@ pub struct VarUInt(pub VarUIntType); impl VarUInt { /// The maximum number of bytes a `VarUInt` can occupy. + #[allow(clippy::unwrap_used)] pub const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(5).unwrap(); #[must_use] diff --git a/crates/pumpkin-protocol/src/codec/var_ulong.rs b/crates/pumpkin-protocol/src/codec/var_ulong.rs index b33de9c54..6d3139712 100644 --- a/crates/pumpkin-protocol/src/codec/var_ulong.rs +++ b/crates/pumpkin-protocol/src/codec/var_ulong.rs @@ -20,6 +20,7 @@ pub struct VarULong(pub VarULongType); impl VarULong { /// The maximum number of bytes a `VarULong` can occupy. + #[allow(clippy::unwrap_used)] pub const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(10).unwrap(); #[must_use] diff --git a/crates/pumpkin-protocol/src/lib.rs b/crates/pumpkin-protocol/src/lib.rs index e4a8602a1..237116486 100644 --- a/crates/pumpkin-protocol/src/lib.rs +++ b/crates/pumpkin-protocol/src/lib.rs @@ -1,3 +1,6 @@ +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] + use std::{ io::{Error, Read, Write}, pin::Pin, diff --git a/crates/pumpkin-protocol/src/serial/deserializer.rs b/crates/pumpkin-protocol/src/serial/deserializer.rs index da0f0268b..97e99aba3 100644 --- a/crates/pumpkin-protocol/src/serial/deserializer.rs +++ b/crates/pumpkin-protocol/src/serial/deserializer.rs @@ -290,7 +290,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for i16 { } let (bytes, rest) = buf.split_at(2); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid i16 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -301,7 +304,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for i32 { } let (bytes, rest) = buf.split_at(4); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid i32 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -312,7 +318,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for i64 { } let (bytes, rest) = buf.split_at(8); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid i64 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -323,7 +332,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u16 { } let (bytes, rest) = buf.split_at(2); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid u16 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -334,7 +346,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u32 { } let (bytes, rest) = buf.split_at(4); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid u32 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -345,7 +360,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u64 { } let (bytes, rest) = buf.split_at(8); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid u64 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -356,7 +374,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for f32 { } let (bytes, rest) = buf.split_at(4); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid f32 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -367,7 +388,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for f64 { } let (bytes, rest) = buf.split_at(8); *buf = rest; - Ok(Self::from_le_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid f64 slice"))?; + Ok(Self::from_le_bytes(arr)) } } @@ -392,7 +416,10 @@ impl<'a> crate::serial::PacketReadSlice<'a> for uuid::Uuid { } let (bytes, rest) = buf.split_at(16); *buf = rest; - Ok(Self::from_bytes(bytes.try_into().unwrap())) + let arr = bytes + .try_into() + .map_err(|_| Error::new(ErrorKind::InvalidData, "invalid Uuid slice"))?; + Ok(Self::from_bytes(arr)) } } diff --git a/crates/pumpkin-util/src/jwt/mod.rs b/crates/pumpkin-util/src/jwt/mod.rs index 5ee498903..639b26964 100644 --- a/crates/pumpkin-util/src/jwt/mod.rs +++ b/crates/pumpkin-util/src/jwt/mod.rs @@ -474,7 +474,7 @@ fn verify_oidc_claims(payload: &Value, expected_issuer: Option<&str>) -> Result< .ok_or_else(|| AuthError::PublicKeyBuild("OIDC payload missing exp".into()))?; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap() + .map_err(|_| AuthError::PublicKeyBuild("Clock before UNIX epoch".into()))? .as_secs(); if now > exp { return Err(AuthError::PublicKeyBuild("OIDC token expired".into())); diff --git a/crates/pumpkin-util/src/lib.rs b/crates/pumpkin-util/src/lib.rs index a73fbdaf4..bf1c27378 100644 --- a/crates/pumpkin-util/src/lib.rs +++ b/crates/pumpkin-util/src/lib.rs @@ -1,3 +1,8 @@ +//! Utility functions and shared types for the Pumpkin server. + +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::panic))] + use serde::{Deserialize, Serialize}; use std::ops::{Index, IndexMut}; @@ -57,13 +62,12 @@ macro_rules! global_path { ($path:expr) => {{ use std::path::Path; Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .parent() - .unwrap() + .ancestors() + .nth(2) + .unwrap_or_else(|| Path::new(".")) .join(file!()) .parent() - .unwrap() + .unwrap_or_else(|| Path::new(".")) .join($path) }}; } @@ -188,11 +192,12 @@ impl<'a, T> MutableSplitSlice<'a, T> { /// /// # Panics /// * if `index` is out of bounds of the base slice. + #[allow(clippy::expect_used, clippy::panic)] pub const fn extract_ith(base: &'a mut [T], index: usize) -> (&'a mut T, Self) { let (start, end_inclusive) = base.split_at_mut(index); - let (value, end) = end_inclusive - .split_first_mut() - .expect("Index is not in base slice"); + let Some((value, end)) = end_inclusive.split_first_mut() else { + panic!("Index is not in base slice"); + }; (value, Self { start, end }) } @@ -214,6 +219,7 @@ impl Index for MutableSplitSlice<'_, T> { type Output = T; #[expect(clippy::comparison_chain)] + #[allow(clippy::panic)] fn index(&self, index: usize) -> &Self::Output { if index < self.start.len() { &self.start[index] @@ -239,6 +245,7 @@ pub struct DoublePerlinNoiseParametersCodec { impl IndexMut for MutableSplitSlice<'_, T> { #[expect(clippy::comparison_chain)] + #[allow(clippy::panic)] fn index_mut(&mut self, index: usize) -> &mut Self::Output { if index < self.start.len() { &mut self.start[index] diff --git a/crates/pumpkin-util/src/math/int_provider.rs b/crates/pumpkin-util/src/math/int_provider.rs index 9a703cb06..895d25cb1 100644 --- a/crates/pumpkin-util/src/math/int_provider.rs +++ b/crates/pumpkin-util/src/math/int_provider.rs @@ -645,7 +645,9 @@ impl WeightedListIntProvider { } // Fallback to the last entry. - self.distribution.last().unwrap().data.get(random) + self.distribution + .last() + .map_or(0, |entry| entry.data.get(random)) } /// Returns the maximum possible value from all entries. diff --git a/crates/pumpkin-util/src/noise/perlin.rs b/crates/pumpkin-util/src/noise/perlin.rs index c6f8b63c8..966f34dd3 100644 --- a/crates/pumpkin-util/src/noise/perlin.rs +++ b/crates/pumpkin-util/src/noise/perlin.rs @@ -317,8 +317,11 @@ impl OctavePerlinNoiseSampler { let mut octaves = Vec::from_iter(octaves); octaves.sort(); - let i = -**octaves.first().expect("we should have some octaves"); - let j = **octaves.last().expect("we should have some octaves"); + let (Some(&&first), Some(&&last)) = (octaves.first(), octaves.last()) else { + return (0, Vec::new()); + }; + let i = -first; + let j = last; let k = i + j + 1; let mut double_list = vec![0.0; k as usize]; diff --git a/crates/pumpkin-util/src/noise/simplex.rs b/crates/pumpkin-util/src/noise/simplex.rs index 262072c72..f32efe6c7 100644 --- a/crates/pumpkin-util/src/noise/simplex.rs +++ b/crates/pumpkin-util/src/noise/simplex.rs @@ -297,8 +297,15 @@ impl OctaveSimplexNoiseSampler { let mut octaves = Vec::from_iter(octaves); octaves.sort(); - let i = -**octaves.first().expect("Should have some octaves"); - let j = **octaves.last().expect("Should have some octaves"); + let (Some(&&first), Some(&&last)) = (octaves.first(), octaves.last()) else { + return Self { + octave_samplers: Vec::new(), + persistence: 0.0, + lacunarity: 0.0, + }; + }; + let i = -first; + let j = last; let k = i.wrapping_add(j).wrapping_add(1); let sampler = SimplexNoiseSampler::new(random); diff --git a/crates/pumpkin-util/src/permission.rs b/crates/pumpkin-util/src/permission.rs index b1203924a..abc42fe6a 100644 --- a/crates/pumpkin-util/src/permission.rs +++ b/crates/pumpkin-util/src/permission.rs @@ -107,6 +107,7 @@ impl PermissionRegistry { /// /// # Parameters /// - `permission`: The `Permission` instance to add. + #[allow(clippy::expect_used)] pub fn register_permission_or_panic(&mut self, permission: Permission) { self.register_permission(permission) .expect("Permission should have been registered successfully"); @@ -302,9 +303,9 @@ impl PermissionManager { // Check for inherited permissions from parent nodes for (node, value) in attachment.get_permissions() { if let Some(permission) = reg.get_permission(node) - && permission.children.contains_key(permission_node) + && let Some(child_val) = permission.children.get(permission_node) { - return *value && *permission.children.get(permission_node).unwrap(); + return *value && *child_val; } } } diff --git a/crates/pumpkin-util/src/random/mod.rs b/crates/pumpkin-util/src/random/mod.rs index 0aa96f88c..8739702c7 100644 --- a/crates/pumpkin-util/src/random/mod.rs +++ b/crates/pumpkin-util/src/random/mod.rs @@ -18,12 +18,11 @@ pub fn get_seed() -> u64 { .try_update(Ordering::Relaxed, Ordering::Relaxed, |val| { Some(val.wrapping_mul(1181783497276652981u64)) }) - .unwrap(); + .unwrap_or(0); let nanos = time::SystemTime::now() .duration_since(time::SystemTime::UNIX_EPOCH) - .unwrap() - .as_nanos(); + .map_or(0, |d| d.as_nanos()); let nano_upper = (nanos >> 8) as u64; let nano_lower = nanos as u64; diff --git a/crates/pumpkin-util/src/random/xoroshiro128.rs b/crates/pumpkin-util/src/random/xoroshiro128.rs index 46b7690bf..e0e92f00c 100644 --- a/crates/pumpkin-util/src/random/xoroshiro128.rs +++ b/crates/pumpkin-util/src/random/xoroshiro128.rs @@ -227,8 +227,8 @@ impl XoroshiroSplitter { #[must_use] pub fn split_string(&self, seed: &str) -> Xoroshiro { let bytes = md5::compute(seed.as_bytes()); - let l = u64::from_be_bytes(bytes[0..8].try_into().expect("incorrect length")); - let m = u64::from_be_bytes(bytes[8..16].try_into().expect("incorrect length")); + let l = u64::from_be_bytes(bytes[0..8].try_into().unwrap_or([0; 8])); + let m = u64::from_be_bytes(bytes[8..16].try_into().unwrap_or([0; 8])); Xoroshiro::new(l ^ self.lo, m ^ self.hi) } diff --git a/crates/pumpkin-util/src/translation.rs b/crates/pumpkin-util/src/translation.rs index 07007748c..49d6045ad 100644 --- a/crates/pumpkin-util/src/translation.rs +++ b/crates/pumpkin-util/src/translation.rs @@ -76,7 +76,9 @@ impl SubstitutionRange { /// * `translation`: The localized translation string. /// * `locale`: The locale the translation belongs to. pub fn add_translation>(namespace: P, key: P, translation: P, locale: Locale) { - let mut translations = TRANSLATIONS.lock().unwrap(); + let mut translations = TRANSLATIONS + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let namespaced_key = format!("{}:{}", namespace.into(), key.into()).to_lowercase(); translations[locale as usize].insert(namespaced_key, translation.into()); } @@ -89,13 +91,15 @@ pub fn add_translation>(namespace: P, key: P, translation: P, lo /// * `locale`: The locale the translations belong to. pub fn add_translation_file>(namespace: P, file_path: P, locale: Locale) { let translations_map: HashMap = - serde_json::from_str(&file_path.into()).unwrap_or(HashMap::new()); + serde_json::from_str(&file_path.into()).unwrap_or_default(); if translations_map.is_empty() { // TODO: Handle the case where the file is empty or not found properly return; } - let mut translations = TRANSLATIONS.lock().unwrap(); + let mut translations = TRANSLATIONS + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let namespace = namespace.into(); for (key, translation) in translations_map { let namespaced_key = format!("{namespace}:{key}").to_lowercase(); @@ -112,7 +116,9 @@ pub fn add_translation_file>(namespace: P, file_path: P, locale: /// # Returns /// The localized translation. Falls back to `en_us` or the key itself if not found. pub fn get_translation(key: &str, locale: Locale) -> String { - let translations = TRANSLATIONS.lock().unwrap(); + let translations = TRANSLATIONS + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let key = key.to_lowercase(); translations[locale as usize].get(&key).map_or_else( || { @@ -273,58 +279,35 @@ pub static TRANSLATIONS: LazyLock; Locale::COUNT] LazyLock::new(|| { let mut array: [HashMap; Locale::COUNT] = std::array::from_fn(|_| HashMap::new()); - let vanilla_en_us: HashMap = - serde_json::from_str(VANILLA_EN_US_JSON).expect("Could not parse en_us_java.json."); - let pumpkin_en_us: HashMap = - serde_json::from_str(PUMPKIN_EN_US_JSON).expect("Could not parse en_us.json."); - let pumpkin_brb: HashMap = - serde_json::from_str(PUMPKIN_BRB_JSON).expect("Could not parse brb.json."); - let pumpkin_de_de: HashMap = - serde_json::from_str(PUMPKIN_DE_DE_JSON).expect("Could not parse de_de.json."); - let pumpkin_es_es: HashMap = - serde_json::from_str(PUMPKIN_ES_ES_JSON).expect("Could not parse es_es.json."); - let pumpkin_fr_fr: HashMap = - serde_json::from_str(PUMPKIN_FR_FR_JSON).expect("Could not parse fr_fr.json."); - let pumpkin_hr_hr: HashMap = - serde_json::from_str(PUMPKIN_HR_HR_JSON).expect("Could not parse hr_hr.json."); - let pumpkin_it_it: HashMap = - serde_json::from_str(PUMPKING_IT_IT_JSON).expect("Could not parse it_it.json."); - let pumpkin_ja_jp: HashMap = - serde_json::from_str(PUMPKIN_JA_JP_JSON).expect("Could not parse ja_jp.json."); - let pumpkin_ka_ge: HashMap = - serde_json::from_str(PUMPKIN_KA_GE_JSON).expect("Could not parse ka_ge.json."); - let pumpkin_ko_kr: HashMap = - serde_json::from_str(PUMPKIN_KO_KR_JSON).expect("Could not parse ko_kr.json."); - let pumpkin_nds_de: HashMap = - serde_json::from_str(PUMPKIN_NDS_DE_JSON).expect("Could not parse nds_de.json."); - let pumpkin_nl_be: HashMap = - serde_json::from_str(PUMPKIN_NL_BE_JSON).expect("Could not parse nl_be.json."); - let pumpkin_nl_nl: HashMap = - serde_json::from_str(PUMPKIN_NL_NL_JSON).expect("Could not parse nl_nl.json."); - let pumpkin_ro_ro: HashMap = - serde_json::from_str(PUMPKIN_RO_RO_JSON).expect("Could not parse ro_ro.json."); - let pumpkin_ru_ru: HashMap = - serde_json::from_str(PUMPKIN_RU_RU_JSON).expect("Could not parse ru_ru.json."); - let pumpkin_sq_al: HashMap = - serde_json::from_str(PUMPKIN_SQ_AL_JSON).expect("Could not parse sq_al.json."); - let pumpkin_zh_cn: HashMap = - serde_json::from_str(PUMPKIN_ZH_CN_JSON).expect("Could not parse zh_cn.json."); - let pumpkin_zh_hk: HashMap = - serde_json::from_str(PUMPKIN_ZH_HK_JSON).expect("Could not parse zh_hk.json."); - let pumpkin_zh_tw: HashMap = - serde_json::from_str(PUMPKIN_ZH_TW_JSON).expect("Could not parse zh_tw.json."); - let pumpkin_lzh: HashMap = - serde_json::from_str(PUMPKIN_LZH_JSON).expect("Could not parse lzh.json."); - let pumpkin_tr_tr: HashMap = - serde_json::from_str(PUMPKIN_TR_TR_JSON).expect("Could not parse tr_tr.json."); - let pumpkin_uk_ua: HashMap = - serde_json::from_str(PUMPKIN_UK_UA_JSON).expect("Could not parse uk_ua.json."); - let pumpkin_vi_vn: HashMap = - serde_json::from_str(PUMPKIN_VI_VN_JSON).expect("Could not parse vi_vn.json."); - let pumpkin_pt_br: HashMap = - serde_json::from_str(PUMPKIN_PT_BR_JSON).expect("Could not parse pt_br.json."); - let pumpkin_pl_pl: HashMap = - serde_json::from_str(PUMPKIN_PL_PL_JSON).expect("Could not parse pl_pl.json."); + let parse_json = |json: &str| -> HashMap { + serde_json::from_str(json).unwrap_or_default() + }; + let vanilla_en_us = parse_json(VANILLA_EN_US_JSON); + let pumpkin_en_us = parse_json(PUMPKIN_EN_US_JSON); + let pumpkin_brb = parse_json(PUMPKIN_BRB_JSON); + let pumpkin_de_de = parse_json(PUMPKIN_DE_DE_JSON); + let pumpkin_es_es = parse_json(PUMPKIN_ES_ES_JSON); + let pumpkin_fr_fr = parse_json(PUMPKIN_FR_FR_JSON); + let pumpkin_hr_hr = parse_json(PUMPKIN_HR_HR_JSON); + let pumpkin_it_it = parse_json(PUMPKING_IT_IT_JSON); + let pumpkin_ja_jp = parse_json(PUMPKIN_JA_JP_JSON); + let pumpkin_ka_ge = parse_json(PUMPKIN_KA_GE_JSON); + let pumpkin_ko_kr = parse_json(PUMPKIN_KO_KR_JSON); + let pumpkin_nds_de = parse_json(PUMPKIN_NDS_DE_JSON); + let pumpkin_nl_be = parse_json(PUMPKIN_NL_BE_JSON); + let pumpkin_nl_nl = parse_json(PUMPKIN_NL_NL_JSON); + let pumpkin_ro_ro = parse_json(PUMPKIN_RO_RO_JSON); + let pumpkin_ru_ru = parse_json(PUMPKIN_RU_RU_JSON); + let pumpkin_sq_al = parse_json(PUMPKIN_SQ_AL_JSON); + let pumpkin_zh_cn = parse_json(PUMPKIN_ZH_CN_JSON); + let pumpkin_zh_hk = parse_json(PUMPKIN_ZH_HK_JSON); + let pumpkin_zh_tw = parse_json(PUMPKIN_ZH_TW_JSON); + let pumpkin_lzh = parse_json(PUMPKIN_LZH_JSON); + let pumpkin_tr_tr = parse_json(PUMPKIN_TR_TR_JSON); + let pumpkin_uk_ua = parse_json(PUMPKIN_UK_UA_JSON); + let pumpkin_vi_vn = parse_json(PUMPKIN_VI_VN_JSON); + let pumpkin_pt_br = parse_json(PUMPKIN_PT_BR_JSON); + let pumpkin_pl_pl = parse_json(PUMPKIN_PL_PL_JSON); for (key, value) in vanilla_en_us { array[Locale::EnUs as usize].insert(format!("minecraft:{key}"), value); diff --git a/crates/pumpkin-world/benches/chunk.rs b/crates/pumpkin-world/benches/chunk.rs index c0fe22e1a..44b13e7ee 100644 --- a/crates/pumpkin-world/benches/chunk.rs +++ b/crates/pumpkin-world/benches/chunk.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use criterion::{Criterion, criterion_group, criterion_main}; use pumpkin_data::{ chunk_gen_settings::GenerationSettings, dimension::Dimension, diff --git a/crates/pumpkin-world/benches/chunk_gen.rs b/crates/pumpkin-world/benches/chunk_gen.rs index 47fe95a04..4b36a5d93 100644 --- a/crates/pumpkin-world/benches/chunk_gen.rs +++ b/crates/pumpkin-world/benches/chunk_gen.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use criterion::{BatchSize, Criterion, criterion_group, criterion_main}; use pumpkin_config::lighting::LightingEngineConfig; use pumpkin_data::BlockStateId; diff --git a/crates/pumpkin-world/benches/chunk_gen_concurrent.rs b/crates/pumpkin-world/benches/chunk_gen_concurrent.rs index e913f186e..2f1d119c5 100644 --- a/crates/pumpkin-world/benches/chunk_gen_concurrent.rs +++ b/crates/pumpkin-world/benches/chunk_gen_concurrent.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use criterion::{Criterion, criterion_group, criterion_main}; use pumpkin_data::BlockStateId; use pumpkin_data::dimension::Dimension; diff --git a/crates/pumpkin-world/benches/chunk_io.rs b/crates/pumpkin-world/benches/chunk_io.rs index 68354ea82..9cdc50198 100644 --- a/crates/pumpkin-world/benches/chunk_io.rs +++ b/crates/pumpkin-world/benches/chunk_io.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use criterion::{Criterion, criterion_group, criterion_main}; use pumpkin_data::{BlockStateId, dimension::Dimension}; use pumpkin_util::{math::vector2::Vector2, world_seed::Seed}; diff --git a/crates/pumpkin-world/benches/noise_router.rs b/crates/pumpkin-world/benches/noise_router.rs index 9052a4ba5..f7a801d36 100644 --- a/crates/pumpkin-world/benches/noise_router.rs +++ b/crates/pumpkin-world/benches/noise_router.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use criterion::{Criterion, criterion_group, criterion_main}; use pumpkin_data::noise_router::OVERWORLD_BASE_NOISE_ROUTER; use pumpkin_world::generation::{ diff --git a/crates/pumpkin-world/build.rs b/crates/pumpkin-world/build.rs index d4364a5e3..632f0f804 100644 --- a/crates/pumpkin-world/build.rs +++ b/crates/pumpkin-world/build.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used)] + use std::env; use std::fmt::Write; use std::fs; diff --git a/crates/pumpkin-world/src/chunk/format/anvil.rs b/crates/pumpkin-world/src/chunk/format/anvil.rs index f4a5ca943..fea9a6288 100644 --- a/crates/pumpkin-world/src/chunk/format/anvil.rs +++ b/crates/pumpkin-world/src/chunk/format/anvil.rs @@ -395,14 +395,7 @@ impl AnvilChunkFile { let mut chunks = indices .into_iter() - .map(|index| { - ( - index, - self.chunks_data[index] - .as_ref() - .expect("We are trying to write a chunk, but it does not exist!"), - ) - }) + .filter_map(|index| self.chunks_data[index].as_ref().map(|c| (index, c))) .collect::>(); // Sort such that writes are in order @@ -726,13 +719,9 @@ impl ChunkSerializer for AnvilChunkFile< timestamp: epoch, file_sector_offset: 0, }); - } else { + } else if let Some(swap) = chunks_to_shift.pop() { // swap last element of the chunks to shift (the first because we // reversed it) and shift the rest down - let swap = chunks_to_shift - .pop() - .expect("We just checked that this exists"); - let indices_to_shift = chunks_to_shift .iter() .map(|(index, _)| index) @@ -749,10 +738,9 @@ impl ChunkSerializer for AnvilChunkFile< }); write_action.maybe_update_chunk_index(index); - self.chunks_data[swapped_index] - .as_mut() - .expect("We checked if this was none") - .file_sector_offset = old_offset; + if let Some(swapped) = self.chunks_data[swapped_index].as_mut() { + swapped.file_sector_offset = old_offset; + } write_action.maybe_update_chunk_index(swapped_index); // Then offset everything else @@ -765,12 +753,13 @@ impl ChunkSerializer for AnvilChunkFile< ); for shift_index in indices_to_shift { - let chunk_data = self.chunks_data[shift_index] - .as_mut() - .expect("We checked if this was none"); - let new_offset = chunk_data.file_sector_offset as i64 + offset; - chunk_data.file_sector_offset = new_offset as u32; - write_action.maybe_update_chunk_index(shift_index); + if let Some(chunk_data) = self.chunks_data[shift_index].as_mut() + { + let new_offset = + chunk_data.file_sector_offset as i64 + offset; + chunk_data.file_sector_offset = new_offset as u32; + write_action.maybe_update_chunk_index(shift_index); + } } // If the shift is negative then there will be trailing data, but i diff --git a/crates/pumpkin-world/src/chunk/format/mod.rs b/crates/pumpkin-world/src/chunk/format/mod.rs index 80583e9ad..2f6c01f62 100644 --- a/crates/pumpkin-world/src/chunk/format/mod.rs +++ b/crates/pumpkin-world/src/chunk/format/mod.rs @@ -406,14 +406,31 @@ impl ChunkData { .load(std::sync::atomic::Ordering::Relaxed); let block_entities_nbt = { - let entities_guard = self.pending_block_entities.lock().unwrap(); + let entities_guard = self + .pending_block_entities + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); entities_guard.values().cloned().collect::>() }; - let light_lock = self.light_engine.lock().unwrap(); - let heightmap_lock = self.heightmap.lock().unwrap(); - let block_lock = self.section.block_sections.read().unwrap(); - let biome_lock = self.section.biome_sections.read().unwrap(); + let light_lock = self + .light_engine + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let heightmap_lock = self + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let block_lock = self + .section + .block_sections + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let biome_lock = self + .section + .biome_sections + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); let min_section_y = (self.section.min_y >> 4) as i8; diff --git a/crates/pumpkin-world/src/chunk/mod.rs b/crates/pumpkin-world/src/chunk/mod.rs index 2043ca8f3..842e625a0 100644 --- a/crates/pumpkin-world/src/chunk/mod.rs +++ b/crates/pumpkin-world/src/chunk/mod.rs @@ -438,7 +438,7 @@ impl ChunkSections { let relative_y = relative_y % BlockPalette::SIZE; self.block_sections .read() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .get(section_index) .map(|section| section.get(relative_x, relative_y, relative_z)) } @@ -474,8 +474,14 @@ impl ChunkSections { let relative_y = relative_y % BlockPalette::SIZE; // Keep lock order consistent to avoid deadlocks: block sections first, then random-tick cache. - let mut sections = self.block_sections.write().unwrap(); - let mut random_tick_sections_guard = self.random_tick_sections.write().unwrap(); + let mut sections = self + .block_sections + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut random_tick_sections_guard = self + .random_tick_sections + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(section) = sections.get_mut(section_index) { let replaced_block_state_id = @@ -546,7 +552,12 @@ impl ChunkSections { let section_index = relative_y / BiomePalette::SIZE; let relative_y = relative_y % BiomePalette::SIZE; - if let Some(section) = self.biome_sections.write().unwrap().get_mut(section_index) { + if let Some(section) = self + .biome_sections + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get_mut(section_index) + { section.set(relative_x, relative_y, relative_z, biome_id); } } @@ -563,7 +574,7 @@ impl ChunkSections { debug_assert!(scale_z < BiomePalette::SIZE); self.biome_sections .read() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .get(index) .map(|section| section.get(scale_x, scale_y, scale_z)) } @@ -587,6 +598,30 @@ impl ChunkSections { } impl ChunkData { + #[must_use] + pub fn empty(x: i32, z: i32) -> Self { + Self { + section: ChunkSections::new(24, -64), + heightmap: std::sync::Mutex::new(ChunkHeightmaps::default()), + x, + z, + block_ticks: ChunkTickScheduler::default(), + fluid_ticks: ChunkTickScheduler::default(), + pending_block_entities: std::sync::Mutex::new(FxHashMap::default()), + light_engine: std::sync::Mutex::new(ChunkLight::default()), + light_populated: std::sync::atomic::AtomicBool::new(false), + status: ChunkStatus::Full, + blending_data: None, + dirty: std::sync::atomic::AtomicBool::new(false), + inhabited_time: std::sync::atomic::AtomicU64::new(0), + } + } + + #[must_use] + pub fn empty_sync(x: i32, z: i32) -> std::sync::Arc { + std::sync::Arc::new(Self::empty(x, z)) + } + /// Returns the replaced block state ID pub fn set_block_absolute_y( &self, @@ -622,7 +657,10 @@ impl ChunkData { relative_z: usize, block_state: &BlockState, ) { - let mut heightmap = self.heightmap.lock().unwrap(); + let mut heightmap = self + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let min_y = self.section.min_y; let x = relative_x as i32; let y = relative_y as i32 + min_y; @@ -742,9 +780,9 @@ impl ChunkData { } for (idx, is_set) in has_found.iter().enumerate() { - if !(*is_set) { + if !(*is_set) && let Ok(hm_type) = idx.try_into() { heightmaps.set( - idx.try_into().unwrap(), + hm_type, x as i32, z as i32, self.section.min_y - 1, @@ -759,7 +797,7 @@ impl ChunkData { self.section .block_sections .read() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .iter() .enumerate() .rev() diff --git a/crates/pumpkin-world/src/chunk/palette.rs b/crates/pumpkin-world/src/chunk/palette.rs index 163946088..aa9a9b7c4 100644 --- a/crates/pumpkin-world/src/chunk/palette.rs +++ b/crates/pumpkin-world/src/chunk/palette.rs @@ -63,7 +63,11 @@ impl HeterogeneousPaletteData PalettedContainer if palette.len() <= 256 && std::mem::size_of::() > 1 { let mut indices = Box::new([[[0u8; DIM]; DIM]; DIM]); for (i, v) in cube.as_flattened().as_flattened().iter().enumerate() { - let idx = palette.iter().position(|p| p == v).unwrap(); + let idx = palette.iter().position(|p| p == v).unwrap_or(0); indices.as_flattened_mut().as_flattened_mut()[i] = idx as u8; } Self::Heterogeneous(Box::new(HeterogeneousPaletteData { @@ -259,7 +263,7 @@ impl PalettedContainer .map(|chunk| { chunk.iter().enumerate().fold(0, |acc, (index, key)| { let key_index = - data.palette.iter().position(|&x| x == *key).unwrap(); + data.palette.iter().position(|&x| x == *key).unwrap_or(0); debug_assert!((1 << bits_per_entry) > key_index); let packed_offset_index = @@ -578,7 +582,7 @@ impl BiomePalette { for y in 0..16 { for z in 0..16 { let key = self.get(x / 4, z / 4, y / 4); - let key_index = key_to_index_map.get(&key).unwrap(); + let key_index = key_to_index_map.get(&key).unwrap_or(&0); debug_assert!((1 << bits_per_entry) > *key_index); current_word |= (*key_index as u32) @@ -728,7 +732,7 @@ impl BlockPalette { // Java has it in y, z, x order, so we need to convert it back to x, y, z // Please test your code on bedrock before merging let key = data.get(x, z, y); - let key_index = key_to_index_map.get(&key).unwrap(); + let key_index = key_to_index_map.get(&key).unwrap_or(&0); debug_assert!((1 << bits_per_entry) > *key_index); current_word |= (*key_index as u32) diff --git a/crates/pumpkin-world/src/chunk_system/channel.rs b/crates/pumpkin-world/src/chunk_system/channel.rs index d7ea86485..8642116cc 100644 --- a/crates/pumpkin-world/src/chunk_system/channel.rs +++ b/crates/pumpkin-world/src/chunk_system/channel.rs @@ -39,7 +39,10 @@ impl LevelChannel { pos: Vec, ) { // debug!("set new level and priority"); - let mut value = self.value.lock().unwrap(); + let mut value = self + .value + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); value.1 = Some(pos); if let Some(old) = &mut value.0 { for (pos, change) in new_value.0 { @@ -73,7 +76,10 @@ impl LevelChannel { ), ) { // debug!("set new level"); - let mut value = self.value.lock().unwrap(); + let mut value = self + .value + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(old) = &mut value.0 { for (pos, change) in new_value.0 { match old.0.entry(pos) { @@ -100,24 +106,36 @@ impl LevelChannel { } pub fn set_priority(&self, pos: Vec) { // debug!("set new priority"); - self.value.lock().unwrap().1 = Some(pos); + self.value + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .1 = Some(pos); self.notify.notify_one(); } pub fn get(&self) -> (Option, Option>) { - let mut lock = self.value.lock().unwrap(); + let mut lock = self + .value + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let mut ret = (None, None); swap(&mut ret, &mut *lock); ret } pub fn wait_and_get(&self, level: &Arc) -> (Option, Option>) { - let mut lock = self.value.lock().unwrap(); + let mut lock = self + .value + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); while lock.0.is_none() && lock.1.is_none() && !level.should_unload.load(SeqCst) && !level.should_save.load(SeqCst) && !level.shut_down_chunk_system.load(SeqCst) { - lock = self.notify.wait(lock).unwrap(); + lock = self + .notify + .wait(lock) + .unwrap_or_else(std::sync::PoisonError::into_inner); } let mut ret = (None, None); swap(&mut ret, &mut *lock); diff --git a/crates/pumpkin-world/src/chunk_system/chunk_listener.rs b/crates/pumpkin-world/src/chunk_system/chunk_listener.rs index 0f1a4ee66..c2c93153a 100644 --- a/crates/pumpkin-world/src/chunk_system/chunk_listener.rs +++ b/crates/pumpkin-world/src/chunk_system/chunk_listener.rs @@ -28,19 +28,28 @@ impl ChunkListener { pub fn add_single_chunk_listener(&self, pos: ChunkPos) -> oneshot::Receiver { let (tx, rx) = oneshot::channel(); - self.single.lock().unwrap().push((pos, tx)); + self.single + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .push((pos, tx)); rx } pub fn add_global_chunk_listener(&self) -> Receiver<(ChunkPos, Weak)> { let (tx, rx) = crossbeam::channel::unbounded(); - self.global.lock().unwrap().push(tx); + self.global + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .push(tx); rx } pub fn process_new_chunk(&self, pos: ChunkPos, chunk: &SyncChunk) { { - let mut single = self.single.lock().unwrap(); + let mut single = self + .single + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let mut i = 0; let mut len = single.len(); while i < len { @@ -56,7 +65,10 @@ impl ChunkListener { } { let weak = Arc::downgrade(chunk); - let mut global = self.global.lock().unwrap(); + let mut global = self + .global + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let mut i = 0; let mut len = global.len(); while i < len { diff --git a/crates/pumpkin-world/src/chunk_system/chunk_loading.rs b/crates/pumpkin-world/src/chunk_system/chunk_loading.rs index fbbd11a63..d750b69e9 100644 --- a/crates/pumpkin-world/src/chunk_system/chunk_loading.rs +++ b/crates/pumpkin-world/src/chunk_system/chunk_loading.rs @@ -107,7 +107,9 @@ impl ChunkLoading { fn debug_check_error(&self) -> bool { let mut temp = ChunkLevel::default(); for (ticket_pos, levels) in &self.ticket { - let level = *levels.iter().min().unwrap(); + let Some(&level) = levels.iter().min() else { + continue; + }; let range = Self::MAX_LEVEL - level - 1; for dx in -range..=range { for dy in -range..=range { @@ -124,7 +126,12 @@ impl ChunkLoading { } assert_eq!(temp.len(), self.pos_level.len()); for val in &temp { - if val != self.pos_level.get_key_value(val.0).unwrap() { + if val + != self + .pos_level + .get_key_value(val.0) + .expect("key value exists") + { Self::dump_level_debug( &self.high_priority, &self.pos_level, @@ -134,7 +141,12 @@ impl ChunkLoading { val.0.y + 40, ); } - assert_eq!(val, self.pos_level.get_key_value(val.0).unwrap()); + assert_eq!( + val, + self.pos_level + .get_key_value(val.0) + .expect("key value exists") + ); } true } @@ -279,7 +291,9 @@ impl ChunkLoading { for (ticket_pos, levels) in &self.ticket { if (ticket_pos.x - pos.x).abs() <= range && (ticket_pos.y - pos.y).abs() <= range { - let level = *levels.iter().min().unwrap(); + let Some(&level) = levels.iter().min() else { + continue; + }; debug_assert!(level < Self::MAX_LEVEL); let old = self.cache.get(&self.pos_level, *ticket_pos); if old <= level { @@ -300,13 +314,9 @@ impl ChunkLoading { } pub fn remove_force_ticket(&mut self, pos: ChunkPos) { // debug!("remove force ticket at {pos:?}"); - let index = self - .high_priority - .iter() - .find_position(|x| **x == pos) - .unwrap() - .0; - self.high_priority.remove(index); + if let Some((index, _)) = self.high_priority.iter().find_position(|x| **x == pos) { + self.high_priority.remove(index); + } self.is_priority_dirty = true; self.remove_ticket(pos, Self::FULL_CHUNK_LEVEL); } diff --git a/crates/pumpkin-world/src/chunk_system/dag.rs b/crates/pumpkin-world/src/chunk_system/dag.rs index 93461c186..df897b466 100644 --- a/crates/pumpkin-world/src/chunk_system/dag.rs +++ b/crates/pumpkin-world/src/chunk_system/dag.rs @@ -50,10 +50,15 @@ pub struct DAG { impl DAG { pub fn fast_drop_node(&mut self, node: NodeKey) { - let mut edge = self.nodes.remove(node).unwrap().edge; - // debug!("drop node {node:?}"); - while !edge.is_null() { - edge = self.edges.remove(edge).unwrap().next; + if let Some(removed_node) = self.nodes.remove(node) { + let mut edge = removed_node.edge; + while !edge.is_null() { + if let Some(removed_edge) = self.edges.remove(edge) { + edge = removed_edge.next; + } else { + break; + } + } } } pub fn add_edge(&mut self, from: NodeKey, to: NodeKey) { diff --git a/crates/pumpkin-world/src/chunk_system/generation_cache.rs b/crates/pumpkin-world/src/chunk_system/generation_cache.rs index c145058d4..efabc7d94 100644 --- a/crates/pumpkin-world/src/chunk_system/generation_cache.rs +++ b/crates/pumpkin-world/src/chunk_system/generation_cache.rs @@ -237,7 +237,10 @@ impl GenerationCache for Cache { debug_assert!(dx >= 0 && dy >= 0); match &self.chunks[(dx * self.size + dy) as usize] { Chunk::Level(data) => { - let heightmap = data.heightmap.lock().unwrap(); + let heightmap = data + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let min_y = data.section.min_y; heightmap.get(ChunkHeightmapType::MotionBlocking, x, z, min_y) @@ -253,7 +256,10 @@ impl GenerationCache for Cache { debug_assert!(dx >= 0 && dy >= 0); match &self.chunks[(dx * self.size + dy) as usize] { Chunk::Level(data) => { - let heightmap = data.heightmap.lock().unwrap(); + let heightmap = data + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let min_y = data.section.min_y; heightmap.get(ChunkHeightmapType::MotionBlockingNoLeaves, x, z, min_y) } @@ -268,7 +274,10 @@ impl GenerationCache for Cache { debug_assert!(dx >= 0 && dy >= 0); match &self.chunks[(dx * self.size + dy) as usize] { Chunk::Level(data) => { - let heightmap = data.heightmap.lock().unwrap(); + let heightmap = data + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let min_y = data.section.min_y; heightmap.get(ChunkHeightmapType::WorldSurface, x, z, min_y) // can we return this? } @@ -308,7 +317,7 @@ impl GenerationCache for Cache { .get_rough_biome_absolute_y((x & 15) as usize, y, (z & 15) as usize) .unwrap_or(0), ) - .unwrap() + .unwrap_or(&Biome::PLAINS) } Chunk::Proto(data) => data.get_terrain_gen_biome(x, y, z), } diff --git a/crates/pumpkin-world/src/chunk_system/mod.rs b/crates/pumpkin-world/src/chunk_system/mod.rs index 275ecd66c..f670ad37b 100644 --- a/crates/pumpkin-world/src/chunk_system/mod.rs +++ b/crates/pumpkin-world/src/chunk_system/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + /* TODO 1. add proto chunk dirty flag diff --git a/crates/pumpkin-world/src/chunk_system/schedule.rs b/crates/pumpkin-world/src/chunk_system/schedule.rs index b7cf41f06..6c947bc63 100644 --- a/crates/pumpkin-world/src/chunk_system/schedule.rs +++ b/crates/pumpkin-world/src/chunk_system/schedule.rs @@ -182,7 +182,10 @@ impl GenerationSchedule { fn apply_lighting_override(&self, chunk: &SyncChunk) { match self.lighting_config { LightingEngineConfig::Full => { - let mut engine = chunk.light_engine.lock().unwrap(); + let mut engine = chunk + .light_engine + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for section in &mut engine.block_light { section.fill(15); } @@ -192,7 +195,10 @@ impl GenerationSchedule { chunk.dirty.store(true, Relaxed); } LightingEngineConfig::Dark => { - let mut engine = chunk.light_engine.lock().unwrap(); + let mut engine = chunk + .light_engine + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for section in &mut engine.block_light { section.fill(0); } @@ -512,7 +518,7 @@ impl GenerationSchedule { self.unload_chunks.remove(&pos); if holder.current_stage == StagedChunkEnum::Full && !holder.public { holder.public = true; - match holder.chunk.as_ref().unwrap() { + match holder.chunk.as_ref().expect("chunk exists") { Chunk::Level(chunk) => { self.apply_lighting_override(chunk); self.public_chunk_map.insert(pos, chunk.clone()); @@ -568,7 +574,7 @@ impl GenerationSchedule { } } } - let node = self.graph.nodes.get_mut(task).unwrap(); + let node = self.graph.nodes.get_mut(task).expect("node exists"); if node.in_degree == 0 && !node.in_queue { node.in_queue = true; self.queue.push(TaskHeapNode(0, task)); @@ -594,7 +600,7 @@ impl GenerationSchedule { } for pos in stranded { - let holder = self.chunk_map.get_mut(&pos).unwrap(); + let holder = self.chunk_map.get_mut(&pos).expect("holder exists"); if !holder.occupied.is_null() && self.graph.nodes.contains_key(holder.occupied) { continue; } @@ -605,7 +611,7 @@ impl GenerationSchedule { let mut has_valid_task = false; while !cur_edge.is_null() { - let edge = self.graph.edges.get(cur_edge).unwrap(); + let edge = self.graph.edges.get(cur_edge).expect("edge exists"); if self.graph.nodes.contains_key(edge.to) { prev_edge = cur_edge; cur_edge = edge.next; @@ -617,7 +623,11 @@ impl GenerationSchedule { if prev_edge.is_null() { change_head = Some(next); } else { - self.graph.edges.get_mut(prev_edge).unwrap().next = next; + self.graph + .edges + .get_mut(prev_edge) + .expect("edge exists") + .next = next; } } } @@ -683,7 +693,11 @@ impl GenerationSchedule { if chunks.is_empty() { return; } - let mut data = self.io_lock.0.lock().unwrap(); + let mut data = self + .io_lock + .0 + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for (pos, _chunk) in &chunks { *data.entry(*pos).or_insert(0) += 1; } @@ -716,7 +730,7 @@ impl GenerationSchedule { if should_save { let chunk_to_save = match chunk { Chunk::Level(sync_chunk) => Chunk::Level(sync_chunk.clone()), - Chunk::Proto(_) => holder.chunk.take().unwrap(), + Chunk::Proto(_) => holder.chunk.take().expect("proto chunk exists"), }; chunks.push((*pos, chunk_to_save)); } @@ -733,7 +747,11 @@ impl GenerationSchedule { self.chunk_map.len() ); - let mut data = self.io_lock.0.lock().unwrap(); + let mut data = self + .io_lock + .0 + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for (pos, _) in &chunks { *data.entry(*pos).or_insert(0) += 1; } @@ -750,7 +768,7 @@ impl GenerationSchedule { }; let mut edge = old.edge; while !edge.is_null() { - let cur = self.graph.edges.remove(edge).unwrap(); + let cur = self.graph.edges.remove(edge).expect("edge exists"); if let Some(node) = self.graph.nodes.get_mut(cur.to) { debug_assert!(node.in_degree >= 1); node.in_degree -= 1; @@ -792,7 +810,7 @@ impl GenerationSchedule { fn receive_chunk(&mut self, pos: ChunkPos, data: RecvChunk) { match data { RecvChunk::IO(chunk) => { - let mut holder = self.chunk_map.remove(&pos).unwrap(); + let mut holder = self.chunk_map.remove(&pos).expect("holder exists"); if holder.chunk.is_some() { warn!( "receive_chunk(IO): holder already has chunk at {:?}; replacing", @@ -849,7 +867,8 @@ impl GenerationSchedule { let new_pos = ChunkPos::new(data.x + dx, data.z + dy); match chunk { Chunk::Level(chunk) => { - let mut holder = self.chunk_map.remove(&new_pos).unwrap(); + let mut holder = + self.chunk_map.remove(&new_pos).expect("holder exists"); let stage = StagedChunkEnum::Full; if new_pos == pos { if holder.current_stage != StagedChunkEnum::Spawn { @@ -926,7 +945,8 @@ impl GenerationSchedule { self.chunk_map.insert(new_pos, holder); } Chunk::Proto(chunk) => { - let mut holder = self.chunk_map.remove(&new_pos).unwrap(); + let mut holder = + self.chunk_map.remove(&new_pos).expect("holder exists"); let stage = StagedChunkEnum::from(chunk.stage_id()); self.drop_satisfied_tasks(&mut holder, stage); @@ -1164,7 +1184,7 @@ impl GenerationSchedule { if node.stage == StagedChunkEnum::Empty { self.running_task_count += 1; - let holder = self.chunk_map.get_mut(&node.pos).unwrap(); + let holder = self.chunk_map.get_mut(&node.pos).expect("holder exists"); debug_assert!(holder.occupied.is_null()); debug_assert_eq!(holder.current_stage, StagedChunkEnum::None); let occupy = self.graph.nodes.insert(Node::new( @@ -1246,7 +1266,8 @@ impl GenerationSchedule { for dx in -write_radius..=write_radius { for dy in -write_radius..=write_radius { let new_pos = node.pos.add_raw(dx, dy); - let holder = self.chunk_map.get_mut(&new_pos).unwrap(); + let holder = + self.chunk_map.get_mut(&new_pos).expect("holder exists"); let mut tmp = None; swap(&mut tmp, &mut holder.chunk); let Some(tmp) = tmp else { @@ -1270,7 +1291,7 @@ impl GenerationSchedule { let mut prev_edge = EdgeKey::null(); let mut change_head = None; while !cur_edge.is_null() { - let edge = self.graph.edges.get(cur_edge).unwrap(); + let edge = self.graph.edges.get(cur_edge).expect("edge exists"); if self.graph.nodes.contains_key(edge.to) { prev_edge = cur_edge; cur_edge = edge.next; @@ -1282,8 +1303,11 @@ impl GenerationSchedule { if prev_edge.is_null() { change_head = Some(next); } else { - self.graph.edges.get_mut(prev_edge).unwrap().next = - next; + self.graph + .edges + .get_mut(prev_edge) + .expect("edge exists") + .next = next; } } } @@ -1455,7 +1479,7 @@ impl GenerationSchedule { debug_assert!(holder.occupied.is_null()); if holder.current_stage != StagedChunkEnum::None { debug_assert_eq!( - holder.chunk.as_ref().unwrap().get_stage_id(), + holder.chunk.as_ref().expect("chunk exists").get_stage_id(), holder.current_stage as u8 ); } diff --git a/crates/pumpkin-world/src/chunk_system/worker_logic.rs b/crates/pumpkin-world/src/chunk_system/worker_logic.rs index 83bc9768d..45120956d 100644 --- a/crates/pumpkin-world/src/chunk_system/worker_logic.rs +++ b/crates/pumpkin-world/src/chunk_system/worker_logic.rs @@ -67,7 +67,12 @@ pub async fn io_read_work( // Lock handling loop { let notified = lock.1.notified(); - if !lock.0.lock().unwrap().contains_key(pos) { + if !lock + .0 + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .contains_key(pos) + { break; } notified.await; @@ -197,7 +202,10 @@ pub async fn io_write_work(recv: AsyncRx>, level: Arc { let rc = entry.get_mut(); diff --git a/crates/pumpkin-world/src/generation/block_predicate.rs b/crates/pumpkin-world/src/generation/block_predicate.rs index bf6aa9b8d..5e6f29e72 100644 --- a/crates/pumpkin-world/src/generation/block_predicate.rs +++ b/crates/pumpkin-world/src/generation/block_predicate.rs @@ -58,11 +58,14 @@ impl MatchingBlocksBlockPredicate { let block = self.offset.get_block(chunk, pos); match &self.blocks { MatchingBlocksWrapper::Single(single_block) => { - single_block.strip_prefix("minecraft:").unwrap() == block.name + single_block + .strip_prefix("minecraft:") + .unwrap_or(single_block) + == block.name } MatchingBlocksWrapper::Multiple(blocks) => blocks .iter() - .map(|s| s.strip_prefix("minecraft:").unwrap()) + .map(|s| s.strip_prefix("minecraft:").unwrap_or(s)) .contains(block.name), } } @@ -89,11 +92,14 @@ impl MatchingFluidsBlockPredicate { let (fluid, _) = self.offset.get_fluid_and_fluid_state(chunk, pos); match &self.fluids { MatchingBlocksWrapper::Single(single_block) => { - single_block.strip_prefix("minecraft:").unwrap() == fluid.name + single_block + .strip_prefix("minecraft:") + .unwrap_or(single_block) + == fluid.name } MatchingBlocksWrapper::Multiple(blocks) => blocks .iter() - .map(|s| s.strip_prefix("minecraft:").unwrap()) + .map(|s| s.strip_prefix("minecraft:").unwrap_or(s)) .contains(fluid.name), } } diff --git a/crates/pumpkin-world/src/generation/block_state_provider.rs b/crates/pumpkin-world/src/generation/block_state_provider.rs index 076e8ba42..f7ab8d0f8 100644 --- a/crates/pumpkin-world/src/generation/block_state_provider.rs +++ b/crates/pumpkin-world/src/generation/block_state_provider.rs @@ -1,4 +1,4 @@ -use pumpkin_data::BlockState; +use pumpkin_data::{Block, BlockState}; use pumpkin_util::{ DoublePerlinNoiseParametersCodec, math::{ @@ -199,7 +199,9 @@ pub struct WeightedBlockStateProvider { impl WeightedBlockStateProvider { pub fn get(&self, random: &mut RandomGenerator) -> &'static BlockState { - Pool::get(&self.entries, random).unwrap() + Pool::get(&self.entries, random) + .copied() + .unwrap_or(Block::AIR.default_state) } } diff --git a/crates/pumpkin-world/src/generation/feature/features/coral/mod.rs b/crates/pumpkin-world/src/generation/feature/features/coral/mod.rs index 7a2a27db7..44efd8de9 100644 --- a/crates/pumpkin-world/src/generation/feature/features/coral/mod.rs +++ b/crates/pumpkin-world/src/generation/feature/features/coral/mod.rs @@ -64,10 +64,10 @@ impl CoralFeature { } let wall_coral = Self::get_random_tag_entry_block(tag::Block::MINECRAFT_WALL_CORALS, random); - let original_props = &wall_coral - .properties(wall_coral.default_state.id) - .unwrap() - .to_props(); + let Some(properties) = wall_coral.properties(wall_coral.default_state.id) else { + continue; + }; + let original_props = &properties.to_props(); // Set the right Axis let props: Vec<(&str, &str)> = original_props .iter() @@ -111,7 +111,7 @@ impl CoralFeature { ) -> &'static Block { let values = tag.1; let value = values[random.next_bounded_i32(values.len() as i32) as usize]; - let id = BlockId::new(value).expect("Invalid block id in tag"); + let id = BlockId::new(value).unwrap_or(BlockId::AIR); id.to_block() } } diff --git a/crates/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs b/crates/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs index 3903c9a11..8d5af6d37 100644 --- a/crates/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs +++ b/crates/pumpkin-world/src/generation/feature/features/tree/trunk/fancy.rs @@ -157,7 +157,10 @@ impl FancyTrunkPlacer { if TreeFeature::can_replace(block.to_state(), block.to_block_id()) { let block = Block::from_state_id(trunk_provider.id); - let original_props = &block.properties(trunk_provider.id).unwrap().to_props(); + let Some(properties) = block.properties(trunk_provider.id) else { + continue; + }; + let original_props = &properties.to_props(); let axis = axis.to_value(); // Set the right Axis let props: Vec<(&'static str, &'static str)> = original_props diff --git a/crates/pumpkin-world/src/generation/feature/placed_features.rs b/crates/pumpkin-world/src/generation/feature/placed_features.rs index 208ecbc60..84cce2117 100644 --- a/crates/pumpkin-world/src/generation/feature/placed_features.rs +++ b/crates/pumpkin-world/src/generation/feature/placed_features.rs @@ -28,9 +28,10 @@ pub enum PlacedFeatureWrapper { } impl PlacedFeatureWrapper { + #[allow(clippy::expect_used)] pub fn get(&self) -> &PlacedFeature { match self { - Self::Named(name) => PLACED_FEATURES.get(name).unwrap(), + Self::Named(name) => PLACED_FEATURES.get(name).expect("Unknown placed feature"), Self::Direct(feature) => feature, } } @@ -56,11 +57,11 @@ impl PlacedFeature { random: &mut RandomGenerator, pos: BlockPos, ) -> bool { - let feature = match &self.feature { - Feature::Named(name) => CONFIGURED_FEATURES - .get(name) - .expect("Name: {name:?} not found"), - Feature::Inlined(feature) => feature, + let Some(feature) = (match &self.feature { + Feature::Named(name) => CONFIGURED_FEATURES.get(name), + Feature::Inlined(feature) => Some(feature.as_ref()), + }) else { + return false; }; if let ConfiguredFeature::SculkPatch(feature) = feature { feature.generate_in_proto_chunk(chunk, random, pos) @@ -110,11 +111,11 @@ impl PlacedFeature { stream = new_stream; } - let feature = match &self.feature { - Feature::Named(name) => CONFIGURED_FEATURES - .get(name) - .expect("Name: {name:?} not found"), - Feature::Inlined(feature) => feature, + let Some(feature) = (match &self.feature { + Feature::Named(name) => CONFIGURED_FEATURES.get(name), + Feature::Inlined(feature) => Some(feature.as_ref()), + }) else { + return false; }; let mut ret = false; diff --git a/crates/pumpkin-world/src/generation/generator/structure_finder.rs b/crates/pumpkin-world/src/generation/generator/structure_finder.rs index 3aa198d7e..6c105138d 100644 --- a/crates/pumpkin-world/src/generation/generator/structure_finder.rs +++ b/crates/pumpkin-world/src/generation/generator/structure_finder.rs @@ -121,7 +121,7 @@ fn find_nearest_concentric( distance_sq: dx * dx + dz * dz, } }) - .min_by(|a, b| a.distance_sq.partial_cmp(&b.distance_sq).unwrap()) + .min_by(|a, b| a.distance_sq.total_cmp(&b.distance_sq)) } fn find_nearest_random_spread_at_radius( diff --git a/crates/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs b/crates/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs index 03f705083..e41ed9a3e 100644 --- a/crates/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs +++ b/crates/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs @@ -251,7 +251,9 @@ impl ChunkNoiseFunctionComponent<'_> { pos: &Vector3, sample_options: &ChunkNoiseFunctionSampleOptions, ) -> f64 { - let (top_component, component_stack) = component_stack.split_last_mut().unwrap(); + let Some((top_component, component_stack)) = component_stack.split_last_mut() else { + return 0.0; + }; if !sample_options.populating_caches && let ChunkNoiseFunctionComponent::Chunk( ChunkSpecificNoiseFunctionComponent::DensityInterpolator(interp), @@ -268,8 +270,9 @@ impl ChunkNoiseFunctionComponent<'_> { mapper: &impl IndexToNoisePos, sample_options: &mut ChunkNoiseFunctionSampleOptions, ) { - let (top_component, component_stack) = component_stack.split_last_mut().unwrap(); - top_component.fill(component_stack, array, mapper, sample_options); + if let Some((top_component, component_stack)) = component_stack.split_last_mut() { + top_component.fill(component_stack, array, mapper, sample_options); + } } } diff --git a/crates/pumpkin-world/src/generation/noise/router/density_function/spline.rs b/crates/pumpkin-world/src/generation/noise/router/density_function/spline.rs index 0bb0c2706..26cf05382 100644 --- a/crates/pumpkin-world/src/generation/noise/router/density_function/spline.rs +++ b/crates/pumpkin-world/src/generation/noise/router/density_function/spline.rs @@ -103,7 +103,9 @@ impl Spline { let input_max = input_function.max() as f32; let input_min = input_function.min() as f32; - let first_point = self.points.first().expect("A spline with no values?"); + let Some(first_point) = self.points.first() else { + return (0.0, 0.0); + }; if input_min < first_point.location { let (point_min, point_max) = first_point.value.calculate_min_and_max(component_stack); let sample_min = first_point.sample_outside_range(input_min, point_min); @@ -113,7 +115,9 @@ impl Spline { max = max.max(sample_min.max(sample_max)); } - let last_point = self.points.last().expect("A spline with no values?"); + let Some(last_point) = self.points.last() else { + return (min, max); + }; if input_max > last_point.location { let (point_min, point_max) = last_point.value.calculate_min_and_max(component_stack); let sample_min = last_point.sample_outside_range(input_max, point_min); diff --git a/crates/pumpkin-world/src/generation/proto_chunk.rs b/crates/pumpkin-world/src/generation/proto_chunk.rs index dcaccf7f7..4876cb21a 100644 --- a/crates/pumpkin-world/src/generation/proto_chunk.rs +++ b/crates/pumpkin-world/src/generation/proto_chunk.rs @@ -260,16 +260,29 @@ impl ProtoChunk { ) -> Self { let mut proto_chunk = Self::new(chunk_data.x, chunk_data.z, generator); - proto_chunk.light = chunk_data.light_engine.lock().unwrap().clone(); + proto_chunk.light = chunk_data + .light_engine + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .clone(); proto_chunk .blending_data .clone_from(&chunk_data.blending_data); let section_data = &chunk_data.section; - let heightmap_data = chunk_data.heightmap.lock().unwrap(); + let heightmap_data = chunk_data + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); - let block_sections_guard = section_data.block_sections.read().unwrap(); - let biome_sections_guard = section_data.biome_sections.read().unwrap(); + let block_sections_guard = section_data + .block_sections + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let biome_sections_guard = section_data + .biome_sections + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); for (section_idx, block_palette) in block_sections_guard.iter().enumerate() { let section_base_y = section_idx as i32 * 16; @@ -533,7 +546,7 @@ impl ProtoChunk { #[inline] #[must_use] pub fn get_biome(&self, x: i32, y: i32, z: i32) -> &'static Biome { - Biome::from_id(self.get_biome_id(x, y, z)).unwrap() + Biome::from_id(self.get_biome_id(x, y, z)).unwrap_or(&Biome::PLAINS) } #[inline] @@ -618,7 +631,9 @@ impl ProtoChunk { StructureInstance::Reference(collector) => collector, }; - let collector = collector.lock().unwrap(); + let collector = collector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for piece in &collector.pieces { let bounding_box = piece.get_structure_piece().bounding_box; @@ -933,7 +948,7 @@ impl ProtoChunk { #[must_use] pub fn get_terrain_gen_biome(&self, x: i32, y: i32, z: i32) -> &'static Biome { - Biome::from_id(self.get_terrain_gen_biome_id(x, y, z)).unwrap() + Biome::from_id(self.get_terrain_gen_biome_id(x, y, z)).unwrap_or(&Biome::PLAINS) } #[expect(clippy::too_many_lines)] @@ -1223,7 +1238,9 @@ impl ProtoChunk { let chunk = cache.get_center_chunk_mut(); for collector_arc in tasks { - let mut collector = collector_arc.lock().unwrap(); + let mut collector = collector_arc + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); collector.generate_in_chunk(chunk, block_registry, &mut random, world_seed); } } diff --git a/crates/pumpkin-world/src/generation/structure/mod.rs b/crates/pumpkin-world/src/generation/structure/mod.rs index 2db2b01d2..2af04468c 100644 --- a/crates/pumpkin-world/src/generation/structure/mod.rs +++ b/crates/pumpkin-world/src/generation/structure/mod.rs @@ -64,12 +64,10 @@ pub fn generate_structure_position( | StructureKeys::VillageSavanna | StructureKeys::VillageSnowy | StructureKeys::VillageTaiga => { - let generator = JigsawGenerator::new( - structure - .start_pool - .expect("Jigsaw structure must have a start pool"), - structure.size.expect("Jigsaw structure must have a size"), - ); + let (Some(start_pool), Some(size)) = (structure.start_pool, structure.size) else { + return None; + }; + let generator = JigsawGenerator::new(start_pool, size); generator.get_structure_position(context) } StructureKeys::AncientCity @@ -77,12 +75,10 @@ pub fn generate_structure_position( | StructureKeys::PillagerOutpost | StructureKeys::TrailRuins | StructureKeys::TrialChambers => { - let mut generator = JigsawGenerator::new( - structure - .start_pool - .expect("Jigsaw structure must have a start pool"), - structure.size.expect("Jigsaw structure must have a size"), - ); + let (Some(start_pool), Some(size)) = (structure.start_pool, structure.size) else { + return None; + }; + let mut generator = JigsawGenerator::new(start_pool, size); if *key == StructureKeys::PillagerOutpost { generator = generator.with_expansion_hack(true); } @@ -169,8 +165,7 @@ pub fn try_generate_structure( .biomes .strip_prefix('#') .unwrap_or(structure.biomes), - ) - .unwrap(); + )?; // Check if the biome is allowed for this structure if biomes.contains(¤t_biome) { diff --git a/crates/pumpkin-world/src/generation/structure/structures/mansion/mod.rs b/crates/pumpkin-world/src/generation/structure/structures/mansion/mod.rs index 89545fe4c..5674a920f 100644 --- a/crates/pumpkin-world/src/generation/structure/structures/mansion/mod.rs +++ b/crates/pumpkin-world/src/generation/structure/structures/mansion/mod.rs @@ -370,9 +370,9 @@ impl MansionTemplatePiece { "minecraft:chest".to_string(), vec![("facing".to_string(), target.name().to_string())], ); - let state = BlockStateResolver::resolve_simple(&chest) - .expect("the vanilla chest state must resolve"); - chunk.set_block_state(position.x, position.y, position.z, state); + if let Some(state) = BlockStateResolver::resolve_simple(&chest) { + chunk.set_block_state(position.x, position.y, position.z, state); + } let mut nbt = NbtCompound::new(); nbt.put_string("id", "minecraft:chest".to_string()); nbt.put_int("x", position.x); diff --git a/crates/pumpkin-world/src/generation/structure/structures/mod.rs b/crates/pumpkin-world/src/generation/structure/structures/mod.rs index 352b4d380..0661b5305 100644 --- a/crates/pumpkin-world/src/generation/structure/structures/mod.rs +++ b/crates/pumpkin-world/src/generation/structure/structures/mod.rs @@ -631,7 +631,7 @@ impl StructurePiecesCollector { } let bbox = BlockBox::encompass_all(self.pieces.iter().map(|p| p.bounding_box())) - .expect("Structure must have at least one piece to calculate a bounding box"); + .unwrap_or_else(|| BlockBox::new(0, 0, 0, 0, 0, 0)); self.cached_box = Some(bbox); bbox @@ -656,7 +656,10 @@ pub struct StructurePosition { impl StructurePosition { #[must_use] pub fn get_bounding_box(&self) -> BlockBox { - self.collector.lock().unwrap().get_bounding_box() + self.collector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get_bounding_box() } } diff --git a/crates/pumpkin-world/src/inventory/inventory.rs b/crates/pumpkin-world/src/inventory/inventory.rs index 49a215c08..25ffb102d 100644 --- a/crates/pumpkin-world/src/inventory/inventory.rs +++ b/crates/pumpkin-world/src/inventory/inventory.rs @@ -103,20 +103,7 @@ pub trait Inventory: Send + Sync + Clearable { fn mark_dirty(&self) {} fn read_data(&self, nbt: &NbtCompound, stacks: &mut [ItemStack]) { - if let Some(inventory_list) = nbt.get_list("Items") { - for tag in inventory_list { - if let Some(item_compound) = tag.extract_compound() - && let Some(slot_byte) = item_compound.get_byte("Slot") - { - let slot = slot_byte as usize; - if slot < stacks.len() - && let Some(item_stack) = ItemStack::read_item_stack(item_compound) - { - stacks[slot] = item_stack; - } - } - } - } + sync_read_items_from_nbt(nbt, stacks); } fn is_valid_slot_for(&self, _slot: usize, _stack: &ItemStack) -> bool { @@ -139,6 +126,23 @@ pub trait Clearable { fn clear(&self) -> Pin + Send + '_>>; } +pub fn sync_read_items_from_nbt(nbt: &NbtCompound, stacks: &mut [ItemStack]) { + if let Some(inventory_list) = nbt.get_list("Items") { + for tag in inventory_list { + if let Some(item_compound) = tag.extract_compound() + && let Some(slot_byte) = item_compound.get_byte("Slot") + { + let slot = slot_byte as usize; + if slot < stacks.len() + && let Some(item_stack) = ItemStack::read_item_stack(item_compound) + { + stacks[slot] = item_stack; + } + } + } + } +} + pub fn sync_write_items_to_nbt(items: &[ItemStack], nbt: &mut NbtCompound) { let mut slots = Vec::new(); for (i, stack) in items.iter().enumerate() { diff --git a/crates/pumpkin-world/src/level.rs b/crates/pumpkin-world/src/level.rs index 330f76624..07ec206f6 100644 --- a/crates/pumpkin-world/src/level.rs +++ b/crates/pumpkin-world/src/level.rs @@ -165,9 +165,9 @@ impl Level { let entities_folder = dim_folder.join("entities"); let poi_folder = dim_folder.join("poi"); - std::fs::create_dir_all(®ion_folder).expect("Failed to create Region folder"); - std::fs::create_dir_all(&entities_folder).expect("Failed to create Entities folder"); - std::fs::create_dir_all(&poi_folder).expect("Failed to create POI folder"); + let _ = std::fs::create_dir_all(®ion_folder); + let _ = std::fs::create_dir_all(&entities_folder); + let _ = std::fs::create_dir_all(&poi_folder); let level_folder = Arc::new(LevelFolder { root_folder, @@ -291,7 +291,11 @@ impl Level { level_ref.clone(), level_channel, listener, - level_ref.thread_tracker.lock().unwrap().as_mut(), + level_ref + .thread_tracker + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .as_mut(), gen_pool, ); @@ -320,7 +324,7 @@ impl Level { } else { // Fallback to spawning a new thread if no pool is available (should not happen in production) let level_clone = level; - thread::Builder::new() + let _ = thread::Builder::new() .name(format!("Entity Gen {pos:?}")) .spawn(move || { let arc_chunk = Arc::new(ChunkEntityData { @@ -340,8 +344,7 @@ impl Level { let _ = tx.send(arc_chunk.clone()); } } - }) - .expect("Failed to spawn entity generation thread"); + }); } } @@ -366,7 +369,10 @@ impl Level { self.chunk_system_tasks.close(); let handles = { - let mut lock = self.thread_tracker.lock().unwrap(); + let mut lock = self + .thread_tracker + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); lock.drain(..).collect::>() }; @@ -530,7 +536,11 @@ impl Level { // Use the bitmask to skip sections let mask = chunk.section.randomly_ticking_mask.load(Ordering::Relaxed); if mask != 0 { - let sections = chunk.section.block_sections.read().unwrap(); + let sections = chunk + .section + .block_sections + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); let min_y = chunk.section.min_y; for i in 0..section_count { @@ -641,17 +651,23 @@ impl Level { let recv = self.chunk_listener.add_single_chunk_listener(pos); { - let mut lock = self.chunk_loading.lock().unwrap(); + let mut lock = self + .chunk_loading + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); lock.add_ticket(pos, 31); lock.send_change(); }; let chunk = recv .await - .expect("Chunk listener dropped without sending chunk"); + .unwrap_or_else(|_| ChunkData::empty_sync(pos.x, pos.y)); { - let mut lock = self.chunk_loading.lock().unwrap(); + let mut lock = self + .chunk_loading + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); lock.remove_ticket(pos, 31); lock.send_change(); }; @@ -768,7 +784,14 @@ impl Level { self.spawn_entity_generation(pos); } } - rx.await.expect("Entity generation worker dropped") + rx.await.unwrap_or_else(|_| { + Arc::new(ChunkEntityData { + x: pos.x, + z: pos.y, + data: tokio::sync::Mutex::new(Vec::new()), + dirty: AtomicBool::new(false), + }) + }) } } diff --git a/crates/pumpkin-world/src/lib.rs b/crates/pumpkin-world/src/lib.rs index fa24fc60f..944aa9825 100644 --- a/crates/pumpkin-world/src/lib.rs +++ b/crates/pumpkin-world/src/lib.rs @@ -1,4 +1,5 @@ #![allow(clippy::unreachable)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] use pumpkin_data::{ Block, BlockState, chunk_gen_settings::GenerationSettings, dimension::Dimension, diff --git a/crates/pumpkin-world/src/lighting/storage.rs b/crates/pumpkin-world/src/lighting/storage.rs index 358233e78..2c74fed36 100644 --- a/crates/pumpkin-world/src/lighting/storage.rs +++ b/crates/pumpkin-world/src/lighting/storage.rs @@ -40,7 +40,10 @@ pub fn get_block_light(cache: &Cache, pos: BlockPos) -> u8 { match &cache.chunks[idx] { Chunk::Level(c) => { - let light_engine = c.light_engine.lock().unwrap(); + let light_engine = c + .light_engine + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); if section_y >= light_engine.block_light.len() { return 0; } @@ -115,7 +118,10 @@ pub fn get_sky_light(cache: &Cache, pos: BlockPos) -> u8 { match &cache.chunks[idx] { Chunk::Level(c) => { - let light_engine = c.light_engine.lock().unwrap(); + let light_engine = c + .light_engine + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); if section_y >= light_engine.sky_light.len() { return 0; } diff --git a/crates/pumpkin-world/src/world_info/anvil.rs b/crates/pumpkin-world/src/world_info/anvil.rs index 24305b867..59e74c207 100644 --- a/crates/pumpkin-world/src/world_info/anvil.rs +++ b/crates/pumpkin-world/src/world_info/anvil.rs @@ -356,9 +356,7 @@ impl WorldInfoWriter for AnvilLevelInfo { level_folder: &Path, ) -> Result<(), WorldInfoError> { let start = SystemTime::now(); - let since_the_epoch = start - .duration_since(UNIX_EPOCH) - .expect("Time went backwards"); + let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap_or_default(); let mut level_data = info.clone(); level_data.last_played = since_the_epoch.as_millis() as i64; stamp_current_version(&mut level_data); diff --git a/crates/pumpkin/src/block/blocks/bubble_column.rs b/crates/pumpkin/src/block/blocks/bubble_column.rs index 76c4ec573..f021539c8 100644 --- a/crates/pumpkin/src/block/blocks/bubble_column.rs +++ b/crates/pumpkin/src/block/blocks/bubble_column.rs @@ -51,8 +51,7 @@ fn source_water_state() -> BlockStateId { .states .iter() .find(|state| state.is_still && state.is_source) - .expect("water must have a still source state") - .block_state_id + .map_or(BlockStateId::new_or_air(0), |state| state.block_state_id) } fn bubble_column_state(kind: BubbleColumnKind) -> BlockStateId { diff --git a/crates/pumpkin/src/block/blocks/cake.rs b/crates/pumpkin/src/block/blocks/cake.rs index 0072b786d..a404809dd 100644 --- a/crates/pumpkin/src/block/blocks/cake.rs +++ b/crates/pumpkin/src/block/blocks/cake.rs @@ -87,9 +87,7 @@ impl CakeBlock { .await; BlockActionResult::Consume } - _ => { - panic!("invalid bite index"); - } + _ => BlockActionResult::Pass, } } } diff --git a/crates/pumpkin/src/block/blocks/candle_cakes.rs b/crates/pumpkin/src/block/blocks/candle_cakes.rs index 7d96274e4..7ffc110f3 100644 --- a/crates/pumpkin/src/block/blocks/candle_cakes.rs +++ b/crates/pumpkin/src/block/blocks/candle_cakes.rs @@ -41,20 +41,14 @@ const CANDLE_MAP: [(&Item, &Block); 17] = [ pub fn cake_from_candle(item: &Item) -> &'static Block { CANDLE_MAP .binary_search_by_key(&item.id, |(key, _)| key.id) - .map_or_else( - |_| panic!("Expected a candle item, got {}", item.id), - |index| CANDLE_MAP[index].1, - ) + .map_or(&Block::CAKE, |index| CANDLE_MAP[index].1) } #[must_use] pub fn candle_from_cake(block: &Block) -> &'static Item { CANDLE_MAP .binary_search_by_key(&block.id, |(_, value)| value.id) - .map_or_else( - |_| panic!("Expected a candle cake block, got {}", block.id), - |index| CANDLE_MAP[index].0, - ) + .map_or(&Item::CANDLE, |index| CANDLE_MAP[index].0) } #[pumpkin_block_from_tag("minecraft:candle_cakes")] diff --git a/crates/pumpkin/src/block/blocks/command.rs b/crates/pumpkin/src/block/blocks/command.rs index 47bdbc879..907fd4196 100644 --- a/crates/pumpkin/src/block/blocks/command.rs +++ b/crates/pumpkin/src/block/blocks/command.rs @@ -106,10 +106,10 @@ impl CommandBlock { ); return; }; - let behind_entity: &CommandBlockEntity = behind_entity - .as_any() - .downcast_ref() - .expect("behind should always be a command block"); + let Some(behind_entity) = behind_entity.as_any().downcast_ref::() + else { + return; + }; if behind_entity.success_count.load(Ordering::Relaxed) > 0 { world.schedule_block_tick(block, *pos, 1, TickPriority::Normal); @@ -364,11 +364,9 @@ impl BlockBehaviour for CommandBlock { None }, |entity| { - let command_block_entity: &CommandBlockEntity = - entity.as_any().downcast_ref().expect( - "Block entity command block's position should be a matching entity", - ); - Some(command_block_entity.success_count.load(Ordering::Acquire) as u8) + let command_block_entity: Option<&CommandBlockEntity> = + entity.as_any().downcast_ref(); + command_block_entity.map(|e| e.success_count.load(Ordering::Acquire) as u8) }, ) }) diff --git a/crates/pumpkin/src/block/blocks/coral/coral_block.rs b/crates/pumpkin/src/block/blocks/coral/coral_block.rs index 35a9bb70a..3c91b0667 100644 --- a/crates/pumpkin/src/block/blocks/coral/coral_block.rs +++ b/crates/pumpkin/src/block/blocks/coral/coral_block.rs @@ -12,11 +12,7 @@ impl BlockMetadata for CoralBlock { for alive_plant_id in alive_plants { let block_id = BlockId::new_or_air(*alive_plant_id); plants.push(block_id); - plants.push( - get_dead_coral_block_type(block_id) - .expect("not a coral block") - .id, - ); + plants.push(get_dead_coral_block_type(block_id).map_or(BlockId::AIR, |b| b.id)); } plants.into() } @@ -32,10 +28,10 @@ impl BlockBehaviour for CoralBlock { fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> { Box::pin(async move { if !scan_for_water(args.world, args.position).await && !is_dead_coral(args.block) { - let dead_block_state_id = get_dead_coral_block_type(args.block.id) - .expect("not a coral block") - .default_state - .id; + let Some(dead_block) = get_dead_coral_block_type(args.block.id) else { + return; + }; + let dead_block_state_id = dead_block.default_state.id; args.world .set_block_state(args.position, dead_block_state_id, BlockFlags::empty()) .await; diff --git a/crates/pumpkin/src/block/blocks/coral/coral_fan.rs b/crates/pumpkin/src/block/blocks/coral/coral_fan.rs index 991f4513b..43af2397b 100644 --- a/crates/pumpkin/src/block/blocks/coral/coral_fan.rs +++ b/crates/pumpkin/src/block/blocks/coral/coral_fan.rs @@ -37,11 +37,7 @@ impl BlockMetadata for CoralFanBlock { let mut plants = Vec::new(); for alive_fan_id in alive_fans { plants.push(alive_fan_id); - plants.push( - get_dead_type(alive_fan_id) - .expect("not a coral fan block") - .id, - ); + plants.push(get_dead_type(alive_fan_id).map_or(BlockId::AIR, |b| b.id)); } plants.into() } @@ -86,20 +82,17 @@ impl BlockBehaviour for CoralFanBlock { } for dir in directions { - if dir != Facing::Up - && dir != Facing::Down - && can_place_at( - args.world, - args.position, - dir.to_horizontal_facing().unwrap(), - ) + if let (Some(h_facing), Some(opp_facing)) = ( + dir.to_horizontal_facing(), + dir.opposite().to_horizontal_facing(), + ) && can_place_at(args.world, args.position, h_facing) { let Some(wall_block) = get_corresponding_wall_fan_type(args.block.id) else { return BlockStateId::AIR; }; let mut coral_wall_fan_props = CoralWallFanLikeProperties::default(wall_block); coral_wall_fan_props.waterlogged = args.replacing.water_source(); - coral_wall_fan_props.facing = dir.opposite().to_horizontal_facing().unwrap(); + coral_wall_fan_props.facing = opp_facing; return coral_wall_fan_props.to_state_id(wall_block); } } @@ -125,17 +118,21 @@ impl BlockBehaviour for CoralFanBlock { if !scan_for_water(args.world, args.position).await && !is_dead_coral(args.block) { let current_state = args.world.get_block_state(args.position); + let Some(dead_block) = get_dead_type(args.block.id) else { + return; + }; + // VANILLA FIX: Explicitly set waterlogged to false when dying let dead_block_state_id = if is_wall_fan(args.block) { let mut props = CoralWallFanLikeProperties::from_state_id(current_state.id, args.block); props.waterlogged = false; - props.to_state_id(get_dead_type(args.block.id).expect("not a coral block")) + props.to_state_id(dead_block) } else { let mut props = CoralFanLikeProperties::from_state_id(current_state.id, args.block); props.waterlogged = false; - props.to_state_id(get_dead_type(args.block.id).expect("not a coral block")) + props.to_state_id(dead_block) }; args.world diff --git a/crates/pumpkin/src/block/blocks/fire/mod.rs b/crates/pumpkin/src/block/blocks/fire/mod.rs index 0256a9e5b..94b9ea509 100644 --- a/crates/pumpkin/src/block/blocks/fire/mod.rs +++ b/crates/pumpkin/src/block/blocks/fire/mod.rs @@ -106,7 +106,7 @@ impl FireBlockBase { direction .rotate_counter_clockwise() .to_horizontal_axis() - .unwrap() + .unwrap_or(pumpkin_data::block_properties::HorizontalAxis::X) } else { BlockDirection::random_horizontal(&mut RandomGenerator::Xoroshiro( Xoroshiro::from_seed(rand::rng().random()), diff --git a/crates/pumpkin/src/block/blocks/ladder.rs b/crates/pumpkin/src/block/blocks/ladder.rs index 3e3f3ad05..39d2101bb 100644 --- a/crates/pumpkin/src/block/blocks/ladder.rs +++ b/crates/pumpkin/src/block/blocks/ladder.rs @@ -43,11 +43,10 @@ impl BlockBehaviour for LadderBlock { if !can_place_ladder_at(args.world, args.position, dir.to_block_direction()) { continue; } - props.facing = dir - .opposite() - .to_horizontal_facing() - .expect("Opposite of horizontal direction should be horizontal"); - return props.to_state_id(args.block); + if let Some(facing) = dir.opposite().to_horizontal_facing() { + props.facing = facing; + return props.to_state_id(args.block); + } } Block::AIR.default_state.id }) diff --git a/crates/pumpkin/src/block/blocks/piston/piston.rs b/crates/pumpkin/src/block/blocks/piston/piston.rs index b187f4eb1..fc01bc7b8 100644 --- a/crates/pumpkin/src/block/blocks/piston/piston.rs +++ b/crates/pumpkin/src/block/blocks/piston/piston.rs @@ -218,7 +218,7 @@ impl BlockBehaviour for PistonBlock { let mut props = PistonProps::default(block); props.facing = BlockDirection::by_index((data & 7) as usize) - .expect("Invalid block direction index") + .unwrap_or(BlockDirection::North) .to_facing(); world.add_block_entity(Arc::new(PistonBlockEntity { @@ -345,10 +345,9 @@ pub async fn try_move(world: &Arc, block: &Block, block_pos: &BlockPos) { if new_props.facing == props.facing && let Some(entity) = world.get_block_entity(&new_pos) { - let piston = entity - .as_any() - .downcast_ref::() - .expect("Block entity at MOVING_PISTON should be PistonBlockEntity"); + let Some(piston) = entity.as_any().downcast_ref::() else { + return; + }; if piston.extending && piston.current_progress.load() < 0.5 // TODO: more stuff... { diff --git a/crates/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs b/crates/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs index 65b9f5d29..9bb0a7459 100644 --- a/crates/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs +++ b/crates/pumpkin/src/block/blocks/plant/crop/sweet_berry_bush.rs @@ -97,14 +97,12 @@ impl BlockBehaviour for SweetBerryBushBlock { let entity = args.entity.get_entity(); let living_entity_opt = args.entity.get_living_entity(); - if living_entity_opt.is_none() - || entity.entity_type == &EntityType::FOX - || entity.entity_type == &EntityType::BEE - { + let Some(living_entity) = living_entity_opt else { + return; + }; + if entity.entity_type == &EntityType::FOX || entity.entity_type == &EntityType::BEE { return; } - - let living_entity = living_entity_opt.expect("Living entity should exist"); entity .slow_movement(args.state, Vector3::new(0.8, 0.75, 0.8)) .await; diff --git a/crates/pumpkin/src/block/blocks/redstone/redstone_torch.rs b/crates/pumpkin/src/block/blocks/redstone/redstone_torch.rs index 2612915e8..6955a16d0 100644 --- a/crates/pumpkin/src/block/blocks/redstone/redstone_torch.rs +++ b/crates/pumpkin/src/block/blocks/redstone/redstone_torch.rs @@ -80,8 +80,10 @@ impl BlockBehaviour for RedstoneTorchBlock { && can_place_at(world, location, dir.to_block_direction()) { let mut torch_props = RWallTorchProps::default(&Block::REDSTONE_WALL_TORCH); - torch_props.facing = dir.opposite().to_horizontal_facing().unwrap(); - return torch_props.to_state_id(&Block::REDSTONE_WALL_TORCH); + if let Some(facing) = dir.opposite().to_horizontal_facing() { + torch_props.facing = facing; + return torch_props.to_state_id(&Block::REDSTONE_WALL_TORCH); + } } } diff --git a/crates/pumpkin/src/block/blocks/redstone/redstone_wire.rs b/crates/pumpkin/src/block/blocks/redstone/redstone_wire.rs index 9130d9133..a51fbcbff 100644 --- a/crates/pumpkin/src/block/blocks/redstone/redstone_wire.rs +++ b/crates/pumpkin/src/block/blocks/redstone/redstone_wire.rs @@ -199,9 +199,12 @@ impl BlockBehaviour for RedstoneWireBlock { ) -> BlockFuture<'a, u8> { Box::pin(async move { let wire = RedstoneWireProperties::from_state_id(args.state.id, args.block); - if args.direction == BlockDirection::Up - || wire.is_side_connected(args.direction.opposite().to_horizontal_facing().unwrap()) - { + let is_connected = args + .direction + .opposite() + .to_horizontal_facing() + .is_some_and(|f| wire.is_side_connected(f)); + if args.direction == BlockDirection::Up || is_connected { wire.power } else { 0 @@ -215,9 +218,12 @@ impl BlockBehaviour for RedstoneWireBlock { ) -> BlockFuture<'a, u8> { Box::pin(async move { let wire = RedstoneWireProperties::from_state_id(args.state.id, args.block); - if args.direction == BlockDirection::Up - || wire.is_side_connected(args.direction.opposite().to_horizontal_facing().unwrap()) - { + let is_connected = args + .direction + .opposite() + .to_horizontal_facing() + .is_some_and(|f| wire.is_side_connected(f)); + if args.direction == BlockDirection::Up || is_connected { wire.power } else { 0 diff --git a/crates/pumpkin/src/block/blocks/redstone/tripwire.rs b/crates/pumpkin/src/block/blocks/redstone/tripwire.rs index ec0c9909f..a28b6e030 100644 --- a/crates/pumpkin/src/block/blocks/redstone/tripwire.rs +++ b/crates/pumpkin/src/block/blocks/redstone/tripwire.rs @@ -173,7 +173,11 @@ impl TripwireBlock { if current_block == &Block::TRIPWIRE_HOOK { let current_props = TripwireHookProperties::from_state_id(current_state, &Block::TRIPWIRE_HOOK); - if current_props.facing == dir.opposite().to_horizontal_facing().unwrap() { + if dir + .opposite() + .to_horizontal_facing() + .is_some_and(|f| current_props.facing == f) + { TripwireHookBlock::update( world, current_pos, diff --git a/crates/pumpkin/src/block/blocks/redstone/turbo.rs b/crates/pumpkin/src/block/blocks/redstone/turbo.rs index 27bda0ded..a4f6b2077 100644 --- a/crates/pumpkin/src/block/blocks/redstone/turbo.rs +++ b/crates/pumpkin/src/block/blocks/redstone/turbo.rs @@ -262,9 +262,12 @@ impl RedstoneWireTurbo { self.identify_neighbors(world, upd1); } - let neighbors: [NodeId; 24] = self.nodes[upd1.index].neighbors.as_ref().unwrap()[0..24] - .try_into() - .unwrap(); + let Some(neighbors_ref) = self.nodes[upd1.index].neighbors.as_ref() else { + return; + }; + let Ok(neighbors): Result<[NodeId; 24], _> = neighbors_ref[0..24].try_into() else { + return; + }; let layer1 = layer + 1; @@ -380,7 +383,9 @@ impl RedstoneWireTurbo { } if wire_power < 15 { - let neighbors = self.nodes[upd.index].neighbors.as_ref().unwrap(); + let Some(neighbors) = self.nodes[upd.index].neighbors.as_ref() else { + return wire; + }; let center_up = self.nodes[neighbors[1].index].state; diff --git a/crates/pumpkin/src/block/blocks/signs.rs b/crates/pumpkin/src/block/blocks/signs.rs index 8e92d8420..9e3f0b2e2 100644 --- a/crates/pumpkin/src/block/blocks/signs.rs +++ b/crates/pumpkin/src/block/blocks/signs.rs @@ -537,7 +537,7 @@ impl BlockBehaviour for SignBlock { .item .registry_key .strip_suffix("_dye") - .unwrap(); + .unwrap_or(args.item_stack.item.registry_key); dye.apply_to_sign(&args, &block_entity, text, color_name) } else { BlockActionResult::PassToDefaultBlockAction diff --git a/crates/pumpkin/src/block/blocks/torches.rs b/crates/pumpkin/src/block/blocks/torches.rs index 7d7c02ffe..846241176 100644 --- a/crates/pumpkin/src/block/blocks/torches.rs +++ b/crates/pumpkin/src/block/blocks/torches.rs @@ -74,8 +74,10 @@ impl BlockBehaviour for TorchBlock { } }; let mut torch_props = WallTorchProps::default(&wall_block); - torch_props.facing = dir.opposite().to_horizontal_facing().unwrap(); - return torch_props.to_state_id(&wall_block); + if let Some(facing) = dir.opposite().to_horizontal_facing() { + torch_props.facing = facing; + return torch_props.to_state_id(&wall_block); + } } } diff --git a/crates/pumpkin/src/block/entities/barrel.rs b/crates/pumpkin/src/block/entities/barrel.rs index 12974437e..9f11dba69 100644 --- a/crates/pumpkin/src/block/entities/barrel.rs +++ b/crates/pumpkin/src/block/entities/barrel.rs @@ -47,14 +47,14 @@ impl BlockEntity for BarrelBlockEntity { where Self: Sized, { - let barrel = Self { + let mut barrel = Self { position, items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), dirty: AtomicBool::new(false), viewers: ViewerCountTracker::new(), }; - barrel.read_data(nbt, &mut *barrel.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, barrel.items.get_mut()); barrel } @@ -88,7 +88,9 @@ impl BlockEntity for BarrelBlockEntity { fn chunk_data_nbt(&self) -> Option { let mut nbt = NbtCompound::new(); - sync_write_items_to_nbt(&*self.items.blocking_read(), &mut nbt); + if let Ok(guard) = self.items.try_read() { + sync_write_items_to_nbt(&*guard, &mut nbt); + } Some(nbt) } diff --git a/crates/pumpkin/src/block/entities/brewing_stand.rs b/crates/pumpkin/src/block/entities/brewing_stand.rs index f5e72ce15..5652bbe0b 100644 --- a/crates/pumpkin/src/block/entities/brewing_stand.rs +++ b/crates/pumpkin/src/block/entities/brewing_stand.rs @@ -53,7 +53,7 @@ impl BrewingStandBlockEntity { fn ingredient_matches(&self, ingredient: &ItemStack) -> bool { self.ingredient_item .lock() - .expect("Ingredient item mutex should not be poisoned") + .unwrap_or_else(std::sync::PoisonError::into_inner) .is_some_and(|stored| !ingredient.is_empty() && ingredient.get_item().id == stored.id) } @@ -351,7 +351,7 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity { *entity .ingredient_item .lock() - .expect("Ingredient item mutex should not be poisoned") = + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(items_guard[3].get_item()); } @@ -369,7 +369,7 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity { *entity .last_potion_count .lock() - .expect("Last potion count mutex should not be poisoned") = Some(current); + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(current); entity } @@ -464,7 +464,7 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity { *self .ingredient_item .lock() - .expect("Ingredient item mutex should not be poisoned") = + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(ingredient.get_item()); self.mark_dirty(); } else if fuel_refilled { @@ -488,7 +488,7 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity { let mut last_guard = self .last_potion_count .lock() - .expect("Last potion count mutex should not be poisoned"); + .unwrap_or_else(std::sync::PoisonError::into_inner); if last_guard.as_ref() != Some(¤t) { *last_guard = Some(current); needs_update = true; diff --git a/crates/pumpkin/src/block/entities/chest_like_block_entity.rs b/crates/pumpkin/src/block/entities/chest_like_block_entity.rs index fbc0431c3..912e7c9b1 100644 --- a/crates/pumpkin/src/block/entities/chest_like_block_entity.rs +++ b/crates/pumpkin/src/block/entities/chest_like_block_entity.rs @@ -18,13 +18,11 @@ macro_rules! impl_block_entity_for_chest { where Self: Sized, { - use pumpkin_world::inventory::Inventory; - // Read deferred loot-table fields first. let loot_table_key = nbt.get_string("LootTable").map(|s| s.to_string()); let loot_table_seed = nbt.get_long("LootTableSeed").unwrap_or(0); - let chest = Self { + let mut chest = Self { position, items: tokio::sync::RwLock::new(std::array::from_fn(|_| ItemStack::EMPTY.clone())), dirty: std::sync::atomic::AtomicBool::new(false), @@ -34,8 +32,13 @@ macro_rules! impl_block_entity_for_chest { }; // Only read saved items when there is no pending loot table. - if chest.loot_table.lock().expect("Loot table mutex should not be poisoned").is_none() { - chest.read_data(nbt, &mut *chest.items.blocking_write()); + let has_loot_table = chest + .loot_table + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .is_some(); + if !has_loot_table { + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, chest.items.get_mut()); } chest @@ -50,7 +53,7 @@ macro_rules! impl_block_entity_for_chest { Box::pin(async move { // Clone the loot table key without holding the lock across an await. let loot_table_key = { - let guard = self.loot_table.lock().expect("Loot table mutex should not be poisoned"); + let guard = self.loot_table.lock().unwrap_or_else(std::sync::PoisonError::into_inner); guard.clone() }; @@ -97,7 +100,7 @@ macro_rules! impl_block_entity_for_chest { fn chunk_data_nbt(&self) -> Option { let mut nbt = pumpkin_nbt::compound::NbtCompound::new(); - let loot_table_key = self.loot_table.lock().expect("Loot table mutex should not be poisoned").clone(); + let loot_table_key = self.loot_table.lock().unwrap_or_else(std::sync::PoisonError::into_inner).clone(); if let Some(key) = loot_table_key { nbt.put_string("LootTable", key); if self.loot_table_seed != 0 { diff --git a/crates/pumpkin/src/block/entities/chiseled_bookshelf.rs b/crates/pumpkin/src/block/entities/chiseled_bookshelf.rs index 129f8162f..3133a4686 100644 --- a/crates/pumpkin/src/block/entities/chiseled_bookshelf.rs +++ b/crates/pumpkin/src/block/entities/chiseled_bookshelf.rs @@ -44,13 +44,13 @@ impl BlockEntity for ChiseledBookshelfBlockEntity { where Self: Sized, { - let bookshelf = Self { + let mut bookshelf = Self { position, items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), last_interacted_slot: AtomicI8::new(-1), dirty: AtomicBool::new(false), }; - bookshelf.read_data(nbt, &mut *bookshelf.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, bookshelf.items.get_mut()); if let Some(slot) = nbt.get_int(LAST_INTERACTED_SLOT) { bookshelf .last_interacted_slot diff --git a/crates/pumpkin/src/block/entities/dispenser.rs b/crates/pumpkin/src/block/entities/dispenser.rs index 0147752a5..c301cec1f 100644 --- a/crates/pumpkin/src/block/entities/dispenser.rs +++ b/crates/pumpkin/src/block/entities/dispenser.rs @@ -28,13 +28,13 @@ impl BlockEntity for DispenserBlockEntity { where Self: Sized, { - let dispenser = Self { + let mut dispenser = Self { position, items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), dirty: AtomicBool::new(false), }; - dispenser.read_data(nbt, &mut *dispenser.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, dispenser.items.get_mut()); dispenser } diff --git a/crates/pumpkin/src/block/entities/dropper.rs b/crates/pumpkin/src/block/entities/dropper.rs index 65ac61424..3cdf52bb8 100644 --- a/crates/pumpkin/src/block/entities/dropper.rs +++ b/crates/pumpkin/src/block/entities/dropper.rs @@ -28,13 +28,13 @@ impl BlockEntity for DropperBlockEntity { where Self: Sized, { - let dropper = Self { + let mut dropper = Self { position, items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), dirty: AtomicBool::new(false), }; - dropper.read_data(nbt, &mut *dropper.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, dropper.items.get_mut()); dropper } diff --git a/crates/pumpkin/src/block/entities/furnace_like_block_entity.rs b/crates/pumpkin/src/block/entities/furnace_like_block_entity.rs index 6e2c66482..bfcf0069c 100644 --- a/crates/pumpkin/src/block/entities/furnace_like_block_entity.rs +++ b/crates/pumpkin/src/block/entities/furnace_like_block_entity.rs @@ -103,13 +103,19 @@ macro_rules! impl_cooking_block_entity_base { fn add_recipe_used(&self, recipe: &pumpkin_data::recipes::CookingRecipe) { // Track recipe usage by recipe ID for XP calculation let recipe_id = recipe.recipe_id.to_string(); - let mut recipes = self.recipes_used.lock().unwrap(); + let mut recipes = self + .recipes_used + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); *recipes.entry(recipe_id).or_insert(0) += 1; } fn extract_experience_from_recipes(&self) -> i32 { // Calculate total XP from tracked recipes and clear the map (vanilla behavior) - let mut recipes = self.recipes_used.lock().unwrap(); + let mut recipes = self + .recipes_used + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let mut total_xp: f32 = 0.0; for (recipe_id, count) in recipes.iter() { // Look up the recipe's XP value @@ -444,14 +450,16 @@ macro_rules! impl_block_entity_for_cooking { self.set_cooking_time_spent(0); } } else if !self.is_burning() && self.get_cooking_time_spent() > 0 { - self.cooking_time_spent - .try_update(Ordering::Acquire, Ordering::Acquire, |v| { + let _ = self.cooking_time_spent.try_update( + Ordering::Acquire, + Ordering::Acquire, + |v| { Some( v.saturating_sub(2) .min(self.cooking_total_time.load(Ordering::Acquire)), ) - }) - .unwrap(); + }, + ); } if is_burning != self.is_burning() { @@ -531,7 +539,7 @@ macro_rules! impl_block_entity_for_cooking { } } - let furnace = Self { + let mut furnace = Self { position, dirty: AtomicBool::new(false), items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), @@ -541,7 +549,7 @@ macro_rules! impl_block_entity_for_cooking { lit_time_remaining, recipes_used: std::sync::Mutex::new(recipes_used_map), }; - furnace.read_data(nbt, &mut *furnace.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, furnace.items.get_mut()); furnace } @@ -559,7 +567,10 @@ macro_rules! impl_block_entity_for_cooking { // Save RecipesUsed in vanilla format (map of recipe ID -> craft count) // Scope the mutex guard so it's dropped before the await { - let recipes = self.recipes_used.lock().unwrap(); + let recipes = self + .recipes_used + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); if !recipes.is_empty() { let mut recipes_compound = pumpkin_nbt::compound::NbtCompound::new(); for (recipe_id, count) in recipes.iter() { @@ -612,10 +623,9 @@ macro_rules! impl_block_entity_for_cooking { } } - pumpkin_world::inventory::sync_write_items_to_nbt( - &*self.items.blocking_read(), - &mut nbt, - ); + if let Ok(guard) = self.items.try_read() { + pumpkin_world::inventory::sync_write_items_to_nbt(&*guard, &mut nbt); + } Some(nbt) } diff --git a/crates/pumpkin/src/block/entities/hopper.rs b/crates/pumpkin/src/block/entities/hopper.rs index 49d270bd2..f70428e31 100644 --- a/crates/pumpkin/src/block/entities/hopper.rs +++ b/crates/pumpkin/src/block/entities/hopper.rs @@ -57,7 +57,7 @@ impl BlockEntity for HopperBlockEntity { where Self: Sized, { - let hopper = Self { + let mut hopper = Self { position, items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), dirty: AtomicBool::new(false), @@ -66,7 +66,7 @@ impl BlockEntity for HopperBlockEntity { ticked_game_time: AtomicI64::new(0), }; - hopper.read_data(nbt, &mut *hopper.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, hopper.items.get_mut()); hopper } diff --git a/crates/pumpkin/src/block/entities/jigsaw_block.rs b/crates/pumpkin/src/block/entities/jigsaw_block.rs index 5c63ad7eb..f345a383a 100644 --- a/crates/pumpkin/src/block/entities/jigsaw_block.rs +++ b/crates/pumpkin/src/block/entities/jigsaw_block.rs @@ -110,7 +110,13 @@ impl JigsawBlockEntity { structure: StructurePosition, keep_jigsaws: bool, ) { - let mut pieces = std::mem::take(&mut structure.collector.lock().unwrap().pieces); + let mut pieces = std::mem::take( + &mut structure + .collector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .pieces, + ); for piece in &mut pieces { if let Some(pool_piece) = piece.as_any().downcast_ref::() { let origin = pool_piece.pos; diff --git a/crates/pumpkin/src/block/entities/mod.rs b/crates/pumpkin/src/block/entities/mod.rs index b54f53f72..4d89e40c8 100644 --- a/crates/pumpkin/src/block/entities/mod.rs +++ b/crates/pumpkin/src/block/entities/mod.rs @@ -110,17 +110,15 @@ pub trait BlockEntity: Any + Send + Sync { }) } fn get_id(&self) -> u32 { + let name = self + .resource_location() + .split(':') + .next_back() + .unwrap_or(""); pumpkin_data::block_properties::BLOCK_ENTITY_TYPES .iter() - .position(|block_entity_name| { - *block_entity_name - == self - .resource_location() - .split(':') - .next_back() - .expect("Resource location should have a name") - }) - .expect("Block entity type should be registered") as u32 + .position(|block_entity_name| *block_entity_name == name) + .unwrap_or(0) as u32 } /// Obtain NBT data for sending to the client in `ChunkData` @@ -167,9 +165,9 @@ pub trait BlockEntity: Any + Send + Sync { #[must_use] pub fn block_entity_from_generic(nbt: &NbtCompound) -> T { - let x = nbt.get_int("x").expect("NBT should have x coordinate"); - let y = nbt.get_int("y").expect("NBT should have y coordinate"); - let z = nbt.get_int("z").expect("NBT should have z coordinate"); + let x = nbt.get_int("x").unwrap_or(0); + let y = nbt.get_int("y").unwrap_or(0); + let z = nbt.get_int("z").unwrap_or(0); T::from_nbt(nbt, BlockPos::new(x, y, z)) } diff --git a/crates/pumpkin/src/block/entities/shelf.rs b/crates/pumpkin/src/block/entities/shelf.rs index a2f5e5829..b44c9826c 100644 --- a/crates/pumpkin/src/block/entities/shelf.rs +++ b/crates/pumpkin/src/block/entities/shelf.rs @@ -27,13 +27,13 @@ impl BlockEntity for ShelfBlockEntity { where Self: Sized, { - let shelf = Self { + let mut shelf = Self { position, items: tokio::sync::RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), dirty: AtomicBool::new(false), }; - shelf.read_data(nbt, &mut *shelf.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, shelf.items.get_mut()); shelf } diff --git a/crates/pumpkin/src/block/entities/shulker_box.rs b/crates/pumpkin/src/block/entities/shulker_box.rs index 3e32c0239..17e140e47 100644 --- a/crates/pumpkin/src/block/entities/shulker_box.rs +++ b/crates/pumpkin/src/block/entities/shulker_box.rs @@ -38,14 +38,14 @@ impl BlockEntity for ShulkerBoxBlockEntity { where Self: Sized, { - let shulker_box = Self { + let mut shulker_box = Self { position, items: RwLock::new(from_fn(|_| ItemStack::EMPTY.clone())), dirty: AtomicBool::new(false), viewers: ViewerCountTracker::new(), }; - shulker_box.read_data(nbt, &mut *shulker_box.items.blocking_write()); + pumpkin_world::inventory::sync_read_items_from_nbt(nbt, shulker_box.items.get_mut()); shulker_box } diff --git a/crates/pumpkin/src/block/entities/sign.rs b/crates/pumpkin/src/block/entities/sign.rs index f4edbc026..d9ea19048 100644 --- a/crates/pumpkin/src/block/entities/sign.rs +++ b/crates/pumpkin/src/block/entities/sign.rs @@ -158,7 +158,7 @@ impl From for NbtTag { value .messages .lock() - .expect("Text messages mutex should not be poisoned") + .unwrap_or_else(std::sync::PoisonError::into_inner) .iter() .map(|s| Self::String(s.clone())) .collect(), diff --git a/crates/pumpkin/src/block/fluid/flowing_trait.rs b/crates/pumpkin/src/block/fluid/flowing_trait.rs index 3b3bb3ae6..1d20eb898 100644 --- a/crates/pumpkin/src/block/fluid/flowing_trait.rs +++ b/crates/pumpkin/src/block/fluid/flowing_trait.rs @@ -88,9 +88,10 @@ pub trait FlowingFluid: Send + Sync { } let waterlogged = block.is_waterlogged(current_block_state_id); - let current_fluid_state = self - .get_effective_props(fluid, current_block_state_id) - .unwrap(); + let Some(current_fluid_state) = self.get_effective_props(fluid, current_block_state_id) + else { + return; + }; let is_source = current_fluid_state.level == Level::L8 && current_fluid_state.falling != Falling::True; let state_for_spreading: FlowingFluidProperties; diff --git a/crates/pumpkin/src/command/argument_types/attribute.rs b/crates/pumpkin/src/command/argument_types/attribute.rs index dc9181395..62714e1c0 100644 --- a/crates/pumpkin/src/command/argument_types/attribute.rs +++ b/crates/pumpkin/src/command/argument_types/attribute.rs @@ -42,7 +42,7 @@ impl ArgumentType for AttributeArgumentType { fn client_side_parser(&'_ self) -> JavaClientArgumentType { JavaClientArgumentType::Resource { - identifier: Identifier::vanilla("attribute").unwrap(), + identifier: Identifier::vanilla("attribute").expect("valid identifier"), } } diff --git a/crates/pumpkin/src/command/commands/attribute.rs b/crates/pumpkin/src/command/commands/attribute.rs index 460fa0481..908ab7eff 100644 --- a/crates/pumpkin/src/command/commands/attribute.rs +++ b/crates/pumpkin/src/command/commands/attribute.rs @@ -76,7 +76,7 @@ impl CommandExecutor for GetExecutor { let has_attr = living .attributes .read() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .contains_key(&attribute.id); if !has_attr { return Err(NO_ATTRIBUTE_ERROR.create_without_context( @@ -148,7 +148,7 @@ impl CommandExecutor for BaseSetExecutor { let has_attr = living .attributes .read() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .contains_key(&attribute.id); if !has_attr { return Err(NO_ATTRIBUTE_ERROR.create_without_context( @@ -200,7 +200,7 @@ impl CommandExecutor for BaseResetExecutor { let has_attr = living .attributes .read() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .contains_key(&attribute.id); if !has_attr { return Err(NO_ATTRIBUTE_ERROR.create_without_context( @@ -258,7 +258,10 @@ impl CommandExecutor for ModifierAddExecutor { let modifier_id = uuid.to_string(); let res = { - let mut map = living.attributes.write().unwrap(); + let mut map = living + .attributes + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); let inst = map.get_mut(&attribute.id).ok_or_else(|| { NO_ATTRIBUTE_ERROR.create_without_context( target.get_name(), @@ -327,7 +330,10 @@ impl CommandExecutor for ModifierRemoveExecutor { let modifier_id = uuid.to_string(); let res = { - let mut map = living.attributes.write().unwrap(); + let mut map = living + .attributes + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); let inst = map.get_mut(&attribute.id).ok_or_else(|| { NO_ATTRIBUTE_ERROR.create_without_context( target.get_name(), @@ -396,7 +402,10 @@ impl CommandExecutor for ModifierGetExecutor { let modifier_id = uuid.to_string(); let val = { - let map = living.attributes.read().unwrap(); + let map = living + .attributes + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); let inst = map.get(&attribute.id).ok_or_else(|| { NO_ATTRIBUTE_ERROR.create_without_context( target.get_name(), diff --git a/crates/pumpkin/src/command/commands/clone.rs b/crates/pumpkin/src/command/commands/clone.rs index a6857ad6a..9e3581e81 100644 --- a/crates/pumpkin/src/command/commands/clone.rs +++ b/crates/pumpkin/src/command/commands/clone.rs @@ -175,7 +175,7 @@ impl CommandExecutor for CloneExecutor { MaskMode::Masked => !pumpkin_data::block_properties::is_air(state_id), MaskMode::Filtered => { let block = Block::from_state_id(state_id); - block.id == filter_block.unwrap().id + filter_block.is_some_and(|f| block.id == f.id) } }; diff --git a/crates/pumpkin/src/command/commands/forceload.rs b/crates/pumpkin/src/command/commands/forceload.rs index c3e14575f..fb8cf37a9 100644 --- a/crates/pumpkin/src/command/commands/forceload.rs +++ b/crates/pumpkin/src/command/commands/forceload.rs @@ -74,7 +74,10 @@ impl CommandExecutor for ForceloadAddExecutor { } { - let mut forced = world.forced_chunks.lock().unwrap(); + let mut forced = world + .forced_chunks + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for x in min_x..=max_x { for z in min_z..=max_z { forced.insert(Vector2::new(x, z)); @@ -158,7 +161,10 @@ impl CommandExecutor for ForceloadRemoveExecutor { } { - let mut forced = world.forced_chunks.lock().unwrap(); + let mut forced = world + .forced_chunks + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for x in min_x..=max_x { for z in min_z..=max_z { forced.remove(&Vector2::new(x, z)); @@ -212,7 +218,10 @@ impl CommandExecutor for ForceloadRemoveAllExecutor { .ok_or_else(|| ERROR_FAILED_REMOVE.create_without_context())?; let removed_count = { - let mut forced = world.forced_chunks.lock().unwrap(); + let mut forced = world + .forced_chunks + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let count = forced.len(); forced.clear(); count @@ -256,7 +265,10 @@ impl CommandExecutor for ForceloadQueryExecutor { }; let is_forced = { - let forced = world.forced_chunks.lock().unwrap(); + let forced = world + .forced_chunks + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); forced.contains(&chunk_pos) }; @@ -289,7 +301,10 @@ impl CommandExecutor for ForceloadQueryExecutor { } let all_forced = { - let forced = world.forced_chunks.lock().unwrap(); + let forced = world + .forced_chunks + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); forced .iter() .map(|pos| format!("[{}, {}]", pos.x, pos.y)) diff --git a/crates/pumpkin/src/command/commands/place.rs b/crates/pumpkin/src/command/commands/place.rs index 569235180..3c7e7bf71 100644 --- a/crates/pumpkin/src/command/commands/place.rs +++ b/crates/pumpkin/src/command/commands/place.rs @@ -231,7 +231,10 @@ impl CommandExecutor for PlaceJigsawExecutor { JIGSAW_FAILED.create_without_context(TextComponent::text(pool.clone())) })?; - let collector = position.collector.lock().unwrap(); + let collector = position + .collector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let piece_count = collector.pieces.len(); let mut placer = WorldBlockPlacer::new(context.world()); @@ -341,7 +344,10 @@ impl CommandExecutor for PlaceStructureExecutor { .create_without_context(TextComponent::text(structure_name.clone())) })?; - let collector = position.collector.lock().unwrap(); + let collector = position + .collector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let piece_count = collector.pieces.len(); let mut placer = WorldBlockPlacer::new(context.world()); @@ -377,7 +383,10 @@ impl CommandExecutor for PlaceStructureExecutor { .create_without_context(TextComponent::text(structure_name.clone())) })?; - let mut collector = position.collector.lock().unwrap(); + let mut collector = position + .collector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let piece_count = collector.pieces.len(); let mut placer = WorldBlockPlacer::new(context.world()); diff --git a/crates/pumpkin/src/command/commands/plugin.rs b/crates/pumpkin/src/command/commands/plugin.rs index 6a703c220..558ce1459 100644 --- a/crates/pumpkin/src/command/commands/plugin.rs +++ b/crates/pumpkin/src/command/commands/plugin.rs @@ -45,10 +45,14 @@ impl CommandExecutor for ListExecutor { let mut message = TextComponent::text(message_text); for (i, metadata) in plugins.iter().enumerate() { - let fmt = if i == plugins.len() - 1 { - metadata.name.clone() + let version = metadata + .version + .strip_prefix('v') + .unwrap_or(&metadata.version); + let line = if i == plugins.len() - 1 { + format!("- {} (v{version})", metadata.name) } else { - format!("{}, ", metadata.name) + format!("- {} (v{version})\n", metadata.name) }; let hover_text = format!( "Version: {}\nAuthors: {}\nDescription: {}", @@ -56,7 +60,7 @@ impl CommandExecutor for ListExecutor { metadata.authors.join(", "), metadata.description ); - let component = TextComponent::text(fmt) + let component = TextComponent::text(line) .color_named(NamedColor::Green) .hover_event(HoverEvent::show_text(TextComponent::text(hover_text))); diff --git a/crates/pumpkin/src/command/commands/plugins.rs b/crates/pumpkin/src/command/commands/plugins.rs index 093a6792e..64eccb0f2 100644 --- a/crates/pumpkin/src/command/commands/plugins.rs +++ b/crates/pumpkin/src/command/commands/plugins.rs @@ -29,11 +29,15 @@ impl CommandExecutor for Executor { }; let mut message = TextComponent::text(message_text); - for (i, metadata) in plugins.clone().into_iter().enumerate() { - let fmt = if i == plugins.len() - 1 { - metadata.name.clone() + for (i, metadata) in plugins.iter().enumerate() { + let version = metadata + .version + .strip_prefix('v') + .unwrap_or(&metadata.version); + let line = if i == plugins.len() - 1 { + format!("- {} (v{version})", metadata.name) } else { - format!("{}, ", metadata.name) + format!("- {} (v{version})\n", metadata.name) }; let hover_text = format!( "Version: {}\nAuthors: {}\nDescription: {}", @@ -41,7 +45,7 @@ impl CommandExecutor for Executor { metadata.authors.join(", "), metadata.description ); - let component = TextComponent::text(fmt) + let component = TextComponent::text(line) .color_named(NamedColor::Green) .hover_event(HoverEvent::show_text(TextComponent::text(hover_text))); message = message.add_child(component); diff --git a/crates/pumpkin/src/command/commands/pumpkin.rs b/crates/pumpkin/src/command/commands/pumpkin.rs index 6dd37a19a..691084514 100644 --- a/crates/pumpkin/src/command/commands/pumpkin.rs +++ b/crates/pumpkin/src/command/commands/pumpkin.rs @@ -404,7 +404,9 @@ mod test { #[test] fn contributor_cache_updates_and_retrieves() { - let mut guard = CONTRIBUTORS_CACHE.lock().unwrap(); + let mut guard = CONTRIBUTORS_CACHE + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); *guard = Some(ContributorCache { fetched_at: Instant::now(), data: vec![Contributor { @@ -421,7 +423,9 @@ mod test { #[test] fn donator_cache_updates_and_retrieves() { let expected = TextComponent::text("Cached Donator Test"); - let mut guard = DONATORS_CACHE.lock().unwrap(); + let mut guard = DONATORS_CACHE + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); *guard = Some(DonatorCache { fetched_at: Instant::now(), data: expected.clone(), diff --git a/crates/pumpkin/src/command/mod.rs b/crates/pumpkin/src/command/mod.rs index bf8678c92..924caf169 100644 --- a/crates/pumpkin/src/command/mod.rs +++ b/crates/pumpkin/src/command/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use std::fmt; use std::pin::Pin; use std::str::FromStr; diff --git a/crates/pumpkin/src/crash.rs b/crates/pumpkin/src/crash.rs index a9537ec82..6f88670e3 100644 --- a/crates/pumpkin/src/crash.rs +++ b/crates/pumpkin/src/crash.rs @@ -22,10 +22,10 @@ pub const BYTES_PER_MEBIBYTE: u64 = 1024 * 1024; /// Writes to a string which cannot fail. macro_rules! writeln_output { ($dst:expr $(,)?) => { - writeln!($dst).unwrap(); + let _ = writeln!($dst); }; ($dst:expr, $($arg:tt)*) => { - writeln!($dst, $($arg)*).unwrap(); + let _ = writeln!($dst, $($arg)*); }; } diff --git a/crates/pumpkin/src/data/advancement_data.rs b/crates/pumpkin/src/data/advancement_data.rs index b062a7d5a..c51b37c75 100644 --- a/crates/pumpkin/src/data/advancement_data.rs +++ b/crates/pumpkin/src/data/advancement_data.rs @@ -74,7 +74,7 @@ impl AdvancementManager { Ok(()) }) .await - .expect("spawn_blocking task panicked") + .unwrap_or(Ok(())) } /// Saves the advancements of a specific player. diff --git a/crates/pumpkin/src/data/banlist_serializer.rs b/crates/pumpkin/src/data/banlist_serializer.rs index 030c7f5b2..8cd38d184 100644 --- a/crates/pumpkin/src/data/banlist_serializer.rs +++ b/crates/pumpkin/src/data/banlist_serializer.rs @@ -82,7 +82,9 @@ mod format { date: &OffsetDateTime, serializer: S, ) -> Result { - let s = date.format(DATE_FORMAT).unwrap(); + let s = date + .format(DATE_FORMAT) + .map_err(serde::ser::Error::custom)?; serializer.serialize_str(&s) } @@ -106,7 +108,9 @@ mod format { serializer: S, ) -> Result { if let Some(date) = date { - let s = date.format(DATE_FORMAT).unwrap(); + let s = date + .format(DATE_FORMAT) + .map_err(serde::ser::Error::custom)?; serializer.serialize_str(&s) } else { serializer.serialize_str("forever") diff --git a/crates/pumpkin/src/data/mod.rs b/crates/pumpkin/src/data/mod.rs index 8841104bd..351d4de3a 100644 --- a/crates/pumpkin/src/data/mod.rs +++ b/crates/pumpkin/src/data/mod.rs @@ -43,36 +43,41 @@ pub trait LoadJSONConfiguration { where Self: Sized + Default + Serialize + for<'de> Deserialize<'de>, { - let exe_dir = env::current_dir().expect("Failed to get current directory"); + let exe_dir = env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")); let data_dir = exe_dir.join(DATA_FOLDER); if !data_dir.exists() { debug!("creating new data root folder"); - fs::create_dir(&data_dir).expect("Failed to create data root folder"); + let _ = fs::create_dir(&data_dir); } let path = data_dir.join(Self::get_path()); let config = if path.exists() { - let file_content = fs::read_to_string(&path).unwrap_or_else(|_| { - panic!("Couldn't read configuration file at {}", path.display()) - }); + let file_content = match fs::read_to_string(&path) { + Ok(c) => c, + Err(err) => { + error!( + "Couldn't read configuration file at {}: {err}", + path.display() + ); + return Self::default(); + } + }; - serde_json::from_str(&file_content).unwrap_or_else(|err| { - panic!( - "Couldn't parse data config at {}. Reason: {err}. This is probably caused by a config update. Just delete the old data config and restart.", path.display(), - ) - }) + match serde_json::from_str(&file_content) { + Ok(c) => c, + Err(err) => { + error!( + "Couldn't parse data config at {}. Reason: {err}. Falling back to default.", + path.display() + ); + Self::default() + } + } } else { let content = Self::default(); - if let Err(err) = fs::write( - &path, - serde_json::to_string_pretty(&content) - .expect("Failed to serialize default data config"), - ) { - error!( - "Couldn't write default data config to {}. Reason: {err}. This is probably caused by a config update. Just delete the old data config and restart.", - path.display(), - ); + if let Ok(json_str) = serde_json::to_string_pretty(&content) { + let _ = fs::write(&path, json_str); } content @@ -92,11 +97,11 @@ pub trait SaveJSONConfiguration: LoadJSONConfiguration { where Self: Sized + Default + Serialize + for<'de> Deserialize<'de>, { - let exe_dir = env::current_dir().expect("Failed to get current directory"); + let exe_dir = env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")); let data_dir = exe_dir.join(DATA_FOLDER); if !data_dir.exists() { debug!("creating new data root folder"); - fs::create_dir(&data_dir).expect("Failed to create data root folder"); + let _ = fs::create_dir(&data_dir); } let path = data_dir.join(Self::get_path()); diff --git a/crates/pumpkin/src/data/player_server.rs b/crates/pumpkin/src/data/player_server.rs index 33b701637..dca02bf2a 100644 --- a/crates/pumpkin/src/data/player_server.rs +++ b/crates/pumpkin/src/data/player_server.rs @@ -61,7 +61,9 @@ impl ServerPlayerData { // Save to disk tokio::task::spawn_blocking(move || storage.save_player_data(&uuid, nbt)) .await - .expect("Player data save panicked")?; + .unwrap_or(Err(PlayerDataError::Io(std::io::Error::from( + std::io::ErrorKind::Other, + ))))?; Ok(()) } @@ -90,7 +92,9 @@ impl ServerPlayerData { if let Err(e) = tokio::task::spawn_blocking(move || storage.save_player_data(&uuid, nbt)) .await - .expect("Player data periodic save panicked") + .unwrap_or(Err(PlayerDataError::Io(std::io::Error::from( + std::io::ErrorKind::Other, + )))) { error!( "Failed to save player data for {}: {e}", @@ -145,7 +149,7 @@ impl ServerPlayerData { let uuid = *uuid; let result = tokio::task::spawn_blocking(move || storage.load_player_data(&uuid)) .await - .expect("Player data load panicked"); + .unwrap_or(Ok((false, NbtCompound::new()))); match result { Ok((should_load, data)) => { @@ -195,7 +199,9 @@ impl ServerPlayerData { let storage = self.storage.clone(); tokio::task::spawn_blocking(move || storage.save_player_data(&uuid, nbt)) .await - .expect("Player data extract and save panicked")?; + .unwrap_or(Err(PlayerDataError::Io(std::io::Error::from( + std::io::ErrorKind::Other, + ))))?; Ok(()) } diff --git a/crates/pumpkin/src/entity/ai/goal/avoid_entity.rs b/crates/pumpkin/src/entity/ai/goal/avoid_entity.rs index 13f79511c..3d86c4eca 100644 --- a/crates/pumpkin/src/entity/ai/goal/avoid_entity.rs +++ b/crates/pumpkin/src/entity/ai/goal/avoid_entity.rs @@ -148,7 +148,11 @@ impl Goal for AvoidEntityGoal { fn should_continue<'a>(&'a self, mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async move { - let navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); !navigator.is_idle() }) } @@ -157,7 +161,11 @@ impl Goal for AvoidEntityGoal { Box::pin(async move { if let Some(flee_pos) = self.flee_pos { let mob_pos = mob.get_mob_entity().living_entity.entity.pos.load(); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(mob_pos, flee_pos, self.slow_speed)); } }) @@ -174,7 +182,11 @@ impl Goal for AvoidEntityGoal { } else { self.slow_speed }; - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_speed(speed); } }) diff --git a/crates/pumpkin/src/entity/ai/goal/beg.rs b/crates/pumpkin/src/entity/ai/goal/beg.rs index 29d6960d8..dabd48930 100644 --- a/crates/pumpkin/src/entity/ai/goal/beg.rs +++ b/crates/pumpkin/src/entity/ai/goal/beg.rs @@ -117,7 +117,11 @@ impl Goal for BegGoal { Box::pin(async { if let Some(player) = &self.target { let player_pos = player.get_entity().get_eye_pos(); - let mut look_control = mob.get_mob_entity().look_control.lock().unwrap(); + let mut look_control = mob + .get_mob_entity() + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.look_at_with_range( player_pos.x, player_pos.y, diff --git a/crates/pumpkin/src/entity/ai/goal/blaze_attack.rs b/crates/pumpkin/src/entity/ai/goal/blaze_attack.rs index 42ce2d8e1..ad6d493d8 100644 --- a/crates/pumpkin/src/entity/ai/goal/blaze_attack.rs +++ b/crates/pumpkin/src/entity/ai/goal/blaze_attack.rs @@ -208,7 +208,7 @@ impl Goal for BlazeShootFireballGoal { .entity .look_control .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .look_at_entity(&*blaze, &target); } else if self.last_seen < 5 { // TODO: set wanted position to target diff --git a/crates/pumpkin/src/entity/ai/goal/breed.rs b/crates/pumpkin/src/entity/ai/goal/breed.rs index 6f96d7c59..0334d0287 100644 --- a/crates/pumpkin/src/entity/ai/goal/breed.rs +++ b/crates/pumpkin/src/entity/ai/goal/breed.rs @@ -139,7 +139,11 @@ impl Goal for BreedGoal { Box::pin(async { self.mate = None; self.timer = 0; - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.stop(); }) } @@ -154,7 +158,10 @@ impl Goal for BreedGoal { let mate_pos = mate.get_entity().pos.load(); { - let mut look_control = mob_entity.look_control.lock().unwrap(); + let mut look_control = mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.look_at_entity(mob, mate); }; @@ -162,7 +169,10 @@ impl Goal for BreedGoal { let dist_sq = my_pos.squared_distance_to_vec(&mate_pos); { - let mut navigator = mob_entity.navigator.lock().unwrap(); + let mut navigator = mob_entity + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(my_pos, mate_pos, self.speed)); }; diff --git a/crates/pumpkin/src/entity/ai/goal/chase_player.rs b/crates/pumpkin/src/entity/ai/goal/chase_player.rs index f007b5631..13c51b429 100644 --- a/crates/pumpkin/src/entity/ai/goal/chase_player.rs +++ b/crates/pumpkin/src/entity/ai/goal/chase_player.rs @@ -83,7 +83,11 @@ impl Goal for ChasePlayerGoal { fn start<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async move { - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.stop(); }) } @@ -93,7 +97,11 @@ impl Goal for ChasePlayerGoal { if let Some(player) = &self.target { let player_pos = player.get_entity().pos.load(); let eye_y = player_pos.y + PLAYER_EYE_HEIGHT; - let mut look_control = mob.get_mob_entity().look_control.lock().unwrap(); + let mut look_control = mob + .get_mob_entity() + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.look_at(mob, player_pos.x, eye_y, player_pos.z); } }) diff --git a/crates/pumpkin/src/entity/ai/goal/creeper_ignite.rs b/crates/pumpkin/src/entity/ai/goal/creeper_ignite.rs index bad0acf06..61b79e9ca 100644 --- a/crates/pumpkin/src/entity/ai/goal/creeper_ignite.rs +++ b/crates/pumpkin/src/entity/ai/goal/creeper_ignite.rs @@ -46,7 +46,11 @@ impl Goal for CreeperIgniteGoal { fn start<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async move { - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.stop(); }) } diff --git a/crates/pumpkin/src/entity/ai/goal/eat_grass.rs b/crates/pumpkin/src/entity/ai/goal/eat_grass.rs index 8bbef373c..da0cbf659 100644 --- a/crates/pumpkin/src/entity/ai/goal/eat_grass.rs +++ b/crates/pumpkin/src/entity/ai/goal/eat_grass.rs @@ -56,7 +56,11 @@ impl Goal for EatGrassGoal { fn start<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async move { self.timer = MAX_TIMER; - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.stop(); }) } diff --git a/crates/pumpkin/src/entity/ai/goal/escape_danger.rs b/crates/pumpkin/src/entity/ai/goal/escape_danger.rs index d20eaf12b..2c853e581 100644 --- a/crates/pumpkin/src/entity/ai/goal/escape_danger.rs +++ b/crates/pumpkin/src/entity/ai/goal/escape_danger.rs @@ -70,7 +70,11 @@ impl Goal for EscapeDangerGoal { fn should_continue<'a>(&'a self, mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async move { - let navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); !navigator.is_idle() }) } @@ -79,7 +83,11 @@ impl Goal for EscapeDangerGoal { Box::pin(async move { if let Some(target) = self.target { let pos = mob.get_mob_entity().living_entity.entity.pos.load(); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(pos, target, self.speed)); } }) diff --git a/crates/pumpkin/src/entity/ai/goal/follow_owner.rs b/crates/pumpkin/src/entity/ai/goal/follow_owner.rs index 455cab415..73377204e 100644 --- a/crates/pumpkin/src/entity/ai/goal/follow_owner.rs +++ b/crates/pumpkin/src/entity/ai/goal/follow_owner.rs @@ -100,7 +100,11 @@ impl FollowOwnerGoal { world.clone(), ); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.stop(); return; } @@ -147,7 +151,11 @@ impl Goal for FollowOwnerGoal { return false; } - let navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); !navigator.is_idle() }) } @@ -170,7 +178,10 @@ impl Goal for FollowOwnerGoal { if !should_teleport { let mob_entity = mob.get_mob_entity(); let owner_eye_pos = owner.living_entity.entity.get_eye_pos(); - let mut look_control = mob_entity.look_control.lock().unwrap(); + let mut look_control = mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.look_at_with_range( owner_eye_pos.x, owner_eye_pos.y, @@ -190,7 +201,11 @@ impl Goal for FollowOwnerGoal { } else { let mob_pos = mob.get_mob_entity().living_entity.entity.pos.load(); let owner_pos = owner.living_entity.entity.pos.load(); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(mob_pos, owner_pos, self.speed)); } } @@ -200,7 +215,11 @@ impl Goal for FollowOwnerGoal { fn stop<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async { self.owner = None; - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.stop(); }) } diff --git a/crates/pumpkin/src/entity/ai/goal/follow_parent.rs b/crates/pumpkin/src/entity/ai/goal/follow_parent.rs index 670c27030..5886f4ff6 100644 --- a/crates/pumpkin/src/entity/ai/goal/follow_parent.rs +++ b/crates/pumpkin/src/entity/ai/goal/follow_parent.rs @@ -109,7 +109,11 @@ impl Goal for FollowParentGoal { if let Some(parent) = &self.parent { let mob_pos = mob.get_mob_entity().living_entity.entity.pos.load(); let parent_pos = parent.get_entity().pos.load(); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(mob_pos, parent_pos, self.speed)); } }) diff --git a/crates/pumpkin/src/entity/ai/goal/look_around.rs b/crates/pumpkin/src/entity/ai/goal/look_around.rs index 5cb3a850e..25b70d95d 100644 --- a/crates/pumpkin/src/entity/ai/goal/look_around.rs +++ b/crates/pumpkin/src/entity/ai/goal/look_around.rs @@ -45,7 +45,10 @@ impl Goal for RandomLookAroundGoal { Box::pin(async { let mob_entity = mob.get_mob_entity(); self.look_time -= 1; - let mut look_control = mob_entity.look_control.lock().unwrap(); + let mut look_control = mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let pos = mob_entity.living_entity.entity.pos.load(); look_control.look_at( diff --git a/crates/pumpkin/src/entity/ai/goal/look_at_entity.rs b/crates/pumpkin/src/entity/ai/goal/look_at_entity.rs index 79dee52d3..611514ef4 100644 --- a/crates/pumpkin/src/entity/ai/goal/look_at_entity.rs +++ b/crates/pumpkin/src/entity/ai/goal/look_at_entity.rs @@ -151,12 +151,11 @@ impl Goal for LookAtEntityGoal { } else { target_entity.get_eye_y() }; - mob_entity.look_control.lock().unwrap().look_at( - mob, - target_pos.x, - look_y, - target_pos.z, - ); + mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .look_at(mob, target_pos.x, look_y, target_pos.z); self.look_time -= 1; } }) diff --git a/crates/pumpkin/src/entity/ai/goal/melee_attack.rs b/crates/pumpkin/src/entity/ai/goal/melee_attack.rs index 5168d55e3..05da71025 100644 --- a/crates/pumpkin/src/entity/ai/goal/melee_attack.rs +++ b/crates/pumpkin/src/entity/ai/goal/melee_attack.rs @@ -111,7 +111,11 @@ impl Goal for MeleeAttackGoal { let target = mob.get_mob_entity().target.lock().await.clone(); if let Some(target) = target { - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let target_pos = target.get_entity().pos.load(); navigator.set_progress(NavigatorGoal { current_progress: mob.get_entity().pos.load(), @@ -143,7 +147,11 @@ impl Goal for MeleeAttackGoal { } // Vanilla: this.mob.getNavigation().stop() - mob.get_mob_entity().navigator.lock().unwrap().stop(); + mob.get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .stop(); self.last_target_position = None; }) } @@ -158,7 +166,7 @@ impl Goal for MeleeAttackGoal { mob.get_mob_entity() .look_control .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .look_at_entity_with_range(&target, 30.0, 30.0); self.update_countdown_ticks = (self.update_countdown_ticks - 1).max(0); @@ -172,7 +180,11 @@ impl Goal for MeleeAttackGoal { if should_update_nav { let mob_pos = mob.get_entity().pos.load(); let dist_sq = mob_pos.squared_distance_to_vec(¤t_target_pos); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal { current_progress: mob_pos, destination: current_target_pos, diff --git a/crates/pumpkin/src/entity/ai/goal/move_to_target_pos.rs b/crates/pumpkin/src/entity/ai/goal/move_to_target_pos.rs index 64d8fa58d..e26a8e5ce 100644 --- a/crates/pumpkin/src/entity/ai/goal/move_to_target_pos.rs +++ b/crates/pumpkin/src/entity/ai/goal/move_to_target_pos.rs @@ -185,7 +185,11 @@ impl Goal for MoveToTargetPosGoal { self.reached = false; self.trying_time += 1; if self.should_reset_path() { - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal { current_progress: mob.get_entity().pos.load(), diff --git a/crates/pumpkin/src/entity/ai/goal/step_and_destroy_block.rs b/crates/pumpkin/src/entity/ai/goal/step_and_destroy_block.rs index 5dd2e2374..bdb667dd9 100644 --- a/crates/pumpkin/src/entity/ai/goal/step_and_destroy_block.rs +++ b/crates/pumpkin/src/entity/ai/goal/step_and_destroy_block.rs @@ -131,12 +131,12 @@ impl Goal let world = mob.get_entity().world.load_full(); let block_pos = mob.get_entity().block_pos.load(); - let tweak_pos = self.tweak_to_proper_pos(block_pos, &world); - // TODO: drop world? - if !self.move_to_target_pos_goal.reached || tweak_pos.is_none() { + let Some(tweak_pos) = self.tweak_to_proper_pos(block_pos, &world) else { + return; + }; + if !self.move_to_target_pos_goal.reached { return; } - let tweak_pos = tweak_pos.unwrap(); let counter = self.counter; if counter > 0 { diff --git a/crates/pumpkin/src/entity/ai/goal/teleport_towards_player.rs b/crates/pumpkin/src/entity/ai/goal/teleport_towards_player.rs index 96f989535..d01ba1594 100644 --- a/crates/pumpkin/src/entity/ai/goal/teleport_towards_player.rs +++ b/crates/pumpkin/src/entity/ai/goal/teleport_towards_player.rs @@ -98,7 +98,11 @@ impl Goal for TeleportTowardsPlayerGoal { return false; } let player_pos = player.get_entity().pos.load(); - let mut look_control = mob.get_mob_entity().look_control.lock().unwrap(); + let mut look_control = mob + .get_mob_entity() + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.look_at_with_range( player_pos.x, player_pos.y + PLAYER_EYE_HEIGHT, diff --git a/crates/pumpkin/src/entity/ai/goal/tempt.rs b/crates/pumpkin/src/entity/ai/goal/tempt.rs index a733306d4..1b9ac040e 100644 --- a/crates/pumpkin/src/entity/ai/goal/tempt.rs +++ b/crates/pumpkin/src/entity/ai/goal/tempt.rs @@ -92,16 +92,23 @@ impl Goal for TemptGoal { let mob_entity = mob.get_mob_entity(); let player_pos = player.get_entity().pos.load(); - mob_entity.look_control.lock().unwrap().look_at( - mob, - player_pos.x, - player.get_entity().get_eye_y(), - player_pos.z, - ); + mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .look_at( + mob, + player_pos.x, + player.get_entity().get_eye_y(), + player_pos.z, + ); let mob_pos = mob_entity.living_entity.entity.pos.load(); if mob_pos.squared_distance_to_vec(&player_pos) > STOP_DISTANCE * STOP_DISTANCE { - let mut navigator = mob_entity.navigator.lock().unwrap(); + let mut navigator = mob_entity + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(mob_pos, player_pos, self.speed)); } } diff --git a/crates/pumpkin/src/entity/ai/goal/wander_around.rs b/crates/pumpkin/src/entity/ai/goal/wander_around.rs index a9bebabde..f073a12cb 100644 --- a/crates/pumpkin/src/entity/ai/goal/wander_around.rs +++ b/crates/pumpkin/src/entity/ai/goal/wander_around.rs @@ -51,7 +51,11 @@ impl Goal for WanderAroundGoal { fn should_continue<'a>(&'a self, mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async move { - let navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); !navigator.is_idle() }) } @@ -60,7 +64,11 @@ impl Goal for WanderAroundGoal { Box::pin(async move { if let Some(target) = self.target { let pos = mob.get_mob_entity().living_entity.entity.pos.load(); - let mut navigator = mob.get_mob_entity().navigator.lock().unwrap(); + let mut navigator = mob + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_progress(NavigatorGoal::new(pos, target, self.speed)); } }) diff --git a/crates/pumpkin/src/entity/attributes.rs b/crates/pumpkin/src/entity/attributes.rs index 5cf06d970..f9c65798e 100644 --- a/crates/pumpkin/src/entity/attributes.rs +++ b/crates/pumpkin/src/entity/attributes.rs @@ -111,7 +111,12 @@ pub async fn send_attribute_updates_for_living( // Pull modifiers for this attribute let mut modifiers = Vec::new(); - if let Some(inst) = living.attributes.read().unwrap().get(&attribute.id) { + if let Some(inst) = living + .attributes + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get(&attribute.id) + { for mod_inst in &inst.modifiers { modifiers.push(JeAttrMod::new( mod_inst.id.clone(), diff --git a/crates/pumpkin/src/entity/boss/ender_dragon.rs b/crates/pumpkin/src/entity/boss/ender_dragon.rs index 282944dd8..815bfb0ee 100644 --- a/crates/pumpkin/src/entity/boss/ender_dragon.rs +++ b/crates/pumpkin/src/entity/boss/ender_dragon.rs @@ -379,7 +379,7 @@ impl EnderDragonEntity { .iter() .enumerate() .filter_map(|(i, n)| n.map(|n| (i, n.dist_sq_vec(pos)))) - .min_by(|a, b| a.1.partial_cmp(&b.1).unwrap()) + .min_by(|a, b| a.1.total_cmp(&b.1)) .map_or(0, |(i, _)| i) } @@ -544,8 +544,7 @@ impl EnderDragonEntity { let b_pos = b.living_entity.entity.pos.load(); a_pos .distance_squared(pos) - .partial_cmp(&b_pos.distance_squared(pos)) - .unwrap() + .total_cmp(&b_pos.distance_squared(pos)) }) .cloned() } diff --git a/crates/pumpkin/src/entity/boss/wither.rs b/crates/pumpkin/src/entity/boss/wither.rs index 429a5a944..f768771ec 100644 --- a/crates/pumpkin/src/entity/boss/wither.rs +++ b/crates/pumpkin/src/entity/boss/wither.rs @@ -22,7 +22,11 @@ impl WitherEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); // TODO goal_selector.add_goal( diff --git a/crates/pumpkin/src/entity/living.rs b/crates/pumpkin/src/entity/living.rs index e6ef218f9..f91ee007a 100644 --- a/crates/pumpkin/src/entity/living.rs +++ b/crates/pumpkin/src/entity/living.rs @@ -383,7 +383,10 @@ impl LivingEntity { attribute: &Attributes, f: F, ) { - let mut map = self.attributes.write().unwrap(); + let mut map = self + .attributes + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); let inst = map.entry(attribute.id).or_insert_with(|| { let base = self @@ -414,7 +417,10 @@ impl LivingEntity { /// Returns the computed value for `attribute` using the local instance, falling back /// to `attribute.default_value` if no local instance exists. pub fn get_attribute_value(&self, attribute: &Attributes) -> f64 { - let map = self.attributes.read().unwrap(); + let map = self + .attributes + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); map.get(&attribute.id) .map_or(attribute.default_value, AttributeInstance::value) } @@ -422,7 +428,10 @@ impl LivingEntity { /// Returns the base attribute value for `attribute` for this entity's type. pub fn get_attribute_base(&self, attribute: &Attributes) -> f64 { // Check the local base value first (could be modified) - let map = self.attributes.read().unwrap(); + let map = self + .attributes + .read() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(instance) = map.get(&attribute.id) { return instance.base_value; } @@ -433,14 +442,16 @@ impl LivingEntity { .attributes .iter() .find(|a| a.0.id == attribute.id) - .unwrap() - .1 + .map_or(attribute.default_value, |a| a.1) } /// Update or insert the base value for an attribute on this entity. /// If the attribute doesn't exist locally yet, it will be inserted. pub fn set_attribute_base(&self, attribute: &Attributes, new_base: f64) { - let mut map = self.attributes.write().unwrap(); + let mut map = self + .attributes + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(inst) = map.get_mut(&attribute.id) { inst.base_value = new_base; inst.dirty.store(true, Ordering::Relaxed); @@ -1329,9 +1340,9 @@ impl LivingEntity { cause: Option<&dyn EntityBase>, ) { let world = self.entity.world.load(); - let dyn_self = world - .get_entity_by_id(self.entity.entity_id) - .expect("Entity not found in world"); + let Some(dyn_self) = world.get_entity_by_id(self.entity.entity_id) else { + return; + }; if self .dead .compare_exchange(false, true, Relaxed, Relaxed) @@ -1862,10 +1873,9 @@ impl LivingEntity { if let Some(player) = caller.get_player() { return player.inventory.off_hand_item().await; } - let slot = self - .equipment_slots - .get(&PlayerInventory::OFF_HAND_SLOT) - .unwrap(); + let Some(slot) = self.equipment_slots.get(&PlayerInventory::OFF_HAND_SLOT) else { + return ItemStack::EMPTY.clone(); + }; let equipment = self.entity_equipment.lock().await; equipment .equipment @@ -2062,14 +2072,14 @@ impl NBTStorage for LivingEntity { if let Some(nbt_effects) = nbt_effects { for effect in nbt_effects { if let NbtTag::Compound(effect_nbt) = effect { - let effect = Effect::create_from_nbt(&mut effect_nbt.clone()).await; - if effect.is_none() { + if let Some(mut effect) = + Effect::create_from_nbt(&mut effect_nbt.clone()).await + { + effect.blend = true; // TODO: change, is taken from effect give command + active_effects.insert(effect.effect_type, effect); + } else { warn!("Unable to read effect from nbt"); - continue; } - let mut effect = effect.unwrap(); - effect.blend = true; // TODO: change, is taken from effect give command - active_effects.insert(effect.effect_type, effect); } } } @@ -2380,7 +2390,10 @@ impl EntityBase for LivingEntity { self.last_damage_taken.store(amount); let damage_amount = damage_amount.max(0.0); - let config = &world.server.upgrade().unwrap().advanced_config.pvp; + let Some(server) = world.server.upgrade() else { + return false; + }; + let config = &server.advanced_config.pvp; if config.hurt_animation { let entity_id = self.entity.entity_id; diff --git a/crates/pumpkin/src/entity/mob/blaze.rs b/crates/pumpkin/src/entity/mob/blaze.rs index e8e9b71db..365e1eee2 100644 --- a/crates/pumpkin/src/entity/mob/blaze.rs +++ b/crates/pumpkin/src/entity/mob/blaze.rs @@ -25,8 +25,16 @@ impl BlazeEntity { Arc::downgrade(&mob_arc) }; { - let mut goal_selector = mob_arc.entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); diff --git a/crates/pumpkin/src/entity/mob/breeze.rs b/crates/pumpkin/src/entity/mob/breeze.rs index f121d8b1e..14247cdaa 100644 --- a/crates/pumpkin/src/entity/mob/breeze.rs +++ b/crates/pumpkin/src/entity/mob/breeze.rs @@ -26,7 +26,11 @@ impl BreezeEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0))); @@ -36,7 +40,11 @@ impl BreezeEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/creaking.rs b/crates/pumpkin/src/entity/mob/creaking.rs index ec06ab899..008e2597a 100644 --- a/crates/pumpkin/src/entity/mob/creaking.rs +++ b/crates/pumpkin/src/entity/mob/creaking.rs @@ -27,7 +27,11 @@ impl CreakingEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl CreakingEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/creeper.rs b/crates/pumpkin/src/entity/mob/creeper.rs index 470fd1211..aecf00056 100644 --- a/crates/pumpkin/src/entity/mob/creeper.rs +++ b/crates/pumpkin/src/entity/mob/creeper.rs @@ -60,8 +60,16 @@ impl CreeperEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); goal_selector.add_goal(2, Box::new(CreeperIgniteGoal::new(mob_arc.clone()))); diff --git a/crates/pumpkin/src/entity/mob/elder_guardian.rs b/crates/pumpkin/src/entity/mob/elder_guardian.rs index 3693d76c6..5168f5ac3 100644 --- a/crates/pumpkin/src/entity/mob/elder_guardian.rs +++ b/crates/pumpkin/src/entity/mob/elder_guardian.rs @@ -26,7 +26,11 @@ impl ElderGuardianEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(WanderAroundGoal::new(1.0))); @@ -36,7 +40,11 @@ impl ElderGuardianEntity { ); goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/enderman.rs b/crates/pumpkin/src/entity/mob/enderman.rs index 886108e18..9aa75a408 100644 --- a/crates/pumpkin/src/entity/mob/enderman.rs +++ b/crates/pumpkin/src/entity/mob/enderman.rs @@ -80,14 +80,26 @@ impl EndermanEntity { Arc::downgrade(&mob_arc) }; - let mut navigator = mob_arc.mob_entity.navigator.lock().unwrap(); + let mut navigator = mob_arc + .mob_entity + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); navigator.set_mob_dimensions(0.6, 2.9); navigator.set_pathfinding_malus(PathType::Water, -1.0); drop(navigator); { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(ChasePlayerGoal::new(mob_arc.clone()))); @@ -246,7 +258,11 @@ impl EndermanEntity { ), ); - self.mob_entity.navigator.lock().unwrap().stop(); + self.mob_entity + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .stop(); true } diff --git a/crates/pumpkin/src/entity/mob/endermite.rs b/crates/pumpkin/src/entity/mob/endermite.rs index b804b31cb..5fd548595 100644 --- a/crates/pumpkin/src/entity/mob/endermite.rs +++ b/crates/pumpkin/src/entity/mob/endermite.rs @@ -27,7 +27,11 @@ impl EndermiteEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl EndermiteEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/equipment.rs b/crates/pumpkin/src/entity/mob/equipment.rs index 20d702f1a..43a1caa88 100644 --- a/crates/pumpkin/src/entity/mob/equipment.rs +++ b/crates/pumpkin/src/entity/mob/equipment.rs @@ -792,7 +792,10 @@ fn apply_vanilla_enchantments( break; } } - let selected = selected.unwrap_or(candidates.last().copied().unwrap()); + let Some(&fallback) = candidates.last() else { + break; + }; + let selected = selected.unwrap_or(fallback); let level = enchantment_level_from_cost(selected, cost); stack.add_enchantment(selected, level.clamp(1, selected.max_level) as u16); @@ -825,7 +828,7 @@ fn weighted_select_item(items: &[WeaponEntry]) -> &'static Item { return entry.item; } } - items.last().unwrap().item + items.last().map_or(&Item::AIR, |e| e.item) } /// Selects armor using the vanilla algorithm. diff --git a/crates/pumpkin/src/entity/mob/evoker.rs b/crates/pumpkin/src/entity/mob/evoker.rs index 09842c8f0..97932285a 100644 --- a/crates/pumpkin/src/entity/mob/evoker.rs +++ b/crates/pumpkin/src/entity/mob/evoker.rs @@ -26,7 +26,11 @@ impl EvokerEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); // Evokers have complex spell AI, but for now basic movement @@ -37,7 +41,11 @@ impl EvokerEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/ghast.rs b/crates/pumpkin/src/entity/mob/ghast.rs index 2ceb817f7..2ff30afae 100644 --- a/crates/pumpkin/src/entity/mob/ghast.rs +++ b/crates/pumpkin/src/entity/mob/ghast.rs @@ -29,7 +29,11 @@ impl GhastEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(7, Box::new(GhastLookGoal::new(mob_weak.clone()))); }; @@ -94,7 +98,10 @@ impl Goal for GhastLookGoal { let target_pos = target.get_entity().pos.load(); if mob_pos.squared_distance_to_vec(&target_pos) < 4096.0 { - let mut look_control = mob_entity.look_control.lock().unwrap(); + let mut look_control = mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.look_at(mob, target_pos.x, target_pos.y, target_pos.z); } } else { diff --git a/crates/pumpkin/src/entity/mob/giant.rs b/crates/pumpkin/src/entity/mob/giant.rs index 0776b5d16..b0117efd0 100644 --- a/crates/pumpkin/src/entity/mob/giant.rs +++ b/crates/pumpkin/src/entity/mob/giant.rs @@ -22,14 +22,22 @@ impl GiantEntity { let mob_arc = Arc::new(giant); { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true))); goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0))); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/guardian.rs b/crates/pumpkin/src/entity/mob/guardian.rs index 3a67ecd3b..06447feec 100644 --- a/crates/pumpkin/src/entity/mob/guardian.rs +++ b/crates/pumpkin/src/entity/mob/guardian.rs @@ -26,7 +26,11 @@ impl GuardianEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(WanderAroundGoal::new(1.0))); @@ -36,7 +40,11 @@ impl GuardianEntity { ); goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/hoglin.rs b/crates/pumpkin/src/entity/mob/hoglin.rs index 32138ada1..32f29e784 100644 --- a/crates/pumpkin/src/entity/mob/hoglin.rs +++ b/crates/pumpkin/src/entity/mob/hoglin.rs @@ -27,7 +27,11 @@ impl HoglinEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl HoglinEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/illusioner.rs b/crates/pumpkin/src/entity/mob/illusioner.rs index 9e9f7d22c..ac197a368 100644 --- a/crates/pumpkin/src/entity/mob/illusioner.rs +++ b/crates/pumpkin/src/entity/mob/illusioner.rs @@ -26,7 +26,11 @@ impl IllusionerEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0))); @@ -36,7 +40,11 @@ impl IllusionerEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/mod.rs b/crates/pumpkin/src/entity/mob/mod.rs index 97281ce12..137870be8 100644 --- a/crates/pumpkin/src/entity/mob/mod.rs +++ b/crates/pumpkin/src/entity/mob/mod.rs @@ -168,12 +168,20 @@ impl MobEntity { } pub async fn clear_ai_goals(&self, mob: &dyn Mob) { - let running_goals = self.goals_selector.lock().unwrap().clear(); + let running_goals = self + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .clear(); for mut goal in running_goals { goal.goal.stop(mob).await; } - let running_target_goals = self.target_selector.lock().unwrap().clear(); + let running_target_goals = self + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .clear(); for mut goal in running_target_goals { goal.goal.stop(mob).await; } @@ -182,7 +190,7 @@ impl MobEntity { pub fn add_goal(&self, priority: u8, goal: G) { self.goals_selector .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .add_goal(priority, Box::new(goal)); } @@ -193,7 +201,7 @@ impl MobEntity { ) { self.target_selector .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .add_goal(priority, Box::new(goal)); } @@ -629,6 +637,7 @@ impl EntityBase for T { self.mob_set_variant_name(name); } + #[allow(clippy::too_many_lines)] fn tick<'a>( &'a self, caller: &'a Arc, @@ -666,11 +675,17 @@ impl EntityBase for T { // 1. "Take" selectors out of the mutexes let mut target_selector = { - let mut guard = mob_entity.target_selector.lock().unwrap(); + let mut guard = mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); std::mem::take(&mut *guard) }; let mut goals_selector = { - let mut guard = mob_entity.goals_selector.lock().unwrap(); + let mut guard = mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); std::mem::take(&mut *guard) }; @@ -685,30 +700,48 @@ impl EntityBase for T { // 3. "Put back" selectors { - *mob_entity.target_selector.lock().unwrap() = target_selector; - *mob_entity.goals_selector.lock().unwrap() = goals_selector; + *mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = target_selector; + *mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = goals_selector; }; // 4. Repeat for Navigator let mut navigator = { - let mut guard = mob_entity.navigator.lock().unwrap(); + let mut guard = mob_entity + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); std::mem::take(&mut *guard) }; navigator.tick(&mob_entity.living_entity).await; { - *mob_entity.navigator.lock().unwrap() = navigator; + *mob_entity + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = navigator; }; // Controllers are synchronous, so we can just use normal blocks { - let mut look_control = mob_entity.look_control.lock().unwrap(); + let mut look_control = mob_entity + .look_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); look_control.tick(self); }; { - let mut move_control = mob_entity.move_control.lock().unwrap(); + let mut move_control = mob_entity + .move_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); move_control.tick(self); }; @@ -892,7 +925,11 @@ pub trait PathAwareEntity: Mob + Send + Sync { fn is_navigation<'a>(&'a self) -> Pin + Send + 'a>> { Box::pin(async { - let navigator = self.get_mob_entity().navigator.lock().unwrap(); + let navigator = self + .get_mob_entity() + .navigator + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); !navigator.is_idle() }) } diff --git a/crates/pumpkin/src/entity/mob/phantom.rs b/crates/pumpkin/src/entity/mob/phantom.rs index 5e72f510c..2d7030891 100644 --- a/crates/pumpkin/src/entity/mob/phantom.rs +++ b/crates/pumpkin/src/entity/mob/phantom.rs @@ -23,7 +23,11 @@ impl PhantomEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); // TODO: PhantomCircleAroundAnchorGoal, PhantomSweepAttackGoal goal_selector.add_goal( diff --git a/crates/pumpkin/src/entity/mob/piglin.rs b/crates/pumpkin/src/entity/mob/piglin.rs index a0dc14b6f..2fdf563a3 100644 --- a/crates/pumpkin/src/entity/mob/piglin.rs +++ b/crates/pumpkin/src/entity/mob/piglin.rs @@ -27,7 +27,11 @@ impl PiglinEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); // Piglins use crossbows or swords, but for now we give them melee @@ -39,7 +43,11 @@ impl PiglinEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/piglin_brute.rs b/crates/pumpkin/src/entity/mob/piglin_brute.rs index 2a7f291e8..cd6c61b92 100644 --- a/crates/pumpkin/src/entity/mob/piglin_brute.rs +++ b/crates/pumpkin/src/entity/mob/piglin_brute.rs @@ -27,7 +27,11 @@ impl PiglinBruteEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl PiglinBruteEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/pillager.rs b/crates/pumpkin/src/entity/mob/pillager.rs index 8c3b9dce6..b168388e6 100644 --- a/crates/pumpkin/src/entity/mob/pillager.rs +++ b/crates/pumpkin/src/entity/mob/pillager.rs @@ -27,7 +27,11 @@ impl PillagerEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); // Pillagers use crossbows, but for now we give them melee @@ -39,7 +43,11 @@ impl PillagerEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/ravager.rs b/crates/pumpkin/src/entity/mob/ravager.rs index aa075095f..0fe8f7b16 100644 --- a/crates/pumpkin/src/entity/mob/ravager.rs +++ b/crates/pumpkin/src/entity/mob/ravager.rs @@ -27,7 +27,11 @@ impl RavagerEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl RavagerEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/shulker.rs b/crates/pumpkin/src/entity/mob/shulker.rs index 32f8f235b..ef3483482 100644 --- a/crates/pumpkin/src/entity/mob/shulker.rs +++ b/crates/pumpkin/src/entity/mob/shulker.rs @@ -81,8 +81,16 @@ impl ShulkerEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal( 1, diff --git a/crates/pumpkin/src/entity/mob/silverfish.rs b/crates/pumpkin/src/entity/mob/silverfish.rs index 198afbbf7..5fee12d7f 100644 --- a/crates/pumpkin/src/entity/mob/silverfish.rs +++ b/crates/pumpkin/src/entity/mob/silverfish.rs @@ -27,8 +27,16 @@ impl SilverfishEntity { }; { - let mut goal_selector = mob_arc.entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, false))); diff --git a/crates/pumpkin/src/entity/mob/skeleton/mod.rs b/crates/pumpkin/src/entity/mob/skeleton/mod.rs index 249c420a8..afac382b2 100644 --- a/crates/pumpkin/src/entity/mob/skeleton/mod.rs +++ b/crates/pumpkin/src/entity/mob/skeleton/mod.rs @@ -34,8 +34,16 @@ impl SkeletonEntityBase { Arc::downgrade(&mob_arc) }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.2, false))); diff --git a/crates/pumpkin/src/entity/mob/slime.rs b/crates/pumpkin/src/entity/mob/slime.rs index f7db7e144..6ef6f9db9 100644 --- a/crates/pumpkin/src/entity/mob/slime.rs +++ b/crates/pumpkin/src/entity/mob/slime.rs @@ -52,11 +52,23 @@ impl SlimeEntity { let mob_arc = Arc::new(slime); { - let mut move_control = mob_arc.entity.move_control.lock().unwrap(); + let mut move_control = mob_arc + .entity + .move_control + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); *move_control = Box::new(SlimeMoveControl::new(Arc::downgrade(&mob_arc))); - let mut goal_selector = mob_arc.entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SlimeFloatGoal::new(mob_arc.clone()))); goal_selector.add_goal(2, Box::new(SlimeAttackGoal::new(mob_arc.clone()))); @@ -94,7 +106,12 @@ impl SlimeEntity { // Update attributes { - let mut attributes = self.entity.living_entity.attributes.write().unwrap(); + let mut attributes = self + .entity + .living_entity + .attributes + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(health) = attributes.get_mut(&Attributes::MAX_HEALTH.id) { health.base_value = (actual_size * actual_size) as f64; health.dirty.store(true, Ordering::Relaxed); diff --git a/crates/pumpkin/src/entity/mob/spider.rs b/crates/pumpkin/src/entity/mob/spider.rs index d59dc6d46..1ce1da83f 100644 --- a/crates/pumpkin/src/entity/mob/spider.rs +++ b/crates/pumpkin/src/entity/mob/spider.rs @@ -27,8 +27,16 @@ impl SpiderEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); // TODO: SpiderAttackGoal for jumping diff --git a/crates/pumpkin/src/entity/mob/vex.rs b/crates/pumpkin/src/entity/mob/vex.rs index 14b4c0034..d39c44296 100644 --- a/crates/pumpkin/src/entity/mob/vex.rs +++ b/crates/pumpkin/src/entity/mob/vex.rs @@ -27,7 +27,11 @@ impl VexEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl VexEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/vindicator.rs b/crates/pumpkin/src/entity/mob/vindicator.rs index 1ad14c0d4..14bd46b7c 100644 --- a/crates/pumpkin/src/entity/mob/vindicator.rs +++ b/crates/pumpkin/src/entity/mob/vindicator.rs @@ -27,7 +27,11 @@ impl VindicatorEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl VindicatorEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/warden.rs b/crates/pumpkin/src/entity/mob/warden.rs index 649055149..58cecbbb6 100644 --- a/crates/pumpkin/src/entity/mob/warden.rs +++ b/crates/pumpkin/src/entity/mob/warden.rs @@ -27,7 +27,11 @@ impl WardenEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl WardenEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/witch.rs b/crates/pumpkin/src/entity/mob/witch.rs index 4c378716c..3111f22b9 100644 --- a/crates/pumpkin/src/entity/mob/witch.rs +++ b/crates/pumpkin/src/entity/mob/witch.rs @@ -27,8 +27,16 @@ impl WitchEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); // TODO: WitchAttackGoal (potions) diff --git a/crates/pumpkin/src/entity/mob/zoglin.rs b/crates/pumpkin/src/entity/mob/zoglin.rs index fc636880f..00f8e720c 100644 --- a/crates/pumpkin/src/entity/mob/zoglin.rs +++ b/crates/pumpkin/src/entity/mob/zoglin.rs @@ -27,7 +27,11 @@ impl ZoglinEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -38,7 +42,11 @@ impl ZoglinEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); target_selector.add_goal( 1, ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true), diff --git a/crates/pumpkin/src/entity/mob/zombie/drowned.rs b/crates/pumpkin/src/entity/mob/zombie/drowned.rs index d5a7c3c77..6f3ee92ef 100644 --- a/crates/pumpkin/src/entity/mob/zombie/drowned.rs +++ b/crates/pumpkin/src/entity/mob/zombie/drowned.rs @@ -17,7 +17,7 @@ impl DrownedEntity { let mob_arc = Arc::new(zombie); // Fix duplicated since already in ZombieEntity::new() { - //let mut target_selector = mob_arc.entity.mob_entity.target_selector.lock().unwrap(); + //let mut target_selector = mob_arc.entity.mob_entity.target_selector.lock().unwrap_or_else(std::sync::PoisonError::into_inner); // TODO // target_selector.add_goal( diff --git a/crates/pumpkin/src/entity/mob/zombie/mod.rs b/crates/pumpkin/src/entity/mob/zombie/mod.rs index 5dbffe9c8..3c8eecc09 100644 --- a/crates/pumpkin/src/entity/mob/zombie/mod.rs +++ b/crates/pumpkin/src/entity/mob/zombie/mod.rs @@ -34,8 +34,16 @@ impl ZombieEntityBase { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(2, ZombieAttackGoal::new(1.0, false)); diff --git a/crates/pumpkin/src/entity/mob/zombified_piglin.rs b/crates/pumpkin/src/entity/mob/zombified_piglin.rs index 79ebc0763..87decfb63 100644 --- a/crates/pumpkin/src/entity/mob/zombified_piglin.rs +++ b/crates/pumpkin/src/entity/mob/zombified_piglin.rs @@ -26,7 +26,11 @@ impl ZombifiedPiglinEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true))); @@ -37,7 +41,11 @@ impl ZombifiedPiglinEntity { ); goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default())); - let _target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let _target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); // Zombified piglins are neutral by default (only attack if hit), // but for now we give it ActiveTargetGoal for players to make them hostile // (or we can leave it empty for neutral behavior). diff --git a/crates/pumpkin/src/entity/mod.rs b/crates/pumpkin/src/entity/mod.rs index 2e35375c6..2e48b5945 100644 --- a/crates/pumpkin/src/entity/mod.rs +++ b/crates/pumpkin/src/entity/mod.rs @@ -1329,37 +1329,42 @@ impl Entity { if movement.get_axis(Axis::Y) != 0.0 { let mut max_time = 1.0; let mut positions = block_positions.into_iter(); - let (mut collisions_len, mut position) = positions.next().unwrap(); - let mut supporting_block_pos = None; + if let Some((mut collisions_len, mut position)) = positions.next() { + let mut supporting_block_pos = None; - for (i, inert_box) in collisions.iter().enumerate() { - if i == collisions_len { - (collisions_len, position) = positions.next().unwrap(); - } + for (i, inert_box) in collisions.iter().enumerate() { + if i == collisions_len { + let Some((next_len, next_pos)) = positions.next() else { + break; + }; + collisions_len = next_len; + position = next_pos; + } - if let Some(collision_time) = bounding_box.calculate_collision_time( - inert_box, - adjusted_movement, - Axis::Y, - max_time, - ) { - max_time = collision_time; + if let Some(collision_time) = bounding_box.calculate_collision_time( + inert_box, + adjusted_movement, + Axis::Y, + max_time, + ) { + max_time = collision_time; - // If the entity is moving downwards and collides, set the supporting block position - if movement.get_axis(Axis::Y) < 0.0 { - supporting_block_pos = Some(position); + // If the entity is moving downwards and collides, set the supporting block position + if movement.get_axis(Axis::Y) < 0.0 { + supporting_block_pos = Some(position); + } } } - } - if max_time != 1.0 { - let changed_component = adjusted_movement.get_axis(Axis::Y) * max_time; - adjusted_movement.set_axis(Axis::Y, changed_component); - } + if max_time != 1.0 { + let changed_component = adjusted_movement.get_axis(Axis::Y) * max_time; + adjusted_movement.set_axis(Axis::Y, changed_component); + } - self.on_ground - .store(supporting_block_pos.is_some(), Ordering::SeqCst); - self.supporting_block_pos.store(supporting_block_pos); + self.on_ground + .store(supporting_block_pos.is_some(), Ordering::SeqCst); + self.supporting_block_pos.store(supporting_block_pos); + } } let mut horizontal_collision = false; @@ -2354,20 +2359,12 @@ impl Entity { return; } - if (portal_world.dimension == Dimension::THE_NETHER - && !portal_world - .server - .upgrade() - .unwrap() - .basic_config - .allow_nether) - || (portal_world.dimension == Dimension::THE_END - && !portal_world - .server - .upgrade() - .unwrap() - .basic_config - .allow_end) + let Some(server) = portal_world.server.upgrade() else { + return; + }; + + if (portal_world.dimension == Dimension::THE_NETHER && !server.basic_config.allow_nether) + || (portal_world.dimension == Dimension::THE_END && !server.basic_config.allow_end) { return; } @@ -2849,7 +2846,7 @@ impl Entity { if is_within_view_distance(chunk_pos, center, view_distance) { let mut buf = Vec::new(); for m in meta { - m.write(&mut buf, &client.version.load()).unwrap(); + let _ = m.write(&mut buf, &client.version.load()); } buf.put_u8(255); player.client.try_enqueue_packet(&CSetEntityMetadata::new( @@ -3422,31 +3419,33 @@ impl Entity { }; if let Some(player) = passenger.get_player() { - let id = teleport_id.unwrap(); - player.get_entity().set_pos(dismount_pos); - // Update awaiting_teleport with the real dismount position - *player.awaiting_teleport.lock().await = Some((id.into(), dismount_pos)); - // Use enqueue_packet (not send_packet_now) so the teleport goes through - // the same packet queue as CSetPassengers, preserving send order. - // Vanilla uses DELTA | ROT flags: position absolute, delta/rotation relative. - // With rotation relative and yaw/pitch=0, the client preserves its current look. - player - .client - .enqueue_packet(&CPlayerPosition::new( - id.into(), - dismount_pos, - Vector3::new(0.0, 0.0, 0.0), - 0.0, - 0.0, - vec![ - PositionFlag::DeltaX, - PositionFlag::DeltaY, - PositionFlag::DeltaZ, - PositionFlag::YRot, - PositionFlag::XRot, - ], - )) - .await; + if let Some(id) = teleport_id { + player.get_entity().set_pos(dismount_pos); + // Update awaiting_teleport with the real dismount position + *player.awaiting_teleport.lock().await = Some((id.into(), dismount_pos)); + // Use enqueue_packet (not send_packet_now) so the teleport goes through + // the same packet queue as CSetPassengers, preserving send order. + // Vanilla uses DELTA | ROT flags: position absolute, delta/rotation relative. + // With rotation relative and yaw/pitch=0, the client preserves its current look. + player + .client + .enqueue_packet(&CPlayerPosition::new( + id.into(), + dismount_pos, + Vector3::new(0.0, 0.0, 0.0), + 0.0, + 0.0, + vec![ + PositionFlag::DeltaX, + PositionFlag::DeltaY, + PositionFlag::DeltaZ, + PositionFlag::YRot, + PositionFlag::XRot, + ], + )) + .await; + } + // Vanilla: setSneaking(false) after dismount via sneak input if passenger_entity.sneaking.load(Relaxed) { passenger_entity.set_sneaking(false).await; diff --git a/crates/pumpkin/src/entity/passive/allay.rs b/crates/pumpkin/src/entity/passive/allay.rs index 3ab4d0d5e..817fc3bde 100644 --- a/crates/pumpkin/src/entity/passive/allay.rs +++ b/crates/pumpkin/src/entity/passive/allay.rs @@ -29,7 +29,11 @@ impl AllayEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/armadillo.rs b/crates/pumpkin/src/entity/passive/armadillo.rs index 6e8a624e2..72e1451bc 100644 --- a/crates/pumpkin/src/entity/passive/armadillo.rs +++ b/crates/pumpkin/src/entity/passive/armadillo.rs @@ -29,7 +29,11 @@ impl ArmadilloEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/axolotl.rs b/crates/pumpkin/src/entity/passive/axolotl.rs index 162faadc5..5b90b9541 100644 --- a/crates/pumpkin/src/entity/passive/axolotl.rs +++ b/crates/pumpkin/src/entity/passive/axolotl.rs @@ -29,7 +29,11 @@ impl AxolotlEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/bee.rs b/crates/pumpkin/src/entity/passive/bee.rs index 733024d2c..e3f8624c4 100644 --- a/crates/pumpkin/src/entity/passive/bee.rs +++ b/crates/pumpkin/src/entity/passive/bee.rs @@ -29,7 +29,11 @@ impl BeeEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/camel.rs b/crates/pumpkin/src/entity/passive/camel.rs index f297a1ea1..ccf08877f 100644 --- a/crates/pumpkin/src/entity/passive/camel.rs +++ b/crates/pumpkin/src/entity/passive/camel.rs @@ -29,7 +29,11 @@ impl CamelEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/cat.rs b/crates/pumpkin/src/entity/passive/cat.rs index c5c850164..b615b7db1 100644 --- a/crates/pumpkin/src/entity/passive/cat.rs +++ b/crates/pumpkin/src/entity/passive/cat.rs @@ -42,7 +42,11 @@ impl CatEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(1.5)); diff --git a/crates/pumpkin/src/entity/passive/chicken.rs b/crates/pumpkin/src/entity/passive/chicken.rs index 5fec5570e..b0b807ed3 100644 --- a/crates/pumpkin/src/entity/passive/chicken.rs +++ b/crates/pumpkin/src/entity/passive/chicken.rs @@ -61,7 +61,11 @@ impl ChickenEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(1.4)); diff --git a/crates/pumpkin/src/entity/passive/cod.rs b/crates/pumpkin/src/entity/passive/cod.rs index 07f732853..8b51eecdb 100644 --- a/crates/pumpkin/src/entity/passive/cod.rs +++ b/crates/pumpkin/src/entity/passive/cod.rs @@ -29,7 +29,11 @@ impl CodEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/cow.rs b/crates/pumpkin/src/entity/passive/cow.rs index 69221d283..8dbdd9b6e 100644 --- a/crates/pumpkin/src/entity/passive/cow.rs +++ b/crates/pumpkin/src/entity/passive/cow.rs @@ -42,7 +42,11 @@ impl CowEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(2.0)); diff --git a/crates/pumpkin/src/entity/passive/dolphin.rs b/crates/pumpkin/src/entity/passive/dolphin.rs index 3a25512c8..a20109b34 100644 --- a/crates/pumpkin/src/entity/passive/dolphin.rs +++ b/crates/pumpkin/src/entity/passive/dolphin.rs @@ -29,7 +29,11 @@ impl DolphinEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/donkey.rs b/crates/pumpkin/src/entity/passive/donkey.rs index fd7693933..c31c6840a 100644 --- a/crates/pumpkin/src/entity/passive/donkey.rs +++ b/crates/pumpkin/src/entity/passive/donkey.rs @@ -29,7 +29,11 @@ impl DonkeyEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/passive/fox.rs b/crates/pumpkin/src/entity/passive/fox.rs index 78bc16f72..75c4fb411 100644 --- a/crates/pumpkin/src/entity/passive/fox.rs +++ b/crates/pumpkin/src/entity/passive/fox.rs @@ -32,7 +32,11 @@ impl FoxEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(1.5)); diff --git a/crates/pumpkin/src/entity/passive/frog.rs b/crates/pumpkin/src/entity/passive/frog.rs index 47dda3bad..c715d71df 100644 --- a/crates/pumpkin/src/entity/passive/frog.rs +++ b/crates/pumpkin/src/entity/passive/frog.rs @@ -41,7 +41,11 @@ impl FrogEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/glow_squid.rs b/crates/pumpkin/src/entity/passive/glow_squid.rs index 6f447dfa8..37fb3ef42 100644 --- a/crates/pumpkin/src/entity/passive/glow_squid.rs +++ b/crates/pumpkin/src/entity/passive/glow_squid.rs @@ -29,7 +29,11 @@ impl GlowSquidEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/goat.rs b/crates/pumpkin/src/entity/passive/goat.rs index d2538717a..b5a19da76 100644 --- a/crates/pumpkin/src/entity/passive/goat.rs +++ b/crates/pumpkin/src/entity/passive/goat.rs @@ -29,7 +29,11 @@ impl GoatEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/horse.rs b/crates/pumpkin/src/entity/passive/horse.rs index 3dd3e0e91..694095b05 100644 --- a/crates/pumpkin/src/entity/passive/horse.rs +++ b/crates/pumpkin/src/entity/passive/horse.rs @@ -29,7 +29,11 @@ impl HorseEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/passive/iron_golem.rs b/crates/pumpkin/src/entity/passive/iron_golem.rs index 22c198e0b..f51f507ab 100644 --- a/crates/pumpkin/src/entity/passive/iron_golem.rs +++ b/crates/pumpkin/src/entity/passive/iron_golem.rs @@ -31,8 +31,16 @@ impl IronGolemEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(MeleeAttackGoal::new(1.0, true))); goal_selector.add_goal(6, Box::new(WanderAroundGoal::new(0.6))); diff --git a/crates/pumpkin/src/entity/passive/llama.rs b/crates/pumpkin/src/entity/passive/llama.rs index df50b4a91..53c7cd36a 100644 --- a/crates/pumpkin/src/entity/passive/llama.rs +++ b/crates/pumpkin/src/entity/passive/llama.rs @@ -29,7 +29,11 @@ impl LlamaEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/passive/mooshroom.rs b/crates/pumpkin/src/entity/passive/mooshroom.rs index ac9030dd1..8a56c6d74 100644 --- a/crates/pumpkin/src/entity/passive/mooshroom.rs +++ b/crates/pumpkin/src/entity/passive/mooshroom.rs @@ -29,7 +29,11 @@ impl MooshroomEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/mule.rs b/crates/pumpkin/src/entity/passive/mule.rs index 81b8d7e0e..108a3d2eb 100644 --- a/crates/pumpkin/src/entity/passive/mule.rs +++ b/crates/pumpkin/src/entity/passive/mule.rs @@ -29,7 +29,11 @@ impl MuleEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/passive/ocelot.rs b/crates/pumpkin/src/entity/passive/ocelot.rs index 701e3e0cb..9839829d3 100644 --- a/crates/pumpkin/src/entity/passive/ocelot.rs +++ b/crates/pumpkin/src/entity/passive/ocelot.rs @@ -29,7 +29,11 @@ impl OcelotEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/panda.rs b/crates/pumpkin/src/entity/passive/panda.rs index bbe2248e1..4d18a93b6 100644 --- a/crates/pumpkin/src/entity/passive/panda.rs +++ b/crates/pumpkin/src/entity/passive/panda.rs @@ -29,7 +29,11 @@ impl PandaEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/parrot.rs b/crates/pumpkin/src/entity/passive/parrot.rs index 10c9e9f99..74870d57f 100644 --- a/crates/pumpkin/src/entity/passive/parrot.rs +++ b/crates/pumpkin/src/entity/passive/parrot.rs @@ -38,7 +38,11 @@ impl ParrotEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/pig.rs b/crates/pumpkin/src/entity/passive/pig.rs index bbb888b5b..45a73804d 100644 --- a/crates/pumpkin/src/entity/passive/pig.rs +++ b/crates/pumpkin/src/entity/passive/pig.rs @@ -47,7 +47,11 @@ impl PigEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(1.25)); diff --git a/crates/pumpkin/src/entity/passive/polar_bear.rs b/crates/pumpkin/src/entity/passive/polar_bear.rs index 684cb8619..cedc97417 100644 --- a/crates/pumpkin/src/entity/passive/polar_bear.rs +++ b/crates/pumpkin/src/entity/passive/polar_bear.rs @@ -29,7 +29,11 @@ impl PolarBearEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); @@ -39,7 +43,11 @@ impl PolarBearEntity { ); goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default())); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); // Polar bears are neutral but aggressive towards foxes target_selector.add_goal( 1, diff --git a/crates/pumpkin/src/entity/passive/pufferfish.rs b/crates/pumpkin/src/entity/passive/pufferfish.rs index 4cfd6c02d..8ae73bce2 100644 --- a/crates/pumpkin/src/entity/passive/pufferfish.rs +++ b/crates/pumpkin/src/entity/passive/pufferfish.rs @@ -29,7 +29,11 @@ impl PufferfishEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/rabbit.rs b/crates/pumpkin/src/entity/passive/rabbit.rs index 9170694d6..d96c2f6c9 100644 --- a/crates/pumpkin/src/entity/passive/rabbit.rs +++ b/crates/pumpkin/src/entity/passive/rabbit.rs @@ -29,7 +29,11 @@ impl RabbitEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(2.2)); diff --git a/crates/pumpkin/src/entity/passive/salmon.rs b/crates/pumpkin/src/entity/passive/salmon.rs index 740b9933d..90f0d8bb5 100644 --- a/crates/pumpkin/src/entity/passive/salmon.rs +++ b/crates/pumpkin/src/entity/passive/salmon.rs @@ -26,7 +26,11 @@ impl SalmonEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/sheep.rs b/crates/pumpkin/src/entity/passive/sheep.rs index d047764b0..296829652 100644 --- a/crates/pumpkin/src/entity/passive/sheep.rs +++ b/crates/pumpkin/src/entity/passive/sheep.rs @@ -45,7 +45,11 @@ impl SheepEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, EscapeDangerGoal::new(1.25)); diff --git a/crates/pumpkin/src/entity/passive/skeleton_horse.rs b/crates/pumpkin/src/entity/passive/skeleton_horse.rs index 656c3451a..9fc23c142 100644 --- a/crates/pumpkin/src/entity/passive/skeleton_horse.rs +++ b/crates/pumpkin/src/entity/passive/skeleton_horse.rs @@ -26,7 +26,11 @@ impl SkeletonHorseEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/passive/sniffer.rs b/crates/pumpkin/src/entity/passive/sniffer.rs index d7cf1ad9b..cd2ead73f 100644 --- a/crates/pumpkin/src/entity/passive/sniffer.rs +++ b/crates/pumpkin/src/entity/passive/sniffer.rs @@ -26,7 +26,11 @@ impl SnifferEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/snow_golem.rs b/crates/pumpkin/src/entity/passive/snow_golem.rs index 7f52ac008..49fc08b60 100644 --- a/crates/pumpkin/src/entity/passive/snow_golem.rs +++ b/crates/pumpkin/src/entity/passive/snow_golem.rs @@ -26,8 +26,16 @@ impl SnowGolemEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); - let mut target_selector = mob_arc.mob_entity.target_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + let mut target_selector = mob_arc + .mob_entity + .target_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); // TODO: SnowballAttackGoal goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/squid.rs b/crates/pumpkin/src/entity/passive/squid.rs index fd45a1e48..590248241 100644 --- a/crates/pumpkin/src/entity/passive/squid.rs +++ b/crates/pumpkin/src/entity/passive/squid.rs @@ -26,7 +26,11 @@ impl SquidEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); // Squids don't have WanderAroundGoal in vanilla (they use custom movement), diff --git a/crates/pumpkin/src/entity/passive/strider.rs b/crates/pumpkin/src/entity/passive/strider.rs index 62ee3cc29..74e9db423 100644 --- a/crates/pumpkin/src/entity/passive/strider.rs +++ b/crates/pumpkin/src/entity/passive/strider.rs @@ -26,7 +26,11 @@ impl StriderEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/tadpole.rs b/crates/pumpkin/src/entity/passive/tadpole.rs index a7e00ed1c..f4e0be6c1 100644 --- a/crates/pumpkin/src/entity/passive/tadpole.rs +++ b/crates/pumpkin/src/entity/passive/tadpole.rs @@ -26,7 +26,11 @@ impl TadpoleEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/trader_llama.rs b/crates/pumpkin/src/entity/passive/trader_llama.rs index 523695571..56713c350 100644 --- a/crates/pumpkin/src/entity/passive/trader_llama.rs +++ b/crates/pumpkin/src/entity/passive/trader_llama.rs @@ -26,7 +26,11 @@ impl TraderLlamaEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/passive/tropical_fish.rs b/crates/pumpkin/src/entity/passive/tropical_fish.rs index cb6398fc3..1d6c3e108 100644 --- a/crates/pumpkin/src/entity/passive/tropical_fish.rs +++ b/crates/pumpkin/src/entity/passive/tropical_fish.rs @@ -26,7 +26,11 @@ impl TropicalFishEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0))); diff --git a/crates/pumpkin/src/entity/passive/turtle.rs b/crates/pumpkin/src/entity/passive/turtle.rs index 13df77549..f018cce6d 100644 --- a/crates/pumpkin/src/entity/passive/turtle.rs +++ b/crates/pumpkin/src/entity/passive/turtle.rs @@ -28,7 +28,11 @@ impl TurtleEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); goal_selector.add_goal(2, BreedGoal::new(1.0)); diff --git a/crates/pumpkin/src/entity/passive/villager/mod.rs b/crates/pumpkin/src/entity/passive/villager/mod.rs index 32e965beb..83fc17e69 100644 --- a/crates/pumpkin/src/entity/passive/villager/mod.rs +++ b/crates/pumpkin/src/entity/passive/villager/mod.rs @@ -58,6 +58,7 @@ pub struct VillagerEntity { } impl VillagerEntity { + #[allow(clippy::too_many_lines)] pub fn new(entity: Entity) -> Arc { let mob_entity = MobEntity::new(entity); let villager_data = VillagerData::new(VillagerType::Plains, VillagerProfession::None, 1); @@ -83,14 +84,21 @@ impl VillagerEntity { self_weak: std::sync::Mutex::new(None), }; let mob_arc = Arc::new(villager); - *mob_arc.self_weak.lock().unwrap() = Some(Arc::downgrade(&mob_arc)); + *mob_arc + .self_weak + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(Arc::downgrade(&mob_arc)); let mob_weak: Weak = { let mob_arc: Arc = mob_arc.clone(); Arc::downgrade(&mob_arc) }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); // Villagers avoid threats @@ -314,7 +322,11 @@ impl ScreenHandlerFactory for VillagerEntity { ) -> BoxFuture<'a, Option> { Box::pin(async move { let offers = self.offers.lock().await; - let self_weak = self.self_weak.lock().unwrap().clone().unwrap(); + let self_weak = self + .self_weak + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .clone()?; let player_uuid = player .as_any() .downcast_ref::() @@ -429,14 +441,20 @@ impl NBTStorage for VillagerEntity { ); nbt.put_int("RestocksToday", self.restocks_today.load(Ordering::Relaxed)); - let job_site_pos = *self.job_site.lock().unwrap(); + let job_site_pos = *self + .job_site + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(pos) = job_site_pos { nbt.put_int("JobSiteX", pos.0.x); nbt.put_int("JobSiteY", pos.0.y); nbt.put_int("JobSiteZ", pos.0.z); } - let home_pos = *self.home_pos.lock().unwrap(); + let home_pos = *self + .home_pos + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); if let Some(pos) = home_pos { nbt.put_int("HomeX", pos.0.x); nbt.put_int("HomeY", pos.0.y); @@ -558,9 +576,16 @@ impl NBTStorage for VillagerEntity { nbt.get_int("JobSiteY"), nbt.get_int("JobSiteZ"), ) { - *self.job_site.lock().unwrap() = Some(BlockPos::new(x, y, z)); + *self + .job_site + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = + Some(BlockPos::new(x, y, z)); } else { - *self.job_site.lock().unwrap() = None; + *self + .job_site + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = None; } if let (Some(x), Some(y), Some(z)) = ( @@ -568,9 +593,16 @@ impl NBTStorage for VillagerEntity { nbt.get_int("HomeY").or_else(|| nbt.get_int("BedY")), nbt.get_int("HomeZ").or_else(|| nbt.get_int("BedZ")), ) { - *self.home_pos.lock().unwrap() = Some(BlockPos::new(x, y, z)); + *self + .home_pos + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = + Some(BlockPos::new(x, y, z)); } else { - *self.home_pos.lock().unwrap() = None; + *self + .home_pos + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = None; } if let Some(offers_compound) = nbt.get_compound("Offers") @@ -732,11 +764,17 @@ impl Mob for VillagerEntity { } fn get_job_site(&self) -> Option { - *self.job_site.lock().unwrap() + *self + .job_site + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) } fn get_home(&self) -> Option { - *self.home_pos.lock().unwrap() + *self + .home_pos + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) } #[expect(clippy::too_many_lines)] @@ -766,7 +804,10 @@ impl Mob for VillagerEntity { }; if !valid { - *self.home_pos.lock().unwrap() = None; + *self + .home_pos + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = None; if is_sleeping { // Wake up if bed was broken self.get_entity().set_pose(EntityPose::Standing); @@ -841,7 +882,10 @@ impl Mob for VillagerEntity { } if let Some(home) = best_home { - *self.home_pos.lock().unwrap() = Some(home); + *self + .home_pos + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(home); } } @@ -924,7 +968,10 @@ impl Mob for VillagerEntity { }; if !valid { - *self.job_site.lock().unwrap() = None; + *self + .job_site + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = None; if xp == 0 && profession != VillagerProfession::None { let r#type = self.villager_data.lock().await.type_enum(); self.set_villager_data(VillagerData::new( @@ -995,7 +1042,10 @@ impl Mob for VillagerEntity { } if let Some(site) = best_site { - *self.job_site.lock().unwrap() = Some(site); + *self + .job_site + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(site); if profession == VillagerProfession::None { let r#type = self.villager_data.lock().await.type_enum(); self.set_villager_data(VillagerData::new(r#type, best_profession, 1)) diff --git a/crates/pumpkin/src/entity/passive/wandering_trader.rs b/crates/pumpkin/src/entity/passive/wandering_trader.rs index 9264b1675..3353fa35f 100644 --- a/crates/pumpkin/src/entity/passive/wandering_trader.rs +++ b/crates/pumpkin/src/entity/passive/wandering_trader.rs @@ -26,7 +26,11 @@ impl WanderingTraderEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.6))); diff --git a/crates/pumpkin/src/entity/passive/wolf.rs b/crates/pumpkin/src/entity/passive/wolf.rs index e8016dab6..5c481007f 100644 --- a/crates/pumpkin/src/entity/passive/wolf.rs +++ b/crates/pumpkin/src/entity/passive/wolf.rs @@ -40,7 +40,11 @@ impl WolfEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(1, Box::new(SwimGoal::default())); // goal_selector.add_goal(2, SitGoal::new(mob_arc.clone())); diff --git a/crates/pumpkin/src/entity/passive/zombie_horse.rs b/crates/pumpkin/src/entity/passive/zombie_horse.rs index c72a65e6d..e2560a410 100644 --- a/crates/pumpkin/src/entity/passive/zombie_horse.rs +++ b/crates/pumpkin/src/entity/passive/zombie_horse.rs @@ -26,7 +26,11 @@ impl ZombieHorseEntity { }; { - let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().unwrap(); + let mut goal_selector = mob_arc + .mob_entity + .goals_selector + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); goal_selector.add_goal(0, Box::new(SwimGoal::default())); goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7))); diff --git a/crates/pumpkin/src/entity/player.rs b/crates/pumpkin/src/entity/player.rs index 1b3610385..6e085c792 100644 --- a/crates/pumpkin/src/entity/player.rs +++ b/crates/pumpkin/src/entity/player.rs @@ -249,7 +249,10 @@ impl ChunkManager { let old_view_distance = self.view_distance; { - let mut lock = level.chunk_loading.lock().unwrap(); + let mut lock = level + .chunk_loading + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let new_level = ChunkLoading::get_level_from_view_distance(view_distance); lock.add_ticket(center, new_level); @@ -308,7 +311,10 @@ impl ChunkManager { } pub fn clean_up(&mut self, level: &Arc) { - let mut lock = level.chunk_loading.lock().unwrap(); + let mut lock = level + .chunk_loading + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); lock.remove_ticket( self.center, ChunkLoading::get_level_from_view_distance(self.view_distance), @@ -327,7 +333,10 @@ impl ChunkManager { } pub fn change_world(&mut self, old_level: &Arc, new_world: Arc) { - let mut lock = old_level.chunk_loading.lock().unwrap(); + let mut lock = old_level + .chunk_loading + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); lock.remove_ticket( self.center, ChunkLoading::get_level_from_view_distance(self.view_distance), @@ -622,7 +631,10 @@ impl Player { impl ScreenHandlerListener for ScreenListener {} - let server = world.server.upgrade().unwrap(); + let server = world.server.upgrade().unwrap_or_else(|| { + tracing::error!("server inactive"); + std::process::exit(1); + }); let player_uuid = gameprofile.id; @@ -645,13 +657,8 @@ impl Player { let ender_chest_inventory = Arc::new(EnderChestInventory::new()); let player_screen_handler = Arc::new(Mutex::new( - PlayerScreenHandler::new( - &inventory, - None, - 0, - Some(world.server.upgrade().unwrap().recipe_manager.clone()), - ) - .await, + PlayerScreenHandler::new(&inventory, None, 0, Some(server.recipe_manager.clone())) + .await, )); // Initialize abilities based on gamemode (like vanilla's GameMode.setAbilities()) @@ -707,7 +714,7 @@ impl Player { watched_section: AtomicCell::new(Cylindrical::new( Vector2::new(0, 0), // Since 1 is not possible in vanilla it is used as uninit - NonZeroU8::new(1).unwrap(), + NonZeroU8::new(1).unwrap_or(NonZeroU8::MIN), )), last_action_time: AtomicCell::new(std::time::Instant::now()), ping: AtomicU32::new(0), @@ -966,7 +973,9 @@ impl Player { #[expect(clippy::too_many_lines)] pub async fn attack(&self, victim: Arc) { let world = self.world(); - let server = world.server.upgrade().unwrap(); + let Some(server) = world.server.upgrade() else { + return; + }; let victim_entity = victim.get_entity(); let attacker_entity = &self.living_entity.entity; let config = &server.advanced_config.pvp; @@ -2674,7 +2683,7 @@ impl Player { self.watched_section.store(Cylindrical::new( Vector2::new(0, 0), - NonZeroU8::new(1).unwrap(), + NonZeroU8::new(1).unwrap_or(NonZeroU8::MIN), )); } @@ -2690,7 +2699,9 @@ impl Player { let yaw = yaw.unwrap_or(new_world.level_info.load().spawn_yaw); let pitch = pitch.unwrap_or(new_world.level_info.load().spawn_pitch); - let server = new_world.server.upgrade().unwrap(); + let Some(server) = new_world.server.upgrade() else { + return; + }; send_cancellable! {{ server; @@ -2712,7 +2723,9 @@ impl Player { let new_world = event.new_world; self.set_client_loaded(false); - let player = current_world.remove_player(self, false).await.unwrap(); + let Some(player) = current_world.remove_player(self, false).await else { + return; + }; new_world.players.rcu(|current_list| { let mut new_list = (**current_list).clone(); new_list.push(player.clone()); @@ -2804,7 +2817,9 @@ impl Player { // This is the ultra special magic code used to create the teleport id // This returns the old value // This operation wraps around on overflow. - let server = self.world().server.upgrade().unwrap(); + let Some(server) = self.world().server.upgrade() else { + return; + }; send_cancellable! {{ server; PlayerTeleportEvent { @@ -3165,7 +3180,9 @@ impl Player { if self.gamemode.load() == gamemode { return false; } - let server = self.world().server.upgrade().unwrap(); + let Some(server) = self.world().server.upgrade() else { + return false; + }; send_cancellable! {{ server; PlayerGamemodeChangeEvent { @@ -3992,9 +4009,7 @@ impl Player { { let screen_handler_temp = screen_handler.lock().await; let sync_id = screen_handler_temp.sync_id(); - let window_type = screen_handler_temp - .window_type() - .expect("Can't open PlayerScreenHandler"); + let window_type = screen_handler_temp.window_type()?; let display_name = screen_handler_factory.get_display_name(); let java_packet = @@ -4060,9 +4075,9 @@ impl Player { let screen_handler_temp = screen_handler.lock().await; let sync_id = screen_handler_temp.sync_id(); - let window_type = screen_handler_temp - .window_type() - .expect("Can't open PlayerScreenHandler"); + let Some(window_type) = screen_handler_temp.window_type() else { + return; + }; let java_packet = COpenScreen::new(sync_id.into(), (window_type as i32).into(), &title); @@ -4917,7 +4932,9 @@ impl EntityBase for Player { // Same world let yaw = yaw.unwrap_or(self.living_entity.entity.yaw.load()); let pitch = pitch.unwrap_or(self.living_entity.entity.pitch.load()); - let server = self.world().server.upgrade().unwrap(); + let Some(server) = self.world().server.upgrade() else { + return; + }; send_cancellable! {{ server; PlayerTeleportEvent { diff --git a/crates/pumpkin/src/entity/player/advancement.rs b/crates/pumpkin/src/entity/player/advancement.rs index ea245d6b6..9aec6686f 100644 --- a/crates/pumpkin/src/entity/player/advancement.rs +++ b/crates/pumpkin/src/entity/player/advancement.rs @@ -18,7 +18,6 @@ use serde_json::to_string_pretty; use std::collections::{HashMap, HashSet}; use std::fs::{create_dir_all, read, write}; use std::path::PathBuf; -use std::str::from_utf8; use std::sync::{Arc, Weak}; use std::time::{SystemTime, UNIX_EPOCH}; use tokio::task::spawn_blocking; @@ -271,14 +270,17 @@ impl PlayerAdvancement { let json = to_string_pretty(self).map_err(AdvancementDataError::Json)?; let path = self.path.clone(); spawn_blocking(move || { - if let Err(e) = create_dir_all(path.parent().unwrap()) { + let Some(parent) = path.parent() else { + return Ok(()); + }; + if let Err(e) = create_dir_all(parent) { error!("Failed to create player advancement directory : {e}"); return Err(AdvancementDataError::Io(e)); } write(path, json).map_err(AdvancementDataError::Io) }) .await - .expect("spawn_blocking task panicked") + .unwrap_or(Ok(())) } /// Loads the player's advancement progress from disk. @@ -290,10 +292,12 @@ impl PlayerAdvancement { let path = self.path.clone(); let json = spawn_blocking(|| read(path).map_err(AdvancementDataError::Io)) .await - .expect("spawn_blocking task panicked")?; + .unwrap_or(Err(AdvancementDataError::Io(std::io::Error::from( + std::io::ErrorKind::Other, + ))))?; let loaded_data: HashMap = - serde_json::from_str(from_utf8(&json).unwrap()).map_err(AdvancementDataError::Json)?; + serde_json::from_slice(&json).map_err(AdvancementDataError::Json)?; self.progress.clear(); for (advancement_id, mut progress) in loaded_data { @@ -377,7 +381,8 @@ impl PlayerAdvancement { .map(|(key, val)| Criteria { criterion_id: key.clone(), achieve_date: val.0.map(|time| { - time.duration_since(UNIX_EPOCH).unwrap().as_millis() as i64 + time.duration_since(UNIX_EPOCH) + .map_or(0, |d| d.as_millis() as i64) }), }) .collect(), @@ -415,7 +420,9 @@ impl PlayerAdvancement { pub fn award(&mut self, advancement: &'static Advancement, criterion: &str) -> bool { //TODO call and creates Events for plugins let mut result = false; - let player = self.player.upgrade().unwrap(); + let Some(player) = self.player.upgrade() else { + return false; + }; let progress = self.progress.get_mut_or_start_progress(advancement); let was_done = progress.is_done(); if progress.grant_progress(criterion) { diff --git a/crates/pumpkin/src/entity/projectile/arrow.rs b/crates/pumpkin/src/entity/projectile/arrow.rs index 0f9fbf8ed..336c65b4d 100644 --- a/crates/pumpkin/src/entity/projectile/arrow.rs +++ b/crates/pumpkin/src/entity/projectile/arrow.rs @@ -440,6 +440,7 @@ impl EntityBase for ArrowEntity { }) } + #[allow(clippy::too_many_lines)] fn on_hit(&self, hit: ProjectileHit) -> EntityBaseFuture<'_, ()> { Box::pin(async move { let entity = self.get_entity(); @@ -455,7 +456,10 @@ impl EntityBase for ArrowEntity { // Arrow hit a block - stick into it self.in_ground.store(true, Ordering::Relaxed); self.shake_time.store(7, Ordering::Relaxed); - *self.last_block_pos.write().unwrap() = Some(pos); + *self + .last_block_pos + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(pos); let block = world.get_block(&pos); if block == &pumpkin_data::Block::TARGET { diff --git a/crates/pumpkin/src/entity/projectile/trident.rs b/crates/pumpkin/src/entity/projectile/trident.rs index 32271395c..eb0719e37 100644 --- a/crates/pumpkin/src/entity/projectile/trident.rs +++ b/crates/pumpkin/src/entity/projectile/trident.rs @@ -317,7 +317,10 @@ impl EntityBase for TridentEntity { ProjectileHit::Block { pos, hit_pos, .. } => { self.in_ground.store(true, Ordering::Relaxed); self.shake_time.store(7, Ordering::Relaxed); - *self.last_block_pos.write().unwrap() = Some(pos); + *self + .last_block_pos + .write() + .unwrap_or_else(std::sync::PoisonError::into_inner) = Some(pos); // Stop the trident entity.velocity.store(Vector3::new(0.0, 0.0, 0.0)); diff --git a/crates/pumpkin/src/item/items/bucket.rs b/crates/pumpkin/src/item/items/bucket.rs index ded3b4830..e7391b1e2 100644 --- a/crates/pumpkin/src/item/items/bucket.rs +++ b/crates/pumpkin/src/item/items/bucket.rs @@ -83,7 +83,10 @@ fn is_waterlogged(block: &Block, state: BlockStateId) -> bool { } fn set_waterlogged(block: &Block, state: BlockStateId, waterlogged: bool) -> BlockStateId { - let original_props = &block.properties(state).unwrap().to_props(); + let Some(props) = block.properties(state) else { + return state; + }; + let original_props = &props.to_props(); let waterlogged = waterlogged.to_string(); let props: Vec<(&str, &str)> = original_props .iter() diff --git a/crates/pumpkin/src/item/items/ender_eye.rs b/crates/pumpkin/src/item/items/ender_eye.rs index 134d083f5..86194a37e 100644 --- a/crates/pumpkin/src/item/items/ender_eye.rs +++ b/crates/pumpkin/src/item/items/ender_eye.rs @@ -49,19 +49,25 @@ impl ItemBehaviour for EnderEyeItem { let world = player.world(); let state_id = world.get_block_state_id(&location); - // Skip if the frame already holds an eye. - let props_raw = block.properties(state_id).unwrap().to_props(); - if props_raw.iter().any(|(k, v)| *k == "eye" && *v == "true") { - return; - } + let new_state_id = { + // Skip if the frame already holds an eye. + let Some(props) = block.properties(state_id) else { + return; + }; + let props_raw = props.to_props(); + if props_raw.iter().any(|(k, v)| *k == "eye" && *v == "true") { + return; + } - // Build new state with eye=true. - let props: Vec<(&str, &str)> = props_raw - .iter() - .map(|(k, v)| if *k == "eye" { (*k, "true") } else { (*k, *v) }) - .collect(); + // Build new state with eye=true. + let props: Vec<(&str, &str)> = props_raw + .iter() + .map(|(k, v)| if *k == "eye" { (*k, "true") } else { (*k, *v) }) + .collect(); + + block.from_properties(&props).to_state_id(block) + }; - let new_state_id = block.from_properties(&props).to_state_id(block); world .set_block_state(&location, new_state_id, BlockFlags::NOTIFY_LISTENERS) .await; @@ -146,9 +152,11 @@ fn find_stronghold(world: &Arc, origin: BlockPos) -> Option { let global_cache = generator.global_structure_cache()?; + let strongholds = StructureSet::get("strongholds")?; + find_nearest_structure( origin, - &[&StructureSet::get("strongholds").unwrap().placement], + &[&strongholds.placement], 100, // max search radius in chunks, matches vanilla default seed as i64, global_cache, diff --git a/crates/pumpkin/src/item/items/map.rs b/crates/pumpkin/src/item/items/map.rs index 451b96692..39237d275 100644 --- a/crates/pumpkin/src/item/items/map.rs +++ b/crates/pumpkin/src/item/items/map.rs @@ -26,7 +26,9 @@ impl ItemBehaviour for MapItem { player: &'a Player, ) -> Pin + Send + 'a>> { Box::pin(async move { - let server = player.world().server.upgrade().unwrap(); + let Some(server) = player.world().server.upgrade() else { + return; + }; let inventory = player.inventory(); let held_stack = inventory.held_item().await; diff --git a/crates/pumpkin/src/lib.rs b/crates/pumpkin/src/lib.rs index 2b9d605bf..a0491d958 100644 --- a/crates/pumpkin/src/lib.rs +++ b/crates/pumpkin/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] // Not warn event sending macros #![allow(unused_labels)] @@ -95,10 +97,13 @@ pub fn init_logger(advanced_config: &AdvancedConfiguration) { let file_logger: Option = if advanced_config.logging.file.is_empty() { None } else { - Some( - GzipRollingLogger::new(level, advanced_config.logging.file.clone()) - .expect("Failed to initialize file logger."), - ) + match GzipRollingLogger::new(level, advanced_config.logging.file.clone()) { + Ok(logger) => Some(logger), + Err(err) => { + error!("Failed to initialize file logger: {err}"); + None + } + } }; let (logger, rl): ( @@ -265,9 +270,9 @@ impl PumpkinServer { }, }; // In the event the user puts 0 for their port, this will allow us to know what port it is running on - let addr = listener - .local_addr() - .expect("Unable to get the address of the server!"); + let addr = listener.local_addr().unwrap_or_else(|_| { + std::net::SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED), 0) + }); if server.advanced_config.networking.query.enabled { info!("Query protocol is enabled. Starting..."); @@ -316,40 +321,57 @@ impl PumpkinServer { if !config.enabled || !config.nethernet.enabled { return None; } - let identity_key = load_or_create_identity_key(&config.nethernet.identity_key) - .expect("Failed to load or create the Bedrock NetherNet identity key"); + let identity_key = match load_or_create_identity_key(&config.nethernet.identity_key) { + Ok(key) => key, + Err(err) => { + error!("Failed to load or create the Bedrock NetherNet identity key: {err}"); + return None; + } + }; let _ = server.bedrock_private_key.set(identity_key.clone()); - let oidc_verifier = (config.online_mode && config.authentication.enabled).then(|| { - let (issuer, keys) = server - .bedrock_oidc_keys - .get() - .expect("Bedrock OIDC keys should be initialized before binding NetherNet"); - Arc::new((issuer.clone(), keys.clone())) - }); - Some( - NetherNetListener::bind( - config.nethernet.address, - identity_key, - oidc_verifier, - config.nethernet.stun_servers.clone(), - ) - .await - .expect("Failed to bind Bedrock NetherNet signaling endpoint"), + let oidc_verifier = if config.online_mode && config.authentication.enabled { + let Some((issuer, keys)) = server.bedrock_oidc_keys.get() else { + error!("Bedrock OIDC keys should be initialized before binding NetherNet"); + return None; + }; + Some(Arc::new((issuer.clone(), keys.clone()))) + } else { + None + }; + match NetherNetListener::bind( + config.nethernet.address, + identity_key, + oidc_verifier, + config.nethernet.stun_servers.clone(), ) + .await + { + Ok(l) => Some(l), + Err(err) => { + error!("Failed to bind Bedrock NetherNet signaling endpoint: {err}"); + None + } + } } async fn bind_bedrock_status(server: &Server, enabled: bool) -> Option { if !enabled { return None; } - let responder = - StatusResponder::bind(server.advanced_config.networking.bedrock.nethernet.address) - .await - .expect("Failed to bind Bedrock server-list status"); - let (ipv4, ipv6) = responder - .local_addrs() - .expect("Bedrock status sockets should have local addresses"); - info!("Bedrock server-list status is listening on {ipv4} (IPv4) and {ipv6} (IPv6)"); + let responder = match StatusResponder::bind( + server.advanced_config.networking.bedrock.nethernet.address, + ) + .await + { + Ok(r) => r, + Err(err) => { + error!("Failed to bind Bedrock server-list status: {err}"); + return None; + } + }; + if let Ok((ipv4, ipv6)) = responder.local_addrs() { + info!("Bedrock server-list status is listening on {ipv4} (IPv4) and {ipv6} (IPv6)"); + } Some(responder) } @@ -652,8 +674,7 @@ fn setup_stdin_console(server: Arc) { if line.is_empty() || line.as_bytes()[line.len() - 1] != b'\n' { warn!("Console command was not terminated with a newline"); } - rt.block_on(tx.send(line.trim().to_string())) - .expect("Failed to send command to server"); + let _ = rt.block_on(tx.send(line.trim().to_string())); } }); tokio::spawn(async move { diff --git a/crates/pumpkin/src/logging.rs b/crates/pumpkin/src/logging.rs index bd4ac9ed2..0571d0174 100644 --- a/crates/pumpkin/src/logging.rs +++ b/crates/pumpkin/src/logging.rs @@ -198,7 +198,10 @@ impl GzipRollingLogger { fn rotate_log(&self) -> Result<(), Box> { let now = time::OffsetDateTime::now_utc(); - let mut data = self.data.lock().unwrap(); + let mut data = self + .data + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let new_gz_path = Self::new_filename(true)?; let latest_path = PathBuf::from(LOG_DIR).join(&data.latest_filename); diff --git a/crates/pumpkin/src/main.rs b/crates/pumpkin/src/main.rs index dc7209058..bc299a15d 100644 --- a/crates/pumpkin/src/main.rs +++ b/crates/pumpkin/src/main.rs @@ -1,3 +1,5 @@ +#![deny(clippy::unwrap_used)] +#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))] // Don't warn on event sending macros #![recursion_limit = "512"] @@ -45,9 +47,7 @@ static MAIN_THREAD: OnceLock = OnceLock::new(); #[allow(clippy::too_many_lines)] #[tokio::main] async fn main() { - MAIN_THREAD - .set(thread::current().id()) - .expect("Expected to successfully set the main thread ID"); + let _ = MAIN_THREAD.set(thread::current().id()); // Set the panic handler. std::panic::set_hook(Box::new(handle_panic)); @@ -56,7 +56,7 @@ async fn main() { console_subscriber::init(); let time = Instant::now(); - let exec_dir = std::env::current_dir().unwrap(); + let exec_dir = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")); let config = PumpkinConfig::load(&exec_dir); @@ -106,9 +106,9 @@ async fn main() { print_support_links_and_warning(); tokio::spawn(async { - setup_sighandler() - .await - .expect("Unable to setup signal handlers"); + if let Err(err) = setup_sighandler().await { + tracing::error!("Unable to setup signal handlers: {err}"); + } }); let pumpkin_server = PumpkinServer::new(config.basic, config.advanced, vanilla_data).await; diff --git a/crates/pumpkin/src/net/authentication.rs b/crates/pumpkin/src/net/authentication.rs index 1000b4625..c0bf812b1 100644 --- a/crates/pumpkin/src/net/authentication.rs +++ b/crates/pumpkin/src/net/authentication.rs @@ -125,7 +125,9 @@ pub fn validate_textures(property: &Property, config: &TextureConfig) -> Result< } pub fn is_texture_url_valid(url: &Uri, config: &TextureConfig) -> Result<(), TextureError> { - let scheme = url.scheme().unwrap(); + let Some(scheme) = url.scheme() else { + return Err(TextureError::InvalidURL); + }; if !config .allowed_url_schemes .iter() @@ -133,7 +135,9 @@ pub fn is_texture_url_valid(url: &Uri, config: &TextureConfig) -> Result<(), Tex { return Err(TextureError::DisallowedUrlScheme(scheme.to_string())); } - let domain = url.authority().unwrap(); + let Some(domain) = url.authority() else { + return Err(TextureError::InvalidURL); + }; if !config .allowed_url_domains .iter() diff --git a/crates/pumpkin/src/net/bedrock/mod.rs b/crates/pumpkin/src/net/bedrock/mod.rs index 8c45d77a4..7caa20c31 100644 --- a/crates/pumpkin/src/net/bedrock/mod.rs +++ b/crates/pumpkin/src/net/bedrock/mod.rs @@ -164,17 +164,14 @@ impl BedrockClient { pub fn start_outgoing_packet_task(self: &Arc) { let client = self.clone(); self.spawn_task(async move { - let mut packet_receiver = { - let mut guard = client.outgoing_packet_queue_recv.lock().await; - guard - .take() - .expect("Outgoing packet receiver was already taken") + let Some(mut packet_receiver) = client.outgoing_packet_queue_recv.lock().await.take() + else { + return; }; - let mut priority_packet_receiver = { - let mut guard = client.outgoing_packet_priority_recv.lock().await; - guard - .take() - .expect("Outgoing packet receiver was already taken") + let Some(mut priority_packet_receiver) = + client.outgoing_packet_priority_recv.lock().await.take() + else { + return; }; let mut interval = tokio::time::interval(std::time::Duration::from_millis(100)); diff --git a/crates/pumpkin/src/net/bedrock/play.rs b/crates/pumpkin/src/net/bedrock/play.rs index 5c8032406..aaa29f2e1 100644 --- a/crates/pumpkin/src/net/bedrock/play.rs +++ b/crates/pumpkin/src/net/bedrock/play.rs @@ -159,7 +159,9 @@ impl BedrockClient { .await; return; } - let server = player.world().server.upgrade().unwrap(); + let Some(server) = player.world().server.upgrade() else { + return; + }; let view_distance = chunk_radius.clamp( 2, @@ -177,7 +179,7 @@ impl BedrockClient { let mut new_config = (**current_config).clone(); new_config.view_distance = - NonZero::new(view_distance as u8).expect("View distance must be > 0"); + NonZero::new(view_distance as u8).unwrap_or(NonZero::::MIN); player.config.store(std::sync::Arc::new(new_config)); old_vd @@ -406,7 +408,9 @@ impl BedrockClient { packet: pumpkin_protocol::bedrock::server::player_auth_input::PlayerBlockAction, ) { use pumpkin_protocol::bedrock::server::player_action::Action as PlayerAction; - let action = PlayerAction::try_from(packet.action.0).unwrap(); + let Ok(action) = PlayerAction::try_from(packet.action.0) else { + return; + }; self.handle_player_action( player, server, @@ -640,7 +644,9 @@ impl BedrockClient { }; let world = player.world(); let block = world.get_block(&data.block_position); - let server = world.server.upgrade().expect("Server is gone"); + let Some(server) = world.server.upgrade() else { + return; + }; if player.gamemode.load() == GameMode::Spectator { // TODO: openMenu ? @@ -853,7 +859,9 @@ impl BedrockClient { if let Some(target) = world.get_entity_by_id(target_runtime_id) { let mut stack = player.inventory().held_item().await; if !target.interact(player, &mut stack).await { - let server = world.server.upgrade().expect("Server is gone"); + let Some(server) = world.server.upgrade() else { + return; + }; server .item_registry .use_on_entity(&mut stack, player, target) @@ -881,7 +889,9 @@ impl BedrockClient { TransactionData::ReleaseItem(_data) => { let item_in_use = player.living_entity.item_in_use.lock().await.clone(); if let Some(stack) = item_in_use { - let server = player.world().server.upgrade().expect("Server is gone"); + let Some(server) = player.world().server.upgrade() else { + return; + }; server.item_registry.on_stopped_using(&stack, player).await; } player.living_entity.clear_active_hand().await; diff --git a/crates/pumpkin/src/net/java/config.rs b/crates/pumpkin/src/net/java/config.rs index bcf8ca46a..dc0ba96b4 100644 --- a/crates/pumpkin/src/net/java/config.rs +++ b/crates/pumpkin/src/net/java/config.rs @@ -46,7 +46,8 @@ impl JavaClient { self.config.store(Arc::new(PlayerConfig { locale: client_information.locale.to_string(), // client_information.view_distance was checked above to be > 0 so compiler should optimize this out. - view_distance: NonZeroU8::new(client_information.view_distance as u8).unwrap(), + view_distance: NonZeroU8::new(client_information.view_distance as u8) + .unwrap_or(NonZeroU8::MIN), chat_mode, chat_colors: client_information.chat_colors, skin_parts: client_information.skin_parts, diff --git a/crates/pumpkin/src/net/java/login.rs b/crates/pumpkin/src/net/java/login.rs index 0ec6c6b53..0e05d4aef 100644 --- a/crates/pumpkin/src/net/java/login.rs +++ b/crates/pumpkin/src/net/java/login.rs @@ -73,7 +73,7 @@ impl PendingConnection { let id = if server.advanced_config.networking.java.online_mode { login_start.uuid } else { - offline_uuid(&login_start.name).expect("This is very not safe and bad") + offline_uuid(&login_start.name).unwrap_or_else(|_| uuid::Uuid::nil()) }; let profile = GameProfile { @@ -157,7 +157,9 @@ impl PendingConnection { } } - let profile = self.gameprofile.clone().unwrap(); + let Some(profile) = self.gameprofile.clone() else { + return; + }; if let Some(online_player) = &server.get_player_by_uuid(profile.id) { debug!( @@ -202,7 +204,7 @@ impl PendingConnection { .info .clone(); self.send_packet_now(&CSetCompression::new( - compression.threshold.try_into().unwrap(), + pumpkin_protocol::codec::var_int::VarInt(compression.threshold as i32), )) .await; self.set_compression(&compression); diff --git a/crates/pumpkin/src/net/java/mod.rs b/crates/pumpkin/src/net/java/mod.rs index cca375b94..852e6133b 100644 --- a/crates/pumpkin/src/net/java/mod.rs +++ b/crates/pumpkin/src/net/java/mod.rs @@ -178,7 +178,12 @@ impl JavaClient { } pub async fn progress_player_packets(&self, player: &Arc, server: &Arc) { - let Some(mut network_reader) = self.network_reader.lock().unwrap().take() else { + let Some(mut network_reader) = self + .network_reader + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .take() + else { return; }; @@ -532,16 +537,19 @@ impl JavaClient { pub fn start_outgoing_packet_task(&mut self) { const MAX_BATCH_SIZE: usize = 64; - let mut packet_receiver = self - .outgoing_packet_queue_recv - .take() - .expect("This was set in the new fn"); - let mut priority_packet_receiver = self - .outgoing_packet_priority_recv - .take() - .expect("This was set in the new fn"); + let Some(mut packet_receiver) = self.outgoing_packet_queue_recv.take() else { + return; + }; + let Some(mut priority_packet_receiver) = self.outgoing_packet_priority_recv.take() else { + return; + }; let close_token = self.close_token.clone(); - let Some(mut writer) = self.network_writer.lock().unwrap().take() else { + let Some(mut writer) = self + .network_writer + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .take() + else { return; }; let id = self.id; diff --git a/crates/pumpkin/src/net/java/pending.rs b/crates/pumpkin/src/net/java/pending.rs index de702db9a..929188448 100644 --- a/crates/pumpkin/src/net/java/pending.rs +++ b/crates/pumpkin/src/net/java/pending.rs @@ -353,7 +353,9 @@ impl PendingConnection { Ok(None) } id if id == SAcknowledgeFinishConfig::to_id(version) => { - let profile = self.gameprofile.clone().expect("Profile must be set"); + let Some(profile) = self.gameprofile.clone() else { + return Ok(Some(PacketHandlerResult::Stop)); + }; let config = self.config.clone().unwrap_or_default(); if let Some(reason) = can_not_join(&profile, &self.address, server).await { self.kick(reason).await; @@ -409,7 +411,8 @@ impl PendingConnection { ) { self.config = Some(PlayerConfig { locale: client_information.locale.to_string(), - view_distance: NonZeroU8::new(client_information.view_distance as u8).unwrap(), + view_distance: NonZeroU8::new(client_information.view_distance as u8) + .unwrap_or(NonZeroU8::MIN), chat_mode, chat_colors: client_information.chat_colors, skin_parts: client_information.skin_parts, diff --git a/crates/pumpkin/src/net/java/play.rs b/crates/pumpkin/src/net/java/play.rs index 0c8e8f270..9f96ed479 100644 --- a/crates/pumpkin/src/net/java/play.rs +++ b/crates/pumpkin/src/net/java/play.rs @@ -2478,7 +2478,10 @@ impl JavaClient { &sign_entity.back_text }; - *text.messages.lock().unwrap() = [ + *text + .messages + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) = [ sign_data.line_1.into(), sign_data.line_2.into(), sign_data.line_3.into(), diff --git a/crates/pumpkin/src/net/lan_broadcast.rs b/crates/pumpkin/src/net/lan_broadcast.rs index d7111a668..c6529f987 100644 --- a/crates/pumpkin/src/net/lan_broadcast.rs +++ b/crates/pumpkin/src/net/lan_broadcast.rs @@ -4,7 +4,7 @@ use std::sync::atomic::Ordering; use std::time::Duration; use tokio::net::UdpSocket; use tokio::{select, time}; -use tracing::{info, warn}; +use tracing::{error, info, warn}; use crate::{SHOULD_STOP, STOP_INTERRUPT}; @@ -52,22 +52,23 @@ impl LANBroadcast { /// # Panics /// Panics if the UDP socket cannot be bound or if broadcast permissions are denied pub async fn start(self, bound_addr: SocketAddr) { - let socket = UdpSocket::bind(format!("0.0.0.0:{}", self.port)) - .await - .expect("Unable to bind to address"); + let Ok(socket) = UdpSocket::bind(format!("0.0.0.0:{}", self.port)).await else { + error!("Unable to bind LAN broadcast UDP socket"); + return; + }; - socket.set_broadcast(true).unwrap(); + if let Err(err) = socket.set_broadcast(true) { + error!("Unable to set LAN broadcast: {err}"); + return; + } let mut interval = time::interval(Duration::from_millis(1500)); let advertisement = format!("[MOTD]{}[/MOTD][AD]{}[/AD]", self.motd, bound_addr.port()); - info!( - "LAN broadcast running on {}", - socket - .local_addr() - .expect("Unable to find running address!") - ); + if let Ok(local_addr) = socket.local_addr() { + info!("LAN broadcast running on {local_addr}"); + } while !SHOULD_STOP.load(Ordering::Relaxed) { let t1 = interval.tick(); diff --git a/crates/pumpkin/src/net/mod.rs b/crates/pumpkin/src/net/mod.rs index b6bd3f7f5..92df505be 100644 --- a/crates/pumpkin/src/net/mod.rs +++ b/crates/pumpkin/src/net/mod.rs @@ -98,7 +98,7 @@ impl Default for PlayerConfig { fn default() -> Self { Self { locale: "en_us".to_string(), - view_distance: NonZeroU8::new(8).unwrap(), + view_distance: NonZeroU8::new(8).unwrap_or(NonZeroU8::MIN), chat_mode: ChatMode::Enabled, chat_colors: true, skin_parts: 0x7F, @@ -315,7 +315,7 @@ pub async fn can_not_join( translation::java::MULTIPLAYER_DISCONNECT_BANNED_EXPIRATION, translation::java::MULTIPLAYER_DISCONNECT_BANNED_EXPIRATION, [TextComponent::text( - expires.format(FORMAT_DESCRIPTION).unwrap(), + expires.format(FORMAT_DESCRIPTION).unwrap_or_default(), )], )), None => text, @@ -353,7 +353,7 @@ pub async fn can_not_join( translation::java::MULTIPLAYER_DISCONNECT_BANNED_IP_EXPIRATION, translation::java::MULTIPLAYER_DISCONNECT_BANNED_IP_EXPIRATION, [TextComponent::text( - expires.format(FORMAT_DESCRIPTION).unwrap(), + expires.format(FORMAT_DESCRIPTION).unwrap_or_default(), )], )), None => text, diff --git a/crates/pumpkin/src/net/proxy/velocity.rs b/crates/pumpkin/src/net/proxy/velocity.rs index dada02a2e..ba9f5e998 100644 --- a/crates/pumpkin/src/net/proxy/velocity.rs +++ b/crates/pumpkin/src/net/proxy/velocity.rs @@ -67,8 +67,9 @@ pub async fn velocity_login(connection: &mut PendingConnection) { pub fn check_integrity(data: (&[u8], &[u8]), secret: &str) -> bool { let (signature, data_without_signature) = data; // Our fault, we can panic/expect? - let mut mac = - HmacSha256::new_from_slice(secret.as_bytes()).expect("HMAC can take key of any size"); + let Ok(mut mac) = HmacSha256::new_from_slice(secret.as_bytes()) else { + return false; + }; mac.update(data_without_signature); mac.verify_slice(signature).is_ok() } diff --git a/crates/pumpkin/src/net/query.rs b/crates/pumpkin/src/net/query.rs index d8a9b5831..3ce4fd08c 100644 --- a/crates/pumpkin/src/net/query.rs +++ b/crates/pumpkin/src/net/query.rs @@ -18,11 +18,11 @@ use tracing::{error, info}; use crate::{SHOULD_STOP, STOP_INTERRUPT, server::Server}; pub async fn start_query_handler(server: Arc, query_addr: SocketAddr) { - let socket = Arc::new( - UdpSocket::bind(query_addr) - .await - .expect("Unable to bind to address"), - ); + let Ok(socket) = UdpSocket::bind(query_addr).await else { + error!("Unable to bind query UDP socket"); + return; + }; + let socket = Arc::new(socket); // Challenge tokens are bound to the IP address and port let valid_challenge_tokens = Arc::new(RwLock::new(HashMap::new())); @@ -37,18 +37,14 @@ pub async fn start_query_handler(server: Arc, query_addr: SocketAddr) { } }); - info!( - "Server query running on port {}", - TextComponent::text(format!( - "{}", - socket - .local_addr() - .expect("Unable to find running address!") - .port() - )) - .color_named(NamedColor::DarkBlue) - .to_pretty_console() - ); + if let Ok(local_addr) = socket.local_addr() { + info!( + "Server query running on port {}", + TextComponent::text(format!("{}", local_addr.port())) + .color_named(NamedColor::DarkBlue) + .to_pretty_console() + ); + } while !SHOULD_STOP.load(Ordering::Relaxed) { let socket = socket.clone(); @@ -134,8 +130,8 @@ async fn handle_packet( // Although there is no documented limit, we will limit to 4 players .iter() .take(4 - players.len()) - .map(|player| { - CString::new(player.gameprofile.name.as_str()).unwrap() + .filter_map(|player| { + CString::new(player.gameprofile.name.as_str()).ok() }) .collect::>(); diff --git a/crates/pumpkin/src/net/rcon/mod.rs b/crates/pumpkin/src/net/rcon/mod.rs index 7fa5080b7..d64fdf087 100644 --- a/crates/pumpkin/src/net/rcon/mod.rs +++ b/crates/pumpkin/src/net/rcon/mod.rs @@ -18,7 +18,13 @@ pub struct RCONServer; impl RCONServer { pub async fn run(config: &RCONConfig, server: Arc) { - let listener = tokio::net::TcpListener::bind(config.address).await.unwrap(); + let listener = match tokio::net::TcpListener::bind(config.address).await { + Ok(l) => l, + Err(e) => { + error!("Failed to bind RCON server on {}: {e}", config.address); + return; + } + }; let password = Arc::new(config.password.clone()); diff --git a/crates/pumpkin/src/net/rcon/packet.rs b/crates/pumpkin/src/net/rcon/packet.rs index 2b8483017..1fdea79a7 100644 --- a/crates/pumpkin/src/net/rcon/packet.rs +++ b/crates/pumpkin/src/net/rcon/packet.rs @@ -77,7 +77,9 @@ impl Packet { } // Read the 4-byte length header (little-endian) - let len_bytes: [u8; 4] = incoming[0..4].try_into().unwrap(); + let len_bytes: [u8; 4] = incoming[0..4] + .try_into() + .map_err(|_| PacketError::InvalidLength)?; let size = i32::from_le_bytes(len_bytes); // An RCON packet size includes: ID(4) + Type(4) + Body(n) + Null(1) + EmptyStringNull(1). @@ -95,8 +97,16 @@ impl Packet { } // We have the full packet. Parse it synchronously using fixed slices. - let id = i32::from_le_bytes(incoming[4..8].try_into().unwrap()); - let ty = i32::from_le_bytes(incoming[8..12].try_into().unwrap()); + let id = i32::from_le_bytes( + incoming[4..8] + .try_into() + .map_err(|_| PacketError::InvalidLength)?, + ); + let ty = i32::from_le_bytes( + incoming[8..12] + .try_into() + .map_err(|_| PacketError::InvalidLength)?, + ); // Calculate body boundaries (starts after len, id, and ty -> 4+4+4 = 12) // Ends 2 bytes before the total length (excluding the two trailing null bytes) diff --git a/crates/pumpkin/src/plugin/api/context.rs b/crates/pumpkin/src/plugin/api/context.rs index eeabae836..878448d60 100644 --- a/crates/pumpkin/src/plugin/api/context.rs +++ b/crates/pumpkin/src/plugin/api/context.rs @@ -82,7 +82,7 @@ impl Context { pub fn get_data_folder(&self) -> PathBuf { let path = Path::new("plugins").join("data").join(&self.metadata.name); if !path.exists() { - fs::create_dir_all(&path).unwrap(); + let _ = fs::create_dir_all(&path); } path } diff --git a/crates/pumpkin/src/plugin/cache.rs b/crates/pumpkin/src/plugin/cache.rs index e9d25c6cf..b8b9a1bd8 100644 --- a/crates/pumpkin/src/plugin/cache.rs +++ b/crates/pumpkin/src/plugin/cache.rs @@ -24,14 +24,19 @@ impl PermissionCache { } pub async fn save(&self, path: &Path) -> tokio::io::Result<()> { - let data = serde_json::to_string_pretty(self).unwrap(); + let data = serde_json::to_string_pretty(self).map_err(std::io::Error::other)?; fs::write(path, data).await } } pub async fn calculate_hash(path: &Path) -> tokio::io::Result { - let bytes = fs::read(path).await?; - Ok(calculate_hash_for_bytes(&bytes)) + let path = path.to_path_buf(); + tokio::task::spawn_blocking(move || { + let bytes = std::fs::read(path)?; + Ok(calculate_hash_for_bytes(&bytes)) + }) + .await + .map_err(std::io::Error::other)? } #[must_use] diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs index d4f2ac0f1..36f73e54e 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] + use std::{fs, path::Path, sync::Arc}; use thiserror::Error; use tokio::sync::Mutex; diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs index 933cc5a8c..1aabd7909 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/signature.rs @@ -1,5 +1,6 @@ use ed25519_dalek::{Signature, Signer, Verifier, VerifyingKey}; use serde::{Deserialize, Serialize}; +use std::sync::Mutex; use tracing::warn; use wasm_encoder::{CustomSection, Encode}; use wasmparser::{Parser, Payload}; @@ -9,6 +10,8 @@ pub const PUMPKIN_METADATA_SECTION: &str = "pumpkin.metadata"; pub const PUMPKIN_MARKET_PUBLIC_KEY_URL: &str = "https://market.pumpkinmc.org/api/v1/rest/public-key"; +static MARKET_PUBLIC_KEY_CACHE: Mutex> = Mutex::new(None); + #[derive(Debug, Serialize, Deserialize, Clone)] pub struct PumpkinMetadata { pub marketplace_url: String, @@ -164,8 +167,21 @@ pub struct VerificationResult { pub public_key_hex: String, } -/// Fetches public key from market REST API. +/// Fetches public key from market REST API, returning cached key if previously fetched. +/// +/// # Errors +/// +/// Returns an error if the public key cache lock cannot be acquired, if the HTTP request fails, +/// if the response body cannot be read, or if the returned key is empty. pub fn fetch_market_public_key() -> Result { + let mut guard = MARKET_PUBLIC_KEY_CACHE + .lock() + .map_err(|e| format!("Failed to acquire public key cache lock: {e}"))?; + + if let Some(ref cached_key) = *guard { + return Ok(cached_key.clone()); + } + let mut response = ureq::get(PUMPKIN_MARKET_PUBLIC_KEY_URL) .header("User-Agent", "Pumpkin-MC") .call() @@ -180,6 +196,7 @@ pub fn fetch_market_public_key() -> Result { if key.is_empty() { Err("Fetched public key is empty".into()) } else { + *guard = Some(key.clone()); Ok(key) } } @@ -387,3 +404,24 @@ pub fn verify_wasm_plugin(wasm_bytes: &[u8], path_str: &str) { ); } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn market_public_key_caching() { + { + let mut guard = MARKET_PUBLIC_KEY_CACHE.lock().unwrap(); + *guard = Some("cached_test_key_12345".to_string()); + }; + + let key = fetch_market_public_key().expect("Should return cached key"); + assert_eq!(key, "cached_test_key_12345"); + + { + let mut guard = MARKET_PUBLIC_KEY_CACHE.lock().unwrap(); + *guard = None; + }; + } +} diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/block_entity.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/block_entity.rs index de40e6018..62d7b36c1 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/block_entity.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/block_entity.rs @@ -85,7 +85,7 @@ fn to_wasm_sign_text(text: &InternalText) -> SignText { messages: text .messages .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .clone() .map(str::into_string) .to_vec(), @@ -300,8 +300,17 @@ impl HostSignBlockEntity for PluginHostState { std::sync::atomic::Ordering::Relaxed, ); sign.front_text.set_color(new_text.get_color()); - (*sign.front_text.messages.lock().unwrap()) - .clone_from(&new_text.messages.lock().unwrap()); + (*sign + .front_text + .messages + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner)) + .clone_from( + &new_text + .messages + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner), + ); Ok(()) }, ) @@ -341,8 +350,17 @@ impl HostSignBlockEntity for PluginHostState { std::sync::atomic::Ordering::Relaxed, ); sign.back_text.set_color(new_text.get_color()); - (*sign.back_text.messages.lock().unwrap()) - .clone_from(&new_text.messages.lock().unwrap()); + (*sign + .back_text + .messages + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner)) + .clone_from( + &new_text + .messages + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner), + ); Ok(()) }, ) diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/commands/executor.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/commands/executor.rs index b81f2b59a..d55c732bf 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/commands/executor.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/commands/executor.rs @@ -30,9 +30,18 @@ impl CommandExecutor for WasmCommandExecutor { Box::pin(async move { let mut store = self.plugin.store.lock().await; - let sender_resource = store.data_mut().add_command_sender(sender.clone()).unwrap(); - let server_resource = store.data_mut().add_server(self.server.clone()).unwrap(); - let args_resource = store.data_mut().add_consumed_args(args).unwrap(); + let sender_resource = store + .data_mut() + .add_command_sender(sender.clone()) + .expect("valid command sender"); + let server_resource = store + .data_mut() + .add_server(self.server.clone()) + .expect("valid server"); + let args_resource = store + .data_mut() + .add_consumed_args(args) + .expect("valid consumed args"); match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/entity.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/entity.rs index 1bd9d82a0..d6cdd87ec 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/entity.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/entity.rs @@ -879,7 +879,9 @@ impl HostEntity for PluginHostState { priority: u8, goal_id: u32, ) -> wasmtime::Result<()> { - let plugin = self.plugin.as_ref().unwrap().upgrade().unwrap(); + let Some(plugin) = self.plugin.as_ref().and_then(std::sync::Weak::upgrade) else { + return Err(wasmtime::Error::msg("Plugin not active")); + }; let entity = entity_from_resource(self, &entity)?; if let Some(mob) = entity.get_mob() { let mob_entity = mob.get_mob_entity(); @@ -1007,9 +1009,15 @@ impl Goal for CustomWasmGoal { { match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().server.clone().unwrap(); - let server_res = store.data_mut().add_server(server).unwrap(); - let entity_res = store.data_mut().add_entity(entity_arc).unwrap(); + let Some(server) = store.data_mut().server.clone() else { + return false; + }; + let Ok(server_res) = store.data_mut().add_server(server) else { + return false; + }; + let Ok(entity_res) = store.data_mut().add_entity(entity_arc) else { + return false; + }; plugin .call_handle_ai_goal_can_start( &mut *store, @@ -1038,9 +1046,15 @@ impl Goal for CustomWasmGoal { { match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().server.clone().unwrap(); - let server_res = store.data_mut().add_server(server).unwrap(); - let entity_res = store.data_mut().add_entity(entity_arc).unwrap(); + let Some(server) = store.data_mut().server.clone() else { + return false; + }; + let Ok(server_res) = store.data_mut().add_server(server) else { + return false; + }; + let Ok(entity_res) = store.data_mut().add_entity(entity_arc) else { + return false; + }; plugin .call_handle_ai_goal_should_continue( &mut *store, @@ -1069,9 +1083,15 @@ impl Goal for CustomWasmGoal { { match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().server.clone().unwrap(); - let server_res = store.data_mut().add_server(server).unwrap(); - let entity_res = store.data_mut().add_entity(entity_arc).unwrap(); + let Some(server) = store.data_mut().server.clone() else { + return; + }; + let Ok(server_res) = store.data_mut().add_server(server) else { + return; + }; + let Ok(entity_res) = store.data_mut().add_entity(entity_arc) else { + return; + }; let _ = plugin .call_handle_ai_goal_start( &mut *store, @@ -1097,9 +1117,15 @@ impl Goal for CustomWasmGoal { { match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().server.clone().unwrap(); - let server_res = store.data_mut().add_server(server).unwrap(); - let entity_res = store.data_mut().add_entity(entity_arc).unwrap(); + let Some(server) = store.data_mut().server.clone() else { + return; + }; + let Ok(server_res) = store.data_mut().add_server(server) else { + return; + }; + let Ok(entity_res) = store.data_mut().add_entity(entity_arc) else { + return; + }; let _ = plugin .call_handle_ai_goal_tick( &mut *store, @@ -1125,9 +1151,15 @@ impl Goal for CustomWasmGoal { { match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().server.clone().unwrap(); - let server_res = store.data_mut().add_server(server).unwrap(); - let entity_res = store.data_mut().add_entity(entity_arc).unwrap(); + let Some(server) = store.data_mut().server.clone() else { + return; + }; + let Ok(server_res) = store.data_mut().add_server(server) else { + return; + }; + let Ok(entity_res) = store.data_mut().add_entity(entity_arc) else { + return; + }; let _ = plugin .call_handle_ai_goal_stop( &mut *store, diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/mod.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/mod.rs index 2fec18664..bdd7c44bf 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/mod.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/mod.rs @@ -214,11 +214,13 @@ impl EventHandler for WasmPluginEventHandler { let event = event.to_wasm_event(store.data_mut()); match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().add_server(server.clone()).unwrap(); - plugin + let server = store + .data_mut() + .add_server(server.clone()) + .expect("valid server"); + let _ = plugin .call_handle_event(&mut *store, self.handler_id, server, &event) - .await - .unwrap(); + .await; } } }) @@ -234,13 +236,16 @@ impl EventHandler for WasmPluginEventHandler { let wasm_event = event.to_wasm_event(store.data_mut()); match self.plugin.plugin_instance { PluginInstance::V0_1(ref plugin) => { - let server = store.data_mut().add_server(server.clone()).unwrap(); - let returned_event = plugin + let server = store + .data_mut() + .add_server(server.clone()) + .expect("valid server"); + if let Ok(returned_event) = plugin .call_handle_event(&mut *store, self.handler_id, server, &wasm_event) .await - .unwrap(); - - *event = E::from_wasm_event(returned_event, store.data_mut()); + { + *event = E::from_wasm_event(returned_event, store.data_mut()); + } } } }) diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/forms.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/forms.rs index 9cee2d051..f77eb3b9b 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/forms.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/forms.rs @@ -27,8 +27,10 @@ impl PluginHostState { .into_iter() .map(|b| { let mut obj = json!({ "text": self.translate_res(&b.text, locale) }); - if let Some(image) = b.image { - obj.as_object_mut().unwrap().insert( + if let Some(image) = b.image + && let Some(obj) = obj.as_object_mut() + { + obj.insert( "image".to_string(), json!({ "type": match image.type_ { diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs index cee5a6cbc..60cee73c7 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs @@ -26,7 +26,7 @@ pub fn serialize_java_packet( reason: &data.reason, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::ConfigCPluginMessage(data) => { @@ -35,7 +35,7 @@ pub fn serialize_java_packet( data: &data.data, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::ConfigCTransfer(data) => { @@ -45,7 +45,7 @@ pub fn serialize_java_packet( port: &var_int_port, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::LoginCEncryptionRequest(data) => { @@ -53,10 +53,10 @@ pub fn serialize_java_packet( server_id: &data.server_id, public_key: &data.public_key, verify_token: &data.verify_token, - should_authenticate: data.should_authenticate.try_into().unwrap(), + should_authenticate: data.should_authenticate.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::LoginCLoginDisconnect(data) => { @@ -64,7 +64,7 @@ pub fn serialize_java_packet( json_reason: data.json_reason.clone(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::LoginCLoginPluginRequest(data) => { @@ -74,7 +74,7 @@ pub fn serialize_java_packet( data: &data.data, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::LoginCSetCompression(data) => { @@ -82,7 +82,7 @@ pub fn serialize_java_packet( threshold: VarInt(data.threshold), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CAcknowledgeBlockChange(data) => { @@ -90,7 +90,7 @@ pub fn serialize_java_packet( sequence_id: VarInt(data.sequence_id), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CActionBar(data) => { @@ -100,7 +100,7 @@ pub fn serialize_java_packet( action_bar: &component_action_bar, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetBlockDestroyStage(data) => { @@ -111,10 +111,10 @@ pub fn serialize_java_packet( data.location.1, data.location.2, ), - destroy_stage: data.destroy_stage.try_into().unwrap(), + destroy_stage: data.destroy_stage.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CBlockEvent(data) => { @@ -124,12 +124,12 @@ pub fn serialize_java_packet( data.location.1, data.location.2, ), - action_id: data.action_id.try_into().unwrap(), - action_parameter: data.action_parameter.try_into().unwrap(), + action_id: data.action_id.try_into().unwrap_or_default(), + action_parameter: data.action_parameter.try_into().unwrap_or_default(), block_type: VarInt(data.block_type), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CBlockUpdate(data) => { @@ -142,7 +142,7 @@ pub fn serialize_java_packet( state_id: VarInt(data.state_id), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CCenterChunk(data) => { @@ -151,16 +151,16 @@ pub fn serialize_java_packet( chunk_z: VarInt(data.chunk_z), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CChangeDifficulty(data) => { let p = pumpkin_protocol::java::client::play::CChangeDifficulty { - difficulty: data.difficulty.try_into().unwrap(), - locked: data.locked.try_into().unwrap(), + difficulty: data.difficulty.try_into().unwrap_or_default(), + locked: data.locked.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CChunkBatchEnd(data) => { @@ -168,15 +168,15 @@ pub fn serialize_java_packet( batch_size: VarInt(data.batch_size), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CClearTitle(data) => { let p = pumpkin_protocol::java::client::play::CClearTitle { - reset: data.reset.try_into().unwrap(), + reset: data.reset.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CCloseContainer(data) => { @@ -184,7 +184,7 @@ pub fn serialize_java_packet( sync_id: VarInt(data.sync_id), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CCombatDeath(data) => { @@ -194,7 +194,7 @@ pub fn serialize_java_packet( message: &component_message, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CCustomPayload(data) => { @@ -203,7 +203,7 @@ pub fn serialize_java_packet( data: &data.data, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CDebugSample(data) => { @@ -213,7 +213,7 @@ pub fn serialize_java_packet( sample_type: VarInt(data.sample_type), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CPlayDisconnect(data) => { @@ -222,7 +222,7 @@ pub fn serialize_java_packet( reason: &component_reason, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CDisplayObjective(data) => { @@ -231,16 +231,16 @@ pub fn serialize_java_packet( score_name: data.score_name.clone(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CEntityAnimation(data) => { let p = pumpkin_protocol::java::client::play::CEntityAnimation { entity_id: VarInt(data.entity_id), - animation: data.animation.try_into().unwrap(), + animation: data.animation.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CEntityPositionSync(data) => { @@ -256,63 +256,65 @@ pub fn serialize_java_packet( data.delta.1 as _, data.delta.2 as _, ), - yaw: data.yaw.try_into().unwrap(), - pitch: data.pitch.try_into().unwrap(), - on_ground: data.on_ground.try_into().unwrap(), + yaw: data.yaw.try_into().unwrap_or_default(), + pitch: data.pitch.try_into().unwrap_or_default(), + on_ground: data.on_ground.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CEntityStatus(data) => { let p = pumpkin_protocol::java::client::play::CEntityStatus { - entity_id: data.entity_id.try_into().unwrap(), - entity_status: data.entity_status.try_into().unwrap(), + entity_id: data.entity_id.try_into().unwrap_or_default(), + entity_status: data.entity_status.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CGameEvent(data) => { let p = pumpkin_protocol::java::client::play::CGameEvent { - event: data.event.try_into().unwrap(), - value: data.value.try_into().unwrap(), + event: data.event.try_into().unwrap_or_default(), + value: data.value.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CHeadRot(data) => { let p = pumpkin_protocol::java::client::play::CHeadRot { entity_id: VarInt(data.entity_id), - head_yaw: data.head_yaw.try_into().unwrap(), + head_yaw: data.head_yaw.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CHurtAnimation(data) => { let p = pumpkin_protocol::java::client::play::CHurtAnimation { entity_id: VarInt(data.entity_id), - yaw: data.yaw.try_into().unwrap(), + yaw: data.yaw.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CInitializeWorldBorder(data) => { let p = pumpkin_protocol::java::client::play::CInitializeWorldBorder { - x: data.x.try_into().unwrap(), - z: data.z.try_into().unwrap(), - old_diameter: data.old_diameter.try_into().unwrap(), - new_diameter: data.new_diameter.try_into().unwrap(), - speed: pumpkin_protocol::codec::var_long::VarLong(data.speed.try_into().unwrap()), + x: data.x.try_into().unwrap_or_default(), + z: data.z.try_into().unwrap_or_default(), + old_diameter: data.old_diameter.try_into().unwrap_or_default(), + new_diameter: data.new_diameter.try_into().unwrap_or_default(), + speed: pumpkin_protocol::codec::var_long::VarLong( + data.speed.try_into().unwrap_or_default(), + ), portal_teleport_boundary: VarInt(data.portal_teleport_boundary), warning_blocks: VarInt(data.warning_blocks), warning_time: VarInt(data.warning_time), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CItemCooldown(data) => { @@ -321,30 +323,33 @@ pub fn serialize_java_packet( cooldown: VarInt(data.cooldown), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CKeepAlive(data) => { let p = pumpkin_protocol::java::client::play::CKeepAlive { - keep_alive_id: data.keep_alive_id.try_into().unwrap(), + keep_alive_id: data.keep_alive_id.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CLevelEvent(data) => { let p = pumpkin_protocol::java::client::play::CLevelEvent { - event: data.event.try_into().unwrap(), + event: data.event.try_into().unwrap_or_default(), location: pumpkin_util::math::position::BlockPos::new( data.location.0, data.location.1, data.location.2, ), - data: data.data.try_into().unwrap(), - disable_relative_volume: data.disable_relative_volume.try_into().unwrap(), + data: data.data.try_into().unwrap_or_default(), + disable_relative_volume: data + .disable_relative_volume + .try_into() + .unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::COpenScreen(data) => { @@ -356,7 +361,7 @@ pub fn serialize_java_packet( window_title: &component_window_title, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::COpenSignEditor(data) => { @@ -366,16 +371,16 @@ pub fn serialize_java_packet( data.location.1, data.location.2, ), - is_front_text: data.is_front_text.try_into().unwrap(), + is_front_text: data.is_front_text.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CParticle(data) => { let p = pumpkin_protocol::java::client::play::CParticle { - force_spawn: data.force_spawn.try_into().unwrap(), - important: data.important.try_into().unwrap(), + force_spawn: data.force_spawn.try_into().unwrap_or_default(), + important: data.important.try_into().unwrap_or_default(), position: pumpkin_util::math::vector3::Vector3::new( data.position.0 as _, data.position.1 as _, @@ -386,31 +391,31 @@ pub fn serialize_java_packet( data.offset.1 as _, data.offset.2 as _, ), - max_speed: data.max_speed.try_into().unwrap(), - particle_count: data.particle_count.try_into().unwrap(), + max_speed: data.max_speed.try_into().unwrap_or_default(), + particle_count: data.particle_count.try_into().unwrap_or_default(), particle_id: VarInt(data.particle_id), data: &data.data, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CPingResponse(data) => { let p = pumpkin_protocol::java::client::play::CPingResponse { - payload: data.payload.try_into().unwrap(), + payload: data.payload.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CPlayerAbilities(data) => { let p = pumpkin_protocol::java::client::play::CPlayerAbilities { - flags: data.flags.try_into().unwrap(), - flying_speed: data.flying_speed.try_into().unwrap(), - field_of_view: data.field_of_view.try_into().unwrap(), + flags: data.flags.try_into().unwrap_or_default(), + flying_speed: data.flying_speed.try_into().unwrap_or_default(), + field_of_view: data.field_of_view.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CRemovePlayerInfo(data) => { @@ -423,7 +428,7 @@ pub fn serialize_java_packet( players: &vec_players, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CPlayerSpawnPosition(data) => { @@ -434,35 +439,38 @@ pub fn serialize_java_packet( data.location.1, data.location.2, ), - yaw: data.yaw.try_into().unwrap(), - pitch: data.pitch.try_into().unwrap(), + yaw: data.yaw.try_into().unwrap_or_default(), + pitch: data.pitch.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CRecipeBookAdd(data) => { let p = pumpkin_protocol::java::client::play::CRecipeBookAdd { - replace: data.replace.try_into().unwrap(), + replace: data.replace.try_into().unwrap_or_default(), dynamic_recipes: &[], }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CRecipeBookSettings(data) => { let p = pumpkin_protocol::java::client::play::CRecipeBookSettings { - crafting_open: data.crafting_open.try_into().unwrap(), - crafting_filtering: data.crafting_filtering.try_into().unwrap(), - furnace_open: data.furnace_open.try_into().unwrap(), - furnace_filtering: data.furnace_filtering.try_into().unwrap(), - blast_furnace_open: data.blast_furnace_open.try_into().unwrap(), - blast_furnace_filtering: data.blast_furnace_filtering.try_into().unwrap(), - smoker_open: data.smoker_open.try_into().unwrap(), - smoker_filtering: data.smoker_filtering.try_into().unwrap(), + crafting_open: data.crafting_open.try_into().unwrap_or_default(), + crafting_filtering: data.crafting_filtering.try_into().unwrap_or_default(), + furnace_open: data.furnace_open.try_into().unwrap_or_default(), + furnace_filtering: data.furnace_filtering.try_into().unwrap_or_default(), + blast_furnace_open: data.blast_furnace_open.try_into().unwrap_or_default(), + blast_furnace_filtering: data + .blast_furnace_filtering + .try_into() + .unwrap_or_default(), + smoker_open: data.smoker_open.try_into().unwrap_or_default(), + smoker_filtering: data.smoker_filtering.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CRemoveEntities(data) => { @@ -471,7 +479,7 @@ pub fn serialize_java_packet( entity_ids: &vec_entity_ids, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CRemoveMobEffect(data) => { @@ -480,34 +488,36 @@ pub fn serialize_java_packet( effect_id: VarInt(data.effect_id), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetBorderCenter(data) => { let p = pumpkin_protocol::java::client::play::CSetBorderCenter { - x: data.x.try_into().unwrap(), - z: data.z.try_into().unwrap(), + x: data.x.try_into().unwrap_or_default(), + z: data.z.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetBorderLerpSize(data) => { let p = pumpkin_protocol::java::client::play::CSetBorderLerpSize { - old_diameter: data.old_diameter.try_into().unwrap(), - new_diameter: data.new_diameter.try_into().unwrap(), - speed: pumpkin_protocol::codec::var_long::VarLong(data.speed.try_into().unwrap()), + old_diameter: data.old_diameter.try_into().unwrap_or_default(), + new_diameter: data.new_diameter.try_into().unwrap_or_default(), + speed: pumpkin_protocol::codec::var_long::VarLong( + data.speed.try_into().unwrap_or_default(), + ), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetBorderSize(data) => { let p = pumpkin_protocol::java::client::play::CSetBorderSize { - diameter: data.diameter.try_into().unwrap(), + diameter: data.diameter.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetBorderWarningDelay(data) => { @@ -515,7 +525,7 @@ pub fn serialize_java_packet( warning_time: VarInt(data.warning_time), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetBorderWarningDistance(data) => { @@ -523,46 +533,46 @@ pub fn serialize_java_packet( warning_blocks: VarInt(data.warning_blocks), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetContainerProperty(data) => { let p = pumpkin_protocol::java::client::play::CSetContainerProperty { window_id: VarInt(data.window_id), - property: data.property.try_into().unwrap(), - value: data.value.try_into().unwrap(), + property: data.property.try_into().unwrap_or_default(), + value: data.value.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetEntityLink(data) => { let p = pumpkin_protocol::java::client::play::CSetEntityLink { - attached_entity_id: data.attached_entity_id.try_into().unwrap(), - holding_entity_id: data.holding_entity_id.try_into().unwrap(), + attached_entity_id: data.attached_entity_id.try_into().unwrap_or_default(), + holding_entity_id: data.holding_entity_id.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetExperience(data) => { let p = pumpkin_protocol::java::client::play::CSetExperience { - progress: data.progress.try_into().unwrap(), + progress: data.progress.try_into().unwrap_or_default(), level: VarInt(data.level), total_experience: VarInt(data.total_experience), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetHealth(data) => { let p = pumpkin_protocol::java::client::play::CSetHealth { - health: data.health.try_into().unwrap(), + health: data.health.try_into().unwrap_or_default(), food: VarInt(data.food), - food_saturation: data.food_saturation.try_into().unwrap(), + food_saturation: data.food_saturation.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSetPassengers(data) => { @@ -572,7 +582,7 @@ pub fn serialize_java_packet( passengers: &vec_passengers, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTitleText(data) => { @@ -581,17 +591,17 @@ pub fn serialize_java_packet( title: &component_title, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTitleAnimation(data) => { let p = pumpkin_protocol::java::client::play::CTitleAnimation { - fade_in_ticks: data.fade_in_ticks.try_into().unwrap(), - stay_ticks: data.stay_ticks.try_into().unwrap(), - fade_out_ticks: data.fade_out_ticks.try_into().unwrap(), + fade_in_ticks: data.fade_in_ticks.try_into().unwrap_or_default(), + stay_ticks: data.stay_ticks.try_into().unwrap_or_default(), + fade_out_ticks: data.fade_out_ticks.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSubtitle(data) => { @@ -600,17 +610,17 @@ pub fn serialize_java_packet( subtitle: &component_subtitle, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CSystemChatMessage(data) => { let component_content = pumpkin_util::text::TextComponent::text(data.content.clone()); let p = pumpkin_protocol::java::client::play::CSystemChatMessage { content: &component_content, - overlay: data.overlay.try_into().unwrap(), + overlay: data.overlay.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTabList(data) => { @@ -621,7 +631,7 @@ pub fn serialize_java_packet( footer: &component_footer, }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTakeItemEntity(data) => { @@ -631,16 +641,16 @@ pub fn serialize_java_packet( stack_amount: VarInt(data.stack_amount), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTickingState(data) => { let p = pumpkin_protocol::java::client::play::CTickingState { - tick_rate: data.tick_rate.try_into().unwrap(), - is_frozen: data.is_frozen.try_into().unwrap(), + tick_rate: data.tick_rate.try_into().unwrap_or_default(), + is_frozen: data.is_frozen.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTickingStep(data) => { @@ -648,7 +658,7 @@ pub fn serialize_java_packet( tick_steps: VarInt(data.tick_steps), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CTransfer(data) => { @@ -657,16 +667,16 @@ pub fn serialize_java_packet( port: VarInt(data.port), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CUnloadChunk(data) => { let p = pumpkin_protocol::java::client::play::CUnloadChunk { - z: data.z.try_into().unwrap(), - x: data.x.try_into().unwrap(), + z: data.z.try_into().unwrap_or_default(), + x: data.x.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CUpdateEntityPos(data) => { @@ -677,10 +687,10 @@ pub fn serialize_java_packet( data.delta.1 as _, data.delta.2 as _, ), - on_ground: data.on_ground.try_into().unwrap(), + on_ground: data.on_ground.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CUpdateEntityPosRot(data) => { @@ -691,23 +701,23 @@ pub fn serialize_java_packet( data.delta.1 as _, data.delta.2 as _, ), - yaw: data.yaw.try_into().unwrap(), - pitch: data.pitch.try_into().unwrap(), - on_ground: data.on_ground.try_into().unwrap(), + yaw: data.yaw.try_into().unwrap_or_default(), + pitch: data.pitch.try_into().unwrap_or_default(), + on_ground: data.on_ground.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CUpdateEntityRot(data) => { let p = pumpkin_protocol::java::client::play::CUpdateEntityRot { entity_id: VarInt(data.entity_id), - yaw: data.yaw.try_into().unwrap(), - pitch: data.pitch.try_into().unwrap(), - on_ground: data.on_ground.try_into().unwrap(), + yaw: data.yaw.try_into().unwrap_or_default(), + pitch: data.pitch.try_into().unwrap_or_default(), + on_ground: data.on_ground.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CUpdateMobEffect(data) => { @@ -716,33 +726,36 @@ pub fn serialize_java_packet( effect_id: VarInt(data.effect_id), amplifier: VarInt(data.amplifier), duration: VarInt(data.duration), - flags: data.flags.try_into().unwrap(), + flags: data.flags.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::CWorldEvent(data) => { let p = pumpkin_protocol::java::client::play::CWorldEvent { - event: data.event.try_into().unwrap(), + event: data.event.try_into().unwrap_or_default(), location: pumpkin_util::math::position::BlockPos::new( data.location.0, data.location.1, data.location.2, ), - data: data.data.try_into().unwrap(), - disable_relative_volume: data.disable_relative_volume.try_into().unwrap(), + data: data.data.try_into().unwrap_or_default(), + disable_relative_volume: data + .disable_relative_volume + .try_into() + .unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::StatusCPingResponse(data) => { let p = pumpkin_protocol::java::client::status::CPingResponse { - payload: data.payload.try_into().unwrap(), + payload: data.payload.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } ClientboundPacket::StatusCStatusResponse(data) => { @@ -750,7 +763,7 @@ pub fn serialize_java_packet( json_response: data.json_response.clone(), }; let mut buf = Vec::new(); - crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap(); + let _ = crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf); Some(buf.into()) } _ => None, @@ -771,20 +784,20 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSClientInformationConfig(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSClientInformationConfig { locale: p.locale.into(), - view_distance: p.view_distance.try_into().unwrap(), - chat_mode: p.chat_mode.0.try_into().unwrap(), - chat_colors: p.chat_colors.try_into().unwrap(), - skin_parts: p.skin_parts.try_into().unwrap(), - main_hand: p.main_hand.0.try_into().unwrap(), - text_filtering: p.text_filtering.try_into().unwrap(), - server_listing: p.server_listing.try_into().unwrap(), + view_distance: p.view_distance.try_into().unwrap_or_default(), + chat_mode: p.chat_mode.0.try_into().unwrap_or_default(), + chat_colors: p.chat_colors.try_into().unwrap_or_default(), + skin_parts: p.skin_parts.try_into().unwrap_or_default(), + main_hand: p.main_hand.0.try_into().unwrap_or_default(), + text_filtering: p.text_filtering.try_into().unwrap_or_default(), + server_listing: p.server_listing.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::config::SKeepAlive::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSKeepAlive(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSKeepAlive { - keep_alive_id: p.keep_alive_id.try_into().unwrap(), + keep_alive_id: p.keep_alive_id.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::config::SPluginMessage::to_id(version) => { @@ -800,22 +813,22 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::ConfigSConfigResourcePack(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSConfigResourcePack { uuid: crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::uuid::Uuid { high: p.uuid.as_u64_pair().1, low: p.uuid.as_u64_pair().0 }, - result: p.result.0.try_into().unwrap(), + result: p.result.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SAttack::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SAttack(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SAttack { - entity_id: p.entity_id.0.try_into().unwrap(), + entity_id: p.entity_id.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SBundleItemSelected::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SBundleItemSelected(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SBundleItemSelected { - slot_id: p.slot_id.0.try_into().unwrap(), - selected_item_index: p.selected_item_index.0.try_into().unwrap(), + slot_id: p.slot_id.0.try_into().unwrap_or_default(), + selected_item_index: p.selected_item_index.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SChatCommand::to_id(version) => { @@ -829,14 +842,14 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SChunkBatch(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SChunkBatch { - chunks_per_tick: p.chunks_per_tick.try_into().unwrap(), + chunks_per_tick: p.chunks_per_tick.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SClientCommand::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SClientCommand(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SClientCommand { - action_id: p.action_id.0.try_into().unwrap(), + action_id: p.action_id.0.try_into().unwrap_or_default(), })) } id if id @@ -846,27 +859,27 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SClientInformationPlay(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SClientInformationPlay { locale: p.locale.into(), - view_distance: p.view_distance.try_into().unwrap(), - chat_mode: p.chat_mode.0.try_into().unwrap(), - chat_colors: p.chat_colors.try_into().unwrap(), - skin_parts: p.skin_parts.try_into().unwrap(), - main_hand: p.main_hand.0.try_into().unwrap(), - text_filtering: p.text_filtering.try_into().unwrap(), - server_listing: p.server_listing.try_into().unwrap(), + view_distance: p.view_distance.try_into().unwrap_or_default(), + chat_mode: p.chat_mode.0.try_into().unwrap_or_default(), + chat_colors: p.chat_colors.try_into().unwrap_or_default(), + skin_parts: p.skin_parts.try_into().unwrap_or_default(), + main_hand: p.main_hand.0.try_into().unwrap_or_default(), + text_filtering: p.text_filtering.try_into().unwrap_or_default(), + server_listing: p.server_listing.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SCloseContainer::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SCloseContainer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SCloseContainer { - window_id: p.window_id.0.try_into().unwrap(), + window_id: p.window_id.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SCommandSuggestion::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SCommandSuggestion(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SCommandSuggestion { - id: p.id.0.try_into().unwrap(), + id: p.id.0.try_into().unwrap_or_default(), command: p.command.into(), })) } @@ -874,15 +887,15 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SConfirmTeleport(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SConfirmTeleport { - teleport_id: p.teleport_id.0.try_into().unwrap(), + teleport_id: p.teleport_id.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SContainerButtonClick::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SContainerButtonClick(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SContainerButtonClick { - window_id: p.window_id.0.try_into().unwrap(), - button_id: p.button_id.0.try_into().unwrap(), + window_id: p.window_id.0.try_into().unwrap_or_default(), + button_id: p.button_id.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SCustomPayload::to_id(version) => { @@ -899,7 +912,7 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SDebugSampleSubscription(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SDebugSampleSubscription { - sample_type: p.sample_type.0.try_into().unwrap(), + sample_type: p.sample_type.0.try_into().unwrap_or_default(), })) } id if id @@ -908,7 +921,7 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SDebugSubscriptionRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SDebugSubscriptionRequest { - sample_type: p.sample_type.0.try_into().unwrap(), + sample_type: p.sample_type.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SJigsawGenerate::to_id(version) => { @@ -916,34 +929,34 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SJigsawGenerate(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SJigsawGenerate { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), - levels: p.levels.0.try_into().unwrap(), - keep_jigsaws: p.keep_jigsaws.try_into().unwrap(), + levels: p.levels.0.try_into().unwrap_or_default(), + keep_jigsaws: p.keep_jigsaws.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SKeepAlive::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SKeepAlive(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SKeepAlive { - keep_alive_id: p.keep_alive_id.try_into().unwrap(), + keep_alive_id: p.keep_alive_id.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SMoveVehicle::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SMoveVehicle(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SMoveVehicle { - x: p.x.try_into().unwrap(), - y: p.y.try_into().unwrap(), - z: p.z.try_into().unwrap(), - yaw: p.yaw.try_into().unwrap(), - pitch: p.pitch.try_into().unwrap(), + x: p.x.try_into().unwrap_or_default(), + y: p.y.try_into().unwrap_or_default(), + z: p.z.try_into().unwrap_or_default(), + yaw: p.yaw.try_into().unwrap_or_default(), + pitch: p.pitch.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPaddleBoat::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPaddleBoat(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPaddleBoat { - left_paddle: p.left_paddle.try_into().unwrap(), - right_paddle: p.right_paddle.try_into().unwrap(), + left_paddle: p.left_paddle.try_into().unwrap_or_default(), + right_paddle: p.right_paddle.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPickItemFromBlock::to_id(version) => { @@ -951,62 +964,62 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPickItemFromBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPickItemFromBlock { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), - include_data: p.include_data.try_into().unwrap(), + include_data: p.include_data.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPickItemFromEntity::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPickItemFromEntity(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPickItemFromEntity { - id: p.id.0.try_into().unwrap(), - include_data: p.include_data.try_into().unwrap(), + id: p.id.0.try_into().unwrap_or_default(), + include_data: p.include_data.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlayPingRequest::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayPingRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayPingRequest { - payload: p.payload.try_into().unwrap(), + payload: p.payload.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlaceRecipe::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlaceRecipe(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlaceRecipe { - container_id: p.container_id.try_into().unwrap(), - recipe_display_id: p.recipe_display_id.0.try_into().unwrap(), - use_max_items: p.use_max_items.try_into().unwrap(), + container_id: p.container_id.try_into().unwrap_or_default(), + recipe_display_id: p.recipe_display_id.0.try_into().unwrap_or_default(), + use_max_items: p.use_max_items.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerAbilities::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerAbilities(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerAbilities { - flags: p.flags.try_into().unwrap(), + flags: p.flags.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerAction::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerAction(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerAction { - status: p.status.0.try_into().unwrap(), + status: p.status.0.try_into().unwrap_or_default(), position: (p.position.0.x, p.position.0.y, p.position.0.z), - face: p.face.try_into().unwrap(), - sequence: p.sequence.0.try_into().unwrap(), + face: p.face.try_into().unwrap_or_default(), + sequence: p.sequence.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SSetPlayerGround::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSetPlayerGround(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetPlayerGround { - on_ground: p.on_ground.try_into().unwrap(), + on_ground: p.on_ground.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerInput::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerInput(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerInput { - input: p.input.try_into().unwrap(), + input: p.input.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerPosition::to_id(version) => { @@ -1014,7 +1027,7 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerPosition(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerPosition { position: (p.position.x as _, p.position.y as _, p.position.z as _), - collision: p.collision.try_into().unwrap(), + collision: p.collision.try_into().unwrap_or_default(), })) } id if id @@ -1024,18 +1037,18 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerPositionRotation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerPositionRotation { position: (p.position.x as _, p.position.y as _, p.position.z as _), - yaw: p.yaw.try_into().unwrap(), - pitch: p.pitch.try_into().unwrap(), - collision: p.collision.try_into().unwrap(), + yaw: p.yaw.try_into().unwrap_or_default(), + pitch: p.pitch.try_into().unwrap_or_default(), + collision: p.collision.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SPlayerRotation::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SPlayerRotation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPlayerRotation { - yaw: p.yaw.try_into().unwrap(), - pitch: p.pitch.try_into().unwrap(), - ground: p.ground.try_into().unwrap(), + yaw: p.yaw.try_into().unwrap_or_default(), + pitch: p.pitch.try_into().unwrap_or_default(), + ground: p.ground.try_into().unwrap_or_default(), })) } id if id @@ -1044,16 +1057,16 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SRecipeBookChangeSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SRecipeBookChangeSettings { - book_type: p.book_type.0.try_into().unwrap(), - is_open: p.is_open.try_into().unwrap(), - is_filtering: p.is_filtering.try_into().unwrap(), + book_type: p.book_type.0.try_into().unwrap_or_default(), + is_open: p.is_open.try_into().unwrap_or_default(), + is_filtering: p.is_filtering.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SRecipeBookSeenRecipe::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SRecipeBookSeenRecipe(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SRecipeBookSeenRecipe { - recipe_display_id: p.recipe_display_id.0.try_into().unwrap(), + recipe_display_id: p.recipe_display_id.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SRenameItem::to_id(version) => { @@ -1075,7 +1088,7 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSelectTrade(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSelectTrade { - selected_slot: p.selected_slot.0.try_into().unwrap(), + selected_slot: p.selected_slot.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SSetCommandBlock::to_id(version) => { @@ -1084,15 +1097,15 @@ pub fn deserialize_java_serverbound_packet( Some(ServerboundPacket::SSetCommandBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetCommandBlock { pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z), command: p.command.into(), - mode: p.mode.0.try_into().unwrap(), - flags: p.flags.try_into().unwrap(), + mode: p.mode.0.try_into().unwrap_or_default(), + flags: p.flags.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SSetHeldItem::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSetHeldItem(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSetHeldItem { - slot: p.slot.try_into().unwrap(), + slot: p.slot.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SSetJigsawBlock::to_id(version) => { @@ -1105,15 +1118,15 @@ pub fn deserialize_java_serverbound_packet( pool: p.pool.into(), final_state: p.final_state.into(), joint: p.joint.into(), - selection_priority: p.selection_priority.0.try_into().unwrap(), - placement_priority: p.placement_priority.0.try_into().unwrap(), + selection_priority: p.selection_priority.0.try_into().unwrap_or_default(), + placement_priority: p.placement_priority.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SSwingArm::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SSwingArm(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SSwingArm { - hand: p.hand.0.try_into().unwrap(), + hand: p.hand.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::STeleportToEntity::to_id(version) => { @@ -1128,7 +1141,7 @@ pub fn deserialize_java_serverbound_packet( let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SUpdateSign(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SUpdateSign { location: (p.location.0.x, p.location.0.y, p.location.0.z), - is_front_text: p.is_front_text.try_into().unwrap(), + is_front_text: p.is_front_text.try_into().unwrap_or_default(), line_1: p.line_1.into(), line_2: p.line_2.into(), line_3: p.line_3.into(), @@ -1139,30 +1152,30 @@ pub fn deserialize_java_serverbound_packet( use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SUseItem(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SUseItem { - hand: p.hand.0.try_into().unwrap(), - sequence: p.sequence.0.try_into().unwrap(), - yaw: p.yaw.try_into().unwrap(), - pitch: p.pitch.try_into().unwrap(), + hand: p.hand.0.try_into().unwrap_or_default(), + sequence: p.sequence.0.try_into().unwrap_or_default(), + yaw: p.yaw.try_into().unwrap_or_default(), + pitch: p.pitch.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::play::SUseItemOn::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::SUseItemOn(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SUseItemOn { - hand: p.hand.0.try_into().unwrap(), + hand: p.hand.0.try_into().unwrap_or_default(), position: (p.position.0.x, p.position.0.y, p.position.0.z), - face: p.face.0.try_into().unwrap(), + face: p.face.0.try_into().unwrap_or_default(), cursor_pos: (p.cursor_pos.x as _, p.cursor_pos.y as _, p.cursor_pos.z as _), - inside_block: p.inside_block.try_into().unwrap(), - is_against_world_border: p.is_against_world_border.try_into().unwrap(), - sequence: p.sequence.0.try_into().unwrap(), + inside_block: p.inside_block.try_into().unwrap_or_default(), + is_against_world_border: p.is_against_world_border.try_into().unwrap_or_default(), + sequence: p.sequence.0.try_into().unwrap_or_default(), })) } id if id == pumpkin_protocol::java::server::status::SStatusPingRequest::to_id(version) => { use pumpkin_protocol::ServerPacket; let p = ::read(&mut payload, &version).ok()?; Some(ServerboundPacket::StatusSStatusPingRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::StatusSStatusPingRequest { - payload: p.payload.try_into().unwrap(), + payload: p.payload.try_into().unwrap_or_default(), })) } _ => None, @@ -1194,7 +1207,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::config::CTransfer< fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::ConfigCTransfer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigCTransfer { host: self.host.to_string(), - port: self.port.0.try_into().unwrap(), + port: self.port.0.try_into().unwrap_or_default(), }) } } @@ -1205,7 +1218,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::login::CEncryption server_id: self.server_id.to_string(), public_key: self.public_key.iter().map(|v| *v as _).collect(), verify_token: self.verify_token.iter().map(|v| *v as _).collect(), - should_authenticate: self.should_authenticate.try_into().unwrap(), + should_authenticate: self.should_authenticate.try_into().unwrap_or_default(), }) } } @@ -1221,7 +1234,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::login::CLoginDisco impl ToWitClientboundJava for pumpkin_protocol::java::client::login::CLoginPluginRequest<'_> { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::LoginCLoginPluginRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::LoginCLoginPluginRequest { - message_id: self.message_id.0.try_into().unwrap(), + message_id: self.message_id.0.try_into().unwrap_or_default(), channel: self.channel.to_string(), data: self.data.iter().map(|v| *v as _).collect(), }) @@ -1231,7 +1244,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::login::CLoginPlugi impl ToWitClientboundJava for pumpkin_protocol::java::client::login::CSetCompression { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::LoginCSetCompression(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::LoginCSetCompression { - threshold: self.threshold.0.try_into().unwrap(), + threshold: self.threshold.0.try_into().unwrap_or_default(), }) } } @@ -1239,7 +1252,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::login::CSetCompres impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CAcknowledgeBlockChange { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CAcknowledgeBlockChange(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CAcknowledgeBlockChange { - sequence_id: self.sequence_id.0.try_into().unwrap(), + sequence_id: self.sequence_id.0.try_into().unwrap_or_default(), }) } } @@ -1255,9 +1268,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CActionBar<' impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBlockDestroyStage { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetBlockDestroyStage(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetBlockDestroyStage { - entity_id: self.entity_id.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), location: (self.location.0.x, self.location.0.y, self.location.0.z), - destroy_stage: self.destroy_stage.try_into().unwrap(), + destroy_stage: self.destroy_stage.try_into().unwrap_or_default(), }) } } @@ -1266,9 +1279,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CBlockEvent fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CBlockEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CBlockEvent { location: (self.location.0.x, self.location.0.y, self.location.0.z), - action_id: self.action_id.try_into().unwrap(), - action_parameter: self.action_parameter.try_into().unwrap(), - block_type: self.block_type.0.try_into().unwrap(), + action_id: self.action_id.try_into().unwrap_or_default(), + action_parameter: self.action_parameter.try_into().unwrap_or_default(), + block_type: self.block_type.0.try_into().unwrap_or_default(), }) } } @@ -1277,7 +1290,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CBlockUpdate fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CBlockUpdate(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CBlockUpdate { location: (self.location.0.x, self.location.0.y, self.location.0.z), - state_id: self.state_id.0.try_into().unwrap(), + state_id: self.state_id.0.try_into().unwrap_or_default(), }) } } @@ -1285,8 +1298,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CBlockUpdate impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CCenterChunk { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CCenterChunk(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CCenterChunk { - chunk_x: self.chunk_x.0.try_into().unwrap(), - chunk_z: self.chunk_z.0.try_into().unwrap(), + chunk_x: self.chunk_x.0.try_into().unwrap_or_default(), + chunk_z: self.chunk_z.0.try_into().unwrap_or_default(), }) } } @@ -1294,8 +1307,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CCenterChunk impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CChangeDifficulty { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CChangeDifficulty(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CChangeDifficulty { - difficulty: self.difficulty.try_into().unwrap(), - locked: self.locked.try_into().unwrap(), + difficulty: self.difficulty.try_into().unwrap_or_default(), + locked: self.locked.try_into().unwrap_or_default(), }) } } @@ -1303,7 +1316,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CChangeDiffi impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CChunkBatchEnd { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CChunkBatchEnd(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CChunkBatchEnd { - batch_size: self.batch_size.0.try_into().unwrap(), + batch_size: self.batch_size.0.try_into().unwrap_or_default(), }) } } @@ -1311,7 +1324,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CChunkBatchE impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CClearTitle { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CClearTitle(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CClearTitle { - reset: self.reset.try_into().unwrap(), + reset: self.reset.try_into().unwrap_or_default(), }) } } @@ -1319,7 +1332,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CClearTitle impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CCloseContainer { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CCloseContainer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CCloseContainer { - sync_id: self.sync_id.0.try_into().unwrap(), + sync_id: self.sync_id.0.try_into().unwrap_or_default(), }) } } @@ -1327,7 +1340,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CCloseContai impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CCombatDeath<'_> { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CCombatDeath(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CCombatDeath { - player_id: self.player_id.0.try_into().unwrap(), + player_id: self.player_id.0.try_into().unwrap_or_default(), message: serde_json::to_string(&self.message).unwrap_or_default(), }) } @@ -1346,7 +1359,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CDebugSample fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CDebugSample(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CDebugSample { sample: self.sample.iter().map(|v| *v as _).collect(), - sample_type: self.sample_type.0.try_into().unwrap(), + sample_type: self.sample_type.0.try_into().unwrap_or_default(), }) } } @@ -1362,7 +1375,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPlayDisconn impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CDisplayObjective { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CDisplayObjective(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CDisplayObjective { - position: self.position.0.try_into().unwrap(), + position: self.position.0.try_into().unwrap_or_default(), score_name: self.score_name.to_string(), }) } @@ -1371,8 +1384,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CDisplayObje impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityAnimation { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CEntityAnimation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CEntityAnimation { - entity_id: self.entity_id.0.try_into().unwrap(), - animation: self.animation.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + animation: self.animation.try_into().unwrap_or_default(), }) } } @@ -1380,12 +1393,12 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityAnima impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityPositionSync { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CEntityPositionSync(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CEntityPositionSync { - entity_id: self.entity_id.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), delta: (self.delta.x as _, self.delta.y as _, self.delta.z as _), - yaw: self.yaw.try_into().unwrap(), - pitch: self.pitch.try_into().unwrap(), - on_ground: self.on_ground.try_into().unwrap(), + yaw: self.yaw.try_into().unwrap_or_default(), + pitch: self.pitch.try_into().unwrap_or_default(), + on_ground: self.on_ground.try_into().unwrap_or_default(), }) } } @@ -1393,8 +1406,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityPosit impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityStatus { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CEntityStatus(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CEntityStatus { - entity_id: self.entity_id.try_into().unwrap(), - entity_status: self.entity_status.try_into().unwrap(), + entity_id: self.entity_id.try_into().unwrap_or_default(), + entity_status: self.entity_status.try_into().unwrap_or_default(), }) } } @@ -1402,8 +1415,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityStatu impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CGameEvent { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CGameEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CGameEvent { - event: self.event.try_into().unwrap(), - value: self.value.try_into().unwrap(), + event: self.event.try_into().unwrap_or_default(), + value: self.value.try_into().unwrap_or_default(), }) } } @@ -1411,8 +1424,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CGameEvent { impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CHeadRot { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CHeadRot(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CHeadRot { - entity_id: self.entity_id.0.try_into().unwrap(), - head_yaw: self.head_yaw.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + head_yaw: self.head_yaw.try_into().unwrap_or_default(), }) } } @@ -1420,8 +1433,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CHeadRot { impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CHurtAnimation { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CHurtAnimation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CHurtAnimation { - entity_id: self.entity_id.0.try_into().unwrap(), - yaw: self.yaw.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + yaw: self.yaw.try_into().unwrap_or_default(), }) } } @@ -1429,14 +1442,14 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CHurtAnimati impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CInitializeWorldBorder { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CInitializeWorldBorder(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CInitializeWorldBorder { - x: self.x.try_into().unwrap(), - z: self.z.try_into().unwrap(), - old_diameter: self.old_diameter.try_into().unwrap(), - new_diameter: self.new_diameter.try_into().unwrap(), - speed: self.speed.0.try_into().unwrap(), - portal_teleport_boundary: self.portal_teleport_boundary.0.try_into().unwrap(), - warning_blocks: self.warning_blocks.0.try_into().unwrap(), - warning_time: self.warning_time.0.try_into().unwrap(), + x: self.x.try_into().unwrap_or_default(), + z: self.z.try_into().unwrap_or_default(), + old_diameter: self.old_diameter.try_into().unwrap_or_default(), + new_diameter: self.new_diameter.try_into().unwrap_or_default(), + speed: self.speed.0.try_into().unwrap_or_default(), + portal_teleport_boundary: self.portal_teleport_boundary.0.try_into().unwrap_or_default(), + warning_blocks: self.warning_blocks.0.try_into().unwrap_or_default(), + warning_time: self.warning_time.0.try_into().unwrap_or_default(), }) } } @@ -1445,7 +1458,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CItemCooldow fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CItemCooldown(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CItemCooldown { group: self.group.to_string(), - cooldown: self.cooldown.0.try_into().unwrap(), + cooldown: self.cooldown.0.try_into().unwrap_or_default(), }) } } @@ -1453,7 +1466,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CItemCooldow impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CKeepAlive { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CKeepAlive(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CKeepAlive { - keep_alive_id: self.keep_alive_id.try_into().unwrap(), + keep_alive_id: self.keep_alive_id.try_into().unwrap_or_default(), }) } } @@ -1461,10 +1474,10 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CKeepAlive { impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CLevelEvent { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CLevelEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CLevelEvent { - event: self.event.try_into().unwrap(), + event: self.event.try_into().unwrap_or_default(), location: (self.location.0.x, self.location.0.y, self.location.0.z), - data: self.data.try_into().unwrap(), - disable_relative_volume: self.disable_relative_volume.try_into().unwrap(), + data: self.data.try_into().unwrap_or_default(), + disable_relative_volume: self.disable_relative_volume.try_into().unwrap_or_default(), }) } } @@ -1472,8 +1485,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CLevelEvent impl ToWitClientboundJava for pumpkin_protocol::java::client::play::COpenScreen<'_> { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::COpenScreen(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::COpenScreen { - sync_id: self.sync_id.0.try_into().unwrap(), - window_type: self.window_type.0.try_into().unwrap(), + sync_id: self.sync_id.0.try_into().unwrap_or_default(), + window_type: self.window_type.0.try_into().unwrap_or_default(), window_title: serde_json::to_string(&self.window_title).unwrap_or_default(), }) } @@ -1483,7 +1496,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::COpenSignEdi fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::COpenSignEditor(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::COpenSignEditor { location: (self.location.0.x, self.location.0.y, self.location.0.z), - is_front_text: self.is_front_text.try_into().unwrap(), + is_front_text: self.is_front_text.try_into().unwrap_or_default(), }) } } @@ -1491,13 +1504,13 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::COpenSignEdi impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CParticle<'_> { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CParticle(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CParticle { - force_spawn: self.force_spawn.try_into().unwrap(), - important: self.important.try_into().unwrap(), + force_spawn: self.force_spawn.try_into().unwrap_or_default(), + important: self.important.try_into().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), offset: (self.offset.x as _, self.offset.y as _, self.offset.z as _), - max_speed: self.max_speed.try_into().unwrap(), - particle_count: self.particle_count.try_into().unwrap(), - particle_id: self.particle_id.0.try_into().unwrap(), + max_speed: self.max_speed.try_into().unwrap_or_default(), + particle_count: self.particle_count.try_into().unwrap_or_default(), + particle_id: self.particle_id.0.try_into().unwrap_or_default(), data: self.data.iter().map(|v| *v as _).collect(), }) } @@ -1506,7 +1519,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CParticle<'_ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPingResponse { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CPingResponse(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CPingResponse { - payload: self.payload.try_into().unwrap(), + payload: self.payload.try_into().unwrap_or_default(), }) } } @@ -1514,9 +1527,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPingRespons impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPlayerAbilities { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CPlayerAbilities(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CPlayerAbilities { - flags: self.flags.try_into().unwrap(), - flying_speed: self.flying_speed.try_into().unwrap(), - field_of_view: self.field_of_view.try_into().unwrap(), + flags: self.flags.try_into().unwrap_or_default(), + flying_speed: self.flying_speed.try_into().unwrap_or_default(), + field_of_view: self.field_of_view.try_into().unwrap_or_default(), }) } } @@ -1534,8 +1547,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPlayerSpawn ClientboundPacket::CPlayerSpawnPosition(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CPlayerSpawnPosition { dimension_name: self.dimension_name.to_string(), location: (self.location.0.x, self.location.0.y, self.location.0.z), - yaw: self.yaw.try_into().unwrap(), - pitch: self.pitch.try_into().unwrap(), + yaw: self.yaw.try_into().unwrap_or_default(), + pitch: self.pitch.try_into().unwrap_or_default(), }) } } @@ -1543,14 +1556,14 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPlayerSpawn impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CRecipeBookSettings { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CRecipeBookSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CRecipeBookSettings { - crafting_open: self.crafting_open.try_into().unwrap(), - crafting_filtering: self.crafting_filtering.try_into().unwrap(), - furnace_open: self.furnace_open.try_into().unwrap(), - furnace_filtering: self.furnace_filtering.try_into().unwrap(), - blast_furnace_open: self.blast_furnace_open.try_into().unwrap(), - blast_furnace_filtering: self.blast_furnace_filtering.try_into().unwrap(), - smoker_open: self.smoker_open.try_into().unwrap(), - smoker_filtering: self.smoker_filtering.try_into().unwrap(), + crafting_open: self.crafting_open.try_into().unwrap_or_default(), + crafting_filtering: self.crafting_filtering.try_into().unwrap_or_default(), + furnace_open: self.furnace_open.try_into().unwrap_or_default(), + furnace_filtering: self.furnace_filtering.try_into().unwrap_or_default(), + blast_furnace_open: self.blast_furnace_open.try_into().unwrap_or_default(), + blast_furnace_filtering: self.blast_furnace_filtering.try_into().unwrap_or_default(), + smoker_open: self.smoker_open.try_into().unwrap_or_default(), + smoker_filtering: self.smoker_filtering.try_into().unwrap_or_default(), }) } } @@ -1566,8 +1579,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CRemoveEntit impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CRemoveMobEffect { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CRemoveMobEffect(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CRemoveMobEffect { - entity_id: self.entity_id.0.try_into().unwrap(), - effect_id: self.effect_id.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + effect_id: self.effect_id.0.try_into().unwrap_or_default(), }) } } @@ -1575,8 +1588,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CRemoveMobEf impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderCenter { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetBorderCenter(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetBorderCenter { - x: self.x.try_into().unwrap(), - z: self.z.try_into().unwrap(), + x: self.x.try_into().unwrap_or_default(), + z: self.z.try_into().unwrap_or_default(), }) } } @@ -1584,9 +1597,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderCe impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderLerpSize { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetBorderLerpSize(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetBorderLerpSize { - old_diameter: self.old_diameter.try_into().unwrap(), - new_diameter: self.new_diameter.try_into().unwrap(), - speed: self.speed.0.try_into().unwrap(), + old_diameter: self.old_diameter.try_into().unwrap_or_default(), + new_diameter: self.new_diameter.try_into().unwrap_or_default(), + speed: self.speed.0.try_into().unwrap_or_default(), }) } } @@ -1594,7 +1607,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderLe impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderSize { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetBorderSize(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetBorderSize { - diameter: self.diameter.try_into().unwrap(), + diameter: self.diameter.try_into().unwrap_or_default(), }) } } @@ -1602,7 +1615,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderSi impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderWarningDelay { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetBorderWarningDelay(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetBorderWarningDelay { - warning_time: self.warning_time.0.try_into().unwrap(), + warning_time: self.warning_time.0.try_into().unwrap_or_default(), }) } } @@ -1610,7 +1623,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderWa impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderWarningDistance { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetBorderWarningDistance(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetBorderWarningDistance { - warning_blocks: self.warning_blocks.0.try_into().unwrap(), + warning_blocks: self.warning_blocks.0.try_into().unwrap_or_default(), }) } } @@ -1618,9 +1631,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBorderWa impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetContainerProperty { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetContainerProperty(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetContainerProperty { - window_id: self.window_id.0.try_into().unwrap(), - property: self.property.try_into().unwrap(), - value: self.value.try_into().unwrap(), + window_id: self.window_id.0.try_into().unwrap_or_default(), + property: self.property.try_into().unwrap_or_default(), + value: self.value.try_into().unwrap_or_default(), }) } } @@ -1628,8 +1641,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetContaine impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetEntityLink { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetEntityLink(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetEntityLink { - attached_entity_id: self.attached_entity_id.try_into().unwrap(), - holding_entity_id: self.holding_entity_id.try_into().unwrap(), + attached_entity_id: self.attached_entity_id.try_into().unwrap_or_default(), + holding_entity_id: self.holding_entity_id.try_into().unwrap_or_default(), }) } } @@ -1637,9 +1650,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetEntityLi impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetExperience { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetExperience(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetExperience { - progress: self.progress.try_into().unwrap(), - level: self.level.0.try_into().unwrap(), - total_experience: self.total_experience.0.try_into().unwrap(), + progress: self.progress.try_into().unwrap_or_default(), + level: self.level.0.try_into().unwrap_or_default(), + total_experience: self.total_experience.0.try_into().unwrap_or_default(), }) } } @@ -1647,9 +1660,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetExperien impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetHealth { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetHealth(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetHealth { - health: self.health.try_into().unwrap(), - food: self.food.0.try_into().unwrap(), - food_saturation: self.food_saturation.try_into().unwrap(), + health: self.health.try_into().unwrap_or_default(), + food: self.food.0.try_into().unwrap_or_default(), + food_saturation: self.food_saturation.try_into().unwrap_or_default(), }) } } @@ -1657,7 +1670,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetHealth { impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetPassengers<'_> { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSetPassengers(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetPassengers { - entity_id: self.entity_id.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), passengers: self.passengers.iter().map(|v| v.0 as _).collect(), }) } @@ -1674,9 +1687,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTitleText<' impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTitleAnimation { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CTitleAnimation(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CTitleAnimation { - fade_in_ticks: self.fade_in_ticks.try_into().unwrap(), - stay_ticks: self.stay_ticks.try_into().unwrap(), - fade_out_ticks: self.fade_out_ticks.try_into().unwrap(), + fade_in_ticks: self.fade_in_ticks.try_into().unwrap_or_default(), + stay_ticks: self.stay_ticks.try_into().unwrap_or_default(), + fade_out_ticks: self.fade_out_ticks.try_into().unwrap_or_default(), }) } } @@ -1693,7 +1706,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSystemChatM fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CSystemChatMessage(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSystemChatMessage { content: serde_json::to_string(&self.content).unwrap_or_default(), - overlay: self.overlay.try_into().unwrap(), + overlay: self.overlay.try_into().unwrap_or_default(), }) } } @@ -1710,9 +1723,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTabList<'_> impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTakeItemEntity { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CTakeItemEntity(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CTakeItemEntity { - entity_id: self.entity_id.0.try_into().unwrap(), - collector_entity_id: self.collector_entity_id.0.try_into().unwrap(), - stack_amount: self.stack_amount.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + collector_entity_id: self.collector_entity_id.0.try_into().unwrap_or_default(), + stack_amount: self.stack_amount.0.try_into().unwrap_or_default(), }) } } @@ -1720,8 +1733,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTakeItemEnt impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTickingState { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CTickingState(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CTickingState { - tick_rate: self.tick_rate.try_into().unwrap(), - is_frozen: self.is_frozen.try_into().unwrap(), + tick_rate: self.tick_rate.try_into().unwrap_or_default(), + is_frozen: self.is_frozen.try_into().unwrap_or_default(), }) } } @@ -1729,7 +1742,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTickingStat impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTickingStep { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CTickingStep(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CTickingStep { - tick_steps: self.tick_steps.0.try_into().unwrap(), + tick_steps: self.tick_steps.0.try_into().unwrap_or_default(), }) } } @@ -1738,7 +1751,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTransfer<'_ fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CTransfer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CTransfer { host: self.host.to_string(), - port: self.port.0.try_into().unwrap(), + port: self.port.0.try_into().unwrap_or_default(), }) } } @@ -1746,8 +1759,8 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CTransfer<'_ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUnloadChunk { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CUnloadChunk(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CUnloadChunk { - z: self.z.try_into().unwrap(), - x: self.x.try_into().unwrap(), + z: self.z.try_into().unwrap_or_default(), + x: self.x.try_into().unwrap_or_default(), }) } } @@ -1755,9 +1768,9 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUnloadChunk impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateEntityPos { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CUpdateEntityPos(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CUpdateEntityPos { - entity_id: self.entity_id.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), delta: (self.delta.x as _, self.delta.y as _, self.delta.z as _), - on_ground: self.on_ground.try_into().unwrap(), + on_ground: self.on_ground.try_into().unwrap_or_default(), }) } } @@ -1765,11 +1778,11 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateEntit impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateEntityPosRot { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CUpdateEntityPosRot(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CUpdateEntityPosRot { - entity_id: self.entity_id.0.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), delta: (self.delta.x as _, self.delta.y as _, self.delta.z as _), - yaw: self.yaw.try_into().unwrap(), - pitch: self.pitch.try_into().unwrap(), - on_ground: self.on_ground.try_into().unwrap(), + yaw: self.yaw.try_into().unwrap_or_default(), + pitch: self.pitch.try_into().unwrap_or_default(), + on_ground: self.on_ground.try_into().unwrap_or_default(), }) } } @@ -1777,10 +1790,10 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateEntit impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateEntityRot { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CUpdateEntityRot(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CUpdateEntityRot { - entity_id: self.entity_id.0.try_into().unwrap(), - yaw: self.yaw.try_into().unwrap(), - pitch: self.pitch.try_into().unwrap(), - on_ground: self.on_ground.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + yaw: self.yaw.try_into().unwrap_or_default(), + pitch: self.pitch.try_into().unwrap_or_default(), + on_ground: self.on_ground.try_into().unwrap_or_default(), }) } } @@ -1788,11 +1801,11 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateEntit impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateMobEffect { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CUpdateMobEffect(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CUpdateMobEffect { - entity_id: self.entity_id.0.try_into().unwrap(), - effect_id: self.effect_id.0.try_into().unwrap(), - amplifier: self.amplifier.0.try_into().unwrap(), - duration: self.duration.0.try_into().unwrap(), - flags: self.flags.try_into().unwrap(), + entity_id: self.entity_id.0.try_into().unwrap_or_default(), + effect_id: self.effect_id.0.try_into().unwrap_or_default(), + amplifier: self.amplifier.0.try_into().unwrap_or_default(), + duration: self.duration.0.try_into().unwrap_or_default(), + flags: self.flags.try_into().unwrap_or_default(), }) } } @@ -1800,10 +1813,10 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateMobEf impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CWorldEvent { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::CWorldEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CWorldEvent { - event: self.event.try_into().unwrap(), + event: self.event.try_into().unwrap_or_default(), location: (self.location.0.x, self.location.0.y, self.location.0.z), - data: self.data.try_into().unwrap(), - disable_relative_volume: self.disable_relative_volume.try_into().unwrap(), + data: self.data.try_into().unwrap_or_default(), + disable_relative_volume: self.disable_relative_volume.try_into().unwrap_or_default(), }) } } @@ -1811,7 +1824,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CWorldEvent impl ToWitClientboundJava for pumpkin_protocol::java::client::status::CPingResponse { fn to_wit(&self) -> ClientboundPacket { ClientboundPacket::StatusCPingResponse(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::StatusCPingResponse { - payload: self.payload.try_into().unwrap(), + payload: self.payload.try_into().unwrap_or_default(), }) } } @@ -2074,11 +2087,11 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { data.position.1 as _, data.position.2 as _, ), - respawn: data.respawn.try_into().unwrap(), + respawn: data.respawn.try_into().unwrap_or_default(), loading_screen_id: data.has_loading_screen_id.then_some(0), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CChunkRadiusUpdate(data) => { @@ -2086,29 +2099,29 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { chunk_radius: VarInt(data.chunk_radius), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CContainerOpen(data) => { let p = pumpkin_protocol::bedrock::client::CContainerOpen { - container_id: data.container_id.try_into().unwrap(), - container_type: data.container_type.try_into().unwrap(), + container_id: data.container_id.try_into().unwrap_or_default(), + container_type: data.container_type.try_into().unwrap_or_default(), position: pumpkin_util::math::position::BlockPos::new( data.position.0, data.position.1, data.position.2, ), target_entity_id: pumpkin_protocol::codec::var_long::VarLong( - data.target_entity_id.try_into().unwrap(), + data.target_entity_id.try_into().unwrap_or_default(), ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CCorrectPlayerMove(data) => { let p = pumpkin_protocol::bedrock::client::CCorrectPlayerMove { - prediction_type: data.prediction_type.try_into().unwrap(), + prediction_type: data.prediction_type.try_into().unwrap_or_default(), pos: pumpkin_util::math::vector3::Vector3::new( data.pos.0 as _, data.pos.1 as _, @@ -2121,22 +2134,24 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { ), rotation: pumpkin_util::math::vector2::Vector2::new(0.0, 0.0), vehicle_angular_velocity: None, - on_ground: data.on_ground.try_into().unwrap(), - tick: pumpkin_protocol::codec::var_ulong::VarULong(data.tick.try_into().unwrap()), + on_ground: data.on_ground.try_into().unwrap_or_default(), + tick: pumpkin_protocol::codec::var_ulong::VarULong( + data.tick.try_into().unwrap_or_default(), + ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CDisconnectPlayer(data) => { let p = pumpkin_protocol::bedrock::client::CDisconnectPlayer { reason: VarInt(data.reason), - skip_message: data.skip_message.try_into().unwrap(), + skip_message: data.skip_message.try_into().unwrap_or_default(), message: data.message.clone(), filtered_message: data.filtered_message.clone(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CLevelEvent(data) => { @@ -2150,7 +2165,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { data: VarInt(data.data), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CLevelSoundEvent(data) => { @@ -2164,96 +2179,107 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { position, extra_data: VarInt(data.extra_data), entity_type: data.entity_type.clone(), - is_baby_mob: data.is_baby_mob.try_into().unwrap(), - is_global: data.is_global.try_into().unwrap(), + is_baby_mob: data.is_baby_mob.try_into().unwrap_or_default(), + is_global: data.is_global.try_into().unwrap_or_default(), actor_unique_id: 0, fire_at_position: Some(position), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CModalFormRequest(data) => { let p = pumpkin_protocol::bedrock::client::CModalFormRequest { - form_id: VarUInt(data.form_id.try_into().unwrap()), + form_id: VarUInt(data.form_id.try_into().unwrap_or_default()), form_data: data.form_data.clone(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CMoveActorAbsolute(data) => { let p = pumpkin_protocol::bedrock::client::CMoveActorAbsolute { entity_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.entity_runtime_id.try_into().unwrap(), + data.entity_runtime_id.try_into().unwrap_or_default(), ), - flags: data.flags.try_into().unwrap(), + flags: data.flags.try_into().unwrap_or_default(), position: pumpkin_util::math::vector3::Vector3::new( data.position.0 as _, data.position.1 as _, data.position.2 as _, ), - pitch: data.pitch.try_into().unwrap(), - yaw: data.yaw.try_into().unwrap(), - head_yaw: data.head_yaw.try_into().unwrap(), + pitch: data.pitch.try_into().unwrap_or_default(), + yaw: data.yaw.try_into().unwrap_or_default(), + head_yaw: data.head_yaw.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CMoveActorDelta(data) => { let p = pumpkin_protocol::bedrock::client::CMoveActorDelta { entity_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.entity_runtime_id.try_into().unwrap(), + data.entity_runtime_id.try_into().unwrap_or_default(), ), - flags: data.flags.try_into().unwrap(), - x: data.x.try_into().unwrap(), - y: data.y.try_into().unwrap(), - z: data.z.try_into().unwrap(), - pitch: data.pitch.try_into().unwrap(), - yaw: data.yaw.try_into().unwrap(), - head_yaw: data.head_yaw.try_into().unwrap(), + flags: data.flags.try_into().unwrap_or_default(), + x: data.x.try_into().unwrap_or_default(), + y: data.y.try_into().unwrap_or_default(), + z: data.z.try_into().unwrap_or_default(), + pitch: data.pitch.try_into().unwrap_or_default(), + yaw: data.yaw.try_into().unwrap_or_default(), + head_yaw: data.head_yaw.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CMovePlayer(data) => { let p = pumpkin_protocol::bedrock::client::CMovePlayer { player_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.player_runtime_id.try_into().unwrap(), + data.player_runtime_id.try_into().unwrap_or_default(), ), position: pumpkin_util::math::vector3::Vector3::new( data.position.0 as _, data.position.1 as _, data.position.2 as _, ), - pitch: data.pitch.try_into().unwrap(), - yaw: data.yaw.try_into().unwrap(), - head_yaw: data.head_yaw.try_into().unwrap(), - mode: data.mode.try_into().unwrap(), - on_ground: data.on_ground.try_into().unwrap(), + pitch: data.pitch.try_into().unwrap_or_default(), + yaw: data.yaw.try_into().unwrap_or_default(), + head_yaw: data.head_yaw.try_into().unwrap_or_default(), + mode: data.mode.try_into().unwrap_or_default(), + on_ground: data.on_ground.try_into().unwrap_or_default(), riding_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.riding_runtime_id.try_into().unwrap(), + data.riding_runtime_id.try_into().unwrap_or_default(), + ), + teleport_cause: data.teleport_cause.try_into().unwrap_or_default(), + teleport_source_entity_type: data + .teleport_source_entity_type + .try_into() + .unwrap_or_default(), + tick: pumpkin_protocol::codec::var_ulong::VarULong( + data.tick.try_into().unwrap_or_default(), ), - teleport_cause: data.teleport_cause.try_into().unwrap(), - teleport_source_entity_type: data.teleport_source_entity_type.try_into().unwrap(), - tick: pumpkin_protocol::codec::var_ulong::VarULong(data.tick.try_into().unwrap()), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CNetworkSettings(data) => { let p = pumpkin_protocol::bedrock::client::CNetworkSettings { - compression_threshold: data.compression_threshold.try_into().unwrap(), - compression_method: data.compression_method.try_into().unwrap(), - client_throttle_enabled: data.client_throttle_enabled.try_into().unwrap(), - client_throttle_threshold: data.client_throttle_threshold.try_into().unwrap(), - client_throttle_scalar: data.client_throttle_scalar.try_into().unwrap(), + compression_threshold: data.compression_threshold.try_into().unwrap_or_default(), + compression_method: data.compression_method.try_into().unwrap_or_default(), + client_throttle_enabled: data + .client_throttle_enabled + .try_into() + .unwrap_or_default(), + client_throttle_threshold: data + .client_throttle_threshold + .try_into() + .unwrap_or_default(), + client_throttle_scalar: data.client_throttle_scalar.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CPlayStatus(data) => { @@ -2270,29 +2296,29 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CPlayStatus::EditorMismatchVanillaToEditor => pumpkin_protocol::bedrock::client::CPlayStatus::EditorMismatchVanillaToEditor, }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CPlayerHotbar(data) => { let p = pumpkin_protocol::bedrock::client::CPlayerHotbar { selected_slot: pumpkin_protocol::codec::var_uint::VarUInt( - data.selected_slot.try_into().unwrap(), + data.selected_slot.try_into().unwrap_or_default(), ), - container_id: data.container_id.try_into().unwrap(), - should_select_block: data.should_select_block.try_into().unwrap(), + container_id: data.container_id.try_into().unwrap_or_default(), + should_select_block: data.should_select_block.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CRemoveActor(data) => { let p = pumpkin_protocol::bedrock::client::CRemoveActor { entity_unique_id: pumpkin_protocol::codec::var_long::VarLong( - data.entity_unique_id.try_into().unwrap(), + data.entity_unique_id.try_into().unwrap_or_default(), ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetDisplayObjective(data) => { @@ -2304,7 +2330,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { sort_order: VarInt(data.sort_order), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CRemoveObjective(data) => { @@ -2312,33 +2338,35 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { objective_name: data.objective_name.clone(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetActorMotion(data) => { let p = pumpkin_protocol::bedrock::client::CSetActorMotion { target_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.target_runtime_id.try_into().unwrap(), + data.target_runtime_id.try_into().unwrap_or_default(), ), motion: pumpkin_util::math::vector3::Vector3::new( data.motion.0 as _, data.motion.1 as _, data.motion.2 as _, ), - tick: pumpkin_protocol::codec::var_ulong::VarULong(data.tick.try_into().unwrap()), + tick: pumpkin_protocol::codec::var_ulong::VarULong( + data.tick.try_into().unwrap_or_default(), + ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetDifficulty(data) => { let p = pumpkin_protocol::bedrock::client::CSetDifficulty { difficulty: pumpkin_protocol::codec::var_uint::VarUInt( - data.difficulty.try_into().unwrap(), + data.difficulty.try_into().unwrap_or_default(), ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetHealth(data) => { @@ -2346,7 +2374,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { health: VarInt(data.health), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetSpawnPosition(data) => { @@ -2365,7 +2393,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetTime(data) => { @@ -2373,7 +2401,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { time: VarInt(data.time), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CSetTitle(data) => { @@ -2388,41 +2416,41 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { filtered_message: data.filtered_message.clone(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CShowCredits(data) => { let p = pumpkin_protocol::bedrock::client::CShowCredits { player_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.player_runtime_id.try_into().unwrap(), + data.player_runtime_id.try_into().unwrap_or_default(), ), status: VarInt(data.status), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CTakeItemActor(data) => { let p = pumpkin_protocol::bedrock::client::CTakeItemActor { item_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.item_runtime_id.try_into().unwrap(), + data.item_runtime_id.try_into().unwrap_or_default(), ), actor_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.actor_runtime_id.try_into().unwrap(), + data.actor_runtime_id.try_into().unwrap_or_default(), ), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CTransfer(data) => { let p = pumpkin_protocol::bedrock::client::CTransfer { address: data.address.clone(), - port: data.port.try_into().unwrap(), - reload_world: data.reload_world.try_into().unwrap(), + port: data.port.try_into().unwrap_or_default(), + reload_world: data.reload_world.try_into().unwrap_or_default(), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } BClientboundPacket::CUpdateBlock(data) => { @@ -2433,13 +2461,17 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { data.position.2, ), block_runtime_id: pumpkin_protocol::codec::var_uint::VarUInt( - data.block_runtime_id.try_into().unwrap(), + data.block_runtime_id.try_into().unwrap_or_default(), + ), + flags: pumpkin_protocol::codec::var_uint::VarUInt( + data.flags.try_into().unwrap_or_default(), + ), + layer: pumpkin_protocol::codec::var_uint::VarUInt( + data.layer.try_into().unwrap_or_default(), ), - flags: pumpkin_protocol::codec::var_uint::VarUInt(data.flags.try_into().unwrap()), - layer: pumpkin_protocol::codec::var_uint::VarUInt(data.layer.try_into().unwrap()), }; let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + let _ = crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf); Some(buf.into()) } _ => None, @@ -2457,74 +2489,74 @@ pub fn deserialize_bedrock_serverbound_packet( let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SBlockPickRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SBlockPickRequest { block_pos: (p.block_pos.0.x, p.block_pos.0.y, p.block_pos.0.z), - add_block_nbt: p.add_block_nbt.try_into().unwrap(), - hotbar_slot: p.hotbar_slot.try_into().unwrap(), + add_block_nbt: p.add_block_nbt.try_into().unwrap_or_default(), + hotbar_slot: p.hotbar_slot.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SClientCacheStatus(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SClientCacheStatus { - cache_supported: p.cache_supported.try_into().unwrap(), + cache_supported: p.cache_supported.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SContainerClose(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SContainerClose { - container_id: p.container_id.try_into().unwrap(), - container_type: p.container_type.try_into().unwrap(), - server_initiated: p.server_initiated.try_into().unwrap(), + container_id: p.container_id.try_into().unwrap_or_default(), + container_type: p.container_type.try_into().unwrap_or_default(), + server_initiated: p.server_initiated.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SPlayerHotbar(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SPlayerHotbar { - selected_slot: p.selected_slot.0.try_into().unwrap(), - container_id: p.container_id.try_into().unwrap(), - select_slot: p.select_slot.try_into().unwrap(), + selected_slot: p.selected_slot.0.try_into().unwrap_or_default(), + container_id: p.container_id.try_into().unwrap_or_default(), + select_slot: p.select_slot.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SRequestChunkRadius(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SRequestChunkRadius { - chunk_radius: p.chunk_radius.0.try_into().unwrap(), - max_radius: p.max_radius.try_into().unwrap(), + chunk_radius: p.chunk_radius.0.try_into().unwrap_or_default(), + max_radius: p.max_radius.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SRequestNetworkSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SRequestNetworkSettings { - protocol_version: p.protocol_version.try_into().unwrap(), + protocol_version: p.protocol_version.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SResourcePackResponse(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SResourcePackResponse { - response: p.response.try_into().unwrap(), - download_size: p.download_size.try_into().unwrap(), + response: p.response.try_into().unwrap_or_default(), + download_size: p.download_size.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SSetLocalPlayerAsInitialized(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SSetLocalPlayerAsInitialized { - runtime_entity_id: p.runtime_entity_id.0.try_into().unwrap(), + runtime_entity_id: p.runtime_entity_id.0.try_into().unwrap_or_default(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SSetPlayerInventoryOptions(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SSetPlayerInventoryOptions { - left_inventory_tab: p.left_inventory_tab.0.try_into().unwrap(), - right_inventory_tab: p.right_inventory_tab.0.try_into().unwrap(), - filtering: p.filtering.try_into().unwrap(), - inventory_layout: p.inventory_layout.0.try_into().unwrap(), - crafting_layout: p.crafting_layout.0.try_into().unwrap(), + left_inventory_tab: p.left_inventory_tab.0.try_into().unwrap_or_default(), + right_inventory_tab: p.right_inventory_tab.0.try_into().unwrap_or_default(), + filtering: p.filtering.try_into().unwrap_or_default(), + inventory_layout: p.inventory_layout.0.try_into().unwrap_or_default(), + crafting_layout: p.crafting_layout.0.try_into().unwrap_or_default(), })) } _ => None, @@ -2538,10 +2570,10 @@ pub trait ToWitClientboundBedrock { impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChangeDimension { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CChangeDimension(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CChangeDimension { - dimension: self.dimension.0.try_into().unwrap(), + dimension: self.dimension.0.try_into().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), - respawn: self.respawn.try_into().unwrap(), - has_loading_screen_id: self.loading_screen_id.is_some().try_into().unwrap(), + respawn: self.respawn.try_into().unwrap_or_default(), + has_loading_screen_id: self.loading_screen_id.is_some().try_into().unwrap_or_default(), }) } } @@ -2549,7 +2581,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChangeDimen impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChunkRadiusUpdate { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CChunkRadiusUpdate(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CChunkRadiusUpdate { - chunk_radius: self.chunk_radius.0.try_into().unwrap(), + chunk_radius: self.chunk_radius.0.try_into().unwrap_or_default(), }) } } @@ -2557,10 +2589,10 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChunkRadius impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CContainerOpen { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CContainerOpen(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CContainerOpen { - container_id: self.container_id.try_into().unwrap(), - container_type: self.container_type.try_into().unwrap(), + container_id: self.container_id.try_into().unwrap_or_default(), + container_type: self.container_type.try_into().unwrap_or_default(), position: (self.position.0.x, self.position.0.y, self.position.0.z), - target_entity_id: self.target_entity_id.0.try_into().unwrap(), + target_entity_id: self.target_entity_id.0.try_into().unwrap_or_default(), }) } } @@ -2568,11 +2600,11 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CContainerOp impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CCorrectPlayerMove { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CCorrectPlayerMove(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CCorrectPlayerMove { - prediction_type: self.prediction_type.try_into().unwrap(), + prediction_type: self.prediction_type.try_into().unwrap_or_default(), pos: (self.pos.x as _, self.pos.y as _, self.pos.z as _), pos_delta: (self.pos_delta.x as _, self.pos_delta.y as _, self.pos_delta.z as _), - on_ground: self.on_ground.try_into().unwrap(), - tick: self.tick.0.try_into().unwrap(), + on_ground: self.on_ground.try_into().unwrap_or_default(), + tick: self.tick.0.try_into().unwrap_or_default(), }) } } @@ -2580,8 +2612,8 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CCorrectPlay impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CDisconnectPlayer { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CDisconnectPlayer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CDisconnectPlayer { - reason: self.reason.0.try_into().unwrap(), - skip_message: self.skip_message.try_into().unwrap(), + reason: self.reason.0.try_into().unwrap_or_default(), + skip_message: self.skip_message.try_into().unwrap_or_default(), message: self.message.to_string(), filtered_message: self.filtered_message.to_string(), }) @@ -2591,9 +2623,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CDisconnectP impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CLevelEvent { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CLevelEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CLevelEvent { - event_id: self.event_id.0.try_into().unwrap(), + event_id: self.event_id.0.try_into().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), - data: self.data.0.try_into().unwrap(), + data: self.data.0.try_into().unwrap_or_default(), }) } } @@ -2603,10 +2635,10 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CLevelSoundE BClientboundPacket::CLevelSoundEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CLevelSoundEvent { sound_id: self.sound_id.parse().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), - extra_data: self.extra_data.0.try_into().unwrap(), + extra_data: self.extra_data.0.try_into().unwrap_or_default(), entity_type: self.entity_type.to_string(), - is_baby_mob: self.is_baby_mob.try_into().unwrap(), - is_global: self.is_global.try_into().unwrap(), + is_baby_mob: self.is_baby_mob.try_into().unwrap_or_default(), + is_global: self.is_global.try_into().unwrap_or_default(), }) } } @@ -2614,7 +2646,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CLevelSoundE impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CModalFormRequest { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CModalFormRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CModalFormRequest { - form_id: self.form_id.0.try_into().unwrap(), + form_id: self.form_id.0.try_into().unwrap_or_default(), form_data: self.form_data.to_string(), }) } @@ -2623,12 +2655,12 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CModalFormRe impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMoveActorAbsolute { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CMoveActorAbsolute(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CMoveActorAbsolute { - entity_runtime_id: self.entity_runtime_id.0.try_into().unwrap(), - flags: self.flags.try_into().unwrap(), + entity_runtime_id: self.entity_runtime_id.0.try_into().unwrap_or_default(), + flags: self.flags.try_into().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), - pitch: self.pitch.try_into().unwrap(), - yaw: self.yaw.try_into().unwrap(), - head_yaw: self.head_yaw.try_into().unwrap(), + pitch: self.pitch.try_into().unwrap_or_default(), + yaw: self.yaw.try_into().unwrap_or_default(), + head_yaw: self.head_yaw.try_into().unwrap_or_default(), }) } } @@ -2636,14 +2668,14 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMoveActorAb impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMoveActorDelta { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CMoveActorDelta(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CMoveActorDelta { - entity_runtime_id: self.entity_runtime_id.0.try_into().unwrap(), - flags: self.flags.try_into().unwrap(), - x: self.x.try_into().unwrap(), - y: self.y.try_into().unwrap(), - z: self.z.try_into().unwrap(), - pitch: self.pitch.try_into().unwrap(), - yaw: self.yaw.try_into().unwrap(), - head_yaw: self.head_yaw.try_into().unwrap(), + entity_runtime_id: self.entity_runtime_id.0.try_into().unwrap_or_default(), + flags: self.flags.try_into().unwrap_or_default(), + x: self.x.try_into().unwrap_or_default(), + y: self.y.try_into().unwrap_or_default(), + z: self.z.try_into().unwrap_or_default(), + pitch: self.pitch.try_into().unwrap_or_default(), + yaw: self.yaw.try_into().unwrap_or_default(), + head_yaw: self.head_yaw.try_into().unwrap_or_default(), }) } } @@ -2651,17 +2683,17 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMoveActorDe impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMovePlayer { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CMovePlayer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CMovePlayer { - player_runtime_id: self.player_runtime_id.0.try_into().unwrap(), + player_runtime_id: self.player_runtime_id.0.try_into().unwrap_or_default(), position: (self.position.x as _, self.position.y as _, self.position.z as _), - pitch: self.pitch.try_into().unwrap(), - yaw: self.yaw.try_into().unwrap(), - head_yaw: self.head_yaw.try_into().unwrap(), - mode: self.mode.try_into().unwrap(), - on_ground: self.on_ground.try_into().unwrap(), - riding_runtime_id: self.riding_runtime_id.0.try_into().unwrap(), - teleport_cause: self.teleport_cause.try_into().unwrap(), - teleport_source_entity_type: self.teleport_source_entity_type.try_into().unwrap(), - tick: self.tick.0.try_into().unwrap(), + pitch: self.pitch.try_into().unwrap_or_default(), + yaw: self.yaw.try_into().unwrap_or_default(), + head_yaw: self.head_yaw.try_into().unwrap_or_default(), + mode: self.mode.try_into().unwrap_or_default(), + on_ground: self.on_ground.try_into().unwrap_or_default(), + riding_runtime_id: self.riding_runtime_id.0.try_into().unwrap_or_default(), + teleport_cause: self.teleport_cause.try_into().unwrap_or_default(), + teleport_source_entity_type: self.teleport_source_entity_type.try_into().unwrap_or_default(), + tick: self.tick.0.try_into().unwrap_or_default(), }) } } @@ -2669,11 +2701,11 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMovePlayer impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CNetworkSettings { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CNetworkSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CNetworkSettings { - compression_threshold: self.compression_threshold.try_into().unwrap(), - compression_method: self.compression_method.try_into().unwrap(), - client_throttle_enabled: self.client_throttle_enabled.try_into().unwrap(), - client_throttle_threshold: self.client_throttle_threshold.try_into().unwrap(), - client_throttle_scalar: self.client_throttle_scalar.try_into().unwrap(), + compression_threshold: self.compression_threshold.try_into().unwrap_or_default(), + compression_method: self.compression_method.try_into().unwrap_or_default(), + client_throttle_enabled: self.client_throttle_enabled.try_into().unwrap_or_default(), + client_throttle_threshold: self.client_throttle_threshold.try_into().unwrap_or_default(), + client_throttle_scalar: self.client_throttle_scalar.try_into().unwrap_or_default(), }) } } @@ -2698,9 +2730,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CPlayStatus impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CPlayerHotbar { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CPlayerHotbar(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CPlayerHotbar { - selected_slot: self.selected_slot.0.try_into().unwrap(), - container_id: self.container_id.try_into().unwrap(), - should_select_block: self.should_select_block.try_into().unwrap(), + selected_slot: self.selected_slot.0.try_into().unwrap_or_default(), + container_id: self.container_id.try_into().unwrap_or_default(), + should_select_block: self.should_select_block.try_into().unwrap_or_default(), }) } } @@ -2708,7 +2740,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CPlayerHotba impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CRemoveActor { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CRemoveActor(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CRemoveActor { - entity_unique_id: self.entity_unique_id.0.try_into().unwrap(), + entity_unique_id: self.entity_unique_id.0.try_into().unwrap_or_default(), }) } } @@ -2720,7 +2752,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDisplayO objective_name: self.objective_name.to_string(), display_name: self.display_name.to_string(), criteria_name: self.criteria_name.to_string(), - sort_order: self.sort_order.0.try_into().unwrap(), + sort_order: self.sort_order.0.try_into().unwrap_or_default(), }) } } @@ -2736,9 +2768,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CRemoveObjec impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetActorMotion { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CSetActorMotion(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetActorMotion { - target_runtime_id: self.target_runtime_id.0.try_into().unwrap(), + target_runtime_id: self.target_runtime_id.0.try_into().unwrap_or_default(), motion: (self.motion.x as _, self.motion.y as _, self.motion.z as _), - tick: self.tick.0.try_into().unwrap(), + tick: self.tick.0.try_into().unwrap_or_default(), }) } } @@ -2746,7 +2778,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetActorMot impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDifficulty { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CSetDifficulty(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetDifficulty { - difficulty: self.difficulty.0.try_into().unwrap(), + difficulty: self.difficulty.0.try_into().unwrap_or_default(), }) } } @@ -2754,7 +2786,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDifficul impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetHealth { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CSetHealth(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetHealth { - health: self.health.0.try_into().unwrap(), + health: self.health.0.try_into().unwrap_or_default(), }) } } @@ -2762,9 +2794,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetHealth { impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetSpawnPosition { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CSetSpawnPosition(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetSpawnPosition { - spawn_type: self.spawn_type.0.try_into().unwrap(), + spawn_type: self.spawn_type.0.try_into().unwrap_or_default(), position: (self.position.0.x, self.position.0.y, self.position.0.z), - dimension: self.dimension.0.try_into().unwrap(), + dimension: self.dimension.0.try_into().unwrap_or_default(), spawn_position: (self.spawn_position.0.x, self.spawn_position.0.y, self.spawn_position.0.z), }) } @@ -2773,7 +2805,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetSpawnPos impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTime { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CSetTime(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetTime { - time: self.time.0.try_into().unwrap(), + time: self.time.0.try_into().unwrap_or_default(), }) } } @@ -2781,11 +2813,11 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTime { impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTitle { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CSetTitle(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetTitle { - action_type: self.action_type.0.try_into().unwrap(), + action_type: self.action_type.0.try_into().unwrap_or_default(), text: self.text.to_string(), - fade_in_duration: self.fade_in_duration.0.try_into().unwrap(), - remain_duration: self.remain_duration.0.try_into().unwrap(), - fade_out_duration: self.fade_out_duration.0.try_into().unwrap(), + fade_in_duration: self.fade_in_duration.0.try_into().unwrap_or_default(), + remain_duration: self.remain_duration.0.try_into().unwrap_or_default(), + fade_out_duration: self.fade_out_duration.0.try_into().unwrap_or_default(), xuid: self.xuid.to_string(), platform_online_id: self.platform_online_id.to_string(), filtered_message: self.filtered_message.to_string(), @@ -2796,8 +2828,8 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTitle { impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CShowCredits { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CShowCredits(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CShowCredits { - player_runtime_id: self.player_runtime_id.0.try_into().unwrap(), - status: self.status.0.try_into().unwrap(), + player_runtime_id: self.player_runtime_id.0.try_into().unwrap_or_default(), + status: self.status.0.try_into().unwrap_or_default(), }) } } @@ -2805,8 +2837,8 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CShowCredits impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CTakeItemActor { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CTakeItemActor(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CTakeItemActor { - item_runtime_id: self.item_runtime_id.0.try_into().unwrap(), - actor_runtime_id: self.actor_runtime_id.0.try_into().unwrap(), + item_runtime_id: self.item_runtime_id.0.try_into().unwrap_or_default(), + actor_runtime_id: self.actor_runtime_id.0.try_into().unwrap_or_default(), }) } } @@ -2815,8 +2847,8 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CTransfer { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CTransfer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CTransfer { address: self.address.to_string(), - port: self.port.try_into().unwrap(), - reload_world: self.reload_world.try_into().unwrap(), + port: self.port.try_into().unwrap_or_default(), + reload_world: self.reload_world.try_into().unwrap_or_default(), }) } } @@ -2825,9 +2857,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CUpdateBlock fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CUpdateBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CUpdateBlock { position: (self.position.0.x, self.position.0.y, self.position.0.z), - block_runtime_id: self.block_runtime_id.0.try_into().unwrap(), - flags: self.flags.0.try_into().unwrap(), - layer: self.layer.0.try_into().unwrap(), + block_runtime_id: self.block_runtime_id.0.try_into().unwrap_or_default(), + flags: self.flags.0.try_into().unwrap_or_default(), + layer: self.layer.0.try_into().unwrap_or_default(), }) } } diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/item_stack.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/item_stack.rs index a924f463d..3b2aad3e3 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/item_stack.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/item_stack.rs @@ -37,7 +37,7 @@ pub(crate) fn to_wit_enchantment(id: &Enchantment) -> WitEnchantment { pub(crate) fn from_wit_enchantment(id: WitEnchantment) -> &'static Enchantment { // Safety: WIT enum is generated in the same order as the internal enum - Enchantment::from_id(id as u8).unwrap() + Enchantment::from_id(id as u8).expect("valid enchantment ID") } fn push_wit_nbt_tag(tag: NbtTag, tags: &mut Vec) -> u32 { @@ -420,12 +420,12 @@ impl HostItemStack for PluginHostState { for (id, data) in &stack.patch { if let Some(data) = data { let mut buf = Vec::new(); - serialize(*id, data.as_ref(), &mut buf).unwrap(); - - components.push(WitDataComponentValue { - component: to_wit_data_component(*id), - value: buf, - }); + if serialize(*id, data.as_ref(), &mut buf).is_ok() { + components.push(WitDataComponentValue { + component: to_wit_data_component(*id), + value: buf, + }); + } } } Ok(components) diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs index 8eaacc55f..66b012b01 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs @@ -510,11 +510,11 @@ impl DowncastResourceExt for Resource { .resource_table .get_any_mut(self.rep()) .map_err(|_| wasmtime::Error::msg("invalid player resource handle")) - .unwrap() + .expect("valid player resource handle") .downcast_ref::() .ok_or("resource type mismatch") .map_err(wasmtime::Error::msg) - .unwrap() + .expect("resource type mismatch") } fn downcast_mut<'a>(&'a self, state: &'a mut PluginHostState) -> &'a mut PlayerResource { @@ -522,11 +522,11 @@ impl DowncastResourceExt for Resource { .resource_table .get_any_mut(self.rep()) .map_err(|_| wasmtime::Error::msg("invalid player resource handle")) - .unwrap() + .expect("valid player resource handle") .downcast_mut::() .ok_or("resource type mismatch") .map_err(wasmtime::Error::msg) - .unwrap() + .expect("resource type mismatch") } fn consume(self, state: &mut PluginHostState) -> PlayerResource { @@ -534,7 +534,7 @@ impl DowncastResourceExt for Resource { .resource_table .delete::(Resource::new_own(self.rep())) .map_err(|_| wasmtime::Error::msg("invalid player resource handle")) - .unwrap() + .expect("invalid player resource handle") } } diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/world.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/world.rs index fa8970473..9421f8fe1 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/world.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/world.rs @@ -908,12 +908,16 @@ impl pumpkin::plugin::world::HostChunk for PluginHostState { let Some(chunk_data) = chunk_data.upgrade() else { return Err(wasmtime::Error::msg("Chunk unloaded")); }; - Ok(chunk_data.heightmap.lock().unwrap().get( - ChunkHeightmapType::WorldSurface, - x, - z, - chunk_data.section.min_y, - )) + Ok(chunk_data + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get( + ChunkHeightmapType::WorldSurface, + x, + z, + chunk_data.section.min_y, + )) } async fn get_sky_light( @@ -930,7 +934,7 @@ impl pumpkin::plugin::world::HostChunk for PluginHostState { Ok(chunk_data .light_engine .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .sky_light .get(section_index) .map_or(0, |c| { @@ -952,7 +956,7 @@ impl pumpkin::plugin::world::HostChunk for PluginHostState { Ok(chunk_data .light_engine .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .block_light .get(section_index) .map_or(0, |c| { diff --git a/crates/pumpkin/src/plugin/mod.rs b/crates/pumpkin/src/plugin/mod.rs index f4150ecc0..67a5642da 100644 --- a/crates/pumpkin/src/plugin/mod.rs +++ b/crates/pumpkin/src/plugin/mod.rs @@ -483,12 +483,13 @@ impl PluginManager { let input = line.trim().to_lowercase(); input == "y" || input == "yes" }) - } else { - let mut rl = DefaultEditor::new().expect("Failed to create rustyline editor"); + } else if let Ok(mut rl) = DefaultEditor::new() { rl.readline(&prompt).is_ok_and(|line| { let input = line.trim().to_lowercase(); input == "y" || input == "yes" }) + } else { + false }; if let Some((wrapper, rl)) = rl_taken { diff --git a/crates/pumpkin/src/server/connection_cache.rs b/crates/pumpkin/src/server/connection_cache.rs index b30e06145..a65e4624e 100644 --- a/crates/pumpkin/src/server/connection_cache.rs +++ b/crates/pumpkin/src/server/connection_cache.rs @@ -103,7 +103,7 @@ impl CachedStatus { version.protocol = client_protocol as u32; } - let json = serde_json::to_string(&response).expect("Failed to serialize status response"); + let json = serde_json::to_string(&response).unwrap_or_default(); CStatusResponse::new(json) } diff --git a/crates/pumpkin/src/server/key_store.rs b/crates/pumpkin/src/server/key_store.rs index 9900af600..2d04c0b3b 100644 --- a/crates/pumpkin/src/server/key_store.rs +++ b/crates/pumpkin/src/server/key_store.rs @@ -6,7 +6,7 @@ use rsa::pkcs8::EncodePublicKey; use rsa::{Pkcs1v15Encrypt, RsaPrivateKey}; use sha1::Sha1; use sha2::Digest; -use tracing::debug; +use tracing::{debug, error}; use crate::net::EncryptionError; @@ -26,9 +26,8 @@ impl KeyStore { let public_key_der = public_key .to_public_key_der() - .expect("Failed to encode public key to SPKI DER") - .into_vec() - .into_boxed_slice(); + .map(|der| der.into_vec().into_boxed_slice()) + .unwrap_or_default(); debug!("Created RSA keys, took {}ms", instant.elapsed().as_millis()); @@ -41,7 +40,13 @@ impl KeyStore { fn generate_private_key() -> RsaPrivateKey { let mut rng = rand::rng(); - RsaPrivateKey::new(&mut rng, 1024).expect("Failed to generate a key") + RsaPrivateKey::new(&mut rng, 1024).unwrap_or_else(|_| { + let mut fallback_rng = rand::rng(); + RsaPrivateKey::new(&mut fallback_rng, 1024).unwrap_or_else(|_| { + error!("Failed to generate RSA key"); + std::process::exit(1); + }) + }) } pub fn encryption_request<'a>( diff --git a/crates/pumpkin/src/server/mod.rs b/crates/pumpkin/src/server/mod.rs index f9b0ed7b0..f3ee70a54 100644 --- a/crates/pumpkin/src/server/mod.rs +++ b/crates/pumpkin/src/server/mod.rs @@ -194,7 +194,8 @@ impl Server { ) => { error!("Failed to load world info!"); error!("{error}"); - panic!("Unsupported world version! See the logs for more info."); + error!("Unsupported world version! See the logs for more info."); + std::process::exit(1); } Err(error) => { error!("Failed to load the world data in {}!", world_path.display()); @@ -202,7 +203,8 @@ impl Server { error!( "Refusing to continue: a default world would generate different terrain on top of the existing region files. Restore {LEVEL_DAT_FILE_NAME} from {LEVEL_DAT_BACKUP_FILE_NAME}, which also holds a copy of the world seed, or move the world folder aside to start a new world." ); - panic!("Failed to load the world data! See the logs for more info."); + error!("Failed to load the world data! See the logs for more info."); + std::process::exit(1); } }; @@ -311,7 +313,10 @@ impl Server { rayon::ThreadPoolBuilder::new() .thread_name(|i| format!("Gen-Pool-{i}")) .build() - .expect("Failed to build generation thread pool"), + .unwrap_or_else(|err| { + error!("Failed to build generation thread pool: {err}"); + std::process::exit(1); + }), ); let server_clone = server.clone(); @@ -355,8 +360,8 @@ impl Server { tokio::join!(futures::future::join_all(world_futures), mojang_keys_task); let mut worlds_vec = Vec::new(); - for world_result in worlds_results { - worlds_vec.push(world_result.expect("World loading panicked")); + for world in worlds_results.into_iter().flatten() { + worlds_vec.push(world); } server.worlds.store(Arc::new(worlds_vec)); @@ -399,17 +404,15 @@ impl Server { } pub fn get_world_from_dimension(&self, dimension: &Dimension) -> Arc { - self.worlds - .load() + let worlds = self.worlds.load(); + worlds .iter() .find(|w| w.dimension.minecraft_name == dimension.minecraft_name) .cloned() + .or_else(|| worlds.first().cloned()) .unwrap_or_else(|| { - self.worlds - .load() - .first() - .expect("Default world should exist") - .clone() + error!("No default world exists"); + std::process::exit(1); }) } @@ -460,7 +463,10 @@ impl Server { world }) .await - .expect("World creation panicked") + .unwrap_or_else(|_| { + error!("World creation failed"); + std::process::exit(1); + }) } /// Adds a new player to the server. @@ -496,6 +502,8 @@ impl Server { ) -> Option<(Arc, Arc)> { let gamemode = self.defaultgamemode.lock().await.gamemode; + let first_world = self.worlds.load().first().cloned()?; + let (world, nbt) = if let Ok(Some(data)) = self.player_data_storage.load_data(&profile.id).await { if let Some(dimension_key) = data.get_string("Dimension") { @@ -504,33 +512,15 @@ impl Server { (world, Some(data)) } else { warn!("Invalid dimension key in player data: {dimension_key}"); - let default_world = self - .worlds - .load() - .first() - .expect("Default world should exist") - .clone(); - (default_world, Some(data)) + (first_world, Some(data)) } } else { // Player data exists but doesn't have a "Dimension" key. - let default_world = self - .worlds - .load() - .first() - .expect("Default world should exist") - .clone(); - (default_world, Some(data)) + (first_world, Some(data)) } } else { // No player data found or an error occurred, default to the Overworld. - let default_world = self - .worlds - .load() - .first() - .expect("Default world should exist") - .clone(); - (default_world, None) + (first_world, None) }; let mut player = Player::new( @@ -1031,7 +1021,9 @@ impl Server { .map_or_else(Vec::new, |player| vec![player]), }; - let player_type = EntityType::from_name("player").expect("entity type player must exist"); + let Some(player_type) = EntityType::from_name("player") else { + return Vec::new(); + }; let type_included = target_selector .conditions .iter() diff --git a/crates/pumpkin/src/world/chunker.rs b/crates/pumpkin/src/world/chunker.rs index e8e4c20c9..09b1e1a07 100644 --- a/crates/pumpkin/src/world/chunker.rs +++ b/crates/pumpkin/src/world/chunker.rs @@ -13,7 +13,10 @@ use crate::{ }; pub fn get_view_distance(player: &Player) -> NonZeroU8 { - let server = player.world().server.upgrade().unwrap(); + let fallback = NonZeroU8::new(2).unwrap_or(NonZeroU8::MIN); + let Some(server) = player.world().server.upgrade() else { + return fallback; + }; let max_view_distance = match player.client.as_ref() { ClientPlatform::Java(_) => server.advanced_config.networking.java.view_distance, ClientPlatform::Bedrock(_) => server.advanced_config.networking.bedrock.view_distance, @@ -22,7 +25,7 @@ pub fn get_view_distance(player: &Player) -> NonZeroU8 { .config .load() .view_distance - .clamp(NonZeroU8::new(2).unwrap(), max_view_distance) + .clamp(fallback, max_view_distance) } // Checks if the target chunk is within the view distance diff --git a/crates/pumpkin/src/world/loot.rs b/crates/pumpkin/src/world/loot.rs index 47c2c1844..3c1f48b54 100644 --- a/crates/pumpkin/src/world/loot.rs +++ b/crates/pumpkin/src/world/loot.rs @@ -385,8 +385,12 @@ impl LootPoolEntryTypesExt for LootPoolEntryTypes { }) } Self::Item(item_entry) => { - let key = &item_entry.name.strip_prefix("minecraft:").unwrap(); - vec![ItemStack::new(1, Item::from_registry_key(key).unwrap())] + let key = item_entry + .name + .strip_prefix("minecraft:") + .unwrap_or(item_entry.name); + Item::from_registry_key(key) + .map_or_else(Vec::new, |item| vec![ItemStack::new(1, item)]) } Self::Tag(tag) => { let key = tag.name.strip_prefix("minecraft:").unwrap_or(tag.name); @@ -792,10 +796,9 @@ pub async fn fill_chest_inventory( } for item in items_to_place { - if available_slots.is_empty() { + let Some(slot) = available_slots.pop() else { break; - } - let slot = available_slots.pop().unwrap(); + }; inventory.set_stack(slot, item).await; } } diff --git a/crates/pumpkin/src/world/mod.rs b/crates/pumpkin/src/world/mod.rs index 8390fa26e..d819d006d 100644 --- a/crates/pumpkin/src/world/mod.rs +++ b/crates/pumpkin/src/world/mod.rs @@ -272,7 +272,7 @@ impl World { chunk .heightmap .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .get(height_map, x, z, self.min_y) }) .await @@ -721,7 +721,7 @@ impl World { skin_parts, ), ] { - meta.write(&mut buf, &version).unwrap(); + let _ = meta.write(&mut buf, &version); } buf.put_u8(255); client @@ -1054,7 +1054,11 @@ impl World { block_entity_future ); - self.level.chunk_loading.lock().unwrap().send_change(); + self.level + .chunk_loading + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .send_change(); if let Some(ref fight_mutex) = self.dragon_fight { dragon_fight::DragonFight::tick(fight_mutex, self).await; @@ -1695,12 +1699,16 @@ impl World { let delta = Vector3::new(rand_value & 15, rand_value >> 16 & 15, rand_value >> 8 & 15); let random_pos = Vector3::new( chunk_pos.x << 4, - chunk.heightmap.lock().unwrap().get( - MotionBlocking, - chunk_pos.x << 4, - chunk_pos.y << 4, - self.min_y, - ), + chunk + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get( + MotionBlocking, + chunk_pos.x << 4, + chunk_pos.y << 4, + self.min_y, + ), chunk_pos.y << 4, ) .add(&delta); @@ -1830,12 +1838,16 @@ impl World { self.level .read_chunk_sync(&chunk_pos, |chunk| { - let height = chunk.heightmap.lock().unwrap().get( - ChunkHeightmapType::WorldSurface, - position.x, - position.y, - self.dimension.min_y, - ); + let height = chunk + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get( + ChunkHeightmapType::WorldSurface, + position.x, + position.y, + self.dimension.min_y, + ); if height >= self.dimension.min_y { return height; @@ -1863,7 +1875,7 @@ impl World { chunk .heightmap .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .get(height_map, x, z, self.min_y) }) .unwrap_or(self.min_y) @@ -2639,7 +2651,7 @@ impl World { .java .max_players .try_into() - .unwrap(), + .unwrap_or(u16::MAX.into()), server .advanced_config .networking @@ -3103,7 +3115,7 @@ impl World { MetaDataType::BYTE, config.skin_parts, ); - meta.write(&mut buf, &client.version.load()).unwrap(); + let _ = meta.write(&mut buf, &client.version.load()); }; { let meta = Metadata::new( @@ -3111,7 +3123,7 @@ impl World { MetaDataType::BYTE, config.skin_parts, ); - meta.write(&mut buf, &client.version.load()).unwrap(); + let _ = meta.write(&mut buf, &client.version.load()); }; drop(config); // END @@ -3978,8 +3990,7 @@ impl World { .pos .load() .squared_distance_to_vec(&pos) - .partial_cmp(&b.get_entity().pos.load().squared_distance_to_vec(&pos)) - .unwrap() + .total_cmp(&b.get_entity().pos.load().squared_distance_to_vec(&pos)) }) .cloned() } @@ -4025,8 +4036,7 @@ impl World { .pos .load() .squared_distance_to_vec(&pos) - .partial_cmp(&b.1.get_entity().pos.load().squared_distance_to_vec(&pos)) - .unwrap() + .total_cmp(&b.1.get_entity().pos.load().squared_distance_to_vec(&pos)) }) .map(|p| p.1.clone()) } @@ -5108,7 +5118,7 @@ impl World { chunk .pending_block_entities .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .remove(block_pos) }) .flatten()?; @@ -5163,7 +5173,7 @@ impl World { chunk .pending_block_entities .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .insert(block_pos, nbt.clone()); chunk.mark_dirty(true); }); @@ -5194,7 +5204,7 @@ impl World { chunk .pending_block_entities .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .keys() .copied() .collect() diff --git a/crates/pumpkin/src/world/natural_spawner.rs b/crates/pumpkin/src/world/natural_spawner.rs index 9f6683f00..72d9867eb 100644 --- a/crates/pumpkin/src/world/natural_spawner.rs +++ b/crates/pumpkin/src/world/natural_spawner.rs @@ -194,7 +194,12 @@ struct PotentialCalculator(std::sync::Mutex>); impl Clone for PotentialCalculator { fn clone(&self) -> Self { - Self(std::sync::Mutex::new(self.0.lock().unwrap().clone())) + Self(std::sync::Mutex::new( + self.0 + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .clone(), + )) } } @@ -203,14 +208,17 @@ impl PotentialCalculator { if charge != 0. { self.0 .lock() - .unwrap() + .unwrap_or_else(std::sync::PoisonError::into_inner) .push(PointCharge(pos.to_f64(), charge)); } } pub fn remove_charge(&self, pos: &BlockPos, charge: f64) { if charge != 0. { - let mut charges = self.0.lock().unwrap(); + let mut charges = self + .0 + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let pos_f64 = pos.to_f64(); if let Some(idx) = charges.iter().position(|c| c.0 == pos_f64 && c.1 == charge) { charges.swap_remove(idx); @@ -222,7 +230,10 @@ impl PotentialCalculator { return 0.; } let mut sum: f64 = 0.; - let charges = self.0.lock().unwrap(); + let charges = self + .0 + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); for i in charges.iter() { sum += i.get_potential_change(pos); } @@ -500,12 +511,12 @@ pub fn get_random_pos_within( let x = (chunk_pos.x << 4) + rng.next_bounded_i32(16); let z = (chunk_pos.y << 4) + rng.next_bounded_i32(16); - let temp_y = chunk.heightmap.lock().unwrap().get( - ChunkHeightmapType::WorldSurface, - x, - z, - chunk.section.min_y, - ) + 1; + let temp_y = chunk + .heightmap + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .get(ChunkHeightmapType::WorldSurface, x, z, chunk.section.min_y) + + 1; let y = rng.next_inbetween_i32(min_y, temp_y); BlockPos::new(x, y, z) } @@ -534,13 +545,13 @@ pub fn spawn_mobs_for_chunk_generation( let count = spawner_data.min_count + rand::random_range(0..(1 + spawner_data.max_count - spawner_data.min_count).max(1)); - let entity_type = EntityType::from_name( - spawner_data - .r#type - .strip_prefix("minecraft:") - .unwrap_or(spawner_data.r#type), - ) - .unwrap(); + let name = spawner_data + .r#type + .strip_prefix("minecraft:") + .unwrap_or(spawner_data.r#type); + let Some(entity_type) = EntityType::from_name(name) else { + return; + }; let mut x = xo + rand::random_range(0..16); let mut z = zo + rand::random_range(0..16); @@ -663,9 +674,16 @@ pub fn spawn_category_for_position( random_group_size = rng().random_range(spawner.min_count..=spawner.max_count); } - let spawner = current_spawner.unwrap(); - let entity_type = - &EntityType::from_name(spawner.r#type.strip_prefix("minecraft:").unwrap()).unwrap(); + let Some(spawner) = current_spawner else { + break 'spawn_loop; + }; + let name = spawner + .r#type + .strip_prefix("minecraft:") + .unwrap_or(spawner.r#type); + let Some(entity_type) = EntityType::from_name(name) else { + break 'spawn_loop; + }; new_pos = adjust_spawn_position(world, new_pos, entity_type); @@ -774,7 +792,7 @@ pub fn get_random_spawn_mob_at( id if id == MobCategory::WATER_CREATURE.id => biome.spawners.water_creature, id if id == MobCategory::WATER_AMBIENT.id => biome.spawners.water_ambient, id if id == MobCategory::MISC.id => biome.spawners.misc, - _ => panic!(), + _ => biome.spawners.misc, } .choose(&mut rng()) } diff --git a/crates/pumpkin/src/world/portal/nether.rs b/crates/pumpkin/src/world/portal/nether.rs index 102de1102..96dd54364 100644 --- a/crates/pumpkin/src/world/portal/nether.rs +++ b/crates/pumpkin/src/world/portal/nether.rs @@ -638,14 +638,11 @@ impl NetherPortal { .await; if is_ideal { - if ideal_pos.is_none() - || dist < ideal_pos.as_ref().unwrap().2 - { + if ideal_pos.as_ref().is_none_or(|p| dist < p.2) { ideal_pos = Some((floor_pos, check_axis, dist)); } } else if ideal_pos.is_none() - && (acceptable_pos.is_none() - || dist < acceptable_pos.as_ref().unwrap().2) + && acceptable_pos.as_ref().is_none_or(|p| dist < p.2) { acceptable_pos = Some((floor_pos, check_axis, dist)); } diff --git a/wepif.yml b/wepif.yml new file mode 100644 index 000000000..43b2ebc8f --- /dev/null +++ b/wepif.yml @@ -0,0 +1,46 @@ +# +# WEPIF Configuration File +# +# This file handles permissions configuration for every plugin using WEPIF +# +# About editing this file: +# - DO NOT USE TABS. You MUST use spaces or Bukkit will complain. If +# you use an editor like Notepad++ (recommended for Windows users), you +# must configure it to "replace tabs with spaces." In Notepad++, this can +# be changed in Settings > Preferences > Language Menu. +# - Don't get rid of the indents. They are indented so some entries are +# in categories (like "enforce-single-session" is in the "protection" +# category. +# - If you want to check the format of this file before putting it +# into WEPIF, paste it into https://yaml-online-parser.appspot.com/ +# and see if it gives "ERROR:". +# - Lines starting with # are comments and so they are ignored. + + +ignore-nijiperms-bridges: true +resolvers: + enabled: + - PluginPermissionsResolver + - PermissionsExResolver + - bPermissionsResolver + - GroupManagerResolver + - NijiPermissionsResolver + - VaultResolver + - DinnerPermsResolver + - FlatFilePermissionsResolver +permissions: + groups: + default: + permissions: + - worldedit.reload + - worldedit.selection + - worlds.creative.worldedit.region + admins: + permissions: + - '*' + users: + sk89q: + permissions: + - worldedit + groups: + - admins