1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00
* 23w51b

* make recalculate_near_end_of_path public

so other plugins can do .after(recalculate_near_end_of_path)

* update to 24w03a i think

* start implementing 24w13a

* registries work (but a lot of packets are still broken)

* fix recipes and commands packets

* i love codecs :D i am not going insane :D mojang's java is very readable :D

* item components are "implemented" meowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeowmeow

* update to 1.20.5-pre3

* fix all the broken packets and clippy (mojang please don't do an update like this again or i will murder someone)

* 1.20.5-rc1

* fix failing tests

* 1.20.5
This commit is contained in:
mat 2024-04-23 10:34:50 -05:00 committed by GitHub
parent 0ddad8bd9c
commit 1d80f531b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
88 changed files with 7401 additions and 4808 deletions

6
Cargo.lock generated
View file

@ -347,7 +347,6 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"simdnbt", "simdnbt",
"socks5-impl",
"thiserror", "thiserror",
"tokio", "tokio",
"tracing", "tracing",
@ -359,7 +358,6 @@ name = "azalea-core"
version = "0.9.1" version = "0.9.1"
dependencies = [ dependencies = [
"azalea-buf", "azalea-buf",
"azalea-inventory",
"azalea-registry", "azalea-registry",
"bevy_ecs", "bevy_ecs",
"nohash-hasher", "nohash-hasher",
@ -416,9 +414,12 @@ name = "azalea-inventory"
version = "0.9.1" version = "0.9.1"
dependencies = [ dependencies = [
"azalea-buf", "azalea-buf",
"azalea-chat",
"azalea-core",
"azalea-inventory-macros", "azalea-inventory-macros",
"azalea-registry", "azalea-registry",
"simdnbt", "simdnbt",
"uuid",
] ]
[[package]] [[package]]
@ -536,7 +537,6 @@ dependencies = [
"azalea-buf", "azalea-buf",
"azalea-client", "azalea-client",
"azalea-core", "azalea-core",
"azalea-inventory",
"azalea-registry", "azalea-registry",
"bevy_ecs", "bevy_ecs",
"criterion", "criterion",

View file

@ -11,7 +11,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. --> <!-- The line below is automatically read and updated by the migrate script, so don't change it manually. -->
_Currently supported Minecraft version: `1.20.4`._ _Currently supported Minecraft version: `1.20.5`._
> [!WARNING] > [!WARNING]
> Azalea is still very unfinished, though most crates are in a somewhat useable state > Azalea is still very unfinished, though most crates are in a somewhat useable state

View file

@ -1917,7 +1917,8 @@ make_block_states! {
}, },
"cracked" => Cracked(bool), "cracked" => Cracked(bool),
"crafting" => Crafting(bool), "crafting" => Crafting(bool),
"trial_spawner_state" => State { "ominous" => Ominous(bool),
"trial_spawner_state" => TrialSpawnerState {
Inactive, Inactive,
WaitingForPlayers, WaitingForPlayers,
Active, Active,
@ -1925,6 +1926,12 @@ make_block_states! {
EjectingReward, EjectingReward,
Cooldown, Cooldown,
}, },
"vault_state" => VaultState {
Inactive,
Active,
Unlocking,
Ejecting,
},
}, },
Blocks => { Blocks => {
air => BlockBehavior::new(), {}, air => BlockBehavior::new(), {},
@ -5376,7 +5383,16 @@ make_block_states! {
triggered: Triggered(false), triggered: Triggered(false),
}, },
trial_spawner => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 50.0), { trial_spawner => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 50.0), {
trial_spawner_state: State::Inactive, ominous: Ominous(false),
trial_spawner_state: TrialSpawnerState::Inactive,
},
vault => BlockBehavior::new(), {
facing: FacingCardinal::North,
ominous: Ominous(false),
vault_state: VaultState::Inactive,
},
heavy_core => BlockBehavior::new(), {
waterlogged: Waterlogged(false),
}, },
} }
} }

View file

@ -38,24 +38,34 @@ fn read_named_fields(
pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { pub fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream {
match data { match data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
let syn::Fields::Named(FieldsNamed { named, .. }) = fields else { syn::Fields::Named(FieldsNamed { named, .. }) => {
panic!("#[derive(McBuf)] can only be used on structs with named fields")
};
let (read_fields, read_field_names) = read_named_fields(named); let (read_fields, read_field_names) = read_named_fields(named);
quote! { quote! {
impl azalea_buf::McBufReadable for #ident { impl azalea_buf::McBufReadable for #ident {
fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> { fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
#(#read_fields)* #(#read_fields)*
Ok(#ident { Ok(Self {
#(#read_field_names: #read_field_names),* #(#read_field_names: #read_field_names),*
}) })
} }
} }
} }
} }
syn::Fields::Unit => {
quote! {
impl azalea_buf::McBufReadable for #ident {
fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
Ok(Self)
}
}
}
}
_ => {
panic!("#[derive(McBuf)] can only be used on structs with named fields")
}
},
syn::Data::Enum(syn::DataEnum { variants, .. }) => { syn::Data::Enum(syn::DataEnum { variants, .. }) => {
let mut match_contents = quote!(); let mut match_contents = quote!();
let mut variant_discrim: u32 = 0; let mut variant_discrim: u32 = 0;

View file

@ -39,11 +39,8 @@ fn write_named_fields(
pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream {
match data { match data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
let syn::Fields::Named(FieldsNamed { named, .. }) = fields else { syn::Fields::Named(FieldsNamed { named, .. }) => {
panic!("#[derive(McBuf)] can only be used on structs with named fields")
};
let write_fields = let write_fields =
write_named_fields(named, Some(&Ident::new("self", Span::call_site()))); write_named_fields(named, Some(&Ident::new("self", Span::call_site())));
@ -56,6 +53,19 @@ pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::Tok
} }
} }
} }
syn::Fields::Unit => {
quote! {
impl azalea_buf::McBufWritable for #ident {
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
Ok(())
}
}
}
}
_ => {
panic!("#[derive(McBuf)] can only be used on structs with named fields")
}
},
syn::Data::Enum(syn::DataEnum { variants, .. }) => { syn::Data::Enum(syn::DataEnum { variants, .. }) => {
// remember whether it's a data variant so we can do an optimization later // remember whether it's a data variant so we can do an optimization later
let mut is_data_enum = false; let mut is_data_enum = false;

View file

@ -103,17 +103,6 @@ fn read_utf_with_len(buf: &mut Cursor<&[u8]>, max_length: u32) -> Result<String,
Ok(string) Ok(string)
} }
// fast varints modified from https://github.com/luojia65/mc-varint/blob/master/src/lib.rs#L67
/// Read a single varint from the reader and return the value, along with the
/// number of bytes read
// pub async fn read_varint_async(
// reader: &mut (dyn AsyncRead + Unpin + Send),
// ) -> Result<i32, BufReadError> { let mut buffer = [0]; let mut ans = 0; for i
// in 0..5 { reader.read_exact(&mut buffer).await?; ans |= ((buffer[0] &
// 0b0111_1111) as i32) << (7 * i); if buffer[0] & 0b1000_0000 == 0 { break; }
// } Ok(ans)
// }
pub trait McBufReadable pub trait McBufReadable
where where
Self: Sized, Self: Sized,
@ -373,3 +362,12 @@ impl McBufReadable for simdnbt::owned::Nbt {
Ok(simdnbt::owned::Nbt::read_unnamed(buf)?) Ok(simdnbt::owned::Nbt::read_unnamed(buf)?)
} }
} }
impl<T> McBufReadable for Box<T>
where
T: McBufReadable,
{
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
Ok(Box::new(T::read_from(buf)?))
}
}

View file

@ -281,3 +281,12 @@ impl McBufWritable for simdnbt::owned::Nbt {
buf.write_all(&data) buf.write_all(&data)
} }
} }
impl<T> McBufWritable for Box<T>
where
T: McBufWritable,
{
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
T::write_into(&**self, buf)
}
}

View file

@ -28,7 +28,6 @@ bevy_ecs = "0.13.2"
bevy_log = { version = "0.13.2", optional = true } bevy_log = { version = "0.13.2", optional = true }
bevy_tasks = "0.13.2" bevy_tasks = "0.13.2"
bevy_time = "0.13.2" bevy_time = "0.13.2"
azalea-inventory = { path = "../azalea-inventory", version = "0.9.0" }
derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] } derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] }
futures = "0.3.30" futures = "0.3.30"
tracing = "0.1.40" tracing = "0.1.40"
@ -39,11 +38,11 @@ regex = "1.10.4"
thiserror = "^1.0.58" thiserror = "^1.0.58"
tokio = { version = "^1.37.0", features = ["sync"] } tokio = { version = "^1.37.0", features = ["sync"] }
uuid = "^1.8.0" uuid = "^1.8.0"
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
serde_json = "1.0.116" serde_json = "1.0.116"
serde = "1.0.198" serde = "1.0.198"
minecraft_folder_path = "0.1.2" minecraft_folder_path = "0.1.2"
socks5-impl = "0.5.12" azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
[features] [features]
default = ["log"] default = ["log"]

View file

@ -306,6 +306,14 @@ impl Client {
run_schedule_sender.clone(), run_schedule_sender.clone(),
); );
let instance = Instance::default();
let instance_holder = crate::local_player::InstanceHolder::new(
entity,
// default to an empty world, it'll be set correctly later when we
// get the login packet
Arc::new(RwLock::new(instance)),
);
ecs.entity_mut(entity).insert(( ecs.entity_mut(entity).insert((
// these stay when we switch to the game state // these stay when we switch to the game state
LocalPlayerBundle { LocalPlayerBundle {
@ -318,6 +326,7 @@ impl Client {
local_player_events: LocalPlayerEvents(tx), local_player_events: LocalPlayerEvents(tx),
game_profile: GameProfileComponent(game_profile), game_profile: GameProfileComponent(game_profile),
client_information: crate::ClientInformation::default(), client_information: crate::ClientInformation::default(),
instance_holder,
}, },
InConfigurationState, InConfigurationState,
)); ));
@ -394,7 +403,7 @@ impl Client {
match packet { match packet {
ClientboundLoginPacket::Hello(p) => { ClientboundLoginPacket::Hello(p) => {
debug!("Got encryption request"); debug!("Got encryption request");
let e = azalea_crypto::encrypt(&p.public_key, &p.nonce).unwrap(); let e = azalea_crypto::encrypt(&p.public_key, &p.challenge).unwrap();
if let Some(access_token) = &account.access_token { if let Some(access_token) = &account.access_token {
// keep track of the number of times we tried // keep track of the number of times we tried
@ -436,7 +445,7 @@ impl Client {
conn.write( conn.write(
ServerboundKeyPacket { ServerboundKeyPacket {
key_bytes: e.encrypted_public_key, key_bytes: e.encrypted_public_key,
encrypted_challenge: e.encrypted_nonce, encrypted_challenge: e.encrypted_challenge,
} }
.get(), .get(),
) )
@ -466,6 +475,9 @@ impl Client {
// replying to custom query is done in // replying to custom query is done in
// packet_handling::login::process_packet_events // packet_handling::login::process_packet_events
} }
ClientboundLoginPacket::CookieRequest(p) => {
debug!("Got cookie request {:?}", p);
}
} }
}; };
@ -666,6 +678,7 @@ pub struct LocalPlayerBundle {
pub local_player_events: LocalPlayerEvents, pub local_player_events: LocalPlayerEvents,
pub game_profile: GameProfileComponent, pub game_profile: GameProfileComponent,
pub client_information: ClientInformation, pub client_information: ClientInformation,
pub instance_holder: InstanceHolder,
} }
/// A bundle for the components that are present on a local player that is /// A bundle for the components that are present on a local player that is

View file

@ -17,6 +17,7 @@ use azalea_protocol::packets::game::{
serverbound_swing_packet::ServerboundSwingPacket, serverbound_swing_packet::ServerboundSwingPacket,
serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket}, serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket},
}; };
use azalea_registry::DataComponentKind;
use azalea_world::{Instance, InstanceContainer, InstanceName}; use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_app::{App, Plugin, Update}; use bevy_app::{App, Plugin, Update};
use bevy_ecs::{ use bevy_ecs::{
@ -28,7 +29,6 @@ use bevy_ecs::{
system::{Commands, Query, Res}, system::{Commands, Query, Res},
}; };
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use simdnbt::owned::NbtList;
use tracing::warn; use tracing::warn;
use crate::{ use crate::{
@ -269,20 +269,11 @@ pub fn check_block_can_be_broken_by_item_in_adventure_mode(
// minecraft caches the last checked block but that's kind of an unnecessary // minecraft caches the last checked block but that's kind of an unnecessary
// optimization and makes the code too complicated // optimization and makes the code too complicated
let Some(can_destroy) = item let Some(_can_destroy) = item.components.get(DataComponentKind::CanBreak) else {
.nbt
.compound("tag")
.and_then(|nbt| nbt.list("CanDestroy"))
else {
// no CanDestroy tag // no CanDestroy tag
return false; return false;
}; };
let NbtList::String(_can_destroy) = can_destroy else {
// CanDestroy tag must be a list of strings
return false;
};
false false
// for block_predicate in can_destroy { // for block_predicate in can_destroy {

View file

@ -252,7 +252,7 @@ impl InventoryComponent {
// && slot.may_place(item_stack) // && slot.may_place(item_stack)
&& ( && (
self.quick_craft_kind == QuickCraftKind::Middle self.quick_craft_kind == QuickCraftKind::Middle
|| item_stack.count() as i32 >= self.quick_craft_slots.len() as i32 || item_stack.count() >= self.quick_craft_slots.len() as i32
) )
{ {
break; break;
@ -273,9 +273,9 @@ impl InventoryComponent {
&mut new_carried, &mut new_carried,
slot_item_count, slot_item_count,
); );
let max_stack_size = i8::min( let max_stack_size = i32::min(
new_carried.kind.max_stack_size(), new_carried.kind.max_stack_size(),
i8::min( i32::min(
new_carried.kind.max_stack_size(), new_carried.kind.max_stack_size(),
slot.kind.max_stack_size(), slot.kind.max_stack_size(),
), ),
@ -391,7 +391,7 @@ impl InventoryComponent {
}; };
if self.menu().may_place(source_slot_index, target_item) { if self.menu().may_place(source_slot_index, target_item) {
let source_max_stack = self.menu().max_stack_size(source_slot_index); let source_max_stack = self.menu().max_stack_size(source_slot_index);
if target_slot.count() > source_max_stack as i8 { if target_slot.count() > source_max_stack as i32 {
// if there's more than the max stack size in the target slot // if there's more than the max stack size in the target slot
let target_slot = self.menu_mut().slot_mut(target_slot_index).unwrap(); let target_slot = self.menu_mut().slot_mut(target_slot_index).unwrap();
@ -449,7 +449,7 @@ impl InventoryComponent {
ThrowClick::All { .. } => slot_item.count, ThrowClick::All { .. } => slot_item.count,
}; };
let _dropping = slot_item.split(dropping_count as u8); let _dropping = slot_item.split(dropping_count as u32);
// player.drop(dropping, true); // player.drop(dropping, true);
} }
ClickOperation::PickupAll(PickupAllClick { ClickOperation::PickupAll(PickupAllClick {
@ -492,7 +492,7 @@ impl InventoryComponent {
let checking_slot = self.menu_mut().slot_mut(i).unwrap(); let checking_slot = self.menu_mut().slot_mut(i).unwrap();
let taken_item = let taken_item =
checking_slot.split(checking_slot.count() as u8); checking_slot.split(checking_slot.count() as u32);
// now extend the carried item // now extend the carried item
let target_slot = &mut self.carried; let target_slot = &mut self.carried;
@ -537,7 +537,7 @@ fn can_item_quick_replace(
return false; return false;
}; };
if !item.is_same_item_and_nbt(target_slot) { if !item.is_same_item_and_components(target_slot) {
return false; return false;
} }
let count = target_slot.count as u16 let count = target_slot.count as u16
@ -553,10 +553,10 @@ fn get_quick_craft_slot_count(
quick_craft_slots: &HashSet<u16>, quick_craft_slots: &HashSet<u16>,
quick_craft_kind: &QuickCraftKind, quick_craft_kind: &QuickCraftKind,
item: &mut ItemSlotData, item: &mut ItemSlotData,
slot_item_count: i8, slot_item_count: i32,
) { ) {
item.count = match quick_craft_kind { item.count = match quick_craft_kind {
QuickCraftKind::Left => item.count / quick_craft_slots.len() as i8, QuickCraftKind::Left => item.count / quick_craft_slots.len() as i32,
QuickCraftKind::Right => 1, QuickCraftKind::Right => 1,
QuickCraftKind::Middle => item.kind.max_stack_size(), QuickCraftKind::Middle => item.kind.max_stack_size(),
}; };

View file

@ -1,20 +1,18 @@
use std::io::Cursor; use std::io::Cursor;
use std::sync::Arc;
use azalea_entity::indexing::EntityIdIndex; use azalea_entity::indexing::EntityIdIndex;
use azalea_protocol::packets::configuration::serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket; use azalea_protocol::packets::configuration::serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket;
use azalea_protocol::packets::configuration::serverbound_keep_alive_packet::ServerboundKeepAlivePacket; use azalea_protocol::packets::configuration::serverbound_keep_alive_packet::ServerboundKeepAlivePacket;
use azalea_protocol::packets::configuration::serverbound_pong_packet::ServerboundPongPacket; use azalea_protocol::packets::configuration::serverbound_pong_packet::ServerboundPongPacket;
use azalea_protocol::packets::configuration::serverbound_resource_pack_packet::ServerboundResourcePackPacket; use azalea_protocol::packets::configuration::serverbound_resource_pack_packet::ServerboundResourcePackPacket;
use azalea_protocol::packets::configuration::serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket;
use azalea_protocol::packets::configuration::{ use azalea_protocol::packets::configuration::{
ClientboundConfigurationPacket, ServerboundConfigurationPacket, ClientboundConfigurationPacket, ServerboundConfigurationPacket,
}; };
use azalea_protocol::packets::ConnectionProtocol; use azalea_protocol::packets::ConnectionProtocol;
use azalea_protocol::read::deserialize_packet; use azalea_protocol::read::deserialize_packet;
use azalea_world::Instance;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_ecs::system::SystemState; use bevy_ecs::system::SystemState;
use parking_lot::RwLock;
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
use crate::client::InConfigurationState; use crate::client::InConfigurationState;
@ -22,6 +20,7 @@ use crate::disconnect::DisconnectEvent;
use crate::local_player::Hunger; use crate::local_player::Hunger;
use crate::packet_handling::game::KeepAliveEvent; use crate::packet_handling::game::KeepAliveEvent;
use crate::raw_connection::RawConnection; use crate::raw_connection::RawConnection;
use crate::InstanceHolder;
#[derive(Event, Debug, Clone)] #[derive(Event, Debug, Clone)]
pub struct ConfigurationPacketEvent { pub struct ConfigurationPacketEvent {
@ -80,21 +79,14 @@ pub fn process_packet_events(ecs: &mut World) {
for (player_entity, packet) in events_owned { for (player_entity, packet) in events_owned {
match packet { match packet {
ClientboundConfigurationPacket::RegistryData(p) => { ClientboundConfigurationPacket::RegistryData(p) => {
let mut instance = Instance::default(); let mut system_state: SystemState<Query<&mut InstanceHolder>> =
SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
let instance_holder = query.get_mut(player_entity).unwrap();
let mut instance = instance_holder.instance.write();
// override the old registries with the new ones // add the new registry data
// but if a registry wasn't sent, keep the old one instance.registries.append(p.registry_id, p.entries);
for (registry_name, registry) in p.registry_holder.map {
instance.registries.map.insert(registry_name, registry);
}
let instance_holder = crate::local_player::InstanceHolder::new(
player_entity,
// default to an empty world, it'll be set correctly later when we
// get the login packet
Arc::new(RwLock::new(instance)),
);
ecs.entity_mut(player_entity).insert(instance_holder);
} }
ClientboundConfigurationPacket::CustomPayload(p) => { ClientboundConfigurationPacket::CustomPayload(p) => {
@ -200,6 +192,35 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundConfigurationPacket::UpdateTags(_p) => { ClientboundConfigurationPacket::UpdateTags(_p) => {
debug!("Got update tags packet"); debug!("Got update tags packet");
} }
ClientboundConfigurationPacket::CookieRequest(p) => {
debug!("Got cookie request packet {p:?}");
}
ClientboundConfigurationPacket::ResetChat(p) => {
debug!("Got reset chat packet {p:?}");
}
ClientboundConfigurationPacket::StoreCookie(p) => {
debug!("Got store cookie packet {p:?}");
}
ClientboundConfigurationPacket::Transfer(p) => {
debug!("Got transfer packet {p:?}");
}
ClientboundConfigurationPacket::SelectKnownPacks(p) => {
debug!("Got select known packs packet {p:?}");
let mut system_state: SystemState<Query<&RawConnection>> = SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
let raw_connection = query.get_mut(player_entity).unwrap();
// resource pack management isn't implemented
raw_connection
.write_packet(
ServerboundSelectKnownPacksPacket {
known_packs: vec![],
}
.get(),
)
.unwrap();
}
} }
} }
} }

View file

@ -243,20 +243,20 @@ pub fn process_packet_events(ecs: &mut World) {
.insert(InstanceName(new_instance_name.clone())); .insert(InstanceName(new_instance_name.clone()));
} }
let Some(dimension_type) = let Some(dimension_type_element) =
instance_holder.instance.read().registries.dimension_type() instance_holder.instance.read().registries.dimension_type()
else { else {
error!("Server didn't send dimension type registry, can't log in"); error!("Server didn't send dimension type registry, can't log in");
continue; continue;
}; };
let dimension = &dimension_type
.value let dimension_type =
.iter() ResourceLocation::new(&p.common.dimension_type.to_string());
.find(|t| t.name == p.common.dimension_type)
.unwrap_or_else(|| { let dimension = dimension_type_element
panic!("No dimension_type with name {}", p.common.dimension_type) .map
}) .get(&dimension_type)
.element; .unwrap_or_else(|| panic!("No dimension_type with name {dimension_type}"));
// add this world to the instance_container (or don't if it's already // add this world to the instance_container (or don't if it's already
// there) // there)
@ -1288,9 +1288,6 @@ pub fn process_packet_events(ecs: &mut World) {
packet: ServerboundPongPacket { id: p.id }.get(), packet: ServerboundPongPacket { id: p.id }.get(),
}); });
} }
ClientboundGamePacket::PongResponse(p) => {
debug!("Got pong response packet {p:?}");
}
ClientboundGamePacket::PlaceGhostRecipe(_) => {} ClientboundGamePacket::PlaceGhostRecipe(_) => {}
ClientboundGamePacket::PlayerCombatEnd(_) => {} ClientboundGamePacket::PlayerCombatEnd(_) => {}
ClientboundGamePacket::PlayerCombatEnter(_) => {} ClientboundGamePacket::PlayerCombatEnter(_) => {}
@ -1359,21 +1356,20 @@ pub fn process_packet_events(ecs: &mut World) {
{ {
let new_instance_name = p.common.dimension.clone(); let new_instance_name = p.common.dimension.clone();
let Some(dimension_type) = let Some(dimension_type_element) =
instance_holder.instance.read().registries.dimension_type() instance_holder.instance.read().registries.dimension_type()
else { else {
error!("Server didn't send dimension type registry, can't log in"); error!("Server didn't send dimension type registry, can't log in");
continue; continue;
}; };
let dimension = &dimension_type let dimension_type =
.value ResourceLocation::new(&p.common.dimension_type.to_string());
.iter()
.find(|t| t.name == p.common.dimension_type) let dimension = dimension_type_element
.unwrap_or_else(|| { .map
panic!("No dimension_type with name {}", p.common.dimension_type) .get(&dimension_type)
}) .unwrap_or_else(|| panic!("No dimension_type with name {dimension_type}"));
.element;
// add this world to the instance_container (or don't if it's already // add this world to the instance_container (or don't if it's already
// there) // there)
@ -1475,6 +1471,11 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::TickingStep(_) => {} ClientboundGamePacket::TickingStep(_) => {}
ClientboundGamePacket::ResetScore(_) => {} ClientboundGamePacket::ResetScore(_) => {}
ClientboundGamePacket::CookieRequest(_) => {}
ClientboundGamePacket::DebugSample(_) => {}
ClientboundGamePacket::PongResponse(_) => {}
ClientboundGamePacket::StoreCookie(_) => {}
ClientboundGamePacket::Transfer(_) => {}
} }
} }
} }

View file

@ -11,7 +11,6 @@ version = "0.9.1"
[dependencies] [dependencies]
simdnbt = { version = "0.4", git = "https://github.com/azalea-rs/simdnbt" } simdnbt = { version = "0.4", git = "https://github.com/azalea-rs/simdnbt" }
azalea-buf = { path = "../azalea-buf", version = "0.9.0" } azalea-buf = { path = "../azalea-buf", version = "0.9.0" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-registry = { path = "../azalea-registry", version = "0.9.0" } azalea-registry = { path = "../azalea-registry", version = "0.9.0" }
bevy_ecs = { version = "0.13.2", default-features = false, optional = true } bevy_ecs = { version = "0.13.2", default-features = false, optional = true }
nohash-hasher = "0.2.0" nohash-hasher = "0.2.0"

View file

@ -1,5 +1,6 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![feature(lazy_cell)] #![feature(lazy_cell)]
#![feature(trait_upcasting)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![feature(generic_const_exprs)] #![feature(generic_const_exprs)]
@ -13,7 +14,6 @@ pub mod direction;
pub mod game_type; pub mod game_type;
pub mod math; pub mod math;
pub mod objectives; pub mod objectives;
pub mod particle;
pub mod position; pub mod position;
pub mod registry_holder; pub mod registry_holder;
pub mod resource_location; pub mod resource_location;

View file

@ -424,11 +424,11 @@ impl From<ChunkSectionBlockPos> for u16 {
impl nohash_hasher::IsEnabled for ChunkSectionBlockPos {} impl nohash_hasher::IsEnabled for ChunkSectionBlockPos {}
/// A block pos with an attached world /// A block pos with an attached world
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct GlobalPos { pub struct GlobalPos {
pub pos: BlockPos,
// this is actually a ResourceKey in Minecraft, but i don't think it matters? // this is actually a ResourceKey in Minecraft, but i don't think it matters?
pub world: ResourceLocation, pub world: ResourceLocation,
pub pos: BlockPos,
} }
impl From<&BlockPos> for ChunkPos { impl From<&BlockPos> for ChunkPos {

View file

@ -5,7 +5,6 @@
//! the game, including the types of chat messages, dimensions, and //! the game, including the types of chat messages, dimensions, and
//! biomes. //! biomes.
use azalea_buf::{BufReadError, McBufReadable, McBufWritable};
use simdnbt::{ use simdnbt::{
owned::{NbtCompound, NbtTag}, owned::{NbtCompound, NbtTag},
Deserialize, FromNbtTag, Serialize, ToNbtTag, Deserialize, FromNbtTag, Serialize, ToNbtTag,
@ -20,23 +19,51 @@ use crate::resource_location::ResourceLocation;
/// This is the registry that is sent to the client upon login. /// This is the registry that is sent to the client upon login.
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct RegistryHolder { pub struct RegistryHolder {
pub map: HashMap<ResourceLocation, NbtCompound>, pub map: HashMap<ResourceLocation, HashMap<ResourceLocation, NbtCompound>>,
} }
impl RegistryHolder { impl RegistryHolder {
pub fn append(
&mut self,
id: ResourceLocation,
entries: HashMap<ResourceLocation, Option<NbtCompound>>,
) {
let map = self.map.entry(id).or_default();
for (key, value) in entries {
if let Some(value) = value {
map.insert(key, value);
} else {
map.remove(&key);
}
}
}
fn get<T: Deserialize>( fn get<T: Deserialize>(
&self, &self,
name: &ResourceLocation, name: &ResourceLocation,
) -> Option<Result<T, simdnbt::DeserializeError>> { ) -> Option<Result<RegistryType<T>, simdnbt::DeserializeError>> {
// this is suboptimal, ideally simdnbt should just have a way to get the // this is suboptimal, ideally simdnbt should just have a way to get the
// owned::NbtCompound as a borrow::NbtCompound // owned::NbtCompound as a borrow::NbtCompound
let nbt_owned_compound = self.map.get(name)?; let mut map = HashMap::new();
for (key, value) in self.map.get(name)? {
// convert the value to T
let mut nbt_bytes = Vec::new(); let mut nbt_bytes = Vec::new();
nbt_owned_compound.write(&mut nbt_bytes); value.write(&mut nbt_bytes);
let nbt_borrow_compound = let nbt_borrow_compound =
simdnbt::borrow::NbtCompound::read(&mut Cursor::new(&nbt_bytes)).ok()?; simdnbt::borrow::NbtCompound::read(&mut Cursor::new(&nbt_bytes)).ok()?;
Some(T::from_compound(&nbt_borrow_compound)) let value = match T::from_compound(&nbt_borrow_compound) {
Ok(value) => value,
Err(err) => {
return Some(Err(err));
}
};
map.insert(key.clone(), value);
}
Some(Ok(RegistryType { map }))
} }
/// Get the dimension type registry, or `None` if it doesn't exist. You /// Get the dimension type registry, or `None` if it doesn't exist. You
@ -57,48 +84,10 @@ impl RegistryHolder {
} }
} }
impl McBufReadable for RegistryHolder {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let nbt_tag = simdnbt::borrow::NbtTag::read(buf)?;
let nbt_compound = nbt_tag
.compound()
.ok_or_else(|| BufReadError::Custom("RegistryHolder must be a compound".to_string()))?;
Ok(RegistryHolder {
map: simdnbt::Deserialize::from_compound(nbt_compound)?,
})
}
}
impl McBufWritable for RegistryHolder {
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
let mut written = Vec::new();
self.map.clone().to_compound().write_into(&mut written)?;
buf.write_all(&written)
}
}
/// A collection of values for a certain type of registry data. /// A collection of values for a certain type of registry data.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone)]
#[cfg_attr(feature = "strict_registry", simdnbt(deny_unknown_fields))] pub struct RegistryType<T> {
pub struct RegistryType<T> pub map: HashMap<ResourceLocation, T>,
where
T: Serialize + Deserialize,
{
#[simdnbt(rename = "type")]
pub kind: ResourceLocation,
pub value: Vec<TypeValue<T>>,
}
/// A value for a certain type of registry data.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "strict_registry", simdnbt(deny_unknown_fields))]
pub struct TypeValue<T>
where
T: Serialize + Deserialize,
{
pub id: u32,
pub name: ResourceLocation,
pub element: T,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]

View file

@ -3,6 +3,7 @@
use azalea_buf::{BufReadError, McBufReadable, McBufWritable}; use azalea_buf::{BufReadError, McBufReadable, McBufWritable};
use simdnbt::{owned::NbtTag, FromNbtTag, ToNbtTag}; use simdnbt::{owned::NbtTag, FromNbtTag, ToNbtTag};
use std::{ use std::{
fmt,
io::{Cursor, Write}, io::{Cursor, Write},
str::FromStr, str::FromStr,
}; };
@ -41,13 +42,13 @@ impl ResourceLocation {
} }
} }
impl std::fmt::Display for ResourceLocation { impl fmt::Display for ResourceLocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.namespace, self.path) write!(f, "{}:{}", self.namespace, self.path)
} }
} }
impl std::fmt::Debug for ResourceLocation { impl fmt::Debug for ResourceLocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.namespace, self.path) write!(f, "{}:{}", self.namespace, self.path)
} }
} }

View file

@ -39,10 +39,10 @@ pub fn hex_digest(digest: &[u8]) -> String {
pub struct EncryptResult { pub struct EncryptResult {
pub secret_key: [u8; 16], pub secret_key: [u8; 16],
pub encrypted_public_key: Vec<u8>, pub encrypted_public_key: Vec<u8>,
pub encrypted_nonce: Vec<u8>, pub encrypted_challenge: Vec<u8>,
} }
pub fn encrypt(public_key: &[u8], nonce: &[u8]) -> Result<EncryptResult, String> { pub fn encrypt(public_key: &[u8], challenge: &[u8]) -> Result<EncryptResult, String> {
// On receipt of a Encryption Request from the server, the client will // On receipt of a Encryption Request from the server, the client will
// generate a random 16-byte shared secret, to be used with the AES/CFB8 // generate a random 16-byte shared secret, to be used with the AES/CFB8
// stream cipher. // stream cipher.
@ -51,14 +51,14 @@ pub fn encrypt(public_key: &[u8], nonce: &[u8]) -> Result<EncryptResult, String>
// &secret_key)); // &secret_key));
// this.keybytes = Crypt.encryptUsingKey(publicKey, secretKey.getEncoded()); // this.keybytes = Crypt.encryptUsingKey(publicKey, secretKey.getEncoded());
// this.nonce = Crypt.encryptUsingKey(publicKey, arrby); // this.challenge = Crypt.encryptUsingKey(publicKey, arrby);
let encrypted_public_key: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, &secret_key)?; let encrypted_public_key: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, &secret_key)?;
let encrypted_nonce: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, nonce)?; let encrypted_challenge: Vec<u8> = rsa_public_encrypt_pkcs1::encrypt(public_key, challenge)?;
Ok(EncryptResult { Ok(EncryptResult {
secret_key, secret_key,
encrypted_public_key, encrypted_public_key,
encrypted_nonce, encrypted_challenge,
}) })
} }

View file

@ -6,7 +6,6 @@ use azalea_buf::{
use azalea_chat::FormattedText; use azalea_chat::FormattedText;
use azalea_core::{ use azalea_core::{
direction::Direction, direction::Direction,
particle::Particle,
position::{BlockPos, GlobalPos, Vec3}, position::{BlockPos, GlobalPos, Vec3},
}; };
use azalea_inventory::ItemSlot; use azalea_inventory::ItemSlot;
@ -17,6 +16,8 @@ use nohash_hasher::IntSet;
use std::io::{Cursor, Write}; use std::io::{Cursor, Write};
use uuid::Uuid; use uuid::Uuid;
use crate::particle::Particle;
#[derive(Clone, Debug, Deref)] #[derive(Clone, Debug, Deref)]
pub struct EntityMetadataItems(Vec<EntityDataItem>); pub struct EntityMetadataItems(Vec<EntityDataItem>);
@ -83,15 +84,18 @@ pub enum EntityDataValue {
OptionalBlockState(azalea_block::BlockState), OptionalBlockState(azalea_block::BlockState),
CompoundTag(simdnbt::owned::NbtCompound), CompoundTag(simdnbt::owned::NbtCompound),
Particle(Particle), Particle(Particle),
Particles(Vec<Particle>),
VillagerData(VillagerData), VillagerData(VillagerData),
// 0 for absent; 1 + actual value otherwise. Used for entity IDs. // 0 for absent; 1 + actual value otherwise. Used for entity IDs.
OptionalUnsignedInt(OptionalUnsignedInt), OptionalUnsignedInt(OptionalUnsignedInt),
Pose(Pose), Pose(Pose),
CatVariant(azalea_registry::CatVariant), CatVariant(azalea_registry::CatVariant),
WolfVariant(azalea_registry::WolfVariant),
FrogVariant(azalea_registry::FrogVariant), FrogVariant(azalea_registry::FrogVariant),
OptionalGlobalPos(Option<GlobalPos>), OptionalGlobalPos(Option<GlobalPos>),
PaintingVariant(azalea_registry::PaintingVariant), PaintingVariant(azalea_registry::PaintingVariant),
SnifferState(SnifferState), SnifferState(SnifferState),
ArmadilloState(ArmadilloStateKind),
Vector3(Vec3), Vector3(Vec3),
Quaternion(Quaternion), Quaternion(Quaternion),
} }
@ -107,6 +111,16 @@ pub struct Quaternion {
pub w: f32, pub w: f32,
} }
// mojang just calls this ArmadilloState but i added "Kind" since otherwise it
// collides with a name in metadata.rs
#[derive(Clone, Debug, Copy, Default, McBuf)]
pub enum ArmadilloStateKind {
#[default]
Idle,
Rolling,
Scared,
}
impl McBufReadable for OptionalUnsignedInt { impl McBufReadable for OptionalUnsignedInt {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let val = u32::var_read_from(buf)?; let val = u32::var_read_from(buf)?;

View file

@ -7,6 +7,7 @@ mod effects;
mod enchantments; mod enchantments;
pub mod metadata; pub mod metadata;
pub mod mining; pub mod mining;
pub mod particle;
mod plugin; mod plugin;
use self::attributes::AttributeInstance; use self::attributes::AttributeInstance;

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
use crate::position::BlockPos;
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_core::position::BlockPos;
use azalea_inventory::ItemSlot; use azalea_inventory::ItemSlot;
use azalea_registry::ParticleKind; use azalea_registry::ParticleKind;
use bevy_ecs::component::Component;
#[cfg_attr(feature = "bevy_ecs", derive(bevy_ecs::component::Component))] #[derive(Component, Debug, Clone, McBuf, Default)]
#[derive(Debug, Clone, McBuf, Default)]
pub struct Particle { pub struct Particle {
#[var] #[var]
pub id: i32, pub id: i32,
@ -13,15 +13,21 @@ pub struct Particle {
#[derive(Clone, Debug, McBuf, Default)] #[derive(Clone, Debug, McBuf, Default)]
pub enum ParticleData { pub enum ParticleData {
AmbientEntityEffect,
AngryVillager, AngryVillager,
Block(BlockParticle),
BlockMarker(BlockParticle), BlockMarker(BlockParticle),
Block(BlockParticle),
Bubble, Bubble,
BubbleColumnUp,
BubblePop,
CampfireCosySmoke,
CampfireSignalSmoke,
Cloud, Cloud,
Composter,
Crit, Crit,
CurrentDown,
DamageIndicator, DamageIndicator,
DragonBreath, DragonBreath,
Dolphin,
DrippingLava, DrippingLava,
FallingLava, FallingLava,
LandingLava, LandingLava,
@ -38,31 +44,33 @@ pub enum ParticleData {
EntityEffect, EntityEffect,
ExplosionEmitter, ExplosionEmitter,
Explosion, Explosion,
Gust,
GustEmitter,
SonicBoom, SonicBoom,
FallingDust(BlockParticle), FallingDust(BlockParticle),
Gust,
SmallGust,
GustEmitterLarge,
GustEmitterSmall,
Firework, Firework,
Fishing, Fishing,
Flame, Flame,
CherryLeaves, Infested,
SculkSoul, SculkSoul,
SculkCharge(SculkChargeParticle), SculkCharge(SculkChargeParticle),
SculkChargePop, SculkChargePop,
SoulFireFlame,
Soul, Soul,
SoulFireFlame,
Flash, Flash,
HappyVillager, HappyVillager,
Composter,
Heart, Heart,
InstantEffect, InstantEffect,
Item(ItemParticle), Item(ItemParticle),
Vibration(VibrationParticle),
ItemSlime, ItemSlime,
ItemCobweb,
ItemSnowball, ItemSnowball,
LargeSmoke, LargeSmoke,
Lava, Lava,
Mycelium, Mycelium,
Nautilus,
Note, Note,
Poof, Poof,
Portal, Portal,
@ -70,40 +78,35 @@ pub enum ParticleData {
Smoke, Smoke,
WhiteSmoke, WhiteSmoke,
Sneeze, Sneeze,
Snowflake,
Spit, Spit,
SquidInk,
SweepAttack, SweepAttack,
TotemOfUndying, TotemOfUndying,
SquidInk,
Underwater, Underwater,
Splash, Splash,
Witch, Witch,
BubblePop,
CurrentDown,
BubbleColumnUp,
Nautilus,
Dolphin,
CampfireCozySmoke,
CampfireSignalSmoke,
DrippingHoney, DrippingHoney,
FallingHoney, FallingHoney,
LandingHoney, LandingHoney,
FallingNectar, FallingNectar,
FallingSporeBlossom, FallingSporeBlossom,
SporeBlossomAir,
Ash, Ash,
CrimsonSpore, CrimsonSpore,
WarpedSpore, WarpedSpore,
SporeBlossomAir,
DrippingObsidianTear, DrippingObsidianTear,
FallingObsidianTear, FallingObsidianTear,
LandingObsidianTear, LandingObsidianTear,
ReversePortal, ReversePortal,
WhiteAsh, WhiteAsh,
SmallFlame, SmallFlame,
Snowflake,
DrippingDripstoneLava,
FallingDripstoneLava,
DrippingDripstoneWater, DrippingDripstoneWater,
FallingDripstoneWater, FallingDripstoneWater,
CherryLeaves,
DrippingDripstoneLava,
FallingDripstoneLava,
Vibration(VibrationParticle),
GlowSquidInk, GlowSquidInk,
Glow, Glow,
WaxOn, WaxOn,
@ -113,8 +116,13 @@ pub enum ParticleData {
Shriek(ShriekParticle), Shriek(ShriekParticle),
EggCrack, EggCrack,
DustPlume, DustPlume,
GustDust,
TrialSpawnerDetection, TrialSpawnerDetection,
TrialSpawnerDetectionOminous,
VaultConnection,
DustPillar,
RaidOmen,
TrialOmen,
OminousSpawning,
} }
impl From<ParticleKind> for ParticleData { impl From<ParticleKind> for ParticleData {
@ -124,7 +132,6 @@ impl From<ParticleKind> for ParticleData {
// this is mostly just here so it fails to compile when a new particle is added // this is mostly just here so it fails to compile when a new particle is added
// to ParticleKind, since ParticleData has to be updated manually // to ParticleKind, since ParticleData has to be updated manually
match kind { match kind {
ParticleKind::AmbientEntityEffect => Self::AmbientEntityEffect,
ParticleKind::AngryVillager => Self::AngryVillager, ParticleKind::AngryVillager => Self::AngryVillager,
ParticleKind::Block => Self::Block(BlockParticle::default()), ParticleKind::Block => Self::Block(BlockParticle::default()),
ParticleKind::BlockMarker => Self::BlockMarker(BlockParticle::default()), ParticleKind::BlockMarker => Self::BlockMarker(BlockParticle::default()),
@ -151,7 +158,6 @@ impl From<ParticleKind> for ParticleData {
ParticleKind::ExplosionEmitter => Self::ExplosionEmitter, ParticleKind::ExplosionEmitter => Self::ExplosionEmitter,
ParticleKind::Explosion => Self::Explosion, ParticleKind::Explosion => Self::Explosion,
ParticleKind::Gust => Self::Gust, ParticleKind::Gust => Self::Gust,
ParticleKind::GustEmitter => Self::GustEmitter,
ParticleKind::SonicBoom => Self::SonicBoom, ParticleKind::SonicBoom => Self::SonicBoom,
ParticleKind::FallingDust => Self::FallingDust(BlockParticle::default()), ParticleKind::FallingDust => Self::FallingDust(BlockParticle::default()),
ParticleKind::Firework => Self::Firework, ParticleKind::Firework => Self::Firework,
@ -194,7 +200,7 @@ impl From<ParticleKind> for ParticleData {
ParticleKind::BubbleColumnUp => Self::BubbleColumnUp, ParticleKind::BubbleColumnUp => Self::BubbleColumnUp,
ParticleKind::Nautilus => Self::Nautilus, ParticleKind::Nautilus => Self::Nautilus,
ParticleKind::Dolphin => Self::Dolphin, ParticleKind::Dolphin => Self::Dolphin,
ParticleKind::CampfireCosySmoke => Self::CampfireCozySmoke, ParticleKind::CampfireCosySmoke => Self::CampfireCosySmoke,
ParticleKind::CampfireSignalSmoke => Self::CampfireSignalSmoke, ParticleKind::CampfireSignalSmoke => Self::CampfireSignalSmoke,
ParticleKind::DrippingHoney => Self::DrippingHoney, ParticleKind::DrippingHoney => Self::DrippingHoney,
ParticleKind::FallingHoney => Self::FallingHoney, ParticleKind::FallingHoney => Self::FallingHoney,
@ -225,8 +231,18 @@ impl From<ParticleKind> for ParticleData {
ParticleKind::Shriek => Self::Shriek(ShriekParticle::default()), ParticleKind::Shriek => Self::Shriek(ShriekParticle::default()),
ParticleKind::EggCrack => Self::EggCrack, ParticleKind::EggCrack => Self::EggCrack,
ParticleKind::DustPlume => Self::DustPlume, ParticleKind::DustPlume => Self::DustPlume,
ParticleKind::GustDust => Self::GustDust, ParticleKind::SmallGust => Self::SmallGust,
ParticleKind::GustEmitterLarge => Self::GustEmitterLarge,
ParticleKind::GustEmitterSmall => Self::GustEmitterSmall,
ParticleKind::Infested => Self::Infested,
ParticleKind::ItemCobweb => Self::ItemCobweb,
ParticleKind::TrialSpawnerDetection => Self::TrialSpawnerDetection, ParticleKind::TrialSpawnerDetection => Self::TrialSpawnerDetection,
ParticleKind::TrialSpawnerDetectionOminous => Self::TrialSpawnerDetectionOminous,
ParticleKind::VaultConnection => Self::VaultConnection,
ParticleKind::DustPillar => Self::DustPillar,
ParticleKind::OminousSpawning => Self::OminousSpawning,
ParticleKind::RaidOmen => Self::RaidOmen,
ParticleKind::TrialOmen => Self::TrialOmen,
} }
} }
} }

View file

@ -13,3 +13,6 @@ simdnbt = { version = "0.4", git = "https://github.com/azalea-rs/simdnbt" }
azalea-buf = { version = "0.9.0", path = "../azalea-buf" } azalea-buf = { version = "0.9.0", path = "../azalea-buf" }
azalea-inventory-macros = { version = "0.9.0", path = "./azalea-inventory-macros" } azalea-inventory-macros = { version = "0.9.0", path = "./azalea-inventory-macros" }
azalea-registry = { version = "0.9.0", path = "../azalea-registry" } azalea-registry = { version = "0.9.0", path = "../azalea-registry" }
azalea-chat = { version = "0.9.0", path = "../azalea-chat" }
azalea-core = { version = "0.9.0", path = "../azalea-core" }
uuid = "1.8.0"

View file

@ -1,2 +0,0 @@
Representations of various inventory data structures in Minecraft.

View file

@ -0,0 +1,656 @@
use core::f64;
use std::{any::Any, collections::HashMap, io::Cursor};
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
use azalea_chat::FormattedText;
use azalea_core::{position::GlobalPos, resource_location::ResourceLocation};
use azalea_registry::{
Attribute, Block, DataComponentKind, Enchantment, HolderSet, Item, MobEffect, Potion,
TrimMaterial, TrimPattern,
};
use simdnbt::owned::{Nbt, NbtCompound};
use uuid::Uuid;
use crate::ItemSlot;
pub trait DataComponent: Send + Sync + Any {}
pub trait EncodableDataComponent: Send + Sync + Any {
fn encode(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error>;
// using the Clone trait makes it not be object-safe, so we have our own clone
// function instead
fn clone(&self) -> Box<dyn EncodableDataComponent>;
// same deal here
fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool;
}
impl<T> EncodableDataComponent for T
where
T: DataComponent + Clone + McBufWritable + McBufReadable + PartialEq,
{
fn encode(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
self.write_into(buf)
}
fn clone(&self) -> Box<dyn EncodableDataComponent> {
let cloned = self.clone();
Box::new(cloned)
}
fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool {
let other_any: Box<dyn Any> = other;
if let Some(other) = other_any.downcast_ref::<T>() {
self == other
} else {
false
}
}
}
pub fn from_kind(
kind: azalea_registry::DataComponentKind,
buf: &mut Cursor<&[u8]>,
) -> Result<Box<dyn EncodableDataComponent>, BufReadError> {
Ok(match kind {
DataComponentKind::CustomData => Box::new(CustomData::read_from(buf)?),
DataComponentKind::MaxStackSize => Box::new(MaxStackSize::read_from(buf)?),
DataComponentKind::MaxDamage => Box::new(MaxDamage::read_from(buf)?),
DataComponentKind::Damage => Box::new(Damage::read_from(buf)?),
DataComponentKind::Unbreakable => Box::new(Unbreakable::read_from(buf)?),
DataComponentKind::CustomName => Box::new(CustomName::read_from(buf)?),
DataComponentKind::ItemName => Box::new(ItemName::read_from(buf)?),
DataComponentKind::Lore => Box::new(Lore::read_from(buf)?),
DataComponentKind::Rarity => Box::new(Rarity::read_from(buf)?),
DataComponentKind::Enchantments => Box::new(Enchantments::read_from(buf)?),
DataComponentKind::CanPlaceOn => Box::new(CanPlaceOn::read_from(buf)?),
DataComponentKind::CanBreak => Box::new(CanBreak::read_from(buf)?),
DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::read_from(buf)?),
DataComponentKind::CustomModelData => Box::new(CustomModelData::read_from(buf)?),
DataComponentKind::HideAdditionalTooltip => {
Box::new(HideAdditionalTooltip::read_from(buf)?)
}
DataComponentKind::HideTooltip => Box::new(HideTooltip::read_from(buf)?),
DataComponentKind::RepairCost => Box::new(RepairCost::read_from(buf)?),
DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::read_from(buf)?),
DataComponentKind::EnchantmentGlintOverride => {
Box::new(EnchantmentGlintOverride::read_from(buf)?)
}
DataComponentKind::IntangibleProjectile => Box::new(IntangibleProjectile::read_from(buf)?),
DataComponentKind::Food => Box::new(Food::read_from(buf)?),
DataComponentKind::FireResistant => Box::new(FireResistant::read_from(buf)?),
DataComponentKind::Tool => Box::new(Tool::read_from(buf)?),
DataComponentKind::StoredEnchantments => Box::new(StoredEnchantments::read_from(buf)?),
DataComponentKind::DyedColor => Box::new(DyedColor::read_from(buf)?),
DataComponentKind::MapColor => Box::new(MapColor::read_from(buf)?),
DataComponentKind::MapId => Box::new(MapId::read_from(buf)?),
DataComponentKind::MapDecorations => Box::new(MapDecorations::read_from(buf)?),
DataComponentKind::MapPostProcessing => Box::new(MapPostProcessing::read_from(buf)?),
DataComponentKind::ChargedProjectiles => Box::new(ChargedProjectiles::read_from(buf)?),
DataComponentKind::BundleContents => Box::new(BundleContents::read_from(buf)?),
DataComponentKind::PotionContents => Box::new(PotionContents::read_from(buf)?),
DataComponentKind::SuspiciousStewEffects => {
Box::new(SuspiciousStewEffects::read_from(buf)?)
}
DataComponentKind::WritableBookContent => Box::new(WritableBookContent::read_from(buf)?),
DataComponentKind::WrittenBookContent => Box::new(WrittenBookContent::read_from(buf)?),
DataComponentKind::Trim => Box::new(Trim::read_from(buf)?),
DataComponentKind::DebugStickState => Box::new(DebugStickState::read_from(buf)?),
DataComponentKind::EntityData => Box::new(EntityData::read_from(buf)?),
DataComponentKind::BucketEntityData => Box::new(BucketEntityData::read_from(buf)?),
DataComponentKind::BlockEntityData => Box::new(BlockEntityData::read_from(buf)?),
DataComponentKind::Instrument => Box::new(Instrument::read_from(buf)?),
DataComponentKind::OminousBottleAmplifier => {
Box::new(OminousBottleAmplifier::read_from(buf)?)
}
DataComponentKind::Recipes => Box::new(Recipes::read_from(buf)?),
DataComponentKind::LodestoneTracker => Box::new(LodestoneTracker::read_from(buf)?),
DataComponentKind::FireworkExplosion => Box::new(FireworkExplosion::read_from(buf)?),
DataComponentKind::Fireworks => Box::new(Fireworks::read_from(buf)?),
DataComponentKind::Profile => Box::new(Profile::read_from(buf)?),
DataComponentKind::NoteBlockSound => Box::new(NoteBlockSound::read_from(buf)?),
DataComponentKind::BannerPatterns => Box::new(BannerPatterns::read_from(buf)?),
DataComponentKind::BaseColor => Box::new(BaseColor::read_from(buf)?),
DataComponentKind::PotDecorations => Box::new(PotDecorations::read_from(buf)?),
DataComponentKind::Container => Box::new(Container::read_from(buf)?),
DataComponentKind::BlockState => Box::new(BlockState::read_from(buf)?),
DataComponentKind::Bees => Box::new(Bees::read_from(buf)?),
DataComponentKind::Lock => Box::new(Lock::read_from(buf)?),
DataComponentKind::ContainerLoot => Box::new(ContainerLoot::read_from(buf)?),
})
}
#[derive(Clone, PartialEq, McBuf)]
pub struct CustomData {
pub nbt: Nbt,
}
impl DataComponent for CustomData {}
#[derive(Clone, PartialEq, McBuf)]
pub struct MaxStackSize {
#[var]
pub count: i32,
}
impl DataComponent for MaxStackSize {}
#[derive(Clone, PartialEq, McBuf)]
pub struct MaxDamage {
#[var]
pub amount: i32,
}
impl DataComponent for MaxDamage {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Damage {
#[var]
pub amount: i32,
}
impl DataComponent for Damage {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Unbreakable {
pub show_in_tooltip: bool,
}
impl DataComponent for Unbreakable {}
impl Default for Unbreakable {
fn default() -> Self {
Self {
show_in_tooltip: true,
}
}
}
#[derive(Clone, PartialEq, McBuf)]
pub struct CustomName {
pub name: FormattedText,
}
impl DataComponent for CustomName {}
#[derive(Clone, PartialEq, McBuf)]
pub struct ItemName {
pub name: FormattedText,
}
impl DataComponent for ItemName {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Lore {
pub lines: Vec<FormattedText>,
// vanilla also has styled_lines here but it doesn't appear to be used for the protocol
}
impl DataComponent for Lore {}
#[derive(Clone, PartialEq, Copy, McBuf)]
pub enum Rarity {
Common,
Uncommon,
Rare,
Epic,
}
impl DataComponent for Rarity {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Enchantments {
#[var]
pub levels: HashMap<Enchantment, u32>,
pub show_in_tooltip: bool,
}
impl DataComponent for Enchantments {}
#[derive(Clone, PartialEq, McBuf)]
pub enum BlockStateValueMatcher {
Exact {
value: String,
},
Range {
min: Option<String>,
max: Option<String>,
},
}
#[derive(Clone, PartialEq, McBuf)]
pub struct BlockStatePropertyMatcher {
pub name: String,
pub value_matcher: BlockStateValueMatcher,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct BlockPredicate {
pub blocks: Option<HolderSet<Block, ResourceLocation>>,
pub properties: Option<Vec<BlockStatePropertyMatcher>>,
pub nbt: Option<NbtCompound>,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct AdventureModePredicate {
pub predicates: Vec<BlockPredicate>,
pub show_in_tooltip: bool,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct CanPlaceOn {
pub predicate: AdventureModePredicate,
}
impl DataComponent for CanPlaceOn {}
#[derive(Clone, PartialEq, McBuf)]
pub struct CanBreak {
pub predicate: AdventureModePredicate,
}
impl DataComponent for CanBreak {}
#[derive(Clone, Copy, PartialEq, McBuf)]
pub enum EquipmentSlotGroup {
Any,
Mainhand,
Offhand,
Hand,
Feet,
Legs,
Chest,
Head,
Armor,
Body,
}
#[derive(Clone, Copy, PartialEq, McBuf)]
pub enum AttributeModifierOperation {
Addition,
MultiplyBase,
MultiplyTotal,
}
// this is duplicated in azalea-entity, BUT the one there has a different
// protocol format (and we can't use it anyways because it would cause a
// circular dependency)
#[derive(Clone, PartialEq, McBuf)]
pub struct AttributeModifier {
pub uuid: Uuid,
pub name: String,
pub amount: f64,
pub operation: AttributeModifierOperation,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct AttributeModifiersEntry {
pub attribute: Attribute,
pub modifier: AttributeModifier,
pub slot: EquipmentSlotGroup,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct AttributeModifiers {
pub modifiers: Vec<AttributeModifiersEntry>,
pub show_in_tooltip: bool,
}
impl DataComponent for AttributeModifiers {}
#[derive(Clone, PartialEq, McBuf)]
pub struct CustomModelData {
#[var]
pub value: i32,
}
impl DataComponent for CustomModelData {}
#[derive(Clone, PartialEq, McBuf)]
pub struct HideAdditionalTooltip;
impl DataComponent for HideAdditionalTooltip {}
#[derive(Clone, PartialEq, McBuf)]
pub struct HideTooltip;
impl DataComponent for HideTooltip {}
#[derive(Clone, PartialEq, McBuf)]
pub struct RepairCost {
#[var]
pub cost: u32,
}
impl DataComponent for RepairCost {}
#[derive(Clone, PartialEq, McBuf)]
pub struct CreativeSlotLock;
impl DataComponent for CreativeSlotLock {}
#[derive(Clone, PartialEq, McBuf)]
pub struct EnchantmentGlintOverride {
pub show_glint: bool,
}
impl DataComponent for EnchantmentGlintOverride {}
#[derive(Clone, PartialEq, McBuf)]
pub struct IntangibleProjectile;
impl DataComponent for IntangibleProjectile {}
#[derive(Clone, PartialEq, McBuf)]
pub struct MobEffectDetails {
#[var]
pub amplifier: i32,
#[var]
pub duration: i32,
pub ambient: bool,
pub show_particles: bool,
pub show_icon: bool,
pub hidden_effect: Option<Box<MobEffectDetails>>,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct MobEffectInstance {
pub effect: MobEffect,
pub details: MobEffectDetails,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct PossibleEffect {
pub effect: MobEffectInstance,
pub probability: f32,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct Food {
#[var]
pub nutrition: i32,
pub saturation: f32,
pub can_always_eat: bool,
pub eat_seconds: f32,
pub effects: Vec<PossibleEffect>,
}
impl DataComponent for Food {}
#[derive(Clone, PartialEq, McBuf)]
pub struct FireResistant;
impl DataComponent for FireResistant {}
#[derive(Clone, PartialEq, McBuf)]
pub struct ToolRule {
pub blocks: Vec<Block>,
pub speed: Option<f32>,
pub correct_for_drops: Option<bool>,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct Tool {
pub rules: Vec<ToolRule>,
pub default_mining_speed: f32,
#[var]
pub damage_per_block: i32,
}
impl DataComponent for Tool {}
#[derive(Clone, PartialEq, McBuf)]
pub struct StoredEnchantments {
#[var]
pub enchantments: HashMap<Enchantment, i32>,
pub show_in_tooltip: bool,
}
impl DataComponent for StoredEnchantments {}
#[derive(Clone, PartialEq, McBuf)]
pub struct DyedColor {
pub rgb: i32,
pub show_in_tooltip: bool,
}
impl DataComponent for DyedColor {}
#[derive(Clone, PartialEq, McBuf)]
pub struct MapColor {
pub color: i32,
}
impl DataComponent for MapColor {}
#[derive(Clone, PartialEq, McBuf)]
pub struct MapId {
#[var]
pub id: i32,
}
impl DataComponent for MapId {}
#[derive(Clone, PartialEq, McBuf)]
pub struct MapDecorations {
pub decorations: NbtCompound,
}
impl DataComponent for MapDecorations {}
#[derive(Clone, Copy, PartialEq, McBuf)]
pub enum MapPostProcessing {
Lock,
Scale,
}
impl DataComponent for MapPostProcessing {}
#[derive(Clone, PartialEq, McBuf)]
pub struct ChargedProjectiles {
pub items: Vec<ItemSlot>,
}
impl DataComponent for ChargedProjectiles {}
#[derive(Clone, PartialEq, McBuf)]
pub struct BundleContents {
pub items: Vec<ItemSlot>,
}
impl DataComponent for BundleContents {}
#[derive(Clone, PartialEq, McBuf)]
pub struct PotionContents {
pub potion: Option<Potion>,
pub custom_color: Option<i32>,
pub custom_effects: Vec<MobEffectInstance>,
}
impl DataComponent for PotionContents {}
#[derive(Clone, PartialEq, McBuf)]
pub struct SuspiciousStewEffect {
pub effect: MobEffect,
#[var]
pub duration: i32,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct SuspiciousStewEffects {
pub effects: Vec<SuspiciousStewEffect>,
}
impl DataComponent for SuspiciousStewEffects {}
#[derive(Clone, PartialEq, McBuf)]
pub struct WritableBookContent {
pub pages: Vec<String>,
}
impl DataComponent for WritableBookContent {}
#[derive(Clone, PartialEq, McBuf)]
pub struct WrittenBookContent {
pub title: String,
pub author: String,
#[var]
pub generation: i32,
pub pages: Vec<FormattedText>,
pub resolved: bool,
}
impl DataComponent for WrittenBookContent {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Trim {
pub material: TrimMaterial,
pub pattern: TrimPattern,
pub show_in_tooltip: bool,
}
impl DataComponent for Trim {}
#[derive(Clone, PartialEq, McBuf)]
pub struct DebugStickState {
pub properties: NbtCompound,
}
impl DataComponent for DebugStickState {}
#[derive(Clone, PartialEq, McBuf)]
pub struct EntityData {
pub entity: NbtCompound,
}
impl DataComponent for EntityData {}
#[derive(Clone, PartialEq, McBuf)]
pub struct BucketEntityData {
pub entity: NbtCompound,
}
impl DataComponent for BucketEntityData {}
#[derive(Clone, PartialEq, McBuf)]
pub struct BlockEntityData {
pub entity: NbtCompound,
}
impl DataComponent for BlockEntityData {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Instrument {
pub instrument: azalea_registry::Instrument,
}
impl DataComponent for Instrument {}
#[derive(Clone, PartialEq, McBuf)]
pub struct OminousBottleAmplifier {
#[var]
pub amplifier: i32,
}
impl DataComponent for OminousBottleAmplifier {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Recipes {
pub recipes: Vec<ResourceLocation>,
}
impl DataComponent for Recipes {}
#[derive(Clone, PartialEq, McBuf)]
pub struct LodestoneTracker {
pub target: Option<GlobalPos>,
pub tracked: bool,
}
impl DataComponent for LodestoneTracker {}
#[derive(Clone, Copy, PartialEq, McBuf)]
pub enum FireworkExplosionShape {
SmallBall,
LargeBall,
Star,
Creeper,
Burst,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct FireworkExplosion {
pub shape: FireworkExplosionShape,
pub colors: Vec<i32>,
pub fade_colors: Vec<i32>,
pub has_trail: bool,
pub has_twinkle: bool,
}
impl DataComponent for FireworkExplosion {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Fireworks {
#[var]
pub flight_duration: i32,
pub explosions: Vec<FireworkExplosion>,
}
impl DataComponent for Fireworks {}
#[derive(Clone, PartialEq, McBuf)]
pub struct GameProfileProperty {
pub name: String,
pub value: String,
pub signature: Option<String>,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct Profile {
pub name: String,
pub id: Option<Uuid>,
pub properties: Vec<GameProfileProperty>,
}
impl DataComponent for Profile {}
#[derive(Clone, PartialEq, McBuf)]
pub struct NoteBlockSound {
pub sound: ResourceLocation,
}
impl DataComponent for NoteBlockSound {}
#[derive(Clone, PartialEq, McBuf)]
pub struct BannerPattern {
#[var]
pub pattern: i32,
#[var]
pub color: i32,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct BannerPatterns {
pub patterns: Vec<BannerPattern>,
}
impl DataComponent for BannerPatterns {}
#[derive(Clone, Copy, PartialEq, McBuf)]
pub enum DyeColor {
White,
Orange,
Magenta,
LightBlue,
Yellow,
Lime,
Pink,
Gray,
LightGray,
Cyan,
Purple,
Blue,
Brown,
Green,
Red,
Black,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct BaseColor {
pub color: DyeColor,
}
impl DataComponent for BaseColor {}
#[derive(Clone, PartialEq, McBuf)]
pub struct PotDecorations {
pub items: Vec<Item>,
}
impl DataComponent for PotDecorations {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Container {
pub items: Vec<ItemSlot>,
}
impl DataComponent for Container {}
#[derive(Clone, PartialEq, McBuf)]
pub struct BlockState {
pub properties: HashMap<String, String>,
}
impl DataComponent for BlockState {}
#[derive(Clone, PartialEq, McBuf)]
pub struct BeehiveOccupant {
pub entity_data: NbtCompound,
#[var]
pub ticks_in_hive: i32,
#[var]
pub min_ticks_in_hive: i32,
}
#[derive(Clone, PartialEq, McBuf)]
pub struct Bees {
pub occupants: Vec<BeehiveOccupant>,
}
impl DataComponent for Bees {}
#[derive(Clone, PartialEq, McBuf)]
pub struct Lock {
pub key: String,
}
impl DataComponent for Lock {}
#[derive(Clone, PartialEq, McBuf)]
pub struct ContainerLoot {
pub loot: NbtCompound,
}
impl DataComponent for ContainerLoot {}

View file

@ -5,7 +5,7 @@ pub trait MaxStackSizeExt {
/// [`ItemSlotData`]. /// [`ItemSlotData`].
/// ///
/// [`ItemSlotData`]: crate::ItemSlotData /// [`ItemSlotData`]: crate::ItemSlotData
fn max_stack_size(&self) -> i8; fn max_stack_size(&self) -> i32;
/// Whether this item can be stacked with other items. /// Whether this item can be stacked with other items.
/// ///
@ -16,7 +16,7 @@ pub trait MaxStackSizeExt {
} }
impl MaxStackSizeExt for azalea_registry::Item { impl MaxStackSizeExt for azalea_registry::Item {
fn max_stack_size(&self) -> i8 { fn max_stack_size(&self) -> i32 {
// TODO: have the properties for every item defined somewhere // TODO: have the properties for every item defined somewhere
64 64
} }

View file

@ -1,5 +1,7 @@
#![doc = include_str!("../README.md")] #![feature(trait_upcasting)]
/// Representations of various inventory data structures in Minecraft.
pub mod components;
pub mod item; pub mod item;
pub mod operations; pub mod operations;
mod slot; mod slot;

View file

@ -621,7 +621,7 @@ impl Menu {
} }
/// Get the maximum number of items that can be placed in this slot. /// Get the maximum number of items that can be placed in this slot.
pub fn max_stack_size(&self, _target_slot_index: usize) -> u8 { pub fn max_stack_size(&self, _target_slot_index: usize) -> u32 {
64 64
} }
@ -671,9 +671,11 @@ impl Menu {
let target_slot = self.slot(target_slot_index).unwrap(); let target_slot = self.slot(target_slot_index).unwrap();
if let ItemSlot::Present(target_item) = target_slot { if let ItemSlot::Present(target_item) = target_slot {
// the target slot is empty, so we can just move the item there // the target slot is empty, so we can just move the item there
if self.may_place(target_slot_index, item) && target_item.is_same_item_and_nbt(item) { if self.may_place(target_slot_index, item)
&& target_item.is_same_item_and_components(item)
{
let slot_item_limit = self.max_stack_size(target_slot_index); let slot_item_limit = self.max_stack_size(target_slot_index);
let new_target_slot_data = item.split(u8::min(slot_item_limit, item.count as u8)); let new_target_slot_data = item.split(u32::min(slot_item_limit, item.count as u32));
// get the target slot again but mut this time so we can update it // get the target slot again but mut this time so we can update it
let target_slot = self.slot_mut(target_slot_index).unwrap(); let target_slot = self.slot_mut(target_slot_index).unwrap();
@ -691,7 +693,7 @@ impl Menu {
let target_slot = self.slot(target_slot_index).unwrap(); let target_slot = self.slot(target_slot_index).unwrap();
if target_slot.is_empty() && self.may_place(target_slot_index, item) { if target_slot.is_empty() && self.may_place(target_slot_index, item) {
let slot_item_limit = self.max_stack_size(target_slot_index); let slot_item_limit = self.max_stack_size(target_slot_index);
let new_target_slot_data = item.split(u8::min(slot_item_limit, item.count as u8)); let new_target_slot_data = item.split(u32::min(slot_item_limit, item.count as u32));
let target_slot = self.slot_mut(target_slot_index).unwrap(); let target_slot = self.slot_mut(target_slot_index).unwrap();
*target_slot = ItemSlot::Present(new_target_slot_data); *target_slot = ItemSlot::Present(new_target_slot_data);

View file

@ -1,6 +1,12 @@
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable}; use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
use simdnbt::owned::Nbt; use azalea_registry::DataComponentKind;
use std::io::{Cursor, Write}; use std::{
collections::HashMap,
fmt,
io::{Cursor, Write},
};
use crate::components::{self};
/// Either an item in an inventory or nothing. /// Either an item in an inventory or nothing.
#[derive(Debug, Clone, Default, PartialEq)] #[derive(Debug, Clone, Default, PartialEq)]
@ -33,7 +39,7 @@ impl ItemSlot {
/// ///
/// Note that it's possible for the count to be zero or negative when the /// Note that it's possible for the count to be zero or negative when the
/// slot is present. /// slot is present.
pub fn count(&self) -> i8 { pub fn count(&self) -> i32 {
match self { match self {
ItemSlot::Empty => 0, ItemSlot::Empty => 0,
ItemSlot::Present(i) => i.count, ItemSlot::Present(i) => i.count,
@ -41,7 +47,7 @@ impl ItemSlot {
} }
/// Remove `count` items from this slot, returning the removed items. /// Remove `count` items from this slot, returning the removed items.
pub fn split(&mut self, count: u8) -> ItemSlot { pub fn split(&mut self, count: u32) -> ItemSlot {
match self { match self {
ItemSlot::Empty => ItemSlot::Empty, ItemSlot::Empty => ItemSlot::Empty,
ItemSlot::Present(i) => { ItemSlot::Present(i) => {
@ -83,20 +89,20 @@ impl ItemSlot {
/// An item in an inventory, with a count and NBT. Usually you want [`ItemSlot`] /// An item in an inventory, with a count and NBT. Usually you want [`ItemSlot`]
/// or [`azalea_registry::Item`] instead. /// or [`azalea_registry::Item`] instead.
#[derive(Debug, Clone, McBuf, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct ItemSlotData { pub struct ItemSlotData {
pub kind: azalea_registry::Item,
/// The amount of the item in this slot. /// The amount of the item in this slot.
/// ///
/// The count can be zero or negative, but this is rare. /// The count can be zero or negative, but this is rare.
pub count: i8, pub count: i32,
pub nbt: Nbt, pub kind: azalea_registry::Item,
pub components: DataComponentPatch,
} }
impl ItemSlotData { impl ItemSlotData {
/// Remove `count` items from this slot, returning the removed items. /// Remove `count` items from this slot, returning the removed items.
pub fn split(&mut self, count: u8) -> ItemSlotData { pub fn split(&mut self, count: u32) -> ItemSlotData {
let returning_count = i8::min(count as i8, self.count); let returning_count = i32::min(count as i32, self.count);
let mut returning = self.clone(); let mut returning = self.clone();
returning.count = returning_count; returning.count = returning_count;
self.count -= returning_count; self.count -= returning_count;
@ -116,39 +122,161 @@ impl ItemSlotData {
/// let mut a = ItemSlotData { /// let mut a = ItemSlotData {
/// kind: Item::Stone, /// kind: Item::Stone,
/// count: 1, /// count: 1,
/// nbt: Default::default(), /// components: Default::default(),
/// }; /// };
/// let mut b = ItemSlotData { /// let mut b = ItemSlotData {
/// kind: Item::Stone, /// kind: Item::Stone,
/// count: 2, /// count: 2,
/// nbt: Default::default(), /// components: Default::default(),
/// }; /// };
/// assert!(a.is_same_item_and_nbt(&b)); /// assert!(a.is_same_item_and_components(&b));
/// ///
/// b.kind = Item::Dirt; /// b.kind = Item::Dirt;
/// assert!(!a.is_same_item_and_nbt(&b)); /// assert!(!a.is_same_item_and_components(&b));
/// ``` /// ```
pub fn is_same_item_and_nbt(&self, other: &ItemSlotData) -> bool { pub fn is_same_item_and_components(&self, other: &ItemSlotData) -> bool {
self.kind == other.kind && self.nbt == other.nbt self.kind == other.kind && self.components == other.components
} }
} }
impl McBufReadable for ItemSlot { impl McBufReadable for ItemSlot {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let slot = Option::<ItemSlotData>::read_from(buf)?; let count = i32::var_read_from(buf)?;
Ok(slot.map_or(ItemSlot::Empty, ItemSlot::Present)) if count <= 0 {
Ok(ItemSlot::Empty)
} else {
let kind = azalea_registry::Item::read_from(buf)?;
let components = DataComponentPatch::read_from(buf)?;
Ok(ItemSlot::Present(ItemSlotData {
count,
kind,
components,
}))
}
} }
} }
impl McBufWritable for ItemSlot { impl McBufWritable for ItemSlot {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
match self { match self {
ItemSlot::Empty => false.write_into(buf)?, ItemSlot::Empty => 0.var_write_into(buf)?,
ItemSlot::Present(i) => { ItemSlot::Present(i) => {
true.write_into(buf)?; i.count.var_write_into(buf)?;
i.write_into(buf)?; i.kind.write_into(buf)?;
i.components.write_into(buf)?;
} }
}; };
Ok(()) Ok(())
} }
} }
#[derive(Default)]
pub struct DataComponentPatch {
components: HashMap<DataComponentKind, Option<Box<dyn components::EncodableDataComponent>>>,
}
impl DataComponentPatch {
pub fn get(&self, kind: DataComponentKind) -> Option<&dyn components::EncodableDataComponent> {
self.components.get(&kind).and_then(|c| c.as_deref())
}
}
impl McBufReadable for DataComponentPatch {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let components_with_data_count = u32::var_read_from(buf)?;
let components_without_data_count = u32::var_read_from(buf)?;
if components_without_data_count == 0 && components_with_data_count == 0 {
return Ok(DataComponentPatch::default());
}
let mut components = HashMap::new();
for _ in 0..components_with_data_count {
let component_kind = DataComponentKind::read_from(buf)?;
let component_data = components::from_kind(component_kind, buf)?;
components.insert(component_kind, Some(component_data));
}
for _ in 0..components_without_data_count {
let component_kind = DataComponentKind::read_from(buf)?;
components.insert(component_kind, None);
}
Ok(DataComponentPatch { components })
}
}
impl McBufWritable for DataComponentPatch {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let mut components_with_data_count = 0;
let mut components_without_data_count = 0;
for component in self.components.values() {
if component.is_some() {
components_with_data_count += 1;
} else {
components_without_data_count += 1;
}
}
components_with_data_count.write_into(buf)?;
components_without_data_count.write_into(buf)?;
for (kind, component) in &self.components {
if let Some(component) = component {
kind.write_into(buf)?;
let mut component_buf = Vec::new();
component.encode(&mut component_buf).unwrap();
component_buf.write_into(buf)?;
}
}
for (kind, component) in &self.components {
if component.is_none() {
kind.write_into(buf)?;
}
}
Ok(())
}
}
impl Clone for DataComponentPatch {
fn clone(&self) -> Self {
let mut components = HashMap::with_capacity(self.components.len());
for (kind, component) in &self.components {
components.insert(*kind, component.as_ref().map(|c| (*c).clone()));
}
DataComponentPatch { components }
}
}
impl fmt::Debug for DataComponentPatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.components.keys()).finish()
}
}
impl PartialEq for DataComponentPatch {
fn eq(&self, other: &Self) -> bool {
if self.components.len() != other.components.len() {
return false;
}
for (kind, component) in &self.components {
if let Some(other_component) = other.components.get(kind) {
// we can't use PartialEq, but we can use our own eq method
if let Some(component) = component {
if let Some(other_component) = other_component {
if !component.eq((*other_component).clone()) {
return false;
}
} else {
return false;
}
} else if other_component.is_some() {
return false;
}
} else {
return false;
}
}
true
}
}

View file

@ -18,10 +18,16 @@
"advancements.adventure.arbalistic.title": "Arbalistic", "advancements.adventure.arbalistic.title": "Arbalistic",
"advancements.adventure.avoid_vibration.description": "Sneak near a Sculk Sensor or Warden to prevent it from detecting you", "advancements.adventure.avoid_vibration.description": "Sneak near a Sculk Sensor or Warden to prevent it from detecting you",
"advancements.adventure.avoid_vibration.title": "Sneak 100", "advancements.adventure.avoid_vibration.title": "Sneak 100",
"advancements.adventure.blowback.description": "Kill a Breeze with a deflected Breeze-shot Wind Charge",
"advancements.adventure.blowback.title": "Blowback",
"advancements.adventure.brush_armadillo.description": "Get Armadillo Scutes from an Armadillo using a Brush",
"advancements.adventure.brush_armadillo.title": "Isn't It Scute?",
"advancements.adventure.bullseye.description": "Hit the bullseye of a Target block from at least 30 meters away", "advancements.adventure.bullseye.description": "Hit the bullseye of a Target block from at least 30 meters away",
"advancements.adventure.bullseye.title": "Bullseye", "advancements.adventure.bullseye.title": "Bullseye",
"advancements.adventure.craft_decorated_pot_using_only_sherds.description": "Make a Decorated Pot out of 4 Pottery Sherds", "advancements.adventure.craft_decorated_pot_using_only_sherds.description": "Make a Decorated Pot out of 4 Pottery Sherds",
"advancements.adventure.craft_decorated_pot_using_only_sherds.title": "Careful Restoration", "advancements.adventure.craft_decorated_pot_using_only_sherds.title": "Careful Restoration",
"advancements.adventure.crafters_crafting_crafters.description": "Be near a Crafter when it crafts a Crafter",
"advancements.adventure.crafters_crafting_crafters.title": "Crafters Crafting Crafters",
"advancements.adventure.fall_from_world_height.description": "Free fall from the top of the world (build limit) to the bottom of the world and survive", "advancements.adventure.fall_from_world_height.description": "Free fall from the top of the world (build limit) to the bottom of the world and survive",
"advancements.adventure.fall_from_world_height.title": "Caves & Cliffs", "advancements.adventure.fall_from_world_height.title": "Caves & Cliffs",
"advancements.adventure.hero_of_the_village.description": "Successfully defend a village from a raid", "advancements.adventure.hero_of_the_village.description": "Successfully defend a village from a raid",
@ -34,14 +40,22 @@
"advancements.adventure.kill_all_mobs.title": "Monsters Hunted", "advancements.adventure.kill_all_mobs.title": "Monsters Hunted",
"advancements.adventure.kill_mob_near_sculk_catalyst.description": "Kill a mob near a Sculk Catalyst", "advancements.adventure.kill_mob_near_sculk_catalyst.description": "Kill a mob near a Sculk Catalyst",
"advancements.adventure.kill_mob_near_sculk_catalyst.title": "It Spreads", "advancements.adventure.kill_mob_near_sculk_catalyst.title": "It Spreads",
"advancements.adventure.lighten_up.description": "Scrape a Copper Bulb with an Axe to make it brighter",
"advancements.adventure.lighten_up.title": "Lighten Up",
"advancements.adventure.lightning_rod_with_villager_no_fire.description": "Protect a Villager from an undesired shock without starting a fire", "advancements.adventure.lightning_rod_with_villager_no_fire.description": "Protect a Villager from an undesired shock without starting a fire",
"advancements.adventure.lightning_rod_with_villager_no_fire.title": "Surge Protector", "advancements.adventure.lightning_rod_with_villager_no_fire.title": "Surge Protector",
"advancements.adventure.minecraft_trials_edition.description": "Step foot in a Trial Chamber",
"advancements.adventure.minecraft_trials_edition.title": "Minecraft: Trial(s) Edition",
"advancements.adventure.ol_betsy.description": "Shoot a Crossbow", "advancements.adventure.ol_betsy.description": "Shoot a Crossbow",
"advancements.adventure.ol_betsy.title": "Ol' Betsy", "advancements.adventure.ol_betsy.title": "Ol' Betsy",
"advancements.adventure.overoverkill.description": "Deal 50 hearts of damage in a single hit using the Mace",
"advancements.adventure.overoverkill.title": "Over-Overkill",
"advancements.adventure.play_jukebox_in_meadows.description": "Make the Meadows come alive with the sound of music from a Jukebox", "advancements.adventure.play_jukebox_in_meadows.description": "Make the Meadows come alive with the sound of music from a Jukebox",
"advancements.adventure.play_jukebox_in_meadows.title": "Sound of Music", "advancements.adventure.play_jukebox_in_meadows.title": "Sound of Music",
"advancements.adventure.read_power_from_chiseled_bookshelf.description": "Read the power signal of a Chiseled Bookshelf using a Comparator", "advancements.adventure.read_power_from_chiseled_bookshelf.description": "Read the power signal of a Chiseled Bookshelf using a Comparator",
"advancements.adventure.read_power_from_chiseled_bookshelf.title": "The Power of Books", "advancements.adventure.read_power_from_chiseled_bookshelf.title": "The Power of Books",
"advancements.adventure.revaulting.description": "Unlock an Ominous Vault with an Ominous Trial Key",
"advancements.adventure.revaulting.title": "Revaulting",
"advancements.adventure.root.description": "Adventure, exploration and combat", "advancements.adventure.root.description": "Adventure, exploration and combat",
"advancements.adventure.root.title": "Adventure", "advancements.adventure.root.title": "Adventure",
"advancements.adventure.salvage_sherd.description": "Brush a Suspicious block to obtain a Pottery Sherd", "advancements.adventure.salvage_sherd.description": "Brush a Suspicious block to obtain a Pottery Sherd",
@ -74,12 +88,16 @@
"advancements.adventure.trim_with_any_armor_pattern.title": "Crafting a New Look", "advancements.adventure.trim_with_any_armor_pattern.title": "Crafting a New Look",
"advancements.adventure.two_birds_one_arrow.description": "Kill two Phantoms with a piercing Arrow", "advancements.adventure.two_birds_one_arrow.description": "Kill two Phantoms with a piercing Arrow",
"advancements.adventure.two_birds_one_arrow.title": "Two Birds, One Arrow", "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.very_very_frightening.description": "Strike a Villager with lightning", "advancements.adventure.very_very_frightening.description": "Strike a Villager with lightning",
"advancements.adventure.very_very_frightening.title": "Very Very Frightening", "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...", "advancements.adventure.voluntary_exile.description": "Kill a raid captain.\nMaybe consider staying away from villages for the time being...",
"advancements.adventure.voluntary_exile.title": "Voluntary Exile", "advancements.adventure.voluntary_exile.title": "Voluntary Exile",
"advancements.adventure.walk_on_powder_snow_with_leather_boots.description": "Walk on Powder Snow... without sinking in it", "advancements.adventure.walk_on_powder_snow_with_leather_boots.description": "Walk on Powder Snow... without sinking in it",
"advancements.adventure.walk_on_powder_snow_with_leather_boots.title": "Light as a Rabbit", "advancements.adventure.walk_on_powder_snow_with_leather_boots.title": "Light as a Rabbit",
"advancements.adventure.who_needs_rockets.description": "Use a Wind Charge to launch yourself upward 8 blocks",
"advancements.adventure.who_needs_rockets.title": "Who Needs Rockets?",
"advancements.adventure.whos_the_pillager_now.description": "Give a Pillager a taste of their own medicine", "advancements.adventure.whos_the_pillager_now.description": "Give a Pillager a taste of their own medicine",
"advancements.adventure.whos_the_pillager_now.title": "Who's the Pillager Now?", "advancements.adventure.whos_the_pillager_now.title": "Who's the Pillager Now?",
"advancements.empty": "There doesn't seem to be anything here...", "advancements.empty": "There doesn't seem to be anything here...",
@ -135,6 +153,10 @@
"advancements.husbandry.plant_any_sniffer_seed.title": "Planting the Past", "advancements.husbandry.plant_any_sniffer_seed.title": "Planting the Past",
"advancements.husbandry.plant_seed.description": "Plant a seed and watch it grow", "advancements.husbandry.plant_seed.description": "Plant a seed and watch it grow",
"advancements.husbandry.plant_seed.title": "A Seedy Place", "advancements.husbandry.plant_seed.title": "A Seedy Place",
"advancements.husbandry.remove_wolf_armor.description": "Remove Wolf Armor from a Wolf using Shears",
"advancements.husbandry.remove_wolf_armor.title": "Shear Brilliance",
"advancements.husbandry.repair_wolf_armor.description": "Repair a damaged Wolf Armor using Armadillo Scutes",
"advancements.husbandry.repair_wolf_armor.title": "Good as New",
"advancements.husbandry.ride_a_boat_with_a_goat.description": "Get in a Boat and float with a Goat", "advancements.husbandry.ride_a_boat_with_a_goat.description": "Get in a Boat and float with a Goat",
"advancements.husbandry.ride_a_boat_with_a_goat.title": "Whatever Floats Your Goat!", "advancements.husbandry.ride_a_boat_with_a_goat.title": "Whatever Floats Your Goat!",
"advancements.husbandry.root.description": "The world is full of friends and food", "advancements.husbandry.root.description": "The world is full of friends and food",
@ -153,6 +175,8 @@
"advancements.husbandry.wax_off.title": "Wax Off", "advancements.husbandry.wax_off.title": "Wax Off",
"advancements.husbandry.wax_on.description": "Apply Honeycomb to a Copper block!", "advancements.husbandry.wax_on.description": "Apply Honeycomb to a Copper block!",
"advancements.husbandry.wax_on.title": "Wax On", "advancements.husbandry.wax_on.title": "Wax On",
"advancements.husbandry.whole_pack.description": "Tame one of each Wolf variant",
"advancements.husbandry.whole_pack.title": "The Whole Pack",
"advancements.nether.all_effects.description": "Have every effect applied at the same time", "advancements.nether.all_effects.description": "Have every effect applied at the same time",
"advancements.nether.all_effects.title": "How Did We Get Here?", "advancements.nether.all_effects.title": "How Did We Get Here?",
"advancements.nether.all_potions.description": "Have every potion effect applied at the same time", "advancements.nether.all_potions.description": "Have every potion effect applied at the same time",
@ -332,6 +356,7 @@
"argument.literal.incorrect": "Expected literal %s", "argument.literal.incorrect": "Expected literal %s",
"argument.long.big": "Long must not be more than %s, found %s", "argument.long.big": "Long must not be more than %s, found %s",
"argument.long.low": "Long must not be less than %s, found %s", "argument.long.low": "Long must not be less than %s, found %s",
"argument.message.too_long": "Chat message was too long (%s > maximum %s characters)",
"argument.nbt.array.invalid": "Invalid array type '%s'", "argument.nbt.array.invalid": "Invalid array type '%s'",
"argument.nbt.array.mixed": "Can't insert %s into %s", "argument.nbt.array.mixed": "Can't insert %s into %s",
"argument.nbt.expected.key": "Expected key", "argument.nbt.expected.key": "Expected key",
@ -352,6 +377,8 @@
"argument.range.empty": "Expected value or range of values", "argument.range.empty": "Expected value or range of values",
"argument.range.ints": "Only whole numbers allowed, not decimals", "argument.range.ints": "Only whole numbers allowed, not decimals",
"argument.range.swapped": "Min cannot be bigger than max", "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_tag.invalid_type": "Tag '%s' has wrong type '%s' (expected '%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_tag.not_found": "Can't find tag '%s' of type '%s'",
"argument.resource.invalid_type": "Element '%s' has wrong type '%s' (expected '%s')", "argument.resource.invalid_type": "Element '%s' has wrong type '%s' (expected '%s')",
@ -360,14 +387,21 @@
"argument.scoreboardDisplaySlot.invalid": "Unknown display slot '%s'", "argument.scoreboardDisplaySlot.invalid": "Unknown display slot '%s'",
"argument.scoreHolder.empty": "No relevant score holders could be found", "argument.scoreHolder.empty": "No relevant score holders could be found",
"argument.style.invalid": "Invalid style: %s", "argument.style.invalid": "Invalid style: %s",
"argument.time.invalid_tick_count": "Tick count must be non-negative", "argument.time.invalid_tick_count": "The tick count must be non-negative",
"argument.time.invalid_unit": "Invalid unit", "argument.time.invalid_unit": "Invalid unit",
"argument.time.tick_count_too_low": "Tick count must not be less than %s, found %s", "argument.time.tick_count_too_low": "The tick count must not be less than %s, found %s",
"argument.uuid.invalid": "Invalid UUID", "argument.uuid.invalid": "Invalid UUID",
"arguments.block.tag.unknown": "Unknown block tag '%s'", "arguments.block.tag.unknown": "Unknown block tag '%s'",
"arguments.function.tag.unknown": "Unknown function tag '%s'", "arguments.function.tag.unknown": "Unknown function tag '%s'",
"arguments.function.unknown": "Unknown function %s", "arguments.function.unknown": "Unknown function %s",
"arguments.item.component.expected": "Expected item component",
"arguments.item.component.malformed": "Malformed '%s' component: '%s'",
"arguments.item.component.repeated": "Item component '%s' was repeated, but only one value can be specified",
"arguments.item.component.unknown": "Unknown item component '%s'",
"arguments.item.malformed": "Malformed item: '%s'",
"arguments.item.overstacked": "%s can only stack up to %s", "arguments.item.overstacked": "%s can only stack up to %s",
"arguments.item.predicate.malformed": "Malformed '%s' predicate: '%s'",
"arguments.item.predicate.unknown": "Unknown item predicate '%s'",
"arguments.item.tag.unknown": "Unknown item tag '%s'", "arguments.item.tag.unknown": "Unknown item tag '%s'",
"arguments.nbtpath.node.invalid": "Invalid NBT path element", "arguments.nbtpath.node.invalid": "Invalid NBT path element",
"arguments.nbtpath.nothing_found": "Found no elements matching %s", "arguments.nbtpath.nothing_found": "Found no elements matching %s",
@ -392,14 +426,25 @@
"attribute.name.generic.attack_damage": "Attack Damage", "attribute.name.generic.attack_damage": "Attack Damage",
"attribute.name.generic.attack_knockback": "Attack Knockback", "attribute.name.generic.attack_knockback": "Attack Knockback",
"attribute.name.generic.attack_speed": "Attack Speed", "attribute.name.generic.attack_speed": "Attack Speed",
"attribute.name.generic.block_interaction_range": "Block Interaction Range",
"attribute.name.generic.entity_interaction_range": "Entity Interaction Range",
"attribute.name.generic.fall_damage_multiplier": "Fall Damage Multiplier",
"attribute.name.generic.flying_speed": "Flying Speed", "attribute.name.generic.flying_speed": "Flying Speed",
"attribute.name.generic.follow_range": "Mob Follow Range", "attribute.name.generic.follow_range": "Mob Follow Range",
"attribute.name.generic.gravity": "Gravity",
"attribute.name.generic.jump_strength": "Jump Strength",
"attribute.name.generic.knockback_resistance": "Knockback Resistance", "attribute.name.generic.knockback_resistance": "Knockback Resistance",
"attribute.name.generic.luck": "Luck", "attribute.name.generic.luck": "Luck",
"attribute.name.generic.max_absorption": "Max Absorption", "attribute.name.generic.max_absorption": "Max Absorption",
"attribute.name.generic.max_health": "Max Health", "attribute.name.generic.max_health": "Max Health",
"attribute.name.generic.movement_speed": "Speed", "attribute.name.generic.movement_speed": "Speed",
"attribute.name.generic.safe_fall_distance": "Safe Fall Distance",
"attribute.name.generic.scale": "Scale",
"attribute.name.generic.step_height": "Step Height",
"attribute.name.horse.jump_strength": "Horse Jump Strength", "attribute.name.horse.jump_strength": "Horse Jump Strength",
"attribute.name.player.block_break_speed": "Block Break Speed",
"attribute.name.player.block_interaction_range": "Block Interaction Range",
"attribute.name.player.entity_interaction_range": "Entity Interaction Range",
"attribute.name.zombie.spawn_reinforcements": "Zombie Reinforcements", "attribute.name.zombie.spawn_reinforcements": "Zombie Reinforcements",
"biome.minecraft.badlands": "Badlands", "biome.minecraft.badlands": "Badlands",
"biome.minecraft.bamboo_jungle": "Bamboo Jungle", "biome.minecraft.bamboo_jungle": "Bamboo Jungle",
@ -693,6 +738,22 @@
"block.minecraft.banner.diagonal_up_right.red": "Red Per Bend Sinister Inverted", "block.minecraft.banner.diagonal_up_right.red": "Red Per Bend Sinister Inverted",
"block.minecraft.banner.diagonal_up_right.white": "White Per Bend Sinister Inverted", "block.minecraft.banner.diagonal_up_right.white": "White Per Bend Sinister Inverted",
"block.minecraft.banner.diagonal_up_right.yellow": "Yellow Per Bend Sinister Inverted", "block.minecraft.banner.diagonal_up_right.yellow": "Yellow Per Bend Sinister Inverted",
"block.minecraft.banner.flow.black": "Black Flow",
"block.minecraft.banner.flow.blue": "Blue Flow",
"block.minecraft.banner.flow.brown": "Brown Flow",
"block.minecraft.banner.flow.cyan": "Cyan Flow",
"block.minecraft.banner.flow.gray": "Gray Flow",
"block.minecraft.banner.flow.green": "Green Flow",
"block.minecraft.banner.flow.light_blue": "Light Blue Flow",
"block.minecraft.banner.flow.light_gray": "Light Gray Flow",
"block.minecraft.banner.flow.lime": "Lime Flow",
"block.minecraft.banner.flow.magenta": "Magenta Flow",
"block.minecraft.banner.flow.orange": "Orange Flow",
"block.minecraft.banner.flow.pink": "Pink Flow",
"block.minecraft.banner.flow.purple": "Purple Flow",
"block.minecraft.banner.flow.red": "Red Flow",
"block.minecraft.banner.flow.white": "White Flow",
"block.minecraft.banner.flow.yellow": "Yellow Flow",
"block.minecraft.banner.flower.black": "Black Flower Charge", "block.minecraft.banner.flower.black": "Black Flower Charge",
"block.minecraft.banner.flower.blue": "Blue Flower Charge", "block.minecraft.banner.flower.blue": "Blue Flower Charge",
"block.minecraft.banner.flower.brown": "Brown Flower Charge", "block.minecraft.banner.flower.brown": "Brown Flower Charge",
@ -757,6 +818,22 @@
"block.minecraft.banner.gradient.red": "Red Gradient", "block.minecraft.banner.gradient.red": "Red Gradient",
"block.minecraft.banner.gradient.white": "White Gradient", "block.minecraft.banner.gradient.white": "White Gradient",
"block.minecraft.banner.gradient.yellow": "Yellow Gradient", "block.minecraft.banner.gradient.yellow": "Yellow Gradient",
"block.minecraft.banner.guster.black": "Black Guster",
"block.minecraft.banner.guster.blue": "Blue Guster",
"block.minecraft.banner.guster.brown": "Brown Guster",
"block.minecraft.banner.guster.cyan": "Cyan Guster",
"block.minecraft.banner.guster.gray": "Gray Guster",
"block.minecraft.banner.guster.green": "Green Guster",
"block.minecraft.banner.guster.light_blue": "Light Blue Guster",
"block.minecraft.banner.guster.light_gray": "Light Gray Guster",
"block.minecraft.banner.guster.lime": "Lime Guster",
"block.minecraft.banner.guster.magenta": "Magenta Guster",
"block.minecraft.banner.guster.orange": "Orange Guster",
"block.minecraft.banner.guster.pink": "Pink Guster",
"block.minecraft.banner.guster.purple": "Purple Guster",
"block.minecraft.banner.guster.red": "Red Guster",
"block.minecraft.banner.guster.white": "White Guster",
"block.minecraft.banner.guster.yellow": "Yellow Guster",
"block.minecraft.banner.half_horizontal_bottom.black": "Black Per Fess Inverted", "block.minecraft.banner.half_horizontal_bottom.black": "Black Per Fess Inverted",
"block.minecraft.banner.half_horizontal_bottom.blue": "Blue Per Fess Inverted", "block.minecraft.banner.half_horizontal_bottom.blue": "Blue Per Fess Inverted",
"block.minecraft.banner.half_horizontal_bottom.brown": "Brown Per Fess Inverted", "block.minecraft.banner.half_horizontal_bottom.brown": "Brown Per Fess Inverted",
@ -1551,6 +1628,7 @@
"block.minecraft.grindstone": "Grindstone", "block.minecraft.grindstone": "Grindstone",
"block.minecraft.hanging_roots": "Hanging Roots", "block.minecraft.hanging_roots": "Hanging Roots",
"block.minecraft.hay_block": "Hay Bale", "block.minecraft.hay_block": "Hay Bale",
"block.minecraft.heavy_core": "Heavy Core",
"block.minecraft.heavy_weighted_pressure_plate": "Heavy Weighted Pressure Plate", "block.minecraft.heavy_weighted_pressure_plate": "Heavy Weighted Pressure Plate",
"block.minecraft.honey_block": "Honey Block", "block.minecraft.honey_block": "Honey Block",
"block.minecraft.honeycomb_block": "Honeycomb Block", "block.minecraft.honeycomb_block": "Honeycomb Block",
@ -2071,6 +2149,7 @@
"block.minecraft.turtle_egg": "Turtle Egg", "block.minecraft.turtle_egg": "Turtle Egg",
"block.minecraft.twisting_vines": "Twisting Vines", "block.minecraft.twisting_vines": "Twisting Vines",
"block.minecraft.twisting_vines_plant": "Twisting Vines Plant", "block.minecraft.twisting_vines_plant": "Twisting Vines Plant",
"block.minecraft.vault": "Vault",
"block.minecraft.verdant_froglight": "Verdant Froglight", "block.minecraft.verdant_froglight": "Verdant Froglight",
"block.minecraft.vine": "Vines", "block.minecraft.vine": "Vines",
"block.minecraft.void_air": "Void Air", "block.minecraft.void_air": "Void Air",
@ -2200,9 +2279,12 @@
"chat.deleted_marker": "This chat message has been deleted by the server.", "chat.deleted_marker": "This chat message has been deleted by the server.",
"chat.disabled.chain_broken": "Chat disabled due to broken chain. Please try reconnecting.", "chat.disabled.chain_broken": "Chat disabled due to broken chain. Please try reconnecting.",
"chat.disabled.expiredProfileKey": "Chat disabled due to expired profile public key. Please try reconnecting.", "chat.disabled.expiredProfileKey": "Chat disabled due to expired profile public key. Please try reconnecting.",
"chat.disabled.invalid_command_signature": "Command had unexpected or missing command argument signatures.",
"chat.disabled.invalid_signature": "Chat had an invalid signature. Please try reconnecting.",
"chat.disabled.launcher": "Chat disabled by launcher option. Cannot send message.", "chat.disabled.launcher": "Chat disabled by launcher option. Cannot send message.",
"chat.disabled.missingProfileKey": "Chat disabled due to missing profile public key. Please try reconnecting.", "chat.disabled.missingProfileKey": "Chat disabled due to missing profile public key. Please try reconnecting.",
"chat.disabled.options": "Chat disabled in client options.", "chat.disabled.options": "Chat disabled in client options.",
"chat.disabled.out_of_order_chat": "Chat received out-of-order. Did your system time change?",
"chat.disabled.profile": "Chat not allowed by account settings. Press '%s' again for more information.", "chat.disabled.profile": "Chat not allowed by account settings. Press '%s' again for more information.",
"chat.disabled.profile.moreInfo": "Chat not allowed by account settings. Cannot send or view messages.", "chat.disabled.profile.moreInfo": "Chat not allowed by account settings. Cannot send or view messages.",
"chat.editBox": "chat", "chat.editBox": "chat",
@ -2231,6 +2313,11 @@
"chat.type.text": "<%s> %s", "chat.type.text": "<%s> %s",
"chat.type.text.narrate": "%s says %s", "chat.type.text.narrate": "%s says %s",
"chat.validation_error": "Chat validation error", "chat.validation_error": "Chat validation error",
"chunk.toast.checkLog": "See log for more details",
"chunk.toast.loadFailure": "Failed to load chunk at %s",
"chunk.toast.lowDiskSpace": "Low disk space!",
"chunk.toast.lowDiskSpace.description": "Might not be able to save the world.",
"chunk.toast.saveFailure": "Failed to save chunk at %s",
"clear.failed.multiple": "No items were found on %s players", "clear.failed.multiple": "No items were found on %s players",
"clear.failed.single": "No items were found on player %s", "clear.failed.single": "No items were found on player %s",
"color.minecraft.black": "Black", "color.minecraft.black": "Black",
@ -2363,6 +2450,7 @@
"commands.data.storage.modified": "Modified storage %s", "commands.data.storage.modified": "Modified storage %s",
"commands.data.storage.query": "Storage %s has the following contents: %s", "commands.data.storage.query": "Storage %s has the following contents: %s",
"commands.datapack.disable.failed": "Pack '%s' is not enabled!", "commands.datapack.disable.failed": "Pack '%s' is not enabled!",
"commands.datapack.disable.failed.feature": "Pack '%s' cannot be disabled, since it is part of an enabled flag!",
"commands.datapack.enable.failed": "Pack '%s' is already enabled!", "commands.datapack.enable.failed": "Pack '%s' is already enabled!",
"commands.datapack.enable.failed.no_flags": "Pack '%s' cannot be enabled, since required flags are not enabled in this world: %s!", "commands.datapack.enable.failed.no_flags": "Pack '%s' cannot be enabled, since required flags are not enabled in this world: %s!",
"commands.datapack.list.available.none": "There are no more data packs available", "commands.datapack.list.available.none": "There are no more data packs available",
@ -2613,6 +2701,7 @@
"commands.setblock.failed": "Could not set the block", "commands.setblock.failed": "Could not set the block",
"commands.setblock.success": "Changed the block at %s, %s, %s", "commands.setblock.success": "Changed the block at %s, %s, %s",
"commands.setidletimeout.success": "The player idle timeout is now %s minute(s)", "commands.setidletimeout.success": "The player idle timeout is now %s minute(s)",
"commands.setworldspawn.failure.not_overworld": "Can only set the world spawn for overworld",
"commands.setworldspawn.success": "Set the world spawn point to %s, %s, %s [%s]", "commands.setworldspawn.success": "Set the world spawn point to %s, %s, %s [%s]",
"commands.spawnpoint.success.multiple": "Set spawn point to %s, %s, %s [%s] in %s for %s players", "commands.spawnpoint.success.multiple": "Set spawn point to %s, %s, %s [%s] in %s for %s players",
"commands.spawnpoint.success.single": "Set spawn point to %s, %s, %s [%s] in %s for %s", "commands.spawnpoint.success.single": "Set spawn point to %s, %s, %s [%s] in %s for %s",
@ -2689,14 +2778,14 @@
"commands.tick.rate.success": "Set the target tick rate to %s per second", "commands.tick.rate.success": "Set the target tick rate to %s per second",
"commands.tick.sprint.report": "Sprint completed with %s ticks per second, or %s ms per tick", "commands.tick.sprint.report": "Sprint completed with %s ticks per second, or %s ms per tick",
"commands.tick.sprint.stop.fail": "No tick sprint in progress", "commands.tick.sprint.stop.fail": "No tick sprint in progress",
"commands.tick.sprint.stop.success": "A tick sprint interrupted", "commands.tick.sprint.stop.success": "Interrupted the current tick sprint",
"commands.tick.status.frozen": "The game is frozen", "commands.tick.status.frozen": "The game is frozen",
"commands.tick.status.lagging": "The game is running, but can't keep up with the target tick rate", "commands.tick.status.lagging": "The game is running, but can't keep up with the target tick rate",
"commands.tick.status.running": "The game runs normally", "commands.tick.status.running": "The game is running normally",
"commands.tick.status.sprinting": "The game is sprinting", "commands.tick.status.sprinting": "The game is sprinting",
"commands.tick.step.fail": "Unable to step the game - the game must be frozen first", "commands.tick.step.fail": "Unable to step the game - the game must be frozen first",
"commands.tick.step.stop.fail": "No tick step in progress", "commands.tick.step.stop.fail": "No tick step in progress",
"commands.tick.step.stop.success": "A tick step interrupted", "commands.tick.step.stop.success": "Interrupted the current tick step",
"commands.tick.step.success": "Stepping %s tick(s)", "commands.tick.step.success": "Stepping %s tick(s)",
"commands.time.query": "The time is %s", "commands.time.query": "The time is %s",
"commands.time.set": "Set the time to %s", "commands.time.set": "Set the time to %s",
@ -2712,6 +2801,9 @@
"commands.title.show.title.single": "Showing new title for %s", "commands.title.show.title.single": "Showing new title for %s",
"commands.title.times.multiple": "Changed title display times for %s players", "commands.title.times.multiple": "Changed title display times for %s players",
"commands.title.times.single": "Changed title display times for %s", "commands.title.times.single": "Changed title display times for %s",
"commands.transfer.error.no_players": "Must specify at least one player to transfer",
"commands.transfer.success.multiple": "Transferring %s players to %s:%s",
"commands.transfer.success.single": "Transferring %s to %s:%s",
"commands.trigger.add.success": "Triggered %s (added %s to value)", "commands.trigger.add.success": "Triggered %s (added %s to value)",
"commands.trigger.failed.invalid": "You can only trigger objectives that are 'trigger' type", "commands.trigger.failed.invalid": "You can only trigger objectives that are 'trigger' type",
"commands.trigger.failed.unprimed": "You cannot trigger this objective yet", "commands.trigger.failed.unprimed": "You cannot trigger this objective yet",
@ -2757,10 +2849,12 @@
"connect.connecting": "Connecting to the server...", "connect.connecting": "Connecting to the server...",
"connect.encrypting": "Encrypting...", "connect.encrypting": "Encrypting...",
"connect.failed": "Failed to connect to the server", "connect.failed": "Failed to connect to the server",
"connect.failed.transfer": "Connection failed while transferring to the server",
"connect.joining": "Joining world...", "connect.joining": "Joining world...",
"connect.negotiating": "Negotiating...", "connect.negotiating": "Negotiating...",
"connect.reconfiging": "Reconfiguring...", "connect.reconfiging": "Reconfiguring...",
"connect.reconfiguring": "Reconfiguring...", "connect.reconfiguring": "Reconfiguring...",
"connect.transferring": "Transferring to new server...",
"container.barrel": "Barrel", "container.barrel": "Barrel",
"container.beacon": "Beacon", "container.beacon": "Beacon",
"container.blast_furnace": "Blast Furnace", "container.blast_furnace": "Blast Furnace",
@ -3094,9 +3188,11 @@
"disconnect.loginFailedInfo.userBanned": "You are banned from playing online", "disconnect.loginFailedInfo.userBanned": "You are banned from playing online",
"disconnect.lost": "Connection Lost", "disconnect.lost": "Connection Lost",
"disconnect.overflow": "Buffer overflow", "disconnect.overflow": "Buffer overflow",
"disconnect.packetError": "Network Protocol Error",
"disconnect.quitting": "Quitting", "disconnect.quitting": "Quitting",
"disconnect.spam": "Kicked for spamming", "disconnect.spam": "Kicked for spamming",
"disconnect.timeout": "Timed out", "disconnect.timeout": "Timed out",
"disconnect.transfer": "Transferred to another server",
"disconnect.unknownHost": "Unknown host", "disconnect.unknownHost": "Unknown host",
"download.pack.failed": "%s out of %s packs failed to download", "download.pack.failed": "%s out of %s packs failed to download",
"download.pack.progress.bytes": "Progress: %s (total size unknown)", "download.pack.progress.bytes": "Progress: %s (total size unknown)",
@ -3117,6 +3213,7 @@
"effect.minecraft.health_boost": "Health Boost", "effect.minecraft.health_boost": "Health Boost",
"effect.minecraft.hero_of_the_village": "Hero of the Village", "effect.minecraft.hero_of_the_village": "Hero of the Village",
"effect.minecraft.hunger": "Hunger", "effect.minecraft.hunger": "Hunger",
"effect.minecraft.infested": "Infested",
"effect.minecraft.instant_damage": "Instant Damage", "effect.minecraft.instant_damage": "Instant Damage",
"effect.minecraft.instant_health": "Instant Health", "effect.minecraft.instant_health": "Instant Health",
"effect.minecraft.invisibility": "Invisibility", "effect.minecraft.invisibility": "Invisibility",
@ -3126,7 +3223,9 @@
"effect.minecraft.mining_fatigue": "Mining Fatigue", "effect.minecraft.mining_fatigue": "Mining Fatigue",
"effect.minecraft.nausea": "Nausea", "effect.minecraft.nausea": "Nausea",
"effect.minecraft.night_vision": "Night Vision", "effect.minecraft.night_vision": "Night Vision",
"effect.minecraft.oozing": "Oozing",
"effect.minecraft.poison": "Poison", "effect.minecraft.poison": "Poison",
"effect.minecraft.raid_omen": "Raid Omen",
"effect.minecraft.regeneration": "Regeneration", "effect.minecraft.regeneration": "Regeneration",
"effect.minecraft.resistance": "Resistance", "effect.minecraft.resistance": "Resistance",
"effect.minecraft.saturation": "Saturation", "effect.minecraft.saturation": "Saturation",
@ -3134,9 +3233,12 @@
"effect.minecraft.slowness": "Slowness", "effect.minecraft.slowness": "Slowness",
"effect.minecraft.speed": "Speed", "effect.minecraft.speed": "Speed",
"effect.minecraft.strength": "Strength", "effect.minecraft.strength": "Strength",
"effect.minecraft.trial_omen": "Trial Omen",
"effect.minecraft.unluck": "Bad Luck", "effect.minecraft.unluck": "Bad Luck",
"effect.minecraft.water_breathing": "Water Breathing", "effect.minecraft.water_breathing": "Water Breathing",
"effect.minecraft.weakness": "Weakness", "effect.minecraft.weakness": "Weakness",
"effect.minecraft.weaving": "Weaving",
"effect.minecraft.wind_charged": "Wind Charged",
"effect.minecraft.wither": "Wither", "effect.minecraft.wither": "Wither",
"effect.none": "No Effects", "effect.none": "No Effects",
"enchantment.level.1": "I", "enchantment.level.1": "I",
@ -3153,7 +3255,9 @@
"enchantment.minecraft.bane_of_arthropods": "Bane of Arthropods", "enchantment.minecraft.bane_of_arthropods": "Bane of Arthropods",
"enchantment.minecraft.binding_curse": "Curse of Binding", "enchantment.minecraft.binding_curse": "Curse of Binding",
"enchantment.minecraft.blast_protection": "Blast Protection", "enchantment.minecraft.blast_protection": "Blast Protection",
"enchantment.minecraft.breach": "Breach",
"enchantment.minecraft.channeling": "Channeling", "enchantment.minecraft.channeling": "Channeling",
"enchantment.minecraft.density": "Density",
"enchantment.minecraft.depth_strider": "Depth Strider", "enchantment.minecraft.depth_strider": "Depth Strider",
"enchantment.minecraft.efficiency": "Efficiency", "enchantment.minecraft.efficiency": "Efficiency",
"enchantment.minecraft.feather_falling": "Feather Falling", "enchantment.minecraft.feather_falling": "Feather Falling",
@ -3184,12 +3288,15 @@
"enchantment.minecraft.smite": "Smite", "enchantment.minecraft.smite": "Smite",
"enchantment.minecraft.soul_speed": "Soul Speed", "enchantment.minecraft.soul_speed": "Soul Speed",
"enchantment.minecraft.sweeping": "Sweeping Edge", "enchantment.minecraft.sweeping": "Sweeping Edge",
"enchantment.minecraft.sweeping_edge": "Sweeping Edge",
"enchantment.minecraft.swift_sneak": "Swift Sneak", "enchantment.minecraft.swift_sneak": "Swift Sneak",
"enchantment.minecraft.thorns": "Thorns", "enchantment.minecraft.thorns": "Thorns",
"enchantment.minecraft.unbreaking": "Unbreaking", "enchantment.minecraft.unbreaking": "Unbreaking",
"enchantment.minecraft.vanishing_curse": "Curse of Vanishing", "enchantment.minecraft.vanishing_curse": "Curse of Vanishing",
"enchantment.minecraft.wind_burst": "Wind Burst",
"entity.minecraft.allay": "Allay", "entity.minecraft.allay": "Allay",
"entity.minecraft.area_effect_cloud": "Area Effect Cloud", "entity.minecraft.area_effect_cloud": "Area Effect Cloud",
"entity.minecraft.armadillo": "Armadillo",
"entity.minecraft.armor_stand": "Armor Stand", "entity.minecraft.armor_stand": "Armor Stand",
"entity.minecraft.arrow": "Arrow", "entity.minecraft.arrow": "Arrow",
"entity.minecraft.axolotl": "Axolotl", "entity.minecraft.axolotl": "Axolotl",
@ -3198,7 +3305,9 @@
"entity.minecraft.blaze": "Blaze", "entity.minecraft.blaze": "Blaze",
"entity.minecraft.block_display": "Block Display", "entity.minecraft.block_display": "Block Display",
"entity.minecraft.boat": "Boat", "entity.minecraft.boat": "Boat",
"entity.minecraft.bogged": "Bogged",
"entity.minecraft.breeze": "Breeze", "entity.minecraft.breeze": "Breeze",
"entity.minecraft.breeze_wind_charge": "Wind Charge",
"entity.minecraft.camel": "Camel", "entity.minecraft.camel": "Camel",
"entity.minecraft.cat": "Cat", "entity.minecraft.cat": "Cat",
"entity.minecraft.cave_spider": "Cave Spider", "entity.minecraft.cave_spider": "Cave Spider",
@ -3260,6 +3369,7 @@
"entity.minecraft.mooshroom": "Mooshroom", "entity.minecraft.mooshroom": "Mooshroom",
"entity.minecraft.mule": "Mule", "entity.minecraft.mule": "Mule",
"entity.minecraft.ocelot": "Ocelot", "entity.minecraft.ocelot": "Ocelot",
"entity.minecraft.ominous_item_spawner": "Ominous Item Spawner",
"entity.minecraft.painting": "Painting", "entity.minecraft.painting": "Painting",
"entity.minecraft.panda": "Panda", "entity.minecraft.panda": "Panda",
"entity.minecraft.parrot": "Parrot", "entity.minecraft.parrot": "Parrot",
@ -3381,6 +3491,7 @@
"filled_map.mansion": "Woodland Explorer Map", "filled_map.mansion": "Woodland Explorer Map",
"filled_map.monument": "Ocean Explorer Map", "filled_map.monument": "Ocean Explorer Map",
"filled_map.scale": "Scaling at 1:%s", "filled_map.scale": "Scaling at 1:%s",
"filled_map.trial_chambers": "Trial Chambers Map",
"filled_map.unknown": "Unknown Map", "filled_map.unknown": "Unknown Map",
"filled_map.village_desert": "Desert Village Map", "filled_map.village_desert": "Desert Village Map",
"filled_map.village_plains": "Plains Village Map", "filled_map.village_plains": "Plains Village Map",
@ -3476,7 +3587,10 @@
"gamerule.showDeathMessages": "Show death messages", "gamerule.showDeathMessages": "Show death messages",
"gamerule.snowAccumulationHeight": "Snow accumulation height", "gamerule.snowAccumulationHeight": "Snow accumulation height",
"gamerule.snowAccumulationHeight.description": "When it snows, layers of snow form on the ground up to at most this number of layers.", "gamerule.snowAccumulationHeight.description": "When it snows, layers of snow form on the ground up to at most this number of layers.",
"gamerule.spawnChunkRadius": "Spawn chunk radius",
"gamerule.spawnChunkRadius.description": "Amount of chunks that stay loaded around the overworld spawn position.",
"gamerule.spawnRadius": "Respawn location radius", "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.spectatorsGenerateChunks": "Allow spectators to generate terrain",
"gamerule.tntExplosionDropDecay": "In TNT explosions, some blocks won't drop their loot", "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.tntExplosionDropDecay.description": "Some of the drops from blocks destroyed by explosions caused by TNT are lost in the explosion.",
@ -3700,7 +3814,9 @@
"item_modifier.unknown": "Unknown item modifier: %s", "item_modifier.unknown": "Unknown item modifier: %s",
"item.canBreak": "Can break:", "item.canBreak": "Can break:",
"item.canPlace": "Can be placed on:", "item.canPlace": "Can be placed on:",
"item.canUse.unknown": "Unknown",
"item.color": "Color: %s", "item.color": "Color: %s",
"item.components": "%s component(s)",
"item.disabled": "Disabled item", "item.disabled": "Disabled item",
"item.durability": "Durability: %s / %s", "item.durability": "Durability: %s / %s",
"item.dyed": "Dyed", "item.dyed": "Dyed",
@ -3713,6 +3829,8 @@
"item.minecraft.apple": "Apple", "item.minecraft.apple": "Apple",
"item.minecraft.archer_pottery_shard": "Archer Pottery Shard", "item.minecraft.archer_pottery_shard": "Archer Pottery Shard",
"item.minecraft.archer_pottery_sherd": "Archer Pottery Sherd", "item.minecraft.archer_pottery_sherd": "Archer Pottery Sherd",
"item.minecraft.armadillo_scute": "Armadillo Scute",
"item.minecraft.armadillo_spawn_egg": "Armadillo Spawn Egg",
"item.minecraft.armor_stand": "Armor Stand", "item.minecraft.armor_stand": "Armor Stand",
"item.minecraft.arms_up_pottery_shard": "Arms Up Pottery Shard", "item.minecraft.arms_up_pottery_shard": "Arms Up Pottery Shard",
"item.minecraft.arms_up_pottery_sherd": "Arms Up Pottery Sherd", "item.minecraft.arms_up_pottery_sherd": "Arms Up Pottery Sherd",
@ -3737,12 +3855,15 @@
"item.minecraft.blaze_rod": "Blaze Rod", "item.minecraft.blaze_rod": "Blaze Rod",
"item.minecraft.blaze_spawn_egg": "Blaze Spawn Egg", "item.minecraft.blaze_spawn_egg": "Blaze Spawn Egg",
"item.minecraft.blue_dye": "Blue Dye", "item.minecraft.blue_dye": "Blue Dye",
"item.minecraft.bogged_spawn_egg": "Bogged Spawn Egg",
"item.minecraft.bolt_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.bone": "Bone", "item.minecraft.bone": "Bone",
"item.minecraft.bone_meal": "Bone Meal", "item.minecraft.bone_meal": "Bone Meal",
"item.minecraft.book": "Book", "item.minecraft.book": "Book",
"item.minecraft.bow": "Bow", "item.minecraft.bow": "Bow",
"item.minecraft.bowl": "Bowl", "item.minecraft.bowl": "Bowl",
"item.minecraft.bread": "Bread", "item.minecraft.bread": "Bread",
"item.minecraft.breeze_rod": "Breeze Rod",
"item.minecraft.breeze_spawn_egg": "Breeze Spawn Egg", "item.minecraft.breeze_spawn_egg": "Breeze Spawn Egg",
"item.minecraft.brewer_pottery_shard": "Brewer Pottery Shard", "item.minecraft.brewer_pottery_shard": "Brewer Pottery Shard",
"item.minecraft.brewer_pottery_sherd": "Brewer Pottery Sherd", "item.minecraft.brewer_pottery_sherd": "Brewer Pottery Sherd",
@ -3879,6 +4000,10 @@
"item.minecraft.fishing_rod": "Fishing Rod", "item.minecraft.fishing_rod": "Fishing Rod",
"item.minecraft.flint": "Flint", "item.minecraft.flint": "Flint",
"item.minecraft.flint_and_steel": "Flint and Steel", "item.minecraft.flint_and_steel": "Flint and Steel",
"item.minecraft.flow_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.flow_banner_pattern": "Banner Pattern",
"item.minecraft.flow_banner_pattern.desc": "Flow",
"item.minecraft.flow_pottery_sherd": "Flow Pottery Sherd",
"item.minecraft.flower_banner_pattern": "Banner Pattern", "item.minecraft.flower_banner_pattern": "Banner Pattern",
"item.minecraft.flower_banner_pattern.desc": "Flower Charge", "item.minecraft.flower_banner_pattern.desc": "Flower Charge",
"item.minecraft.flower_pot": "Flower Pot", "item.minecraft.flower_pot": "Flower Pot",
@ -3918,6 +4043,9 @@
"item.minecraft.green_dye": "Green Dye", "item.minecraft.green_dye": "Green Dye",
"item.minecraft.guardian_spawn_egg": "Guardian Spawn Egg", "item.minecraft.guardian_spawn_egg": "Guardian Spawn Egg",
"item.minecraft.gunpowder": "Gunpowder", "item.minecraft.gunpowder": "Gunpowder",
"item.minecraft.guster_banner_pattern": "Banner Pattern",
"item.minecraft.guster_banner_pattern.desc": "Guster",
"item.minecraft.guster_pottery_sherd": "Guster Pottery Sherd",
"item.minecraft.heart_of_the_sea": "Heart of the Sea", "item.minecraft.heart_of_the_sea": "Heart of the Sea",
"item.minecraft.heart_pottery_shard": "Heart Pottery Shard", "item.minecraft.heart_pottery_shard": "Heart Pottery Shard",
"item.minecraft.heart_pottery_sherd": "Heart Pottery Sherd", "item.minecraft.heart_pottery_sherd": "Heart Pottery Sherd",
@ -3968,12 +4096,14 @@
"item.minecraft.lingering_potion.effect.fire_resistance": "Lingering Potion of Fire Resistance", "item.minecraft.lingering_potion.effect.fire_resistance": "Lingering Potion of Fire Resistance",
"item.minecraft.lingering_potion.effect.harming": "Lingering Potion of Harming", "item.minecraft.lingering_potion.effect.harming": "Lingering Potion of Harming",
"item.minecraft.lingering_potion.effect.healing": "Lingering Potion of Healing", "item.minecraft.lingering_potion.effect.healing": "Lingering Potion of Healing",
"item.minecraft.lingering_potion.effect.infested": "Lingering Potion of Infestation",
"item.minecraft.lingering_potion.effect.invisibility": "Lingering Potion of Invisibility", "item.minecraft.lingering_potion.effect.invisibility": "Lingering Potion of Invisibility",
"item.minecraft.lingering_potion.effect.leaping": "Lingering Potion of Leaping", "item.minecraft.lingering_potion.effect.leaping": "Lingering Potion of Leaping",
"item.minecraft.lingering_potion.effect.levitation": "Lingering Potion of Levitation", "item.minecraft.lingering_potion.effect.levitation": "Lingering Potion of Levitation",
"item.minecraft.lingering_potion.effect.luck": "Lingering Potion of Luck", "item.minecraft.lingering_potion.effect.luck": "Lingering Potion of Luck",
"item.minecraft.lingering_potion.effect.mundane": "Mundane Lingering Potion", "item.minecraft.lingering_potion.effect.mundane": "Mundane Lingering Potion",
"item.minecraft.lingering_potion.effect.night_vision": "Lingering Potion of Night Vision", "item.minecraft.lingering_potion.effect.night_vision": "Lingering Potion of Night Vision",
"item.minecraft.lingering_potion.effect.oozing": "Lingering Potion of Oozing",
"item.minecraft.lingering_potion.effect.poison": "Lingering Potion of Poison", "item.minecraft.lingering_potion.effect.poison": "Lingering Potion of Poison",
"item.minecraft.lingering_potion.effect.regeneration": "Lingering Potion of Regeneration", "item.minecraft.lingering_potion.effect.regeneration": "Lingering Potion of Regeneration",
"item.minecraft.lingering_potion.effect.slow_falling": "Lingering Potion of Slow Falling", "item.minecraft.lingering_potion.effect.slow_falling": "Lingering Potion of Slow Falling",
@ -3985,8 +4115,11 @@
"item.minecraft.lingering_potion.effect.water": "Lingering Water Bottle", "item.minecraft.lingering_potion.effect.water": "Lingering Water Bottle",
"item.minecraft.lingering_potion.effect.water_breathing": "Lingering Potion of Water Breathing", "item.minecraft.lingering_potion.effect.water_breathing": "Lingering Potion of Water Breathing",
"item.minecraft.lingering_potion.effect.weakness": "Lingering Potion of Weakness", "item.minecraft.lingering_potion.effect.weakness": "Lingering Potion of Weakness",
"item.minecraft.lingering_potion.effect.weaving": "Lingering Potion of Weaving",
"item.minecraft.lingering_potion.effect.wind_charged": "Lingering Potion of Wind Charging",
"item.minecraft.llama_spawn_egg": "Llama Spawn Egg", "item.minecraft.llama_spawn_egg": "Llama Spawn Egg",
"item.minecraft.lodestone_compass": "Lodestone Compass", "item.minecraft.lodestone_compass": "Lodestone Compass",
"item.minecraft.mace": "Mace",
"item.minecraft.magenta_dye": "Magenta Dye", "item.minecraft.magenta_dye": "Magenta Dye",
"item.minecraft.magma_cream": "Magma Cream", "item.minecraft.magma_cream": "Magma Cream",
"item.minecraft.magma_cube_spawn_egg": "Magma Cube Spawn Egg", "item.minecraft.magma_cube_spawn_egg": "Magma Cube Spawn Egg",
@ -4059,6 +4192,8 @@
"item.minecraft.oak_boat": "Oak Boat", "item.minecraft.oak_boat": "Oak Boat",
"item.minecraft.oak_chest_boat": "Oak Boat with Chest", "item.minecraft.oak_chest_boat": "Oak Boat with Chest",
"item.minecraft.ocelot_spawn_egg": "Ocelot Spawn Egg", "item.minecraft.ocelot_spawn_egg": "Ocelot Spawn Egg",
"item.minecraft.ominous_bottle": "Ominous Bottle",
"item.minecraft.ominous_trial_key": "Ominous Trial Key",
"item.minecraft.orange_dye": "Orange Dye", "item.minecraft.orange_dye": "Orange Dye",
"item.minecraft.painting": "Painting", "item.minecraft.painting": "Painting",
"item.minecraft.panda_spawn_egg": "Panda Spawn Egg", "item.minecraft.panda_spawn_egg": "Panda Spawn Egg",
@ -4088,12 +4223,14 @@
"item.minecraft.potion.effect.fire_resistance": "Potion of Fire Resistance", "item.minecraft.potion.effect.fire_resistance": "Potion of Fire Resistance",
"item.minecraft.potion.effect.harming": "Potion of Harming", "item.minecraft.potion.effect.harming": "Potion of Harming",
"item.minecraft.potion.effect.healing": "Potion of Healing", "item.minecraft.potion.effect.healing": "Potion of Healing",
"item.minecraft.potion.effect.infested": "Potion of Infestation",
"item.minecraft.potion.effect.invisibility": "Potion of Invisibility", "item.minecraft.potion.effect.invisibility": "Potion of Invisibility",
"item.minecraft.potion.effect.leaping": "Potion of Leaping", "item.minecraft.potion.effect.leaping": "Potion of Leaping",
"item.minecraft.potion.effect.levitation": "Potion of Levitation", "item.minecraft.potion.effect.levitation": "Potion of Levitation",
"item.minecraft.potion.effect.luck": "Potion of Luck", "item.minecraft.potion.effect.luck": "Potion of Luck",
"item.minecraft.potion.effect.mundane": "Mundane Potion", "item.minecraft.potion.effect.mundane": "Mundane Potion",
"item.minecraft.potion.effect.night_vision": "Potion of Night Vision", "item.minecraft.potion.effect.night_vision": "Potion of Night Vision",
"item.minecraft.potion.effect.oozing": "Potion of Oozing",
"item.minecraft.potion.effect.poison": "Potion of Poison", "item.minecraft.potion.effect.poison": "Potion of Poison",
"item.minecraft.potion.effect.regeneration": "Potion of Regeneration", "item.minecraft.potion.effect.regeneration": "Potion of Regeneration",
"item.minecraft.potion.effect.slow_falling": "Potion of Slow Falling", "item.minecraft.potion.effect.slow_falling": "Potion of Slow Falling",
@ -4105,6 +4242,8 @@
"item.minecraft.potion.effect.water": "Water Bottle", "item.minecraft.potion.effect.water": "Water Bottle",
"item.minecraft.potion.effect.water_breathing": "Potion of Water Breathing", "item.minecraft.potion.effect.water_breathing": "Potion of Water Breathing",
"item.minecraft.potion.effect.weakness": "Potion of Weakness", "item.minecraft.potion.effect.weakness": "Potion of Weakness",
"item.minecraft.potion.effect.weaving": "Potion of Weaving",
"item.minecraft.potion.effect.wind_charged": "Potion of Wind Charging",
"item.minecraft.pottery_shard_archer": "Archer Pottery Shard", "item.minecraft.pottery_shard_archer": "Archer Pottery Shard",
"item.minecraft.pottery_shard_arms_up": "Arms Up Pottery Shard", "item.minecraft.pottery_shard_arms_up": "Arms Up Pottery Shard",
"item.minecraft.pottery_shard_prize": "Prize Pottery Shard", "item.minecraft.pottery_shard_prize": "Prize Pottery Shard",
@ -4140,6 +4279,7 @@
"item.minecraft.salmon": "Raw Salmon", "item.minecraft.salmon": "Raw Salmon",
"item.minecraft.salmon_bucket": "Bucket of Salmon", "item.minecraft.salmon_bucket": "Bucket of Salmon",
"item.minecraft.salmon_spawn_egg": "Salmon Spawn Egg", "item.minecraft.salmon_spawn_egg": "Salmon Spawn Egg",
"item.minecraft.scrape_pottery_sherd": "Scrape Pottery Sherd",
"item.minecraft.scute": "Scute", "item.minecraft.scute": "Scute",
"item.minecraft.sentry_armor_trim_smithing_template": "Smithing Template", "item.minecraft.sentry_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.shaper_armor_trim_smithing_template": "Smithing Template", "item.minecraft.shaper_armor_trim_smithing_template": "Smithing Template",
@ -4207,12 +4347,14 @@
"item.minecraft.splash_potion.effect.fire_resistance": "Splash Potion of Fire Resistance", "item.minecraft.splash_potion.effect.fire_resistance": "Splash Potion of Fire Resistance",
"item.minecraft.splash_potion.effect.harming": "Splash Potion of Harming", "item.minecraft.splash_potion.effect.harming": "Splash Potion of Harming",
"item.minecraft.splash_potion.effect.healing": "Splash Potion of Healing", "item.minecraft.splash_potion.effect.healing": "Splash Potion of Healing",
"item.minecraft.splash_potion.effect.infested": "Splash Potion of Infestation",
"item.minecraft.splash_potion.effect.invisibility": "Splash Potion of Invisibility", "item.minecraft.splash_potion.effect.invisibility": "Splash Potion of Invisibility",
"item.minecraft.splash_potion.effect.leaping": "Splash Potion of Leaping", "item.minecraft.splash_potion.effect.leaping": "Splash Potion of Leaping",
"item.minecraft.splash_potion.effect.levitation": "Splash Potion of Levitation", "item.minecraft.splash_potion.effect.levitation": "Splash Potion of Levitation",
"item.minecraft.splash_potion.effect.luck": "Splash Potion of Luck", "item.minecraft.splash_potion.effect.luck": "Splash Potion of Luck",
"item.minecraft.splash_potion.effect.mundane": "Mundane Splash Potion", "item.minecraft.splash_potion.effect.mundane": "Mundane Splash Potion",
"item.minecraft.splash_potion.effect.night_vision": "Splash Potion of Night Vision", "item.minecraft.splash_potion.effect.night_vision": "Splash Potion of Night Vision",
"item.minecraft.splash_potion.effect.oozing": "Splash Potion of Oozing",
"item.minecraft.splash_potion.effect.poison": "Splash Potion of Poison", "item.minecraft.splash_potion.effect.poison": "Splash Potion of Poison",
"item.minecraft.splash_potion.effect.regeneration": "Splash Potion of Regeneration", "item.minecraft.splash_potion.effect.regeneration": "Splash Potion of Regeneration",
"item.minecraft.splash_potion.effect.slow_falling": "Splash Potion of Slow Falling", "item.minecraft.splash_potion.effect.slow_falling": "Splash Potion of Slow Falling",
@ -4224,6 +4366,8 @@
"item.minecraft.splash_potion.effect.water": "Splash Water Bottle", "item.minecraft.splash_potion.effect.water": "Splash Water Bottle",
"item.minecraft.splash_potion.effect.water_breathing": "Splash Potion of Water Breathing", "item.minecraft.splash_potion.effect.water_breathing": "Splash Potion of Water Breathing",
"item.minecraft.splash_potion.effect.weakness": "Splash Potion of Weakness", "item.minecraft.splash_potion.effect.weakness": "Splash Potion of Weakness",
"item.minecraft.splash_potion.effect.weaving": "Splash Potion of Weaving",
"item.minecraft.splash_potion.effect.wind_charged": "Splash Potion of Wind Charging",
"item.minecraft.spruce_boat": "Spruce Boat", "item.minecraft.spruce_boat": "Spruce Boat",
"item.minecraft.spruce_chest_boat": "Spruce Boat with Chest", "item.minecraft.spruce_chest_boat": "Spruce Boat with Chest",
"item.minecraft.spyglass": "Spyglass", "item.minecraft.spyglass": "Spyglass",
@ -4249,12 +4393,14 @@
"item.minecraft.tipped_arrow.effect.fire_resistance": "Arrow of Fire Resistance", "item.minecraft.tipped_arrow.effect.fire_resistance": "Arrow of Fire Resistance",
"item.minecraft.tipped_arrow.effect.harming": "Arrow of Harming", "item.minecraft.tipped_arrow.effect.harming": "Arrow of Harming",
"item.minecraft.tipped_arrow.effect.healing": "Arrow of Healing", "item.minecraft.tipped_arrow.effect.healing": "Arrow of Healing",
"item.minecraft.tipped_arrow.effect.infested": "Arrow of Infestation",
"item.minecraft.tipped_arrow.effect.invisibility": "Arrow of Invisibility", "item.minecraft.tipped_arrow.effect.invisibility": "Arrow of Invisibility",
"item.minecraft.tipped_arrow.effect.leaping": "Arrow of Leaping", "item.minecraft.tipped_arrow.effect.leaping": "Arrow of Leaping",
"item.minecraft.tipped_arrow.effect.levitation": "Arrow of Levitation", "item.minecraft.tipped_arrow.effect.levitation": "Arrow of Levitation",
"item.minecraft.tipped_arrow.effect.luck": "Arrow of Luck", "item.minecraft.tipped_arrow.effect.luck": "Arrow of Luck",
"item.minecraft.tipped_arrow.effect.mundane": "Tipped Arrow", "item.minecraft.tipped_arrow.effect.mundane": "Tipped Arrow",
"item.minecraft.tipped_arrow.effect.night_vision": "Arrow of Night Vision", "item.minecraft.tipped_arrow.effect.night_vision": "Arrow of Night Vision",
"item.minecraft.tipped_arrow.effect.oozing": "Arrow of Oozing",
"item.minecraft.tipped_arrow.effect.poison": "Arrow of Poison", "item.minecraft.tipped_arrow.effect.poison": "Arrow of Poison",
"item.minecraft.tipped_arrow.effect.regeneration": "Arrow of Regeneration", "item.minecraft.tipped_arrow.effect.regeneration": "Arrow of Regeneration",
"item.minecraft.tipped_arrow.effect.slow_falling": "Arrow of Slow Falling", "item.minecraft.tipped_arrow.effect.slow_falling": "Arrow of Slow Falling",
@ -4266,6 +4412,8 @@
"item.minecraft.tipped_arrow.effect.water": "Arrow of Splashing", "item.minecraft.tipped_arrow.effect.water": "Arrow of Splashing",
"item.minecraft.tipped_arrow.effect.water_breathing": "Arrow of Water Breathing", "item.minecraft.tipped_arrow.effect.water_breathing": "Arrow of Water Breathing",
"item.minecraft.tipped_arrow.effect.weakness": "Arrow of Weakness", "item.minecraft.tipped_arrow.effect.weakness": "Arrow of Weakness",
"item.minecraft.tipped_arrow.effect.weaving": "Arrow of Weaving",
"item.minecraft.tipped_arrow.effect.wind_charged": "Arrow of Wind Charging",
"item.minecraft.tnt_minecart": "Minecart with TNT", "item.minecraft.tnt_minecart": "Minecart with TNT",
"item.minecraft.torchflower_seeds": "Torchflower Seeds", "item.minecraft.torchflower_seeds": "Torchflower Seeds",
"item.minecraft.totem_of_undying": "Totem of Undying", "item.minecraft.totem_of_undying": "Totem of Undying",
@ -4276,6 +4424,7 @@
"item.minecraft.tropical_fish_bucket": "Bucket of Tropical Fish", "item.minecraft.tropical_fish_bucket": "Bucket of Tropical Fish",
"item.minecraft.tropical_fish_spawn_egg": "Tropical Fish Spawn Egg", "item.minecraft.tropical_fish_spawn_egg": "Tropical Fish Spawn Egg",
"item.minecraft.turtle_helmet": "Turtle Shell", "item.minecraft.turtle_helmet": "Turtle Shell",
"item.minecraft.turtle_scute": "Turtle Scute",
"item.minecraft.turtle_spawn_egg": "Turtle Spawn Egg", "item.minecraft.turtle_spawn_egg": "Turtle Spawn Egg",
"item.minecraft.vex_armor_trim_smithing_template": "Smithing Template", "item.minecraft.vex_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.vex_spawn_egg": "Vex Spawn Egg", "item.minecraft.vex_spawn_egg": "Vex Spawn Egg",
@ -4291,9 +4440,11 @@
"item.minecraft.wheat_seeds": "Wheat Seeds", "item.minecraft.wheat_seeds": "Wheat Seeds",
"item.minecraft.white_dye": "White Dye", "item.minecraft.white_dye": "White Dye",
"item.minecraft.wild_armor_trim_smithing_template": "Smithing Template", "item.minecraft.wild_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.wind_charge": "Wind Charge",
"item.minecraft.witch_spawn_egg": "Witch Spawn Egg", "item.minecraft.witch_spawn_egg": "Witch Spawn Egg",
"item.minecraft.wither_skeleton_spawn_egg": "Wither Skeleton Spawn Egg", "item.minecraft.wither_skeleton_spawn_egg": "Wither Skeleton Spawn Egg",
"item.minecraft.wither_spawn_egg": "Wither Spawn Egg", "item.minecraft.wither_spawn_egg": "Wither Spawn Egg",
"item.minecraft.wolf_armor": "Wolf Armor",
"item.minecraft.wolf_spawn_egg": "Wolf Spawn Egg", "item.minecraft.wolf_spawn_egg": "Wolf Spawn Egg",
"item.minecraft.wooden_axe": "Wooden Axe", "item.minecraft.wooden_axe": "Wooden Axe",
"item.minecraft.wooden_hoe": "Wooden Hoe", "item.minecraft.wooden_hoe": "Wooden Hoe",
@ -4308,6 +4459,7 @@
"item.minecraft.zombie_spawn_egg": "Zombie Spawn Egg", "item.minecraft.zombie_spawn_egg": "Zombie Spawn Egg",
"item.minecraft.zombie_villager_spawn_egg": "Zombie Villager Spawn Egg", "item.minecraft.zombie_villager_spawn_egg": "Zombie Villager Spawn Egg",
"item.minecraft.zombified_piglin_spawn_egg": "Zombified Piglin Spawn Egg", "item.minecraft.zombified_piglin_spawn_egg": "Zombified Piglin Spawn Egg",
"item.modifiers.body": "When equipped:",
"item.modifiers.chest": "When on Body:", "item.modifiers.chest": "When on Body:",
"item.modifiers.feet": "When on Feet:", "item.modifiers.feet": "When on Feet:",
"item.modifiers.head": "When on Head:", "item.modifiers.head": "When on Head:",
@ -4516,6 +4668,7 @@
"mco.backup.entry.worldType": "World Type", "mco.backup.entry.worldType": "World Type",
"mco.backup.generate.world": "Generate world", "mco.backup.generate.world": "Generate world",
"mco.backup.info.title": "Changes From Last Backup", "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.nobackups": "This realm doesn't have any backups currently.",
"mco.backup.restoring": "Restoring your realm", "mco.backup.restoring": "Restoring your realm",
"mco.backup.unknown": "UNKNOWN", "mco.backup.unknown": "UNKNOWN",
@ -4533,6 +4686,8 @@
"mco.client.incompatible.msg.line2": "Please use the most recent version of Minecraft.", "mco.client.incompatible.msg.line2": "Please use the most recent version of Minecraft.",
"mco.client.incompatible.msg.line3": "Realms is not compatible with snapshot versions.", "mco.client.incompatible.msg.line3": "Realms is not compatible with snapshot versions.",
"mco.client.incompatible.title": "Client incompatible!", "mco.client.incompatible.title": "Client incompatible!",
"mco.client.outdated.stable.version": "Your client version (%s) is not compatible with Realms.\n\nPlease use the most recent version of Minecraft.",
"mco.client.unsupported.snapshot.version": "Your client version (%s) is not compatible with Realms.\n\nRealms is not available for this snapshot version.",
"mco.compatibility.downgrade": "Downgrade", "mco.compatibility.downgrade": "Downgrade",
"mco.compatibility.downgrade.description": "This world was last played in version %s; you are on version %s. Downgrading a world could cause corruption - we cannot guarantee that it will load or work.\n\nA backup of your world will be saved under \"World backups\". Please restore your world if needed.", "mco.compatibility.downgrade.description": "This world was last played in version %s; you are on version %s. Downgrading a world could cause corruption - we cannot guarantee that it will load or work.\n\nA backup of your world will be saved under \"World backups\". Please restore your world if needed.",
"mco.compatibility.unverifiable.message": "The version this world was last played in could not be verified. If the world gets upgraded or downgraded, a backup will be automatically created and saved under \"World backups\".", "mco.compatibility.unverifiable.message": "The version this world was last played in could not be verified. If the world gets upgraded or downgraded, a backup will be automatically created and saved under \"World backups\".",
@ -4556,7 +4711,7 @@
"mco.configure.world.buttons.resetworld": "Reset World", "mco.configure.world.buttons.resetworld": "Reset World",
"mco.configure.world.buttons.settings": "Settings", "mco.configure.world.buttons.settings": "Settings",
"mco.configure.world.buttons.subscription": "Subscription", "mco.configure.world.buttons.subscription": "Subscription",
"mco.configure.world.buttons.switchminigame": "Switch minigame", "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.close.question.line2": "Are you sure you want to continue?",
"mco.configure.world.closing": "Closing the realm...", "mco.configure.world.closing": "Closing the realm...",
@ -4574,7 +4729,7 @@
"mco.configure.world.invite.profile.name": "Name", "mco.configure.world.invite.profile.name": "Name",
"mco.configure.world.invited": "Invited", "mco.configure.world.invited": "Invited",
"mco.configure.world.invited.number": "Invited (%s)", "mco.configure.world.invited.number": "Invited (%s)",
"mco.configure.world.invites.normal.tooltip": "Normal user", "mco.configure.world.invites.normal.tooltip": "Normal User",
"mco.configure.world.invites.ops.tooltip": "Operator", "mco.configure.world.invites.ops.tooltip": "Operator",
"mco.configure.world.invites.remove.tooltip": "Remove", "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",
@ -4679,26 +4834,27 @@
"mco.gui.button": "Button", "mco.gui.button": "Button",
"mco.gui.ok": "Ok", "mco.gui.ok": "Ok",
"mco.info": "Info!", "mco.info": "Info!",
"mco.invited.player.narration": "Invited player %s",
"mco.invites.button.accept": "Accept", "mco.invites.button.accept": "Accept",
"mco.invites.button.reject": "Reject", "mco.invites.button.reject": "Reject",
"mco.invites.nopending": "No pending invites!", "mco.invites.nopending": "No pending invites!",
"mco.invites.pending": "New invite(s)!", "mco.invites.pending": "New invite(s)!",
"mco.invites.title": "Pending Invites", "mco.invites.title": "Pending Invites",
"mco.minigame.world.changeButton": "Select another minigame", "mco.minigame.world.changeButton": "Select Another Minigame",
"mco.minigame.world.info.line1": "This will temporarily replace your world with a minigame!", "mco.minigame.world.info.line1": "This will temporarily replace your world with a minigame!",
"mco.minigame.world.info.line2": "You can later return to your original world without losing anything.", "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.noSelection": "Please make a selection",
"mco.minigame.world.restore": "Ending minigame...", "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.restore.question.line2": "Are you sure you want to continue?",
"mco.minigame.world.selected": "Selected minigame:", "mco.minigame.world.selected": "Selected Minigame:",
"mco.minigame.world.slot.screen.title": "Switching world...", "mco.minigame.world.slot.screen.title": "Switching World...",
"mco.minigame.world.startButton": "Switch", "mco.minigame.world.startButton": "Switch",
"mco.minigame.world.starting.screen.title": "Starting minigame...", "mco.minigame.world.starting.screen.title": "Starting Minigame...",
"mco.minigame.world.stopButton": "End minigame", "mco.minigame.world.stopButton": "End Minigame",
"mco.minigame.world.switch.new": "Select another minigame?", "mco.minigame.world.switch.new": "Select another minigame?",
"mco.minigame.world.switch.title": "Switch minigame", "mco.minigame.world.switch.title": "Switch Minigame",
"mco.minigame.world.title": "Switch realm to minigame", "mco.minigame.world.title": "Switch Realm to Minigame",
"mco.news": "Realms news", "mco.news": "Realms news",
"mco.notification.dismiss": "Dismiss", "mco.notification.dismiss": "Dismiss",
"mco.notification.transferSubscription.buttonText": "Transfer Now", "mco.notification.transferSubscription.buttonText": "Transfer Now",
@ -4792,6 +4948,7 @@
"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.done": "Upload done",
"mco.upload.entry.cheats": "%1$s, %2$s", "mco.upload.entry.cheats": "%1$s, %2$s",
"mco.upload.entry.commands": "%1$s, %2$s",
"mco.upload.entry.id": "%1$s (%2$s)", "mco.upload.entry.id": "%1$s (%2$s)",
"mco.upload.failed": "Upload failed! (%s)", "mco.upload.failed": "Upload failed! (%s)",
"mco.upload.hardcore": "Hardcore worlds can't be uploaded!", "mco.upload.hardcore": "Hardcore worlds can't be uploaded!",
@ -4882,6 +5039,7 @@
"multiplayer.disconnect.server_shutdown": "Server closed", "multiplayer.disconnect.server_shutdown": "Server closed",
"multiplayer.disconnect.slow_login": "Took too long to log in", "multiplayer.disconnect.slow_login": "Took too long to log in",
"multiplayer.disconnect.too_many_pending_chats": "Too many unacknowledged chat messages", "multiplayer.disconnect.too_many_pending_chats": "Too many unacknowledged chat messages",
"multiplayer.disconnect.transfers_disabled": "Server does not accept transfers",
"multiplayer.disconnect.unexpected_query_response": "Unexpected custom data from client", "multiplayer.disconnect.unexpected_query_response": "Unexpected custom data from client",
"multiplayer.disconnect.unsigned_chat": "Received chat packet with missing or invalid signature.", "multiplayer.disconnect.unsigned_chat": "Received chat packet with missing or invalid signature.",
"multiplayer.disconnect.unverified_username": "Failed to verify username!", "multiplayer.disconnect.unverified_username": "Failed to verify username!",
@ -4986,13 +5144,21 @@
"optimizeWorld.stage.counting": "Counting chunks...", "optimizeWorld.stage.counting": "Counting chunks...",
"optimizeWorld.stage.failed": "Failed! :(", "optimizeWorld.stage.failed": "Failed! :(",
"optimizeWorld.stage.finished": "Finishing up...", "optimizeWorld.stage.finished": "Finishing up...",
"optimizeWorld.stage.finished.chunks": "Finishing up upgrading chunks...",
"optimizeWorld.stage.finished.entities": "Finishing up upgrading entities...",
"optimizeWorld.stage.finished.poi": "Finishing up upgrading points of interest...",
"optimizeWorld.stage.upgrading": "Upgrading all chunks...", "optimizeWorld.stage.upgrading": "Upgrading all chunks...",
"optimizeWorld.stage.upgrading.chunks": "Upgrading all chunks...",
"optimizeWorld.stage.upgrading.entities": "Upgrading all entities...",
"optimizeWorld.stage.upgrading.poi": "Upgrading all points of interest...",
"optimizeWorld.title": "Optimizing World '%s'", "optimizeWorld.title": "Optimizing World '%s'",
"options.accessibility": "Accessibility Settings...", "options.accessibility": "Accessibility Settings...",
"options.accessibility.high_contrast": "High Contrast", "options.accessibility.high_contrast": "High Contrast",
"options.accessibility.high_contrast.error.tooltip": "High Contrast resource pack is not available", "options.accessibility.high_contrast.error.tooltip": "High Contrast resource pack is not available",
"options.accessibility.high_contrast.tooltip": "Enhances the contrast of UI elements", "options.accessibility.high_contrast.tooltip": "Enhances the contrast of UI elements",
"options.accessibility.link": "Accessibility Guide", "options.accessibility.link": "Accessibility Guide",
"options.accessibility.menu_background_blurriness": "Menu Background Blur",
"options.accessibility.menu_background_blurriness.tooltip": "Changes the blurriness of menu backgrounds",
"options.accessibility.narrator_hotkey": "Narrator Hotkey", "options.accessibility.narrator_hotkey": "Narrator Hotkey",
"options.accessibility.narrator_hotkey.mac.tooltip": "Allows the Narrator to be toggled on and off with 'Cmd+B'", "options.accessibility.narrator_hotkey.mac.tooltip": "Allows the Narrator to be toggled on and off with 'Cmd+B'",
"options.accessibility.narrator_hotkey.tooltip": "Allows the Narrator to be toggled on and off with 'Ctrl+B'", "options.accessibility.narrator_hotkey.tooltip": "Allows the Narrator to be toggled on and off with 'Ctrl+B'",
@ -5071,6 +5237,8 @@
"options.discrete_mouse_scroll": "Discrete Scrolling", "options.discrete_mouse_scroll": "Discrete Scrolling",
"options.entityDistanceScaling": "Entity Distance", "options.entityDistanceScaling": "Entity Distance",
"options.entityShadows": "Entity Shadows", "options.entityShadows": "Entity Shadows",
"options.font": "Font Settings...",
"options.font.title": "Font Settings",
"options.forceUnicodeFont": "Force Unicode Font", "options.forceUnicodeFont": "Force Unicode Font",
"options.fov": "FOV", "options.fov": "FOV",
"options.fov.max": "Quake Pro", "options.fov.max": "Quake Pro",
@ -5118,6 +5286,8 @@
"options.hideSplashTexts": "Hide Splash Texts", "options.hideSplashTexts": "Hide Splash Texts",
"options.hideSplashTexts.tooltip": "Hides the yellow splash text in the main menu.", "options.hideSplashTexts.tooltip": "Hides the yellow splash text in the main menu.",
"options.invertMouse": "Invert Mouse", "options.invertMouse": "Invert Mouse",
"options.japaneseGlyphVariants": "Japanese Glyph Variants",
"options.japaneseGlyphVariants.tooltip": "Uses Japanese variants of CJK characters in the default font",
"options.key.hold": "Hold", "options.key.hold": "Hold",
"options.key.toggle": "Toggle", "options.key.toggle": "Toggle",
"options.language": "Language...", "options.language": "Language...",
@ -5191,6 +5361,7 @@
"options.telemetry": "Telemetry Data...", "options.telemetry": "Telemetry Data...",
"options.telemetry.button": "Data Collection", "options.telemetry.button": "Data Collection",
"options.telemetry.button.tooltip": "\"%s\" includes only the required data.\n\"%s\" includes optional, as well as the required data.", "options.telemetry.button.tooltip": "\"%s\" includes only the required data.\n\"%s\" includes optional, as well as the required data.",
"options.telemetry.disabled": "Telemetry is disabled.",
"options.telemetry.state.all": "All", "options.telemetry.state.all": "All",
"options.telemetry.state.minimal": "Minimal", "options.telemetry.state.minimal": "Minimal",
"options.telemetry.state.none": "None", "options.telemetry.state.none": "None",
@ -5300,6 +5471,7 @@
"parsing.quote.escape": "Invalid escape sequence '\\%s' in quoted string", "parsing.quote.escape": "Invalid escape sequence '\\%s' in quoted string",
"parsing.quote.expected.end": "Unclosed quoted string", "parsing.quote.expected.end": "Unclosed quoted string",
"parsing.quote.expected.start": "Expected quote to start a string", "parsing.quote.expected.start": "Expected quote to start a string",
"particle.invalidOptions": "Can't parse particle options: %s",
"particle.notFound": "Unknown particle: %s", "particle.notFound": "Unknown particle: %s",
"permissions.requires.entity": "An entity is required to run this command here", "permissions.requires.entity": "An entity is required to run this command here",
"permissions.requires.player": "A player is required to run this command here", "permissions.requires.player": "A player is required to run this command here",
@ -5366,6 +5538,7 @@
"selectWorld.access_failure": "Failed to access world", "selectWorld.access_failure": "Failed to access world",
"selectWorld.allowCommands": "Allow Cheats", "selectWorld.allowCommands": "Allow Cheats",
"selectWorld.allowCommands.info": "Commands like /gamemode, /experience", "selectWorld.allowCommands.info": "Commands like /gamemode, /experience",
"selectWorld.allowCommands.new": "Allow Commands",
"selectWorld.backupEraseCache": "Erase Cached Data", "selectWorld.backupEraseCache": "Erase Cached Data",
"selectWorld.backupJoinConfirmButton": "Create Backup and Load", "selectWorld.backupJoinConfirmButton": "Create Backup and Load",
"selectWorld.backupJoinSkipButton": "I know what I'm doing!", "selectWorld.backupJoinSkipButton": "I know what I'm doing!",
@ -5379,6 +5552,7 @@
"selectWorld.backupWarning.snapshot": "This world was last played in version %s; you are on version %s. Please make a backup in case you experience world corruptions.", "selectWorld.backupWarning.snapshot": "This world was last played in version %s; you are on version %s. Please make a backup in case you experience world corruptions.",
"selectWorld.bonusItems": "Bonus Chest", "selectWorld.bonusItems": "Bonus Chest",
"selectWorld.cheats": "Cheats", "selectWorld.cheats": "Cheats",
"selectWorld.commands": "Commands",
"selectWorld.conversion": "Must be converted!", "selectWorld.conversion": "Must be converted!",
"selectWorld.conversion.tooltip": "This world must be opened in an older version (like 1.6.4) to be safely converted", "selectWorld.conversion.tooltip": "This world must be opened in an older version (like 1.6.4) to be safely converted",
"selectWorld.create": "Create New World", "selectWorld.create": "Create New World",
@ -5482,11 +5656,14 @@
"selectWorld.warning.deprecated.title": "Warning! These settings are using deprecated features", "selectWorld.warning.deprecated.title": "Warning! These settings are using deprecated features",
"selectWorld.warning.experimental.question": "These settings are experimental and could one day stop working. Do you wish to proceed?", "selectWorld.warning.experimental.question": "These settings are experimental and could one day stop working. Do you wish to proceed?",
"selectWorld.warning.experimental.title": "Warning! These settings are using experimental features", "selectWorld.warning.experimental.title": "Warning! These settings are using experimental features",
"selectWorld.warning.lowDiskSpace.description": "There is not much space left on your device.\nRunning out of disk space while in game can lead to your world being damaged.",
"selectWorld.warning.lowDiskSpace.title": "Warning! Low disk space!",
"selectWorld.world": "World", "selectWorld.world": "World",
"sign.edit": "Edit Sign Message", "sign.edit": "Edit Sign Message",
"sleep.not_possible": "No amount of rest can pass this night", "sleep.not_possible": "No amount of rest can pass this night",
"sleep.players_sleeping": "%s/%s players sleeping", "sleep.players_sleeping": "%s/%s players sleeping",
"sleep.skipping_night": "Sleeping through this night", "sleep.skipping_night": "Sleeping through this night",
"slot.only_single_allowed": "Only single slots allowed, got '%s'",
"slot.unknown": "Unknown slot '%s'", "slot.unknown": "Unknown slot '%s'",
"soundCategory.ambient": "Ambient/Environment", "soundCategory.ambient": "Ambient/Environment",
"soundCategory.block": "Blocks", "soundCategory.block": "Blocks",
@ -5671,6 +5848,7 @@
"subtitles.block.cake.add_candle": "Cake squishes", "subtitles.block.cake.add_candle": "Cake squishes",
"subtitles.block.campfire.crackle": "Campfire crackles", "subtitles.block.campfire.crackle": "Campfire crackles",
"subtitles.block.candle.crackle": "Candle crackles", "subtitles.block.candle.crackle": "Candle crackles",
"subtitles.block.candle.extinguish": "Candle extinguishes",
"subtitles.block.chest.close": "Chest closes", "subtitles.block.chest.close": "Chest closes",
"subtitles.block.chest.locked": "Chest locked", "subtitles.block.chest.locked": "Chest locked",
"subtitles.block.chest.open": "Chest opens", "subtitles.block.chest.open": "Chest opens",
@ -5730,7 +5908,7 @@
"subtitles.block.pressure_plate.click": "Pressure Plate clicks", "subtitles.block.pressure_plate.click": "Pressure Plate clicks",
"subtitles.block.pumpkin.carve": "Shears carve", "subtitles.block.pumpkin.carve": "Shears carve",
"subtitles.block.redstone_torch.burnout": "Torch fizzes", "subtitles.block.redstone_torch.burnout": "Torch fizzes",
"subtitles.block.respawn_anchor.ambient": "Portal whooshes", "subtitles.block.respawn_anchor.ambient": "Respawn Anchor whooshes",
"subtitles.block.respawn_anchor.charge": "Respawn Anchor is charged", "subtitles.block.respawn_anchor.charge": "Respawn Anchor is charged",
"subtitles.block.respawn_anchor.deplete": "Respawn Anchor depletes", "subtitles.block.respawn_anchor.deplete": "Respawn Anchor depletes",
"subtitles.block.respawn_anchor.set_spawn": "Respawn Anchor sets spawn", "subtitles.block.respawn_anchor.set_spawn": "Respawn Anchor sets spawn",
@ -5751,16 +5929,30 @@
"subtitles.block.sponge.absorb": "Sponge sucks", "subtitles.block.sponge.absorb": "Sponge sucks",
"subtitles.block.sweet_berry_bush.pick_berries": "Berries pop", "subtitles.block.sweet_berry_bush.pick_berries": "Berries pop",
"subtitles.block.trapdoor.toggle": "Trapdoor creaks", "subtitles.block.trapdoor.toggle": "Trapdoor creaks",
"subtitles.block.trial_spawner.about_to_spawn_item": "Ominous item prepares",
"subtitles.block.trial_spawner.ambient": "Trial Spawner crackles", "subtitles.block.trial_spawner.ambient": "Trial Spawner crackles",
"subtitles.block.trial_spawner.ambient_charged": "Ominous Trial Spawner crackles",
"subtitles.block.trial_spawner.charge_activate": "Omen engulfs Trial Spawner",
"subtitles.block.trial_spawner.close_shutter": "Trial Spawner closes", "subtitles.block.trial_spawner.close_shutter": "Trial Spawner closes",
"subtitles.block.trial_spawner.detect_player": "Trial Spawner charges up", "subtitles.block.trial_spawner.detect_player": "Trial Spawner charges up",
"subtitles.block.trial_spawner.eject_item": "Trial Spawner ejects items", "subtitles.block.trial_spawner.eject_item": "Trial Spawner ejects items",
"subtitles.block.trial_spawner.open_shutter": "Trial Spawner opens", "subtitles.block.trial_spawner.open_shutter": "Trial Spawner opens",
"subtitles.block.trial_spawner.spawn_mob": "Mob spawns", "subtitles.block.trial_spawner.spawn_item": "Ominous item drops",
"subtitles.block.trial_spawner.spawn_item_begin": "Ominous item appears",
"subtitles.block.trial_spawner.spawn_mob": "Trial Spawner spawns a mob",
"subtitles.block.tripwire.attach": "Tripwire attaches", "subtitles.block.tripwire.attach": "Tripwire attaches",
"subtitles.block.tripwire.click": "Tripwire clicks", "subtitles.block.tripwire.click": "Tripwire clicks",
"subtitles.block.tripwire.detach": "Tripwire detaches", "subtitles.block.tripwire.detach": "Tripwire detaches",
"subtitles.block.vault.activate": "Vault ignites",
"subtitles.block.vault.ambient": "Vault crackles",
"subtitles.block.vault.close_shutter": "Vault closes",
"subtitles.block.vault.deactivate": "Vault extinguishes",
"subtitles.block.vault.eject_item": "Vault ejects item",
"subtitles.block.vault.insert_item": "Vault unlocks",
"subtitles.block.vault.insert_item_fail": "Vault fails unlocking",
"subtitles.block.vault.open_shutter": "Vault opens",
"subtitles.block.water.ambient": "Water flows", "subtitles.block.water.ambient": "Water flows",
"subtitles.block.wet_sponge.dries": "Sponge dries",
"subtitles.chiseled_bookshelf.insert": "Book placed", "subtitles.chiseled_bookshelf.insert": "Book placed",
"subtitles.chiseled_bookshelf.insert_enchanted": "Enchanted Book placed", "subtitles.chiseled_bookshelf.insert_enchanted": "Enchanted Book placed",
"subtitles.chiseled_bookshelf.take": "Book taken", "subtitles.chiseled_bookshelf.take": "Book taken",
@ -5773,6 +5965,18 @@
"subtitles.entity.allay.item_given": "Allay chortles", "subtitles.entity.allay.item_given": "Allay chortles",
"subtitles.entity.allay.item_taken": "Allay allays", "subtitles.entity.allay.item_taken": "Allay allays",
"subtitles.entity.allay.item_thrown": "Allay tosses", "subtitles.entity.allay.item_thrown": "Allay tosses",
"subtitles.entity.armadillo.ambient": "Armadillo grunts",
"subtitles.entity.armadillo.brush": "Scute is brushed off",
"subtitles.entity.armadillo.death": "Armadillo dies",
"subtitles.entity.armadillo.eat": "Armadillo eats",
"subtitles.entity.armadillo.hurt": "Armadillo hurts",
"subtitles.entity.armadillo.hurt_reduced": "Armadillo shields itself",
"subtitles.entity.armadillo.land": "Armadillo lands",
"subtitles.entity.armadillo.peek": "Armadillo peeks",
"subtitles.entity.armadillo.roll": "Armadillo rolls up",
"subtitles.entity.armadillo.scute_drop": "Armadillo sheds scute",
"subtitles.entity.armadillo.unroll_finish": "Armadillo unrolls",
"subtitles.entity.armadillo.unroll_start": "Armadillo peeks",
"subtitles.entity.armor_stand.fall": "Something fell", "subtitles.entity.armor_stand.fall": "Something fell",
"subtitles.entity.arrow.hit": "Arrow hits", "subtitles.entity.arrow.hit": "Arrow hits",
"subtitles.entity.arrow.hit_player": "Player hit", "subtitles.entity.arrow.hit_player": "Player hit",
@ -5802,7 +6006,12 @@
"subtitles.entity.blaze.shoot": "Blaze shoots", "subtitles.entity.blaze.shoot": "Blaze shoots",
"subtitles.entity.boat.paddle_land": "Rowing", "subtitles.entity.boat.paddle_land": "Rowing",
"subtitles.entity.boat.paddle_water": "Rowing", "subtitles.entity.boat.paddle_water": "Rowing",
"subtitles.entity.bogged.ambient": "Bogged rattles",
"subtitles.entity.bogged.death": "Bogged dies",
"subtitles.entity.bogged.hurt": "Bogged hurts",
"subtitles.entity.breeze.charge": "Breeze charges",
"subtitles.entity.breeze.death": "Breeze dies", "subtitles.entity.breeze.death": "Breeze dies",
"subtitles.entity.breeze.deflect": "Breeze deflects",
"subtitles.entity.breeze.hurt": "Breeze hurts", "subtitles.entity.breeze.hurt": "Breeze hurts",
"subtitles.entity.breeze.idle_air": "Breeze flies", "subtitles.entity.breeze.idle_air": "Breeze flies",
"subtitles.entity.breeze.idle_ground": "Breeze whirs", "subtitles.entity.breeze.idle_ground": "Breeze whirs",
@ -5811,6 +6020,8 @@
"subtitles.entity.breeze.land": "Breeze lands", "subtitles.entity.breeze.land": "Breeze lands",
"subtitles.entity.breeze.shoot": "Breeze shoots", "subtitles.entity.breeze.shoot": "Breeze shoots",
"subtitles.entity.breeze.slide": "Breeze slides", "subtitles.entity.breeze.slide": "Breeze slides",
"subtitles.entity.breeze.whirl": "Breeze whirls",
"subtitles.entity.breeze.wind_burst": "Wind Charge bursts",
"subtitles.entity.camel.ambient": "Camel grunts", "subtitles.entity.camel.ambient": "Camel grunts",
"subtitles.entity.camel.dash": "Camel yeets", "subtitles.entity.camel.dash": "Camel yeets",
"subtitles.entity.camel.dash_ready": "Camel recovers", "subtitles.entity.camel.dash_ready": "Camel recovers",
@ -5859,6 +6070,7 @@
"subtitles.entity.donkey.death": "Donkey dies", "subtitles.entity.donkey.death": "Donkey dies",
"subtitles.entity.donkey.eat": "Donkey eats", "subtitles.entity.donkey.eat": "Donkey eats",
"subtitles.entity.donkey.hurt": "Donkey hurts", "subtitles.entity.donkey.hurt": "Donkey hurts",
"subtitles.entity.donkey.jump": "Donkey jumps",
"subtitles.entity.drowned.ambient": "Drowned gurgles", "subtitles.entity.drowned.ambient": "Drowned gurgles",
"subtitles.entity.drowned.ambient_water": "Drowned gurgles", "subtitles.entity.drowned.ambient_water": "Drowned gurgles",
"subtitles.entity.drowned.death": "Drowned dies", "subtitles.entity.drowned.death": "Drowned dies",
@ -5941,7 +6153,7 @@
"subtitles.entity.ghast.hurt": "Ghast hurts", "subtitles.entity.ghast.hurt": "Ghast hurts",
"subtitles.entity.ghast.shoot": "Ghast shoots", "subtitles.entity.ghast.shoot": "Ghast shoots",
"subtitles.entity.glow_item_frame.add_item": "Glow Item Frame fills", "subtitles.entity.glow_item_frame.add_item": "Glow Item Frame fills",
"subtitles.entity.glow_item_frame.break": "Glow Item Frame breaks", "subtitles.entity.glow_item_frame.break": "Glow Item Frame broken",
"subtitles.entity.glow_item_frame.place": "Glow Item Frame placed", "subtitles.entity.glow_item_frame.place": "Glow Item Frame placed",
"subtitles.entity.glow_item_frame.remove_item": "Glow Item Frame empties", "subtitles.entity.glow_item_frame.remove_item": "Glow Item Frame empties",
"subtitles.entity.glow_item_frame.rotate_item": "Glow Item Frame clicks", "subtitles.entity.glow_item_frame.rotate_item": "Glow Item Frame clicks",
@ -6001,13 +6213,13 @@
"subtitles.entity.iron_golem.hurt": "Iron Golem hurts", "subtitles.entity.iron_golem.hurt": "Iron Golem hurts",
"subtitles.entity.iron_golem.repair": "Iron Golem repaired", "subtitles.entity.iron_golem.repair": "Iron Golem repaired",
"subtitles.entity.item_frame.add_item": "Item Frame fills", "subtitles.entity.item_frame.add_item": "Item Frame fills",
"subtitles.entity.item_frame.break": "Item Frame breaks", "subtitles.entity.item_frame.break": "Item Frame broken",
"subtitles.entity.item_frame.place": "Item Frame placed", "subtitles.entity.item_frame.place": "Item Frame placed",
"subtitles.entity.item_frame.remove_item": "Item Frame empties", "subtitles.entity.item_frame.remove_item": "Item Frame empties",
"subtitles.entity.item_frame.rotate_item": "Item Frame clicks", "subtitles.entity.item_frame.rotate_item": "Item Frame clicks",
"subtitles.entity.item.break": "Item breaks", "subtitles.entity.item.break": "Item breaks",
"subtitles.entity.item.pickup": "Item plops", "subtitles.entity.item.pickup": "Item plops",
"subtitles.entity.leash_knot.break": "Leash Knot breaks", "subtitles.entity.leash_knot.break": "Leash Knot broken",
"subtitles.entity.leash_knot.place": "Leash Knot tied", "subtitles.entity.leash_knot.place": "Leash Knot tied",
"subtitles.entity.lightning_bolt.impact": "Lightning strikes", "subtitles.entity.lightning_bolt.impact": "Lightning strikes",
"subtitles.entity.lightning_bolt.thunder": "Thunder roars", "subtitles.entity.lightning_bolt.thunder": "Thunder roars",
@ -6034,7 +6246,8 @@
"subtitles.entity.mule.death": "Mule dies", "subtitles.entity.mule.death": "Mule dies",
"subtitles.entity.mule.eat": "Mule eats", "subtitles.entity.mule.eat": "Mule eats",
"subtitles.entity.mule.hurt": "Mule hurts", "subtitles.entity.mule.hurt": "Mule hurts",
"subtitles.entity.painting.break": "Painting breaks", "subtitles.entity.mule.jump": "Mule jumps",
"subtitles.entity.painting.break": "Painting broken",
"subtitles.entity.painting.place": "Painting placed", "subtitles.entity.painting.place": "Painting placed",
"subtitles.entity.panda.aggressive_ambient": "Panda huffs", "subtitles.entity.panda.aggressive_ambient": "Panda huffs",
"subtitles.entity.panda.ambient": "Panda pants", "subtitles.entity.panda.ambient": "Panda pants",
@ -6053,6 +6266,7 @@
"subtitles.entity.parrot.fly": "Parrot flutters", "subtitles.entity.parrot.fly": "Parrot flutters",
"subtitles.entity.parrot.hurts": "Parrot hurts", "subtitles.entity.parrot.hurts": "Parrot hurts",
"subtitles.entity.parrot.imitate.blaze": "Parrot breathes", "subtitles.entity.parrot.imitate.blaze": "Parrot breathes",
"subtitles.entity.parrot.imitate.bogged": "Parrot rattles",
"subtitles.entity.parrot.imitate.breeze": "Parrot whirs", "subtitles.entity.parrot.imitate.breeze": "Parrot whirs",
"subtitles.entity.parrot.imitate.creeper": "Parrot hisses", "subtitles.entity.parrot.imitate.creeper": "Parrot hisses",
"subtitles.entity.parrot.imitate.drowned": "Parrot gurgles", "subtitles.entity.parrot.imitate.drowned": "Parrot gurgles",
@ -6130,7 +6344,7 @@
"subtitles.entity.player.levelup": "Player dings", "subtitles.entity.player.levelup": "Player dings",
"subtitles.entity.player.teleport": "Player teleports", "subtitles.entity.player.teleport": "Player teleports",
"subtitles.entity.polar_bear.ambient": "Polar Bear groans", "subtitles.entity.polar_bear.ambient": "Polar Bear groans",
"subtitles.entity.polar_bear.ambient_baby": "Polar Bear hums", "subtitles.entity.polar_bear.ambient_baby": "Baby Polar Bear hums",
"subtitles.entity.polar_bear.death": "Polar Bear dies", "subtitles.entity.polar_bear.death": "Polar Bear dies",
"subtitles.entity.polar_bear.hurt": "Polar Bear hurts", "subtitles.entity.polar_bear.hurt": "Polar Bear hurts",
"subtitles.entity.polar_bear.warning": "Polar Bear roars", "subtitles.entity.polar_bear.warning": "Polar Bear roars",
@ -6229,15 +6443,15 @@
"subtitles.entity.tropical_fish.hurt": "Tropical Fish hurts", "subtitles.entity.tropical_fish.hurt": "Tropical Fish hurts",
"subtitles.entity.turtle.ambient_land": "Turtle chirps", "subtitles.entity.turtle.ambient_land": "Turtle chirps",
"subtitles.entity.turtle.death": "Turtle dies", "subtitles.entity.turtle.death": "Turtle dies",
"subtitles.entity.turtle.death_baby": "Turtle baby dies", "subtitles.entity.turtle.death_baby": "Baby Turtle dies",
"subtitles.entity.turtle.egg_break": "Turtle Egg breaks", "subtitles.entity.turtle.egg_break": "Turtle Egg breaks",
"subtitles.entity.turtle.egg_crack": "Turtle Egg cracks", "subtitles.entity.turtle.egg_crack": "Turtle Egg cracks",
"subtitles.entity.turtle.egg_hatch": "Turtle Egg hatches", "subtitles.entity.turtle.egg_hatch": "Turtle Egg hatches",
"subtitles.entity.turtle.hurt": "Turtle hurts", "subtitles.entity.turtle.hurt": "Turtle hurts",
"subtitles.entity.turtle.hurt_baby": "Turtle baby hurts", "subtitles.entity.turtle.hurt_baby": "Baby Turtle hurts",
"subtitles.entity.turtle.lay_egg": "Turtle lays egg", "subtitles.entity.turtle.lay_egg": "Turtle lays egg",
"subtitles.entity.turtle.shamble": "Turtle shambles", "subtitles.entity.turtle.shamble": "Turtle shambles",
"subtitles.entity.turtle.shamble_baby": "Turtle baby shambles", "subtitles.entity.turtle.shamble_baby": "Baby Turtle shambles",
"subtitles.entity.turtle.swim": "Turtle swims", "subtitles.entity.turtle.swim": "Turtle swims",
"subtitles.entity.vex.ambient": "Vex vexes", "subtitles.entity.vex.ambient": "Vex vexes",
"subtitles.entity.vex.charge": "Vex shrieks", "subtitles.entity.vex.charge": "Vex shrieks",
@ -6297,6 +6511,8 @@
"subtitles.entity.warden.sonic_charge": "Warden charges", "subtitles.entity.warden.sonic_charge": "Warden charges",
"subtitles.entity.warden.step": "Warden steps", "subtitles.entity.warden.step": "Warden steps",
"subtitles.entity.warden.tendril_clicks": "Warden's tendrils click", "subtitles.entity.warden.tendril_clicks": "Warden's tendrils click",
"subtitles.entity.wind_charge.throw": "Wind Charge flies",
"subtitles.entity.wind_charge.wind_burst": "Wind Charge bursts",
"subtitles.entity.witch.ambient": "Witch giggles", "subtitles.entity.witch.ambient": "Witch giggles",
"subtitles.entity.witch.celebrate": "Witch cheers", "subtitles.entity.witch.celebrate": "Witch cheers",
"subtitles.entity.witch.death": "Witch dies", "subtitles.entity.witch.death": "Witch dies",
@ -6342,6 +6558,9 @@
"subtitles.entity.zombified_piglin.angry": "Zombified Piglin grunts angrily", "subtitles.entity.zombified_piglin.angry": "Zombified Piglin grunts angrily",
"subtitles.entity.zombified_piglin.death": "Zombified Piglin dies", "subtitles.entity.zombified_piglin.death": "Zombified Piglin dies",
"subtitles.entity.zombified_piglin.hurt": "Zombified Piglin hurts", "subtitles.entity.zombified_piglin.hurt": "Zombified Piglin hurts",
"subtitles.event.mob_effect.bad_omen": "Omen takes hold",
"subtitles.event.mob_effect.raid_omen": "Raid looms nearby",
"subtitles.event.mob_effect.trial_omen": "Ominous trial looms nearby",
"subtitles.event.raid.horn": "Ominous horn blares", "subtitles.event.raid.horn": "Ominous horn blares",
"subtitles.item.armor.equip": "Gear equips", "subtitles.item.armor.equip": "Gear equips",
"subtitles.item.armor.equip_chain": "Chain armor jingles", "subtitles.item.armor.equip_chain": "Chain armor jingles",
@ -6352,6 +6571,8 @@
"subtitles.item.armor.equip_leather": "Leather armor rustles", "subtitles.item.armor.equip_leather": "Leather armor rustles",
"subtitles.item.armor.equip_netherite": "Netherite armor clanks", "subtitles.item.armor.equip_netherite": "Netherite armor clanks",
"subtitles.item.armor.equip_turtle": "Turtle Shell thunks", "subtitles.item.armor.equip_turtle": "Turtle Shell thunks",
"subtitles.item.armor.equip_wolf": "Wolf Armor is fastened",
"subtitles.item.armor.unequip_wolf": "Wolf Armor snips away",
"subtitles.item.axe.scrape": "Axe scrapes", "subtitles.item.axe.scrape": "Axe scrapes",
"subtitles.item.axe.strip": "Axe strips", "subtitles.item.axe.strip": "Axe strips",
"subtitles.item.axe.wax_off": "Wax off", "subtitles.item.axe.wax_off": "Wax off",
@ -6389,7 +6610,10 @@
"subtitles.item.honeycomb.wax_on": "Wax on", "subtitles.item.honeycomb.wax_on": "Wax on",
"subtitles.item.ink_sac.use": "Ink Sac splotches", "subtitles.item.ink_sac.use": "Ink Sac splotches",
"subtitles.item.lodestone_compass.lock": "Lodestone Compass locks onto Lodestone", "subtitles.item.lodestone_compass.lock": "Lodestone Compass locks onto Lodestone",
"subtitles.item.mace.smash_air": "Mace smashes",
"subtitles.item.mace.smash_ground": "Mace smashes",
"subtitles.item.nether_wart.plant": "Crop planted", "subtitles.item.nether_wart.plant": "Crop planted",
"subtitles.item.ominous_bottle.dispose": "Bottle breaks",
"subtitles.item.shears.shear": "Shears click", "subtitles.item.shears.shear": "Shears click",
"subtitles.item.shield.block": "Shield blocks", "subtitles.item.shield.block": "Shield blocks",
"subtitles.item.shovel.flatten": "Shovel flattens", "subtitles.item.shovel.flatten": "Shovel flattens",
@ -6402,6 +6626,10 @@
"subtitles.item.trident.riptide": "Trident zooms", "subtitles.item.trident.riptide": "Trident zooms",
"subtitles.item.trident.throw": "Trident clangs", "subtitles.item.trident.throw": "Trident clangs",
"subtitles.item.trident.thunder": "Trident thunder cracks", "subtitles.item.trident.thunder": "Trident thunder cracks",
"subtitles.item.wolf_armor.break": "Wolf Armor breaks",
"subtitles.item.wolf_armor.crack": "Wolf Armor cracks",
"subtitles.item.wolf_armor.damage": "Wolf Armor takes damage",
"subtitles.item.wolf_armor.repair": "Wolf Armor is repaired",
"subtitles.particle.soul_escape": "Soul escapes", "subtitles.particle.soul_escape": "Soul escapes",
"subtitles.ui.cartography_table.take_result": "Map drawn", "subtitles.ui.cartography_table.take_result": "Map drawn",
"subtitles.ui.loom.take_result": "Loom used", "subtitles.ui.loom.take_result": "Loom used",
@ -6506,9 +6734,11 @@
"trim_material.minecraft.netherite": "Netherite Material", "trim_material.minecraft.netherite": "Netherite Material",
"trim_material.minecraft.quartz": "Quartz Material", "trim_material.minecraft.quartz": "Quartz Material",
"trim_material.minecraft.redstone": "Redstone Material", "trim_material.minecraft.redstone": "Redstone Material",
"trim_pattern.minecraft.bolt": "Bolt Armor Trim",
"trim_pattern.minecraft.coast": "Coast Armor Trim", "trim_pattern.minecraft.coast": "Coast Armor Trim",
"trim_pattern.minecraft.dune": "Dune Armor Trim", "trim_pattern.minecraft.dune": "Dune Armor Trim",
"trim_pattern.minecraft.eye": "Eye Armor Trim", "trim_pattern.minecraft.eye": "Eye Armor Trim",
"trim_pattern.minecraft.flow": "Flow Armor Trim",
"trim_pattern.minecraft.host": "Host Armor Trim", "trim_pattern.minecraft.host": "Host Armor Trim",
"trim_pattern.minecraft.raiser": "Raiser Armor Trim", "trim_pattern.minecraft.raiser": "Raiser Armor Trim",
"trim_pattern.minecraft.rib": "Rib Armor Trim", "trim_pattern.minecraft.rib": "Rib Armor Trim",

View file

@ -11,8 +11,6 @@ version = "0.9.1"
[dependencies] [dependencies]
azalea-block = { path = "../azalea-block", version = "0.9.0" } azalea-block = { path = "../azalea-block", version = "0.9.0" }
azalea-core = { path = "../azalea-core", version = "0.9.0" } azalea-core = { path = "../azalea-core", version = "0.9.0" }
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-registry = { path = "../azalea-registry", version = "0.9.0" } azalea-registry = { path = "../azalea-registry", version = "0.9.0" }
azalea-world = { path = "../azalea-world", version = "0.9.0" } azalea-world = { path = "../azalea-world", version = "0.9.0" }
bevy_app = "0.13.2" bevy_app = "0.13.2"
@ -22,6 +20,8 @@ once_cell = "1.19.0"
parking_lot = "^0.12.1" parking_lot = "^0.12.1"
nohash-hasher = "0.2.0" nohash-hasher = "0.2.0"
smallvec = "1.13.2" smallvec = "1.13.2"
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
[dev-dependencies] [dev-dependencies]
bevy_time = "0.13.2" bevy_time = "0.13.2"

View file

@ -24,8 +24,6 @@ azalea-core = { path = "../azalea-core", optional = true, version = "0.9.0", fea
"serde", "serde",
] } ] }
azalea-crypto = { path = "../azalea-crypto", version = "0.9.0" } azalea-crypto = { path = "../azalea-crypto", version = "0.9.0" }
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-protocol-macros = { path = "./azalea-protocol-macros", version = "0.9.0" } azalea-protocol-macros = { path = "./azalea-protocol-macros", version = "0.9.0" }
azalea-registry = { path = "../azalea-registry", version = "0.9.0" } azalea-registry = { path = "../azalea-registry", version = "0.9.0" }
azalea-world = { path = "../azalea-world", version = "0.9.0" } azalea-world = { path = "../azalea-world", version = "0.9.0" }
@ -47,7 +45,8 @@ trust-dns-resolver = { version = "^0.23.2", default-features = false, features =
] } ] }
uuid = "1.8.0" uuid = "1.8.0"
log = "0.4.21" log = "0.4.21"
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
socks5-impl = "0.5.12" socks5-impl = "0.5.12"
[features] [features]

View file

@ -12,7 +12,8 @@ fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> Toke
let syn::Data::Struct(syn::DataStruct { fields, .. }) = &data else { let syn::Data::Struct(syn::DataStruct { fields, .. }) = &data else {
panic!("#[derive(*Packet)] can only be used on structs") panic!("#[derive(*Packet)] can only be used on structs")
}; };
let syn::Fields::Named(_) = fields else {
let (syn::Fields::Named(_) | syn::Fields::Unit) = fields else {
panic!("#[derive(*Packet)] can only be used on structs with named fields") panic!("#[derive(*Packet)] can only be used on structs with named fields")
}; };
let variant_name = variant_name_from(&ident); let variant_name = variant_name_from(&ident);

View file

@ -104,12 +104,12 @@ pub struct WriteConnection<W: ProtocolPacket> {
/// let packet = conn.read().await?; /// let packet = conn.read().await?;
/// match packet { /// match packet {
/// ClientboundLoginPacket::Hello(p) => { /// ClientboundLoginPacket::Hello(p) => {
/// let e = azalea_crypto::encrypt(&p.public_key, &p.nonce).unwrap(); /// let e = azalea_crypto::encrypt(&p.public_key, &p.challenge).unwrap();
/// ///
/// conn.write( /// conn.write(
/// ServerboundKeyPacket { /// ServerboundKeyPacket {
/// key_bytes: e.encrypted_public_key, /// key_bytes: e.encrypted_public_key,
/// encrypted_challenge: e.encrypted_nonce, /// encrypted_challenge: e.encrypted_challenge,
/// } /// }
/// .get(), /// .get(),
/// ) /// )
@ -127,6 +127,7 @@ pub struct WriteConnection<W: ProtocolPacket> {
/// return Err("login disconnect".into()); /// return Err("login disconnect".into());
/// } /// }
/// ClientboundLoginPacket::CustomQuery(p) => {} /// ClientboundLoginPacket::CustomQuery(p) => {}
/// ClientboundLoginPacket::CookieRequest(_) => {}
/// } /// }
/// }; /// };
/// ///
@ -404,7 +405,7 @@ impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
/// match conn.read().await? { /// match conn.read().await? {
/// ClientboundLoginPacket::Hello(p) => { /// ClientboundLoginPacket::Hello(p) => {
/// // tell Mojang we're joining the server & enable encryption /// // tell Mojang we're joining the server & enable encryption
/// let e = azalea_crypto::encrypt(&p.public_key, &p.nonce).unwrap(); /// let e = azalea_crypto::encrypt(&p.public_key, &p.challenge).unwrap();
/// conn.authenticate( /// conn.authenticate(
/// &access_token, /// &access_token,
/// &profile.id, /// &profile.id,
@ -414,7 +415,7 @@ impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
/// conn.write( /// conn.write(
/// ServerboundKeyPacket { /// ServerboundKeyPacket {
/// key_bytes: e.encrypted_public_key, /// key_bytes: e.encrypted_public_key,
/// encrypted_challenge: e.encrypted_nonce, /// encrypted_challenge: e.encrypted_challenge,
/// }.get() /// }.get()
/// ).await?; /// ).await?;
/// conn.set_encryption_key(e.secret_key); /// conn.set_encryption_key(e.secret_key);

View file

@ -7,7 +7,7 @@ use azalea_core::{
#[derive(Clone, Debug, McBuf)] #[derive(Clone, Debug, McBuf)]
pub struct CommonPlayerSpawnInfo { pub struct CommonPlayerSpawnInfo {
pub dimension_type: ResourceLocation, pub dimension_type: azalea_registry::DimensionType,
pub dimension: ResourceLocation, pub dimension: ResourceLocation,
pub seed: i64, pub seed: i64,
pub game_type: GameMode, pub game_type: GameMode,

View file

@ -0,0 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundConfigurationPacket;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
pub struct ClientboundCookieRequestPacket {
pub key: ResourceLocation,
}

View file

@ -1,8 +1,12 @@
use std::collections::HashMap;
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_core::registry_holder::RegistryHolder; use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundConfigurationPacket; use azalea_protocol_macros::ClientboundConfigurationPacket;
use simdnbt::owned::NbtCompound;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)] #[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
pub struct ClientboundRegistryDataPacket { pub struct ClientboundRegistryDataPacket {
pub registry_holder: RegistryHolder, pub registry_id: ResourceLocation,
pub entries: HashMap<ResourceLocation, Option<NbtCompound>>,
} }

View file

@ -0,0 +1,5 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundConfigurationPacket;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
pub struct ClientboundResetChatPacket;

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundConfigurationPacket;
use super::serverbound_select_known_packs_packet::KnownPack;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
pub struct ClientboundSelectKnownPacksPacket {
pub known_packs: Vec<KnownPack>,
}

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundConfigurationPacket;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
pub struct ClientboundStoreCookiePacket {
pub key: ResourceLocation,
pub payload: Vec<u8>,
}

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundConfigurationPacket;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
pub struct ClientboundTransferPacket {
pub host: String,
#[var]
pub port: u32,
}

View file

@ -1,41 +1,56 @@
pub mod clientbound_cookie_request_packet;
pub mod clientbound_custom_payload_packet; pub mod clientbound_custom_payload_packet;
pub mod clientbound_disconnect_packet; pub mod clientbound_disconnect_packet;
pub mod clientbound_finish_configuration_packet; pub mod clientbound_finish_configuration_packet;
pub mod clientbound_keep_alive_packet; pub mod clientbound_keep_alive_packet;
pub mod clientbound_ping_packet; pub mod clientbound_ping_packet;
pub mod clientbound_registry_data_packet; pub mod clientbound_registry_data_packet;
pub mod clientbound_reset_chat_packet;
pub mod clientbound_resource_pack_pop_packet; pub mod clientbound_resource_pack_pop_packet;
pub mod clientbound_resource_pack_push_packet; pub mod clientbound_resource_pack_push_packet;
pub mod clientbound_select_known_packs_packet;
pub mod clientbound_store_cookie_packet;
pub mod clientbound_transfer_packet;
pub mod clientbound_update_enabled_features_packet; pub mod clientbound_update_enabled_features_packet;
pub mod clientbound_update_tags_packet; pub mod clientbound_update_tags_packet;
pub mod serverbound_client_information_packet; pub mod serverbound_client_information_packet;
pub mod serverbound_cookie_response_packet;
pub mod serverbound_custom_payload_packet; pub mod serverbound_custom_payload_packet;
pub mod serverbound_finish_configuration_packet; pub mod serverbound_finish_configuration_packet;
pub mod serverbound_keep_alive_packet; pub mod serverbound_keep_alive_packet;
pub mod serverbound_pong_packet; pub mod serverbound_pong_packet;
pub mod serverbound_resource_pack_packet; pub mod serverbound_resource_pack_packet;
pub mod serverbound_select_known_packs_packet;
use azalea_protocol_macros::declare_state_packets; use azalea_protocol_macros::declare_state_packets;
declare_state_packets!( declare_state_packets!(
ConfigurationPacket, ConfigurationPacket,
Serverbound => { Serverbound => {
0x00: serverbound_client_information_packet::ServerboundClientInformationPacket, 0x00: serverbound_client_information_packet::ServerboundClientInformationPacket,
0x01: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, 0x01: serverbound_cookie_response_packet::ServerboundCookieResponsePacket,
0x02: serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket, 0x02: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
0x03: serverbound_keep_alive_packet::ServerboundKeepAlivePacket, 0x03: serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket,
0x04: serverbound_pong_packet::ServerboundPongPacket, 0x04: serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
0x05: serverbound_resource_pack_packet::ServerboundResourcePackPacket, 0x05: serverbound_pong_packet::ServerboundPongPacket,
0x06: serverbound_resource_pack_packet::ServerboundResourcePackPacket,
0x07: serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket,
}, },
Clientbound => { Clientbound => {
0x00: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, 0x00: clientbound_cookie_request_packet::ClientboundCookieRequestPacket,
0x01: clientbound_disconnect_packet::ClientboundDisconnectPacket, 0x01: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
0x02: clientbound_finish_configuration_packet::ClientboundFinishConfigurationPacket, 0x02: clientbound_disconnect_packet::ClientboundDisconnectPacket,
0x03: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, 0x03: clientbound_finish_configuration_packet::ClientboundFinishConfigurationPacket,
0x04: clientbound_ping_packet::ClientboundPingPacket, 0x04: clientbound_keep_alive_packet::ClientboundKeepAlivePacket,
0x05: clientbound_registry_data_packet::ClientboundRegistryDataPacket, 0x05: clientbound_ping_packet::ClientboundPingPacket,
0x06: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket, 0x06: clientbound_reset_chat_packet::ClientboundResetChatPacket,
0x07: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket, 0x07: clientbound_registry_data_packet::ClientboundRegistryDataPacket,
0x08: clientbound_update_enabled_features_packet::ClientboundUpdateEnabledFeaturesPacket, 0x08: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket,
0x09: clientbound_update_tags_packet::ClientboundUpdateTagsPacket, 0x09: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket,
0x0a: clientbound_store_cookie_packet::ClientboundStoreCookiePacket,
0x0b: clientbound_transfer_packet::ClientboundTransferPacket,
0x0c: clientbound_update_enabled_features_packet::ClientboundUpdateEnabledFeaturesPacket,
0x0d: clientbound_update_tags_packet::ClientboundUpdateTagsPacket,
0x0e: clientbound_select_known_packs_packet::ClientboundSelectKnownPacksPacket,
} }
); );

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ServerboundConfigurationPacket;
#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)]
pub struct ServerboundCookieResponsePacket {
pub key: ResourceLocation,
pub payload: Option<Vec<u8>>,
}

View file

@ -0,0 +1,14 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ServerboundConfigurationPacket;
#[derive(Clone, Debug, McBuf, ServerboundConfigurationPacket)]
pub struct ServerboundSelectKnownPacksPacket {
pub known_packs: Vec<KnownPack>,
}
#[derive(Clone, Debug, McBuf)]
pub struct KnownPack {
pub namespace: String,
pub id: String,
pub version: String,
}

View file

@ -22,21 +22,6 @@ pub struct ClientboundAddEntityPacket {
pub z_vel: i16, pub z_vel: i16,
} }
// impl From<&ClientboundAddEntityPacket> for EntityData {
// fn from(p: &ClientboundAddEntityPacket) -> Self {
// Self::new(
// p.uuid,
// Vec3 {
// x: p.x,
// y: p.y,
// z: p.z,
// },
// // default metadata for the entity type
// EntityMetadata::from(p.entity_type),
// )
// }
// }
impl ClientboundAddEntityPacket { impl ClientboundAddEntityPacket {
/// Make the entity into a bundle that can be inserted into the ECS. You /// Make the entity into a bundle that can be inserted into the ECS. You
/// must apply the metadata after inserting the bundle with /// must apply the metadata after inserting the bundle with

View file

@ -128,6 +128,7 @@ pub enum BrigadierParser {
Swizzle, Swizzle,
Team, Team,
ItemSlot, ItemSlot,
ItemSlots,
ResourceLocation, ResourceLocation,
Function, Function,
EntityAnchor, EntityAnchor,
@ -143,6 +144,9 @@ pub enum BrigadierParser {
TemplateMirror, TemplateMirror,
TemplateRotation, TemplateRotation,
Heightmap, Heightmap,
LootTable,
LootPredicate,
LootModifier,
Uuid, Uuid,
} }

View file

@ -0,0 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundCookieRequestPacket {
pub key: ResourceLocation,
}

View file

@ -0,0 +1,10 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundGamePacket;
use super::serverbound_debug_sample_subscription::RemoteDebugSampleType;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundDebugSamplePacket {
pub sample: Vec<u64>,
pub debug_sample_type: RemoteDebugSampleType,
}

View file

@ -1,12 +1,9 @@
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; use azalea_buf::McBuf;
use azalea_core::particle::ParticleData;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
use std::io::{Cursor, Write}; use azalea_registry::ParticleKind;
#[derive(Clone, Debug, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundLevelParticlesPacket { pub struct ClientboundLevelParticlesPacket {
#[var]
pub particle_id: u32,
pub override_limiter: bool, pub override_limiter: bool,
pub x: f64, pub x: f64,
pub y: f64, pub y: f64,
@ -15,54 +12,7 @@ pub struct ClientboundLevelParticlesPacket {
pub y_dist: f32, pub y_dist: f32,
pub z_dist: f32, pub z_dist: f32,
pub max_speed: f32, pub max_speed: f32,
#[var]
pub count: u32, pub count: u32,
pub data: ParticleData, pub particle: ParticleKind,
}
impl McBufReadable for ClientboundLevelParticlesPacket {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let particle_id = u32::var_read_from(buf)?;
let override_limiter = bool::read_from(buf)?;
let x = f64::read_from(buf)?;
let y = f64::read_from(buf)?;
let z = f64::read_from(buf)?;
let x_dist = f32::read_from(buf)?;
let y_dist = f32::read_from(buf)?;
let z_dist = f32::read_from(buf)?;
let max_speed = f32::read_from(buf)?;
let count = u32::read_from(buf)?;
let data = ParticleData::read_from_id(buf, particle_id)?;
Ok(Self {
particle_id,
override_limiter,
x,
y,
z,
x_dist,
y_dist,
z_dist,
max_speed,
count,
data,
})
}
}
impl McBufWritable for ClientboundLevelParticlesPacket {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
self.particle_id.var_write_into(buf)?;
self.override_limiter.write_into(buf)?;
self.x.write_into(buf)?;
self.y.write_into(buf)?;
self.z.write_into(buf)?;
self.x_dist.write_into(buf)?;
self.y_dist.write_into(buf)?;
self.z_dist.write_into(buf)?;
self.max_speed.write_into(buf)?;
self.count.write_into(buf)?;
self.data.write_without_id(buf)?;
Ok(())
}
} }

View file

@ -23,4 +23,5 @@ pub struct ClientboundLoginPacket {
pub show_death_screen: bool, pub show_death_screen: bool,
pub do_limited_crafting: bool, pub do_limited_crafting: bool,
pub common: CommonPlayerSpawnInfo, pub common: CommonPlayerSpawnInfo,
pub enforces_secure_chat: bool,
} }

View file

@ -6,5 +6,4 @@ use azalea_protocol_macros::ClientboundGamePacket;
pub struct ClientboundServerDataPacket { pub struct ClientboundServerDataPacket {
pub motd: FormattedText, pub motd: FormattedText,
pub icon_bytes: Option<Vec<u8>>, pub icon_bytes: Option<Vec<u8>>,
pub enforces_secure_chat: bool,
} }

View file

@ -7,7 +7,7 @@ use std::io::Cursor;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetEquipmentPacket { pub struct ClientboundSetEquipmentPacket {
#[var] #[var]
pub entity: i32, pub entity_id: u32,
pub slots: EquipmentSlots, pub slots: EquipmentSlots,
} }

View file

@ -1,15 +1,27 @@
use super::clientbound_sound_packet::SoundSource;
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::OptionalRegistry;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundEntityPacket { pub struct ClientboundSoundEntityPacket {
pub sound: OptionalRegistry<azalea_registry::SoundEvent>,
pub source: SoundSource, pub source: SoundSource,
#[var] #[var]
pub id: u32, pub id: u32,
pub volume: f32, pub volume: f32,
pub pitch: f32, pub pitch: f32,
#[var]
pub seed: u64, pub seed: u64,
} }
#[derive(McBuf, Clone, Copy, Debug)]
pub enum SoundSource {
Master = 0,
Music = 1,
Records = 2,
Weather = 3,
Blocks = 4,
Hostile = 5,
Neutral = 6,
Players = 7,
Ambient = 8,
Voice = 9,
}

View file

@ -1,10 +1,10 @@
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::SoundEvent;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundPacket { pub struct ClientboundSoundPacket {
pub sound: azalea_registry::CustomRegistry<azalea_registry::SoundEvent, CustomSoundEvent>, pub sound: SoundEvent,
pub source: SoundSource, pub source: SoundSource,
pub x: i32, pub x: i32,
pub y: i32, pub y: i32,
@ -14,12 +14,6 @@ pub struct ClientboundSoundPacket {
pub seed: u64, pub seed: u64,
} }
#[derive(McBuf, Clone, Debug)]
pub struct CustomSoundEvent {
pub location: ResourceLocation,
pub range: Option<f32>,
}
#[derive(McBuf, Clone, Copy, Debug)] #[derive(McBuf, Clone, Copy, Debug)]
pub enum SoundSource { pub enum SoundSource {
Master = 0, Master = 0,

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundStoreCookiePacket {
pub key: ResourceLocation,
pub payload: Vec<u8>,
}

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundTransferPacket {
pub host: String,
#[var]
pub port: u32,
}

View file

@ -1,18 +1,18 @@
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_entity::attributes::AttributeModifier; use azalea_entity::attributes::AttributeModifier;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::Attribute;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateAttributesPacket { pub struct ClientboundUpdateAttributesPacket {
#[var] #[var]
pub entity_id: u32, pub entity_id: u32,
pub attributes: Vec<AttributeSnapshot>, pub values: Vec<AttributeSnapshot>,
} }
#[derive(Clone, Debug, McBuf)] #[derive(Clone, Debug, McBuf)]
pub struct AttributeSnapshot { pub struct AttributeSnapshot {
pub attribute: ResourceLocation, pub attribute: Attribute,
pub base: f64, pub base: f64,
pub modifiers: Vec<AttributeModifier>, pub modifiers: Vec<AttributeModifier>,
} }

View file

@ -1,15 +1,15 @@
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
use simdnbt::owned::NbtTag; use azalea_registry::MobEffect;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateMobEffectPacket { pub struct ClientboundUpdateMobEffectPacket {
#[var] #[var]
pub entity_id: u32, pub entity_id: u32,
pub effect: azalea_registry::MobEffect, pub mob_effect: MobEffect,
pub effect_amplifier: u8, #[var]
pub effect_amplifier: u32,
#[var] #[var]
pub effect_duration_ticks: u32, pub effect_duration_ticks: u32,
pub flags: u8, pub flags: u8,
pub factor_data: Option<NbtTag>,
} }

View file

@ -4,19 +4,17 @@ use azalea_buf::{
use azalea_core::resource_location::ResourceLocation; use azalea_core::resource_location::ResourceLocation;
use azalea_inventory::ItemSlot; use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::RecipeSerializer;
use std::io::{Cursor, Write}; use std::io::{Cursor, Write};
use std::str::FromStr;
#[derive(Clone, Debug, McBuf, PartialEq, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, PartialEq, ClientboundGamePacket)]
pub struct ClientboundUpdateRecipesPacket { pub struct ClientboundUpdateRecipesPacket {
pub recipes: Vec<Recipe>, pub recipes: Vec<RecipeHolder>,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq, McBuf)]
pub struct Recipe { pub struct RecipeHolder {
pub identifier: ResourceLocation, pub id: ResourceLocation,
pub data: RecipeData, pub data: RecipeData,
} }
@ -156,147 +154,6 @@ pub struct Ingredient {
pub allowed: Vec<ItemSlot>, pub allowed: Vec<ItemSlot>,
} }
impl McBufWritable for Recipe {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
let recipe_serializer = match &self.data {
RecipeData::CraftingShapeless(_) => RecipeSerializer::CraftingShapeless,
RecipeData::CraftingShaped(_) => RecipeSerializer::CraftingShaped,
RecipeData::CraftingSpecialArmorDye(_) => RecipeSerializer::CraftingSpecialArmordye,
RecipeData::CraftingSpecialBookCloning(_) => {
RecipeSerializer::CraftingSpecialBookcloning
}
RecipeData::CraftingSpecialMapCloning(_) => RecipeSerializer::CraftingSpecialMapcloning,
RecipeData::CraftingSpecialMapExtending(_) => {
RecipeSerializer::CraftingSpecialMapextending
}
RecipeData::CraftingSpecialFireworkRocket(_) => {
RecipeSerializer::CraftingSpecialFireworkRocket
}
RecipeData::CraftingSpecialFireworkStar(_) => {
RecipeSerializer::CraftingSpecialFireworkStar
}
RecipeData::CraftingSpecialFireworkStarFade(_) => {
RecipeSerializer::CraftingSpecialFireworkStarFade
}
RecipeData::CraftingSpecialRepairItem(_) => RecipeSerializer::CraftingSpecialRepairitem,
RecipeData::CraftingSpecialTippedArrow(_) => {
RecipeSerializer::CraftingSpecialTippedarrow
}
RecipeData::CraftingSpecialBannerDuplicate(_) => {
RecipeSerializer::CraftingSpecialBannerduplicate
}
RecipeData::CraftingSpecialShieldDecoration(_) => {
RecipeSerializer::CraftingSpecialShielddecoration
}
RecipeData::CraftingSpecialShulkerBoxColoring(_) => {
RecipeSerializer::CraftingSpecialShulkerboxcoloring
}
RecipeData::CraftingSpecialSuspiciousStew(_) => {
RecipeSerializer::CraftingSpecialSuspiciousstew
}
RecipeData::Smelting(_) => RecipeSerializer::Smelting,
RecipeData::Blasting(_) => RecipeSerializer::Blasting,
RecipeData::Smoking(_) => RecipeSerializer::Smoking,
RecipeData::CampfireCooking(_) => RecipeSerializer::CampfireCooking,
RecipeData::Stonecutting(_) => RecipeSerializer::Stonecutting,
RecipeData::SmithingTransform(_) => RecipeSerializer::SmithingTransform,
RecipeData::SmithingTrim(_) => RecipeSerializer::SmithingTrim,
RecipeData::CraftingDecoratedPot(_) => RecipeSerializer::CraftingDecoratedPot,
};
let resource_location = ResourceLocation::new(&recipe_serializer.to_string());
resource_location.write_into(buf)?;
self.identifier.write_into(buf)?;
self.data.write_without_id(buf)?;
Ok(())
}
}
impl McBufReadable for Recipe {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let recipe_serializer_name = ResourceLocation::read_from(buf)?;
let Ok(recipe_serializer) = RecipeSerializer::from_str(&recipe_serializer_name.to_string())
else {
return Err(BufReadError::UnexpectedStringEnumVariant {
id: recipe_serializer_name.to_string(),
});
};
let identifier = ResourceLocation::read_from(buf)?;
// rust doesn't let us match ResourceLocation so we have to do a big
// if-else chain :(
let data = match recipe_serializer {
RecipeSerializer::CraftingShaped => {
RecipeData::CraftingShaped(ShapedRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingShapeless => {
RecipeData::CraftingShapeless(ShapelessRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialArmordye => {
RecipeData::CraftingSpecialArmorDye(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialBookcloning => {
RecipeData::CraftingSpecialBookCloning(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialMapcloning => {
RecipeData::CraftingSpecialMapCloning(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialMapextending => {
RecipeData::CraftingSpecialMapExtending(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialFireworkRocket => {
RecipeData::CraftingSpecialFireworkRocket(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialFireworkStar => {
RecipeData::CraftingSpecialFireworkStar(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialFireworkStarFade => {
RecipeData::CraftingSpecialFireworkStarFade(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialRepairitem => {
RecipeData::CraftingSpecialRepairItem(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialTippedarrow => {
RecipeData::CraftingSpecialTippedArrow(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialBannerduplicate => {
RecipeData::CraftingSpecialBannerDuplicate(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialShielddecoration => {
RecipeData::CraftingSpecialShieldDecoration(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialShulkerboxcoloring => {
RecipeData::CraftingSpecialShulkerBoxColoring(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingSpecialSuspiciousstew => {
RecipeData::CraftingSpecialSuspiciousStew(SimpleRecipe::read_from(buf)?)
}
RecipeSerializer::Smelting => RecipeData::Smelting(CookingRecipe::read_from(buf)?),
RecipeSerializer::Blasting => RecipeData::Blasting(CookingRecipe::read_from(buf)?),
RecipeSerializer::Smoking => RecipeData::Smoking(CookingRecipe::read_from(buf)?),
RecipeSerializer::CampfireCooking => {
RecipeData::CampfireCooking(CookingRecipe::read_from(buf)?)
}
RecipeSerializer::Stonecutting => {
RecipeData::Stonecutting(StoneCutterRecipe::read_from(buf)?)
}
RecipeSerializer::SmithingTransform => {
RecipeData::SmithingTransform(SmithingTransformRecipe::read_from(buf)?)
}
RecipeSerializer::SmithingTrim => {
RecipeData::SmithingTrim(SmithingTrimRecipe::read_from(buf)?)
}
RecipeSerializer::CraftingDecoratedPot => {
RecipeData::CraftingDecoratedPot(SimpleRecipe::read_from(buf)?)
}
};
let recipe = Recipe { identifier, data };
Ok(recipe)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -304,8 +161,8 @@ mod tests {
#[test] #[test]
fn test_crafting_shaped() { fn test_crafting_shaped() {
let mut buf = Vec::new(); let mut buf = Vec::new();
let recipe = Recipe { let recipe = RecipeHolder {
identifier: ResourceLocation::new("minecraft:crafting_shaped"), id: ResourceLocation::new("minecraft:crafting_shaped"),
data: RecipeData::CraftingShaped(ShapedRecipe { data: RecipeData::CraftingShaped(ShapedRecipe {
group: String::new(), group: String::new(),
category: CraftingBookCategory::Building, category: CraftingBookCategory::Building,
@ -332,15 +189,15 @@ mod tests {
}), }),
}; };
recipe.write_into(&mut buf).unwrap(); recipe.write_into(&mut buf).unwrap();
let decoded_recipe = Recipe::read_from(&mut Cursor::new(&buf[..])).unwrap(); let decoded_recipe = RecipeHolder::read_from(&mut Cursor::new(&buf[..])).unwrap();
assert_eq!(recipe, decoded_recipe); assert_eq!(recipe, decoded_recipe);
} }
#[test] #[test]
fn test_crafting_shapeless() { fn test_crafting_shapeless() {
let mut buf = Vec::new(); let mut buf = Vec::new();
let recipe = Recipe { let recipe = RecipeHolder {
identifier: ResourceLocation::new("minecraft:crafting_shapeless"), id: ResourceLocation::new("minecraft:crafting_shapeless"),
data: RecipeData::CraftingShapeless(ShapelessRecipe { data: RecipeData::CraftingShapeless(ShapelessRecipe {
group: String::new(), group: String::new(),
category: CraftingBookCategory::Building, category: CraftingBookCategory::Building,
@ -362,21 +219,21 @@ mod tests {
}), }),
}; };
recipe.write_into(&mut buf).unwrap(); recipe.write_into(&mut buf).unwrap();
let decoded_recipe = Recipe::read_from(&mut Cursor::new(&buf[..])).unwrap(); let decoded_recipe = RecipeHolder::read_from(&mut Cursor::new(&buf[..])).unwrap();
assert_eq!(recipe, decoded_recipe); assert_eq!(recipe, decoded_recipe);
} }
#[test] #[test]
fn test_crafting_special_armordye() { fn test_crafting_special_armordye() {
let mut buf = Vec::new(); let mut buf = Vec::new();
let recipe = Recipe { let recipe = RecipeHolder {
identifier: ResourceLocation::new("minecraft:crafting_special_armordye"), id: ResourceLocation::new("minecraft:crafting_special_armordye"),
data: RecipeData::CraftingSpecialArmorDye(SimpleRecipe { data: RecipeData::CraftingSpecialArmorDye(SimpleRecipe {
category: CraftingBookCategory::Building, category: CraftingBookCategory::Building,
}), }),
}; };
recipe.write_into(&mut buf).unwrap(); recipe.write_into(&mut buf).unwrap();
let decoded_recipe = Recipe::read_from(&mut Cursor::new(&buf[..])).unwrap(); let decoded_recipe = RecipeHolder::read_from(&mut Cursor::new(&buf[..])).unwrap();
assert_eq!(recipe, decoded_recipe); assert_eq!(recipe, decoded_recipe);
} }
} }

View file

@ -20,10 +20,12 @@ pub mod clientbound_container_close_packet;
pub mod clientbound_container_set_content_packet; pub mod clientbound_container_set_content_packet;
pub mod clientbound_container_set_data_packet; pub mod clientbound_container_set_data_packet;
pub mod clientbound_container_set_slot_packet; pub mod clientbound_container_set_slot_packet;
pub mod clientbound_cookie_request_packet;
pub mod clientbound_cooldown_packet; pub mod clientbound_cooldown_packet;
pub mod clientbound_custom_chat_completions_packet; pub mod clientbound_custom_chat_completions_packet;
pub mod clientbound_custom_payload_packet; pub mod clientbound_custom_payload_packet;
pub mod clientbound_damage_event_packet; pub mod clientbound_damage_event_packet;
pub mod clientbound_debug_sample_packet;
pub mod clientbound_delete_chat_packet; pub mod clientbound_delete_chat_packet;
pub mod clientbound_disconnect_packet; pub mod clientbound_disconnect_packet;
pub mod clientbound_disguised_chat_packet; pub mod clientbound_disguised_chat_packet;
@ -103,6 +105,7 @@ pub mod clientbound_sound_entity_packet;
pub mod clientbound_sound_packet; pub mod clientbound_sound_packet;
pub mod clientbound_start_configuration_packet; pub mod clientbound_start_configuration_packet;
pub mod clientbound_stop_sound_packet; pub mod clientbound_stop_sound_packet;
pub mod clientbound_store_cookie_packet;
pub mod clientbound_system_chat_packet; pub mod clientbound_system_chat_packet;
pub mod clientbound_tab_list_packet; pub mod clientbound_tab_list_packet;
pub mod clientbound_tag_query_packet; pub mod clientbound_tag_query_packet;
@ -110,16 +113,18 @@ pub mod clientbound_take_item_entity_packet;
pub mod clientbound_teleport_entity_packet; pub mod clientbound_teleport_entity_packet;
pub mod clientbound_ticking_state_packet; pub mod clientbound_ticking_state_packet;
pub mod clientbound_ticking_step_packet; pub mod clientbound_ticking_step_packet;
pub mod clientbound_transfer_packet;
pub mod clientbound_update_advancements_packet; pub mod clientbound_update_advancements_packet;
pub mod clientbound_update_attributes_packet; pub mod clientbound_update_attributes_packet;
pub mod clientbound_update_mob_effect_packet; pub mod clientbound_update_mob_effect_packet;
pub mod clientbound_update_recipes_packet; pub mod clientbound_update_recipes_packet;
pub mod clientbound_update_tags_packet; pub mod clientbound_update_tags_packet;
pub mod serverbound_accept_teleportation_packet; pub mod serverbound_accept_teleportation_packet;
pub mod serverbound_block_entity_tag_query; pub mod serverbound_block_entity_tag_query_packet;
pub mod serverbound_change_difficulty_packet; pub mod serverbound_change_difficulty_packet;
pub mod serverbound_chat_ack_packet; pub mod serverbound_chat_ack_packet;
pub mod serverbound_chat_command_packet; pub mod serverbound_chat_command_packet;
pub mod serverbound_chat_command_signed_packet;
pub mod serverbound_chat_packet; pub mod serverbound_chat_packet;
pub mod serverbound_chat_session_update_packet; pub mod serverbound_chat_session_update_packet;
pub mod serverbound_chunk_batch_received_packet; pub mod serverbound_chunk_batch_received_packet;
@ -131,9 +136,11 @@ pub mod serverbound_container_button_click_packet;
pub mod serverbound_container_click_packet; pub mod serverbound_container_click_packet;
pub mod serverbound_container_close_packet; pub mod serverbound_container_close_packet;
pub mod serverbound_container_slot_state_changed_packet; pub mod serverbound_container_slot_state_changed_packet;
pub mod serverbound_cookie_response_packet;
pub mod serverbound_custom_payload_packet; pub mod serverbound_custom_payload_packet;
pub mod serverbound_debug_sample_subscription;
pub mod serverbound_edit_book_packet; pub mod serverbound_edit_book_packet;
pub mod serverbound_entity_tag_query; pub mod serverbound_entity_tag_query_packet;
pub mod serverbound_interact_packet; pub mod serverbound_interact_packet;
pub mod serverbound_jigsaw_generate_packet; pub mod serverbound_jigsaw_generate_packet;
pub mod serverbound_keep_alive_packet; pub mod serverbound_keep_alive_packet;
@ -177,60 +184,63 @@ declare_state_packets!(
GamePacket, GamePacket,
Serverbound => { Serverbound => {
0x00: serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, 0x00: serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket,
0x01: serverbound_block_entity_tag_query::ServerboundBlockEntityTagQuery, 0x01: serverbound_block_entity_tag_query_packet::ServerboundBlockEntityTagQueryPacket,
0x02: serverbound_change_difficulty_packet::ServerboundChangeDifficultyPacket, 0x02: serverbound_change_difficulty_packet::ServerboundChangeDifficultyPacket,
0x03: serverbound_chat_ack_packet::ServerboundChatAckPacket, 0x03: serverbound_chat_ack_packet::ServerboundChatAckPacket,
0x04: serverbound_chat_command_packet::ServerboundChatCommandPacket, 0x04: serverbound_chat_command_packet::ServerboundChatCommandPacket,
0x05: serverbound_chat_packet::ServerboundChatPacket, 0x05: serverbound_chat_command_signed_packet::ServerboundChatCommandSignedPacket,
0x06: serverbound_chat_session_update_packet::ServerboundChatSessionUpdatePacket, 0x06: serverbound_chat_packet::ServerboundChatPacket,
0x07: serverbound_chunk_batch_received_packet::ServerboundChunkBatchReceivedPacket, 0x07: serverbound_chat_session_update_packet::ServerboundChatSessionUpdatePacket,
0x08: serverbound_client_command_packet::ServerboundClientCommandPacket, 0x08: serverbound_chunk_batch_received_packet::ServerboundChunkBatchReceivedPacket,
0x09: serverbound_client_information_packet::ServerboundClientInformationPacket, 0x09: serverbound_client_command_packet::ServerboundClientCommandPacket,
0x0a: serverbound_command_suggestion_packet::ServerboundCommandSuggestionPacket, 0x0a: serverbound_client_information_packet::ServerboundClientInformationPacket,
0x0b: serverbound_configuration_acknowledged_packet::ServerboundConfigurationAcknowledgedPacket, 0x0b: serverbound_command_suggestion_packet::ServerboundCommandSuggestionPacket,
0x0c: serverbound_container_button_click_packet::ServerboundContainerButtonClickPacket, 0x0c: serverbound_configuration_acknowledged_packet::ServerboundConfigurationAcknowledgedPacket,
0x0d: serverbound_container_click_packet::ServerboundContainerClickPacket, 0x0d: serverbound_container_button_click_packet::ServerboundContainerButtonClickPacket,
0x0e: serverbound_container_close_packet::ServerboundContainerClosePacket, 0x0e: serverbound_container_click_packet::ServerboundContainerClickPacket,
0x0f: serverbound_container_slot_state_changed_packet::ServerboundContainerSlotStateChangedPacket, 0x0f: serverbound_container_close_packet::ServerboundContainerClosePacket,
0x10: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, 0x10: serverbound_container_slot_state_changed_packet::ServerboundContainerSlotStateChangedPacket,
0x11: serverbound_edit_book_packet::ServerboundEditBookPacket, 0x11: serverbound_cookie_response_packet::ServerboundCookieResponsePacket,
0x12: serverbound_entity_tag_query::ServerboundEntityTagQuery, 0x12: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
0x13: serverbound_interact_packet::ServerboundInteractPacket, 0x13: serverbound_debug_sample_subscription::ServerboundDebugSampleSubscription,
0x14: serverbound_jigsaw_generate_packet::ServerboundJigsawGeneratePacket, 0x14: serverbound_edit_book_packet::ServerboundEditBookPacket,
0x15: serverbound_keep_alive_packet::ServerboundKeepAlivePacket, 0x15: serverbound_entity_tag_query_packet::ServerboundEntityTagQueryPacket,
0x16: serverbound_lock_difficulty_packet::ServerboundLockDifficultyPacket, 0x16: serverbound_interact_packet::ServerboundInteractPacket,
0x17: serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket, 0x17: serverbound_jigsaw_generate_packet::ServerboundJigsawGeneratePacket,
0x18: serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, 0x18: serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
0x19: serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket, 0x19: serverbound_lock_difficulty_packet::ServerboundLockDifficultyPacket,
0x1a: serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket, 0x1a: serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket,
0x1b: serverbound_move_vehicle_packet::ServerboundMoveVehiclePacket, 0x1b: serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket,
0x1c: serverbound_paddle_boat_packet::ServerboundPaddleBoatPacket, 0x1c: serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket,
0x1d: serverbound_pick_item_packet::ServerboundPickItemPacket, 0x1d: serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket,
0x1e: serverbound_ping_request_packet::ServerboundPingRequestPacket, 0x1e: serverbound_move_vehicle_packet::ServerboundMoveVehiclePacket,
0x1f: serverbound_place_recipe_packet::ServerboundPlaceRecipePacket, 0x1f: serverbound_paddle_boat_packet::ServerboundPaddleBoatPacket,
0x20: serverbound_player_abilities_packet::ServerboundPlayerAbilitiesPacket, 0x20: serverbound_pick_item_packet::ServerboundPickItemPacket,
0x21: serverbound_player_action_packet::ServerboundPlayerActionPacket, 0x21: serverbound_ping_request_packet::ServerboundPingRequestPacket,
0x22: serverbound_player_command_packet::ServerboundPlayerCommandPacket, 0x22: serverbound_place_recipe_packet::ServerboundPlaceRecipePacket,
0x23: serverbound_player_input_packet::ServerboundPlayerInputPacket, 0x23: serverbound_player_abilities_packet::ServerboundPlayerAbilitiesPacket,
0x24: serverbound_pong_packet::ServerboundPongPacket, 0x24: serverbound_player_action_packet::ServerboundPlayerActionPacket,
0x25: serverbound_recipe_book_change_settings_packet::ServerboundRecipeBookChangeSettingsPacket, 0x25: serverbound_player_command_packet::ServerboundPlayerCommandPacket,
0x26: serverbound_recipe_book_seen_recipe_packet::ServerboundRecipeBookSeenRecipePacket, 0x26: serverbound_player_input_packet::ServerboundPlayerInputPacket,
0x27: serverbound_rename_item_packet::ServerboundRenameItemPacket, 0x27: serverbound_pong_packet::ServerboundPongPacket,
0x28: serverbound_resource_pack_packet::ServerboundResourcePackPacket, 0x28: serverbound_recipe_book_change_settings_packet::ServerboundRecipeBookChangeSettingsPacket,
0x29: serverbound_seen_advancements_packet::ServerboundSeenAdvancementsPacket, 0x29: serverbound_recipe_book_seen_recipe_packet::ServerboundRecipeBookSeenRecipePacket,
0x2a: serverbound_select_trade_packet::ServerboundSelectTradePacket, 0x2a: serverbound_rename_item_packet::ServerboundRenameItemPacket,
0x2b: serverbound_set_beacon_packet::ServerboundSetBeaconPacket, 0x2b: serverbound_resource_pack_packet::ServerboundResourcePackPacket,
0x2c: serverbound_set_carried_item_packet::ServerboundSetCarriedItemPacket, 0x2c: serverbound_seen_advancements_packet::ServerboundSeenAdvancementsPacket,
0x2d: serverbound_set_command_block_packet::ServerboundSetCommandBlockPacket, 0x2d: serverbound_select_trade_packet::ServerboundSelectTradePacket,
0x2e: serverbound_set_command_minecart_packet::ServerboundSetCommandMinecartPacket, 0x2e: serverbound_set_beacon_packet::ServerboundSetBeaconPacket,
0x2f: serverbound_set_creative_mode_slot_packet::ServerboundSetCreativeModeSlotPacket, 0x2f: serverbound_set_carried_item_packet::ServerboundSetCarriedItemPacket,
0x30: serverbound_set_jigsaw_block_packet::ServerboundSetJigsawBlockPacket, 0x30: serverbound_set_command_block_packet::ServerboundSetCommandBlockPacket,
0x31: serverbound_set_structure_block_packet::ServerboundSetStructureBlockPacket, 0x31: serverbound_set_command_minecart_packet::ServerboundSetCommandMinecartPacket,
0x32: serverbound_sign_update_packet::ServerboundSignUpdatePacket, 0x32: serverbound_set_creative_mode_slot_packet::ServerboundSetCreativeModeSlotPacket,
0x33: serverbound_swing_packet::ServerboundSwingPacket, 0x33: serverbound_set_jigsaw_block_packet::ServerboundSetJigsawBlockPacket,
0x34: serverbound_teleport_to_entity_packet::ServerboundTeleportToEntityPacket, 0x34: serverbound_set_structure_block_packet::ServerboundSetStructureBlockPacket,
0x35: serverbound_use_item_on_packet::ServerboundUseItemOnPacket, 0x35: serverbound_sign_update_packet::ServerboundSignUpdatePacket,
0x36: serverbound_use_item_packet::ServerboundUseItemPacket, 0x36: serverbound_swing_packet::ServerboundSwingPacket,
0x37: serverbound_teleport_to_entity_packet::ServerboundTeleportToEntityPacket,
0x38: serverbound_use_item_on_packet::ServerboundUseItemOnPacket,
0x39: serverbound_use_item_packet::ServerboundUseItemPacket,
}, },
Clientbound => { Clientbound => {
0x00: clientbound_bundle_packet::ClientboundBundlePacket, 0x00: clientbound_bundle_packet::ClientboundBundlePacket,
@ -255,100 +265,104 @@ declare_state_packets!(
0x13: clientbound_container_set_content_packet::ClientboundContainerSetContentPacket, 0x13: clientbound_container_set_content_packet::ClientboundContainerSetContentPacket,
0x14: clientbound_container_set_data_packet::ClientboundContainerSetDataPacket, 0x14: clientbound_container_set_data_packet::ClientboundContainerSetDataPacket,
0x15: clientbound_container_set_slot_packet::ClientboundContainerSetSlotPacket, 0x15: clientbound_container_set_slot_packet::ClientboundContainerSetSlotPacket,
0x16: clientbound_cooldown_packet::ClientboundCooldownPacket, 0x16: clientbound_cookie_request_packet::ClientboundCookieRequestPacket,
0x17: clientbound_custom_chat_completions_packet::ClientboundCustomChatCompletionsPacket, 0x17: clientbound_cooldown_packet::ClientboundCooldownPacket,
0x18: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, 0x18: clientbound_custom_chat_completions_packet::ClientboundCustomChatCompletionsPacket,
0x19: clientbound_damage_event_packet::ClientboundDamageEventPacket, 0x19: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
0x1a: clientbound_delete_chat_packet::ClientboundDeleteChatPacket, 0x1a: clientbound_damage_event_packet::ClientboundDamageEventPacket,
0x1b: clientbound_disconnect_packet::ClientboundDisconnectPacket, 0x1b: clientbound_debug_sample_packet::ClientboundDebugSamplePacket,
0x1c: clientbound_disguised_chat_packet::ClientboundDisguisedChatPacket, 0x1c: clientbound_delete_chat_packet::ClientboundDeleteChatPacket,
0x1d: clientbound_entity_event_packet::ClientboundEntityEventPacket, 0x1d: clientbound_disconnect_packet::ClientboundDisconnectPacket,
0x1e: clientbound_explode_packet::ClientboundExplodePacket, 0x1e: clientbound_disguised_chat_packet::ClientboundDisguisedChatPacket,
0x1f: clientbound_forget_level_chunk_packet::ClientboundForgetLevelChunkPacket, 0x1f: clientbound_entity_event_packet::ClientboundEntityEventPacket,
0x20: clientbound_game_event_packet::ClientboundGameEventPacket, 0x20: clientbound_explode_packet::ClientboundExplodePacket,
0x21: clientbound_horse_screen_open_packet::ClientboundHorseScreenOpenPacket, 0x21: clientbound_forget_level_chunk_packet::ClientboundForgetLevelChunkPacket,
0x22: clientbound_hurt_animation_packet::ClientboundHurtAnimationPacket, 0x22: clientbound_game_event_packet::ClientboundGameEventPacket,
0x23: clientbound_initialize_border_packet::ClientboundInitializeBorderPacket, 0x23: clientbound_horse_screen_open_packet::ClientboundHorseScreenOpenPacket,
0x24: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, 0x24: clientbound_hurt_animation_packet::ClientboundHurtAnimationPacket,
0x25: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, 0x25: clientbound_initialize_border_packet::ClientboundInitializeBorderPacket,
0x26: clientbound_level_event_packet::ClientboundLevelEventPacket, 0x26: clientbound_keep_alive_packet::ClientboundKeepAlivePacket,
0x27: clientbound_level_particles_packet::ClientboundLevelParticlesPacket, 0x27: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket,
0x28: clientbound_light_update_packet::ClientboundLightUpdatePacket, 0x28: clientbound_level_event_packet::ClientboundLevelEventPacket,
0x29: clientbound_login_packet::ClientboundLoginPacket, 0x29: clientbound_level_particles_packet::ClientboundLevelParticlesPacket,
0x2a: clientbound_map_item_data_packet::ClientboundMapItemDataPacket, 0x2a: clientbound_light_update_packet::ClientboundLightUpdatePacket,
0x2b: clientbound_merchant_offers_packet::ClientboundMerchantOffersPacket, 0x2b: clientbound_login_packet::ClientboundLoginPacket,
0x2c: clientbound_move_entity_pos_packet::ClientboundMoveEntityPosPacket, 0x2c: clientbound_map_item_data_packet::ClientboundMapItemDataPacket,
0x2d: clientbound_move_entity_pos_rot_packet::ClientboundMoveEntityPosRotPacket, 0x2d: clientbound_merchant_offers_packet::ClientboundMerchantOffersPacket,
0x2e: clientbound_move_entity_rot_packet::ClientboundMoveEntityRotPacket, 0x2e: clientbound_move_entity_pos_packet::ClientboundMoveEntityPosPacket,
0x2f: clientbound_move_vehicle_packet::ClientboundMoveVehiclePacket, 0x2f: clientbound_move_entity_pos_rot_packet::ClientboundMoveEntityPosRotPacket,
0x30: clientbound_open_book_packet::ClientboundOpenBookPacket, 0x30: clientbound_move_entity_rot_packet::ClientboundMoveEntityRotPacket,
0x31: clientbound_open_screen_packet::ClientboundOpenScreenPacket, 0x31: clientbound_move_vehicle_packet::ClientboundMoveVehiclePacket,
0x32: clientbound_open_sign_editor_packet::ClientboundOpenSignEditorPacket, 0x32: clientbound_open_book_packet::ClientboundOpenBookPacket,
0x33: clientbound_ping_packet::ClientboundPingPacket, 0x33: clientbound_open_screen_packet::ClientboundOpenScreenPacket,
0x34: clientbound_pong_response_packet::ClientboundPongResponsePacket, 0x34: clientbound_open_sign_editor_packet::ClientboundOpenSignEditorPacket,
0x35: clientbound_place_ghost_recipe_packet::ClientboundPlaceGhostRecipePacket, 0x35: clientbound_ping_packet::ClientboundPingPacket,
0x36: clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket, 0x36: clientbound_pong_response_packet::ClientboundPongResponsePacket,
0x37: clientbound_player_chat_packet::ClientboundPlayerChatPacket, 0x37: clientbound_place_ghost_recipe_packet::ClientboundPlaceGhostRecipePacket,
0x38: clientbound_player_combat_end_packet::ClientboundPlayerCombatEndPacket, 0x38: clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket,
0x39: clientbound_player_combat_enter_packet::ClientboundPlayerCombatEnterPacket, 0x39: clientbound_player_chat_packet::ClientboundPlayerChatPacket,
0x3a: clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, 0x3a: clientbound_player_combat_end_packet::ClientboundPlayerCombatEndPacket,
0x3b: clientbound_player_info_remove_packet::ClientboundPlayerInfoRemovePacket, 0x3b: clientbound_player_combat_enter_packet::ClientboundPlayerCombatEnterPacket,
0x3c: clientbound_player_info_update_packet::ClientboundPlayerInfoUpdatePacket, 0x3c: clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket,
0x3d: clientbound_player_look_at_packet::ClientboundPlayerLookAtPacket, 0x3d: clientbound_player_info_remove_packet::ClientboundPlayerInfoRemovePacket,
0x3e: clientbound_player_position_packet::ClientboundPlayerPositionPacket, 0x3e: clientbound_player_info_update_packet::ClientboundPlayerInfoUpdatePacket,
0x3f: clientbound_recipe_packet::ClientboundRecipePacket, 0x3f: clientbound_player_look_at_packet::ClientboundPlayerLookAtPacket,
0x40: clientbound_remove_entities_packet::ClientboundRemoveEntitiesPacket, 0x40: clientbound_player_position_packet::ClientboundPlayerPositionPacket,
0x41: clientbound_remove_mob_effect_packet::ClientboundRemoveMobEffectPacket, 0x41: clientbound_recipe_packet::ClientboundRecipePacket,
0x42: clientbound_reset_score_packet::ClientboundResetScorePacket, 0x42: clientbound_remove_entities_packet::ClientboundRemoveEntitiesPacket,
0x43: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket, 0x43: clientbound_remove_mob_effect_packet::ClientboundRemoveMobEffectPacket,
0x44: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket, 0x44: clientbound_reset_score_packet::ClientboundResetScorePacket,
0x45: clientbound_respawn_packet::ClientboundRespawnPacket, 0x45: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket,
0x46: clientbound_rotate_head_packet::ClientboundRotateHeadPacket, 0x46: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket,
0x47: clientbound_section_blocks_update_packet::ClientboundSectionBlocksUpdatePacket, 0x47: clientbound_respawn_packet::ClientboundRespawnPacket,
0x48: clientbound_select_advancements_tab_packet::ClientboundSelectAdvancementsTabPacket, 0x48: clientbound_rotate_head_packet::ClientboundRotateHeadPacket,
0x49: clientbound_server_data_packet::ClientboundServerDataPacket, 0x49: clientbound_section_blocks_update_packet::ClientboundSectionBlocksUpdatePacket,
0x4a: clientbound_set_action_bar_text_packet::ClientboundSetActionBarTextPacket, 0x4a: clientbound_select_advancements_tab_packet::ClientboundSelectAdvancementsTabPacket,
0x4b: clientbound_set_border_center_packet::ClientboundSetBorderCenterPacket, 0x4b: clientbound_server_data_packet::ClientboundServerDataPacket,
0x4c: clientbound_set_border_lerp_size_packet::ClientboundSetBorderLerpSizePacket, 0x4c: clientbound_set_action_bar_text_packet::ClientboundSetActionBarTextPacket,
0x4d: clientbound_set_border_size_packet::ClientboundSetBorderSizePacket, 0x4d: clientbound_set_border_center_packet::ClientboundSetBorderCenterPacket,
0x4e: clientbound_set_border_warning_delay_packet::ClientboundSetBorderWarningDelayPacket, 0x4e: clientbound_set_border_lerp_size_packet::ClientboundSetBorderLerpSizePacket,
0x4f: clientbound_set_border_warning_distance_packet::ClientboundSetBorderWarningDistancePacket, 0x4f: clientbound_set_border_size_packet::ClientboundSetBorderSizePacket,
0x50: clientbound_set_camera_packet::ClientboundSetCameraPacket, 0x50: clientbound_set_border_warning_delay_packet::ClientboundSetBorderWarningDelayPacket,
0x51: clientbound_set_carried_item_packet::ClientboundSetCarriedItemPacket, 0x51: clientbound_set_border_warning_distance_packet::ClientboundSetBorderWarningDistancePacket,
0x52: clientbound_set_chunk_cache_center_packet::ClientboundSetChunkCacheCenterPacket, 0x52: clientbound_set_camera_packet::ClientboundSetCameraPacket,
0x53: clientbound_set_chunk_cache_radius_packet::ClientboundSetChunkCacheRadiusPacket, 0x53: clientbound_set_carried_item_packet::ClientboundSetCarriedItemPacket,
0x54: clientbound_set_default_spawn_position_packet::ClientboundSetDefaultSpawnPositionPacket, 0x54: clientbound_set_chunk_cache_center_packet::ClientboundSetChunkCacheCenterPacket,
0x55: clientbound_set_display_objective_packet::ClientboundSetDisplayObjectivePacket, 0x55: clientbound_set_chunk_cache_radius_packet::ClientboundSetChunkCacheRadiusPacket,
0x56: clientbound_set_entity_data_packet::ClientboundSetEntityDataPacket, 0x56: clientbound_set_default_spawn_position_packet::ClientboundSetDefaultSpawnPositionPacket,
0x57: clientbound_set_entity_link_packet::ClientboundSetEntityLinkPacket, 0x57: clientbound_set_display_objective_packet::ClientboundSetDisplayObjectivePacket,
0x58: clientbound_set_entity_motion_packet::ClientboundSetEntityMotionPacket, 0x58: clientbound_set_entity_data_packet::ClientboundSetEntityDataPacket,
0x59: clientbound_set_equipment_packet::ClientboundSetEquipmentPacket, 0x59: clientbound_set_entity_link_packet::ClientboundSetEntityLinkPacket,
0x5a: clientbound_set_experience_packet::ClientboundSetExperiencePacket, 0x5a: clientbound_set_entity_motion_packet::ClientboundSetEntityMotionPacket,
0x5b: clientbound_set_health_packet::ClientboundSetHealthPacket, 0x5b: clientbound_set_equipment_packet::ClientboundSetEquipmentPacket,
0x5c: clientbound_set_objective_packet::ClientboundSetObjectivePacket, 0x5c: clientbound_set_experience_packet::ClientboundSetExperiencePacket,
0x5d: clientbound_set_passengers_packet::ClientboundSetPassengersPacket, 0x5d: clientbound_set_health_packet::ClientboundSetHealthPacket,
0x5e: clientbound_set_player_team_packet::ClientboundSetPlayerTeamPacket, 0x5e: clientbound_set_objective_packet::ClientboundSetObjectivePacket,
0x5f: clientbound_set_score_packet::ClientboundSetScorePacket, 0x5f: clientbound_set_passengers_packet::ClientboundSetPassengersPacket,
0x60: clientbound_set_simulation_distance_packet::ClientboundSetSimulationDistancePacket, 0x60: clientbound_set_player_team_packet::ClientboundSetPlayerTeamPacket,
0x61: clientbound_set_subtitle_text_packet::ClientboundSetSubtitleTextPacket, 0x61: clientbound_set_score_packet::ClientboundSetScorePacket,
0x62: clientbound_set_time_packet::ClientboundSetTimePacket, 0x62: clientbound_set_simulation_distance_packet::ClientboundSetSimulationDistancePacket,
0x63: clientbound_set_title_text_packet::ClientboundSetTitleTextPacket, 0x63: clientbound_set_subtitle_text_packet::ClientboundSetSubtitleTextPacket,
0x64: clientbound_set_titles_animation_packet::ClientboundSetTitlesAnimationPacket, 0x64: clientbound_set_time_packet::ClientboundSetTimePacket,
0x65: clientbound_sound_entity_packet::ClientboundSoundEntityPacket, 0x65: clientbound_set_title_text_packet::ClientboundSetTitleTextPacket,
0x66: clientbound_sound_packet::ClientboundSoundPacket, 0x66: clientbound_set_titles_animation_packet::ClientboundSetTitlesAnimationPacket,
0x67: clientbound_start_configuration_packet::ClientboundStartConfigurationPacket, 0x67: clientbound_sound_entity_packet::ClientboundSoundEntityPacket,
0x68: clientbound_stop_sound_packet::ClientboundStopSoundPacket, 0x68: clientbound_sound_packet::ClientboundSoundPacket,
0x69: clientbound_system_chat_packet::ClientboundSystemChatPacket, 0x69: clientbound_start_configuration_packet::ClientboundStartConfigurationPacket,
0x6a: clientbound_tab_list_packet::ClientboundTabListPacket, 0x6a: clientbound_stop_sound_packet::ClientboundStopSoundPacket,
0x6b: clientbound_tag_query_packet::ClientboundTagQueryPacket, 0x6b: clientbound_store_cookie_packet::ClientboundStoreCookiePacket,
0x6c: clientbound_take_item_entity_packet::ClientboundTakeItemEntityPacket, 0x6c: clientbound_system_chat_packet::ClientboundSystemChatPacket,
0x6d: clientbound_teleport_entity_packet::ClientboundTeleportEntityPacket, 0x6d: clientbound_tab_list_packet::ClientboundTabListPacket,
0x6e: clientbound_ticking_state_packet::ClientboundTickingStatePacket, 0x6e: clientbound_tag_query_packet::ClientboundTagQueryPacket,
0x6f: clientbound_ticking_step_packet::ClientboundTickingStepPacket, 0x6f: clientbound_take_item_entity_packet::ClientboundTakeItemEntityPacket,
0x70: clientbound_update_advancements_packet::ClientboundUpdateAdvancementsPacket, 0x70: clientbound_teleport_entity_packet::ClientboundTeleportEntityPacket,
0x71: clientbound_update_attributes_packet::ClientboundUpdateAttributesPacket, 0x71: clientbound_ticking_state_packet::ClientboundTickingStatePacket,
0x72: clientbound_update_mob_effect_packet::ClientboundUpdateMobEffectPacket, 0x72: clientbound_ticking_step_packet::ClientboundTickingStepPacket,
0x73: clientbound_update_recipes_packet::ClientboundUpdateRecipesPacket, 0x73: clientbound_transfer_packet::ClientboundTransferPacket,
0x74: clientbound_update_tags_packet::ClientboundUpdateTagsPacket, 0x74: clientbound_update_advancements_packet::ClientboundUpdateAdvancementsPacket,
0x75: clientbound_update_attributes_packet::ClientboundUpdateAttributesPacket,
0x76: clientbound_update_mob_effect_packet::ClientboundUpdateMobEffectPacket,
0x77: clientbound_update_recipes_packet::ClientboundUpdateRecipesPacket,
0x78: clientbound_update_tags_packet::ClientboundUpdateTagsPacket,
} }
); );

View file

@ -0,0 +1,10 @@
use azalea_buf::McBuf;
use azalea_core::position::BlockPos;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundBlockEntityTagQueryPacket {
#[var]
pub transaction_id: u32,
pub pos: BlockPos,
}

View file

@ -0,0 +1,19 @@
use super::serverbound_chat_packet::LastSeenMessagesUpdate;
use azalea_buf::McBuf;
use azalea_crypto::MessageSignature;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundChatCommandSignedPacket {
pub command: String,
pub timestamp: u64,
pub salt: u64,
pub argument_signatures: Vec<ArgumentSignature>,
pub last_seen_messages: LastSeenMessagesUpdate,
}
#[derive(Clone, Debug, McBuf)]
pub struct ArgumentSignature {
pub name: String,
pub signature: MessageSignature,
}

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundCookieResponsePacket {
pub key: ResourceLocation,
pub payload: Option<Vec<u8>>,
}

View file

@ -0,0 +1,12 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundDebugSampleSubscription {
pub sample_type: RemoteDebugSampleType,
}
#[derive(Clone, Copy, Debug, McBuf)]
pub enum RemoteDebugSampleType {
TickTime,
}

View file

@ -0,0 +1,10 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundEntityTagQueryPacket {
#[var]
pub transaction_id: u32,
#[var]
pub entity_id: u32,
}

View file

@ -0,0 +1,8 @@
use azalea_buf::McBuf;
use azalea_chat::FormattedText;
use azalea_protocol_macros::ClientboundLoginPacket;
#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)]
pub struct ClientboundCookieRequestPacket {
pub key: FormattedText,
}

View file

@ -5,4 +5,5 @@ use azalea_protocol_macros::ClientboundLoginPacket;
#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)] #[derive(Clone, Debug, McBuf, ClientboundLoginPacket)]
pub struct ClientboundGameProfilePacket { pub struct ClientboundGameProfilePacket {
pub game_profile: GameProfile, pub game_profile: GameProfile,
pub strict_error_handling: bool,
} }

View file

@ -7,5 +7,6 @@ pub struct ClientboundHelloPacket {
// #[len(20)] // #[len(20)]
pub server_id: String, pub server_id: String,
pub public_key: Vec<u8>, pub public_key: Vec<u8>,
pub nonce: Vec<u8>, pub challenge: Vec<u8>,
pub should_authenticate: bool,
} }

View file

@ -1,8 +1,10 @@
pub mod clientbound_cookie_request_packet;
pub mod clientbound_custom_query_packet; pub mod clientbound_custom_query_packet;
pub mod clientbound_game_profile_packet; pub mod clientbound_game_profile_packet;
pub mod clientbound_hello_packet; pub mod clientbound_hello_packet;
pub mod clientbound_login_compression_packet; pub mod clientbound_login_compression_packet;
pub mod clientbound_login_disconnect_packet; pub mod clientbound_login_disconnect_packet;
pub mod serverbound_cookie_response_packet;
pub mod serverbound_custom_query_answer_packet; pub mod serverbound_custom_query_answer_packet;
pub mod serverbound_hello_packet; pub mod serverbound_hello_packet;
pub mod serverbound_key_packet; pub mod serverbound_key_packet;
@ -17,6 +19,7 @@ declare_state_packets!(
0x01: serverbound_key_packet::ServerboundKeyPacket, 0x01: serverbound_key_packet::ServerboundKeyPacket,
0x02: serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket, 0x02: serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket,
0x03: serverbound_login_acknowledged_packet::ServerboundLoginAcknowledgedPacket, 0x03: serverbound_login_acknowledged_packet::ServerboundLoginAcknowledgedPacket,
0x04: serverbound_cookie_response_packet::ServerboundCookieResponsePacket,
}, },
Clientbound => { Clientbound => {
0x00: clientbound_login_disconnect_packet::ClientboundLoginDisconnectPacket, 0x00: clientbound_login_disconnect_packet::ClientboundLoginDisconnectPacket,
@ -24,5 +27,6 @@ declare_state_packets!(
0x02: clientbound_game_profile_packet::ClientboundGameProfilePacket, 0x02: clientbound_game_profile_packet::ClientboundGameProfilePacket,
0x03: clientbound_login_compression_packet::ClientboundLoginCompressionPacket, 0x03: clientbound_login_compression_packet::ClientboundLoginCompressionPacket,
0x04: clientbound_custom_query_packet::ClientboundCustomQueryPacket, 0x04: clientbound_custom_query_packet::ClientboundCustomQueryPacket,
0x05: clientbound_cookie_request_packet::ClientboundCookieRequestPacket,
} }
); );

View file

@ -0,0 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ServerboundLoginPacket;
#[derive(Clone, Debug, McBuf, ServerboundLoginPacket)]
pub struct ServerboundCookieResponsePacket {
pub key: ResourceLocation,
pub payload: Option<Vec<u8>>,
}

View file

@ -12,7 +12,7 @@ use std::io::{Cursor, Write};
// TODO: rename the packet files to just like clientbound_add_entity instead of // TODO: rename the packet files to just like clientbound_add_entity instead of
// clientbound_add_entity_packet // clientbound_add_entity_packet
pub const PROTOCOL_VERSION: i32 = 765; pub const PROTOCOL_VERSION: i32 = 766;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ConnectionProtocol { pub enum ConnectionProtocol {

View file

@ -0,0 +1,74 @@
//! These registries are sent by the server during the configuration state so
//! you should be relying on those if possible, but these are provided for your
//! convenience anyways.
use crate::Registry;
use azalea_registry_macros::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",
}
}
#[allow(clippy::derivable_impls)]
impl Default for WolfVariant {
fn default() -> Self {
WolfVariant::Pale
}
}
registry! {
enum DimensionType {
Overworld => "minecraft:overworld",
Nether => "minecraft:the_nether",
End => "minecraft:the_end",
OverworldCaves => "minecraft:overworld_caves",
}
}
registry! {
enum TrimMaterial {
Quartz => "minecraft:quartz",
Iron => "minecraft:iron",
Netherite => "minecraft:netherite",
Redstone => "minecraft:redstone",
Copper => "minecraft:copper",
Gold => "minecraft:gold",
Emerald => "minecraft:emerald",
Diamond => "minecraft:diamond",
Lapis => "minecraft:lapis",
Amethyst => "minecraft:amethyst",
}
}
registry! {
enum TrimPattern {
Sentry => "sentry",
Dune => "dune",
Coast => "coast",
Wild => "wild",
Ward => "ward",
Eye => "eye",
Vex => "vex",
Tide => "tide",
Snout => "snout",
Rib => "rib",
Spire => "spire",
Wayfinder => "wayfinder",
Shaper => "shaper",
Silence => "silence",
Raiser => "raiser",
Host => "host",
Flow => "flow",
Bolt => "bolt",
}
}

View file

@ -5,6 +5,7 @@
// auto-generated (so you can add doc comments to the registry enums if you // auto-generated (so you can add doc comments to the registry enums if you
// want) // want)
mod extra;
pub mod tags; pub mod tags;
use std::io::{Cursor, Write}; use std::io::{Cursor, Write};
@ -12,7 +13,9 @@ use std::io::{Cursor, Write};
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
use azalea_registry_macros::registry; use azalea_registry_macros::registry;
pub trait Registry pub use extra::*;
pub trait Registry: McBufReadable + McBufWritable
where where
Self: Sized, Self: Sized,
{ {
@ -77,6 +80,58 @@ impl<D: Registry, C: McBufReadable + McBufWritable> McBufWritable for CustomRegi
} }
} }
#[derive(Clone, PartialEq)]
pub enum HolderSet<D: Registry, ResourceLocation: McBufReadable + McBufWritable> {
Direct {
contents: Vec<D>,
},
Named {
key: ResourceLocation,
contents: Vec<ResourceLocation>,
},
}
impl<D: Registry, ResourceLocation: McBufReadable + McBufWritable> McBufReadable
for HolderSet<D, ResourceLocation>
{
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let size = i32::var_read_from(buf)? - 1;
if size == -1 {
let key = ResourceLocation::read_from(buf)?;
Ok(Self::Named {
key,
contents: Vec::new(),
})
} else {
let mut contents = Vec::new();
for _ in 0..size {
contents.push(D::read_from(buf)?);
}
Ok(Self::Direct { contents })
}
}
}
impl<D: Registry, ResourceLocation: McBufReadable + McBufWritable> McBufWritable
for HolderSet<D, ResourceLocation>
{
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
match self {
Self::Direct { contents } => {
(contents.len() as i32 + 1).var_write_into(buf)?;
for item in contents {
item.write_into(buf)?;
}
}
Self::Named { key, .. } => {
0i32.var_write_into(buf)?;
key.write_into(buf)?;
}
}
Ok(())
}
}
registry! { registry! {
/// The AI code that's currently being executed for the entity. /// The AI code that's currently being executed for the entity.
enum Activity { enum Activity {
@ -116,15 +171,23 @@ enum Attribute {
GenericAttackDamage => "minecraft:generic.attack_damage", GenericAttackDamage => "minecraft:generic.attack_damage",
GenericAttackKnockback => "minecraft:generic.attack_knockback", GenericAttackKnockback => "minecraft:generic.attack_knockback",
GenericAttackSpeed => "minecraft:generic.attack_speed", GenericAttackSpeed => "minecraft:generic.attack_speed",
PlayerBlockBreakSpeed => "minecraft:player.block_break_speed",
PlayerBlockInteractionRange => "minecraft:player.block_interaction_range",
PlayerEntityInteractionRange => "minecraft:player.entity_interaction_range",
GenericFallDamageMultiplier => "minecraft:generic.fall_damage_multiplier",
GenericFlyingSpeed => "minecraft:generic.flying_speed", GenericFlyingSpeed => "minecraft:generic.flying_speed",
GenericFollowRange => "minecraft:generic.follow_range", GenericFollowRange => "minecraft:generic.follow_range",
HorseJumpStrength => "minecraft:horse.jump_strength", GenericGravity => "minecraft:generic.gravity",
GenericJumpStrength => "minecraft:generic.jump_strength",
GenericKnockbackResistance => "minecraft:generic.knockback_resistance", GenericKnockbackResistance => "minecraft:generic.knockback_resistance",
GenericLuck => "minecraft:generic.luck", GenericLuck => "minecraft:generic.luck",
GenericMaxAbsorption => "minecraft:generic.max_absorption", GenericMaxAbsorption => "minecraft:generic.max_absorption",
GenericMaxHealth => "minecraft:generic.max_health", GenericMaxHealth => "minecraft:generic.max_health",
GenericMovementSpeed => "minecraft:generic.movement_speed", GenericMovementSpeed => "minecraft:generic.movement_speed",
GenericSafeFallDistance => "minecraft:generic.safe_fall_distance",
GenericScale => "minecraft:generic.scale",
ZombieSpawnReinforcements => "minecraft:zombie.spawn_reinforcements", ZombieSpawnReinforcements => "minecraft:zombie.spawn_reinforcements",
GenericStepHeight => "minecraft:generic.step_height",
} }
} }
@ -1239,6 +1302,8 @@ enum Block {
DecoratedPot => "minecraft:decorated_pot", DecoratedPot => "minecraft:decorated_pot",
Crafter => "minecraft:crafter", Crafter => "minecraft:crafter",
TrialSpawner => "minecraft:trial_spawner", TrialSpawner => "minecraft:trial_spawner",
Vault => "minecraft:vault",
HeavyCore => "minecraft:heavy_core",
} }
} }
@ -1290,6 +1355,7 @@ enum BlockEntityKind {
DecoratedPot => "minecraft:decorated_pot", DecoratedPot => "minecraft:decorated_pot",
Crafter => "minecraft:crafter", Crafter => "minecraft:crafter",
TrialSpawner => "minecraft:trial_spawner", TrialSpawner => "minecraft:trial_spawner",
Vault => "minecraft:vault",
} }
} }
@ -1379,6 +1445,7 @@ enum CommandArgumentKind {
Swizzle => "minecraft:swizzle", Swizzle => "minecraft:swizzle",
Team => "minecraft:team", Team => "minecraft:team",
ItemSlot => "minecraft:item_slot", ItemSlot => "minecraft:item_slot",
ItemSlots => "minecraft:item_slots",
ResourceLocation => "minecraft:resource_location", ResourceLocation => "minecraft:resource_location",
Function => "minecraft:function", Function => "minecraft:function",
EntityAnchor => "minecraft:entity_anchor", EntityAnchor => "minecraft:entity_anchor",
@ -1394,6 +1461,9 @@ enum CommandArgumentKind {
TemplateMirror => "minecraft:template_mirror", TemplateMirror => "minecraft:template_mirror",
TemplateRotation => "minecraft:template_rotation", TemplateRotation => "minecraft:template_rotation",
Heightmap => "minecraft:heightmap", Heightmap => "minecraft:heightmap",
LootTable => "minecraft:loot_table",
LootPredicate => "minecraft:loot_predicate",
LootModifier => "minecraft:loot_modifier",
Uuid => "minecraft:uuid", Uuid => "minecraft:uuid",
} }
} }
@ -1499,7 +1569,7 @@ enum Enchantment {
Knockback => "minecraft:knockback", Knockback => "minecraft:knockback",
FireAspect => "minecraft:fire_aspect", FireAspect => "minecraft:fire_aspect",
Looting => "minecraft:looting", Looting => "minecraft:looting",
Sweeping => "minecraft:sweeping", SweepingEdge => "minecraft:sweeping_edge",
Efficiency => "minecraft:efficiency", Efficiency => "minecraft:efficiency",
SilkTouch => "minecraft:silk_touch", SilkTouch => "minecraft:silk_touch",
Unbreaking => "minecraft:unbreaking", Unbreaking => "minecraft:unbreaking",
@ -1517,6 +1587,9 @@ enum Enchantment {
Multishot => "minecraft:multishot", Multishot => "minecraft:multishot",
QuickCharge => "minecraft:quick_charge", QuickCharge => "minecraft:quick_charge",
Piercing => "minecraft:piercing", Piercing => "minecraft:piercing",
Density => "minecraft:density",
Breach => "minecraft:breach",
WindBurst => "minecraft:wind_burst",
Mending => "minecraft:mending", Mending => "minecraft:mending",
VanishingCurse => "minecraft:vanishing_curse", VanishingCurse => "minecraft:vanishing_curse",
} }
@ -1527,6 +1600,7 @@ registry! {
enum EntityKind { enum EntityKind {
Allay => "minecraft:allay", Allay => "minecraft:allay",
AreaEffectCloud => "minecraft:area_effect_cloud", AreaEffectCloud => "minecraft:area_effect_cloud",
Armadillo => "minecraft:armadillo",
ArmorStand => "minecraft:armor_stand", ArmorStand => "minecraft:armor_stand",
Arrow => "minecraft:arrow", Arrow => "minecraft:arrow",
Axolotl => "minecraft:axolotl", Axolotl => "minecraft:axolotl",
@ -1535,7 +1609,9 @@ enum EntityKind {
Blaze => "minecraft:blaze", Blaze => "minecraft:blaze",
BlockDisplay => "minecraft:block_display", BlockDisplay => "minecraft:block_display",
Boat => "minecraft:boat", Boat => "minecraft:boat",
Bogged => "minecraft:bogged",
Breeze => "minecraft:breeze", Breeze => "minecraft:breeze",
BreezeWindCharge => "minecraft:breeze_wind_charge",
Camel => "minecraft:camel", Camel => "minecraft:camel",
Cat => "minecraft:cat", Cat => "minecraft:cat",
CaveSpider => "minecraft:cave_spider", CaveSpider => "minecraft:cave_spider",
@ -1583,6 +1659,7 @@ enum EntityKind {
Item => "minecraft:item", Item => "minecraft:item",
ItemDisplay => "minecraft:item_display", ItemDisplay => "minecraft:item_display",
ItemFrame => "minecraft:item_frame", ItemFrame => "minecraft:item_frame",
OminousItemSpawner => "minecraft:ominous_item_spawner",
Fireball => "minecraft:fireball", Fireball => "minecraft:fireball",
LeashKnot => "minecraft:leash_knot", LeashKnot => "minecraft:leash_knot",
LightningBolt => "minecraft:lightning_bolt", LightningBolt => "minecraft:lightning_bolt",
@ -1868,6 +1945,7 @@ enum Item {
RawIronBlock => "minecraft:raw_iron_block", RawIronBlock => "minecraft:raw_iron_block",
RawCopperBlock => "minecraft:raw_copper_block", RawCopperBlock => "minecraft:raw_copper_block",
RawGoldBlock => "minecraft:raw_gold_block", RawGoldBlock => "minecraft:raw_gold_block",
HeavyCore => "minecraft:heavy_core",
AmethystBlock => "minecraft:amethyst_block", AmethystBlock => "minecraft:amethyst_block",
BuddingAmethyst => "minecraft:budding_amethyst", BuddingAmethyst => "minecraft:budding_amethyst",
IronBlock => "minecraft:iron_block", IronBlock => "minecraft:iron_block",
@ -2577,7 +2655,9 @@ enum Item {
StructureBlock => "minecraft:structure_block", StructureBlock => "minecraft:structure_block",
Jigsaw => "minecraft:jigsaw", Jigsaw => "minecraft:jigsaw",
TurtleHelmet => "minecraft:turtle_helmet", TurtleHelmet => "minecraft:turtle_helmet",
Scute => "minecraft:scute", TurtleScute => "minecraft:turtle_scute",
ArmadilloScute => "minecraft:armadillo_scute",
WolfArmor => "minecraft:wolf_armor",
FlintAndSteel => "minecraft:flint_and_steel", FlintAndSteel => "minecraft:flint_and_steel",
Apple => "minecraft:apple", Apple => "minecraft:apple",
Bow => "minecraft:bow", Bow => "minecraft:bow",
@ -2788,11 +2868,13 @@ enum Item {
Cauldron => "minecraft:cauldron", Cauldron => "minecraft:cauldron",
EnderEye => "minecraft:ender_eye", EnderEye => "minecraft:ender_eye",
GlisteringMelonSlice => "minecraft:glistering_melon_slice", GlisteringMelonSlice => "minecraft:glistering_melon_slice",
ArmadilloSpawnEgg => "minecraft:armadillo_spawn_egg",
AllaySpawnEgg => "minecraft:allay_spawn_egg", AllaySpawnEgg => "minecraft:allay_spawn_egg",
AxolotlSpawnEgg => "minecraft:axolotl_spawn_egg", AxolotlSpawnEgg => "minecraft:axolotl_spawn_egg",
BatSpawnEgg => "minecraft:bat_spawn_egg", BatSpawnEgg => "minecraft:bat_spawn_egg",
BeeSpawnEgg => "minecraft:bee_spawn_egg", BeeSpawnEgg => "minecraft:bee_spawn_egg",
BlazeSpawnEgg => "minecraft:blaze_spawn_egg", BlazeSpawnEgg => "minecraft:blaze_spawn_egg",
BoggedSpawnEgg => "minecraft:bogged_spawn_egg",
BreezeSpawnEgg => "minecraft:breeze_spawn_egg", BreezeSpawnEgg => "minecraft:breeze_spawn_egg",
CatSpawnEgg => "minecraft:cat_spawn_egg", CatSpawnEgg => "minecraft:cat_spawn_egg",
CamelSpawnEgg => "minecraft:camel_spawn_egg", CamelSpawnEgg => "minecraft:camel_spawn_egg",
@ -2868,8 +2950,10 @@ enum Item {
ZombifiedPiglinSpawnEgg => "minecraft:zombified_piglin_spawn_egg", ZombifiedPiglinSpawnEgg => "minecraft:zombified_piglin_spawn_egg",
ExperienceBottle => "minecraft:experience_bottle", ExperienceBottle => "minecraft:experience_bottle",
FireCharge => "minecraft:fire_charge", FireCharge => "minecraft:fire_charge",
WindCharge => "minecraft:wind_charge",
WritableBook => "minecraft:writable_book", WritableBook => "minecraft:writable_book",
WrittenBook => "minecraft:written_book", WrittenBook => "minecraft:written_book",
Mace => "minecraft:mace",
ItemFrame => "minecraft:item_frame", ItemFrame => "minecraft:item_frame",
GlowItemFrame => "minecraft:glow_item_frame", GlowItemFrame => "minecraft:glow_item_frame",
FlowerPot => "minecraft:flower_pot", FlowerPot => "minecraft:flower_pot",
@ -2974,6 +3058,8 @@ enum Item {
MojangBannerPattern => "minecraft:mojang_banner_pattern", MojangBannerPattern => "minecraft:mojang_banner_pattern",
GlobeBannerPattern => "minecraft:globe_banner_pattern", GlobeBannerPattern => "minecraft:globe_banner_pattern",
PiglinBannerPattern => "minecraft:piglin_banner_pattern", PiglinBannerPattern => "minecraft:piglin_banner_pattern",
FlowBannerPattern => "minecraft:flow_banner_pattern",
GusterBannerPattern => "minecraft:guster_banner_pattern",
GoatHorn => "minecraft:goat_horn", GoatHorn => "minecraft:goat_horn",
Composter => "minecraft:composter", Composter => "minecraft:composter",
Barrel => "minecraft:barrel", Barrel => "minecraft:barrel",
@ -3057,6 +3143,8 @@ enum Item {
SilenceArmorTrimSmithingTemplate => "minecraft:silence_armor_trim_smithing_template", SilenceArmorTrimSmithingTemplate => "minecraft:silence_armor_trim_smithing_template",
RaiserArmorTrimSmithingTemplate => "minecraft:raiser_armor_trim_smithing_template", RaiserArmorTrimSmithingTemplate => "minecraft:raiser_armor_trim_smithing_template",
HostArmorTrimSmithingTemplate => "minecraft:host_armor_trim_smithing_template", HostArmorTrimSmithingTemplate => "minecraft:host_armor_trim_smithing_template",
FlowArmorTrimSmithingTemplate => "minecraft:flow_armor_trim_smithing_template",
BoltArmorTrimSmithingTemplate => "minecraft:bolt_armor_trim_smithing_template",
AnglerPotterySherd => "minecraft:angler_pottery_sherd", AnglerPotterySherd => "minecraft:angler_pottery_sherd",
ArcherPotterySherd => "minecraft:archer_pottery_sherd", ArcherPotterySherd => "minecraft:archer_pottery_sherd",
ArmsUpPotterySherd => "minecraft:arms_up_pottery_sherd", ArmsUpPotterySherd => "minecraft:arms_up_pottery_sherd",
@ -3065,7 +3153,9 @@ enum Item {
BurnPotterySherd => "minecraft:burn_pottery_sherd", BurnPotterySherd => "minecraft:burn_pottery_sherd",
DangerPotterySherd => "minecraft:danger_pottery_sherd", DangerPotterySherd => "minecraft:danger_pottery_sherd",
ExplorerPotterySherd => "minecraft:explorer_pottery_sherd", ExplorerPotterySherd => "minecraft:explorer_pottery_sherd",
FlowPotterySherd => "minecraft:flow_pottery_sherd",
FriendPotterySherd => "minecraft:friend_pottery_sherd", FriendPotterySherd => "minecraft:friend_pottery_sherd",
GusterPotterySherd => "minecraft:guster_pottery_sherd",
HeartPotterySherd => "minecraft:heart_pottery_sherd", HeartPotterySherd => "minecraft:heart_pottery_sherd",
HeartbreakPotterySherd => "minecraft:heartbreak_pottery_sherd", HeartbreakPotterySherd => "minecraft:heartbreak_pottery_sherd",
HowlPotterySherd => "minecraft:howl_pottery_sherd", HowlPotterySherd => "minecraft:howl_pottery_sherd",
@ -3073,6 +3163,7 @@ enum Item {
MournerPotterySherd => "minecraft:mourner_pottery_sherd", MournerPotterySherd => "minecraft:mourner_pottery_sherd",
PlentyPotterySherd => "minecraft:plenty_pottery_sherd", PlentyPotterySherd => "minecraft:plenty_pottery_sherd",
PrizePotterySherd => "minecraft:prize_pottery_sherd", PrizePotterySherd => "minecraft:prize_pottery_sherd",
ScrapePotterySherd => "minecraft:scrape_pottery_sherd",
SheafPotterySherd => "minecraft:sheaf_pottery_sherd", SheafPotterySherd => "minecraft:sheaf_pottery_sherd",
ShelterPotterySherd => "minecraft:shelter_pottery_sherd", ShelterPotterySherd => "minecraft:shelter_pottery_sherd",
SkullPotterySherd => "minecraft:skull_pottery_sherd", SkullPotterySherd => "minecraft:skull_pottery_sherd",
@ -3095,6 +3186,10 @@ enum Item {
WaxedOxidizedCopperBulb => "minecraft:waxed_oxidized_copper_bulb", WaxedOxidizedCopperBulb => "minecraft:waxed_oxidized_copper_bulb",
TrialSpawner => "minecraft:trial_spawner", TrialSpawner => "minecraft:trial_spawner",
TrialKey => "minecraft:trial_key", TrialKey => "minecraft:trial_key",
OminousTrialKey => "minecraft:ominous_trial_key",
Vault => "minecraft:vault",
OminousBottle => "minecraft:ominous_bottle",
BreezeRod => "minecraft:breeze_rod",
} }
} }
@ -3124,10 +3219,12 @@ enum LootConditionKind {
registry! { registry! {
enum LootFunctionKind { enum LootFunctionKind {
SetCount => "minecraft:set_count", SetCount => "minecraft:set_count",
SetItem => "minecraft:set_item",
EnchantWithLevels => "minecraft:enchant_with_levels", EnchantWithLevels => "minecraft:enchant_with_levels",
EnchantRandomly => "minecraft:enchant_randomly", EnchantRandomly => "minecraft:enchant_randomly",
SetEnchantments => "minecraft:set_enchantments", SetEnchantments => "minecraft:set_enchantments",
SetNbt => "minecraft:set_nbt", SetCustomData => "minecraft:set_custom_data",
SetComponents => "minecraft:set_components",
FurnaceSmelt => "minecraft:furnace_smelt", FurnaceSmelt => "minecraft:furnace_smelt",
LootingEnchant => "minecraft:looting_enchant", LootingEnchant => "minecraft:looting_enchant",
SetDamage => "minecraft:set_damage", SetDamage => "minecraft:set_damage",
@ -3137,19 +3234,30 @@ enum LootFunctionKind {
SetStewEffect => "minecraft:set_stew_effect", SetStewEffect => "minecraft:set_stew_effect",
CopyName => "minecraft:copy_name", CopyName => "minecraft:copy_name",
SetContents => "minecraft:set_contents", SetContents => "minecraft:set_contents",
ModifyContents => "minecraft:modify_contents",
Filtered => "minecraft:filtered",
LimitCount => "minecraft:limit_count", LimitCount => "minecraft:limit_count",
ApplyBonus => "minecraft:apply_bonus", ApplyBonus => "minecraft:apply_bonus",
SetLootTable => "minecraft:set_loot_table", SetLootTable => "minecraft:set_loot_table",
ExplosionDecay => "minecraft:explosion_decay", ExplosionDecay => "minecraft:explosion_decay",
SetLore => "minecraft:set_lore", SetLore => "minecraft:set_lore",
FillPlayerHead => "minecraft:fill_player_head", FillPlayerHead => "minecraft:fill_player_head",
CopyNbt => "minecraft:copy_nbt", CopyCustomData => "minecraft:copy_custom_data",
CopyState => "minecraft:copy_state", CopyState => "minecraft:copy_state",
SetBannerPattern => "minecraft:set_banner_pattern", SetBannerPattern => "minecraft:set_banner_pattern",
SetPotion => "minecraft:set_potion", SetPotion => "minecraft:set_potion",
SetInstrument => "minecraft:set_instrument", SetInstrument => "minecraft:set_instrument",
Reference => "minecraft:reference", Reference => "minecraft:reference",
Sequence => "minecraft:sequence", Sequence => "minecraft:sequence",
CopyComponents => "minecraft:copy_components",
SetFireworks => "minecraft:set_fireworks",
SetFireworkExplosion => "minecraft:set_firework_explosion",
SetBookCover => "minecraft:set_book_cover",
SetWrittenBookPages => "minecraft:set_written_book_pages",
SetWritableBookPages => "minecraft:set_writable_book_pages",
ToggleTooltips => "minecraft:toggle_tooltips",
SetOminousBottleAmplifier => "minecraft:set_ominous_bottle_amplifier",
SetCustomModelData => "minecraft:set_custom_model_data",
} }
} }
@ -3166,6 +3274,7 @@ enum LootNumberProviderKind {
Uniform => "minecraft:uniform", Uniform => "minecraft:uniform",
Binomial => "minecraft:binomial", Binomial => "minecraft:binomial",
Score => "minecraft:score", Score => "minecraft:score",
Storage => "minecraft:storage",
} }
} }
@ -3223,6 +3332,7 @@ enum MemoryModuleKind {
HeardBellTime => "minecraft:heard_bell_time", HeardBellTime => "minecraft:heard_bell_time",
CantReachWalkTargetSince => "minecraft:cant_reach_walk_target_since", CantReachWalkTargetSince => "minecraft:cant_reach_walk_target_since",
GolemDetectedRecently => "minecraft:golem_detected_recently", GolemDetectedRecently => "minecraft:golem_detected_recently",
DangerDetectedRecently => "minecraft:danger_detected_recently",
LastSlept => "minecraft:last_slept", LastSlept => "minecraft:last_slept",
LastWoken => "minecraft:last_woken", LastWoken => "minecraft:last_woken",
LastWorkedAtPoi => "minecraft:last_worked_at_poi", LastWorkedAtPoi => "minecraft:last_worked_at_poi",
@ -3295,6 +3405,7 @@ enum MemoryModuleKind {
BreezeShootCooldown => "minecraft:breeze_shoot_cooldown", BreezeShootCooldown => "minecraft:breeze_shoot_cooldown",
BreezeJumpInhaling => "minecraft:breeze_jump_inhaling", BreezeJumpInhaling => "minecraft:breeze_jump_inhaling",
BreezeJumpTarget => "minecraft:breeze_jump_target", BreezeJumpTarget => "minecraft:breeze_jump_target",
BreezeLeavingWater => "minecraft:breeze_leaving_water",
} }
} }
@ -3362,6 +3473,12 @@ enum MobEffect {
BadOmen => "minecraft:bad_omen", BadOmen => "minecraft:bad_omen",
HeroOfTheVillage => "minecraft:hero_of_the_village", HeroOfTheVillage => "minecraft:hero_of_the_village",
Darkness => "minecraft:darkness", Darkness => "minecraft:darkness",
TrialOmen => "minecraft:trial_omen",
RaidOmen => "minecraft:raid_omen",
WindCharged => "minecraft:wind_charged",
Weaving => "minecraft:weaving",
Oozing => "minecraft:oozing",
Infested => "minecraft:infested",
} }
} }
@ -3402,7 +3519,6 @@ enum PaintingVariant {
registry! { registry! {
enum ParticleKind { enum ParticleKind {
AmbientEntityEffect => "minecraft:ambient_entity_effect",
AngryVillager => "minecraft:angry_villager", AngryVillager => "minecraft:angry_villager",
Block => "minecraft:block", Block => "minecraft:block",
BlockMarker => "minecraft:block_marker", BlockMarker => "minecraft:block_marker",
@ -3427,12 +3543,15 @@ enum ParticleKind {
ExplosionEmitter => "minecraft:explosion_emitter", ExplosionEmitter => "minecraft:explosion_emitter",
Explosion => "minecraft:explosion", Explosion => "minecraft:explosion",
Gust => "minecraft:gust", Gust => "minecraft:gust",
GustEmitter => "minecraft:gust_emitter", SmallGust => "minecraft:small_gust",
GustEmitterLarge => "minecraft:gust_emitter_large",
GustEmitterSmall => "minecraft:gust_emitter_small",
SonicBoom => "minecraft:sonic_boom", SonicBoom => "minecraft:sonic_boom",
FallingDust => "minecraft:falling_dust", FallingDust => "minecraft:falling_dust",
Firework => "minecraft:firework", Firework => "minecraft:firework",
Fishing => "minecraft:fishing", Fishing => "minecraft:fishing",
Flame => "minecraft:flame", Flame => "minecraft:flame",
Infested => "minecraft:infested",
CherryLeaves => "minecraft:cherry_leaves", CherryLeaves => "minecraft:cherry_leaves",
SculkSoul => "minecraft:sculk_soul", SculkSoul => "minecraft:sculk_soul",
SculkCharge => "minecraft:sculk_charge", SculkCharge => "minecraft:sculk_charge",
@ -3447,6 +3566,7 @@ enum ParticleKind {
Item => "minecraft:item", Item => "minecraft:item",
Vibration => "minecraft:vibration", Vibration => "minecraft:vibration",
ItemSlime => "minecraft:item_slime", ItemSlime => "minecraft:item_slime",
ItemCobweb => "minecraft:item_cobweb",
ItemSnowball => "minecraft:item_snowball", ItemSnowball => "minecraft:item_snowball",
LargeSmoke => "minecraft:large_smoke", LargeSmoke => "minecraft:large_smoke",
Lava => "minecraft:lava", Lava => "minecraft:lava",
@ -3501,8 +3621,13 @@ enum ParticleKind {
Shriek => "minecraft:shriek", Shriek => "minecraft:shriek",
EggCrack => "minecraft:egg_crack", EggCrack => "minecraft:egg_crack",
DustPlume => "minecraft:dust_plume", DustPlume => "minecraft:dust_plume",
GustDust => "minecraft:gust_dust",
TrialSpawnerDetection => "minecraft:trial_spawner_detection", TrialSpawnerDetection => "minecraft:trial_spawner_detection",
TrialSpawnerDetectionOminous => "minecraft:trial_spawner_detection_ominous",
VaultConnection => "minecraft:vault_connection",
DustPillar => "minecraft:dust_pillar",
OminousSpawning => "minecraft:ominous_spawning",
RaidOmen => "minecraft:raid_omen",
TrialOmen => "minecraft:trial_omen",
} }
} }
@ -3548,7 +3673,6 @@ enum PositionSourceKind {
registry! { registry! {
enum Potion { enum Potion {
Empty => "minecraft:empty",
Water => "minecraft:water", Water => "minecraft:water",
Mundane => "minecraft:mundane", Mundane => "minecraft:mundane",
Thick => "minecraft:thick", Thick => "minecraft:thick",
@ -3591,6 +3715,10 @@ enum Potion {
Luck => "minecraft:luck", Luck => "minecraft:luck",
SlowFalling => "minecraft:slow_falling", SlowFalling => "minecraft:slow_falling",
LongSlowFalling => "minecraft:long_slow_falling", LongSlowFalling => "minecraft:long_slow_falling",
WindCharged => "minecraft:wind_charged",
Weaving => "minecraft:weaving",
Oozing => "minecraft:oozing",
Infested => "minecraft:infested",
} }
} }
@ -3666,6 +3794,7 @@ enum SensorKind {
VillagerBabies => "minecraft:villager_babies", VillagerBabies => "minecraft:villager_babies",
SecondaryPois => "minecraft:secondary_pois", SecondaryPois => "minecraft:secondary_pois",
GolemDetected => "minecraft:golem_detected", GolemDetected => "minecraft:golem_detected",
ArmadilloScareDetected => "minecraft:armadillo_scare_detected",
PiglinSpecificSensor => "minecraft:piglin_specific_sensor", PiglinSpecificSensor => "minecraft:piglin_specific_sensor",
PiglinBruteSpecificSensor => "minecraft:piglin_brute_specific_sensor", PiglinBruteSpecificSensor => "minecraft:piglin_brute_specific_sensor",
HoglinSpecificSensor => "minecraft:hoglin_specific_sensor", HoglinSpecificSensor => "minecraft:hoglin_specific_sensor",
@ -3675,6 +3804,7 @@ enum SensorKind {
GoatTemptations => "minecraft:goat_temptations", GoatTemptations => "minecraft:goat_temptations",
FrogTemptations => "minecraft:frog_temptations", FrogTemptations => "minecraft:frog_temptations",
CamelTemptations => "minecraft:camel_temptations", CamelTemptations => "minecraft:camel_temptations",
ArmadilloTemptations => "minecraft:armadillo_temptations",
FrogAttackables => "minecraft:frog_attackables", FrogAttackables => "minecraft:frog_attackables",
IsInWater => "minecraft:is_in_water", IsInWater => "minecraft:is_in_water",
WardenEntitySensor => "minecraft:warden_entity_sensor", WardenEntitySensor => "minecraft:warden_entity_sensor",
@ -3739,6 +3869,19 @@ enum SoundEvent {
BlockAnvilPlace => "minecraft:block.anvil.place", BlockAnvilPlace => "minecraft:block.anvil.place",
BlockAnvilStep => "minecraft:block.anvil.step", BlockAnvilStep => "minecraft:block.anvil.step",
BlockAnvilUse => "minecraft:block.anvil.use", BlockAnvilUse => "minecraft:block.anvil.use",
EntityArmadilloEat => "minecraft:entity.armadillo.eat",
EntityArmadilloHurt => "minecraft:entity.armadillo.hurt",
EntityArmadilloHurtReduced => "minecraft:entity.armadillo.hurt_reduced",
EntityArmadilloAmbient => "minecraft:entity.armadillo.ambient",
EntityArmadilloStep => "minecraft:entity.armadillo.step",
EntityArmadilloDeath => "minecraft:entity.armadillo.death",
EntityArmadilloRoll => "minecraft:entity.armadillo.roll",
EntityArmadilloLand => "minecraft:entity.armadillo.land",
EntityArmadilloScuteDrop => "minecraft:entity.armadillo.scute_drop",
EntityArmadilloUnrollFinish => "minecraft:entity.armadillo.unroll_finish",
EntityArmadilloPeek => "minecraft:entity.armadillo.peek",
EntityArmadilloUnrollStart => "minecraft:entity.armadillo.unroll_start",
EntityArmadilloBrush => "minecraft:entity.armadillo.brush",
ItemArmorEquipChain => "minecraft:item.armor.equip_chain", ItemArmorEquipChain => "minecraft:item.armor.equip_chain",
ItemArmorEquipDiamond => "minecraft:item.armor.equip_diamond", ItemArmorEquipDiamond => "minecraft:item.armor.equip_diamond",
ItemArmorEquipElytra => "minecraft:item.armor.equip_elytra", ItemArmorEquipElytra => "minecraft:item.armor.equip_elytra",
@ -3748,6 +3891,8 @@ enum SoundEvent {
ItemArmorEquipLeather => "minecraft:item.armor.equip_leather", ItemArmorEquipLeather => "minecraft:item.armor.equip_leather",
ItemArmorEquipNetherite => "minecraft:item.armor.equip_netherite", ItemArmorEquipNetherite => "minecraft:item.armor.equip_netherite",
ItemArmorEquipTurtle => "minecraft:item.armor.equip_turtle", ItemArmorEquipTurtle => "minecraft:item.armor.equip_turtle",
ItemArmorEquipWolf => "minecraft:item.armor.equip_wolf",
ItemArmorUnequipWolf => "minecraft:item.armor.unequip_wolf",
EntityArmorStandBreak => "minecraft:entity.armor_stand.break", EntityArmorStandBreak => "minecraft:entity.armor_stand.break",
EntityArmorStandFall => "minecraft:entity.armor_stand.fall", EntityArmorStandFall => "minecraft:entity.armor_stand.fall",
EntityArmorStandHit => "minecraft:entity.armor_stand.hit", EntityArmorStandHit => "minecraft:entity.armor_stand.hit",
@ -3839,6 +3984,11 @@ enum SoundEvent {
EntityBlazeShoot => "minecraft:entity.blaze.shoot", EntityBlazeShoot => "minecraft:entity.blaze.shoot",
EntityBoatPaddleLand => "minecraft:entity.boat.paddle_land", EntityBoatPaddleLand => "minecraft:entity.boat.paddle_land",
EntityBoatPaddleWater => "minecraft:entity.boat.paddle_water", EntityBoatPaddleWater => "minecraft:entity.boat.paddle_water",
EntityBoggedAmbient => "minecraft:entity.bogged.ambient",
EntityBoggedDeath => "minecraft:entity.bogged.death",
EntityBoggedHurt => "minecraft:entity.bogged.hurt",
EntityBoggedShear => "minecraft:entity.bogged.shear",
EntityBoggedStep => "minecraft:entity.bogged.step",
BlockBoneBlockBreak => "minecraft:block.bone_block.break", BlockBoneBlockBreak => "minecraft:block.bone_block.break",
BlockBoneBlockFall => "minecraft:block.bone_block.fall", BlockBoneBlockFall => "minecraft:block.bone_block.fall",
BlockBoneBlockHit => "minecraft:block.bone_block.hit", BlockBoneBlockHit => "minecraft:block.bone_block.hit",
@ -3851,6 +4001,8 @@ enum SoundEvent {
ItemBottleEmpty => "minecraft:item.bottle.empty", ItemBottleEmpty => "minecraft:item.bottle.empty",
ItemBottleFill => "minecraft:item.bottle.fill", ItemBottleFill => "minecraft:item.bottle.fill",
ItemBottleFillDragonbreath => "minecraft:item.bottle.fill_dragonbreath", ItemBottleFillDragonbreath => "minecraft:item.bottle.fill_dragonbreath",
EntityBreezeCharge => "minecraft:entity.breeze.charge",
EntityBreezeDeflect => "minecraft:entity.breeze.deflect",
EntityBreezeInhale => "minecraft:entity.breeze.inhale", EntityBreezeInhale => "minecraft:entity.breeze.inhale",
EntityBreezeIdleGround => "minecraft:entity.breeze.idle_ground", EntityBreezeIdleGround => "minecraft:entity.breeze.idle_ground",
EntityBreezeIdleAir => "minecraft:entity.breeze.idle_air", EntityBreezeIdleAir => "minecraft:entity.breeze.idle_air",
@ -3860,6 +4012,8 @@ enum SoundEvent {
EntityBreezeSlide => "minecraft:entity.breeze.slide", EntityBreezeSlide => "minecraft:entity.breeze.slide",
EntityBreezeDeath => "minecraft:entity.breeze.death", EntityBreezeDeath => "minecraft:entity.breeze.death",
EntityBreezeHurt => "minecraft:entity.breeze.hurt", EntityBreezeHurt => "minecraft:entity.breeze.hurt",
EntityBreezeWhirl => "minecraft:entity.breeze.whirl",
EntityBreezeWindBurst => "minecraft:entity.breeze.wind_burst",
BlockBrewingStandBrew => "minecraft:block.brewing_stand.brew", BlockBrewingStandBrew => "minecraft:block.brewing_stand.brew",
ItemBrushBrushingGeneric => "minecraft:item.brush.brushing.generic", ItemBrushBrushingGeneric => "minecraft:item.brush.brushing.generic",
ItemBrushBrushingSand => "minecraft:item.brush.brushing.sand", ItemBrushBrushingSand => "minecraft:item.brush.brushing.sand",
@ -3981,6 +4135,11 @@ enum SoundEvent {
BlockChorusFlowerDeath => "minecraft:block.chorus_flower.death", BlockChorusFlowerDeath => "minecraft:block.chorus_flower.death",
BlockChorusFlowerGrow => "minecraft:block.chorus_flower.grow", BlockChorusFlowerGrow => "minecraft:block.chorus_flower.grow",
ItemChorusFruitTeleport => "minecraft:item.chorus_fruit.teleport", ItemChorusFruitTeleport => "minecraft:item.chorus_fruit.teleport",
BlockCobwebBreak => "minecraft:block.cobweb.break",
BlockCobwebStep => "minecraft:block.cobweb.step",
BlockCobwebPlace => "minecraft:block.cobweb.place",
BlockCobwebHit => "minecraft:block.cobweb.hit",
BlockCobwebFall => "minecraft:block.cobweb.fall",
EntityCodAmbient => "minecraft:entity.cod.ambient", EntityCodAmbient => "minecraft:entity.cod.ambient",
EntityCodDeath => "minecraft:entity.cod.death", EntityCodDeath => "minecraft:entity.cod.death",
EntityCodFlop => "minecraft:entity.cod.flop", EntityCodFlop => "minecraft:entity.cod.flop",
@ -4083,6 +4242,7 @@ enum SoundEvent {
EntityDonkeyDeath => "minecraft:entity.donkey.death", EntityDonkeyDeath => "minecraft:entity.donkey.death",
EntityDonkeyEat => "minecraft:entity.donkey.eat", EntityDonkeyEat => "minecraft:entity.donkey.eat",
EntityDonkeyHurt => "minecraft:entity.donkey.hurt", EntityDonkeyHurt => "minecraft:entity.donkey.hurt",
EntityDonkeyJump => "minecraft:entity.donkey.jump",
BlockDripstoneBlockBreak => "minecraft:block.dripstone_block.break", BlockDripstoneBlockBreak => "minecraft:block.dripstone_block.break",
BlockDripstoneBlockStep => "minecraft:block.dripstone_block.step", BlockDripstoneBlockStep => "minecraft:block.dripstone_block.step",
BlockDripstoneBlockPlace => "minecraft:block.dripstone_block.place", BlockDripstoneBlockPlace => "minecraft:block.dripstone_block.place",
@ -4313,6 +4473,11 @@ enum SoundEvent {
BlockHangingSignFall => "minecraft:block.hanging_sign.fall", BlockHangingSignFall => "minecraft:block.hanging_sign.fall",
BlockHangingSignHit => "minecraft:block.hanging_sign.hit", BlockHangingSignHit => "minecraft:block.hanging_sign.hit",
BlockHangingSignPlace => "minecraft:block.hanging_sign.place", BlockHangingSignPlace => "minecraft:block.hanging_sign.place",
BlockHeavyCoreBreak => "minecraft:block.heavy_core.break",
BlockHeavyCoreFall => "minecraft:block.heavy_core.fall",
BlockHeavyCoreHit => "minecraft:block.heavy_core.hit",
BlockHeavyCorePlace => "minecraft:block.heavy_core.place",
BlockHeavyCoreStep => "minecraft:block.heavy_core.step",
BlockNetherWoodHangingSignStep => "minecraft:block.nether_wood_hanging_sign.step", BlockNetherWoodHangingSignStep => "minecraft:block.nether_wood_hanging_sign.step",
BlockNetherWoodHangingSignBreak => "minecraft:block.nether_wood_hanging_sign.break", BlockNetherWoodHangingSignBreak => "minecraft:block.nether_wood_hanging_sign.break",
BlockNetherWoodHangingSignFall => "minecraft:block.nether_wood_hanging_sign.fall", BlockNetherWoodHangingSignFall => "minecraft:block.nether_wood_hanging_sign.fall",
@ -4329,8 +4494,13 @@ enum SoundEvent {
BlockTrialSpawnerHit => "minecraft:block.trial_spawner.hit", BlockTrialSpawnerHit => "minecraft:block.trial_spawner.hit",
BlockTrialSpawnerFall => "minecraft:block.trial_spawner.fall", BlockTrialSpawnerFall => "minecraft:block.trial_spawner.fall",
BlockTrialSpawnerSpawnMob => "minecraft:block.trial_spawner.spawn_mob", BlockTrialSpawnerSpawnMob => "minecraft:block.trial_spawner.spawn_mob",
BlockTrialSpawnerAboutToSpawnItem => "minecraft:block.trial_spawner.about_to_spawn_item",
BlockTrialSpawnerSpawnItem => "minecraft:block.trial_spawner.spawn_item",
BlockTrialSpawnerSpawnItemBegin => "minecraft:block.trial_spawner.spawn_item_begin",
BlockTrialSpawnerDetectPlayer => "minecraft:block.trial_spawner.detect_player", BlockTrialSpawnerDetectPlayer => "minecraft:block.trial_spawner.detect_player",
BlockTrialSpawnerChargeActivate => "minecraft:block.trial_spawner.charge_activate",
BlockTrialSpawnerAmbient => "minecraft:block.trial_spawner.ambient", BlockTrialSpawnerAmbient => "minecraft:block.trial_spawner.ambient",
BlockTrialSpawnerAmbientCharged => "minecraft:block.trial_spawner.ambient_charged",
BlockTrialSpawnerOpenShutter => "minecraft:block.trial_spawner.open_shutter", BlockTrialSpawnerOpenShutter => "minecraft:block.trial_spawner.open_shutter",
BlockTrialSpawnerCloseShutter => "minecraft:block.trial_spawner.close_shutter", BlockTrialSpawnerCloseShutter => "minecraft:block.trial_spawner.close_shutter",
BlockTrialSpawnerEjectItem => "minecraft:block.trial_spawner.eject_item", BlockTrialSpawnerEjectItem => "minecraft:block.trial_spawner.eject_item",
@ -4445,6 +4615,9 @@ enum SoundEvent {
BlockLodestoneHit => "minecraft:block.lodestone.hit", BlockLodestoneHit => "minecraft:block.lodestone.hit",
BlockLodestoneFall => "minecraft:block.lodestone.fall", BlockLodestoneFall => "minecraft:block.lodestone.fall",
ItemLodestoneCompassLock => "minecraft:item.lodestone_compass.lock", ItemLodestoneCompassLock => "minecraft:item.lodestone_compass.lock",
ItemMaceSmashAir => "minecraft:item.mace.smash_air",
ItemMaceSmashGround => "minecraft:item.mace.smash_ground",
ItemMaceSmashGroundHeavy => "minecraft:item.mace.smash_ground_heavy",
EntityMagmaCubeDeath => "minecraft:entity.magma_cube.death", EntityMagmaCubeDeath => "minecraft:entity.magma_cube.death",
EntityMagmaCubeHurt => "minecraft:entity.magma_cube.hurt", EntityMagmaCubeHurt => "minecraft:entity.magma_cube.hurt",
EntityMagmaCubeHurtSmall => "minecraft:entity.magma_cube.hurt_small", EntityMagmaCubeHurtSmall => "minecraft:entity.magma_cube.hurt_small",
@ -4509,6 +4682,7 @@ enum SoundEvent {
EntityMuleDeath => "minecraft:entity.mule.death", EntityMuleDeath => "minecraft:entity.mule.death",
EntityMuleEat => "minecraft:entity.mule.eat", EntityMuleEat => "minecraft:entity.mule.eat",
EntityMuleHurt => "minecraft:entity.mule.hurt", EntityMuleHurt => "minecraft:entity.mule.hurt",
EntityMuleJump => "minecraft:entity.mule.jump",
MusicCreative => "minecraft:music.creative", MusicCreative => "minecraft:music.creative",
MusicCredits => "minecraft:music.credits", MusicCredits => "minecraft:music.credits",
MusicDisc5 => "minecraft:music_disc.5", MusicDisc5 => "minecraft:music_disc.5",
@ -4649,6 +4823,7 @@ enum SoundEvent {
EntityOcelotHurt => "minecraft:entity.ocelot.hurt", EntityOcelotHurt => "minecraft:entity.ocelot.hurt",
EntityOcelotAmbient => "minecraft:entity.ocelot.ambient", EntityOcelotAmbient => "minecraft:entity.ocelot.ambient",
EntityOcelotDeath => "minecraft:entity.ocelot.death", EntityOcelotDeath => "minecraft:entity.ocelot.death",
ItemOminousBottleDispose => "minecraft:item.ominous_bottle.dispose",
EntityPaintingBreak => "minecraft:entity.painting.break", EntityPaintingBreak => "minecraft:entity.painting.break",
EntityPaintingPlace => "minecraft:entity.painting.place", EntityPaintingPlace => "minecraft:entity.painting.place",
EntityPandaPreSneeze => "minecraft:entity.panda.pre_sneeze", EntityPandaPreSneeze => "minecraft:entity.panda.pre_sneeze",
@ -4668,6 +4843,7 @@ enum SoundEvent {
EntityParrotFly => "minecraft:entity.parrot.fly", EntityParrotFly => "minecraft:entity.parrot.fly",
EntityParrotHurt => "minecraft:entity.parrot.hurt", EntityParrotHurt => "minecraft:entity.parrot.hurt",
EntityParrotImitateBlaze => "minecraft:entity.parrot.imitate.blaze", EntityParrotImitateBlaze => "minecraft:entity.parrot.imitate.blaze",
EntityParrotImitateBogged => "minecraft:entity.parrot.imitate.bogged",
EntityParrotImitateBreeze => "minecraft:entity.parrot.imitate.breeze", EntityParrotImitateBreeze => "minecraft:entity.parrot.imitate.breeze",
EntityParrotImitateCreeper => "minecraft:entity.parrot.imitate.creeper", EntityParrotImitateCreeper => "minecraft:entity.parrot.imitate.creeper",
EntityParrotImitateDrowned => "minecraft:entity.parrot.imitate.drowned", EntityParrotImitateDrowned => "minecraft:entity.parrot.imitate.drowned",
@ -5072,6 +5248,19 @@ enum SoundEvent {
UiToastChallengeComplete => "minecraft:ui.toast.challenge_complete", UiToastChallengeComplete => "minecraft:ui.toast.challenge_complete",
UiToastIn => "minecraft:ui.toast.in", UiToastIn => "minecraft:ui.toast.in",
UiToastOut => "minecraft:ui.toast.out", UiToastOut => "minecraft:ui.toast.out",
BlockVaultActivate => "minecraft:block.vault.activate",
BlockVaultAmbient => "minecraft:block.vault.ambient",
BlockVaultBreak => "minecraft:block.vault.break",
BlockVaultCloseShutter => "minecraft:block.vault.close_shutter",
BlockVaultDeactivate => "minecraft:block.vault.deactivate",
BlockVaultEjectItem => "minecraft:block.vault.eject_item",
BlockVaultFall => "minecraft:block.vault.fall",
BlockVaultHit => "minecraft:block.vault.hit",
BlockVaultInsertItem => "minecraft:block.vault.insert_item",
BlockVaultInsertItemFail => "minecraft:block.vault.insert_item_fail",
BlockVaultOpenShutter => "minecraft:block.vault.open_shutter",
BlockVaultPlace => "minecraft:block.vault.place",
BlockVaultStep => "minecraft:block.vault.step",
EntityVexAmbient => "minecraft:entity.vex.ambient", EntityVexAmbient => "minecraft:entity.vex.ambient",
EntityVexCharge => "minecraft:entity.vex.charge", EntityVexCharge => "minecraft:entity.vex.charge",
EntityVexDeath => "minecraft:entity.vex.death", EntityVexDeath => "minecraft:entity.vex.death",
@ -5147,11 +5336,13 @@ enum SoundEvent {
BlockWetGrassPlace => "minecraft:block.wet_grass.place", BlockWetGrassPlace => "minecraft:block.wet_grass.place",
BlockWetGrassStep => "minecraft:block.wet_grass.step", BlockWetGrassStep => "minecraft:block.wet_grass.step",
BlockWetSpongeBreak => "minecraft:block.wet_sponge.break", BlockWetSpongeBreak => "minecraft:block.wet_sponge.break",
BlockWetSpongeDries => "minecraft:block.wet_sponge.dries",
BlockWetSpongeFall => "minecraft:block.wet_sponge.fall", BlockWetSpongeFall => "minecraft:block.wet_sponge.fall",
BlockWetSpongeHit => "minecraft:block.wet_sponge.hit", BlockWetSpongeHit => "minecraft:block.wet_sponge.hit",
BlockWetSpongePlace => "minecraft:block.wet_sponge.place", BlockWetSpongePlace => "minecraft:block.wet_sponge.place",
BlockWetSpongeStep => "minecraft:block.wet_sponge.step", BlockWetSpongeStep => "minecraft:block.wet_sponge.step",
EntityGenericWindBurst => "minecraft:entity.generic.wind_burst", EntityWindChargeWindBurst => "minecraft:entity.wind_charge.wind_burst",
EntityWindChargeThrow => "minecraft:entity.wind_charge.throw",
EntityWitchAmbient => "minecraft:entity.witch.ambient", EntityWitchAmbient => "minecraft:entity.witch.ambient",
EntityWitchCelebrate => "minecraft:entity.witch.celebrate", EntityWitchCelebrate => "minecraft:entity.witch.celebrate",
EntityWitchDeath => "minecraft:entity.witch.death", EntityWitchDeath => "minecraft:entity.witch.death",
@ -5168,6 +5359,10 @@ enum SoundEvent {
EntityWitherSkeletonHurt => "minecraft:entity.wither_skeleton.hurt", EntityWitherSkeletonHurt => "minecraft:entity.wither_skeleton.hurt",
EntityWitherSkeletonStep => "minecraft:entity.wither_skeleton.step", EntityWitherSkeletonStep => "minecraft:entity.wither_skeleton.step",
EntityWitherSpawn => "minecraft:entity.wither.spawn", EntityWitherSpawn => "minecraft:entity.wither.spawn",
ItemWolfArmorBreak => "minecraft:item.wolf_armor.break",
ItemWolfArmorCrack => "minecraft:item.wolf_armor.crack",
ItemWolfArmorDamage => "minecraft:item.wolf_armor.damage",
ItemWolfArmorRepair => "minecraft:item.wolf_armor.repair",
EntityWolfAmbient => "minecraft:entity.wolf.ambient", EntityWolfAmbient => "minecraft:entity.wolf.ambient",
EntityWolfDeath => "minecraft:entity.wolf.death", EntityWolfDeath => "minecraft:entity.wolf.death",
EntityWolfGrowl => "minecraft:entity.wolf.growl", EntityWolfGrowl => "minecraft:entity.wolf.growl",
@ -5224,6 +5419,9 @@ enum SoundEvent {
EntityZombieVillagerDeath => "minecraft:entity.zombie_villager.death", EntityZombieVillagerDeath => "minecraft:entity.zombie_villager.death",
EntityZombieVillagerHurt => "minecraft:entity.zombie_villager.hurt", EntityZombieVillagerHurt => "minecraft:entity.zombie_villager.hurt",
EntityZombieVillagerStep => "minecraft:entity.zombie_villager.step", EntityZombieVillagerStep => "minecraft:entity.zombie_villager.step",
EventMobEffectBadOmen => "minecraft:event.mob_effect.bad_omen",
EventMobEffectTrialOmen => "minecraft:event.mob_effect.trial_omen",
EventMobEffectRaidOmen => "minecraft:event.mob_effect.raid_omen",
} }
} }
@ -5638,7 +5836,9 @@ enum DecoratedPotPatterns {
BurnPotteryPattern => "minecraft:burn_pottery_pattern", BurnPotteryPattern => "minecraft:burn_pottery_pattern",
DangerPotteryPattern => "minecraft:danger_pottery_pattern", DangerPotteryPattern => "minecraft:danger_pottery_pattern",
ExplorerPotteryPattern => "minecraft:explorer_pottery_pattern", ExplorerPotteryPattern => "minecraft:explorer_pottery_pattern",
FlowPotteryPattern => "minecraft:flow_pottery_pattern",
FriendPotteryPattern => "minecraft:friend_pottery_pattern", FriendPotteryPattern => "minecraft:friend_pottery_pattern",
GusterPotteryPattern => "minecraft:guster_pottery_pattern",
HeartPotteryPattern => "minecraft:heart_pottery_pattern", HeartPotteryPattern => "minecraft:heart_pottery_pattern",
HeartbreakPotteryPattern => "minecraft:heartbreak_pottery_pattern", HeartbreakPotteryPattern => "minecraft:heartbreak_pottery_pattern",
HowlPotteryPattern => "minecraft:howl_pottery_pattern", HowlPotteryPattern => "minecraft:howl_pottery_pattern",
@ -5646,6 +5846,7 @@ enum DecoratedPotPatterns {
MournerPotteryPattern => "minecraft:mourner_pottery_pattern", MournerPotteryPattern => "minecraft:mourner_pottery_pattern",
PlentyPotteryPattern => "minecraft:plenty_pottery_pattern", PlentyPotteryPattern => "minecraft:plenty_pottery_pattern",
PrizePotteryPattern => "minecraft:prize_pottery_pattern", PrizePotteryPattern => "minecraft:prize_pottery_pattern",
ScrapePotteryPattern => "minecraft:scrape_pottery_pattern",
SheafPotteryPattern => "minecraft:sheaf_pottery_pattern", SheafPotteryPattern => "minecraft:sheaf_pottery_pattern",
ShelterPotteryPattern => "minecraft:shelter_pottery_pattern", ShelterPotteryPattern => "minecraft:shelter_pottery_pattern",
SkullPotteryPattern => "minecraft:skull_pottery_pattern", SkullPotteryPattern => "minecraft:skull_pottery_pattern",
@ -5813,6 +6014,7 @@ enum BlockKind {
HalfTransparent => "minecraft:half_transparent", HalfTransparent => "minecraft:half_transparent",
HangingRoots => "minecraft:hanging_roots", HangingRoots => "minecraft:hanging_roots",
Hay => "minecraft:hay", Hay => "minecraft:hay",
HeavyCore => "minecraft:heavy_core",
Honey => "minecraft:honey", Honey => "minecraft:honey",
Hopper => "minecraft:hopper", Hopper => "minecraft:hopper",
HugeMushroom => "minecraft:huge_mushroom", HugeMushroom => "minecraft:huge_mushroom",
@ -5928,6 +6130,7 @@ enum BlockKind {
TurtleEgg => "minecraft:turtle_egg", TurtleEgg => "minecraft:turtle_egg",
TwistingVinesPlant => "minecraft:twisting_vines_plant", TwistingVinesPlant => "minecraft:twisting_vines_plant",
TwistingVines => "minecraft:twisting_vines", TwistingVines => "minecraft:twisting_vines",
Vault => "minecraft:vault",
Vine => "minecraft:vine", Vine => "minecraft:vine",
WallBanner => "minecraft:wall_banner", WallBanner => "minecraft:wall_banner",
WallHangingSign => "minecraft:wall_hanging_sign", WallHangingSign => "minecraft:wall_hanging_sign",
@ -6005,6 +6208,8 @@ enum TriggerKind {
BeeNestDestroyed => "minecraft:bee_nest_destroyed", BeeNestDestroyed => "minecraft:bee_nest_destroyed",
TargetHit => "minecraft:target_hit", TargetHit => "minecraft:target_hit",
ItemUsedOnBlock => "minecraft:item_used_on_block", ItemUsedOnBlock => "minecraft:item_used_on_block",
DefaultBlockUse => "minecraft:default_block_use",
AnyBlockUse => "minecraft:any_block_use",
PlayerGeneratesContainerLoot => "minecraft:player_generates_container_loot", PlayerGeneratesContainerLoot => "minecraft:player_generates_container_loot",
ThrownItemPickedUpByEntity => "minecraft:thrown_item_picked_up_by_entity", ThrownItemPickedUpByEntity => "minecraft:thrown_item_picked_up_by_entity",
ThrownItemPickedUpByPlayer => "minecraft:thrown_item_picked_up_by_player", ThrownItemPickedUpByPlayer => "minecraft:thrown_item_picked_up_by_player",
@ -6018,6 +6223,8 @@ enum TriggerKind {
AllayDropItemOnBlock => "minecraft:allay_drop_item_on_block", AllayDropItemOnBlock => "minecraft:allay_drop_item_on_block",
AvoidVibration => "minecraft:avoid_vibration", AvoidVibration => "minecraft:avoid_vibration",
RecipeCrafted => "minecraft:recipe_crafted", RecipeCrafted => "minecraft:recipe_crafted",
CrafterRecipeCrafted => "minecraft:crafter_recipe_crafted",
FallAfterExplosion => "minecraft:fall_after_explosion",
} }
} }
@ -6028,3 +6235,159 @@ enum NumberFormatKind {
Fixed => "minecraft:fixed", Fixed => "minecraft:fixed",
} }
} }
registry! {
enum ArmorMaterial {
Leather => "minecraft:leather",
Chainmail => "minecraft:chainmail",
Iron => "minecraft:iron",
Gold => "minecraft:gold",
Diamond => "minecraft:diamond",
Turtle => "minecraft:turtle",
Netherite => "minecraft:netherite",
Armadillo => "minecraft:armadillo",
}
}
registry! {
enum DataComponentKind {
CustomData => "minecraft:custom_data",
MaxStackSize => "minecraft:max_stack_size",
MaxDamage => "minecraft:max_damage",
Damage => "minecraft:damage",
Unbreakable => "minecraft:unbreakable",
CustomName => "minecraft:custom_name",
ItemName => "minecraft:item_name",
Lore => "minecraft:lore",
Rarity => "minecraft:rarity",
Enchantments => "minecraft:enchantments",
CanPlaceOn => "minecraft:can_place_on",
CanBreak => "minecraft:can_break",
AttributeModifiers => "minecraft:attribute_modifiers",
CustomModelData => "minecraft:custom_model_data",
HideAdditionalTooltip => "minecraft:hide_additional_tooltip",
HideTooltip => "minecraft:hide_tooltip",
RepairCost => "minecraft:repair_cost",
CreativeSlotLock => "minecraft:creative_slot_lock",
EnchantmentGlintOverride => "minecraft:enchantment_glint_override",
IntangibleProjectile => "minecraft:intangible_projectile",
Food => "minecraft:food",
FireResistant => "minecraft:fire_resistant",
Tool => "minecraft:tool",
StoredEnchantments => "minecraft:stored_enchantments",
DyedColor => "minecraft:dyed_color",
MapColor => "minecraft:map_color",
MapId => "minecraft:map_id",
MapDecorations => "minecraft:map_decorations",
MapPostProcessing => "minecraft:map_post_processing",
ChargedProjectiles => "minecraft:charged_projectiles",
BundleContents => "minecraft:bundle_contents",
PotionContents => "minecraft:potion_contents",
SuspiciousStewEffects => "minecraft:suspicious_stew_effects",
WritableBookContent => "minecraft:writable_book_content",
WrittenBookContent => "minecraft:written_book_content",
Trim => "minecraft:trim",
DebugStickState => "minecraft:debug_stick_state",
EntityData => "minecraft:entity_data",
BucketEntityData => "minecraft:bucket_entity_data",
BlockEntityData => "minecraft:block_entity_data",
Instrument => "minecraft:instrument",
OminousBottleAmplifier => "minecraft:ominous_bottle_amplifier",
Recipes => "minecraft:recipes",
LodestoneTracker => "minecraft:lodestone_tracker",
FireworkExplosion => "minecraft:firework_explosion",
Fireworks => "minecraft:fireworks",
Profile => "minecraft:profile",
NoteBlockSound => "minecraft:note_block_sound",
BannerPatterns => "minecraft:banner_patterns",
BaseColor => "minecraft:base_color",
PotDecorations => "minecraft:pot_decorations",
Container => "minecraft:container",
BlockState => "minecraft:block_state",
Bees => "minecraft:bees",
Lock => "minecraft:lock",
ContainerLoot => "minecraft:container_loot",
}
}
registry! {
enum EntitySubPredicateKind {
Lightning => "minecraft:lightning",
FishingHook => "minecraft:fishing_hook",
Player => "minecraft:player",
Slime => "minecraft:slime",
Raider => "minecraft:raider",
Axolotl => "minecraft:axolotl",
Boat => "minecraft:boat",
Fox => "minecraft:fox",
Mooshroom => "minecraft:mooshroom",
Rabbit => "minecraft:rabbit",
Horse => "minecraft:horse",
Llama => "minecraft:llama",
Villager => "minecraft:villager",
Parrot => "minecraft:parrot",
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",
}
}
registry! {
enum MapDecorationKind {
Player => "minecraft:player",
Frame => "minecraft:frame",
RedMarker => "minecraft:red_marker",
BlueMarker => "minecraft:blue_marker",
TargetX => "minecraft:target_x",
TargetPoint => "minecraft:target_point",
PlayerOffMap => "minecraft:player_off_map",
PlayerOffLimits => "minecraft:player_off_limits",
Mansion => "minecraft:mansion",
Monument => "minecraft:monument",
BannerWhite => "minecraft:banner_white",
BannerOrange => "minecraft:banner_orange",
BannerMagenta => "minecraft:banner_magenta",
BannerLightBlue => "minecraft:banner_light_blue",
BannerYellow => "minecraft:banner_yellow",
BannerLime => "minecraft:banner_lime",
BannerPink => "minecraft:banner_pink",
BannerGray => "minecraft:banner_gray",
BannerLightGray => "minecraft:banner_light_gray",
BannerCyan => "minecraft:banner_cyan",
BannerPurple => "minecraft:banner_purple",
BannerBlue => "minecraft:banner_blue",
BannerBrown => "minecraft:banner_brown",
BannerGreen => "minecraft:banner_green",
BannerRed => "minecraft:banner_red",
BannerBlack => "minecraft:banner_black",
RedX => "minecraft:red_x",
VillageDesert => "minecraft:village_desert",
VillagePlains => "minecraft:village_plains",
VillageSavanna => "minecraft:village_savanna",
VillageSnowy => "minecraft:village_snowy",
VillageTaiga => "minecraft:village_taiga",
JungleTemple => "minecraft:jungle_temple",
SwampHut => "minecraft:swamp_hut",
TrialChambers => "minecraft:trial_chambers",
}
}

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@ use once_cell::sync::Lazy;
use crate::Fluid; use crate::Fluid;
pub static LAVA: Lazy<HashSet<Fluid>> =
Lazy::new(|| HashSet::from_iter(vec![Fluid::Lava, Fluid::FlowingLava]));
pub static WATER: Lazy<HashSet<Fluid>> = pub static WATER: Lazy<HashSet<Fluid>> =
Lazy::new(|| HashSet::from_iter(vec![Fluid::Water, Fluid::FlowingWater])); Lazy::new(|| HashSet::from_iter(vec![Fluid::Water, Fluid::FlowingWater]));
pub static LAVA: Lazy<HashSet<Fluid>> =
Lazy::new(|| HashSet::from_iter(vec![Fluid::Lava, Fluid::FlowingLava]));

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,6 @@ azalea-buf = { path = "../azalea-buf", version = "0.9.0" }
azalea-core = { path = "../azalea-core", version = "0.9.0", features = [ azalea-core = { path = "../azalea-core", version = "0.9.0", features = [
"bevy_ecs", "bevy_ecs",
] } ] }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-registry = { path = "../azalea-registry", version = "0.9.0" } azalea-registry = { path = "../azalea-registry", version = "0.9.0" }
bevy_ecs = "0.13.2" bevy_ecs = "0.13.2"
derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] } derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] }

View file

@ -18,7 +18,6 @@ azalea-block = { version = "0.9.0", path = "../azalea-block" }
azalea-chat = { version = "0.9.0", path = "../azalea-chat" } azalea-chat = { version = "0.9.0", path = "../azalea-chat" }
azalea-client = { version = "0.9.0", path = "../azalea-client", default-features = false } azalea-client = { version = "0.9.0", path = "../azalea-client", default-features = false }
azalea-core = { version = "0.9.0", path = "../azalea-core" } azalea-core = { version = "0.9.0", path = "../azalea-core" }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-physics = { version = "0.9.0", path = "../azalea-physics" } azalea-physics = { version = "0.9.0", path = "../azalea-physics" }
azalea-protocol = { version = "0.9.0", path = "../azalea-protocol" } azalea-protocol = { version = "0.9.0", path = "../azalea-protocol" }
azalea-registry = { version = "0.9.0", path = "../azalea-registry" } azalea-registry = { version = "0.9.0", path = "../azalea-registry" }
@ -41,9 +40,10 @@ thiserror = "^1.0.58"
tokio = "^1.37.0" tokio = "^1.37.0"
uuid = "1.8.0" uuid = "1.8.0"
bevy_log = "0.13.2" bevy_log = "0.13.2"
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
bevy_time = "0.13.2" bevy_time = "0.13.2"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
[dev-dependencies] [dev-dependencies]
criterion = "0.5.1" criterion = "0.5.1"

View file

@ -2,7 +2,7 @@ use azalea_block::{Block, BlockState};
use azalea_client::{inventory::InventoryComponent, Client}; use azalea_client::{inventory::InventoryComponent, Client};
use azalea_entity::{FluidOnEyes, Physics}; use azalea_entity::{FluidOnEyes, Physics};
use azalea_inventory::{ItemSlot, Menu}; use azalea_inventory::{ItemSlot, Menu};
use azalea_registry::Fluid; use azalea_registry::{DataComponentKind, Fluid};
#[derive(Debug)] #[derive(Debug)]
pub struct BestToolResult { pub struct BestToolResult {
@ -92,7 +92,11 @@ pub fn accurate_best_tool_in_hotbar_for_block(
ItemSlot::Present(item_slot) => { ItemSlot::Present(item_slot) => {
// lazy way to avoid checking durability since azalea doesn't have durability // lazy way to avoid checking durability since azalea doesn't have durability
// data yet // data yet
if item_slot.nbt.is_none() { if item_slot
.components
.get(DataComponentKind::Damage)
.is_none()
{
this_item_speed = Some(azalea_entity::mining::get_mine_progress( this_item_speed = Some(azalea_entity::mining::get_mine_progress(
block.as_ref(), block.as_ref(),
item_slot.kind, item_slot.kind,

View file

@ -40,7 +40,7 @@ If it all works, make a pull request. If the version you updated to is a snapsho
At the time of writing, the following data generators are used: At the time of writing, the following data generators are used:
- [Vanilla data generator](https://wiki.vg/Data_Generators) - [Vanilla data generator](https://wiki.vg/Data_Generators)
- [Burger](https://github.com/Pokechu22/Burger) - [Burger](https://github.com/mat-1/Burger)
- [PixLyzer](https://gitlab.bixilon.de/bixilon/pixlyzer) - [PixLyzer](https://gitlab.bixilon.de/bixilon/pixlyzer)
Some things can be obtained from multiple generators. You should prefer them by the order above (the vanilla generator is the most reliable). Some things can be obtained from multiple generators. You should prefer them by the order above (the vanilla generator is the most reliable).

View file

@ -9,10 +9,11 @@ import lib.utils
version_id = lib.code.version.get_version_id() version_id = lib.code.version.get_version_id()
# TODO: pixlyzer is broken so we use old data
shape_datas = lib.extract.get_pixlyzer_data( shape_datas = lib.extract.get_pixlyzer_data(
version_id, 'shapes') '1.20.3-pre4', 'shapes')
pixlyzer_block_datas = lib.extract.get_pixlyzer_data( pixlyzer_block_datas = lib.extract.get_pixlyzer_data(
version_id, 'blocks') '1.20.3-pre4', 'blocks')
mappings = lib.download.get_mappings_for_version(version_id) mappings = lib.download.get_mappings_for_version(version_id)
block_states_burger = lib.extract.get_block_states_burger(version_id) block_states_burger = lib.extract.get_block_states_burger(version_id)

View file

@ -41,7 +41,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat
if property_burger is None: if property_burger is None:
print( print(
'Warning: The reports have states for a block, but Burger doesn\'t!', block_data_burger) f'Warning: The reports have states for a block, but Burger doesn\'t! (missing "{property_name}")', block_data_burger)
property_struct_name = get_property_struct_name( property_struct_name = get_property_struct_name(
property_burger, block_data_burger, property_variants, mappings) property_burger, block_data_burger, property_variants, mappings)
@ -90,7 +90,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_dat
for block_id in ordered_blocks: for block_id in ordered_blocks:
block_data_burger = blocks_burger[block_id] block_data_burger = blocks_burger[block_id]
block_data_report = blocks_report['minecraft:' + block_id] block_data_report = blocks_report['minecraft:' + block_id]
block_data_pixlyzer = pixlyzer_block_datas[f'minecraft:{block_id}'] block_data_pixlyzer = pixlyzer_block_datas.get(f'minecraft:{block_id}', {})
block_properties = block_data_burger.get('states', []) block_properties = block_data_burger.get('states', [])
block_properties_burger = block_data_burger.get('states', []) block_properties_burger = block_data_burger.get('states', [])
@ -202,6 +202,10 @@ def get_property_struct_name(property: Optional[dict], block_data_burger: dict,
return 'ChestType' return 'ChestType'
if property_variants == ['compare', 'subtract']: if property_variants == ['compare', 'subtract']:
return 'ComparatorType' return 'ComparatorType'
if property_variants == ['inactive', 'waiting_for_players', 'active', 'waiting_for_reward_ejection', 'ejecting_reward', 'cooldown']:
return 'TrialSpawnerState'
if property_variants == ['inactive', 'active', 'unlocking', 'ejecting']:
return 'VaultState'
if 'harp' in property_variants and 'didgeridoo' in property_variants: if 'harp' in property_variants and 'didgeridoo' in property_variants:
return 'Sound' return 'Sound'

View file

@ -89,7 +89,7 @@ def generate_entity_metadata(burger_entities_data: dict, mappings: Mappings):
with open(DATA_RS_DIR, 'w') as f: with open(DATA_RS_DIR, 'w') as f:
f.write('\n'.join(lines)) f.write('\n'.join(lines))
print('Expected metadata types:\n' + '\n'.join(new_metadata_names)) print('Expected metadata types:\n' + '\n'.join(new_metadata_names))
print('Updated metadata types in azalea-world/src/entity/data.rs, go make sure they\'re correct and then press enter') print('Updated metadata types in azalea-entity/src/data.rs, go make sure they\'re correct (check EntityDataSerializers.java) and then press enter')
input() input()
metadata_types = parse_metadata_types_from_code() metadata_types = parse_metadata_types_from_code()
@ -100,12 +100,17 @@ def generate_entity_metadata(burger_entities_data: dict, mappings: Mappings):
// This file is generated from codegen/lib/code/entity.py. // This file is generated from codegen/lib/code/entity.py.
// Don't change it manually! // Don't change it manually!
use crate::particle::Particle;
use super::{ use super::{
EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion, Rotations, ArmadilloStateKind, EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion,
SnifferState, VillagerData Rotations, SnifferState, VillagerData,
}; };
use azalea_chat::FormattedText; use azalea_chat::FormattedText;
use azalea_core::{particle::Particle, position::{BlockPos, Vec3}, direction::Direction}; use azalea_core::{
direction::Direction,
position::{BlockPos, Vec3},
};
use azalea_inventory::ItemSlot; use azalea_inventory::ItemSlot;
use bevy_ecs::{bundle::Bundle, component::Component}; use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
@ -218,8 +223,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
struct_name = upper_first_letter( struct_name = upper_first_letter(
to_camel_case(name_or_bitfield)) to_camel_case(name_or_bitfield))
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[ type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))['type_id']
'type_id']
metadata_type_data = metadata_types[type_id] metadata_type_data = metadata_types[type_id]
rust_type = metadata_type_data['type'] rust_type = metadata_type_data['type']
@ -281,8 +285,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
if name_or_bitfield in single_use_imported_types: if name_or_bitfield in single_use_imported_types:
field_struct_name = '' field_struct_name = ''
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[ type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))['type_id']
'type_id']
metadata_type_data = metadata_types[type_id] metadata_type_data = metadata_types[type_id]
rust_type = metadata_type_data['type'] rust_type = metadata_type_data['type']
type_name = metadata_type_data['name'] type_name = metadata_type_data['name']
@ -384,8 +387,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
' },') ' },')
for index, name_or_bitfield in get_entity_metadata_names(this_entity_id, burger_entity_metadata, mappings).items(): for index, name_or_bitfield in get_entity_metadata_names(this_entity_id, burger_entity_metadata, mappings).items():
default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get( default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get('default', 'Default::default()')
'default', 'Default::default()')
if isinstance(name_or_bitfield, str): if isinstance(name_or_bitfield, str):
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[ type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[
'type_id'] 'type_id']
@ -454,8 +456,10 @@ impl From<EntityDataValue> for UpdateMetadataError {
for mask, name in name_or_bitfield.items(): for mask, name in name_or_bitfield.items():
name = maybe_rename_field(name, index) name = maybe_rename_field(name, index)
mask = int(mask, 0) mask = int(mask, 0)
bit_default = 'true' if ( if default is None:
default & mask != 0) else 'false' bit_default = 'false'
else:
bit_default = 'true' if (default & mask != 0) else 'false'
code.append( code.append(
f' {name}: {upper_first_letter(to_camel_case(name))}({bit_default}),') f' {name}: {upper_first_letter(to_camel_case(name))}({bit_default}),')
code.append(' Self {') code.append(' Self {')

View file

@ -16,7 +16,7 @@ def get_burger():
if not os.path.exists(get_dir_location('__cache__/Burger')): if not os.path.exists(get_dir_location('__cache__/Burger')):
print('\033[92mDownloading Burger...\033[m') print('\033[92mDownloading Burger...\033[m')
os.system( os.system(
f'cd {get_dir_location("__cache__")} && git clone https://github.com/pokechu22/Burger && cd Burger && git pull') f'cd {get_dir_location("__cache__")} && git clone https://github.com/mat-1/Burger && cd Burger && git pull')
print('\033[92mInstalling dependencies...\033[m') print('\033[92mInstalling dependencies...\033[m')
os.system(f'cd {get_dir_location("__cache__")}/Burger && pip install six jawa') os.system(f'cd {get_dir_location("__cache__")}/Burger && pip install six jawa')

View file

@ -1,5 +1,6 @@
# Extracting data from the Minecraft jars # Extracting data from the Minecraft jars
from typing import TYPE_CHECKING
from lib.download import get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions from lib.download import get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
from lib.utils import get_dir_location from lib.utils import get_dir_location
from zipfile import ZipFile from zipfile import ZipFile
@ -275,3 +276,19 @@ def get_en_us_lang(version_id: str):
return json.loads( return json.loads(
get_file_from_jar(version_id, 'assets/minecraft/lang/en_us.json') get_file_from_jar(version_id, 'assets/minecraft/lang/en_us.json')
) )
# burger packet id extraction is broken since 1.20.5 (always returns -1, so we have to determine packet id ourselves from the mappings).
# this is very much not ideal.
if TYPE_CHECKING: from codegen.lib.mappings import Mappings
def get_packet_list(burger_data, mappings: 'Mappings'):
packet_list = list(burger_data[0]['packets']['packet'].values())
current_packet_id = 0
for packet in packet_list:
if packet['id'] == -1:
packet['id'] = current_packet_id
print(packet)
current_packet_id += 1
return packet_list

View file

@ -26,88 +26,89 @@ if len(sys.argv) == 1:
old_version_id = lib.code.version.get_version_id() old_version_id = lib.code.version.get_version_id()
old_mappings = lib.download.get_mappings_for_version(old_version_id) old_mappings = lib.download.get_mappings_for_version(old_version_id)
old_burger_data = lib.extract.get_burger_data_for_version(old_version_id) old_burger_data = lib.extract.get_burger_data_for_version(old_version_id)
old_packet_list = list(old_burger_data[0]['packets']['packet'].values())
new_version_id = sys.argv[1] new_version_id = sys.argv[1]
new_mappings = lib.download.get_mappings_for_version(new_version_id) new_mappings = lib.download.get_mappings_for_version(new_version_id)
new_burger_data = lib.extract.get_burger_data_for_version(new_version_id) new_burger_data = lib.extract.get_burger_data_for_version(new_version_id)
new_packet_list = list(new_burger_data[0]['packets']['packet'].values())
old_packet_list = lib.extract.get_packet_list(old_burger_data, old_mappings)
new_packet_list = lib.extract.get_packet_list(new_burger_data, new_mappings)
old_packets: dict[PacketIdentifier, str] = {} # old_packets: dict[PacketIdentifier, str] = {}
old_packets_data: dict[PacketIdentifier, dict] = {} # old_packets_data: dict[PacketIdentifier, dict] = {}
new_packets: dict[PacketIdentifier, str] = {} # new_packets: dict[PacketIdentifier, str] = {}
new_packets_data: dict[PacketIdentifier, dict] = {} # new_packets_data: dict[PacketIdentifier, dict] = {}
for packet in old_packet_list: # for packet in old_packet_list:
assert packet['class'].endswith('.class') # assert packet['class'].endswith('.class')
packet_name = old_mappings.get_class(packet['class'][:-6]) # packet_name = old_mappings.get_class(packet['class'][:-6])
packet_ident = PacketIdentifier( # packet_ident = PacketIdentifier(
packet['id'], packet['direction'].lower(), fix_state(packet['state'])) # packet['id'], packet['direction'].lower(), fix_state(packet['state']))
old_packets[packet_ident] = packet_name # old_packets[packet_ident] = packet_name
old_packets_data[packet_ident] = packet # old_packets_data[packet_ident] = packet
for packet in new_packet_list: # for packet in new_packet_list:
assert packet['class'].endswith('.class') # assert packet['class'].endswith('.class')
packet_name = new_mappings.get_class(packet['class'][:-6]) # packet_name = new_mappings.get_class(packet['class'][:-6])
packet_ident = PacketIdentifier( # packet_ident = PacketIdentifier(
packet['id'], packet['direction'].lower(), fix_state(packet['state'])) # packet['id'], packet['direction'].lower(), fix_state(packet['state']))
new_packets[packet_ident] = packet_name # new_packets[packet_ident] = packet_name
new_packets_data[packet_ident] = packet # new_packets_data[packet_ident] = packet
# find removed packets # # find removed packets
removed_packets: list[PacketIdentifier] = [] # removed_packets: list[PacketIdentifier] = []
for packet, packet_name in old_packets.items(): # for packet, packet_name in old_packets.items():
if packet_name not in new_packets.values(): # if packet_name not in new_packets.values():
removed_packets.append(packet) # removed_packets.append(packet)
print('Removed packet:', packet, packet_name) # print('Removed packet:', packet, packet_name)
for (direction, state), packets in group_packets(removed_packets).items(): # for (direction, state), packets in group_packets(removed_packets).items():
lib.code.packet.remove_packet_ids(packets, direction, state) # lib.code.packet.remove_packet_ids(packets, direction, state)
print() print()
# find packets that changed ids # # find packets that changed ids
changed_packets: dict[PacketIdentifier, int] = {} # changed_packets: dict[PacketIdentifier, int] = {}
for old_packet, old_packet_name in old_packets.items(): # for old_packet, old_packet_name in old_packets.items():
for new_packet, new_packet_name in new_packets.items(): # for new_packet, new_packet_name in new_packets.items():
if old_packet_name == new_packet_name and old_packet.direction == new_packet.direction and old_packet.state == new_packet.state and old_packet.packet_id != new_packet.packet_id: # if old_packet_name == new_packet_name and old_packet.direction == new_packet.direction and old_packet.state == new_packet.state and old_packet.packet_id != new_packet.packet_id:
changed_packets[old_packet] = new_packet.packet_id # changed_packets[old_packet] = new_packet.packet_id
print('Changed packet id:', old_packet, '->', # print('Changed packet id:', old_packet, '->',
new_packet, f'({new_packet_name})') # new_packet, f'({new_packet_name})')
break # break
for (direction, state), packets in group_packets(list(changed_packets.keys())).items(): # for (direction, state), packets in group_packets(list(changed_packets.keys())).items():
id_map: dict[int, int] = {} # id_map: dict[int, int] = {}
for old_packet_id in packets: # for old_packet_id in packets:
new_packet_id = changed_packets[PacketIdentifier( # new_packet_id = changed_packets[PacketIdentifier(
old_packet_id, direction, state)] # old_packet_id, direction, state)]
id_map[old_packet_id] = new_packet_id # id_map[old_packet_id] = new_packet_id
lib.code.packet.change_packet_ids(id_map, direction, state) # lib.code.packet.change_packet_ids(id_map, direction, state)
print() # print()
# find added/changed packets # # find added/changed packets
added_or_changed_packets: list[PacketIdentifier] = [] # added_or_changed_packets: list[PacketIdentifier] = []
for new_packet, packet_name in new_packets.items(): # for new_packet, packet_name in new_packets.items():
old_packet = None # old_packet = None
for old_packet_tmp, old_packet_name in old_packets.items(): # for old_packet_tmp, old_packet_name in old_packets.items():
if old_packet_name == packet_name: # if old_packet_name == packet_name:
old_packet = old_packet_tmp # old_packet = old_packet_tmp
break # break
if packet_name not in old_packets.values(): # if packet_name not in old_packets.values():
added_or_changed_packets.append(new_packet) # added_or_changed_packets.append(new_packet)
print('Added packet:', new_packet, packet_name) # print('Added packet:', new_packet, packet_name)
elif old_packet and not lib.code.packet.are_packet_instructions_identical(new_packets_data[new_packet].get('instructions'), old_packets_data[old_packet].get('instructions')): # elif old_packet and not lib.code.packet.are_packet_instructions_identical(new_packets_data[new_packet].get('instructions'), old_packets_data[old_packet].get('instructions')):
added_or_changed_packets.append(new_packet) # added_or_changed_packets.append(new_packet)
print('Changed packet:', new_packet, packet_name) # print('Changed packet:', new_packet, packet_name)
for packet in added_or_changed_packets: # for packet in added_or_changed_packets:
lib.code.packet.generate_packet( # lib.code.packet.generate_packet(
new_burger_data[0]['packets']['packet'], new_mappings, packet.packet_id, packet.direction, packet.state) # new_burger_data[0]['packets']['packet'], new_mappings, packet.packet_id, packet.direction, packet.state)
lib.code.version.set_protocol_version( lib.code.version.set_protocol_version(
new_burger_data[0]['version']['protocol']) new_burger_data[0]['version']['protocol'])
print('Updated protocol!') # print('Updated protocol!')
old_ordered_blocks = lib.extract.get_ordered_blocks_burger(old_version_id) old_ordered_blocks = lib.extract.get_ordered_blocks_burger(old_version_id)
@ -118,10 +119,11 @@ if old_ordered_blocks != new_ordered_blocks:
block_states_burger = lib.extract.get_block_states_burger(new_version_id) block_states_burger = lib.extract.get_block_states_burger(new_version_id)
block_states_report = lib.extract.get_block_states_report(new_version_id) block_states_report = lib.extract.get_block_states_report(new_version_id)
# TODO: pixlyzer is currently broken so uhhhh
shape_datas = lib.extract.get_pixlyzer_data( shape_datas = lib.extract.get_pixlyzer_data(
new_version_id, 'shapes') '1.20.3-pre4', 'shapes')
pixlyzer_block_datas = lib.extract.get_pixlyzer_data( pixlyzer_block_datas = lib.extract.get_pixlyzer_data(
new_version_id, 'blocks') '1.20.3-pre4', 'blocks')
lib.code.blocks.generate_blocks( lib.code.blocks.generate_blocks(
block_states_burger, block_states_report, pixlyzer_block_datas, new_ordered_blocks, new_mappings) block_states_burger, block_states_report, pixlyzer_block_datas, new_ordered_blocks, new_mappings)
@ -136,9 +138,9 @@ print('Generating registries...')
import genregistries import genregistries
genregistries.generate(new_version_id) genregistries.generate(new_version_id)
print('Generating entity metadata...') # print('Generating entity metadata...')
burger_entities_data = new_burger_data[0]['entities'] # burger_entities_data = new_burger_data[0]['entities']
lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings) # lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings)
print('Finishing touches, setting version in README and formatting code...') print('Finishing touches, setting version in README and formatting code...')
lib.code.version.set_version_id(new_version_id) lib.code.version.set_version_id(new_version_id)