1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00
* 25w02a

* move item_components codegen to a different module

* remove outdated test

* 25w03a

* start updating to 24w09b

* 1.21.5-pre2

* fix broken packets

* 1.21.5-rc2

* merge main

* delete unused acket_handling

* 1.21.5
This commit is contained in:
mat 2025-03-25 11:17:39 -05:00 committed by GitHub
parent 8af265e48b
commit ef357fdf36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 3675 additions and 2934 deletions

42
Cargo.lock generated
View file

@ -209,7 +209,7 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "azalea"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"anyhow",
"azalea-auth",
@ -249,7 +249,7 @@ dependencies = [
[[package]]
name = "azalea-auth"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf",
"azalea-crypto",
@ -269,7 +269,7 @@ dependencies = [
[[package]]
name = "azalea-block"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-block-macros",
"azalea-buf",
@ -278,7 +278,7 @@ dependencies = [
[[package]]
name = "azalea-block-macros"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"proc-macro2",
"quote",
@ -287,7 +287,7 @@ dependencies = [
[[package]]
name = "azalea-brigadier"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf",
"azalea-chat",
@ -298,7 +298,7 @@ dependencies = [
[[package]]
name = "azalea-buf"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf-macros",
"byteorder",
@ -311,7 +311,7 @@ dependencies = [
[[package]]
name = "azalea-buf-macros"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"proc-macro2",
"quote",
@ -320,7 +320,7 @@ dependencies = [
[[package]]
name = "azalea-chat"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf",
"azalea-language",
@ -333,7 +333,7 @@ dependencies = [
[[package]]
name = "azalea-client"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"anyhow",
"azalea-auth",
@ -368,7 +368,7 @@ dependencies = [
[[package]]
name = "azalea-core"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf",
"azalea-chat",
@ -384,7 +384,7 @@ dependencies = [
[[package]]
name = "azalea-crypto"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"aes",
"azalea-buf",
@ -401,7 +401,7 @@ dependencies = [
[[package]]
name = "azalea-entity"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-block",
"azalea-buf",
@ -424,7 +424,7 @@ dependencies = [
[[package]]
name = "azalea-inventory"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf",
"azalea-chat",
@ -439,7 +439,7 @@ dependencies = [
[[package]]
name = "azalea-inventory-macros"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"proc-macro2",
"quote",
@ -448,7 +448,7 @@ dependencies = [
[[package]]
name = "azalea-language"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"compact_str",
"serde",
@ -457,7 +457,7 @@ dependencies = [
[[package]]
name = "azalea-physics"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-block",
"azalea-core",
@ -475,7 +475,7 @@ dependencies = [
[[package]]
name = "azalea-protocol"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"anyhow",
"async-recursion",
@ -510,7 +510,7 @@ dependencies = [
[[package]]
name = "azalea-protocol-macros"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"proc-macro2",
"quote",
@ -519,7 +519,7 @@ dependencies = [
[[package]]
name = "azalea-registry"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-buf",
"azalea-registry-macros",
@ -529,7 +529,7 @@ dependencies = [
[[package]]
name = "azalea-registry-macros"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"quote",
"syn",
@ -537,7 +537,7 @@ dependencies = [
[[package]]
name = "azalea-world"
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5-rc2"
dependencies = [
"azalea-block",
"azalea-buf",

View file

@ -22,7 +22,7 @@ resolver = "2"
# --- Workspace Settings ---
[workspace.package]
version = "0.11.0+mc1.21.4"
version = "0.11.0+mc1.21.5"
edition = "2024"
license = "MIT"
repository = "https://github.com/azalea-rs/azalea"

View file

@ -10,7 +10,7 @@ A collection of Rust crates for making Minecraft bots, clients, and tools.
<!-- The line below is automatically read and updated by the migrate script, so don't change it manually. -->
_Currently supported Minecraft version: `1.21.4`._
_Currently supported Minecraft version: `1.21.5`._
> [!WARNING]
> Azalea is still unfinished, though most crates are in a useable state

View file

@ -326,7 +326,11 @@ make_block_states! {
"south" => South(bool),
"up" => Up(bool),
"west" => West(bool),
"active" => Active(bool),
"creaking_heart_state" => CreakingHeartState {
Uprooted,
Dormant,
Awake,
},
"natural" => Natural(bool),
"half" => TopBottom {
Top,
@ -1694,7 +1698,7 @@ make_block_states! {
_14,
_15,
},
"mode" => Mode {
"mode" => StructureMode {
Save,
Load,
Corner,
@ -1714,6 +1718,12 @@ make_block_states! {
NorthUp,
SouthUp,
},
"mode" => TestMode {
Start,
Log,
Fail,
Accept,
},
"level" => ComposterLevel {
_0,
_1,
@ -1958,6 +1968,18 @@ make_block_states! {
_3,
_4,
},
"flower_amount" => WildflowersFlowerAmount {
_1,
_2,
_3,
_4,
},
"segment_amount" => LeafLitterSegmentAmount {
_1,
_2,
_3,
_4,
},
"tilt" => Tilt {
None,
Unstable,
@ -2356,6 +2378,9 @@ make_block_states! {
short_grass => BlockBehavior::new(), {},
fern => BlockBehavior::new(), {},
dead_bush => BlockBehavior::new(), {},
bush => BlockBehavior::new(), {},
short_dry_grass => BlockBehavior::new(), {},
tall_dry_grass => BlockBehavior::new(), {},
seagrass => BlockBehavior::new(), {},
tall_seagrass => BlockBehavior::new(), {
"half": Half::Lower,
@ -2438,8 +2463,8 @@ make_block_states! {
soul_fire => BlockBehavior::new(), {},
spawner => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {},
creaking_heart => BlockBehavior::new(), {
"active": Active(false),
"axis": Axis::Y,
"creaking_heart_state": CreakingHeartState::Uprooted,
"natural": Natural(false),
},
oak_stairs => BlockBehavior::new().strength(2.0, 3.0), {
@ -2754,6 +2779,7 @@ make_block_states! {
cactus => BlockBehavior::new().strength(0.4, 0.4), {
"age": CactusAge::_0,
},
cactus_flower => BlockBehavior::new(), {},
clay => BlockBehavior::new().strength(0.6, 0.6), {},
sugar_cane => BlockBehavior::new(), {
"age": SugarCaneAge::_0,
@ -4771,11 +4797,15 @@ make_block_states! {
"waterlogged": Waterlogged(false),
},
structure_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
"mode": Mode::Load,
"mode": StructureMode::Load,
},
jigsaw => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
"orientation": Orientation::NorthUp,
},
test_block => BlockBehavior::new(), {
"mode": TestMode::Start,
},
test_instance_block => BlockBehavior::new(), {},
composter => BlockBehavior::new().strength(0.6, 0.6), {
"level": ComposterLevel::_0,
},
@ -5419,6 +5449,14 @@ make_block_states! {
"facing": FacingCardinal::North,
"flower_amount": PinkPetalsFlowerAmount::_1,
},
wildflowers => BlockBehavior::new(), {
"facing": FacingCardinal::North,
"flower_amount": WildflowersFlowerAmount::_1,
},
leaf_litter => BlockBehavior::new(), {
"facing": FacingCardinal::North,
"segment_amount": LeafLitterSegmentAmount::_1,
},
moss_block => BlockBehavior::new().strength(0.1, 0.1), {},
big_dripleaf => BlockBehavior::new().strength(0.1, 0.1).force_solid(false), {
"facing": FacingCardinal::North,
@ -5578,5 +5616,6 @@ make_block_states! {
closed_eyeblossom => BlockBehavior::new(), {},
potted_open_eyeblossom => BlockBehavior::new(), {},
potted_closed_eyeblossom => BlockBehavior::new(), {},
firefly_bush => BlockBehavior::new(), {},
}
}

View file

@ -4,7 +4,6 @@
use std::{
io::Cursor,
ops::Deref,
time::{Duration, Instant},
};
@ -15,7 +14,6 @@ use azalea_protocol::packets::game::{
};
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use simdnbt::owned::BaseNbt;
use tracing::{error, trace};
use super::packet::game::handle_outgoing_packets;
@ -98,10 +96,7 @@ pub fn handle_receive_chunk_events(
}
}
let heightmaps_nbt = &event.packet.chunk_data.heightmaps;
// necessary to make the unwrap_or work
let empty_nbt = BaseNbt::default();
let heightmaps = heightmaps_nbt.unwrap_or(&empty_nbt).deref();
let heightmaps = &event.packet.chunk_data.heightmaps;
if let Err(e) = partial_instance.chunks.replace_with_packet_data(
&pos,

View file

@ -57,6 +57,7 @@ pub fn process_packet_events(ecs: &mut World) {
ecs,
};
// the order of these doesn't matter, that's decided by the protocol library
declare_packet_handlers!(
ClientboundGamePacket,
packet.as_ref(),
@ -113,7 +114,6 @@ pub fn process_packet_events(ecs: &mut World) {
server_data,
set_equipment,
update_mob_effect,
add_experience_orb,
award_stats,
block_changed_ack,
block_destruction,
@ -193,6 +193,7 @@ pub fn process_packet_events(ecs: &mut World) {
recipe_book_add,
recipe_book_remove,
recipe_book_settings,
test_instance_block_status,
]
);
}
@ -1196,8 +1197,6 @@ impl GamePacketHandler<'_> {
debug!("Got update mob effect packet {p:?}");
}
pub fn add_experience_orb(&mut self, _p: &ClientboundAddExperienceOrb) {}
pub fn award_stats(&mut self, _p: &ClientboundAwardStats) {}
pub fn block_changed_ack(&mut self, _p: &ClientboundBlockChangedAck) {}
@ -1601,4 +1600,5 @@ impl GamePacketHandler<'_> {
pub fn recipe_book_add(&mut self, _p: &ClientboundRecipeBookAdd) {}
pub fn recipe_book_remove(&mut self, _p: &ClientboundRecipeBookRemove) {}
pub fn recipe_book_settings(&mut self, _p: &ClientboundRecipeBookSettings) {}
pub fn test_instance_block_status(&mut self, _p: &ClientboundTestInstanceBlockStatus) {}
}

View file

@ -22,7 +22,7 @@ use azalea_world::{Chunk, Instance, MinecraftEntityId, Section};
use bevy_app::App;
use bevy_ecs::{prelude::*, schedule::ExecutorKind};
use parking_lot::{Mutex, RwLock};
use simdnbt::owned::{Nbt, NbtCompound, NbtTag};
use simdnbt::owned::{NbtCompound, NbtTag};
use tokio::task::JoinHandle;
use tokio::{sync::mpsc, time::sleep};
use uuid::Uuid;
@ -299,7 +299,7 @@ pub fn make_basic_empty_chunk(
x: pos.x,
z: pos.z,
chunk_data: ClientboundLevelChunkPacketData {
heightmaps: Nbt::None,
heightmaps: Default::default(),
data: Arc::new(chunk_bytes.into()),
block_entities: vec![],
},

View file

@ -5,7 +5,7 @@ use azalea_protocol::packets::{
ConnectionProtocol, Packet,
config::{ClientboundFinishConfiguration, ClientboundRegistryData},
};
use azalea_registry::DimensionType;
use azalea_registry::{DataRegistry, DimensionType};
use azalea_world::InstanceName;
use bevy_log::tracing_subscriber;
use simdnbt::owned::{NbtCompound, NbtTag};

View file

@ -5,7 +5,7 @@ use azalea_protocol::packets::{
ConnectionProtocol,
config::{ClientboundFinishConfiguration, ClientboundRegistryData},
};
use azalea_registry::{DimensionType, EntityKind};
use azalea_registry::{DataRegistry, DimensionType, EntityKind};
use bevy_ecs::query::With;
use bevy_log::tracing_subscriber;
use simdnbt::owned::{NbtCompound, NbtTag};

View file

@ -2,7 +2,7 @@ use azalea_client::test_simulation::*;
use azalea_core::{position::ChunkPos, resource_location::ResourceLocation};
use azalea_entity::metadata::Cow;
use azalea_protocol::packets::{ConnectionProtocol, game::ClientboundMoveEntityRot};
use azalea_registry::{DimensionType, EntityKind};
use azalea_registry::{DataRegistry, DimensionType, EntityKind};
use azalea_world::MinecraftEntityId;
use bevy_ecs::query::With;
use bevy_log::tracing_subscriber;

View file

@ -1,7 +1,7 @@
use azalea_client::{InConfigState, packet::game::SendPacketEvent, test_simulation::*};
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol::packets::{ConnectionProtocol, game::ClientboundStartConfiguration};
use azalea_registry::DimensionType;
use azalea_registry::{DataRegistry, DimensionType};
use azalea_world::InstanceName;
use bevy_ecs::event::Events;
use bevy_log::tracing_subscriber;

View file

@ -6,7 +6,7 @@ use azalea_protocol::packets::{
config::{ClientboundFinishConfiguration, ClientboundRegistryData},
game::ClientboundSetHealth,
};
use azalea_registry::DimensionType;
use azalea_registry::{DataRegistry, DimensionType};
use bevy_log::tracing_subscriber;
use simdnbt::owned::{NbtCompound, NbtTag};

View file

@ -417,6 +417,18 @@ impl BlockPos {
}
}
/// Similar to [`BlockPos`] but it's serialized as 3 varints instead of one
/// 64-bit integer, so it can represent a bigger range of numbers.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, AzBuf)]
pub struct Vec3i {
#[var]
pub x: i32,
#[var]
pub y: i32,
#[var]
pub z: i32,
}
/// Chunk coordinates are used to represent where a chunk is in the world. You
/// can convert the x and z to block coordinates by multiplying them by 16.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]

View file

@ -70,7 +70,7 @@ pub enum EntityDataValue {
BlockPos(BlockPos),
OptionalBlockPos(Option<BlockPos>),
Direction(Direction),
OptionalUuid(Option<Uuid>),
OptionalLivingEntityReference(Option<Uuid>),
BlockState(azalea_block::BlockState),
/// If this is air, that means it's absent,
OptionalBlockState(azalea_block::BlockState),
@ -82,8 +82,12 @@ pub enum EntityDataValue {
OptionalUnsignedInt(OptionalUnsignedInt),
Pose(Pose),
CatVariant(azalea_registry::CatVariant),
ChickenVariant(azalea_registry::ChickenVariant),
CowVariant(azalea_registry::CowVariant),
WolfVariant(azalea_registry::WolfVariant),
WolfSoundVariant(azalea_registry::WolfSoundVariant),
FrogVariant(azalea_registry::FrogVariant),
PigVariant(azalea_registry::PigVariant),
OptionalGlobalPos(Option<GlobalPos>),
PaintingVariant(azalea_registry::PaintingVariant),
SnifferState(SnifferStateKind),

View file

@ -103,6 +103,7 @@ impl From<EntityKind> for EntityDimensions {
EntityKind::JungleChestBoat => EntityDimensions::new(1.375, 0.5625),
EntityKind::LeashKnot => EntityDimensions::new(0.375, 0.5),
EntityKind::LightningBolt => EntityDimensions::new(0.0, 0.0),
EntityKind::LingeringPotion => EntityDimensions::new(0.25, 0.25),
EntityKind::Llama => EntityDimensions::new(0.9, 1.87),
EntityKind::LlamaSpit => EntityDimensions::new(0.25, 0.25),
EntityKind::MagmaCube => EntityDimensions::new(0.52, 0.52),
@ -128,7 +129,6 @@ impl From<EntityKind> for EntityDimensions {
EntityKind::Pillager => EntityDimensions::new(0.6, 1.95),
EntityKind::Player => EntityDimensions::new(0.6, 1.8),
EntityKind::PolarBear => EntityDimensions::new(1.4, 1.4),
EntityKind::Potion => EntityDimensions::new(0.25, 0.25),
EntityKind::Pufferfish => EntityDimensions::new(0.7, 0.7),
EntityKind::Rabbit => EntityDimensions::new(0.4, 0.5),
EntityKind::Ravager => EntityDimensions::new(1.95, 2.2),
@ -147,6 +147,7 @@ impl From<EntityKind> for EntityDimensions {
EntityKind::SpawnerMinecart => EntityDimensions::new(0.98, 0.7),
EntityKind::SpectralArrow => EntityDimensions::new(0.5, 0.5),
EntityKind::Spider => EntityDimensions::new(1.4, 0.9),
EntityKind::SplashPotion => EntityDimensions::new(0.25, 0.25),
EntityKind::SpruceBoat => EntityDimensions::new(1.375, 0.5625),
EntityKind::SpruceChestBoat => EntityDimensions::new(1.375, 0.5625),
EntityKind::Squid => EntityDimensions::new(0.8, 0.8),

File diff suppressed because it is too large Load diff

View file

@ -45,6 +45,7 @@ pub enum Particle {
Infested,
CherryLeaves,
PaleOakLeaves,
TintedLeaves,
SculkSoul,
SculkCharge(SculkChargeParticle),
SculkChargePop,
@ -122,6 +123,7 @@ pub enum Particle {
RaidOmen,
TrialOmen,
BlockCrumble,
Firefly,
}
impl From<ParticleKind> for Particle {
@ -164,6 +166,7 @@ impl From<ParticleKind> for Particle {
ParticleKind::Flame => Self::Flame,
ParticleKind::CherryLeaves => Self::CherryLeaves,
ParticleKind::PaleOakLeaves => Self::PaleOakLeaves,
ParticleKind::TintedLeaves => Self::TintedLeaves,
ParticleKind::SculkSoul => Self::SculkSoul,
ParticleKind::SculkCharge => Self::SculkCharge(SculkChargeParticle::default()),
ParticleKind::SculkChargePop => Self::SculkChargePop,
@ -245,6 +248,7 @@ impl From<ParticleKind> for Particle {
ParticleKind::TrialOmen => Self::TrialOmen,
ParticleKind::Trail => Self::Trail,
ParticleKind::BlockCrumble => Self::BlockCrumble,
ParticleKind::Firefly => Self::Firefly,
}
}
}

View file

@ -8,8 +8,9 @@ use azalea_core::{
sound::CustomSound,
};
use azalea_registry::{
Attribute, Block, ConsumeEffectKind, DataComponentKind, Enchantment, EntityKind, HolderSet,
Item, MobEffect, Potion, SoundEvent, TrimMaterial, TrimPattern,
self as registry, Attribute, Block, ConsumeEffectKind, DamageKind, DataComponentKind,
Enchantment, EntityKind, Holder, HolderSet, Item, MobEffect, Potion, SoundEvent, TrimMaterial,
TrimPattern,
};
use simdnbt::owned::{Nbt, NbtCompound};
use tracing::trace;
@ -51,7 +52,7 @@ where
}
pub fn from_kind(
kind: azalea_registry::DataComponentKind,
kind: registry::DataComponentKind,
buf: &mut Cursor<&[u8]>,
) -> Result<Box<dyn EncodableDataComponent>, BufReadError> {
// if this is causing a compile-time error, look at DataComponents.java in the
@ -75,10 +76,6 @@ pub fn from_kind(
DataComponentKind::CanBreak => Box::new(CanBreak::azalea_read(buf)?),
DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::azalea_read(buf)?),
DataComponentKind::CustomModelData => Box::new(CustomModelData::azalea_read(buf)?),
DataComponentKind::HideAdditionalTooltip => {
Box::new(HideAdditionalTooltip::azalea_read(buf)?)
}
DataComponentKind::HideTooltip => Box::new(HideTooltip::azalea_read(buf)?),
DataComponentKind::RepairCost => Box::new(RepairCost::azalea_read(buf)?),
DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::azalea_read(buf)?),
DataComponentKind::EnchantmentGlintOverride => {
@ -138,6 +135,45 @@ pub fn from_kind(
DataComponentKind::Glider => Box::new(Glider::azalea_read(buf)?),
DataComponentKind::TooltipStyle => Box::new(TooltipStyle::azalea_read(buf)?),
DataComponentKind::DeathProtection => Box::new(DeathProtection::azalea_read(buf)?),
DataComponentKind::Weapon => Box::new(Weapon::azalea_read(buf)?),
DataComponentKind::PotionDurationScale => Box::new(PotionDurationScale::azalea_read(buf)?),
DataComponentKind::VillagerVariant => Box::new(VillagerVariant::azalea_read(buf)?),
DataComponentKind::WolfVariant => Box::new(WolfVariant::azalea_read(buf)?),
DataComponentKind::WolfCollar => Box::new(WolfCollar::azalea_read(buf)?),
DataComponentKind::FoxVariant => Box::new(FoxVariant::azalea_read(buf)?),
DataComponentKind::SalmonSize => Box::new(SalmonSize::azalea_read(buf)?),
DataComponentKind::ParrotVariant => Box::new(ParrotVariant::azalea_read(buf)?),
DataComponentKind::TropicalFishPattern => Box::new(TropicalFishPattern::azalea_read(buf)?),
DataComponentKind::TropicalFishBaseColor => {
Box::new(TropicalFishBaseColor::azalea_read(buf)?)
}
DataComponentKind::TropicalFishPatternColor => {
Box::new(TropicalFishPatternColor::azalea_read(buf)?)
}
DataComponentKind::MooshroomVariant => Box::new(MooshroomVariant::azalea_read(buf)?),
DataComponentKind::RabbitVariant => Box::new(RabbitVariant::azalea_read(buf)?),
DataComponentKind::PigVariant => Box::new(PigVariant::azalea_read(buf)?),
DataComponentKind::FrogVariant => Box::new(FrogVariant::azalea_read(buf)?),
DataComponentKind::HorseVariant => Box::new(HorseVariant::azalea_read(buf)?),
DataComponentKind::PaintingVariant => Box::new(PaintingVariant::azalea_read(buf)?),
DataComponentKind::LlamaVariant => Box::new(LlamaVariant::azalea_read(buf)?),
DataComponentKind::AxolotlVariant => Box::new(AxolotlVariant::azalea_read(buf)?),
DataComponentKind::CatVariant => Box::new(CatVariant::azalea_read(buf)?),
DataComponentKind::CatCollar => Box::new(CatCollar::azalea_read(buf)?),
DataComponentKind::SheepColor => Box::new(SheepColor::azalea_read(buf)?),
DataComponentKind::ShulkerColor => Box::new(ShulkerColor::azalea_read(buf)?),
DataComponentKind::TooltipDisplay => Box::new(TooltipDisplay::azalea_read(buf)?),
DataComponentKind::BlocksAttacks => Box::new(BlocksAttacks::azalea_read(buf)?),
DataComponentKind::ProvidesTrimMaterial => {
Box::new(ProvidesTrimMaterial::azalea_read(buf)?)
}
DataComponentKind::ProvidesBannerPatterns => {
Box::new(ProvidesBannerPatterns::azalea_read(buf)?)
}
DataComponentKind::BreakSound => Box::new(BreakSound::azalea_read(buf)?),
DataComponentKind::WolfSoundVariant => Box::new(WolfSoundVariant::azalea_read(buf)?),
DataComponentKind::CowVariant => Box::new(CowVariant::azalea_read(buf)?),
DataComponentKind::ChickenVariant => Box::new(ChickenVariant::azalea_read(buf)?),
})
}
@ -342,18 +378,6 @@ impl DataComponent for CustomModelData {
const KIND: DataComponentKind = DataComponentKind::CustomModelData;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct HideAdditionalTooltip;
impl DataComponent for HideAdditionalTooltip {
const KIND: DataComponentKind = DataComponentKind::HideAdditionalTooltip;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct HideTooltip;
impl DataComponent for HideTooltip {
const KIND: DataComponentKind = DataComponentKind::HideTooltip;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct RepairCost {
#[var]
@ -600,7 +624,7 @@ impl DataComponent for BlockEntityData {
#[derive(Clone, PartialEq, AzBuf)]
pub struct Instrument {
pub instrument: azalea_registry::Instrument,
pub instrument: registry::Instrument,
}
impl DataComponent for Instrument {
const KIND: DataComponentKind = DataComponentKind::Instrument;
@ -791,7 +815,7 @@ impl DataComponent for ContainerLoot {
#[derive(Clone, PartialEq, AzBuf)]
pub struct JukeboxPlayable {
pub song: azalea_registry::JukeboxSong,
pub song: registry::JukeboxSong,
pub show_in_tooltip: bool,
}
impl DataComponent for JukeboxPlayable {
@ -931,3 +955,302 @@ pub struct DeathProtection {
impl DataComponent for DeathProtection {
const KIND: DataComponentKind = DataComponentKind::DeathProtection;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct Weapon {
#[var]
pub damage_per_attack: i32,
pub can_disable_blocking: bool,
}
impl DataComponent for Weapon {
const KIND: DataComponentKind = DataComponentKind::Weapon;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct PotionDurationScale {
pub value: f32,
}
impl DataComponent for PotionDurationScale {
const KIND: DataComponentKind = DataComponentKind::PotionDurationScale;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct VillagerVariant {
pub variant: registry::VillagerKind,
}
impl DataComponent for VillagerVariant {
const KIND: DataComponentKind = DataComponentKind::VillagerVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct WolfVariant {
pub variant: registry::WolfVariant,
}
impl DataComponent for WolfVariant {
const KIND: DataComponentKind = DataComponentKind::WolfVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct WolfCollar {
pub color: DyeColor,
}
impl DataComponent for WolfCollar {
const KIND: DataComponentKind = DataComponentKind::WolfCollar;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct FoxVariant {
pub variant: registry::FoxVariant,
}
impl DataComponent for FoxVariant {
const KIND: DataComponentKind = DataComponentKind::FoxVariant;
}
#[derive(Clone, Copy, PartialEq, AzBuf)]
pub enum SalmonSize {
Small,
Medium,
Large,
}
impl DataComponent for SalmonSize {
const KIND: DataComponentKind = DataComponentKind::SalmonSize;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct ParrotVariant {
pub variant: registry::ParrotVariant,
}
impl DataComponent for ParrotVariant {
const KIND: DataComponentKind = DataComponentKind::ParrotVariant;
}
#[derive(Clone, Copy, PartialEq, AzBuf)]
pub enum TropicalFishPattern {
Kob,
Sunstreak,
Snooper,
Dasher,
Brinely,
Spotty,
Flopper,
Stripey,
Glitter,
Blockfish,
Betty,
Clayfish,
}
impl DataComponent for TropicalFishPattern {
const KIND: DataComponentKind = DataComponentKind::TropicalFishPattern;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct TropicalFishBaseColor {
pub color: DyeColor,
}
impl DataComponent for TropicalFishBaseColor {
const KIND: DataComponentKind = DataComponentKind::TropicalFishBaseColor;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct TropicalFishPatternColor {
pub color: DyeColor,
}
impl DataComponent for TropicalFishPatternColor {
const KIND: DataComponentKind = DataComponentKind::TropicalFishPatternColor;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct MooshroomVariant {
pub variant: registry::MooshroomVariant,
}
impl DataComponent for MooshroomVariant {
const KIND: DataComponentKind = DataComponentKind::MooshroomVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct RabbitVariant {
pub variant: registry::RabbitVariant,
}
impl DataComponent for RabbitVariant {
const KIND: DataComponentKind = DataComponentKind::RabbitVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct PigVariant {
pub variant: registry::PigVariant,
}
impl DataComponent for PigVariant {
const KIND: DataComponentKind = DataComponentKind::PigVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct FrogVariant {
pub variant: registry::FrogVariant,
}
impl DataComponent for FrogVariant {
const KIND: DataComponentKind = DataComponentKind::FrogVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct HorseVariant {
pub variant: registry::HorseVariant,
}
impl DataComponent for HorseVariant {
const KIND: DataComponentKind = DataComponentKind::HorseVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct PaintingVariant {
pub variant: registry::PaintingVariant,
}
impl DataComponent for PaintingVariant {
const KIND: DataComponentKind = DataComponentKind::PaintingVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct LlamaVariant {
pub variant: registry::LlamaVariant,
}
impl DataComponent for LlamaVariant {
const KIND: DataComponentKind = DataComponentKind::LlamaVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct AxolotlVariant {
pub variant: registry::AxolotlVariant,
}
impl DataComponent for AxolotlVariant {
const KIND: DataComponentKind = DataComponentKind::AxolotlVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct CatVariant {
pub variant: registry::CatVariant,
}
impl DataComponent for CatVariant {
const KIND: DataComponentKind = DataComponentKind::CatVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct CatCollar {
pub color: DyeColor,
}
impl DataComponent for CatCollar {
const KIND: DataComponentKind = DataComponentKind::CatCollar;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct SheepColor {
pub color: DyeColor,
}
impl DataComponent for SheepColor {
const KIND: DataComponentKind = DataComponentKind::SheepColor;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct ShulkerColor {
pub color: DyeColor,
}
impl DataComponent for ShulkerColor {
const KIND: DataComponentKind = DataComponentKind::ShulkerColor;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct TooltipDisplay {
pub hide_tooltip: bool,
pub hidden_components: Vec<DataComponentKind>,
}
impl DataComponent for TooltipDisplay {
const KIND: DataComponentKind = DataComponentKind::TooltipDisplay;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct BlocksAttacks {
pub block_delay_seconds: f32,
pub disable_cooldown_scale: f32,
pub damage_reductions: Vec<DamageReduction>,
pub item_damage: ItemDamageFunction,
pub bypassed_by: Option<ResourceLocation>,
pub block_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
pub disable_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
}
impl DataComponent for BlocksAttacks {
const KIND: DataComponentKind = DataComponentKind::BlocksAttacks;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct DamageReduction {
pub horizontal_blocking_angle: f32,
pub kind: Option<HolderSet<DamageKind, ResourceLocation>>,
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct ItemDamageFunction {
pub threshold: f32,
pub base: f32,
pub factor: f32,
}
#[derive(Clone, PartialEq, AzBuf)]
pub enum ProvidesTrimMaterial {
Holder(Holder<TrimMaterial, DirectTrimMaterial>),
Registry(TrimMaterial),
}
impl DataComponent for ProvidesTrimMaterial {
const KIND: DataComponentKind = DataComponentKind::ProvidesTrimMaterial;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct DirectTrimMaterial {
pub assets: MaterialAssetGroup,
pub description: FormattedText,
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct MaterialAssetGroup {
pub base: AssetInfo,
pub overrides: Vec<(ResourceLocation, AssetInfo)>,
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct AssetInfo {
pub suffix: String,
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct ProvidesBannerPatterns {
pub key: ResourceLocation,
}
impl DataComponent for ProvidesBannerPatterns {
const KIND: DataComponentKind = DataComponentKind::ProvidesBannerPatterns;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct BreakSound {
pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
}
impl DataComponent for BreakSound {
const KIND: DataComponentKind = DataComponentKind::BreakSound;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct WolfSoundVariant {
pub variant: azalea_registry::WolfSoundVariant,
}
impl DataComponent for WolfSoundVariant {
const KIND: DataComponentKind = DataComponentKind::WolfSoundVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct CowVariant {
pub variant: azalea_registry::CowVariant,
}
impl DataComponent for CowVariant {
const KIND: DataComponentKind = DataComponentKind::CowVariant;
}
#[derive(Clone, PartialEq, AzBuf)]
pub struct ChickenVariant {
pub variant: azalea_registry::ChickenVariant,
}
impl DataComponent for ChickenVariant {
const KIND: DataComponentKind = DataComponentKind::ChickenVariant;
}

View file

@ -89,6 +89,8 @@
"advancements.adventure.two_birds_one_arrow.title": "Two Birds, One Arrow",
"advancements.adventure.under_lock_and_key.description": "Unlock a Vault with a Trial Key",
"advancements.adventure.under_lock_and_key.title": "Under Lock and Key",
"advancements.adventure.use_lodestone.description": "Use a Compass on a Lodestone",
"advancements.adventure.use_lodestone.title": "Country Lode, Take Me Home",
"advancements.adventure.very_very_frightening.description": "Strike a Villager with lightning",
"advancements.adventure.very_very_frightening.title": "Very Very Frightening",
"advancements.adventure.voluntary_exile.description": "Kill a raid captain.\nMaybe consider staying away from villages for the time being...",
@ -354,6 +356,7 @@
"argument.message.too_long": "Chat message was too long (%s > maximum %s characters)",
"argument.nbt.array.invalid": "Invalid array type '%s'",
"argument.nbt.array.mixed": "Can't insert %s into %s",
"argument.nbt.expected.compound": "Expected compound tag",
"argument.nbt.expected.key": "Expected key",
"argument.nbt.expected.value": "Expected value",
"argument.nbt.list.mixed": "Can't insert %s into list of %s",
@ -374,6 +377,7 @@
"argument.range.swapped": "Min cannot be bigger than max",
"argument.resource_or_id.failed_to_parse": "Failed to parse structure: %s",
"argument.resource_or_id.invalid": "Invalid id or tag",
"argument.resource_selector.not_found": "No matches for selector '%s' of type '%s'",
"argument.resource_tag.invalid_type": "Tag '%s' has wrong type '%s' (expected '%s')",
"argument.resource_tag.not_found": "Can't find tag '%s' of type '%s'",
"argument.resource.invalid_type": "Element '%s' has wrong type '%s' (expected '%s')",
@ -1387,7 +1391,9 @@
"block.minecraft.bubble_coral_fan": "Bubble Coral Fan",
"block.minecraft.bubble_coral_wall_fan": "Bubble Coral Wall Fan",
"block.minecraft.budding_amethyst": "Budding Amethyst",
"block.minecraft.bush": "Bush",
"block.minecraft.cactus": "Cactus",
"block.minecraft.cactus_flower": "Cactus Flower",
"block.minecraft.cake": "Cake",
"block.minecraft.calcite": "Calcite",
"block.minecraft.calibrated_sculk_sensor": "Calibrated Sculk Sensor",
@ -1618,6 +1624,7 @@
"block.minecraft.fire_coral_block": "Fire Coral Block",
"block.minecraft.fire_coral_fan": "Fire Coral Fan",
"block.minecraft.fire_coral_wall_fan": "Fire Coral Wall Fan",
"block.minecraft.firefly_bush": "Firefly Bush",
"block.minecraft.fletching_table": "Fletching Table",
"block.minecraft.flower_pot": "Flower Pot",
"block.minecraft.flowering_azalea": "Flowering Azalea",
@ -1720,6 +1727,7 @@
"block.minecraft.large_fern": "Large Fern",
"block.minecraft.lava": "Lava",
"block.minecraft.lava_cauldron": "Lava Cauldron",
"block.minecraft.leaf_litter": "Leaf Litter",
"block.minecraft.lectern": "Lectern",
"block.minecraft.lever": "Lever",
"block.minecraft.light": "Light",
@ -2097,6 +2105,7 @@
"block.minecraft.sea_pickle": "Sea Pickle",
"block.minecraft.seagrass": "Seagrass",
"block.minecraft.set_spawn": "Respawn point set",
"block.minecraft.short_dry_grass": "Short Dry Grass",
"block.minecraft.short_grass": "Short Grass",
"block.minecraft.shroomlight": "Shroomlight",
"block.minecraft.shulker_box": "Shulker Box",
@ -2193,12 +2202,16 @@
"block.minecraft.suspicious_gravel": "Suspicious Gravel",
"block.minecraft.suspicious_sand": "Suspicious Sand",
"block.minecraft.sweet_berry_bush": "Sweet Berry Bush",
"block.minecraft.tall_dry_grass": "Tall Dry Grass",
"block.minecraft.tall_grass": "Tall Grass",
"block.minecraft.tall_seagrass": "Tall Seagrass",
"block.minecraft.target": "Target",
"block.minecraft.terracotta": "Terracotta",
"block.minecraft.test_block": "Test Block",
"block.minecraft.test_instance_block": "Test Instance Block",
"block.minecraft.tinted_glass": "Tinted Glass",
"block.minecraft.tnt": "TNT",
"block.minecraft.tnt.disabled": "TNT explosions are disabled",
"block.minecraft.torch": "Torch",
"block.minecraft.torchflower": "Torchflower",
"block.minecraft.torchflower_crop": "Torchflower Crop",
@ -2310,6 +2323,7 @@
"block.minecraft.white_terracotta": "White Terracotta",
"block.minecraft.white_tulip": "White Tulip",
"block.minecraft.white_wool": "White Wool",
"block.minecraft.wildflowers": "Wildflowers",
"block.minecraft.wither_rose": "Wither Rose",
"block.minecraft.wither_skeleton_skull": "Wither Skeleton Skull",
"block.minecraft.wither_skeleton_wall_skull": "Wither Skeleton Wall Skull",
@ -2697,11 +2711,11 @@
"commands.random.roll": "%s rolled %s (from %s to %s)",
"commands.random.sample.success": "Randomized value: %s",
"commands.recipe.give.failed": "No new recipes were learned",
"commands.recipe.give.success.multiple": "Unlocked %s recipes for %s players",
"commands.recipe.give.success.single": "Unlocked %s recipes for %s",
"commands.recipe.give.success.multiple": "Unlocked %s recipe(s) for %s players",
"commands.recipe.give.success.single": "Unlocked %s recipe(s) for %s",
"commands.recipe.take.failed": "No recipes could be forgotten",
"commands.recipe.take.success.multiple": "Took %s recipes from %s players",
"commands.recipe.take.success.single": "Took %s recipes from %s",
"commands.recipe.take.success.multiple": "Took %s recipe(s) from %s players",
"commands.recipe.take.success.single": "Took %s recipe(s) from %s",
"commands.reload.failure": "Reload failed; keeping old data",
"commands.reload.success": "Reloading!",
"commands.ride.already_riding": "%s is already riding %s",
@ -2848,6 +2862,32 @@
"commands.teleport.success.entity.single": "Teleported %s to %s",
"commands.teleport.success.location.multiple": "Teleported %s entities to %s, %s, %s",
"commands.teleport.success.location.single": "Teleported %s to %s, %s, %s",
"commands.test.batch.starting": "Starting environment %s batch %s",
"commands.test.clear.error.no_tests": "Could not find any tests to clear",
"commands.test.clear.success": "Cleared %s structure(s)",
"commands.test.coordinates": "%s, %s, %s",
"commands.test.coordinates.copy": "Click to copy to clipboard",
"commands.test.create.success": "Created test setup for test %s",
"commands.test.error.no_test_containing_pos": "Can't find a test instance that contains %s, %s, %s",
"commands.test.error.no_test_instances": "Found no test instances",
"commands.test.error.non_existant_test": "Test %s could not be found",
"commands.test.error.structure_not_found": "Test structure %s could not be found",
"commands.test.error.test_instance_not_found": "Test instance block entity could not be found",
"commands.test.error.test_instance_not_found.position": "Test instance block entity could not be found for test at %s, %s, %s",
"commands.test.error.too_large": "The structure size must be less than %s blocks along each axis",
"commands.test.locate.done": "Finished locating, found %s structure(s)",
"commands.test.locate.found": "Found structure at: %s (distance: %s)",
"commands.test.locate.started": "Started locating test structures, this might take a while...",
"commands.test.no_tests": "No tests to run",
"commands.test.relative_position": "Position relative to %s: %s",
"commands.test.reset.error.no_tests": "Could not find any tests to reset",
"commands.test.reset.success": "Reset %s structure(s)",
"commands.test.run.no_tests": "No tests found",
"commands.test.run.running": "Running %s test(s)...",
"commands.test.summary": "Game Test complete! %s test(s) were run",
"commands.test.summary.all_required_passed": "All required tests passed :)",
"commands.test.summary.failed": "%s required test(s) failed :(",
"commands.test.summary.optional_failed": "%s optional test(s) failed",
"commands.tick.query.percentiles": "Percentiles: P50: %sms P95: %sms P99: %sms, sample: %s",
"commands.tick.query.rate.running": "Target tick rate: %s per second.\nAverage time per tick: %sms (Target: %sms)",
"commands.tick.query.rate.sprinting": "Target tick rate: %s per second (ignored, reference only).\nAverage time per tick: %sms",
@ -2980,7 +3020,7 @@
"controls.resetAll": "Reset Keys",
"controls.title": "Controls",
"createWorld.customize.buffet.biome": "Please select a biome",
"createWorld.customize.buffet.title": "Buffet world customization",
"createWorld.customize.buffet.title": "Single Biome Customization",
"createWorld.customize.flat.height": "Height",
"createWorld.customize.flat.layer": "%s",
"createWorld.customize.flat.layer.bottom": "Bottom - %s",
@ -2989,7 +3029,7 @@
"createWorld.customize.flat.tile": "Layer Material",
"createWorld.customize.flat.title": "Superflat Customization",
"createWorld.customize.presets": "Presets",
"createWorld.customize.presets.list": "Alternatively, here's some we made earlier!",
"createWorld.customize.presets.list": "Alternatively, here are some we made earlier!",
"createWorld.customize.presets.select": "Use Preset",
"createWorld.customize.presets.share": "Want to share your preset with someone? Use the box below!",
"createWorld.customize.presets.title": "Select a Preset",
@ -3393,6 +3433,7 @@
"entity.minecraft.killer_bunny": "The Killer Bunny",
"entity.minecraft.leash_knot": "Leash Knot",
"entity.minecraft.lightning_bolt": "Lightning Bolt",
"entity.minecraft.lingering_potion": "Lingering Potion",
"entity.minecraft.llama": "Llama",
"entity.minecraft.llama_spit": "Llama Spit",
"entity.minecraft.magma_cube": "Magma Cube",
@ -3437,6 +3478,7 @@
"entity.minecraft.spawner_minecart": "Minecart with Monster Spawner",
"entity.minecraft.spectral_arrow": "Spectral Arrow",
"entity.minecraft.spider": "Spider",
"entity.minecraft.splash_potion": "Splash Potion",
"entity.minecraft.spruce_boat": "Spruce Boat",
"entity.minecraft.spruce_chest_boat": "Spruce Boat with Chest",
"entity.minecraft.squid": "Squid",
@ -3551,9 +3593,11 @@
"gameMode.adventure": "Adventure Mode",
"gameMode.changed": "Your game mode has been updated to %s",
"gameMode.creative": "Creative Mode",
"gameMode.hardcore": "Hardcore Mode!",
"gameMode.hardcore": "Hardcore Mode",
"gameMode.spectator": "Spectator Mode",
"gameMode.survival": "Survival Mode",
"gamerule.allowFireTicksAwayFromPlayer": "Tick fire away from players",
"gamerule.allowFireTicksAwayFromPlayer.description": "Controls whether or not fire and lava should be able to tick further than 8 chunks away from any player",
"gamerule.announceAdvancements": "Announce advancements",
"gamerule.blockExplosionDropDecay": "In block interaction explosions, some blocks won't drop their loot",
"gamerule.blockExplosionDropDecay.description": "Some of the drops from blocks destroyed by explosions caused by block interactions are lost in the explosion.",
@ -3637,6 +3681,7 @@
"gamerule.spawnRadius": "Respawn location radius",
"gamerule.spawnRadius.description": "Controls the size of the area around the spawn point that players can spawn in.",
"gamerule.spectatorsGenerateChunks": "Allow spectators to generate terrain",
"gamerule.tntExplodes": "Allow TNT to be activated and to explode",
"gamerule.tntExplosionDropDecay": "In TNT explosions, some blocks won't drop their loot",
"gamerule.tntExplosionDropDecay.description": "Some of the drops from blocks destroyed by explosions caused by TNT are lost in the explosion.",
"gamerule.universalAnger": "Universal anger",
@ -3911,6 +3956,7 @@
"item.minecraft.blaze_spawn_egg": "Blaze Spawn Egg",
"item.minecraft.blue_bundle": "Blue Bundle",
"item.minecraft.blue_dye": "Blue Dye",
"item.minecraft.blue_egg": "Blue Egg",
"item.minecraft.bogged_spawn_egg": "Bogged Spawn Egg",
"item.minecraft.bolt_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.bolt_armor_trim_smithing_template.new": "Bolt Armor Trim",
@ -3929,6 +3975,7 @@
"item.minecraft.brick": "Brick",
"item.minecraft.brown_bundle": "Brown Bundle",
"item.minecraft.brown_dye": "Brown Dye",
"item.minecraft.brown_egg": "Brown Egg",
"item.minecraft.brush": "Brush",
"item.minecraft.bucket": "Bucket",
"item.minecraft.bundle": "Bundle",
@ -3983,6 +4030,8 @@
"item.minecraft.creeper_spawn_egg": "Creeper Spawn Egg",
"item.minecraft.crossbow": "Crossbow",
"item.minecraft.crossbow.projectile": "Projectile:",
"item.minecraft.crossbow.projectile.multiple": "Projectile: %s x %s",
"item.minecraft.crossbow.projectile.single": "Projectile: %s",
"item.minecraft.cyan_bundle": "Cyan Bundle",
"item.minecraft.cyan_dye": "Cyan Dye",
"item.minecraft.danger_pottery_shard": "Danger Pottery Shard",
@ -4039,6 +4088,8 @@
"item.minecraft.fire_charge": "Fire Charge",
"item.minecraft.firework_rocket": "Firework Rocket",
"item.minecraft.firework_rocket.flight": "Flight Duration:",
"item.minecraft.firework_rocket.multiple_stars": "%s x %s",
"item.minecraft.firework_rocket.single_star": "%s",
"item.minecraft.firework_star": "Firework Star",
"item.minecraft.firework_star.black": "Black",
"item.minecraft.firework_star.blue": "Blue",
@ -4575,13 +4626,14 @@
"item.modifiers.any": "When equipped:",
"item.modifiers.armor": "When worn:",
"item.modifiers.body": "When equipped:",
"item.modifiers.chest": "When on Body:",
"item.modifiers.chest": "When on Chest:",
"item.modifiers.feet": "When on Feet:",
"item.modifiers.hand": "When held:",
"item.modifiers.head": "When on Head:",
"item.modifiers.legs": "When on Legs:",
"item.modifiers.mainhand": "When in Main Hand:",
"item.modifiers.offhand": "When in Off Hand:",
"item.modifiers.saddle": "When saddled:",
"item.nbt_tags": "NBT: %s tag(s)",
"item.op_block_warning.line1": "Warning:",
"item.op_block_warning.line2": "Use of this item might lead to command execution",
@ -4817,15 +4869,15 @@
"mco.backup.generate.world": "Generate world",
"mco.backup.info.title": "Changes From Last Backup",
"mco.backup.narration": "Backup from %s",
"mco.backup.nobackups": "This realm doesn't have any backups currently.",
"mco.backup.restoring": "Restoring your realm",
"mco.backup.nobackups": "This Realm doesn't have any backups currently.",
"mco.backup.restoring": "Restoring your Realm",
"mco.backup.unknown": "UNKNOWN",
"mco.brokenworld.download": "Download",
"mco.brokenworld.downloaded": "Downloaded",
"mco.brokenworld.message.line1": "Please reset or select another world.",
"mco.brokenworld.message.line2": "You can also choose to download the world to singleplayer.",
"mco.brokenworld.minigame.title": "This minigame is no longer supported",
"mco.brokenworld.nonowner.error": "Please wait for the realm owner to reset the world",
"mco.brokenworld.nonowner.error": "Please wait for the Realm owner to reset the world",
"mco.brokenworld.nonowner.title": "World is out of date",
"mco.brokenworld.play": "Play",
"mco.brokenworld.reset": "Reset",
@ -4864,12 +4916,12 @@
"mco.configure.world.buttons.settings": "Settings",
"mco.configure.world.buttons.subscription": "Subscription",
"mco.configure.world.buttons.switchminigame": "Switch Minigame",
"mco.configure.world.close.question.line1": "Your realm will become unavailable.",
"mco.configure.world.close.question.line1": "Your Realm will become unavailable.",
"mco.configure.world.close.question.line2": "Are you sure you want to continue?",
"mco.configure.world.closing": "Closing the realm...",
"mco.configure.world.closing": "Closing the Realm...",
"mco.configure.world.commandBlocks": "Command Blocks",
"mco.configure.world.delete.button": "Delete Realm",
"mco.configure.world.delete.question.line1": "Your realm will be permanently deleted",
"mco.configure.world.delete.question.line1": "Your Realm will be permanently deleted",
"mco.configure.world.delete.question.line2": "Are you sure you want to continue?",
"mco.configure.world.description": "Realm Description",
"mco.configure.world.edit.slot.name": "World Name",
@ -4884,20 +4936,20 @@
"mco.configure.world.invites.normal.tooltip": "Normal User",
"mco.configure.world.invites.ops.tooltip": "Operator",
"mco.configure.world.invites.remove.tooltip": "Remove",
"mco.configure.world.leave.question.line1": "If you leave this realm you won't see it unless you are invited again",
"mco.configure.world.leave.question.line1": "If you leave this Realm you won't see it unless you are invited again",
"mco.configure.world.leave.question.line2": "Are you sure you want to continue?",
"mco.configure.world.location": "Location",
"mco.configure.world.minigame": "Current: %s",
"mco.configure.world.name": "Realm Name",
"mco.configure.world.opening": "Opening the realm...",
"mco.configure.world.opening": "Opening the Realm...",
"mco.configure.world.players.error": "A player with the provided name does not exist",
"mco.configure.world.players.inviting": "Inviting player...",
"mco.configure.world.players.title": "Players",
"mco.configure.world.pvp": "PVP",
"mco.configure.world.reset.question.line1": "Your world will be regenerated and your current world will be lost",
"mco.configure.world.reset.question.line2": "Are you sure you want to continue?",
"mco.configure.world.resourcepack.question": "You need a custom resource pack to play on this realm\n\nDo you want to download it and play?",
"mco.configure.world.resourcepack.question.line1": "You need a custom resource pack to play on this realm",
"mco.configure.world.resourcepack.question": "You need a custom resource pack to play on this Realm\n\nDo you want to download it and play?",
"mco.configure.world.resourcepack.question.line1": "You need a custom resource pack to play on this Realm",
"mco.configure.world.resourcepack.question.line2": "Do you want to download it and play?",
"mco.configure.world.restore.download.question.line1": "The world will be downloaded and added to your single player worlds.",
"mco.configure.world.restore.download.question.line2": "Do you want to continue?",
@ -4906,7 +4958,7 @@
"mco.configure.world.settings.title": "Settings",
"mco.configure.world.slot": "World %s",
"mco.configure.world.slot.empty": "Empty",
"mco.configure.world.slot.switch.question.line1": "Your realm will be switched to another world",
"mco.configure.world.slot.switch.question.line1": "Your Realm will be switched to another world",
"mco.configure.world.slot.switch.question.line2": "Are you sure you want to continue?",
"mco.configure.world.slot.tooltip": "Switch to world",
"mco.configure.world.slot.tooltip.active": "Join",
@ -4942,20 +4994,20 @@
"mco.configure.world.uninvite.question": "Are you sure that you want to uninvite",
"mco.configure.worlds.title": "Worlds",
"mco.connect.authorizing": "Logging in...",
"mco.connect.connecting": "Connecting to the realm...",
"mco.connect.failed": "Failed to connect to the realm",
"mco.connect.connecting": "Connecting to the Realm...",
"mco.connect.failed": "Failed to connect to the Realm",
"mco.connect.success": "Done",
"mco.create.world": "Create",
"mco.create.world.error": "You must enter a name!",
"mco.create.world.failed": "Failed to create world!",
"mco.create.world.reset.title": "Creating world...",
"mco.create.world.skip": "Skip",
"mco.create.world.subtitle": "Optionally, select what world to put on your new realm",
"mco.create.world.wait": "Creating the realm...",
"mco.create.world.subtitle": "Optionally, select what world to put on your new Realm",
"mco.create.world.wait": "Creating the Realm...",
"mco.download.cancelled": "Download cancelled",
"mco.download.confirmation.line1": "The world you are going to download is larger than %s",
"mco.download.confirmation.line2": "You won't be able to upload this world to your realm again",
"mco.download.confirmation.oversized": "The world you are going to download is larger than %s\n\nYou won't be able to upload this world to your realm again",
"mco.download.confirmation.line2": "You won't be able to upload this world to your Realm again",
"mco.download.confirmation.oversized": "The world you are going to download is larger than %s\n\nYou won't be able to upload this world to your Realm again",
"mco.download.done": "Download done",
"mco.download.downloading": "Downloading",
"mco.download.extracting": "Extracting",
@ -5001,7 +5053,7 @@
"mco.minigame.world.info.line2": "You can later return to your original world without losing anything.",
"mco.minigame.world.noSelection": "Please make a selection",
"mco.minigame.world.restore": "Ending Minigame...",
"mco.minigame.world.restore.question.line1": "The minigame will end and your realm will be restored.",
"mco.minigame.world.restore.question.line1": "The minigame will end and your Realm will be restored.",
"mco.minigame.world.restore.question.line2": "Are you sure you want to continue?",
"mco.minigame.world.selected": "Selected Minigame:",
"mco.minigame.world.slot.screen.title": "Switching World...",
@ -5028,16 +5080,16 @@
"mco.reset.world.template": "World Templates",
"mco.reset.world.title": "Reset World",
"mco.reset.world.upload": "Upload world",
"mco.reset.world.warning": "This will replace the current world of your realm",
"mco.reset.world.warning": "This will replace the current world of your Realm",
"mco.selectServer.buy": "Buy a Realm!",
"mco.selectServer.close": "Close",
"mco.selectServer.closed": "Closed realm",
"mco.selectServer.closeserver": "Close realm",
"mco.selectServer.closed": "Closed Realm",
"mco.selectServer.closeserver": "Close Realm",
"mco.selectServer.configure": "Configure",
"mco.selectServer.configureRealm": "Configure realm",
"mco.selectServer.configureRealm": "Configure Realm",
"mco.selectServer.create": "Create Realm",
"mco.selectServer.create.subtitle": "Select what world to put on your new realm",
"mco.selectServer.expired": "Expired realm",
"mco.selectServer.create.subtitle": "Select what world to put on your new Realm",
"mco.selectServer.expired": "Expired Realm",
"mco.selectServer.expiredList": "Your subscription has expired",
"mco.selectServer.expiredRenew": "Renew",
"mco.selectServer.expiredSubscribe": "Subscribe",
@ -5053,13 +5105,13 @@
"mco.selectServer.minigameNotSupportedInVersion": "Can't play this minigame in %s",
"mco.selectServer.noRealms": "You don't seem to have a Realm. Add a Realm to play together with your friends.",
"mco.selectServer.note": "Note:",
"mco.selectServer.open": "Open realm",
"mco.selectServer.openserver": "Open realm",
"mco.selectServer.open": "Open Realm",
"mco.selectServer.openserver": "Open Realm",
"mco.selectServer.play": "Play",
"mco.selectServer.popup": "Realms is a safe, simple way to enjoy an online Minecraft world with up to ten friends at a time. It supports loads of minigames and plenty of custom worlds! Only the owner of the realm needs to pay.",
"mco.selectServer.purchase": "Add Realm",
"mco.selectServer.trial": "Get a Trial!",
"mco.selectServer.uninitialized": "Click to start your new realm!",
"mco.selectServer.uninitialized": "Click to start your new Realm!",
"mco.snapshot.createSnapshotPopup.text": "You are about to create a free Snapshot Realm that will be paired with your paid Realms subscription. This new Snapshot Realm will be accessible for as long as the paid subscription is active. Your paid Realm will not be affected.",
"mco.snapshot.createSnapshotPopup.title": "Create Snapshot Realm?",
"mco.snapshot.creating": "Creating Snapshot Realm...",
@ -5098,11 +5150,11 @@
"mco.time.minutesAgo": "%1$s minute(s) ago",
"mco.time.now": "right now",
"mco.time.secondsAgo": "%1$s second(s) ago",
"mco.trial.message.line1": "Want to get your own realm?",
"mco.trial.message.line1": "Want to get your own Realm?",
"mco.trial.message.line2": "Click here for more info!",
"mco.upload.button.name": "Upload",
"mco.upload.cancelled": "Upload cancelled",
"mco.upload.close.failure": "Could not close your realm, please try again later",
"mco.upload.close.failure": "Could not close your Realm, please try again later",
"mco.upload.done": "Upload done",
"mco.upload.entry.cheats": "%1$s, %2$s",
"mco.upload.entry.commands": "%1$s, %2$s",
@ -5162,6 +5214,7 @@
"mount.onboard": "Press %1$s to Dismount",
"multiplayer.applyingPack": "Applying resource pack",
"multiplayer.disconnect.authservers_down": "Authentication servers are down. Please try again later, sorry!",
"multiplayer.disconnect.bad_chat_index": "Detected missed or reordered chat message from server",
"multiplayer.disconnect.banned": "You are banned from this server",
"multiplayer.disconnect.banned_ip.expiration": "\nYour ban will be removed on %s",
"multiplayer.disconnect.banned_ip.reason": "Your IP address is banned from this server.\nReason: %s",
@ -5697,7 +5750,7 @@
"realms.missing.snapshot.error.text": "Realms is currently not supported in snapshots",
"recipe.notFound": "Unknown recipe: %s",
"recipe.toast.description": "Check your recipe book",
"recipe.toast.title": "New Recipes Unlocked!",
"recipe.toast.title": "New Recipe(s) Unlocked!",
"record.nowPlaying": "Now Playing: %s",
"recover_world.bug_tracker": "Report a Bug",
"recover_world.button": "Attempt to Recover",
@ -5868,6 +5921,27 @@
"sleep.skipping_night": "Sleeping through this night",
"slot.only_single_allowed": "Only single slots allowed, got '%s'",
"slot.unknown": "Unknown slot '%s'",
"snbt.parser.empty_key": "Key cannot be empty",
"snbt.parser.expected_binary_numeral": "Expected a binary number",
"snbt.parser.expected_decimal_numeral": "Expected a decimal number",
"snbt.parser.expected_float_type": "Expected a floating point number",
"snbt.parser.expected_hex_escape": "Expected a character literal of length %s",
"snbt.parser.expected_hex_numeral": "Expected a hexadecimal number",
"snbt.parser.expected_integer_type": "Expected an integer number",
"snbt.parser.expected_non_negative_number": "Expected a non-negative number",
"snbt.parser.expected_number_or_boolean": "Expected a number or a boolean",
"snbt.parser.expected_string_uuid": "Expected a string representing a valid UUID",
"snbt.parser.expected_unquoted_string": "Expected a valid unquoted string",
"snbt.parser.infinity_not_allowed": "Non-finite numbers are not allowed",
"snbt.parser.invalid_array_element_type": "Invalid array element type",
"snbt.parser.invalid_character_name": "Invalid Unicode character name",
"snbt.parser.invalid_codepoint": "Invalid Unicode character value: %s",
"snbt.parser.invalid_string_contents": "Invalid string contents",
"snbt.parser.invalid_unquoted_start": "Unquoted strings can't start with digits 0-9, + or -",
"snbt.parser.leading_zero_not_allowed": "Decimal numbers can't start with 0",
"snbt.parser.no_such_operation": "No such operation: %s",
"snbt.parser.number_parse_failure": "Failed to parse number: %s",
"snbt.parser.undescore_not_allowed": "Underscore characters are not allowed at the start or end of a number",
"soundCategory.ambient": "Ambient/Environment",
"soundCategory.block": "Blocks",
"soundCategory.hostile": "Hostile Creatures",
@ -5992,10 +6066,10 @@
"structure_block.load_not_found": "Structure '%s' is not available",
"structure_block.load_prepare": "Structure '%s' position prepared",
"structure_block.load_success": "Structure loaded from '%s'",
"structure_block.mode_info.corner": "Corner Mode - Placement and Size Marker",
"structure_block.mode_info.data": "Data Mode - Game Logic Marker",
"structure_block.mode_info.load": "Load Mode - Load from File",
"structure_block.mode_info.save": "Save Mode - Write to File",
"structure_block.mode_info.corner": "Corner Mode - Placement and size marker",
"structure_block.mode_info.data": "Data Mode - Game logic marker",
"structure_block.mode_info.load": "Load Mode - Load from file",
"structure_block.mode_info.save": "Save Mode - Write to file",
"structure_block.mode.corner": "Corner",
"structure_block.mode.data": "Data",
"structure_block.mode.load": "Load",
@ -6014,6 +6088,7 @@
"structure_block.size.x": "structure size x",
"structure_block.size.y": "structure size y",
"structure_block.size.z": "structure size z",
"structure_block.strict": "Strict Placement:",
"structure_block.structure_name": "Structure Name",
"subtitles.ambient.cave": "Eerie noise",
"subtitles.ambient.sound": "Eerie noise",
@ -6071,6 +6146,7 @@
"subtitles.block.creaking_heart.hurt": "Creaking Heart grumbles",
"subtitles.block.creaking_heart.idle": "Eerie noise",
"subtitles.block.creaking_heart.spawn": "Creaking Heart awakens",
"subtitles.block.deadbush.idle": "Dry sounds",
"subtitles.block.decorated_pot.insert": "Decorated Pot fills",
"subtitles.block.decorated_pot.insert_fail": "Decorated Pot wobbles",
"subtitles.block.decorated_pot.shatter": "Decorated Pot shatters",
@ -6086,6 +6162,7 @@
"subtitles.block.fence_gate.toggle": "Fence Gate creaks",
"subtitles.block.fire.ambient": "Fire crackles",
"subtitles.block.fire.extinguish": "Fire extinguished",
"subtitles.block.firefly_bush.idle": "Fireflies buzz",
"subtitles.block.frogspawn.hatch": "Tadpole hatches",
"subtitles.block.furnace.fire_crackle": "Furnace crackles",
"subtitles.block.generic.break": "Block broken",
@ -6120,14 +6197,16 @@
"subtitles.block.respawn_anchor.charge": "Respawn Anchor is charged",
"subtitles.block.respawn_anchor.deplete": "Respawn Anchor depletes",
"subtitles.block.respawn_anchor.set_spawn": "Respawn Anchor sets spawn",
"subtitles.block.sand.idle": "Sandy sounds",
"subtitles.block.sand.wind": "Windy sounds",
"subtitles.block.sculk_catalyst.bloom": "Sculk Catalyst blooms",
"subtitles.block.sculk_sensor.clicking": "Sculk Sensor clicks",
"subtitles.block.sculk_sensor.clicking_stop": "Sculk Sensor stops clicking",
"subtitles.block.sculk_shrieker.shriek": "Sculk Shrieker shrieks",
"subtitles.block.sculk.charge": "Sculk bubbles",
"subtitles.block.sculk.spread": "Sculk spreads",
"subtitles.block.shulker_box.close": "Shulker closes",
"subtitles.block.shulker_box.open": "Shulker opens",
"subtitles.block.shulker_box.close": "Shulker box closes",
"subtitles.block.shulker_box.open": "Shulker box opens",
"subtitles.block.sign.waxed_interact_fail": "Sign wobbles",
"subtitles.block.smithing_table.use": "Smithing Table used",
"subtitles.block.smoker.smoke": "Smoker smokes",
@ -6754,10 +6833,13 @@
"subtitles.entity.wither.shoot": "Wither attacks",
"subtitles.entity.wither.spawn": "Wither released",
"subtitles.entity.wolf.ambient": "Wolf pants",
"subtitles.entity.wolf.bark": "Wolf barks",
"subtitles.entity.wolf.death": "Wolf dies",
"subtitles.entity.wolf.growl": "Wolf growls",
"subtitles.entity.wolf.hurt": "Wolf hurts",
"subtitles.entity.wolf.pant": "Wolf pants",
"subtitles.entity.wolf.shake": "Wolf shakes",
"subtitles.entity.wolf.whine": "Wolf whines",
"subtitles.entity.zoglin.ambient": "Zoglin growls",
"subtitles.entity.zoglin.angry": "Zoglin growls angrily",
"subtitles.entity.zoglin.attack": "Zoglin attacks",
@ -6933,6 +7015,85 @@
"telemetry.property.user_id.title": "User ID",
"telemetry.property.world_load_time_ms.title": "World Load Time (Milliseconds)",
"telemetry.property.world_session_id.title": "World Session ID",
"test_block.error.missing": "Test structure missing %s block",
"test_block.error.too_many": "Too many %s blocks",
"test_block.invalid_timeout": "Invalid timeout (%s) - must be a positive number of ticks",
"test_block.message": "Message:",
"test_block.mode_info.accept": "Accept Mode - Accept success for (part of) a test",
"test_block.mode_info.fail": "Fail Mode - Fail the test",
"test_block.mode_info.log": "Log Mode - Log a message",
"test_block.mode_info.start": "Start Mode - The starting point for a test",
"test_block.mode.accept": "Accept",
"test_block.mode.fail": "Fail",
"test_block.mode.log": "Log",
"test_block.mode.start": "Start",
"test_instance_block.entities": "Entities:",
"test_instance_block.error.no_test": "Unable to run test instance at %s, %s, %s since it has an undefined test",
"test_instance_block.error.no_test_structure": "Unable to run test instance at %s, %s, %s since it has no test structure",
"test_instance_block.error.unable_to_save": "Unable to save test structure template for test instance at %s, %s, %s",
"test_instance_block.invalid": "[invalid]",
"test_instance_block.reset_success": "Reset succeeded for test: %s",
"test_instance_block.rotation": "Rotation:",
"test_instance_block.size": "Test Structure Size",
"test_instance_block.starting": "Starting test %s",
"test_instance_block.test_id": "Test Instance ID",
"test_instance.action.reset": "Reset and Load",
"test_instance.action.run": "Load and Run",
"test_instance.action.save": "Save Structure",
"test_instance.description.batch": "Batch: %s",
"test_instance.description.failed": "Failed: %s",
"test_instance.description.function": "Function: %s",
"test_instance.description.invalid_id": "Invalid test ID",
"test_instance.description.no_test": "No such test",
"test_instance.description.structure": "Structure: %s",
"test_instance.description.type": "Type: %s",
"test_instance.type.block_based": "Block-Based Test",
"test_instance.type.function": "Built-in Function Test",
"test.error.block_property_mismatch": "Expected property %s to be %s, was %s",
"test.error.block_property_missing": "Block property missing, expected property %s to be %s",
"test.error.entity_property": "Entity %s failed test: %s",
"test.error.entity_property_details": "Entity %s failed test: %s, expected: %s, was: %s",
"test.error.expected_block": "Expected block %s, got %s",
"test.error.expected_block_tag": "Expected block in #%s, got %s",
"test.error.expected_container_contents": "Container should contain: %s",
"test.error.expected_container_contents_single": "Container should contain a single: %s",
"test.error.expected_empty_container": "Container should be empty",
"test.error.expected_entity": "Expected %s",
"test.error.expected_entity_around": "Expected %s to exist around %s, %s, %s",
"test.error.expected_entity_count": "Expected %s entities of type %s, found %s",
"test.error.expected_entity_data": "Expected entity data to be: %s, was: %s",
"test.error.expected_entity_data_predicate": "Entity data mismatch for %s",
"test.error.expected_entity_effect": "Expected %s to have effect %s %s",
"test.error.expected_entity_having": "Entity inventory should contain %s",
"test.error.expected_entity_holding": "Entity should be holding %s",
"test.error.expected_entity_in_test": "Expected %s to exist in test",
"test.error.expected_entity_not_touching": "Did not expect %s touching %s, %s, %s (relative: %s, %s, %s)",
"test.error.expected_entity_touching": "Expected %s touching %s, %s, %s (relative: %s, %s, %s)",
"test.error.expected_item": "Expected item of type %s",
"test.error.expected_items_count": "Expected %s items of type %s, found %s",
"test.error.fail": "Fail conditions met",
"test.error.invalid_block_type": "Unexpected block type found: %s",
"test.error.missing_block_entity": "Missing block entity",
"test.error.position": "%s at %s, %s, %s (relative: %s, %s, %s) on tick %s",
"test.error.sequence.condition_already_triggered": "Condition already triggered at %s",
"test.error.sequence.condition_not_triggered": "Condition not triggered",
"test.error.sequence.invalid_tick": "Succeeded in invalid tick: expected %s",
"test.error.sequence.not_completed": "Test timed out before sequence completed",
"test.error.set_biome": "Failed to set biome for test",
"test.error.spawn_failure": "Failed to create entity %s",
"test.error.state_not_equal": "Incorrect state. Expected %s, was %s",
"test.error.structure.failure": "Failed to place test structure for %s",
"test.error.tick": "%s on tick %s",
"test.error.ticking_without_structure": "Ticking test before placing structure",
"test.error.timeout.no_result": "Didn't succeed or fail within %s ticks",
"test.error.timeout.no_sequences_finished": "No sequences finished within %s ticks",
"test.error.too_many_entities": "Expected only one %s to exist around %s, %s, %s but found %s",
"test.error.unexpected_block": "Did not expect block to be %s",
"test.error.unexpected_entity": "Did not expect %s to exist",
"test.error.unexpected_item": "Did not expect item of type %s",
"test.error.unknown": "Unknown internal error: %s",
"test.error.value_not_equal": "Expected %s to be %s, was %s",
"test.error.wrong_block_entity": "Wrong block entity type: %s",
"title.32bit.deprecation": "32-bit system detected: this may prevent you from playing in the future as a 64-bit system will be required!",
"title.32bit.deprecation.realms": "Minecraft will soon require a 64-bit system, which will prevent you from playing or using Realms on this device. You will need to manually cancel any Realms subscription.",
"title.32bit.deprecation.realms.check": "Do not show this screen again",

File diff suppressed because it is too large Load diff

View file

@ -91,6 +91,7 @@ pub enum BrigadierString {
GreedyPhrase = 2,
}
// see ArgumentTypeInfo
#[derive(Debug, Clone, AzBuf, PartialEq)]
pub enum BrigadierParser {
Bool,
@ -140,6 +141,7 @@ pub enum BrigadierParser {
ResourceOrTagKey { registry_key: ResourceLocation },
Resource { registry_key: ResourceLocation },
ResourceKey { registry_key: ResourceLocation },
ResourceSelector { registry_key: ResourceLocation },
TemplateMirror,
TemplateRotation,
Heightmap,
@ -182,7 +184,7 @@ impl AzaleaRead for BrigadierNodeStub {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let flags = FixedBitSet::<{ 8_usize.div_ceil(8) }>::azalea_read(buf)?;
if flags.index(5) || flags.index(6) || flags.index(7) {
warn!("Warning: The flags from a Brigadier node are over 31. This is probably a bug.",);
warn!("The flags from a Brigadier node are over 31. This is a bug, BrigadierParser probably needs updating.",);
}
let node_type = u8::from(flags.index(0)) + (u8::from(flags.index(1)) * 2);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
use azalea_buf::AzBuf;
use azalea_chat::{
translatable_component::{StringOrComponent, TranslatableComponent},
FormattedText,
translatable_component::{StringOrComponent, TranslatableComponent},
};
use azalea_protocol_macros::ClientboundGamePacket;
@ -25,8 +25,6 @@ impl ClientboundDisguisedChat {
let content = self.message.clone();
let target = self.chat_type.target_name.clone();
let translation_key = self.chat_type.chat_type.chat_translation_key();
let mut args = vec![
StringOrComponent::FormattedText(sender),
StringOrComponent::FormattedText(content),
@ -35,6 +33,7 @@ impl ClientboundDisguisedChat {
args.push(StringOrComponent::FormattedText(target));
}
let translation_key = self.chat_type.translation_key();
let component = TranslatableComponent::new(translation_key.to_string(), args);
FormattedText::Translatable(component)

File diff suppressed because one or more lines are too long

View file

@ -2,17 +2,20 @@ use std::io::{Cursor, Write};
use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
use azalea_chat::{
translatable_component::{StringOrComponent, TranslatableComponent},
FormattedText,
translatable_component::{StringOrComponent, TranslatableComponent},
};
use azalea_core::bitset::BitSet;
use azalea_crypto::MessageSignature;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::{ChatType, OptionalRegistry};
use azalea_registry::Holder;
use simdnbt::owned::NbtCompound;
use uuid::Uuid;
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket, PartialEq)]
pub struct ClientboundPlayerChat {
#[var]
pub global_index: u32,
pub sender: Uuid,
#[var]
pub index: u32,
@ -52,34 +55,30 @@ pub enum FilterMask {
PartiallyFiltered(BitSet),
}
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, AzBuf)]
pub struct ChatTypeBound {
pub chat_type: ChatType,
pub chat_type: Holder<azalea_registry::ChatType, DirectChatType>,
pub name: FormattedText,
pub target_name: Option<FormattedText>,
}
impl AzaleaRead for ChatTypeBound {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let Some(chat_type) = OptionalRegistry::<ChatType>::azalea_read(buf)?.0 else {
return Err(BufReadError::Custom("ChatType cannot be None".to_owned()));
};
let name = FormattedText::azalea_read(buf)?;
let target_name = Option::<FormattedText>::azalea_read(buf)?;
Ok(ChatTypeBound {
chat_type,
name,
target_name,
})
}
#[derive(Clone, Debug, PartialEq, AzBuf)]
pub struct DirectChatType {
pub chat: ChatTypeDecoration,
pub narration: ChatTypeDecoration,
}
impl AzaleaWrite for ChatTypeBound {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
OptionalRegistry(Some(self.chat_type)).azalea_write(buf)?;
self.name.azalea_write(buf)?;
self.target_name.azalea_write(buf)?;
Ok(())
}
#[derive(Clone, Debug, PartialEq, AzBuf)]
pub struct ChatTypeDecoration {
pub translation_key: String,
pub parameters: Vec<ChatTypeDecorationParameter>,
pub style: NbtCompound,
}
#[derive(Clone, Copy, Debug, PartialEq, AzBuf)]
pub enum ChatTypeDecorationParameter {
Sender = 0,
Target = 1,
Content = 2,
}
// must be in Client
@ -106,8 +105,6 @@ impl ClientboundPlayerChat {
let content = self.content();
let target = self.chat_type.target_name.clone();
let translation_key = self.chat_type.chat_type.chat_translation_key();
let mut args = vec![
StringOrComponent::FormattedText(sender),
StringOrComponent::FormattedText(content),
@ -116,12 +113,22 @@ impl ClientboundPlayerChat {
args.push(StringOrComponent::FormattedText(target));
}
let translation_key = self.chat_type.translation_key();
let component = TranslatableComponent::new(translation_key.to_string(), args);
FormattedText::Translatable(component)
}
}
impl ChatTypeBound {
pub fn translation_key<'a>(&'a self) -> &'a str {
match &self.chat_type {
Holder::Reference(r) => r.chat_translation_key(),
Holder::Direct(d) => d.chat.translation_key.as_str(),
}
}
}
impl AzaleaRead for PackedMessageSignature {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let id = u32::azalea_read_var(buf)?;

View file

@ -80,22 +80,3 @@ impl EquipmentSlot {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hypixel_set_equipment() {
let mut cursor = Cursor::new(
[
230, 25, 0, 1, 224, 6, 2, 0, 3, 0, 22, 79, 0, 0, 0, 3, 0, 0, 0, 0, 0,
]
.as_slice(),
);
let packet = ClientboundSetEquipment::azalea_read(&mut cursor).unwrap();
println!("packet {packet:?}");
assert_eq!(cursor.position(), cursor.get_ref().len() as u64);
}
}

View file

@ -1,12 +1,10 @@
use azalea_buf::AzBuf;
use azalea_chat::FormattedText;
use azalea_core::position::Vec3;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_world::MinecraftEntityId;
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
pub struct ClientboundAddExperienceOrb {
#[var]
pub id: MinecraftEntityId,
pub pos: Vec3,
pub value: u16,
pub struct ClientboundTestInstanceBlockStatus {
pub status: FormattedText,
pub size: Option<Vec3>,
}

View file

@ -13,6 +13,7 @@ pub struct ClientboundUpdateAdvancements {
pub added: Vec<AdvancementHolder>,
pub removed: Vec<ResourceLocation>,
pub progress: HashMap<ResourceLocation, AdvancementProgress>,
pub show_advancements: bool,
}
#[derive(Clone, Debug, AzBuf)]
@ -161,6 +162,7 @@ mod tests {
)]
.into_iter()
.collect(),
show_advancements: false,
};
let mut data = Vec::new();

View file

@ -7,124 +7,124 @@ declare_state_packets!(GamePacket,
Clientbound => [
bundle_delimiter, // 0x00
add_entity, // 0x01
add_experience_orb, // 0x02
animate, // 0x03
award_stats, // 0x04
block_changed_ack, // 0x05
block_destruction, // 0x06
block_entity_data, // 0x07
block_event, // 0x08
block_update, // 0x09
boss_event, // 0x0A
change_difficulty, // 0x0B
chunk_batch_finished, // 0x0C
chunk_batch_start, // 0x0D
chunks_biomes, // 0x0E
clear_titles, // 0x0F
command_suggestions, // 0x10
commands, // 0x11
container_close, // 0x12
container_set_content, // 0x13
container_set_data, // 0x14
container_set_slot, // 0x15
cookie_request, // 0x16
cooldown, // 0x17
custom_chat_completions, // 0x18
custom_payload, // 0x19
damage_event, // 0x1A
debug_sample, // 0x1B
delete_chat, // 0x1C
disconnect, // 0x1D
disguised_chat, // 0x1E
entity_event, // 0x1F
entity_position_sync, // 0x20
explode, // 0x21
forget_level_chunk, // 0x22
game_event, // 0x23
horse_screen_open, // 0x24
hurt_animation, // 0x25
initialize_border, // 0x26
keep_alive, // 0x27
level_chunk_with_light, // 0x28
level_event, // 0x29
level_particles, // 0x2A
light_update, // 0x2B
login, // 0x2C
map_item_data, // 0x2D
merchant_offers, // 0x2E
move_entity_pos, // 0x2F
move_entity_pos_rot, // 0x30
move_minecart_along_track, // 0x31
move_entity_rot, // 0x32
move_vehicle, // 0x33
open_book, // 0x34
open_screen, // 0x35
open_sign_editor, // 0x36
ping, // 0x37
pong_response, // 0x38
place_ghost_recipe, // 0x39
player_abilities, // 0x3A
player_chat, // 0x3B
player_combat_end, // 0x3C
player_combat_enter, // 0x3D
player_combat_kill, // 0x3E
player_info_remove, // 0x3F
player_info_update, // 0x40
player_look_at, // 0x41
player_position, // 0x42
player_rotation, // 0x43
recipe_book_add, // 0x44
recipe_book_remove, // 0x45
recipe_book_settings, // 0x46
remove_entities, // 0x47
remove_mob_effect, // 0x48
reset_score, // 0x49
resource_pack_pop, // 0x4A
resource_pack_push, // 0x4B
respawn, // 0x4C
rotate_head, // 0x4D
section_blocks_update, // 0x4E
select_advancements_tab, // 0x4F
server_data, // 0x50
set_action_bar_text, // 0x51
set_border_center, // 0x52
set_border_lerp_size, // 0x53
set_border_size, // 0x54
set_border_warning_delay, // 0x55
set_border_warning_distance, // 0x56
set_camera, // 0x57
set_chunk_cache_center, // 0x58
set_chunk_cache_radius, // 0x59
set_cursor_item, // 0x5A
set_default_spawn_position, // 0x5B
set_display_objective, // 0x5C
set_entity_data, // 0x5D
set_entity_link, // 0x5E
set_entity_motion, // 0x5F
set_equipment, // 0x60
set_experience, // 0x61
set_health, // 0x62
set_held_slot, // 0x63
set_objective, // 0x64
set_passengers, // 0x65
set_player_inventory, // 0x66
set_player_team, // 0x67
set_score, // 0x68
set_simulation_distance, // 0x69
set_subtitle_text, // 0x6A
set_time, // 0x6B
set_title_text, // 0x6C
set_titles_animation, // 0x6D
sound_entity, // 0x6E
sound, // 0x6F
start_configuration, // 0x70
stop_sound, // 0x71
store_cookie, // 0x72
system_chat, // 0x73
tab_list, // 0x74
tag_query, // 0x75
take_item_entity, // 0x76
teleport_entity, // 0x77
animate, // 0x02
award_stats, // 0x03
block_changed_ack, // 0x04
block_destruction, // 0x05
block_entity_data, // 0x06
block_event, // 0x07
block_update, // 0x08
boss_event, // 0x09
change_difficulty, // 0x0A
chunk_batch_finished, // 0x0B
chunk_batch_start, // 0x0C
chunks_biomes, // 0x0D
clear_titles, // 0x0E
command_suggestions, // 0x0F
commands, // 0x10
container_close, // 0x11
container_set_content, // 0x12
container_set_data, // 0x13
container_set_slot, // 0x14
cookie_request, // 0x15
cooldown, // 0x16
custom_chat_completions, // 0x17
custom_payload, // 0x18
damage_event, // 0x19
debug_sample, // 0x1A
delete_chat, // 0x1B
disconnect, // 0x1C
disguised_chat, // 0x1D
entity_event, // 0x1E
entity_position_sync, // 0x1F
explode, // 0x20
forget_level_chunk, // 0x21
game_event, // 0x22
horse_screen_open, // 0x23
hurt_animation, // 0x24
initialize_border, // 0x25
keep_alive, // 0x26
level_chunk_with_light, // 0x27
level_event, // 0x28
level_particles, // 0x29
light_update, // 0x2A
login, // 0x2B
map_item_data, // 0x2C
merchant_offers, // 0x2D
move_entity_pos, // 0x2E
move_entity_pos_rot, // 0x2F
move_minecart_along_track, // 0x30
move_entity_rot, // 0x31
move_vehicle, // 0x32
open_book, // 0x33
open_screen, // 0x34
open_sign_editor, // 0x35
ping, // 0x36
pong_response, // 0x37
place_ghost_recipe, // 0x38
player_abilities, // 0x39
player_chat, // 0x3A
player_combat_end, // 0x3B
player_combat_enter, // 0x3C
player_combat_kill, // 0x3D
player_info_remove, // 0x3E
player_info_update, // 0x3F
player_look_at, // 0x40
player_position, // 0x41
player_rotation, // 0x42
recipe_book_add, // 0x43
recipe_book_remove, // 0x44
recipe_book_settings, // 0x45
remove_entities, // 0x46
remove_mob_effect, // 0x47
reset_score, // 0x48
resource_pack_pop, // 0x49
resource_pack_push, // 0x4A
respawn, // 0x4B
rotate_head, // 0x4C
section_blocks_update, // 0x4D
select_advancements_tab, // 0x4E
server_data, // 0x4F
set_action_bar_text, // 0x50
set_border_center, // 0x51
set_border_lerp_size, // 0x52
set_border_size, // 0x53
set_border_warning_delay, // 0x54
set_border_warning_distance, // 0x55
set_camera, // 0x56
set_chunk_cache_center, // 0x57
set_chunk_cache_radius, // 0x58
set_cursor_item, // 0x59
set_default_spawn_position, // 0x5A
set_display_objective, // 0x5B
set_entity_data, // 0x5C
set_entity_link, // 0x5D
set_entity_motion, // 0x5E
set_equipment, // 0x5F
set_experience, // 0x60
set_health, // 0x61
set_held_slot, // 0x62
set_objective, // 0x63
set_passengers, // 0x64
set_player_inventory, // 0x65
set_player_team, // 0x66
set_score, // 0x67
set_simulation_distance, // 0x68
set_subtitle_text, // 0x69
set_time, // 0x6A
set_title_text, // 0x6B
set_titles_animation, // 0x6C
sound_entity, // 0x6D
sound, // 0x6E
start_configuration, // 0x6F
stop_sound, // 0x70
store_cookie, // 0x71
system_chat, // 0x72
tab_list, // 0x73
tag_query, // 0x74
take_item_entity, // 0x75
teleport_entity, // 0x76
test_instance_block_status, // 0x77
ticking_state, // 0x78
ticking_step, // 0x79
transfer, // 0x7A
@ -195,10 +195,12 @@ declare_state_packets!(GamePacket,
set_creative_mode_slot, // 0x36
set_jigsaw_block, // 0x37
set_structure_block, // 0x38
sign_update, // 0x39
swing, // 0x3A
teleport_to_entity, // 0x3B
use_item_on, // 0x3C
use_item, // 0x3D
set_test_block, // 0x39
sign_update, // 0x3A
swing, // 0x3B
teleport_to_entity, // 0x3C
test_instance_block_action, // 0x3D
use_item_on, // 0x3E
use_item, // 0x3F
]
);

View file

@ -5,6 +5,7 @@ use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
pub struct ServerboundChat {
#[limit(256)]
pub message: String,
pub timestamp: u64,
pub salt: u64,
@ -15,6 +16,7 @@ pub struct ServerboundChat {
#[derive(Clone, Debug, AzBuf, Default)]
pub struct LastSeenMessagesUpdate {
#[var]
pub messages: u32,
pub offset: u32,
pub acknowledged: FixedBitSet<{ 20_usize.div_ceil(8) }>,
pub checksum: u8,
}

View file

@ -47,15 +47,17 @@ pub enum StructureMode {
Data = 3,
}
#[derive(AzBuf, Clone, Copy, Debug)]
#[derive(AzBuf, Clone, Copy, Debug, Default)]
pub enum Mirror {
#[default]
None = 0,
LeftRight = 1,
FrontBack = 2,
}
#[derive(AzBuf, Clone, Copy, Debug)]
#[derive(AzBuf, Clone, Copy, Debug, Default)]
pub enum Rotation {
#[default]
None = 0,
Clockwise90 = 1,
Clockwise180 = 2,

View file

@ -0,0 +1,19 @@
use azalea_buf::AzBuf;
use azalea_core::position::BlockPos;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
pub struct ServerboundSetTestBlock {
pub position: BlockPos,
pub mode: TestBlockMode,
pub message: String,
}
#[derive(Clone, Copy, Debug, AzBuf, Default)]
pub enum TestBlockMode {
#[default]
Start,
Log,
Fail,
Accept,
}

View file

@ -0,0 +1,44 @@
use azalea_buf::AzBuf;
use azalea_chat::FormattedText;
use azalea_core::position::{BlockPos, Vec3i};
use azalea_protocol_macros::ServerboundGamePacket;
use azalea_registry::TestInstanceKind;
use super::s_set_structure_block::Rotation;
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
pub struct ServerboundTestInstanceBlockAction {
pub pos: BlockPos,
pub action: Action,
pub data: TestInstanceBlockEntityData,
}
#[derive(Clone, Copy, Debug, AzBuf, Default)]
pub enum Action {
#[default]
Init,
Qurey,
Set,
Reset,
Save,
Export,
Run,
}
#[derive(Clone, Debug, AzBuf, Default)]
pub struct TestInstanceBlockEntityData {
pub test: Option<TestInstanceKind>,
pub size: Vec3i,
pub rotation: Rotation,
pub ignore_entities: bool,
pub status: TestInstanceBlockEntityStatus,
pub error_message: Option<FormattedText>,
}
#[derive(Clone, Copy, Debug, AzBuf, Default)]
pub enum TestInstanceBlockEntityStatus {
#[default]
Cleared,
Running,
Finished,
}

View file

@ -11,8 +11,8 @@ use azalea_buf::{AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
use crate::read::ReadPacketError;
pub const PROTOCOL_VERSION: i32 = 769;
pub const VERSION_NAME: &str = "1.21.4";
pub const PROTOCOL_VERSION: i32 = 770;
pub const VERSION_NAME: &str = "1.21.5";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ConnectionProtocol {

View file

@ -7,24 +7,28 @@ use syn::{
punctuated::Punctuated,
};
struct RegistryItem {
name: Ident,
id: String,
}
struct Registry {
name: Ident,
items: Vec<RegistryItem>,
attributes: Vec<Attribute>,
attrs: Vec<Attribute>,
}
struct RegistryItem {
attrs: Vec<Attribute>,
name: Ident,
id: String,
}
impl Parse for RegistryItem {
// Air => "minecraft:air"
fn parse(input: ParseStream) -> Result<Self> {
// parse annotations like #[default]
let attrs = input.call(Attribute::parse_outer).unwrap_or_default();
let name = input.parse()?;
input.parse::<Token![=>]>()?;
let id = input.parse::<LitStr>()?.value();
Ok(RegistryItem { name, id })
Ok(RegistryItem { attrs, name, id })
}
}
@ -36,7 +40,7 @@ impl Parse for Registry {
// }
// this also includes docs
let attributes = input.call(Attribute::parse_outer).unwrap_or_default();
let attrs = input.call(Attribute::parse_outer).unwrap_or_default();
input.parse::<Token![enum]>()?;
let name = input.parse()?;
@ -48,7 +52,7 @@ impl Parse for Registry {
Ok(Registry {
name,
items: items.into_iter().collect(),
attributes,
attrs,
})
}
}
@ -65,13 +69,15 @@ pub fn registry(input: TokenStream) -> TokenStream {
// }
let mut enum_items = quote! {};
for (i, item) in input.items.iter().enumerate() {
let attrs = &item.attrs;
let name = &item.name;
let protocol_id = i as u32;
enum_items.extend(quote! {
#(#attrs)*
#name = #protocol_id,
});
}
let attributes = input.attributes;
let attributes = input.attrs;
generated.extend(quote! {
#(#attributes)*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, azalea_buf::AzBuf, simdnbt::ToNbtTag, simdnbt::FromNbtTag)]

View file

@ -1,41 +1,55 @@
use azalea_buf::AzBuf;
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite};
use crate::Registry;
/// A registry which has its values decided by the server in the
/// `ClientboundRegistryData` packet.
///
/// These can be resolved into their actual values with
/// `ResolvableDataRegistry` from azalea-core.
pub trait DataRegistry {
pub trait DataRegistry: AzaleaRead + AzaleaWrite {
const NAME: &'static str;
fn protocol_id(&self) -> u32;
fn new_raw(id: u32) -> Self;
}
impl<T: DataRegistry> Registry for T {
fn from_u32(value: u32) -> Option<Self> {
Some(Self::new_raw(value))
}
#[derive(Debug, Clone, Copy, AzBuf, PartialEq, Eq, Hash)]
pub struct Enchantment {
#[var]
id: u32,
}
impl DataRegistry for Enchantment {
const NAME: &'static str = "enchantment";
fn protocol_id(&self) -> u32 {
self.id
fn to_u32(&self) -> u32 {
self.protocol_id()
}
}
#[derive(Debug, Clone, Copy, AzBuf, PartialEq, Eq, Hash)]
pub struct DimensionType {
#[var]
id: u32,
}
impl DimensionType {
pub fn new_raw(id: u32) -> Self {
Self { id }
}
}
impl DataRegistry for DimensionType {
const NAME: &'static str = "dimension_type";
fn protocol_id(&self) -> u32 {
self.id
}
macro_rules! data_registry {
($name:ident, $registry_name:expr) => {
#[derive(Debug, Clone, Copy, AzBuf, PartialEq, Eq, Hash)]
pub struct $name {
#[var]
id: u32,
}
impl DataRegistry for $name {
const NAME: &'static str = $registry_name;
fn protocol_id(&self) -> u32 {
self.id
}
fn new_raw(id: u32) -> Self {
Self { id }
}
}
};
}
data_registry! {Enchantment, "enchantment"}
data_registry! {DimensionType, "dimension_type"}
data_registry! {DamageKind, "damage_kind"}
data_registry! {WolfSoundVariant, "wolf_sound_variant"}
data_registry! {CowVariant, "cow_variant"}
data_registry! {ChickenVariant, "chicken_variant"}
data_registry! {FrogVariant, "frog_variant"}
data_registry! {CatVariant, "cat_variant"}
data_registry! {PigVariant, "pig_variant"}
data_registry! {PaintingVariant, "painting_variant"}
data_registry! {WolfVariant, "wolf_variant"}

View file

@ -7,24 +7,82 @@ use azalea_registry_macros::registry;
use crate::Registry;
registry! {
enum WolfVariant {
Pale => "minecraft:wolf",
Spotted => "minecraft:wolf_spotted",
Snowy => "minecraft:wolf_snowy",
Black => "minecraft:wolf_black",
Ashen => "minecraft:wolf_ashen",
Rusty => "minecraft:wolf_rusty",
Woods => "minecraft:wolf_woods",
Chestnut => "minecraft:wolf_chestnut",
Striped => "minecraft:wolf_striped",
#[derive(Default)]
enum FoxVariant {
#[default]
Red => "minecraft:red",
Snow => "minecraft:snow",
}
}
#[allow(clippy::derivable_impls)]
impl Default for WolfVariant {
fn default() -> Self {
WolfVariant::Pale
}
registry! {
enum ParrotVariant {
RedBlue => "minecraft:red_blue",
Blue => "minecraft:blue",
Green => "minecraft:green",
YellowBlue => "minecraft:yellow_blue",
Gray => "minecraft:gray",
}
}
registry! {
#[derive(Default)]
enum MooshroomVariant {
#[default]
Red => "minecraft:red",
Brown => "minecraft:brown",
}
}
registry! {
#[derive(Default)]
enum RabbitVariant {
#[default]
Brown => "minecraft:brown",
White => "minecraft:white",
Black => "minecraft:black",
WhiteSplotched => "minecraft:white_splotched",
Gold => "minecraft:gold",
Salt => "minecraft:salt",
Evil => "minecraft:evil",
}
}
registry! {
#[derive(Default)]
enum HorseVariant {
#[default]
White => "minecraft:white",
Creamy => "minecraft:creamy",
Chestnut => "minecraft:chestnut",
Brown => "minecraft:brown",
Black => "minecraft:black",
Gray => "minecraft:gray",
DarkBrown => "minecraft:dark_brown",
}
}
registry! {
#[derive(Default)]
enum LlamaVariant {
#[default]
Creamy => "minecraft:creamy",
White => "minecraft:white",
Brown => "minecraft:brown",
Gray => "minecraft:gray",
}
}
registry! {
#[derive(Default)]
enum AxolotlVariant {
#[default]
Lucy => "minecraft:lucy",
Wild => "minecraft:wild",
Gold => "minecraft:gold",
Cyan => "minecraft:cyan",
Blue => "minecraft:blue",
}
}
registry! {
@ -135,38 +193,3 @@ enum Instrument {
DreamGoatHorn => "minecraft:dream_goat_horn",
}
}
registry! {
enum PaintingVariant {
Kebab => "minecraft:kebab",
Aztec => "minecraft:aztec",
Alban => "minecraft:alban",
Aztec2 => "minecraft:aztec2",
Bomb => "minecraft:bomb",
Plant => "minecraft:plant",
Wasteland => "minecraft:wasteland",
Pool => "minecraft:pool",
Courbet => "minecraft:courbet",
Sea => "minecraft:sea",
Sunset => "minecraft:sunset",
Creebet => "minecraft:creebet",
Wanderer => "minecraft:wanderer",
Graham => "minecraft:graham",
Match => "minecraft:match",
Bust => "minecraft:bust",
Stage => "minecraft:stage",
Void => "minecraft:void",
SkullAndRoses => "minecraft:skull_and_roses",
Wither => "minecraft:wither",
Fighters => "minecraft:fighters",
Pointer => "minecraft:pointer",
Pigscene => "minecraft:pigscene",
BurningSkull => "minecraft:burning_skull",
Skeleton => "minecraft:skeleton",
Earth => "minecraft:earth",
Wind => "minecraft:wind",
Water => "minecraft:water",
Fire => "minecraft:fire",
DonkeyKong => "minecraft:donkey_kong",
}
}

View file

@ -158,10 +158,9 @@ impl<R: Registry, Direct: AzaleaRead + AzaleaWrite> AzaleaRead for Holder<R, Dir
if id == 0 {
Ok(Self::Direct(Direct::azalea_read(buf)?))
} else {
let Some(value) = R::from_u32(id - 1) else {
return Err(BufReadError::UnexpectedEnumVariant {
id: (id - 1) as i32,
});
let id = id - 1;
let Some(value) = R::from_u32(id) else {
return Err(BufReadError::UnexpectedEnumVariant { id: id as i32 });
};
Ok(Self::Reference(value))
}
@ -415,6 +414,9 @@ enum Block {
ShortGrass => "minecraft:short_grass",
Fern => "minecraft:fern",
DeadBush => "minecraft:dead_bush",
Bush => "minecraft:bush",
ShortDryGrass => "minecraft:short_dry_grass",
TallDryGrass => "minecraft:tall_dry_grass",
Seagrass => "minecraft:seagrass",
TallSeagrass => "minecraft:tall_seagrass",
Piston => "minecraft:piston",
@ -546,6 +548,7 @@ enum Block {
Ice => "minecraft:ice",
SnowBlock => "minecraft:snow_block",
Cactus => "minecraft:cactus",
CactusFlower => "minecraft:cactus_flower",
Clay => "minecraft:clay",
SugarCane => "minecraft:sugar_cane",
Jukebox => "minecraft:jukebox",
@ -1144,6 +1147,8 @@ enum Block {
WarpedWallSign => "minecraft:warped_wall_sign",
StructureBlock => "minecraft:structure_block",
Jigsaw => "minecraft:jigsaw",
TestBlock => "minecraft:test_block",
TestInstanceBlock => "minecraft:test_instance_block",
Composter => "minecraft:composter",
Target => "minecraft:target",
BeeNest => "minecraft:bee_nest",
@ -1326,6 +1331,8 @@ enum Block {
FloweringAzalea => "minecraft:flowering_azalea",
MossCarpet => "minecraft:moss_carpet",
PinkPetals => "minecraft:pink_petals",
Wildflowers => "minecraft:wildflowers",
LeafLitter => "minecraft:leaf_litter",
MossBlock => "minecraft:moss_block",
BigDripleaf => "minecraft:big_dripleaf",
BigDripleafStem => "minecraft:big_dripleaf_stem",
@ -1377,6 +1384,7 @@ enum Block {
ClosedEyeblossom => "minecraft:closed_eyeblossom",
PottedOpenEyeblossom => "minecraft:potted_open_eyeblossom",
PottedClosedEyeblossom => "minecraft:potted_closed_eyeblossom",
FireflyBush => "minecraft:firefly_bush",
}
}
@ -1430,6 +1438,8 @@ enum BlockEntityKind {
Crafter => "minecraft:crafter",
TrialSpawner => "minecraft:trial_spawner",
Vault => "minecraft:vault",
TestBlock => "minecraft:test_block",
TestInstanceBlock => "minecraft:test_instance_block",
}
}
@ -1451,22 +1461,6 @@ enum BlockPredicateKind {
}
}
registry! {
enum CatVariant {
Tabby => "minecraft:tabby",
Black => "minecraft:black",
Red => "minecraft:red",
Siamese => "minecraft:siamese",
BritishShorthair => "minecraft:british_shorthair",
Calico => "minecraft:calico",
Persian => "minecraft:persian",
Ragdoll => "minecraft:ragdoll",
White => "minecraft:white",
Jellie => "minecraft:jellie",
AllBlack => "minecraft:all_black",
}
}
registry! {
enum ChunkStatus {
Empty => "minecraft:empty",
@ -1533,6 +1527,7 @@ enum CommandArgumentKind {
ResourceOrTagKey => "minecraft:resource_or_tag_key",
Resource => "minecraft:resource",
ResourceKey => "minecraft:resource_key",
ResourceSelector => "minecraft:resource_selector",
TemplateMirror => "minecraft:template_mirror",
TemplateRotation => "minecraft:template_rotation",
Heightmap => "minecraft:heightmap",
@ -1725,7 +1720,8 @@ enum EntityKind {
PiglinBrute => "minecraft:piglin_brute",
Pillager => "minecraft:pillager",
PolarBear => "minecraft:polar_bear",
Potion => "minecraft:potion",
SplashPotion => "minecraft:splash_potion",
LingeringPotion => "minecraft:lingering_potion",
Pufferfish => "minecraft:pufferfish",
Rabbit => "minecraft:rabbit",
Ravager => "minecraft:ravager",
@ -1797,14 +1793,6 @@ enum Fluid {
}
}
registry! {
enum FrogVariant {
Temperate => "minecraft:temperate",
Warm => "minecraft:warm",
Cold => "minecraft:cold",
}
}
registry! {
enum GameEvent {
BlockActivate => "minecraft:block_activate",
@ -2098,9 +2086,13 @@ enum Item {
Cobweb => "minecraft:cobweb",
ShortGrass => "minecraft:short_grass",
Fern => "minecraft:fern",
Bush => "minecraft:bush",
Azalea => "minecraft:azalea",
FloweringAzalea => "minecraft:flowering_azalea",
DeadBush => "minecraft:dead_bush",
FireflyBush => "minecraft:firefly_bush",
ShortDryGrass => "minecraft:short_dry_grass",
TallDryGrass => "minecraft:tall_dry_grass",
Seagrass => "minecraft:seagrass",
SeaPickle => "minecraft:sea_pickle",
WhiteWool => "minecraft:white_wool",
@ -2149,6 +2141,8 @@ enum Item {
SugarCane => "minecraft:sugar_cane",
Kelp => "minecraft:kelp",
PinkPetals => "minecraft:pink_petals",
Wildflowers => "minecraft:wildflowers",
LeafLitter => "minecraft:leaf_litter",
MossCarpet => "minecraft:moss_carpet",
MossBlock => "minecraft:moss_block",
PaleMossCarpet => "minecraft:pale_moss_carpet",
@ -2217,6 +2211,7 @@ enum Item {
Ice => "minecraft:ice",
SnowBlock => "minecraft:snow_block",
Cactus => "minecraft:cactus",
CactusFlower => "minecraft:cactus_flower",
Clay => "minecraft:clay",
Jukebox => "minecraft:jukebox",
OakFence => "minecraft:oak_fence",
@ -2719,6 +2714,8 @@ enum Item {
BambooChestRaft => "minecraft:bamboo_chest_raft",
StructureBlock => "minecraft:structure_block",
Jigsaw => "minecraft:jigsaw",
TestBlock => "minecraft:test_block",
TestInstanceBlock => "minecraft:test_instance_block",
TurtleHelmet => "minecraft:turtle_helmet",
TurtleScute => "minecraft:turtle_scute",
ArmadilloScute => "minecraft:armadillo_scute",
@ -2855,6 +2852,8 @@ enum Item {
Book => "minecraft:book",
SlimeBall => "minecraft:slime_ball",
Egg => "minecraft:egg",
BlueEgg => "minecraft:blue_egg",
BrownEgg => "minecraft:brown_egg",
Compass => "minecraft:compass",
RecoveryCompass => "minecraft:recovery_compass",
Bundle => "minecraft:bundle",
@ -3403,6 +3402,7 @@ enum MemoryModuleKind {
NearestPlayers => "minecraft:nearest_players",
NearestVisiblePlayer => "minecraft:nearest_visible_player",
NearestVisibleTargetablePlayer => "minecraft:nearest_visible_targetable_player",
NearestVisibleTargetablePlayers => "minecraft:nearest_visible_targetable_players",
WalkTarget => "minecraft:walk_target",
LookTarget => "minecraft:look_target",
AttackTarget => "minecraft:attack_target",
@ -3581,6 +3581,7 @@ enum ParticleKind {
Infested => "minecraft:infested",
CherryLeaves => "minecraft:cherry_leaves",
PaleOakLeaves => "minecraft:pale_oak_leaves",
TintedLeaves => "minecraft:tinted_leaves",
SculkSoul => "minecraft:sculk_soul",
SculkCharge => "minecraft:sculk_charge",
SculkChargePop => "minecraft:sculk_charge_pop",
@ -3658,6 +3659,7 @@ enum ParticleKind {
RaidOmen => "minecraft:raid_omen",
TrialOmen => "minecraft:trial_omen",
BlockCrumble => "minecraft:block_crumble",
Firefly => "minecraft:firefly",
}
}
@ -4075,6 +4077,8 @@ enum SoundEvent {
ItemBundleInsert => "minecraft:item.bundle.insert",
ItemBundleInsertFail => "minecraft:item.bundle.insert_fail",
ItemBundleRemoveOne => "minecraft:item.bundle.remove_one",
BlockCactusFlowerBreak => "minecraft:block.cactus_flower.break",
BlockCactusFlowerPlace => "minecraft:block.cactus_flower.place",
BlockCakeAddCandle => "minecraft:block.cake.add_candle",
BlockCalciteBreak => "minecraft:block.calcite.break",
BlockCalciteStep => "minecraft:block.calcite.step",
@ -4254,6 +4258,7 @@ enum SoundEvent {
ItemCrossbowQuickCharge2 => "minecraft:item.crossbow.quick_charge_2",
ItemCrossbowQuickCharge3 => "minecraft:item.crossbow.quick_charge_3",
ItemCrossbowShoot => "minecraft:item.crossbow.shoot",
BlockDeadbushIdle => "minecraft:block.deadbush.idle",
BlockDecoratedPotBreak => "minecraft:block.decorated_pot.break",
BlockDecoratedPotFall => "minecraft:block.decorated_pot.fall",
BlockDecoratedPotHit => "minecraft:block.decorated_pot.hit",
@ -4379,6 +4384,7 @@ enum SoundEvent {
BlockFenceGateClose => "minecraft:block.fence_gate.close",
BlockFenceGateOpen => "minecraft:block.fence_gate.open",
ItemFirechargeUse => "minecraft:item.firecharge.use",
BlockFireflyBushIdle => "minecraft:block.firefly_bush.idle",
EntityFireworkRocketBlast => "minecraft:entity.firework_rocket.blast",
EntityFireworkRocketBlastFar => "minecraft:entity.firework_rocket.blast_far",
EntityFireworkRocketLargeBlast => "minecraft:entity.firework_rocket.large_blast",
@ -4618,6 +4624,11 @@ enum SoundEvent {
EntityIllusionerPrepareBlindness => "minecraft:entity.illusioner.prepare_blindness",
EntityIllusionerPrepareMirror => "minecraft:entity.illusioner.prepare_mirror",
ItemInkSacUse => "minecraft:item.ink_sac.use",
BlockIronBreak => "minecraft:block.iron.break",
BlockIronStep => "minecraft:block.iron.step",
BlockIronPlace => "minecraft:block.iron.place",
BlockIronHit => "minecraft:block.iron.hit",
BlockIronFall => "minecraft:block.iron.fall",
BlockIronDoorClose => "minecraft:block.iron_door.close",
BlockIronDoorOpen => "minecraft:block.iron_door.open",
EntityIronGolemAttack => "minecraft:entity.iron_golem.attack",
@ -4650,6 +4661,11 @@ enum SoundEvent {
BlockLavaAmbient => "minecraft:block.lava.ambient",
BlockLavaExtinguish => "minecraft:block.lava.extinguish",
BlockLavaPop => "minecraft:block.lava.pop",
BlockLeafLitterBreak => "minecraft:block.leaf_litter.break",
BlockLeafLitterStep => "minecraft:block.leaf_litter.step",
BlockLeafLitterPlace => "minecraft:block.leaf_litter.place",
BlockLeafLitterHit => "minecraft:block.leaf_litter.hit",
BlockLeafLitterFall => "minecraft:block.leaf_litter.fall",
EntityLeashKnotBreak => "minecraft:entity.leash_knot.break",
EntityLeashKnotPlace => "minecraft:entity.leash_knot.place",
BlockLeverClick => "minecraft:block.lever.click",
@ -5064,6 +5080,8 @@ enum SoundEvent {
BlockSandHit => "minecraft:block.sand.hit",
BlockSandPlace => "minecraft:block.sand.place",
BlockSandStep => "minecraft:block.sand.step",
BlockSandIdle => "minecraft:block.sand.idle",
BlockSandWind => "minecraft:block.sand.wind",
BlockScaffoldingBreak => "minecraft:block.scaffolding.break",
BlockScaffoldingFall => "minecraft:block.scaffolding.fall",
BlockScaffoldingHit => "minecraft:block.scaffolding.hit",
@ -5440,15 +5458,50 @@ enum SoundEvent {
ItemWolfArmorCrack => "minecraft:item.wolf_armor.crack",
ItemWolfArmorDamage => "minecraft:item.wolf_armor.damage",
ItemWolfArmorRepair => "minecraft:item.wolf_armor.repair",
EntityWolfShake => "minecraft:entity.wolf.shake",
EntityWolfStep => "minecraft:entity.wolf.step",
EntityWolfAmbient => "minecraft:entity.wolf.ambient",
EntityWolfDeath => "minecraft:entity.wolf.death",
EntityWolfGrowl => "minecraft:entity.wolf.growl",
EntityWolfHowl => "minecraft:entity.wolf.howl",
EntityWolfHurt => "minecraft:entity.wolf.hurt",
EntityWolfPant => "minecraft:entity.wolf.pant",
EntityWolfShake => "minecraft:entity.wolf.shake",
EntityWolfStep => "minecraft:entity.wolf.step",
EntityWolfWhine => "minecraft:entity.wolf.whine",
EntityWolfPuglinAmbient => "minecraft:entity.wolf_puglin.ambient",
EntityWolfPuglinDeath => "minecraft:entity.wolf_puglin.death",
EntityWolfPuglinGrowl => "minecraft:entity.wolf_puglin.growl",
EntityWolfPuglinHurt => "minecraft:entity.wolf_puglin.hurt",
EntityWolfPuglinPant => "minecraft:entity.wolf_puglin.pant",
EntityWolfPuglinWhine => "minecraft:entity.wolf_puglin.whine",
EntityWolfSadAmbient => "minecraft:entity.wolf_sad.ambient",
EntityWolfSadDeath => "minecraft:entity.wolf_sad.death",
EntityWolfSadGrowl => "minecraft:entity.wolf_sad.growl",
EntityWolfSadHurt => "minecraft:entity.wolf_sad.hurt",
EntityWolfSadPant => "minecraft:entity.wolf_sad.pant",
EntityWolfSadWhine => "minecraft:entity.wolf_sad.whine",
EntityWolfAngryAmbient => "minecraft:entity.wolf_angry.ambient",
EntityWolfAngryDeath => "minecraft:entity.wolf_angry.death",
EntityWolfAngryGrowl => "minecraft:entity.wolf_angry.growl",
EntityWolfAngryHurt => "minecraft:entity.wolf_angry.hurt",
EntityWolfAngryPant => "minecraft:entity.wolf_angry.pant",
EntityWolfAngryWhine => "minecraft:entity.wolf_angry.whine",
EntityWolfGrumpyAmbient => "minecraft:entity.wolf_grumpy.ambient",
EntityWolfGrumpyDeath => "minecraft:entity.wolf_grumpy.death",
EntityWolfGrumpyGrowl => "minecraft:entity.wolf_grumpy.growl",
EntityWolfGrumpyHurt => "minecraft:entity.wolf_grumpy.hurt",
EntityWolfGrumpyPant => "minecraft:entity.wolf_grumpy.pant",
EntityWolfGrumpyWhine => "minecraft:entity.wolf_grumpy.whine",
EntityWolfBigAmbient => "minecraft:entity.wolf_big.ambient",
EntityWolfBigDeath => "minecraft:entity.wolf_big.death",
EntityWolfBigGrowl => "minecraft:entity.wolf_big.growl",
EntityWolfBigHurt => "minecraft:entity.wolf_big.hurt",
EntityWolfBigPant => "minecraft:entity.wolf_big.pant",
EntityWolfBigWhine => "minecraft:entity.wolf_big.whine",
EntityWolfCuteAmbient => "minecraft:entity.wolf_cute.ambient",
EntityWolfCuteDeath => "minecraft:entity.wolf_cute.death",
EntityWolfCuteGrowl => "minecraft:entity.wolf_cute.growl",
EntityWolfCuteHurt => "minecraft:entity.wolf_cute.hurt",
EntityWolfCutePant => "minecraft:entity.wolf_cute.pant",
EntityWolfCuteWhine => "minecraft:entity.wolf_cute.whine",
BlockWoodenDoorClose => "minecraft:block.wooden_door.close",
BlockWoodenDoorOpen => "minecraft:block.wooden_door.open",
BlockWoodenTrapdoorClose => "minecraft:block.wooden_trapdoor.close",
@ -5626,6 +5679,7 @@ registry! {
enum WorldgenFeature {
NoOp => "minecraft:no_op",
Tree => "minecraft:tree",
FallenTree => "minecraft:fallen_tree",
Flower => "minecraft:flower",
NoBonemealFlower => "minecraft:no_bonemeal_flower",
RandomPatch => "minecraft:random_patch",
@ -5888,6 +5942,8 @@ enum WorldgenTreeDecoratorKind {
Beehive => "minecraft:beehive",
AlterGround => "minecraft:alter_ground",
AttachedToLeaves => "minecraft:attached_to_leaves",
PlaceOnGround => "minecraft:place_on_ground",
AttachedToLogs => "minecraft:attached_to_logs",
}
}
@ -5992,8 +6048,10 @@ enum BlockKind {
Brushable => "minecraft:brushable",
BubbleColumn => "minecraft:bubble_column",
BuddingAmethyst => "minecraft:budding_amethyst",
Bush => "minecraft:bush",
Button => "minecraft:button",
Cactus => "minecraft:cactus",
CactusFlower => "minecraft:cactus_flower",
Cake => "minecraft:cake",
CalibratedSculkSensor => "minecraft:calibrated_sculk_sensor",
Campfire => "minecraft:campfire",
@ -6028,7 +6086,7 @@ enum BlockKind {
Crop => "minecraft:crop",
CryingObsidian => "minecraft:crying_obsidian",
DaylightDetector => "minecraft:daylight_detector",
DeadBush => "minecraft:dead_bush",
DryVegetation => "minecraft:dry_vegetation",
DecoratedPot => "minecraft:decorated_pot",
DetectorRail => "minecraft:detector_rail",
DirtPath => "minecraft:dirt_path",
@ -6050,6 +6108,7 @@ enum BlockKind {
Fence => "minecraft:fence",
FenceGate => "minecraft:fence_gate",
Fire => "minecraft:fire",
FireflyBush => "minecraft:firefly_bush",
FletchingTable => "minecraft:fletching_table",
Flower => "minecraft:flower",
FlowerPot => "minecraft:flower_pot",
@ -6082,7 +6141,7 @@ enum BlockKind {
Lantern => "minecraft:lantern",
LavaCauldron => "minecraft:lava_cauldron",
LayeredCauldron => "minecraft:layered_cauldron",
Leaves => "minecraft:leaves",
LeafLitter => "minecraft:leaf_litter",
Lectern => "minecraft:lectern",
Lever => "minecraft:lever",
Light => "minecraft:light",
@ -6107,8 +6166,7 @@ enum BlockKind {
Nylium => "minecraft:nylium",
Observer => "minecraft:observer",
Piglinwallskull => "minecraft:piglinwallskull",
ParticleLeaves => "minecraft:particle_leaves",
PinkPetals => "minecraft:pink_petals",
FlowerBed => "minecraft:flower_bed",
PistonBase => "minecraft:piston_base",
PistonHead => "minecraft:piston_head",
PitcherCrop => "minecraft:pitcher_crop",
@ -6133,6 +6191,7 @@ enum BlockKind {
Roots => "minecraft:roots",
RotatedPillar => "minecraft:rotated_pillar",
Sapling => "minecraft:sapling",
Sand => "minecraft:sand",
Scaffolding => "minecraft:scaffolding",
SculkCatalyst => "minecraft:sculk_catalyst",
Sculk => "minecraft:sculk",
@ -6141,6 +6200,7 @@ enum BlockKind {
SculkVein => "minecraft:sculk_vein",
Seagrass => "minecraft:seagrass",
SeaPickle => "minecraft:sea_pickle",
ShortDryGrass => "minecraft:short_dry_grass",
ShulkerBox => "minecraft:shulker_box",
Skull => "minecraft:skull",
Slab => "minecraft:slab",
@ -6167,11 +6227,16 @@ enum BlockKind {
StructureVoid => "minecraft:structure_void",
SugarCane => "minecraft:sugar_cane",
SweetBerryBush => "minecraft:sweet_berry_bush",
TallDryGrass => "minecraft:tall_dry_grass",
TallFlower => "minecraft:tall_flower",
TallGrass => "minecraft:tall_grass",
TallSeagrass => "minecraft:tall_seagrass",
Target => "minecraft:target",
Terracotta => "minecraft:terracotta",
Test => "minecraft:test",
TestInstance => "minecraft:test_instance",
TintedGlass => "minecraft:tinted_glass",
TintedParticleLeaves => "minecraft:tinted_particle_leaves",
Tnt => "minecraft:tnt",
TorchflowerCrop => "minecraft:torchflower_crop",
Torch => "minecraft:torch",
@ -6184,6 +6249,7 @@ enum BlockKind {
TurtleEgg => "minecraft:turtle_egg",
TwistingVinesPlant => "minecraft:twisting_vines_plant",
TwistingVines => "minecraft:twisting_vines",
UntintedParticleLeaves => "minecraft:untinted_particle_leaves",
Vault => "minecraft:vault",
Vine => "minecraft:vine",
WallBanner => "minecraft:wall_banner",
@ -6307,8 +6373,7 @@ enum DataComponentKind {
CanBreak => "minecraft:can_break",
AttributeModifiers => "minecraft:attribute_modifiers",
CustomModelData => "minecraft:custom_model_data",
HideAdditionalTooltip => "minecraft:hide_additional_tooltip",
HideTooltip => "minecraft:hide_tooltip",
TooltipDisplay => "minecraft:tooltip_display",
RepairCost => "minecraft:repair_cost",
CreativeSlotLock => "minecraft:creative_slot_lock",
EnchantmentGlintOverride => "minecraft:enchantment_glint_override",
@ -6319,12 +6384,14 @@ enum DataComponentKind {
UseCooldown => "minecraft:use_cooldown",
DamageResistant => "minecraft:damage_resistant",
Tool => "minecraft:tool",
Weapon => "minecraft:weapon",
Enchantable => "minecraft:enchantable",
Equippable => "minecraft:equippable",
Repairable => "minecraft:repairable",
Glider => "minecraft:glider",
TooltipStyle => "minecraft:tooltip_style",
DeathProtection => "minecraft:death_protection",
BlocksAttacks => "minecraft:blocks_attacks",
StoredEnchantments => "minecraft:stored_enchantments",
DyedColor => "minecraft:dyed_color",
MapColor => "minecraft:map_color",
@ -6334,6 +6401,7 @@ enum DataComponentKind {
ChargedProjectiles => "minecraft:charged_projectiles",
BundleContents => "minecraft:bundle_contents",
PotionContents => "minecraft:potion_contents",
PotionDurationScale => "minecraft:potion_duration_scale",
SuspiciousStewEffects => "minecraft:suspicious_stew_effects",
WritableBookContent => "minecraft:writable_book_content",
WrittenBookContent => "minecraft:written_book_content",
@ -6343,8 +6411,10 @@ enum DataComponentKind {
BucketEntityData => "minecraft:bucket_entity_data",
BlockEntityData => "minecraft:block_entity_data",
Instrument => "minecraft:instrument",
ProvidesTrimMaterial => "minecraft:provides_trim_material",
OminousBottleAmplifier => "minecraft:ominous_bottle_amplifier",
JukeboxPlayable => "minecraft:jukebox_playable",
ProvidesBannerPatterns => "minecraft:provides_banner_patterns",
Recipes => "minecraft:recipes",
LodestoneTracker => "minecraft:lodestone_tracker",
FireworkExplosion => "minecraft:firework_explosion",
@ -6359,6 +6429,31 @@ enum DataComponentKind {
Bees => "minecraft:bees",
Lock => "minecraft:lock",
ContainerLoot => "minecraft:container_loot",
BreakSound => "minecraft:break_sound",
VillagerVariant => "minecraft:villager/variant",
WolfVariant => "minecraft:wolf/variant",
WolfSoundVariant => "minecraft:wolf/sound_variant",
WolfCollar => "minecraft:wolf/collar",
FoxVariant => "minecraft:fox/variant",
SalmonSize => "minecraft:salmon/size",
ParrotVariant => "minecraft:parrot/variant",
TropicalFishPattern => "minecraft:tropical_fish/pattern",
TropicalFishBaseColor => "minecraft:tropical_fish/base_color",
TropicalFishPatternColor => "minecraft:tropical_fish/pattern_color",
MooshroomVariant => "minecraft:mooshroom/variant",
RabbitVariant => "minecraft:rabbit/variant",
PigVariant => "minecraft:pig/variant",
CowVariant => "minecraft:cow/variant",
ChickenVariant => "minecraft:chicken/variant",
FrogVariant => "minecraft:frog/variant",
HorseVariant => "minecraft:horse/variant",
PaintingVariant => "minecraft:painting/variant",
LlamaVariant => "minecraft:llama/variant",
AxolotlVariant => "minecraft:axolotl/variant",
CatVariant => "minecraft:cat/variant",
CatCollar => "minecraft:cat/collar",
SheepColor => "minecraft:sheep/color",
ShulkerColor => "minecraft:shulker/color",
}
}
@ -6370,39 +6465,6 @@ enum EntitySubPredicateKind {
Slime => "minecraft:slime",
Raider => "minecraft:raider",
Sheep => "minecraft:sheep",
Axolotl => "minecraft:axolotl",
Fox => "minecraft:fox",
Mooshroom => "minecraft:mooshroom",
Rabbit => "minecraft:rabbit",
Horse => "minecraft:horse",
Llama => "minecraft:llama",
Villager => "minecraft:villager",
Parrot => "minecraft:parrot",
Salmon => "minecraft:salmon",
TropicalFish => "minecraft:tropical_fish",
Painting => "minecraft:painting",
Cat => "minecraft:cat",
Frog => "minecraft:frog",
Wolf => "minecraft:wolf",
}
}
registry! {
enum ItemSubPredicateKind {
Damage => "minecraft:damage",
Enchantments => "minecraft:enchantments",
StoredEnchantments => "minecraft:stored_enchantments",
PotionContents => "minecraft:potion_contents",
CustomData => "minecraft:custom_data",
Container => "minecraft:container",
BundleContents => "minecraft:bundle_contents",
FireworkExplosion => "minecraft:firework_explosion",
Fireworks => "minecraft:fireworks",
WritableBookContent => "minecraft:writable_book_content",
WrittenBookContent => "minecraft:written_book_content",
AttributeModifiers => "minecraft:attribute_modifiers",
Trim => "minecraft:trim",
JukeboxPlayable => "minecraft:jukebox_playable",
}
}
@ -6625,3 +6687,66 @@ enum SlotDisplay {
Composite => "minecraft:composite",
}
}
registry! {
enum TicketKind {
Start => "minecraft:start",
Dragon => "minecraft:dragon",
PlayerLoading => "minecraft:player_loading",
PlayerSimulation => "minecraft:player_simulation",
Forced => "minecraft:forced",
Portal => "minecraft:portal",
EnderPearl => "minecraft:ender_pearl",
Unknown => "minecraft:unknown",
}
}
registry! {
enum TestEnvironmentDefinitionKind {
AllOf => "minecraft:all_of",
GameRules => "minecraft:game_rules",
TimeOfDay => "minecraft:time_of_day",
Weather => "minecraft:weather",
Function => "minecraft:function",
}
}
registry! {
enum TestFunction {
AlwaysPass => "minecraft:always_pass",
}
}
registry! {
enum TestInstanceKind {
BlockBased => "minecraft:block_based",
Function => "minecraft:function",
}
}
registry! {
enum DataComponentPredicateKind {
Damage => "minecraft:damage",
Enchantments => "minecraft:enchantments",
StoredEnchantments => "minecraft:stored_enchantments",
PotionContents => "minecraft:potion_contents",
CustomData => "minecraft:custom_data",
Container => "minecraft:container",
BundleContents => "minecraft:bundle_contents",
FireworkExplosion => "minecraft:firework_explosion",
Fireworks => "minecraft:fireworks",
WritableBookContent => "minecraft:writable_book_content",
WrittenBookContent => "minecraft:written_book_content",
AttributeModifiers => "minecraft:attribute_modifiers",
Trim => "minecraft:trim",
JukeboxPlayable => "minecraft:jukebox_playable",
}
}
registry! {
enum SpawnConditionKind {
Structure => "minecraft:structure",
MoonBrightness => "minecraft:moon_brightness",
Biome => "minecraft:biome",
}
}

View file

@ -360,8 +360,10 @@ pub static BEE_ATTRACTIVE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::MangrovePropagule,
Block::CherryLeaves,
Block::PinkPetals,
Block::Wildflowers,
Block::ChorusFlower,
Block::SporeBlossom,
Block::CactusFlower,
])
});
pub static BEE_GROWABLES: LazyLock<HashSet<Block>> = LazyLock::new(|| {
@ -383,9 +385,6 @@ pub static BEEHIVES: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::BeeNest, Block::Beehive]));
pub static BIG_DRIPLEAF_PLACEABLE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::Farmland,
Block::Clay,
Block::MossBlock,
Block::Dirt,
Block::GrassBlock,
Block::Podzol,
@ -393,9 +392,11 @@ pub static BIG_DRIPLEAF_PLACEABLE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::Mycelium,
Block::RootedDirt,
Block::MossBlock,
Block::PaleMossBlock,
Block::Mud,
Block::MuddyMangroveRoots,
Block::Farmland,
Block::Clay,
Block::MossBlock,
])
});
pub static BIRCH_LOGS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
@ -450,6 +451,14 @@ pub static CAMEL_SAND_STEP_SOUND_BLOCKS: LazyLock<HashSet<Block>> = LazyLock::ne
Block::BlackConcretePowder,
])
});
pub static CAMELS_SPAWNABLE_ON: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::Sand,
Block::RedSand,
Block::SuspiciousSand,
Block::SuspiciousSand,
])
});
pub static CAMPFIRES: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::Campfire, Block::SoulCampfire]));
pub static CANDLE_CAKES: LazyLock<HashSet<Block>> = LazyLock::new(|| {
@ -753,41 +762,6 @@ pub static DARK_OAK_LOGS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::StrippedDarkOakWood,
])
});
pub static DEAD_BUSH_MAY_PLACE_ON: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::Sand,
Block::RedSand,
Block::SuspiciousSand,
Block::SuspiciousSand,
Block::Terracotta,
Block::WhiteTerracotta,
Block::OrangeTerracotta,
Block::MagentaTerracotta,
Block::LightBlueTerracotta,
Block::YellowTerracotta,
Block::LimeTerracotta,
Block::PinkTerracotta,
Block::GrayTerracotta,
Block::LightGrayTerracotta,
Block::CyanTerracotta,
Block::PurpleTerracotta,
Block::BlueTerracotta,
Block::BrownTerracotta,
Block::GreenTerracotta,
Block::RedTerracotta,
Block::BlackTerracotta,
Block::Dirt,
Block::GrassBlock,
Block::Podzol,
Block::CoarseDirt,
Block::Mycelium,
Block::RootedDirt,
Block::MossBlock,
Block::PaleMossBlock,
Block::Mud,
Block::MuddyMangroveRoots,
])
});
pub static DEEPSLATE_ORE_REPLACEABLES: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::Deepslate, Block::Tuff]));
pub static DIAMOND_ORES: LazyLock<HashSet<Block>> =
@ -852,6 +826,8 @@ pub static DRAGON_IMMUNE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::IronBars,
Block::RespawnAnchor,
Block::ReinforcedDeepslate,
Block::TestBlock,
Block::TestInstanceBlock,
])
});
pub static DRAGON_TRANSPARENT: LazyLock<HashSet<Block>> =
@ -866,6 +842,50 @@ pub static DRIPSTONE_REPLACEABLE_BLOCKS: LazyLock<HashSet<Block>> = LazyLock::ne
Block::Deepslate,
])
});
pub static DRY_VEGETATION_MAY_PLACE_ON: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::Farmland,
Block::Sand,
Block::RedSand,
Block::SuspiciousSand,
Block::SuspiciousSand,
Block::Terracotta,
Block::WhiteTerracotta,
Block::OrangeTerracotta,
Block::MagentaTerracotta,
Block::LightBlueTerracotta,
Block::YellowTerracotta,
Block::LimeTerracotta,
Block::PinkTerracotta,
Block::GrayTerracotta,
Block::LightGrayTerracotta,
Block::CyanTerracotta,
Block::PurpleTerracotta,
Block::BlueTerracotta,
Block::BrownTerracotta,
Block::GreenTerracotta,
Block::RedTerracotta,
Block::BlackTerracotta,
Block::Dirt,
Block::GrassBlock,
Block::Podzol,
Block::CoarseDirt,
Block::Mycelium,
Block::RootedDirt,
Block::MossBlock,
Block::PaleMossBlock,
Block::Mud,
Block::MuddyMangroveRoots,
])
});
pub static EDIBLE_FOR_SHEEP: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::ShortGrass,
Block::ShortDryGrass,
Block::TallDryGrass,
Block::Fern,
])
});
pub static EMERALD_ORES: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::EmeraldOre, Block::DeepslateEmeraldOre]));
pub static ENCHANTMENT_POWER_PROVIDER: LazyLock<HashSet<Block>> =
@ -878,6 +898,9 @@ pub static ENCHANTMENT_POWER_TRANSMITTER: LazyLock<HashSet<Block>> = LazyLock::n
Block::ShortGrass,
Block::Fern,
Block::DeadBush,
Block::Bush,
Block::ShortDryGrass,
Block::TallDryGrass,
Block::Seagrass,
Block::TallSeagrass,
Block::Fire,
@ -896,6 +919,7 @@ pub static ENCHANTMENT_POWER_TRANSMITTER: LazyLock<HashSet<Block>> = LazyLock::n
Block::WarpedRoots,
Block::NetherSprouts,
Block::CrimsonRoots,
Block::LeafLitter,
Block::HangingRoots,
])
});
@ -918,6 +942,7 @@ pub static ENDERMAN_HOLDABLE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::WarpedFungus,
Block::WarpedNylium,
Block::WarpedRoots,
Block::CactusFlower,
Block::Dandelion,
Block::OpenEyeblossom,
Block::Poppy,
@ -1061,8 +1086,10 @@ pub static FLOWERS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::MangrovePropagule,
Block::CherryLeaves,
Block::PinkPetals,
Block::Wildflowers,
Block::ChorusFlower,
Block::SporeBlossom,
Block::CactusFlower,
Block::Dandelion,
Block::OpenEyeblossom,
Block::Poppy,
@ -1439,6 +1466,8 @@ pub static INSIDE_STEP_SOUND_BLOCKS: LazyLock<HashSet<Block>> = LazyLock::new(||
Block::LilyPad,
Block::SmallAmethystBud,
Block::PinkPetals,
Block::Wildflowers,
Block::LeafLitter,
])
});
pub static INVALID_SPAWN_INSIDE: LazyLock<HashSet<Block>> =
@ -1698,71 +1727,39 @@ pub static MANGROVE_ROOTS_CAN_GROW_THROUGH: LazyLock<HashSet<Block>> = LazyLock:
pub static MINEABLE_AXE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::NoteBlock,
Block::AttachedMelonStem,
Block::AttachedPumpkinStem,
Block::Azalea,
Block::Bamboo,
Block::Barrel,
Block::BeeNest,
Block::Beehive,
Block::Beetroots,
Block::BigDripleafStem,
Block::BigDripleaf,
Block::Bookshelf,
Block::BrownMushroomBlock,
Block::BrownMushroom,
Block::Campfire,
Block::Carrots,
Block::CartographyTable,
Block::CarvedPumpkin,
Block::CaveVinesPlant,
Block::CaveVines,
Block::Chest,
Block::ChorusFlower,
Block::ChorusPlant,
Block::Cocoa,
Block::Composter,
Block::CraftingTable,
Block::CrimsonFungus,
Block::DaylightDetector,
Block::DeadBush,
Block::Fern,
Block::FletchingTable,
Block::GlowLichen,
Block::ShortGrass,
Block::HangingRoots,
Block::JackOLantern,
Block::Jukebox,
Block::Ladder,
Block::LargeFern,
Block::Lectern,
Block::LilyPad,
Block::Loom,
Block::MelonStem,
Block::Melon,
Block::MushroomStem,
Block::NetherWart,
Block::Potatoes,
Block::PumpkinStem,
Block::Pumpkin,
Block::RedMushroomBlock,
Block::RedMushroom,
Block::Scaffolding,
Block::SmallDripleaf,
Block::SmithingTable,
Block::SoulCampfire,
Block::SporeBlossom,
Block::SugarCane,
Block::SweetBerryBush,
Block::TallGrass,
Block::TrappedChest,
Block::TwistingVinesPlant,
Block::TwistingVines,
Block::Vine,
Block::WarpedFungus,
Block::WeepingVinesPlant,
Block::WeepingVines,
Block::Wheat,
Block::MangroveRoots,
Block::BambooMosaic,
Block::BambooMosaicSlab,
@ -1825,17 +1822,6 @@ pub static MINEABLE_AXE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::MangrovePlanks,
Block::BambooPlanks,
Block::CherryPlanks,
Block::OakSapling,
Block::SpruceSapling,
Block::BirchSapling,
Block::JungleSapling,
Block::AcaciaSapling,
Block::DarkOakSapling,
Block::PaleOakSapling,
Block::Azalea,
Block::FloweringAzalea,
Block::MangrovePropagule,
Block::CherrySapling,
Block::OakButton,
Block::SpruceButton,
Block::BirchButton,
@ -2026,16 +2012,6 @@ pub static MINEABLE_HOE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::Shroomlight,
Block::Sponge,
Block::WetSponge,
Block::JungleLeaves,
Block::OakLeaves,
Block::SpruceLeaves,
Block::PaleOakLeaves,
Block::DarkOakLeaves,
Block::AcaciaLeaves,
Block::BirchLeaves,
Block::AzaleaLeaves,
Block::FloweringAzaleaLeaves,
Block::MangroveLeaves,
Block::SculkSensor,
Block::CalibratedSculkSensor,
Block::MossBlock,
@ -2046,7 +2022,16 @@ pub static MINEABLE_HOE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::SculkCatalyst,
Block::SculkVein,
Block::SculkShrieker,
Block::PinkPetals,
Block::JungleLeaves,
Block::OakLeaves,
Block::SpruceLeaves,
Block::PaleOakLeaves,
Block::DarkOakLeaves,
Block::AcaciaLeaves,
Block::BirchLeaves,
Block::AzaleaLeaves,
Block::FloweringAzaleaLeaves,
Block::MangroveLeaves,
Block::CherryLeaves,
])
});
@ -2917,6 +2902,29 @@ pub static PLANKS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::CherryPlanks,
])
});
pub static PLAYS_AMBIENT_DESERT_BLOCK_SOUNDS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::Sand,
Block::RedSand,
Block::Terracotta,
Block::WhiteTerracotta,
Block::OrangeTerracotta,
Block::MagentaTerracotta,
Block::LightBlueTerracotta,
Block::YellowTerracotta,
Block::LimeTerracotta,
Block::PinkTerracotta,
Block::GrayTerracotta,
Block::LightGrayTerracotta,
Block::CyanTerracotta,
Block::PurpleTerracotta,
Block::BlueTerracotta,
Block::BrownTerracotta,
Block::GreenTerracotta,
Block::RedTerracotta,
Block::BlackTerracotta,
])
});
pub static POLAR_BEARS_SPAWNABLE_ON_ALTERNATE: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::Ice]));
pub static PORTALS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
@ -2980,6 +2988,9 @@ pub static REPLACEABLE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::ShortGrass,
Block::Fern,
Block::DeadBush,
Block::Bush,
Block::ShortDryGrass,
Block::TallDryGrass,
Block::Seagrass,
Block::TallSeagrass,
Block::Fire,
@ -2998,9 +3009,70 @@ pub static REPLACEABLE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::WarpedRoots,
Block::NetherSprouts,
Block::CrimsonRoots,
Block::LeafLitter,
Block::HangingRoots,
])
});
pub static REPLACEABLE_BY_MUSHROOMS: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::PaleMossCarpet,
Block::ShortGrass,
Block::Fern,
Block::DeadBush,
Block::Vine,
Block::GlowLichen,
Block::Sunflower,
Block::Lilac,
Block::RoseBush,
Block::Peony,
Block::TallGrass,
Block::LargeFern,
Block::HangingRoots,
Block::PitcherPlant,
Block::Water,
Block::Seagrass,
Block::TallSeagrass,
Block::BrownMushroom,
Block::RedMushroom,
Block::BrownMushroomBlock,
Block::RedMushroomBlock,
Block::WarpedRoots,
Block::NetherSprouts,
Block::CrimsonRoots,
Block::LeafLitter,
Block::ShortDryGrass,
Block::TallDryGrass,
Block::Bush,
Block::FireflyBush,
Block::JungleLeaves,
Block::OakLeaves,
Block::SpruceLeaves,
Block::PaleOakLeaves,
Block::DarkOakLeaves,
Block::AcaciaLeaves,
Block::BirchLeaves,
Block::AzaleaLeaves,
Block::FloweringAzaleaLeaves,
Block::MangroveLeaves,
Block::CherryLeaves,
Block::Dandelion,
Block::OpenEyeblossom,
Block::Poppy,
Block::BlueOrchid,
Block::Allium,
Block::AzureBluet,
Block::RedTulip,
Block::OrangeTulip,
Block::WhiteTulip,
Block::PinkTulip,
Block::OxeyeDaisy,
Block::Cornflower,
Block::LilyOfTheValley,
Block::WitherRose,
Block::Torchflower,
Block::ClosedEyeblossom,
])
});
pub static REPLACEABLE_BY_TREES: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::PaleMossCarpet,
@ -3020,9 +3092,14 @@ pub static REPLACEABLE_BY_TREES: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::Water,
Block::Seagrass,
Block::TallSeagrass,
Block::Bush,
Block::FireflyBush,
Block::WarpedRoots,
Block::NetherSprouts,
Block::CrimsonRoots,
Block::LeafLitter,
Block::ShortDryGrass,
Block::TallDryGrass,
Block::JungleLeaves,
Block::OakLeaves,
Block::SpruceLeaves,
@ -3486,49 +3563,15 @@ pub static STRIDER_WARM_BLOCKS: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::Lava]));
pub static SWORD_EFFICIENT: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::ShortGrass,
Block::Fern,
Block::DeadBush,
Block::Vine,
Block::GlowLichen,
Block::Sunflower,
Block::Lilac,
Block::RoseBush,
Block::Peony,
Block::TallGrass,
Block::LargeFern,
Block::HangingRoots,
Block::PitcherPlant,
Block::BrownMushroom,
Block::RedMushroom,
Block::SugarCane,
Block::Pumpkin,
Block::CarvedPumpkin,
Block::JackOLantern,
Block::Melon,
Block::AttachedPumpkinStem,
Block::AttachedMelonStem,
Block::LilyPad,
Block::Cocoa,
Block::PitcherCrop,
Block::SweetBerryBush,
Block::CaveVines,
Block::CaveVinesPlant,
Block::SporeBlossom,
Block::PinkPetals,
Block::BigDripleaf,
Block::BigDripleafStem,
Block::SmallDripleaf,
Block::NetherWart,
Block::WarpedFungus,
Block::WarpedRoots,
Block::NetherSprouts,
Block::CrimsonFungus,
Block::WeepingVines,
Block::WeepingVinesPlant,
Block::TwistingVines,
Block::TwistingVinesPlant,
Block::CrimsonRoots,
Block::ChorusPlant,
Block::ChorusFlower,
Block::JungleLeaves,
@ -3542,27 +3585,10 @@ pub static SWORD_EFFICIENT: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::FloweringAzaleaLeaves,
Block::MangroveLeaves,
Block::CherryLeaves,
Block::OakSapling,
Block::SpruceSapling,
Block::BirchSapling,
Block::JungleSapling,
Block::AcaciaSapling,
Block::DarkOakSapling,
Block::PaleOakSapling,
Block::Azalea,
Block::FloweringAzalea,
Block::MangrovePropagule,
Block::CherrySapling,
Block::Beetroots,
Block::Carrots,
Block::Potatoes,
Block::Wheat,
Block::MelonStem,
Block::PumpkinStem,
Block::TorchflowerCrop,
Block::PitcherCrop,
])
});
pub static SWORD_INSTANTLY_MINES: LazyLock<HashSet<Block>> =
LazyLock::new(|| HashSet::from_iter(vec![Block::Bamboo, Block::BambooSapling]));
pub static TERRACOTTA: LazyLock<HashSet<Block>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Block::Terracotta,
@ -3682,6 +3708,7 @@ pub static WALL_POST_OVERRIDE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::SoulTorch,
Block::RedstoneTorch,
Block::Tripwire,
Block::CactusFlower,
Block::WhiteBanner,
Block::OrangeBanner,
Block::MagentaBanner,
@ -3827,6 +3854,8 @@ pub static WITHER_IMMUNE: LazyLock<HashSet<Block>> = LazyLock::new(|| {
Block::MovingPiston,
Block::Light,
Block::ReinforcedDeepslate,
Block::TestBlock,
Block::TestInstanceBlock,
])
});
pub static WITHER_SUMMON_BASE_BLOCKS: LazyLock<HashSet<Block>> =

View file

@ -108,8 +108,10 @@ pub static BEE_FOOD: LazyLock<HashSet<Item>> = LazyLock::new(|| {
Item::MangrovePropagule,
Item::CherryLeaves,
Item::PinkPetals,
Item::Wildflowers,
Item::ChorusFlower,
Item::SporeBlossom,
Item::CactusFlower,
])
});
pub static BIRCH_LOGS: LazyLock<HashSet<Item>> = LazyLock::new(|| {
@ -144,6 +146,8 @@ pub static BOATS: LazyLock<HashSet<Item>> = LazyLock::new(|| {
Item::CherryChestBoat,
])
});
pub static BOOK_CLONING_TARGET: LazyLock<HashSet<Item>> =
LazyLock::new(|| HashSet::from_iter(vec![Item::WritableBook]));
pub static BOOKSHELF_BOOKS: LazyLock<HashSet<Item>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Item::Book,
@ -560,6 +564,8 @@ pub static DYEABLE: LazyLock<HashSet<Item>> = LazyLock::new(|| {
Item::WolfArmor,
])
});
pub static EGGS: LazyLock<HashSet<Item>> =
LazyLock::new(|| HashSet::from_iter(vec![Item::Egg, Item::BlueEgg, Item::BrownEgg]));
pub static EMERALD_ORES: LazyLock<HashSet<Item>> =
LazyLock::new(|| HashSet::from_iter(vec![Item::EmeraldOre, Item::DeepslateEmeraldOre]));
pub static ENCHANTABLE_ARMOR: LazyLock<HashSet<Item>> = LazyLock::new(|| {
@ -985,6 +991,40 @@ pub static FISHES: LazyLock<HashSet<Item>> = LazyLock::new(|| {
Item::TropicalFish,
])
});
pub static FLOWERS: LazyLock<HashSet<Item>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Item::Sunflower,
Item::Lilac,
Item::Peony,
Item::RoseBush,
Item::PitcherPlant,
Item::FloweringAzaleaLeaves,
Item::FloweringAzalea,
Item::MangrovePropagule,
Item::CherryLeaves,
Item::PinkPetals,
Item::Wildflowers,
Item::ChorusFlower,
Item::SporeBlossom,
Item::CactusFlower,
Item::Dandelion,
Item::OpenEyeblossom,
Item::Poppy,
Item::BlueOrchid,
Item::Allium,
Item::AzureBluet,
Item::RedTulip,
Item::OrangeTulip,
Item::WhiteTulip,
Item::PinkTulip,
Item::OxeyeDaisy,
Item::Cornflower,
Item::LilyOfTheValley,
Item::WitherRose,
Item::Torchflower,
Item::ClosedEyeblossom,
])
});
pub static FOOT_ARMOR: LazyLock<HashSet<Item>> = LazyLock::new(|| {
HashSet::from_iter(vec![
Item::LeatherBoots,

View file

@ -1,5 +1,4 @@
use std::collections::hash_map::Entry;
use std::str::FromStr;
use std::{
collections::HashMap,
fmt::Debug,
@ -13,7 +12,6 @@ use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos};
use nohash_hasher::IntMap;
use parking_lot::RwLock;
use simdnbt::owned::NbtCompound;
use tracing::{debug, trace, warn};
use crate::heightmap::Heightmap;
@ -177,7 +175,7 @@ impl PartialChunkStorage {
&mut self,
pos: &ChunkPos,
data: &mut Cursor<&[u8]>,
heightmaps: &NbtCompound,
heightmaps: &[(HeightmapKind, Box<[u64]>)],
chunk_storage: &mut ChunkStorage,
) -> Result<(), BufReadError> {
debug!("Replacing chunk at {:?}", pos);
@ -333,7 +331,7 @@ impl Chunk {
buf: &mut Cursor<&[u8]>,
dimension_height: u32,
min_y: i32,
heightmaps_nbt: &NbtCompound,
heightmaps_data: &[(HeightmapKind, Box<[u64]>)],
) -> Result<Self, BufReadError> {
let section_count = dimension_height / SECTION_HEIGHT;
let mut sections = Vec::with_capacity(section_count as usize);
@ -344,18 +342,10 @@ impl Chunk {
let sections = sections.into_boxed_slice();
let mut heightmaps = HashMap::new();
for (name, heightmap) in heightmaps_nbt.iter() {
let Ok(kind) = HeightmapKind::from_str(&name.to_str()) else {
warn!("Unknown heightmap kind: {name}");
continue;
};
let Some(data) = heightmap.long_array() else {
warn!("Heightmap {name} is not a long array");
continue;
};
for (kind, data) in heightmaps_data {
let data: Box<[u64]> = data.iter().map(|x| *x as u64).collect();
let heightmap = Heightmap::new(kind, dimension_height, min_y, data);
heightmaps.insert(kind, heightmap);
let heightmap = Heightmap::new(*kind, dimension_height, min_y, data);
heightmaps.insert(*kind, heightmap);
}
Ok(Chunk {
@ -449,7 +439,7 @@ impl AzaleaRead for Section {
let block_count = u16::azalea_read(buf)?;
// this is commented out because the vanilla server is wrong
// ^ this comment was written ages ago. needs more investigation.
// TODO: ^ this comment was written ages ago. needs more investigation.
// assert!(
// block_count <= 16 * 16 * 16,
// "A section has more blocks than what should be possible. This is a bug!"

View file

@ -1,6 +1,7 @@
use std::{fmt::Display, str::FromStr};
use azalea_block::BlockState;
use azalea_buf::AzBuf;
use azalea_core::{math, position::ChunkBlockPos};
use azalea_registry::tags::blocks::LEAVES;
@ -8,7 +9,7 @@ use crate::{BitStorage, Section, chunk_storage::get_block_state_from_sections};
// (wg stands for worldgen)
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, AzBuf)]
pub enum HeightmapKind {
WorldSurfaceWg,
WorldSurface,

View file

@ -2,7 +2,6 @@ use std::io::{Cursor, Write};
use azalea_block::block_state::BlockStateIntegerRepr;
use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
use azalea_core::math;
use tracing::warn;
use crate::BitStorage;
@ -45,37 +44,15 @@ impl PalettedContainer {
buf: &mut Cursor<&[u8]>,
container_type: &'static PalettedContainerKind,
) -> Result<Self, BufReadError> {
let server_bits_per_entry = u8::azalea_read(buf)?;
let palette_type = PaletteKind::from_bits_and_type(server_bits_per_entry, container_type);
let bits_per_entry = u8::azalea_read(buf)?;
let palette_type = PaletteKind::from_bits_and_type(bits_per_entry, container_type);
let palette = palette_type.read(buf)?;
let size = container_type.size();
let data = Box::<[u64]>::azalea_read(buf)?;
// we can only trust the bits per entry that we're sent if there's enough data
// that it'd be global. if it's not global, then we have to calculate it
// ourselves.
// this almost never matters, except on some custom servers like hypixel limbo
// TODO: this is incorrect. we should be getting the log2 of the max blockstate
// or biome instead of data.len(). this code might be causing wrong data to be
// read. ¯\_(ツ)_/¯
let calculated_bits_per_entry = math::ceil_log2(data.len() as u32) as u8;
let calculated_bits_per_entry_palette_kind =
PaletteKind::from_bits_and_type(calculated_bits_per_entry, container_type);
let bits_per_entry = if calculated_bits_per_entry_palette_kind == PaletteKind::Global {
server_bits_per_entry
} else {
calculated_bits_per_entry
};
debug_assert!(
bits_per_entry != 0 || data.is_empty(),
"Bits per entry is 0 but data is not empty."
);
let mut storage = match BitStorage::new(
bits_per_entry.into(),
bits_per_entry as usize,
size,
if data.is_empty() {
if bits_per_entry == 0 {
Some(Box::new([]))
} else {
// we're going to update the data after creating the bitstorage
@ -90,9 +67,11 @@ impl PalettedContainer {
));
}
};
// minecraft does this to allow the data to have extra padding bits. most
// servers don't use this, but it's notably used by hypixel.
storage.data = data;
// now read the data
for i in 0..storage.data.len() {
storage.data[i] = u64::azalea_read(buf)?;
}
Ok(PalettedContainer {
bits_per_entry,

View file

@ -1,167 +1,6 @@
import lib.code.inventory
import lib.code.registry
import lib.code.item_components
import lib.code.version
import lib.code.packet
import lib.code.utils
import lib.code.tags
import lib.download
import lib.extract
import lib.utils
ITEM_COMPONENTS_DIR = 'azalea-inventory/src/components.rs'
def generate(version_id: str):
expected_variants = get_expected_variants(version_id)
actual_variants = get_actual_variants()
new_variants = []
removed_variants = []
for variant in expected_variants:
if variant not in actual_variants:
new_variants.append(variant)
for variant in actual_variants:
if variant not in expected_variants:
removed_variants.append(variant)
print('New variants:')
for variant in new_variants:
print('-', variant)
print()
print('Removed variants:')
for variant in removed_variants:
print('-', variant)
print()
for variant in removed_variants:
print(f'Removing {variant}...')
remove_variant(variant)
for variant in new_variants:
print(f'Adding {variant}...')
add_variant(variant)
lib.code.utils.fmt()
print('Done!')
def get_expected_variants(version_id: str):
expected_variants = []
registries = lib.extract.get_registries_report(version_id)
registry = registries['minecraft:data_component_type']
registry_entries = sorted(
registry['entries'].items(), key=lambda x: x[1]['protocol_id'])
for variant_name, _variant in registry_entries:
variant_struct_name = lib.utils.to_camel_case(variant_name.split(':')[-1])
expected_variants.append(variant_struct_name)
return expected_variants
def get_actual_variants():
actual_variants = []
with open(ITEM_COMPONENTS_DIR, 'r') as f:
code = f.read().split('\n')
in_match = False
for line in code:
if in_match:
if line == ' })':
break
variant_line_prefix = ' DataComponentKind::'
if line.startswith(variant_line_prefix):
variant = line[len(variant_line_prefix):].split(' ', 1)[0]
actual_variants.append(variant)
elif line == ' Ok(match kind {':
in_match = True
return actual_variants
def remove_variant(variant: str):
with open(ITEM_COMPONENTS_DIR, 'r') as f:
code = f.read().split('\n')
first_line_with_variant = None
line_after_variant = None
in_match = False
for i, line in enumerate(list(code)):
if in_match:
if line == ' })':
line_after_variant = i
break
variant_line_prefix = ' DataComponentKind::'
if line.startswith(variant_line_prefix):
if first_line_with_variant is not None:
line_after_variant = i
break
variant_name = line[len(variant_line_prefix):].split(' ', 1)[0]
if variant_name == variant:
first_line_with_variant = i
elif line == ' Ok(match kind {':
in_match = True
if first_line_with_variant is None:
raise ValueError(f'Variant {variant} not found')
if line_after_variant is None:
raise ValueError(f'Couldn\'t find end of variant {variant}')
code = code[:first_line_with_variant] + code[line_after_variant:]
# now remove the struct
line_before_struct = None # this is the #[derive] line
line_after_struct = None # impl DataComponent for ... {\n...\n}
for i, line in enumerate(list(code)):
if line == f'pub struct {variant} {{' or line == f'pub struct {variant};':
line_before_struct = i - 1
elif line == f'impl DataComponent for {variant} {{':
line_after_struct = i + 3
break
if line_before_struct is None:
raise ValueError(f'Couldn\'t find struct {variant}')
if line_after_struct is None:
raise ValueError(f'Couldn\'t find impl DataComponent for {variant}')
code = code[:line_before_struct] + code[line_after_struct:]
with open(ITEM_COMPONENTS_DIR, 'w') as f:
f.write('\n'.join(code))
def add_variant(variant: str):
with open(ITEM_COMPONENTS_DIR, 'r') as f:
code = f.read().split('\n')
in_match = False
last_line_in_match = None
for i, line in enumerate(list(code)):
if in_match:
if line == ' })':
last_line_in_match = i
break
elif line == ' Ok(match kind {':
in_match = True
if last_line_in_match is None:
raise ValueError('Couldn\'t find end of match')
code = code[:last_line_in_match] + [
f' DataComponentKind::{variant} => Box::new({variant}::azalea_read(buf)?),',
] + code[last_line_in_match:]
# now insert the struct
code.append('')
code.append('#[derive(Clone, PartialEq, AzBuf)]')
code.append(f'pub struct {variant} {{')
code.append(' pub todo: todo!(), // see DataComponents.java')
code.append('}')
code.append(f'impl DataComponent for {variant} {{')
code.append(f' const KIND: DataComponentKind = DataComponentKind::{variant};')
code.append('}')
with open(ITEM_COMPONENTS_DIR, 'w') as f:
f.write('\n'.join(code))
lib.code.utils.fmt()
if __name__ == '__main__':
version_id = lib.code.version.get_version_id()
generate(version_id)
lib.code.item_components.generate(version_id)

View file

@ -33,8 +33,7 @@ def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blo
for property_id in list(block_data_report.get('properties', {}).keys()):
property_variants = block_data_report['properties'][property_id]
property_struct_name = get_property_struct_name(
block_id, property_id, property_variants)
property_struct_name = get_property_struct_name(block_id, property_id, property_variants)
if property_struct_name in properties:
if not properties[property_struct_name] == property_variants:
@ -192,6 +191,10 @@ def get_property_struct_name(block_id: str, property_id: str, property_variants:
return 'TrialSpawnerState'
if property_variants == ['inactive', 'active', 'unlocking', 'ejecting']:
return 'VaultState'
if property_variants == ['start', 'log', 'fail', 'accept']:
return 'TestMode'
if property_variants == ['save', 'load', 'corner', 'data']:
return 'StructureMode'
if 'harp' in property_variants and 'didgeridoo' in property_variants:
return 'Sound'
if is_list_of_string_integers(property_variants):

View file

@ -103,23 +103,24 @@ def generate_entity_metadata(burger_entities_data: dict, mappings: Mappings):
// This file is generated from codegen/lib/code/entity.py.
// Don't change it manually!
use crate::particle::Particle;
use super::{
ArmadilloStateKind, EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion,
Rotations, SnifferStateKind, VillagerData,
};
use azalea_chat::FormattedText;
use azalea_core::{
direction::Direction,
position::{BlockPos, Vec3},
};
use azalea_inventory::ItemStack;
use azalea_registry::DataRegistry;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use thiserror::Error;
use uuid::Uuid;
use super::{
ArmadilloStateKind, EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion,
Rotations, SnifferStateKind, VillagerData,
};
use crate::particle::Particle;
#[derive(Error, Debug)]
pub enum UpdateMetadataError {
#[error("Wrong type ({0:?})")]
@ -410,12 +411,15 @@ impl From<EntityDataValue> for UpdateMetadataError {
# some types don't have Default implemented
if type_name == 'CompoundTag':
default = 'simdnbt::owned::NbtCompound::default()'
elif type_name == 'CatVariant':
default = 'azalea_registry::CatVariant::Tabby'
elif type_name == 'PaintingVariant':
default = 'azalea_registry::PaintingVariant::Kebab'
elif type_name == 'FrogVariant':
default = 'azalea_registry::FrogVariant::Temperate'
# elif type_name == 'CatVariant':
# # TODO: the default should be Tabby but we don't have a way to get that from here
# default = 'azalea_registry::CatVariant::new_raw(0)'
# elif type_name == 'PaintingVariant':
# default = 'azalea_registry::PaintingVariant::Kebab'
# elif type_name == 'FrogVariant':
# default = 'azalea_registry::FrogVariant::Temperate'
elif type_name.endswith('Variant'):
default = f'azalea_registry::{type_name}::new_raw(0)'
elif type_name == 'VillagerData':
default = 'VillagerData { kind: azalea_registry::VillagerKind::Plains, profession: azalea_registry::VillagerProfession::None, level: 0 }'
else:
@ -430,7 +434,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
default = f'BlockPos::new{default}'
elif type_name == 'OptionalBlockPos': # Option<BlockPos>
default = f'Some(BlockPos::new{default})' if default != 'Empty' else 'None'
elif type_name == 'OptionalUuid':
elif type_name == 'OptionalLivingEntityReference':
default = f'Some(uuid::uuid!({default}))' if default != 'Empty' else 'None'
elif type_name == 'OptionalUnsignedInt':
default = f'OptionalUnsignedInt(Some({default}))' if default != 'Empty' else 'OptionalUnsignedInt(None)'

View file

@ -0,0 +1,164 @@
import lib.code.inventory
import lib.code.registry
import lib.code.version
import lib.code.packet
import lib.code.utils
import lib.code.tags
import lib.download
import lib.extract
import lib.utils
ITEM_COMPONENTS_DIR = 'azalea-inventory/src/components.rs'
def generate(version_id: str):
expected_variants = get_expected_variants(version_id)
actual_variants = get_actual_variants()
new_variants = []
removed_variants = []
for variant in expected_variants:
if variant not in actual_variants:
new_variants.append(variant)
for variant in actual_variants:
if variant not in expected_variants:
removed_variants.append(variant)
print('New variants:')
for variant in new_variants:
print('-', variant)
print()
print('Removed variants:')
for variant in removed_variants:
print('-', variant)
print()
for variant in removed_variants:
print(f'Removing {variant}...')
remove_variant(variant)
for variant in new_variants:
print(f'Adding {variant}...')
add_variant(variant)
lib.code.utils.fmt()
print('Done!')
def get_expected_variants(version_id: str):
expected_variants = []
registries = lib.extract.get_registries_report(version_id)
registry = registries['minecraft:data_component_type']
registry_entries = sorted(
registry['entries'].items(), key=lambda x: x[1]['protocol_id'])
for variant_name, _variant in registry_entries:
variant_struct_name = lib.utils.to_camel_case(variant_name.split(':')[-1])
expected_variants.append(variant_struct_name)
return expected_variants
def get_actual_variants():
actual_variants = []
with open(ITEM_COMPONENTS_DIR, 'r') as f:
code = f.read().split('\n')
in_match = False
for line in code:
if in_match:
if line == ' })':
break
variant_line_prefix = ' DataComponentKind::'
if line.startswith(variant_line_prefix):
variant = line[len(variant_line_prefix):].split(' ', 1)[0]
actual_variants.append(variant)
elif line == ' Ok(match kind {':
in_match = True
return actual_variants
def remove_variant(variant: str):
with open(ITEM_COMPONENTS_DIR, 'r') as f:
code = f.read().split('\n')
first_line_with_variant = None
line_after_variant = None
in_match = False
for i, line in enumerate(list(code)):
if in_match:
if line == ' })':
line_after_variant = i
break
variant_line_prefix = ' DataComponentKind::'
if line.startswith(variant_line_prefix):
if first_line_with_variant is not None:
line_after_variant = i
break
variant_name = line[len(variant_line_prefix):].split(' ', 1)[0]
if variant_name == variant:
first_line_with_variant = i
elif line == ' Ok(match kind {':
in_match = True
if first_line_with_variant is None:
raise ValueError(f'Variant {variant} not found')
if line_after_variant is None:
raise ValueError(f'Couldn\'t find end of variant {variant}')
code = code[:first_line_with_variant] + code[line_after_variant:]
# now remove the struct
line_before_struct = None # this is the #[derive] line
line_after_struct = None # impl DataComponent for ... {\n...\n}
for i, line in enumerate(list(code)):
if line == f'pub struct {variant} {{' or line == f'pub struct {variant};':
line_before_struct = i - 1
elif line == f'impl DataComponent for {variant} {{':
line_after_struct = i + 3
break
if line_before_struct is None:
raise ValueError(f'Couldn\'t find struct {variant}')
if line_after_struct is None:
raise ValueError(f'Couldn\'t find impl DataComponent for {variant}')
code = code[:line_before_struct] + code[line_after_struct:]
with open(ITEM_COMPONENTS_DIR, 'w') as f:
f.write('\n'.join(code))
def add_variant(variant: str):
with open(ITEM_COMPONENTS_DIR, 'r') as f:
code = f.read().split('\n')
in_match = False
last_line_in_match = None
for i, line in enumerate(list(code)):
if in_match:
if line == ' })':
last_line_in_match = i
break
elif line == ' Ok(match kind {':
in_match = True
if last_line_in_match is None:
raise ValueError('Couldn\'t find end of match')
code = code[:last_line_in_match] + [
f' DataComponentKind::{variant} => Box::new({variant}::azalea_read(buf)?),',
] + code[last_line_in_match:]
# now insert the struct
code.append('')
code.append('#[derive(Clone, PartialEq, AzBuf)]')
code.append(f'pub struct {variant} {{')
code.append(' pub todo: todo!(), // see DataComponents.java')
code.append('}')
code.append(f'impl DataComponent for {variant} {{')
code.append(f' const KIND: DataComponentKind = DataComponentKind::{variant};')
code.append('}')
with open(ITEM_COMPONENTS_DIR, 'w') as f:
f.write('\n'.join(code))
lib.code.utils.fmt()

View file

@ -14,6 +14,8 @@ MOJMAP_TO_AZALEA_STATE_NAME_MAPPING = {
}
AZALEA_TO_MOJMAP_STATE_NAME_MAPPING = {v: k for k, v in MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.items()}
PACKETS_DIR = '../azalea-protocol/src/packets'
def generate_packet(packets_report, packet_name, direction, state):
mojmap_state = AZALEA_TO_MOJMAP_STATE_NAME_MAPPING.get(state, state)
_packet_report = packets_report[mojmap_state][direction]['minecraft:' + packet_name]
@ -24,7 +26,7 @@ def generate_packet(packets_report, packet_name, direction, state):
packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet'
packet_struct_name = to_camel_case(f'{direction}_{packet_name}')
packet_module_name = f'{direction[0]}_{packet_name}'
packet_module_name = get_packet_module_name(packet_name, direction)
code.append(f'use azalea_buf::AzBuf;')
code.append(f'use azalea_protocol_macros::{packet_derive_name};')
@ -42,11 +44,16 @@ def generate_packet(packets_report, packet_name, direction, state):
# this won't handle writing to the packets/{state}/mod.rs file since we'd need to know the full packet list
def set_packets(packets_report):
def get_packet_module_name(packet_name: str, direction: str):
return f'{direction[0]}_{packet_name}'
def set_packets(packets_report):
for mojmap_state in packets_report:
state = MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.get(mojmap_state, mojmap_state)
mod_rs_dir = get_dir_location(
f'../azalea-protocol/src/packets/{state}/mod.rs')
expected_packet_module_names = set()
state_dir = get_dir_location(f'{PACKETS_DIR}/{state}')
mod_rs_dir = get_dir_location(f'{state_dir}/mod.rs')
serverbound_packets = packet_direction_report_to_packet_names(packets_report[mojmap_state]['serverbound'])
clientbound_packets = packet_direction_report_to_packet_names(packets_report[mojmap_state].get('clientbound', {}))
@ -61,10 +68,12 @@ def set_packets(packets_report):
code.append(' Clientbound => [')
for packet_id, packet_name in enumerate(clientbound_packets):
code.append(f' {packet_name}, // {padded_hex(packet_id)}')
expected_packet_module_names.add(get_packet_module_name(packet_name, 'clientbound'))
code.append(' ],')
code.append(' Serverbound => [')
for packet_id, packet_name in enumerate(serverbound_packets):
code.append(f' {packet_name}, // {padded_hex(packet_id)}')
expected_packet_module_names.add(get_packet_module_name(packet_name, 'serverbound'))
code.append(' ]')
code.append(');')
code.append('')
@ -72,6 +81,23 @@ def set_packets(packets_report):
with open(mod_rs_dir, 'w') as f:
f.write('\n'.join(code))
existing_packet_module_names = set()
# iterate over the directory
for file in os.listdir(state_dir):
if file.endswith('.rs') and file != 'mod.rs':
existing_packet_module_names.add(file[:-len('.rs')])
for packet_module_name in expected_packet_module_names - existing_packet_module_names:
direction = None
if packet_module_name.startswith('c_'):
direction = 'clientbound'
elif packet_module_name.startswith('s_'):
direction = 'serverbound'
else:
raise Exception(f'Invalid packet module name: {packet_module_name}')
packet = packet_module_name[2:]
generate_packet(packets_report, packet, direction, state)
def packet_direction_report_to_packet_names(report):
name_to_id = {}
for resource_location, packet in report.items():
@ -82,8 +108,7 @@ def packet_direction_report_to_packet_names(report):
return names_sorted
def get_packets(direction: str, state: str):
mod_rs_dir = get_dir_location(
f'../azalea-protocol/src/packets/{state}/mod.rs')
mod_rs_dir = get_dir_location(f'{PACKETS_DIR}/{state}/mod.rs')
with open(mod_rs_dir, 'r') as f:
mod_rs = f.read().splitlines()

View file

@ -85,8 +85,7 @@ def run_python_command_and_download_deps(command):
break
missing_lib = regex_match.group(1)
print('Missing required lib:', missing_lib)
os.system(
f'{determine_python_command()} -m pip install {missing_lib}')
subprocess.run(f'venv/bin/pip install {missing_lib}', cwd=os.path.dirname(os.path.dirname(__file__)))
print('ok')
@ -99,7 +98,7 @@ def get_burger_data_for_version(version_id: str):
print('\033[92mRunning Burger...\033[m')
run_python_command_and_download_deps(
f'cd {get_dir_location("__cache__/Burger")} && '\
f'{determine_python_command()} munch.py {get_dir_location("__cache__")}/client-{version_id}.jar '\
f'venv/bin/python munch.py {get_dir_location("__cache__")}/client-{version_id}.jar '\
f'--output {get_dir_location("__cache__")}/burger-{version_id}.json '\
f'--mappings {get_dir_location("__cache__")}/mappings-{version_id}.txt'
)

View file

@ -1,3 +1,4 @@
import lib.code.item_components
import lib.code.inventory
import lib.code.language
import lib.code.registry
@ -48,7 +49,7 @@ new_block_states_report = lib.extract.get_block_states_report(new_version_id)
new_registries = lib.extract.get_registries_report(new_version_id)
new_ordered_blocks = lib.code.blocks.get_ordered_blocks(new_registries)
lib.code.blocks.generate_blocks(
new_block_states_report, new_pixlyzer_block_datas, new_ordered_blocks)
new_block_states_report, new_pixlyzer_block_datas, new_ordered_blocks, new_burger_data)
lib.code.shapes.generate_block_shapes(
new_pixlyzer_block_datas, new_shape_datas['shapes'], new_shape_datas['aabbs'], new_block_states_report)
@ -60,10 +61,13 @@ print('Generating registries...')
import genregistries
genregistries.generate(new_version_id)
# print('Generating entity metadata...')
print('Generating entity metadata...')
burger_entities_data = new_burger_data[0]['entities']
lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings)
print('Generating item components...')
lib.code.item_components.generate(new_version_id)
print('Finishing touches, setting version in README and formatting code...')
lib.code.version.set_version_id(new_version_id)