* 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_json",
"simdnbt",
"socks5-impl",
"thiserror",
"tokio",
"tracing",
@ -359,7 +358,6 @@ name = "azalea-core"
version = "0.9.1"
dependencies = [
"azalea-buf",
"azalea-inventory",
"azalea-registry",
"bevy_ecs",
"nohash-hasher",
@ -416,9 +414,12 @@ name = "azalea-inventory"
version = "0.9.1"
dependencies = [
"azalea-buf",
"azalea-chat",
"azalea-core",
"azalea-inventory-macros",
"azalea-registry",
"simdnbt",
"uuid",
]
[[package]]
@ -536,7 +537,6 @@ dependencies = [
"azalea-buf",
"azalea-client",
"azalea-core",
"azalea-inventory",
"azalea-registry",
"bevy_ecs",
"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. -->
_Currently supported Minecraft version: `1.20.4`._
_Currently supported Minecraft version: `1.20.5`._
> [!WARNING]
> 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),
"crafting" => Crafting(bool),
"trial_spawner_state" => State {
"ominous" => Ominous(bool),
"trial_spawner_state" => TrialSpawnerState {
Inactive,
WaitingForPlayers,
Active,
@ -1925,6 +1926,12 @@ make_block_states! {
EjectingReward,
Cooldown,
},
"vault_state" => VaultState {
Inactive,
Active,
Unlocking,
Ejecting,
},
},
Blocks => {
air => BlockBehavior::new(), {},
@ -5376,7 +5383,16 @@ make_block_states! {
triggered: Triggered(false),
},
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 {
match data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => {
let syn::Fields::Named(FieldsNamed { named, .. }) = fields else {
panic!("#[derive(McBuf)] can only be used on structs with named fields")
};
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
syn::Fields::Named(FieldsNamed { named, .. }) => {
let (read_fields, read_field_names) = read_named_fields(named);
let (read_fields, read_field_names) = read_named_fields(named);
quote! {
impl azalea_buf::McBufReadable for #ident {
fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
#(#read_fields)*
Ok(#ident {
#(#read_field_names: #read_field_names),*
})
quote! {
impl azalea_buf::McBufReadable for #ident {
fn read_from(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
#(#read_fields)*
Ok(Self {
#(#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, .. }) => {
let mut match_contents = quote!();
let mut variant_discrim: u32 = 0;

View file

@ -39,23 +39,33 @@ fn write_named_fields(
pub fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenStream {
match data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => {
let syn::Fields::Named(FieldsNamed { named, .. }) = fields else {
panic!("#[derive(McBuf)] can only be used on structs with named fields")
};
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
syn::Fields::Named(FieldsNamed { named, .. }) => {
let write_fields =
write_named_fields(named, Some(&Ident::new("self", Span::call_site())));
let write_fields =
write_named_fields(named, Some(&Ident::new("self", Span::call_site())));
quote! {
impl azalea_buf::McBufWritable for #ident {
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
#write_fields
Ok(())
quote! {
impl azalea_buf::McBufWritable for #ident {
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
#write_fields
Ok(())
}
}
}
}
}
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, .. }) => {
// remember whether it's a data variant so we can do an optimization later
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)
}
// 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
where
Self: Sized,
@ -373,3 +362,12 @@ impl McBufReadable for simdnbt::owned::Nbt {
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)
}
}
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_tasks = "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"] }
futures = "0.3.30"
tracing = "0.1.40"
@ -39,11 +38,11 @@ regex = "1.10.4"
thiserror = "^1.0.58"
tokio = { version = "^1.37.0", features = ["sync"] }
uuid = "^1.8.0"
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
serde_json = "1.0.116"
serde = "1.0.198"
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]
default = ["log"]

View file

@ -306,6 +306,14 @@ impl Client {
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((
// these stay when we switch to the game state
LocalPlayerBundle {
@ -318,6 +326,7 @@ impl Client {
local_player_events: LocalPlayerEvents(tx),
game_profile: GameProfileComponent(game_profile),
client_information: crate::ClientInformation::default(),
instance_holder,
},
InConfigurationState,
));
@ -394,7 +403,7 @@ impl Client {
match packet {
ClientboundLoginPacket::Hello(p) => {
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 {
// keep track of the number of times we tried
@ -436,7 +445,7 @@ impl Client {
conn.write(
ServerboundKeyPacket {
key_bytes: e.encrypted_public_key,
encrypted_challenge: e.encrypted_nonce,
encrypted_challenge: e.encrypted_challenge,
}
.get(),
)
@ -466,6 +475,9 @@ impl Client {
// replying to custom query is done in
// 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 game_profile: GameProfileComponent,
pub client_information: ClientInformation,
pub instance_holder: InstanceHolder,
}
/// 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_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket},
};
use azalea_registry::DataComponentKind;
use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_app::{App, Plugin, Update};
use bevy_ecs::{
@ -28,7 +29,6 @@ use bevy_ecs::{
system::{Commands, Query, Res},
};
use derive_more::{Deref, DerefMut};
use simdnbt::owned::NbtList;
use tracing::warn;
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
// optimization and makes the code too complicated
let Some(can_destroy) = item
.nbt
.compound("tag")
.and_then(|nbt| nbt.list("CanDestroy"))
else {
let Some(_can_destroy) = item.components.get(DataComponentKind::CanBreak) else {
// no CanDestroy tag
return false;
};
let NbtList::String(_can_destroy) = can_destroy else {
// CanDestroy tag must be a list of strings
return false;
};
false
// for block_predicate in can_destroy {

View file

@ -252,7 +252,7 @@ impl InventoryComponent {
// && slot.may_place(item_stack)
&& (
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;
@ -273,9 +273,9 @@ impl InventoryComponent {
&mut new_carried,
slot_item_count,
);
let max_stack_size = i8::min(
let max_stack_size = i32::min(
new_carried.kind.max_stack_size(),
i8::min(
i32::min(
new_carried.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) {
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
let target_slot = self.menu_mut().slot_mut(target_slot_index).unwrap();
@ -449,7 +449,7 @@ impl InventoryComponent {
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);
}
ClickOperation::PickupAll(PickupAllClick {
@ -492,7 +492,7 @@ impl InventoryComponent {
let checking_slot = self.menu_mut().slot_mut(i).unwrap();
let taken_item =
checking_slot.split(checking_slot.count() as u8);
checking_slot.split(checking_slot.count() as u32);
// now extend the carried item
let target_slot = &mut self.carried;
@ -537,7 +537,7 @@ fn can_item_quick_replace(
return false;
};
if !item.is_same_item_and_nbt(target_slot) {
if !item.is_same_item_and_components(target_slot) {
return false;
}
let count = target_slot.count as u16
@ -553,10 +553,10 @@ fn get_quick_craft_slot_count(
quick_craft_slots: &HashSet<u16>,
quick_craft_kind: &QuickCraftKind,
item: &mut ItemSlotData,
slot_item_count: i8,
slot_item_count: i32,
) {
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::Middle => item.kind.max_stack_size(),
};

View file

@ -1,20 +1,18 @@
use std::io::Cursor;
use std::sync::Arc;
use azalea_entity::indexing::EntityIdIndex;
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_pong_packet::ServerboundPongPacket;
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::{
ClientboundConfigurationPacket, ServerboundConfigurationPacket,
};
use azalea_protocol::packets::ConnectionProtocol;
use azalea_protocol::read::deserialize_packet;
use azalea_world::Instance;
use bevy_ecs::prelude::*;
use bevy_ecs::system::SystemState;
use parking_lot::RwLock;
use tracing::{debug, error, warn};
use crate::client::InConfigurationState;
@ -22,6 +20,7 @@ use crate::disconnect::DisconnectEvent;
use crate::local_player::Hunger;
use crate::packet_handling::game::KeepAliveEvent;
use crate::raw_connection::RawConnection;
use crate::InstanceHolder;
#[derive(Event, Debug, Clone)]
pub struct ConfigurationPacketEvent {
@ -80,21 +79,14 @@ pub fn process_packet_events(ecs: &mut World) {
for (player_entity, packet) in events_owned {
match packet {
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
// but if a registry wasn't sent, keep the old one
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);
// add the new registry data
instance.registries.append(p.registry_id, p.entries);
}
ClientboundConfigurationPacket::CustomPayload(p) => {
@ -200,6 +192,35 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundConfigurationPacket::UpdateTags(_p) => {
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()));
}
let Some(dimension_type) =
let Some(dimension_type_element) =
instance_holder.instance.read().registries.dimension_type()
else {
error!("Server didn't send dimension type registry, can't log in");
continue;
};
let dimension = &dimension_type
.value
.iter()
.find(|t| t.name == p.common.dimension_type)
.unwrap_or_else(|| {
panic!("No dimension_type with name {}", p.common.dimension_type)
})
.element;
let dimension_type =
ResourceLocation::new(&p.common.dimension_type.to_string());
let dimension = dimension_type_element
.map
.get(&dimension_type)
.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
// there)
@ -1288,9 +1288,6 @@ pub fn process_packet_events(ecs: &mut World) {
packet: ServerboundPongPacket { id: p.id }.get(),
});
}
ClientboundGamePacket::PongResponse(p) => {
debug!("Got pong response packet {p:?}");
}
ClientboundGamePacket::PlaceGhostRecipe(_) => {}
ClientboundGamePacket::PlayerCombatEnd(_) => {}
ClientboundGamePacket::PlayerCombatEnter(_) => {}
@ -1359,21 +1356,20 @@ pub fn process_packet_events(ecs: &mut World) {
{
let new_instance_name = p.common.dimension.clone();
let Some(dimension_type) =
let Some(dimension_type_element) =
instance_holder.instance.read().registries.dimension_type()
else {
error!("Server didn't send dimension type registry, can't log in");
continue;
};
let dimension = &dimension_type
.value
.iter()
.find(|t| t.name == p.common.dimension_type)
.unwrap_or_else(|| {
panic!("No dimension_type with name {}", p.common.dimension_type)
})
.element;
let dimension_type =
ResourceLocation::new(&p.common.dimension_type.to_string());
let dimension = dimension_type_element
.map
.get(&dimension_type)
.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
// there)
@ -1475,6 +1471,11 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::TickingStep(_) => {}
ClientboundGamePacket::ResetScore(_) => {}
ClientboundGamePacket::CookieRequest(_) => {}
ClientboundGamePacket::DebugSample(_) => {}
ClientboundGamePacket::PongResponse(_) => {}
ClientboundGamePacket::StoreCookie(_) => {}
ClientboundGamePacket::Transfer(_) => {}
}
}
}

View file

@ -11,7 +11,6 @@ version = "0.9.1"
[dependencies]
simdnbt = { version = "0.4", git = "https://github.com/azalea-rs/simdnbt" }
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" }
bevy_ecs = { version = "0.13.2", default-features = false, optional = true }
nohash-hasher = "0.2.0"

View file

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

View file

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

View file

@ -5,7 +5,6 @@
//! the game, including the types of chat messages, dimensions, and
//! biomes.
use azalea_buf::{BufReadError, McBufReadable, McBufWritable};
use simdnbt::{
owned::{NbtCompound, NbtTag},
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.
#[derive(Default, Debug, Clone)]
pub struct RegistryHolder {
pub map: HashMap<ResourceLocation, NbtCompound>,
pub map: HashMap<ResourceLocation, HashMap<ResourceLocation, NbtCompound>>,
}
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>(
&self,
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
// owned::NbtCompound as a borrow::NbtCompound
let nbt_owned_compound = self.map.get(name)?;
let mut nbt_bytes = Vec::new();
nbt_owned_compound.write(&mut nbt_bytes);
let nbt_borrow_compound =
simdnbt::borrow::NbtCompound::read(&mut Cursor::new(&nbt_bytes)).ok()?;
Some(T::from_compound(&nbt_borrow_compound))
let mut map = HashMap::new();
for (key, value) in self.map.get(name)? {
// convert the value to T
let mut nbt_bytes = Vec::new();
value.write(&mut nbt_bytes);
let nbt_borrow_compound =
simdnbt::borrow::NbtCompound::read(&mut Cursor::new(&nbt_bytes)).ok()?;
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
@ -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.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "strict_registry", simdnbt(deny_unknown_fields))]
pub struct RegistryType<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)]
pub struct RegistryType<T> {
pub map: HashMap<ResourceLocation, T>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]

View file

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

View file

@ -39,10 +39,10 @@ pub fn hex_digest(digest: &[u8]) -> String {
pub struct EncryptResult {
pub secret_key: [u8; 16],
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
// generate a random 16-byte shared secret, to be used with the AES/CFB8
// stream cipher.
@ -51,14 +51,14 @@ pub fn encrypt(public_key: &[u8], nonce: &[u8]) -> Result<EncryptResult, String>
// &secret_key));
// 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_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 {
secret_key,
encrypted_public_key,
encrypted_nonce,
encrypted_challenge,
})
}

View file

@ -6,7 +6,6 @@ use azalea_buf::{
use azalea_chat::FormattedText;
use azalea_core::{
direction::Direction,
particle::Particle,
position::{BlockPos, GlobalPos, Vec3},
};
use azalea_inventory::ItemSlot;
@ -17,6 +16,8 @@ use nohash_hasher::IntSet;
use std::io::{Cursor, Write};
use uuid::Uuid;
use crate::particle::Particle;
#[derive(Clone, Debug, Deref)]
pub struct EntityMetadataItems(Vec<EntityDataItem>);
@ -83,15 +84,18 @@ pub enum EntityDataValue {
OptionalBlockState(azalea_block::BlockState),
CompoundTag(simdnbt::owned::NbtCompound),
Particle(Particle),
Particles(Vec<Particle>),
VillagerData(VillagerData),
// 0 for absent; 1 + actual value otherwise. Used for entity IDs.
OptionalUnsignedInt(OptionalUnsignedInt),
Pose(Pose),
CatVariant(azalea_registry::CatVariant),
WolfVariant(azalea_registry::WolfVariant),
FrogVariant(azalea_registry::FrogVariant),
OptionalGlobalPos(Option<GlobalPos>),
PaintingVariant(azalea_registry::PaintingVariant),
SnifferState(SnifferState),
ArmadilloState(ArmadilloStateKind),
Vector3(Vec3),
Quaternion(Quaternion),
}
@ -107,6 +111,16 @@ pub struct Quaternion {
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 {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let val = u32::var_read_from(buf)?;

View file

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

@ -1,5 +1,5 @@
use syn::{
braced,
braced,
parse::{Parse, ParseStream, Result},
Ident, LitInt, Token,
};

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`]: crate::ItemSlotData
fn max_stack_size(&self) -> i8;
fn max_stack_size(&self) -> i32;
/// Whether this item can be stacked with other items.
///
@ -16,7 +16,7 @@ pub trait MaxStackSizeExt {
}
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
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 operations;
mod slot;

View file

@ -621,7 +621,7 @@ impl Menu {
}
/// 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
}
@ -671,9 +671,11 @@ impl Menu {
let target_slot = self.slot(target_slot_index).unwrap();
if let ItemSlot::Present(target_item) = target_slot {
// 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 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
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();
if target_slot.is_empty() && self.may_place(target_slot_index, item) {
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();
*target_slot = ItemSlot::Present(new_target_slot_data);

View file

@ -1,6 +1,12 @@
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
use simdnbt::owned::Nbt;
use std::io::{Cursor, Write};
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
use azalea_registry::DataComponentKind;
use std::{
collections::HashMap,
fmt,
io::{Cursor, Write},
};
use crate::components::{self};
/// Either an item in an inventory or nothing.
#[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
/// slot is present.
pub fn count(&self) -> i8 {
pub fn count(&self) -> i32 {
match self {
ItemSlot::Empty => 0,
ItemSlot::Present(i) => i.count,
@ -41,7 +47,7 @@ impl ItemSlot {
}
/// 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 {
ItemSlot::Empty => ItemSlot::Empty,
ItemSlot::Present(i) => {
@ -83,20 +89,20 @@ impl ItemSlot {
/// An item in an inventory, with a count and NBT. Usually you want [`ItemSlot`]
/// or [`azalea_registry::Item`] instead.
#[derive(Debug, Clone, McBuf, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct ItemSlotData {
pub kind: azalea_registry::Item,
/// The amount of the item in this slot.
///
/// The count can be zero or negative, but this is rare.
pub count: i8,
pub nbt: Nbt,
pub count: i32,
pub kind: azalea_registry::Item,
pub components: DataComponentPatch,
}
impl ItemSlotData {
/// Remove `count` items from this slot, returning the removed items.
pub fn split(&mut self, count: u8) -> ItemSlotData {
let returning_count = i8::min(count as i8, self.count);
pub fn split(&mut self, count: u32) -> ItemSlotData {
let returning_count = i32::min(count as i32, self.count);
let mut returning = self.clone();
returning.count = returning_count;
self.count -= returning_count;
@ -116,39 +122,161 @@ impl ItemSlotData {
/// let mut a = ItemSlotData {
/// kind: Item::Stone,
/// count: 1,
/// nbt: Default::default(),
/// components: Default::default(),
/// };
/// let mut b = ItemSlotData {
/// kind: Item::Stone,
/// 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;
/// 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 {
self.kind == other.kind && self.nbt == other.nbt
pub fn is_same_item_and_components(&self, other: &ItemSlotData) -> bool {
self.kind == other.kind && self.components == other.components
}
}
impl McBufReadable for ItemSlot {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let slot = Option::<ItemSlotData>::read_from(buf)?;
Ok(slot.map_or(ItemSlot::Empty, ItemSlot::Present))
let count = i32::var_read_from(buf)?;
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 {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
match self {
ItemSlot::Empty => false.write_into(buf)?,
ItemSlot::Empty => 0.var_write_into(buf)?,
ItemSlot::Present(i) => {
true.write_into(buf)?;
i.write_into(buf)?;
i.count.var_write_into(buf)?;
i.kind.write_into(buf)?;
i.components.write_into(buf)?;
}
};
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.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.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.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.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.title": "Caves & Cliffs",
"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_mob_near_sculk_catalyst.description": "Kill a mob near a Sculk Catalyst",
"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.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.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.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.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.title": "Adventure",
"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.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.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.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.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.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.title": "Who's the Pillager Now?",
"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_seed.description": "Plant a seed and watch it grow",
"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.title": "Whatever Floats Your Goat!",
"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_on.description": "Apply Honeycomb to a Copper block!",
"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.title": "How Did We Get Here?",
"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.long.big": "Long must not be more 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.mixed": "Can't insert %s into %s",
"argument.nbt.expected.key": "Expected key",
@ -352,6 +377,8 @@
"argument.range.empty": "Expected value or range of values",
"argument.range.ints": "Only whole numbers allowed, not decimals",
"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.not_found": "Can't find tag '%s' of type '%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.scoreHolder.empty": "No relevant score holders could be found",
"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.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",
"arguments.block.tag.unknown": "Unknown block tag '%s'",
"arguments.function.tag.unknown": "Unknown function tag '%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.predicate.malformed": "Malformed '%s' predicate: '%s'",
"arguments.item.predicate.unknown": "Unknown item predicate '%s'",
"arguments.item.tag.unknown": "Unknown item tag '%s'",
"arguments.nbtpath.node.invalid": "Invalid NBT path element",
"arguments.nbtpath.nothing_found": "Found no elements matching %s",
@ -392,14 +426,25 @@
"attribute.name.generic.attack_damage": "Attack Damage",
"attribute.name.generic.attack_knockback": "Attack Knockback",
"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.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.luck": "Luck",
"attribute.name.generic.max_absorption": "Max Absorption",
"attribute.name.generic.max_health": "Max Health",
"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.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",
"biome.minecraft.badlands": "Badlands",
"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.white": "White 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.blue": "Blue 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.white": "White 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.blue": "Blue Per Fess Inverted",
"block.minecraft.banner.half_horizontal_bottom.brown": "Brown Per Fess Inverted",
@ -1551,6 +1628,7 @@
"block.minecraft.grindstone": "Grindstone",
"block.minecraft.hanging_roots": "Hanging Roots",
"block.minecraft.hay_block": "Hay Bale",
"block.minecraft.heavy_core": "Heavy Core",
"block.minecraft.heavy_weighted_pressure_plate": "Heavy Weighted Pressure Plate",
"block.minecraft.honey_block": "Honey Block",
"block.minecraft.honeycomb_block": "Honeycomb Block",
@ -2071,6 +2149,7 @@
"block.minecraft.turtle_egg": "Turtle Egg",
"block.minecraft.twisting_vines": "Twisting Vines",
"block.minecraft.twisting_vines_plant": "Twisting Vines Plant",
"block.minecraft.vault": "Vault",
"block.minecraft.verdant_froglight": "Verdant Froglight",
"block.minecraft.vine": "Vines",
"block.minecraft.void_air": "Void Air",
@ -2200,9 +2279,12 @@
"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.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.missingProfileKey": "Chat disabled due to missing profile public key. Please try reconnecting.",
"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.moreInfo": "Chat not allowed by account settings. Cannot send or view messages.",
"chat.editBox": "chat",
@ -2231,6 +2313,11 @@
"chat.type.text": "<%s> %s",
"chat.type.text.narrate": "%s says %s",
"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.single": "No items were found on player %s",
"color.minecraft.black": "Black",
@ -2363,6 +2450,7 @@
"commands.data.storage.modified": "Modified storage %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.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.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",
@ -2613,6 +2701,7 @@
"commands.setblock.failed": "Could not set the block",
"commands.setblock.success": "Changed the block at %s, %s, %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.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",
@ -2689,14 +2778,14 @@
"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.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.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.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.success": "A tick step interrupted",
"commands.tick.step.stop.success": "Interrupted the current tick step",
"commands.tick.step.success": "Stepping %s tick(s)",
"commands.time.query": "The time is %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.times.multiple": "Changed title display times for %s players",
"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.failed.invalid": "You can only trigger objectives that are 'trigger' type",
"commands.trigger.failed.unprimed": "You cannot trigger this objective yet",
@ -2757,10 +2849,12 @@
"connect.connecting": "Connecting to the server...",
"connect.encrypting": "Encrypting...",
"connect.failed": "Failed to connect to the server",
"connect.failed.transfer": "Connection failed while transferring to the server",
"connect.joining": "Joining world...",
"connect.negotiating": "Negotiating...",
"connect.reconfiging": "Reconfiguring...",
"connect.reconfiguring": "Reconfiguring...",
"connect.transferring": "Transferring to new server...",
"container.barrel": "Barrel",
"container.beacon": "Beacon",
"container.blast_furnace": "Blast Furnace",
@ -3094,9 +3188,11 @@
"disconnect.loginFailedInfo.userBanned": "You are banned from playing online",
"disconnect.lost": "Connection Lost",
"disconnect.overflow": "Buffer overflow",
"disconnect.packetError": "Network Protocol Error",
"disconnect.quitting": "Quitting",
"disconnect.spam": "Kicked for spamming",
"disconnect.timeout": "Timed out",
"disconnect.transfer": "Transferred to another server",
"disconnect.unknownHost": "Unknown host",
"download.pack.failed": "%s out of %s packs failed to download",
"download.pack.progress.bytes": "Progress: %s (total size unknown)",
@ -3117,6 +3213,7 @@
"effect.minecraft.health_boost": "Health Boost",
"effect.minecraft.hero_of_the_village": "Hero of the Village",
"effect.minecraft.hunger": "Hunger",
"effect.minecraft.infested": "Infested",
"effect.minecraft.instant_damage": "Instant Damage",
"effect.minecraft.instant_health": "Instant Health",
"effect.minecraft.invisibility": "Invisibility",
@ -3126,7 +3223,9 @@
"effect.minecraft.mining_fatigue": "Mining Fatigue",
"effect.minecraft.nausea": "Nausea",
"effect.minecraft.night_vision": "Night Vision",
"effect.minecraft.oozing": "Oozing",
"effect.minecraft.poison": "Poison",
"effect.minecraft.raid_omen": "Raid Omen",
"effect.minecraft.regeneration": "Regeneration",
"effect.minecraft.resistance": "Resistance",
"effect.minecraft.saturation": "Saturation",
@ -3134,9 +3233,12 @@
"effect.minecraft.slowness": "Slowness",
"effect.minecraft.speed": "Speed",
"effect.minecraft.strength": "Strength",
"effect.minecraft.trial_omen": "Trial Omen",
"effect.minecraft.unluck": "Bad Luck",
"effect.minecraft.water_breathing": "Water Breathing",
"effect.minecraft.weakness": "Weakness",
"effect.minecraft.weaving": "Weaving",
"effect.minecraft.wind_charged": "Wind Charged",
"effect.minecraft.wither": "Wither",
"effect.none": "No Effects",
"enchantment.level.1": "I",
@ -3153,7 +3255,9 @@
"enchantment.minecraft.bane_of_arthropods": "Bane of Arthropods",
"enchantment.minecraft.binding_curse": "Curse of Binding",
"enchantment.minecraft.blast_protection": "Blast Protection",
"enchantment.minecraft.breach": "Breach",
"enchantment.minecraft.channeling": "Channeling",
"enchantment.minecraft.density": "Density",
"enchantment.minecraft.depth_strider": "Depth Strider",
"enchantment.minecraft.efficiency": "Efficiency",
"enchantment.minecraft.feather_falling": "Feather Falling",
@ -3184,12 +3288,15 @@
"enchantment.minecraft.smite": "Smite",
"enchantment.minecraft.soul_speed": "Soul Speed",
"enchantment.minecraft.sweeping": "Sweeping Edge",
"enchantment.minecraft.sweeping_edge": "Sweeping Edge",
"enchantment.minecraft.swift_sneak": "Swift Sneak",
"enchantment.minecraft.thorns": "Thorns",
"enchantment.minecraft.unbreaking": "Unbreaking",
"enchantment.minecraft.vanishing_curse": "Curse of Vanishing",
"enchantment.minecraft.wind_burst": "Wind Burst",
"entity.minecraft.allay": "Allay",
"entity.minecraft.area_effect_cloud": "Area Effect Cloud",
"entity.minecraft.armadillo": "Armadillo",
"entity.minecraft.armor_stand": "Armor Stand",
"entity.minecraft.arrow": "Arrow",
"entity.minecraft.axolotl": "Axolotl",
@ -3198,7 +3305,9 @@
"entity.minecraft.blaze": "Blaze",
"entity.minecraft.block_display": "Block Display",
"entity.minecraft.boat": "Boat",
"entity.minecraft.bogged": "Bogged",
"entity.minecraft.breeze": "Breeze",
"entity.minecraft.breeze_wind_charge": "Wind Charge",
"entity.minecraft.camel": "Camel",
"entity.minecraft.cat": "Cat",
"entity.minecraft.cave_spider": "Cave Spider",
@ -3260,6 +3369,7 @@
"entity.minecraft.mooshroom": "Mooshroom",
"entity.minecraft.mule": "Mule",
"entity.minecraft.ocelot": "Ocelot",
"entity.minecraft.ominous_item_spawner": "Ominous Item Spawner",
"entity.minecraft.painting": "Painting",
"entity.minecraft.panda": "Panda",
"entity.minecraft.parrot": "Parrot",
@ -3381,6 +3491,7 @@
"filled_map.mansion": "Woodland Explorer Map",
"filled_map.monument": "Ocean Explorer Map",
"filled_map.scale": "Scaling at 1:%s",
"filled_map.trial_chambers": "Trial Chambers Map",
"filled_map.unknown": "Unknown Map",
"filled_map.village_desert": "Desert Village Map",
"filled_map.village_plains": "Plains Village Map",
@ -3476,7 +3587,10 @@
"gamerule.showDeathMessages": "Show death messages",
"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.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.description": "Controls the size of the area around the spawn point that players can spawn in.",
"gamerule.spectatorsGenerateChunks": "Allow spectators to generate terrain",
"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.",
@ -3700,7 +3814,9 @@
"item_modifier.unknown": "Unknown item modifier: %s",
"item.canBreak": "Can break:",
"item.canPlace": "Can be placed on:",
"item.canUse.unknown": "Unknown",
"item.color": "Color: %s",
"item.components": "%s component(s)",
"item.disabled": "Disabled item",
"item.durability": "Durability: %s / %s",
"item.dyed": "Dyed",
@ -3713,6 +3829,8 @@
"item.minecraft.apple": "Apple",
"item.minecraft.archer_pottery_shard": "Archer Pottery Shard",
"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.arms_up_pottery_shard": "Arms Up Pottery Shard",
"item.minecraft.arms_up_pottery_sherd": "Arms Up Pottery Sherd",
@ -3737,12 +3855,15 @@
"item.minecraft.blaze_rod": "Blaze Rod",
"item.minecraft.blaze_spawn_egg": "Blaze Spawn Egg",
"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_meal": "Bone Meal",
"item.minecraft.book": "Book",
"item.minecraft.bow": "Bow",
"item.minecraft.bowl": "Bowl",
"item.minecraft.bread": "Bread",
"item.minecraft.breeze_rod": "Breeze Rod",
"item.minecraft.breeze_spawn_egg": "Breeze Spawn Egg",
"item.minecraft.brewer_pottery_shard": "Brewer Pottery Shard",
"item.minecraft.brewer_pottery_sherd": "Brewer Pottery Sherd",
@ -3879,6 +4000,10 @@
"item.minecraft.fishing_rod": "Fishing Rod",
"item.minecraft.flint": "Flint",
"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.desc": "Flower Charge",
"item.minecraft.flower_pot": "Flower Pot",
@ -3918,6 +4043,9 @@
"item.minecraft.green_dye": "Green Dye",
"item.minecraft.guardian_spawn_egg": "Guardian Spawn Egg",
"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_pottery_shard": "Heart Pottery Shard",
"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.harming": "Lingering Potion of Harming",
"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.leaping": "Lingering Potion of Leaping",
"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.mundane": "Mundane Lingering Potion",
"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.regeneration": "Lingering Potion of Regeneration",
"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_breathing": "Lingering Potion of Water Breathing",
"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.lodestone_compass": "Lodestone Compass",
"item.minecraft.mace": "Mace",
"item.minecraft.magenta_dye": "Magenta Dye",
"item.minecraft.magma_cream": "Magma Cream",
"item.minecraft.magma_cube_spawn_egg": "Magma Cube Spawn Egg",
@ -4059,6 +4192,8 @@
"item.minecraft.oak_boat": "Oak Boat",
"item.minecraft.oak_chest_boat": "Oak Boat with Chest",
"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.painting": "Painting",
"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.harming": "Potion of Harming",
"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.leaping": "Potion of Leaping",
"item.minecraft.potion.effect.levitation": "Potion of Levitation",
"item.minecraft.potion.effect.luck": "Potion of Luck",
"item.minecraft.potion.effect.mundane": "Mundane Potion",
"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.regeneration": "Potion of Regeneration",
"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_breathing": "Potion of Water Breathing",
"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_arms_up": "Arms Up Pottery Shard",
"item.minecraft.pottery_shard_prize": "Prize Pottery Shard",
@ -4140,6 +4279,7 @@
"item.minecraft.salmon": "Raw Salmon",
"item.minecraft.salmon_bucket": "Bucket of Salmon",
"item.minecraft.salmon_spawn_egg": "Salmon Spawn Egg",
"item.minecraft.scrape_pottery_sherd": "Scrape Pottery Sherd",
"item.minecraft.scute": "Scute",
"item.minecraft.sentry_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.harming": "Splash Potion of Harming",
"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.leaping": "Splash Potion of Leaping",
"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.mundane": "Mundane Splash Potion",
"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.regeneration": "Splash Potion of Regeneration",
"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_breathing": "Splash Potion of Water Breathing",
"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_chest_boat": "Spruce Boat with Chest",
"item.minecraft.spyglass": "Spyglass",
@ -4249,12 +4393,14 @@
"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.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.leaping": "Arrow of Leaping",
"item.minecraft.tipped_arrow.effect.levitation": "Arrow of Levitation",
"item.minecraft.tipped_arrow.effect.luck": "Arrow of Luck",
"item.minecraft.tipped_arrow.effect.mundane": "Tipped Arrow",
"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.regeneration": "Arrow of Regeneration",
"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_breathing": "Arrow of Water Breathing",
"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.torchflower_seeds": "Torchflower Seeds",
"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_spawn_egg": "Tropical Fish Spawn Egg",
"item.minecraft.turtle_helmet": "Turtle Shell",
"item.minecraft.turtle_scute": "Turtle Scute",
"item.minecraft.turtle_spawn_egg": "Turtle Spawn Egg",
"item.minecraft.vex_armor_trim_smithing_template": "Smithing Template",
"item.minecraft.vex_spawn_egg": "Vex Spawn Egg",
@ -4291,9 +4440,11 @@
"item.minecraft.wheat_seeds": "Wheat Seeds",
"item.minecraft.white_dye": "White Dye",
"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.wither_skeleton_spawn_egg": "Wither Skeleton 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.wooden_axe": "Wooden Axe",
"item.minecraft.wooden_hoe": "Wooden Hoe",
@ -4308,6 +4459,7 @@
"item.minecraft.zombie_spawn_egg": "Zombie Spawn Egg",
"item.minecraft.zombie_villager_spawn_egg": "Zombie Villager 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.feet": "When on Feet:",
"item.modifiers.head": "When on Head:",
@ -4516,6 +4668,7 @@
"mco.backup.entry.worldType": "World Type",
"mco.backup.generate.world": "Generate world",
"mco.backup.info.title": "Changes From Last Backup",
"mco.backup.narration": "Backup from %s",
"mco.backup.nobackups": "This realm doesn't have any backups currently.",
"mco.backup.restoring": "Restoring your realm",
"mco.backup.unknown": "UNKNOWN",
@ -4533,6 +4686,8 @@
"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.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.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\".",
@ -4556,7 +4711,7 @@
"mco.configure.world.buttons.resetworld": "Reset World",
"mco.configure.world.buttons.settings": "Settings",
"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.line2": "Are you sure you want to continue?",
"mco.configure.world.closing": "Closing the realm...",
@ -4574,7 +4729,7 @@
"mco.configure.world.invite.profile.name": "Name",
"mco.configure.world.invited": "Invited",
"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.remove.tooltip": "Remove",
"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.ok": "Ok",
"mco.info": "Info!",
"mco.invited.player.narration": "Invited player %s",
"mco.invites.button.accept": "Accept",
"mco.invites.button.reject": "Reject",
"mco.invites.nopending": "No pending invites!",
"mco.invites.pending": "New invite(s)!",
"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.line2": "You can later return to your original world without losing anything.",
"mco.minigame.world.noSelection": "Please make a selection",
"mco.minigame.world.restore": "Ending minigame...",
"mco.minigame.world.restore": "Ending Minigame...",
"mco.minigame.world.restore.question.line1": "The minigame will end and your realm will be restored.",
"mco.minigame.world.restore.question.line2": "Are you sure you want to continue?",
"mco.minigame.world.selected": "Selected minigame:",
"mco.minigame.world.slot.screen.title": "Switching world...",
"mco.minigame.world.selected": "Selected Minigame:",
"mco.minigame.world.slot.screen.title": "Switching World...",
"mco.minigame.world.startButton": "Switch",
"mco.minigame.world.starting.screen.title": "Starting minigame...",
"mco.minigame.world.stopButton": "End minigame",
"mco.minigame.world.starting.screen.title": "Starting Minigame...",
"mco.minigame.world.stopButton": "End Minigame",
"mco.minigame.world.switch.new": "Select another minigame?",
"mco.minigame.world.switch.title": "Switch minigame",
"mco.minigame.world.title": "Switch realm to minigame",
"mco.minigame.world.switch.title": "Switch Minigame",
"mco.minigame.world.title": "Switch Realm to Minigame",
"mco.news": "Realms news",
"mco.notification.dismiss": "Dismiss",
"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.done": "Upload done",
"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.failed": "Upload failed! (%s)",
"mco.upload.hardcore": "Hardcore worlds can't be uploaded!",
@ -4882,6 +5039,7 @@
"multiplayer.disconnect.server_shutdown": "Server closed",
"multiplayer.disconnect.slow_login": "Took too long to log in",
"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.unsigned_chat": "Received chat packet with missing or invalid signature.",
"multiplayer.disconnect.unverified_username": "Failed to verify username!",
@ -4986,13 +5144,21 @@
"optimizeWorld.stage.counting": "Counting chunks...",
"optimizeWorld.stage.failed": "Failed! :(",
"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.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'",
"options.accessibility": "Accessibility Settings...",
"options.accessibility.high_contrast": "High Contrast",
"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.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.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'",
@ -5071,6 +5237,8 @@
"options.discrete_mouse_scroll": "Discrete Scrolling",
"options.entityDistanceScaling": "Entity Distance",
"options.entityShadows": "Entity Shadows",
"options.font": "Font Settings...",
"options.font.title": "Font Settings",
"options.forceUnicodeFont": "Force Unicode Font",
"options.fov": "FOV",
"options.fov.max": "Quake Pro",
@ -5118,6 +5286,8 @@
"options.hideSplashTexts": "Hide Splash Texts",
"options.hideSplashTexts.tooltip": "Hides the yellow splash text in the main menu.",
"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.toggle": "Toggle",
"options.language": "Language...",
@ -5191,6 +5361,7 @@
"options.telemetry": "Telemetry Data...",
"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.disabled": "Telemetry is disabled.",
"options.telemetry.state.all": "All",
"options.telemetry.state.minimal": "Minimal",
"options.telemetry.state.none": "None",
@ -5300,6 +5471,7 @@
"parsing.quote.escape": "Invalid escape sequence '\\%s' in quoted string",
"parsing.quote.expected.end": "Unclosed quoted string",
"parsing.quote.expected.start": "Expected quote to start a string",
"particle.invalidOptions": "Can't parse particle options: %s",
"particle.notFound": "Unknown particle: %s",
"permissions.requires.entity": "An entity 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.allowCommands": "Allow Cheats",
"selectWorld.allowCommands.info": "Commands like /gamemode, /experience",
"selectWorld.allowCommands.new": "Allow Commands",
"selectWorld.backupEraseCache": "Erase Cached Data",
"selectWorld.backupJoinConfirmButton": "Create Backup and Load",
"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.bonusItems": "Bonus Chest",
"selectWorld.cheats": "Cheats",
"selectWorld.commands": "Commands",
"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.create": "Create New World",
@ -5482,11 +5656,14 @@
"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.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",
"sign.edit": "Edit Sign Message",
"sleep.not_possible": "No amount of rest can pass this night",
"sleep.players_sleeping": "%s/%s players sleeping",
"sleep.skipping_night": "Sleeping through this night",
"slot.only_single_allowed": "Only single slots allowed, got '%s'",
"slot.unknown": "Unknown slot '%s'",
"soundCategory.ambient": "Ambient/Environment",
"soundCategory.block": "Blocks",
@ -5671,6 +5848,7 @@
"subtitles.block.cake.add_candle": "Cake squishes",
"subtitles.block.campfire.crackle": "Campfire crackles",
"subtitles.block.candle.crackle": "Candle crackles",
"subtitles.block.candle.extinguish": "Candle extinguishes",
"subtitles.block.chest.close": "Chest closes",
"subtitles.block.chest.locked": "Chest locked",
"subtitles.block.chest.open": "Chest opens",
@ -5730,7 +5908,7 @@
"subtitles.block.pressure_plate.click": "Pressure Plate clicks",
"subtitles.block.pumpkin.carve": "Shears carve",
"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.deplete": "Respawn Anchor depletes",
"subtitles.block.respawn_anchor.set_spawn": "Respawn Anchor sets spawn",
@ -5751,16 +5929,30 @@
"subtitles.block.sponge.absorb": "Sponge sucks",
"subtitles.block.sweet_berry_bush.pick_berries": "Berries pop",
"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_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.detect_player": "Trial Spawner charges up",
"subtitles.block.trial_spawner.eject_item": "Trial Spawner ejects items",
"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.click": "Tripwire clicks",
"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.wet_sponge.dries": "Sponge dries",
"subtitles.chiseled_bookshelf.insert": "Book placed",
"subtitles.chiseled_bookshelf.insert_enchanted": "Enchanted Book placed",
"subtitles.chiseled_bookshelf.take": "Book taken",
@ -5773,6 +5965,18 @@
"subtitles.entity.allay.item_given": "Allay chortles",
"subtitles.entity.allay.item_taken": "Allay allays",
"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.arrow.hit": "Arrow hits",
"subtitles.entity.arrow.hit_player": "Player hit",
@ -5802,7 +6006,12 @@
"subtitles.entity.blaze.shoot": "Blaze shoots",
"subtitles.entity.boat.paddle_land": "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.deflect": "Breeze deflects",
"subtitles.entity.breeze.hurt": "Breeze hurts",
"subtitles.entity.breeze.idle_air": "Breeze flies",
"subtitles.entity.breeze.idle_ground": "Breeze whirs",
@ -5811,6 +6020,8 @@
"subtitles.entity.breeze.land": "Breeze lands",
"subtitles.entity.breeze.shoot": "Breeze shoots",
"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.dash": "Camel yeets",
"subtitles.entity.camel.dash_ready": "Camel recovers",
@ -5859,6 +6070,7 @@
"subtitles.entity.donkey.death": "Donkey dies",
"subtitles.entity.donkey.eat": "Donkey eats",
"subtitles.entity.donkey.hurt": "Donkey hurts",
"subtitles.entity.donkey.jump": "Donkey jumps",
"subtitles.entity.drowned.ambient": "Drowned gurgles",
"subtitles.entity.drowned.ambient_water": "Drowned gurgles",
"subtitles.entity.drowned.death": "Drowned dies",
@ -5941,7 +6153,7 @@
"subtitles.entity.ghast.hurt": "Ghast hurts",
"subtitles.entity.ghast.shoot": "Ghast shoots",
"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.remove_item": "Glow Item Frame empties",
"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.repair": "Iron Golem repaired",
"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.remove_item": "Item Frame empties",
"subtitles.entity.item_frame.rotate_item": "Item Frame clicks",
"subtitles.entity.item.break": "Item breaks",
"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.lightning_bolt.impact": "Lightning strikes",
"subtitles.entity.lightning_bolt.thunder": "Thunder roars",
@ -6034,7 +6246,8 @@
"subtitles.entity.mule.death": "Mule dies",
"subtitles.entity.mule.eat": "Mule eats",
"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.panda.aggressive_ambient": "Panda huffs",
"subtitles.entity.panda.ambient": "Panda pants",
@ -6053,6 +6266,7 @@
"subtitles.entity.parrot.fly": "Parrot flutters",
"subtitles.entity.parrot.hurts": "Parrot hurts",
"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.creeper": "Parrot hisses",
"subtitles.entity.parrot.imitate.drowned": "Parrot gurgles",
@ -6130,7 +6344,7 @@
"subtitles.entity.player.levelup": "Player dings",
"subtitles.entity.player.teleport": "Player teleports",
"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.hurt": "Polar Bear hurts",
"subtitles.entity.polar_bear.warning": "Polar Bear roars",
@ -6229,15 +6443,15 @@
"subtitles.entity.tropical_fish.hurt": "Tropical Fish hurts",
"subtitles.entity.turtle.ambient_land": "Turtle chirps",
"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_crack": "Turtle Egg cracks",
"subtitles.entity.turtle.egg_hatch": "Turtle Egg hatches",
"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.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.vex.ambient": "Vex vexes",
"subtitles.entity.vex.charge": "Vex shrieks",
@ -6297,6 +6511,8 @@
"subtitles.entity.warden.sonic_charge": "Warden charges",
"subtitles.entity.warden.step": "Warden steps",
"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.celebrate": "Witch cheers",
"subtitles.entity.witch.death": "Witch dies",
@ -6342,6 +6558,9 @@
"subtitles.entity.zombified_piglin.angry": "Zombified Piglin grunts angrily",
"subtitles.entity.zombified_piglin.death": "Zombified Piglin dies",
"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.item.armor.equip": "Gear equips",
"subtitles.item.armor.equip_chain": "Chain armor jingles",
@ -6352,6 +6571,8 @@
"subtitles.item.armor.equip_leather": "Leather armor rustles",
"subtitles.item.armor.equip_netherite": "Netherite armor clanks",
"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.strip": "Axe strips",
"subtitles.item.axe.wax_off": "Wax off",
@ -6389,7 +6610,10 @@
"subtitles.item.honeycomb.wax_on": "Wax on",
"subtitles.item.ink_sac.use": "Ink Sac splotches",
"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.ominous_bottle.dispose": "Bottle breaks",
"subtitles.item.shears.shear": "Shears click",
"subtitles.item.shield.block": "Shield blocks",
"subtitles.item.shovel.flatten": "Shovel flattens",
@ -6402,6 +6626,10 @@
"subtitles.item.trident.riptide": "Trident zooms",
"subtitles.item.trident.throw": "Trident clangs",
"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.ui.cartography_table.take_result": "Map drawn",
"subtitles.ui.loom.take_result": "Loom used",
@ -6506,9 +6734,11 @@
"trim_material.minecraft.netherite": "Netherite Material",
"trim_material.minecraft.quartz": "Quartz Material",
"trim_material.minecraft.redstone": "Redstone Material",
"trim_pattern.minecraft.bolt": "Bolt Armor Trim",
"trim_pattern.minecraft.coast": "Coast Armor Trim",
"trim_pattern.minecraft.dune": "Dune 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.raiser": "Raiser Armor Trim",
"trim_pattern.minecraft.rib": "Rib Armor Trim",

View file

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

View file

@ -24,8 +24,6 @@ azalea-core = { path = "../azalea-core", optional = true, version = "0.9.0", fea
"serde",
] }
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-registry = { path = "../azalea-registry", 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"
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"
[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 {
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")
};
let variant_name = variant_name_from(&ident);

View file

@ -104,12 +104,12 @@ pub struct WriteConnection<W: ProtocolPacket> {
/// let packet = conn.read().await?;
/// match packet {
/// 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(
/// ServerboundKeyPacket {
/// key_bytes: e.encrypted_public_key,
/// encrypted_challenge: e.encrypted_nonce,
/// encrypted_challenge: e.encrypted_challenge,
/// }
/// .get(),
/// )
@ -127,6 +127,7 @@ pub struct WriteConnection<W: ProtocolPacket> {
/// return Err("login disconnect".into());
/// }
/// ClientboundLoginPacket::CustomQuery(p) => {}
/// ClientboundLoginPacket::CookieRequest(_) => {}
/// }
/// };
///
@ -404,7 +405,7 @@ impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
/// match conn.read().await? {
/// ClientboundLoginPacket::Hello(p) => {
/// // 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(
/// &access_token,
/// &profile.id,
@ -414,7 +415,7 @@ impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
/// conn.write(
/// ServerboundKeyPacket {
/// key_bytes: e.encrypted_public_key,
/// encrypted_challenge: e.encrypted_nonce,
/// encrypted_challenge: e.encrypted_challenge,
/// }.get()
/// ).await?;
/// conn.set_encryption_key(e.secret_key);

View file

@ -7,7 +7,7 @@ use azalea_core::{
#[derive(Clone, Debug, McBuf)]
pub struct CommonPlayerSpawnInfo {
pub dimension_type: ResourceLocation,
pub dimension_type: azalea_registry::DimensionType,
pub dimension: ResourceLocation,
pub seed: i64,
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_core::registry_holder::RegistryHolder;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundConfigurationPacket;
use simdnbt::owned::NbtCompound;
#[derive(Clone, Debug, McBuf, ClientboundConfigurationPacket)]
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_disconnect_packet;
pub mod clientbound_finish_configuration_packet;
pub mod clientbound_keep_alive_packet;
pub mod clientbound_ping_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_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_tags_packet;
pub mod serverbound_client_information_packet;
pub mod serverbound_cookie_response_packet;
pub mod serverbound_custom_payload_packet;
pub mod serverbound_finish_configuration_packet;
pub mod serverbound_keep_alive_packet;
pub mod serverbound_pong_packet;
pub mod serverbound_resource_pack_packet;
pub mod serverbound_select_known_packs_packet;
use azalea_protocol_macros::declare_state_packets;
declare_state_packets!(
ConfigurationPacket,
Serverbound => {
0x00: serverbound_client_information_packet::ServerboundClientInformationPacket,
0x01: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
0x02: serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket,
0x03: serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
0x04: serverbound_pong_packet::ServerboundPongPacket,
0x05: serverbound_resource_pack_packet::ServerboundResourcePackPacket,
0x01: serverbound_cookie_response_packet::ServerboundCookieResponsePacket,
0x02: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
0x03: serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket,
0x04: serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
0x05: serverbound_pong_packet::ServerboundPongPacket,
0x06: serverbound_resource_pack_packet::ServerboundResourcePackPacket,
0x07: serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket,
},
Clientbound => {
0x00: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
0x01: clientbound_disconnect_packet::ClientboundDisconnectPacket,
0x02: clientbound_finish_configuration_packet::ClientboundFinishConfigurationPacket,
0x03: clientbound_keep_alive_packet::ClientboundKeepAlivePacket,
0x04: clientbound_ping_packet::ClientboundPingPacket,
0x05: clientbound_registry_data_packet::ClientboundRegistryDataPacket,
0x06: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket,
0x07: clientbound_resource_pack_push_packet::ClientboundResourcePackPushPacket,
0x08: clientbound_update_enabled_features_packet::ClientboundUpdateEnabledFeaturesPacket,
0x09: clientbound_update_tags_packet::ClientboundUpdateTagsPacket,
0x00: clientbound_cookie_request_packet::ClientboundCookieRequestPacket,
0x01: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
0x02: clientbound_disconnect_packet::ClientboundDisconnectPacket,
0x03: clientbound_finish_configuration_packet::ClientboundFinishConfigurationPacket,
0x04: clientbound_keep_alive_packet::ClientboundKeepAlivePacket,
0x05: clientbound_ping_packet::ClientboundPingPacket,
0x06: clientbound_reset_chat_packet::ClientboundResetChatPacket,
0x07: clientbound_registry_data_packet::ClientboundRegistryDataPacket,
0x08: clientbound_resource_pack_pop_packet::ClientboundResourcePackPopPacket,
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,
}
// 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 {
/// Make the entity into a bundle that can be inserted into the ECS. You
/// must apply the metadata after inserting the bundle with

View file

@ -128,6 +128,7 @@ pub enum BrigadierParser {
Swizzle,
Team,
ItemSlot,
ItemSlots,
ResourceLocation,
Function,
EntityAnchor,
@ -143,6 +144,9 @@ pub enum BrigadierParser {
TemplateMirror,
TemplateRotation,
Heightmap,
LootTable,
LootPredicate,
LootModifier,
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_core::particle::ParticleData;
use azalea_buf::McBuf;
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 {
#[var]
pub particle_id: u32,
pub override_limiter: bool,
pub x: f64,
pub y: f64,
@ -15,54 +12,7 @@ pub struct ClientboundLevelParticlesPacket {
pub y_dist: f32,
pub z_dist: f32,
pub max_speed: f32,
#[var]
pub count: u32,
pub data: ParticleData,
}
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(())
}
pub particle: ParticleKind,
}

View file

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

View file

@ -6,5 +6,4 @@ use azalea_protocol_macros::ClientboundGamePacket;
pub struct ClientboundServerDataPacket {
pub motd: FormattedText,
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)]
pub struct ClientboundSetEquipmentPacket {
#[var]
pub entity: i32,
pub entity_id: u32,
pub slots: EquipmentSlots,
}

View file

@ -1,15 +1,27 @@
use super::clientbound_sound_packet::SoundSource;
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::OptionalRegistry;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundEntityPacket {
pub sound: OptionalRegistry<azalea_registry::SoundEvent>,
pub source: SoundSource,
#[var]
pub id: u32,
pub volume: f32,
pub pitch: f32,
#[var]
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_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::SoundEvent;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundPacket {
pub sound: azalea_registry::CustomRegistry<azalea_registry::SoundEvent, CustomSoundEvent>,
pub sound: SoundEvent,
pub source: SoundSource,
pub x: i32,
pub y: i32,
@ -14,12 +14,6 @@ pub struct ClientboundSoundPacket {
pub seed: u64,
}
#[derive(McBuf, Clone, Debug)]
pub struct CustomSoundEvent {
pub location: ResourceLocation,
pub range: Option<f32>,
}
#[derive(McBuf, Clone, Copy, Debug)]
pub enum SoundSource {
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_core::resource_location::ResourceLocation;
use azalea_entity::attributes::AttributeModifier;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::Attribute;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateAttributesPacket {
#[var]
pub entity_id: u32,
pub attributes: Vec<AttributeSnapshot>,
pub values: Vec<AttributeSnapshot>,
}
#[derive(Clone, Debug, McBuf)]
pub struct AttributeSnapshot {
pub attribute: ResourceLocation,
pub attribute: Attribute,
pub base: f64,
pub modifiers: Vec<AttributeModifier>,
}

View file

@ -1,15 +1,15 @@
use azalea_buf::McBuf;
use azalea_protocol_macros::ClientboundGamePacket;
use simdnbt::owned::NbtTag;
use azalea_registry::MobEffect;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateMobEffectPacket {
#[var]
pub entity_id: u32,
pub effect: azalea_registry::MobEffect,
pub effect_amplifier: u8,
pub mob_effect: MobEffect,
#[var]
pub effect_amplifier: u32,
#[var]
pub effect_duration_ticks: u32,
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_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::RecipeSerializer;
use std::io::{Cursor, Write};
use std::str::FromStr;
#[derive(Clone, Debug, McBuf, PartialEq, ClientboundGamePacket)]
pub struct ClientboundUpdateRecipesPacket {
pub recipes: Vec<Recipe>,
pub recipes: Vec<RecipeHolder>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Recipe {
pub identifier: ResourceLocation,
#[derive(Clone, Debug, PartialEq, McBuf)]
pub struct RecipeHolder {
pub id: ResourceLocation,
pub data: RecipeData,
}
@ -156,147 +154,6 @@ pub struct Ingredient {
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)]
mod tests {
use super::*;
@ -304,8 +161,8 @@ mod tests {
#[test]
fn test_crafting_shaped() {
let mut buf = Vec::new();
let recipe = Recipe {
identifier: ResourceLocation::new("minecraft:crafting_shaped"),
let recipe = RecipeHolder {
id: ResourceLocation::new("minecraft:crafting_shaped"),
data: RecipeData::CraftingShaped(ShapedRecipe {
group: String::new(),
category: CraftingBookCategory::Building,
@ -332,15 +189,15 @@ mod tests {
}),
};
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);
}
#[test]
fn test_crafting_shapeless() {
let mut buf = Vec::new();
let recipe = Recipe {
identifier: ResourceLocation::new("minecraft:crafting_shapeless"),
let recipe = RecipeHolder {
id: ResourceLocation::new("minecraft:crafting_shapeless"),
data: RecipeData::CraftingShapeless(ShapelessRecipe {
group: String::new(),
category: CraftingBookCategory::Building,
@ -362,21 +219,21 @@ mod tests {
}),
};
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);
}
#[test]
fn test_crafting_special_armordye() {
let mut buf = Vec::new();
let recipe = Recipe {
identifier: ResourceLocation::new("minecraft:crafting_special_armordye"),
let recipe = RecipeHolder {
id: ResourceLocation::new("minecraft:crafting_special_armordye"),
data: RecipeData::CraftingSpecialArmorDye(SimpleRecipe {
category: CraftingBookCategory::Building,
}),
};
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);
}
}

View file

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

View file

@ -7,5 +7,6 @@ pub struct ClientboundHelloPacket {
// #[len(20)]
pub server_id: String,
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_game_profile_packet;
pub mod clientbound_hello_packet;
pub mod clientbound_login_compression_packet;
pub mod clientbound_login_disconnect_packet;
pub mod serverbound_cookie_response_packet;
pub mod serverbound_custom_query_answer_packet;
pub mod serverbound_hello_packet;
pub mod serverbound_key_packet;
@ -17,6 +19,7 @@ declare_state_packets!(
0x01: serverbound_key_packet::ServerboundKeyPacket,
0x02: serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket,
0x03: serverbound_login_acknowledged_packet::ServerboundLoginAcknowledgedPacket,
0x04: serverbound_cookie_response_packet::ServerboundCookieResponsePacket,
},
Clientbound => {
0x00: clientbound_login_disconnect_packet::ClientboundLoginDisconnectPacket,
@ -24,5 +27,6 @@ declare_state_packets!(
0x02: clientbound_game_profile_packet::ClientboundGameProfilePacket,
0x03: clientbound_login_compression_packet::ClientboundLoginCompressionPacket,
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
// clientbound_add_entity_packet
pub const PROTOCOL_VERSION: i32 = 765;
pub const PROTOCOL_VERSION: i32 = 766;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
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
// want)
mod extra;
pub mod tags;
use std::io::{Cursor, Write};
@ -12,7 +13,9 @@ use std::io::{Cursor, Write};
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
use azalea_registry_macros::registry;
pub trait Registry
pub use extra::*;
pub trait Registry: McBufReadable + McBufWritable
where
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! {
/// The AI code that's currently being executed for the entity.
enum Activity {
@ -116,15 +171,23 @@ enum Attribute {
GenericAttackDamage => "minecraft:generic.attack_damage",
GenericAttackKnockback => "minecraft:generic.attack_knockback",
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",
GenericFollowRange => "minecraft:generic.follow_range",
HorseJumpStrength => "minecraft:horse.jump_strength",
GenericGravity => "minecraft:generic.gravity",
GenericJumpStrength => "minecraft:generic.jump_strength",
GenericKnockbackResistance => "minecraft:generic.knockback_resistance",
GenericLuck => "minecraft:generic.luck",
GenericMaxAbsorption => "minecraft:generic.max_absorption",
GenericMaxHealth => "minecraft:generic.max_health",
GenericMovementSpeed => "minecraft:generic.movement_speed",
GenericSafeFallDistance => "minecraft:generic.safe_fall_distance",
GenericScale => "minecraft:generic.scale",
ZombieSpawnReinforcements => "minecraft:zombie.spawn_reinforcements",
GenericStepHeight => "minecraft:generic.step_height",
}
}
@ -1239,6 +1302,8 @@ enum Block {
DecoratedPot => "minecraft:decorated_pot",
Crafter => "minecraft:crafter",
TrialSpawner => "minecraft:trial_spawner",
Vault => "minecraft:vault",
HeavyCore => "minecraft:heavy_core",
}
}
@ -1290,6 +1355,7 @@ enum BlockEntityKind {
DecoratedPot => "minecraft:decorated_pot",
Crafter => "minecraft:crafter",
TrialSpawner => "minecraft:trial_spawner",
Vault => "minecraft:vault",
}
}
@ -1379,6 +1445,7 @@ enum CommandArgumentKind {
Swizzle => "minecraft:swizzle",
Team => "minecraft:team",
ItemSlot => "minecraft:item_slot",
ItemSlots => "minecraft:item_slots",
ResourceLocation => "minecraft:resource_location",
Function => "minecraft:function",
EntityAnchor => "minecraft:entity_anchor",
@ -1394,6 +1461,9 @@ enum CommandArgumentKind {
TemplateMirror => "minecraft:template_mirror",
TemplateRotation => "minecraft:template_rotation",
Heightmap => "minecraft:heightmap",
LootTable => "minecraft:loot_table",
LootPredicate => "minecraft:loot_predicate",
LootModifier => "minecraft:loot_modifier",
Uuid => "minecraft:uuid",
}
}
@ -1499,7 +1569,7 @@ enum Enchantment {
Knockback => "minecraft:knockback",
FireAspect => "minecraft:fire_aspect",
Looting => "minecraft:looting",
Sweeping => "minecraft:sweeping",
SweepingEdge => "minecraft:sweeping_edge",
Efficiency => "minecraft:efficiency",
SilkTouch => "minecraft:silk_touch",
Unbreaking => "minecraft:unbreaking",
@ -1517,6 +1587,9 @@ enum Enchantment {
Multishot => "minecraft:multishot",
QuickCharge => "minecraft:quick_charge",
Piercing => "minecraft:piercing",
Density => "minecraft:density",
Breach => "minecraft:breach",
WindBurst => "minecraft:wind_burst",
Mending => "minecraft:mending",
VanishingCurse => "minecraft:vanishing_curse",
}
@ -1527,6 +1600,7 @@ registry! {
enum EntityKind {
Allay => "minecraft:allay",
AreaEffectCloud => "minecraft:area_effect_cloud",
Armadillo => "minecraft:armadillo",
ArmorStand => "minecraft:armor_stand",
Arrow => "minecraft:arrow",
Axolotl => "minecraft:axolotl",
@ -1535,7 +1609,9 @@ enum EntityKind {
Blaze => "minecraft:blaze",
BlockDisplay => "minecraft:block_display",
Boat => "minecraft:boat",
Bogged => "minecraft:bogged",
Breeze => "minecraft:breeze",
BreezeWindCharge => "minecraft:breeze_wind_charge",
Camel => "minecraft:camel",
Cat => "minecraft:cat",
CaveSpider => "minecraft:cave_spider",
@ -1583,6 +1659,7 @@ enum EntityKind {
Item => "minecraft:item",
ItemDisplay => "minecraft:item_display",
ItemFrame => "minecraft:item_frame",
OminousItemSpawner => "minecraft:ominous_item_spawner",
Fireball => "minecraft:fireball",
LeashKnot => "minecraft:leash_knot",
LightningBolt => "minecraft:lightning_bolt",
@ -1868,6 +1945,7 @@ enum Item {
RawIronBlock => "minecraft:raw_iron_block",
RawCopperBlock => "minecraft:raw_copper_block",
RawGoldBlock => "minecraft:raw_gold_block",
HeavyCore => "minecraft:heavy_core",
AmethystBlock => "minecraft:amethyst_block",
BuddingAmethyst => "minecraft:budding_amethyst",
IronBlock => "minecraft:iron_block",
@ -2577,7 +2655,9 @@ enum Item {
StructureBlock => "minecraft:structure_block",
Jigsaw => "minecraft:jigsaw",
TurtleHelmet => "minecraft:turtle_helmet",
Scute => "minecraft:scute",
TurtleScute => "minecraft:turtle_scute",
ArmadilloScute => "minecraft:armadillo_scute",
WolfArmor => "minecraft:wolf_armor",
FlintAndSteel => "minecraft:flint_and_steel",
Apple => "minecraft:apple",
Bow => "minecraft:bow",
@ -2788,11 +2868,13 @@ enum Item {
Cauldron => "minecraft:cauldron",
EnderEye => "minecraft:ender_eye",
GlisteringMelonSlice => "minecraft:glistering_melon_slice",
ArmadilloSpawnEgg => "minecraft:armadillo_spawn_egg",
AllaySpawnEgg => "minecraft:allay_spawn_egg",
AxolotlSpawnEgg => "minecraft:axolotl_spawn_egg",
BatSpawnEgg => "minecraft:bat_spawn_egg",
BeeSpawnEgg => "minecraft:bee_spawn_egg",
BlazeSpawnEgg => "minecraft:blaze_spawn_egg",
BoggedSpawnEgg => "minecraft:bogged_spawn_egg",
BreezeSpawnEgg => "minecraft:breeze_spawn_egg",
CatSpawnEgg => "minecraft:cat_spawn_egg",
CamelSpawnEgg => "minecraft:camel_spawn_egg",
@ -2868,8 +2950,10 @@ enum Item {
ZombifiedPiglinSpawnEgg => "minecraft:zombified_piglin_spawn_egg",
ExperienceBottle => "minecraft:experience_bottle",
FireCharge => "minecraft:fire_charge",
WindCharge => "minecraft:wind_charge",
WritableBook => "minecraft:writable_book",
WrittenBook => "minecraft:written_book",
Mace => "minecraft:mace",
ItemFrame => "minecraft:item_frame",
GlowItemFrame => "minecraft:glow_item_frame",
FlowerPot => "minecraft:flower_pot",
@ -2974,6 +3058,8 @@ enum Item {
MojangBannerPattern => "minecraft:mojang_banner_pattern",
GlobeBannerPattern => "minecraft:globe_banner_pattern",
PiglinBannerPattern => "minecraft:piglin_banner_pattern",
FlowBannerPattern => "minecraft:flow_banner_pattern",
GusterBannerPattern => "minecraft:guster_banner_pattern",
GoatHorn => "minecraft:goat_horn",
Composter => "minecraft:composter",
Barrel => "minecraft:barrel",
@ -3057,6 +3143,8 @@ enum Item {
SilenceArmorTrimSmithingTemplate => "minecraft:silence_armor_trim_smithing_template",
RaiserArmorTrimSmithingTemplate => "minecraft:raiser_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",
ArcherPotterySherd => "minecraft:archer_pottery_sherd",
ArmsUpPotterySherd => "minecraft:arms_up_pottery_sherd",
@ -3065,7 +3153,9 @@ enum Item {
BurnPotterySherd => "minecraft:burn_pottery_sherd",
DangerPotterySherd => "minecraft:danger_pottery_sherd",
ExplorerPotterySherd => "minecraft:explorer_pottery_sherd",
FlowPotterySherd => "minecraft:flow_pottery_sherd",
FriendPotterySherd => "minecraft:friend_pottery_sherd",
GusterPotterySherd => "minecraft:guster_pottery_sherd",
HeartPotterySherd => "minecraft:heart_pottery_sherd",
HeartbreakPotterySherd => "minecraft:heartbreak_pottery_sherd",
HowlPotterySherd => "minecraft:howl_pottery_sherd",
@ -3073,6 +3163,7 @@ enum Item {
MournerPotterySherd => "minecraft:mourner_pottery_sherd",
PlentyPotterySherd => "minecraft:plenty_pottery_sherd",
PrizePotterySherd => "minecraft:prize_pottery_sherd",
ScrapePotterySherd => "minecraft:scrape_pottery_sherd",
SheafPotterySherd => "minecraft:sheaf_pottery_sherd",
ShelterPotterySherd => "minecraft:shelter_pottery_sherd",
SkullPotterySherd => "minecraft:skull_pottery_sherd",
@ -3095,6 +3186,10 @@ enum Item {
WaxedOxidizedCopperBulb => "minecraft:waxed_oxidized_copper_bulb",
TrialSpawner => "minecraft:trial_spawner",
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! {
enum LootFunctionKind {
SetCount => "minecraft:set_count",
SetItem => "minecraft:set_item",
EnchantWithLevels => "minecraft:enchant_with_levels",
EnchantRandomly => "minecraft:enchant_randomly",
SetEnchantments => "minecraft:set_enchantments",
SetNbt => "minecraft:set_nbt",
SetCustomData => "minecraft:set_custom_data",
SetComponents => "minecraft:set_components",
FurnaceSmelt => "minecraft:furnace_smelt",
LootingEnchant => "minecraft:looting_enchant",
SetDamage => "minecraft:set_damage",
@ -3137,19 +3234,30 @@ enum LootFunctionKind {
SetStewEffect => "minecraft:set_stew_effect",
CopyName => "minecraft:copy_name",
SetContents => "minecraft:set_contents",
ModifyContents => "minecraft:modify_contents",
Filtered => "minecraft:filtered",
LimitCount => "minecraft:limit_count",
ApplyBonus => "minecraft:apply_bonus",
SetLootTable => "minecraft:set_loot_table",
ExplosionDecay => "minecraft:explosion_decay",
SetLore => "minecraft:set_lore",
FillPlayerHead => "minecraft:fill_player_head",
CopyNbt => "minecraft:copy_nbt",
CopyCustomData => "minecraft:copy_custom_data",
CopyState => "minecraft:copy_state",
SetBannerPattern => "minecraft:set_banner_pattern",
SetPotion => "minecraft:set_potion",
SetInstrument => "minecraft:set_instrument",
Reference => "minecraft:reference",
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",
Binomial => "minecraft:binomial",
Score => "minecraft:score",
Storage => "minecraft:storage",
}
}
@ -3223,6 +3332,7 @@ enum MemoryModuleKind {
HeardBellTime => "minecraft:heard_bell_time",
CantReachWalkTargetSince => "minecraft:cant_reach_walk_target_since",
GolemDetectedRecently => "minecraft:golem_detected_recently",
DangerDetectedRecently => "minecraft:danger_detected_recently",
LastSlept => "minecraft:last_slept",
LastWoken => "minecraft:last_woken",
LastWorkedAtPoi => "minecraft:last_worked_at_poi",
@ -3295,6 +3405,7 @@ enum MemoryModuleKind {
BreezeShootCooldown => "minecraft:breeze_shoot_cooldown",
BreezeJumpInhaling => "minecraft:breeze_jump_inhaling",
BreezeJumpTarget => "minecraft:breeze_jump_target",
BreezeLeavingWater => "minecraft:breeze_leaving_water",
}
}
@ -3362,6 +3473,12 @@ enum MobEffect {
BadOmen => "minecraft:bad_omen",
HeroOfTheVillage => "minecraft:hero_of_the_village",
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! {
enum ParticleKind {
AmbientEntityEffect => "minecraft:ambient_entity_effect",
AngryVillager => "minecraft:angry_villager",
Block => "minecraft:block",
BlockMarker => "minecraft:block_marker",
@ -3427,12 +3543,15 @@ enum ParticleKind {
ExplosionEmitter => "minecraft:explosion_emitter",
Explosion => "minecraft:explosion",
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",
FallingDust => "minecraft:falling_dust",
Firework => "minecraft:firework",
Fishing => "minecraft:fishing",
Flame => "minecraft:flame",
Infested => "minecraft:infested",
CherryLeaves => "minecraft:cherry_leaves",
SculkSoul => "minecraft:sculk_soul",
SculkCharge => "minecraft:sculk_charge",
@ -3447,6 +3566,7 @@ enum ParticleKind {
Item => "minecraft:item",
Vibration => "minecraft:vibration",
ItemSlime => "minecraft:item_slime",
ItemCobweb => "minecraft:item_cobweb",
ItemSnowball => "minecraft:item_snowball",
LargeSmoke => "minecraft:large_smoke",
Lava => "minecraft:lava",
@ -3501,8 +3621,13 @@ enum ParticleKind {
Shriek => "minecraft:shriek",
EggCrack => "minecraft:egg_crack",
DustPlume => "minecraft:dust_plume",
GustDust => "minecraft:gust_dust",
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! {
enum Potion {
Empty => "minecraft:empty",
Water => "minecraft:water",
Mundane => "minecraft:mundane",
Thick => "minecraft:thick",
@ -3591,6 +3715,10 @@ enum Potion {
Luck => "minecraft:luck",
SlowFalling => "minecraft: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",
SecondaryPois => "minecraft:secondary_pois",
GolemDetected => "minecraft:golem_detected",
ArmadilloScareDetected => "minecraft:armadillo_scare_detected",
PiglinSpecificSensor => "minecraft:piglin_specific_sensor",
PiglinBruteSpecificSensor => "minecraft:piglin_brute_specific_sensor",
HoglinSpecificSensor => "minecraft:hoglin_specific_sensor",
@ -3675,6 +3804,7 @@ enum SensorKind {
GoatTemptations => "minecraft:goat_temptations",
FrogTemptations => "minecraft:frog_temptations",
CamelTemptations => "minecraft:camel_temptations",
ArmadilloTemptations => "minecraft:armadillo_temptations",
FrogAttackables => "minecraft:frog_attackables",
IsInWater => "minecraft:is_in_water",
WardenEntitySensor => "minecraft:warden_entity_sensor",
@ -3739,6 +3869,19 @@ enum SoundEvent {
BlockAnvilPlace => "minecraft:block.anvil.place",
BlockAnvilStep => "minecraft:block.anvil.step",
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",
ItemArmorEquipDiamond => "minecraft:item.armor.equip_diamond",
ItemArmorEquipElytra => "minecraft:item.armor.equip_elytra",
@ -3748,6 +3891,8 @@ enum SoundEvent {
ItemArmorEquipLeather => "minecraft:item.armor.equip_leather",
ItemArmorEquipNetherite => "minecraft:item.armor.equip_netherite",
ItemArmorEquipTurtle => "minecraft:item.armor.equip_turtle",
ItemArmorEquipWolf => "minecraft:item.armor.equip_wolf",
ItemArmorUnequipWolf => "minecraft:item.armor.unequip_wolf",
EntityArmorStandBreak => "minecraft:entity.armor_stand.break",
EntityArmorStandFall => "minecraft:entity.armor_stand.fall",
EntityArmorStandHit => "minecraft:entity.armor_stand.hit",
@ -3839,6 +3984,11 @@ enum SoundEvent {
EntityBlazeShoot => "minecraft:entity.blaze.shoot",
EntityBoatPaddleLand => "minecraft:entity.boat.paddle_land",
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",
BlockBoneBlockFall => "minecraft:block.bone_block.fall",
BlockBoneBlockHit => "minecraft:block.bone_block.hit",
@ -3851,6 +4001,8 @@ enum SoundEvent {
ItemBottleEmpty => "minecraft:item.bottle.empty",
ItemBottleFill => "minecraft:item.bottle.fill",
ItemBottleFillDragonbreath => "minecraft:item.bottle.fill_dragonbreath",
EntityBreezeCharge => "minecraft:entity.breeze.charge",
EntityBreezeDeflect => "minecraft:entity.breeze.deflect",
EntityBreezeInhale => "minecraft:entity.breeze.inhale",
EntityBreezeIdleGround => "minecraft:entity.breeze.idle_ground",
EntityBreezeIdleAir => "minecraft:entity.breeze.idle_air",
@ -3860,6 +4012,8 @@ enum SoundEvent {
EntityBreezeSlide => "minecraft:entity.breeze.slide",
EntityBreezeDeath => "minecraft:entity.breeze.death",
EntityBreezeHurt => "minecraft:entity.breeze.hurt",
EntityBreezeWhirl => "minecraft:entity.breeze.whirl",
EntityBreezeWindBurst => "minecraft:entity.breeze.wind_burst",
BlockBrewingStandBrew => "minecraft:block.brewing_stand.brew",
ItemBrushBrushingGeneric => "minecraft:item.brush.brushing.generic",
ItemBrushBrushingSand => "minecraft:item.brush.brushing.sand",
@ -3981,6 +4135,11 @@ enum SoundEvent {
BlockChorusFlowerDeath => "minecraft:block.chorus_flower.death",
BlockChorusFlowerGrow => "minecraft:block.chorus_flower.grow",
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",
EntityCodDeath => "minecraft:entity.cod.death",
EntityCodFlop => "minecraft:entity.cod.flop",
@ -4083,6 +4242,7 @@ enum SoundEvent {
EntityDonkeyDeath => "minecraft:entity.donkey.death",
EntityDonkeyEat => "minecraft:entity.donkey.eat",
EntityDonkeyHurt => "minecraft:entity.donkey.hurt",
EntityDonkeyJump => "minecraft:entity.donkey.jump",
BlockDripstoneBlockBreak => "minecraft:block.dripstone_block.break",
BlockDripstoneBlockStep => "minecraft:block.dripstone_block.step",
BlockDripstoneBlockPlace => "minecraft:block.dripstone_block.place",
@ -4313,6 +4473,11 @@ enum SoundEvent {
BlockHangingSignFall => "minecraft:block.hanging_sign.fall",
BlockHangingSignHit => "minecraft:block.hanging_sign.hit",
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",
BlockNetherWoodHangingSignBreak => "minecraft:block.nether_wood_hanging_sign.break",
BlockNetherWoodHangingSignFall => "minecraft:block.nether_wood_hanging_sign.fall",
@ -4329,8 +4494,13 @@ enum SoundEvent {
BlockTrialSpawnerHit => "minecraft:block.trial_spawner.hit",
BlockTrialSpawnerFall => "minecraft:block.trial_spawner.fall",
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",
BlockTrialSpawnerChargeActivate => "minecraft:block.trial_spawner.charge_activate",
BlockTrialSpawnerAmbient => "minecraft:block.trial_spawner.ambient",
BlockTrialSpawnerAmbientCharged => "minecraft:block.trial_spawner.ambient_charged",
BlockTrialSpawnerOpenShutter => "minecraft:block.trial_spawner.open_shutter",
BlockTrialSpawnerCloseShutter => "minecraft:block.trial_spawner.close_shutter",
BlockTrialSpawnerEjectItem => "minecraft:block.trial_spawner.eject_item",
@ -4445,6 +4615,9 @@ enum SoundEvent {
BlockLodestoneHit => "minecraft:block.lodestone.hit",
BlockLodestoneFall => "minecraft:block.lodestone.fall",
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",
EntityMagmaCubeHurt => "minecraft:entity.magma_cube.hurt",
EntityMagmaCubeHurtSmall => "minecraft:entity.magma_cube.hurt_small",
@ -4509,6 +4682,7 @@ enum SoundEvent {
EntityMuleDeath => "minecraft:entity.mule.death",
EntityMuleEat => "minecraft:entity.mule.eat",
EntityMuleHurt => "minecraft:entity.mule.hurt",
EntityMuleJump => "minecraft:entity.mule.jump",
MusicCreative => "minecraft:music.creative",
MusicCredits => "minecraft:music.credits",
MusicDisc5 => "minecraft:music_disc.5",
@ -4649,6 +4823,7 @@ enum SoundEvent {
EntityOcelotHurt => "minecraft:entity.ocelot.hurt",
EntityOcelotAmbient => "minecraft:entity.ocelot.ambient",
EntityOcelotDeath => "minecraft:entity.ocelot.death",
ItemOminousBottleDispose => "minecraft:item.ominous_bottle.dispose",
EntityPaintingBreak => "minecraft:entity.painting.break",
EntityPaintingPlace => "minecraft:entity.painting.place",
EntityPandaPreSneeze => "minecraft:entity.panda.pre_sneeze",
@ -4668,6 +4843,7 @@ enum SoundEvent {
EntityParrotFly => "minecraft:entity.parrot.fly",
EntityParrotHurt => "minecraft:entity.parrot.hurt",
EntityParrotImitateBlaze => "minecraft:entity.parrot.imitate.blaze",
EntityParrotImitateBogged => "minecraft:entity.parrot.imitate.bogged",
EntityParrotImitateBreeze => "minecraft:entity.parrot.imitate.breeze",
EntityParrotImitateCreeper => "minecraft:entity.parrot.imitate.creeper",
EntityParrotImitateDrowned => "minecraft:entity.parrot.imitate.drowned",
@ -5072,6 +5248,19 @@ enum SoundEvent {
UiToastChallengeComplete => "minecraft:ui.toast.challenge_complete",
UiToastIn => "minecraft:ui.toast.in",
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",
EntityVexCharge => "minecraft:entity.vex.charge",
EntityVexDeath => "minecraft:entity.vex.death",
@ -5147,11 +5336,13 @@ enum SoundEvent {
BlockWetGrassPlace => "minecraft:block.wet_grass.place",
BlockWetGrassStep => "minecraft:block.wet_grass.step",
BlockWetSpongeBreak => "minecraft:block.wet_sponge.break",
BlockWetSpongeDries => "minecraft:block.wet_sponge.dries",
BlockWetSpongeFall => "minecraft:block.wet_sponge.fall",
BlockWetSpongeHit => "minecraft:block.wet_sponge.hit",
BlockWetSpongePlace => "minecraft:block.wet_sponge.place",
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",
EntityWitchCelebrate => "minecraft:entity.witch.celebrate",
EntityWitchDeath => "minecraft:entity.witch.death",
@ -5168,6 +5359,10 @@ enum SoundEvent {
EntityWitherSkeletonHurt => "minecraft:entity.wither_skeleton.hurt",
EntityWitherSkeletonStep => "minecraft:entity.wither_skeleton.step",
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",
EntityWolfDeath => "minecraft:entity.wolf.death",
EntityWolfGrowl => "minecraft:entity.wolf.growl",
@ -5224,6 +5419,9 @@ enum SoundEvent {
EntityZombieVillagerDeath => "minecraft:entity.zombie_villager.death",
EntityZombieVillagerHurt => "minecraft:entity.zombie_villager.hurt",
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",
DangerPotteryPattern => "minecraft:danger_pottery_pattern",
ExplorerPotteryPattern => "minecraft:explorer_pottery_pattern",
FlowPotteryPattern => "minecraft:flow_pottery_pattern",
FriendPotteryPattern => "minecraft:friend_pottery_pattern",
GusterPotteryPattern => "minecraft:guster_pottery_pattern",
HeartPotteryPattern => "minecraft:heart_pottery_pattern",
HeartbreakPotteryPattern => "minecraft:heartbreak_pottery_pattern",
HowlPotteryPattern => "minecraft:howl_pottery_pattern",
@ -5646,6 +5846,7 @@ enum DecoratedPotPatterns {
MournerPotteryPattern => "minecraft:mourner_pottery_pattern",
PlentyPotteryPattern => "minecraft:plenty_pottery_pattern",
PrizePotteryPattern => "minecraft:prize_pottery_pattern",
ScrapePotteryPattern => "minecraft:scrape_pottery_pattern",
SheafPotteryPattern => "minecraft:sheaf_pottery_pattern",
ShelterPotteryPattern => "minecraft:shelter_pottery_pattern",
SkullPotteryPattern => "minecraft:skull_pottery_pattern",
@ -5813,6 +6014,7 @@ enum BlockKind {
HalfTransparent => "minecraft:half_transparent",
HangingRoots => "minecraft:hanging_roots",
Hay => "minecraft:hay",
HeavyCore => "minecraft:heavy_core",
Honey => "minecraft:honey",
Hopper => "minecraft:hopper",
HugeMushroom => "minecraft:huge_mushroom",
@ -5928,6 +6130,7 @@ enum BlockKind {
TurtleEgg => "minecraft:turtle_egg",
TwistingVinesPlant => "minecraft:twisting_vines_plant",
TwistingVines => "minecraft:twisting_vines",
Vault => "minecraft:vault",
Vine => "minecraft:vine",
WallBanner => "minecraft:wall_banner",
WallHangingSign => "minecraft:wall_hanging_sign",
@ -6005,6 +6208,8 @@ enum TriggerKind {
BeeNestDestroyed => "minecraft:bee_nest_destroyed",
TargetHit => "minecraft:target_hit",
ItemUsedOnBlock => "minecraft:item_used_on_block",
DefaultBlockUse => "minecraft:default_block_use",
AnyBlockUse => "minecraft:any_block_use",
PlayerGeneratesContainerLoot => "minecraft:player_generates_container_loot",
ThrownItemPickedUpByEntity => "minecraft:thrown_item_picked_up_by_entity",
ThrownItemPickedUpByPlayer => "minecraft:thrown_item_picked_up_by_player",
@ -6018,6 +6223,8 @@ enum TriggerKind {
AllayDropItemOnBlock => "minecraft:allay_drop_item_on_block",
AvoidVibration => "minecraft:avoid_vibration",
RecipeCrafted => "minecraft:recipe_crafted",
CrafterRecipeCrafted => "minecraft:crafter_recipe_crafted",
FallAfterExplosion => "minecraft:fall_after_explosion",
}
}
@ -6028,3 +6235,159 @@ enum NumberFormatKind {
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;
pub static LAVA: Lazy<HashSet<Fluid>> =
Lazy::new(|| HashSet::from_iter(vec![Fluid::Lava, Fluid::FlowingLava]));
pub static WATER: Lazy<HashSet<Fluid>> =
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 = [
"bevy_ecs",
] }
azalea-inventory = { version = "0.9.0", path = "../azalea-inventory" }
azalea-registry = { path = "../azalea-registry", version = "0.9.0" }
bevy_ecs = "0.13.2"
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-client = { version = "0.9.0", path = "../azalea-client", default-features = false }
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-protocol = { version = "0.9.0", path = "../azalea-protocol" }
azalea-registry = { version = "0.9.0", path = "../azalea-registry" }
@ -41,9 +40,10 @@ thiserror = "^1.0.58"
tokio = "^1.37.0"
uuid = "1.8.0"
bevy_log = "0.13.2"
azalea-entity = { version = "0.9.0", path = "../azalea-entity" }
bevy_time = "0.13.2"
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]
criterion = "0.5.1"

View file

@ -2,7 +2,7 @@ use azalea_block::{Block, BlockState};
use azalea_client::{inventory::InventoryComponent, Client};
use azalea_entity::{FluidOnEyes, Physics};
use azalea_inventory::{ItemSlot, Menu};
use azalea_registry::Fluid;
use azalea_registry::{DataComponentKind, Fluid};
#[derive(Debug)]
pub struct BestToolResult {
@ -92,7 +92,11 @@ pub fn accurate_best_tool_in_hotbar_for_block(
ItemSlot::Present(item_slot) => {
// lazy way to avoid checking durability since azalea doesn't have durability
// 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(
block.as_ref(),
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:
- [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)
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()
# TODO: pixlyzer is broken so we use old data
shape_datas = lib.extract.get_pixlyzer_data(
version_id, 'shapes')
'1.20.3-pre4', 'shapes')
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)
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:
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_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:
block_data_burger = blocks_burger[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_burger = block_data_burger.get('states', [])
@ -202,6 +202,10 @@ def get_property_struct_name(property: Optional[dict], block_data_burger: dict,
return 'ChestType'
if property_variants == ['compare', 'subtract']:
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:
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:
f.write('\n'.join(lines))
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()
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.
// Don't change it manually!
use crate::particle::Particle;
use super::{
EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion, Rotations,
SnifferState, VillagerData
ArmadilloStateKind, EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion,
Rotations, SnifferState, VillagerData,
};
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 bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
@ -218,8 +223,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
struct_name = upper_first_letter(
to_camel_case(name_or_bitfield))
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[
'type_id']
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))['type_id']
metadata_type_data = metadata_types[type_id]
rust_type = metadata_type_data['type']
@ -281,8 +285,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
if name_or_bitfield in single_use_imported_types:
field_struct_name = ''
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[
'type_id']
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))['type_id']
metadata_type_data = metadata_types[type_id]
rust_type = metadata_type_data['type']
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():
default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get(
'default', 'Default::default()')
default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get('default', 'Default::default()')
if isinstance(name_or_bitfield, str):
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[
'type_id']
@ -454,8 +456,10 @@ impl From<EntityDataValue> for UpdateMetadataError {
for mask, name in name_or_bitfield.items():
name = maybe_rename_field(name, index)
mask = int(mask, 0)
bit_default = 'true' if (
default & mask != 0) else 'false'
if default is None:
bit_default = 'false'
else:
bit_default = 'true' if (default & mask != 0) else 'false'
code.append(
f' {name}: {upper_first_letter(to_camel_case(name))}({bit_default}),')
code.append(' Self {')

View file

@ -16,7 +16,7 @@ def get_burger():
if not os.path.exists(get_dir_location('__cache__/Burger')):
print('\033[92mDownloading Burger...\033[m')
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')
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
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.utils import get_dir_location
from zipfile import ZipFile
@ -275,3 +276,19 @@ def get_en_us_lang(version_id: str):
return json.loads(
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_mappings = lib.download.get_mappings_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_mappings = lib.download.get_mappings_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_data: dict[PacketIdentifier, dict] = {}
new_packets: dict[PacketIdentifier, str] = {}
new_packets_data: dict[PacketIdentifier, dict] = {}
# old_packets: dict[PacketIdentifier, str] = {}
# old_packets_data: dict[PacketIdentifier, dict] = {}
# new_packets: dict[PacketIdentifier, str] = {}
# new_packets_data: dict[PacketIdentifier, dict] = {}
for packet in old_packet_list:
assert packet['class'].endswith('.class')
packet_name = old_mappings.get_class(packet['class'][:-6])
packet_ident = PacketIdentifier(
packet['id'], packet['direction'].lower(), fix_state(packet['state']))
old_packets[packet_ident] = packet_name
old_packets_data[packet_ident] = packet
for packet in new_packet_list:
assert packet['class'].endswith('.class')
packet_name = new_mappings.get_class(packet['class'][:-6])
packet_ident = PacketIdentifier(
packet['id'], packet['direction'].lower(), fix_state(packet['state']))
new_packets[packet_ident] = packet_name
new_packets_data[packet_ident] = packet
# for packet in old_packet_list:
# assert packet['class'].endswith('.class')
# packet_name = old_mappings.get_class(packet['class'][:-6])
# packet_ident = PacketIdentifier(
# packet['id'], packet['direction'].lower(), fix_state(packet['state']))
# old_packets[packet_ident] = packet_name
# old_packets_data[packet_ident] = packet
# for packet in new_packet_list:
# assert packet['class'].endswith('.class')
# packet_name = new_mappings.get_class(packet['class'][:-6])
# packet_ident = PacketIdentifier(
# packet['id'], packet['direction'].lower(), fix_state(packet['state']))
# new_packets[packet_ident] = packet_name
# new_packets_data[packet_ident] = packet
# find removed packets
removed_packets: list[PacketIdentifier] = []
for packet, packet_name in old_packets.items():
if packet_name not in new_packets.values():
removed_packets.append(packet)
print('Removed packet:', packet, packet_name)
for (direction, state), packets in group_packets(removed_packets).items():
lib.code.packet.remove_packet_ids(packets, direction, state)
# # find removed packets
# removed_packets: list[PacketIdentifier] = []
# for packet, packet_name in old_packets.items():
# if packet_name not in new_packets.values():
# removed_packets.append(packet)
# print('Removed packet:', packet, packet_name)
# for (direction, state), packets in group_packets(removed_packets).items():
# lib.code.packet.remove_packet_ids(packets, direction, state)
print()
# find packets that changed ids
changed_packets: dict[PacketIdentifier, int] = {}
for old_packet, old_packet_name in old_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:
changed_packets[old_packet] = new_packet.packet_id
print('Changed packet id:', old_packet, '->',
new_packet, f'({new_packet_name})')
break
for (direction, state), packets in group_packets(list(changed_packets.keys())).items():
id_map: dict[int, int] = {}
for old_packet_id in packets:
new_packet_id = changed_packets[PacketIdentifier(
old_packet_id, direction, state)]
id_map[old_packet_id] = new_packet_id
lib.code.packet.change_packet_ids(id_map, direction, state)
# # find packets that changed ids
# changed_packets: dict[PacketIdentifier, int] = {}
# for old_packet, old_packet_name in old_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:
# changed_packets[old_packet] = new_packet.packet_id
# print('Changed packet id:', old_packet, '->',
# new_packet, f'({new_packet_name})')
# break
# for (direction, state), packets in group_packets(list(changed_packets.keys())).items():
# id_map: dict[int, int] = {}
# for old_packet_id in packets:
# new_packet_id = changed_packets[PacketIdentifier(
# old_packet_id, direction, state)]
# id_map[old_packet_id] = new_packet_id
# lib.code.packet.change_packet_ids(id_map, direction, state)
print()
# print()
# find added/changed packets
added_or_changed_packets: list[PacketIdentifier] = []
for new_packet, packet_name in new_packets.items():
old_packet = None
for old_packet_tmp, old_packet_name in old_packets.items():
if old_packet_name == packet_name:
old_packet = old_packet_tmp
break
# # find added/changed packets
# added_or_changed_packets: list[PacketIdentifier] = []
# for new_packet, packet_name in new_packets.items():
# old_packet = None
# for old_packet_tmp, old_packet_name in old_packets.items():
# if old_packet_name == packet_name:
# old_packet = old_packet_tmp
# break
if packet_name not in old_packets.values():
added_or_changed_packets.append(new_packet)
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')):
added_or_changed_packets.append(new_packet)
print('Changed packet:', new_packet, packet_name)
for packet in added_or_changed_packets:
lib.code.packet.generate_packet(
new_burger_data[0]['packets']['packet'], new_mappings, packet.packet_id, packet.direction, packet.state)
# if packet_name not in old_packets.values():
# added_or_changed_packets.append(new_packet)
# 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')):
# added_or_changed_packets.append(new_packet)
# print('Changed packet:', new_packet, packet_name)
# for packet in added_or_changed_packets:
# lib.code.packet.generate_packet(
# new_burger_data[0]['packets']['packet'], new_mappings, packet.packet_id, packet.direction, packet.state)
lib.code.version.set_protocol_version(
new_burger_data[0]['version']['protocol'])
print('Updated protocol!')
# print('Updated protocol!')
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_report = lib.extract.get_block_states_report(new_version_id)
# TODO: pixlyzer is currently broken so uhhhh
shape_datas = lib.extract.get_pixlyzer_data(
new_version_id, 'shapes')
'1.20.3-pre4', 'shapes')
pixlyzer_block_datas = lib.extract.get_pixlyzer_data(
new_version_id, 'blocks')
'1.20.3-pre4', 'blocks')
lib.code.blocks.generate_blocks(
block_states_burger, block_states_report, pixlyzer_block_datas, new_ordered_blocks, new_mappings)
@ -136,9 +138,9 @@ print('Generating registries...')
import genregistries
genregistries.generate(new_version_id)
print('Generating entity metadata...')
burger_entities_data = new_burger_data[0]['entities']
lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings)
# print('Generating entity metadata...')
# burger_entities_data = new_burger_data[0]['entities']
# lib.code.entity.generate_entity_metadata(burger_entities_data, new_mappings)
print('Finishing touches, setting version in README and formatting code...')
lib.code.version.set_version_id(new_version_id)