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

update to rust edition 2024

This commit is contained in:
mat 2025-02-22 23:01:54 +00:00
parent bdd2fc91e1
commit 34f53baf85
109 changed files with 571 additions and 498 deletions

View file

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

View file

@ -360,7 +360,7 @@ pub async fn get_ms_auth_token(
tokio::time::sleep(std::time::Duration::from_secs(res.interval)).await; tokio::time::sleep(std::time::Duration::from_secs(res.interval)).await;
trace!("Polling to check if user has logged in..."); trace!("Polling to check if user has logged in...");
if let Ok(access_token_response) = client let res = client
.post(format!( .post(format!(
"https://login.live.com/oauth20_token.srf?client_id={client_id}" "https://login.live.com/oauth20_token.srf?client_id={client_id}"
)) ))
@ -372,8 +372,8 @@ pub async fn get_ms_auth_token(
.send() .send()
.await? .await?
.json::<AccessTokenResponse>() .json::<AccessTokenResponse>()
.await .await;
{ if let Ok(access_token_response) = res {
trace!("access_token_response: {:?}", access_token_response); trace!("access_token_response: {:?}", access_token_response);
let expires_at = SystemTime::now() let expires_at = SystemTime::now()
+ std::time::Duration::from_secs(access_token_response.expires_in); + std::time::Duration::from_secs(access_token_response.expires_in);

View file

@ -1,6 +1,6 @@
use base64::Engine; use base64::Engine;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use rsa::{pkcs8::DecodePrivateKey, RsaPrivateKey}; use rsa::{RsaPrivateKey, pkcs8::DecodePrivateKey};
use serde::Deserialize; use serde::Deserialize;
use thiserror::Error; use thiserror::Error;
use tracing::trace; use tracing::trace;

View file

@ -159,7 +159,7 @@ pub async fn serverside_auth(
StatusCode::FORBIDDEN => { StatusCode::FORBIDDEN => {
return Err(ServerSessionServerError::Unknown( return Err(ServerSessionServerError::Unknown(
res.json::<ForbiddenError>().await?.error, res.json::<ForbiddenError>().await?.error,
)) ));
} }
status_code => { status_code => {
// log the headers // log the headers

View file

@ -9,13 +9,13 @@ use proc_macro::TokenStream;
use proc_macro2::TokenTree; use proc_macro2::TokenTree;
use quote::quote; use quote::quote;
use syn::{ use syn::{
braced, Expr, Ident, LitStr, Token, braced,
ext::IdentExt, ext::IdentExt,
parenthesized, parenthesized,
parse::{Parse, ParseStream, Result}, parse::{Parse, ParseStream, Result},
parse_macro_input, parse_macro_input,
punctuated::Punctuated, punctuated::Punctuated,
token, Expr, Ident, LitStr, Token, token,
}; };
use utils::{combinations_of, to_pascal_case}; use utils::{combinations_of, to_pascal_case};
@ -511,13 +511,13 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
Ident::new(&combination[i].to_string(), proc_macro2::Span::call_site()); Ident::new(&combination[i].to_string(), proc_macro2::Span::call_site());
// this terrible code just gets the property default as a string // this terrible code just gets the property default as a string
let property_default_as_string = if let TokenTree::Ident(ident) = let property_default_as_string =
property.default.clone().into_iter().last().unwrap() match property.default.clone().into_iter().last().unwrap() {
{ TokenTree::Ident(ident) => ident.to_string(),
ident.to_string() _ => {
} else { panic!()
panic!() }
}; };
if property_default_as_string != combination[i] { if property_default_as_string != combination[i] {
is_default = false; is_default = false;
} }
@ -565,15 +565,16 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
let Some(default_state_id) = default_state_id else { let Some(default_state_id) = default_state_id else {
let defaults = properties_with_name let defaults = properties_with_name
.iter() .iter()
.map(|p| { .map(|p| match p.default.clone().into_iter().last().unwrap() {
if let TokenTree::Ident(i) = p.default.clone().into_iter().last().unwrap() { TokenTree::Ident(i) => i.to_string(),
i.to_string() _ => {
} else {
panic!() panic!()
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
panic!("Couldn't get default state id for {block_name_pascal_case}, combinations={block_properties_vec:?}, defaults={defaults:?}") panic!(
"Couldn't get default state id for {block_name_pascal_case}, combinations={block_properties_vec:?}, defaults={defaults:?}"
)
}; };
// 7035..=7058 => { // 7035..=7058 => {

View file

@ -1,9 +1,9 @@
use std::{ use std::{
collections::{hash_set, HashSet}, collections::{HashSet, hash_set},
ops::{Add, RangeInclusive}, ops::{Add, RangeInclusive},
}; };
use crate::{block_state::BlockStateIntegerRepr, BlockState}; use crate::{BlockState, block_state::BlockStateIntegerRepr};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BlockStates { pub struct BlockStates {

View file

@ -108,23 +108,30 @@ impl<S> CommandDispatcher<S> {
1 1
}) { }) {
reader.skip(); reader.skip();
if let Some(redirect) = &child.read().redirect { match &child.read().redirect {
let child_context = Some(redirect) => {
CommandContextBuilder::new(self, source, redirect.clone(), reader.cursor); let child_context = CommandContextBuilder::new(
let parse = self self,
.parse_nodes(redirect, &reader, child_context) source,
.expect("Parsing nodes failed"); redirect.clone(),
context.with_child(Rc::new(parse.context)); reader.cursor,
return Ok(ParseResults { );
context, let parse = self
reader: parse.reader, .parse_nodes(redirect, &reader, child_context)
exceptions: parse.exceptions, .expect("Parsing nodes failed");
}); context.with_child(Rc::new(parse.context));
} else { return Ok(ParseResults {
let parse = self context,
.parse_nodes(&child, &reader, context) reader: parse.reader,
.expect("Parsing nodes failed"); exceptions: parse.exceptions,
potentials.push(parse); });
}
_ => {
let parse = self
.parse_nodes(&child, &reader, context)
.expect("Parsing nodes failed");
potentials.push(parse);
}
} }
} else { } else {
potentials.push(ParseResults { potentials.push(ParseResults {
@ -215,11 +222,14 @@ impl<S> CommandDispatcher<S> {
pub fn find_node(&self, path: &[&str]) -> Option<Arc<RwLock<CommandNode<S>>>> { pub fn find_node(&self, path: &[&str]) -> Option<Arc<RwLock<CommandNode<S>>>> {
let mut node = self.root.clone(); let mut node = self.root.clone();
for name in path { for name in path {
if let Some(child) = node.clone().read().child(name) { match node.clone().read().child(name) {
node = child; Some(child) => {
} else { node = child;
return None; }
} _ => {
return None;
}
};
} }
Some(node) Some(node)
} }
@ -258,31 +268,41 @@ impl<S> CommandDispatcher<S> {
let modifier = &context.modifier; let modifier = &context.modifier;
if let Some(modifier) = modifier { if let Some(modifier) = modifier {
let results = modifier(context); let results = modifier(context);
if let Ok(results) = results { match results {
if !results.is_empty() { Ok(results) => {
next.extend(results.iter().map(|s| child.copy_for(s.clone()))); if !results.is_empty() {
next.extend(
results.iter().map(|s| child.copy_for(s.clone())),
);
}
} }
} else { _ => {
// TODO // TODO
// self.consumer.on_command_complete(context, false, 0); // self.consumer.on_command_complete(context, false, 0);
if !forked { if !forked {
return Err(results.err().unwrap()); return Err(results.err().unwrap());
}
} }
} }
} else { } else {
next.push(child.copy_for(context.source.clone())); next.push(child.copy_for(context.source.clone()));
} }
} }
} else if let Some(context_command) = &context.command { } else {
found_command = true; match &context.command {
Some(context_command) => {
found_command = true;
let value = context_command(context); let value = context_command(context);
result += value; result += value;
// consumer.on_command_complete(context, true, value); // consumer.on_command_complete(context, true, value);
successful_forks += 1; successful_forks += 1;
// TODO: allow context_command to error and handle those // TODO: allow context_command to error and handle
// errors // those errors
}
_ => {}
}
} }
} }
@ -332,32 +352,35 @@ impl<S> CommandDispatcher<S> {
if node.command.is_some() { if node.command.is_some() {
result.push(prefix.to_owned()); result.push(prefix.to_owned());
} }
if let Some(redirect) = &node.redirect { match &node.redirect {
let redirect = if redirect.data_ptr() == self.root.data_ptr() { Some(redirect) => {
"...".to_string() let redirect = if redirect.data_ptr() == self.root.data_ptr() {
} else { "...".to_string()
format!("-> {}", redirect.read().usage_text()) } else {
}; format!("-> {}", redirect.read().usage_text())
if prefix.is_empty() { };
result.push(format!("{} {redirect}", node.usage_text())); if prefix.is_empty() {
} else { result.push(format!("{} {redirect}", node.usage_text()));
result.push(format!("{prefix} {redirect}")); } else {
result.push(format!("{prefix} {redirect}"));
}
} }
} else { _ => {
for child in node.children.values() { for child in node.children.values() {
let child = child.read(); let child = child.read();
self.get_all_usage_recursive( self.get_all_usage_recursive(
&child, &child,
source, source,
result, result,
if prefix.is_empty() { if prefix.is_empty() {
child.usage_text() child.usage_text()
} else { } else {
format!("{prefix} {}", child.usage_text()) format!("{prefix} {}", child.usage_text())
} }
.as_str(), .as_str(),
restricted, restricted,
); );
}
} }
} }
} }

View file

@ -2,7 +2,7 @@ use std::{any::Any, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
use parking_lot::RwLock; use parking_lot::RwLock;
use super::{parsed_command_node::ParsedCommandNode, string_range::StringRange, ParsedArgument}; use super::{ParsedArgument, parsed_command_node::ParsedCommandNode, string_range::StringRange};
use crate::{ use crate::{
modifier::RedirectModifier, modifier::RedirectModifier,
tree::{Command, CommandNode}, tree::{Command, CommandNode},

View file

@ -3,8 +3,8 @@ use std::{collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
use parking_lot::RwLock; use parking_lot::RwLock;
use super::{ use super::{
command_context::CommandContext, parsed_command_node::ParsedCommandNode, ParsedArgument, command_context::CommandContext, parsed_command_node::ParsedCommandNode,
string_range::StringRange, suggestion_context::SuggestionContext, ParsedArgument, string_range::StringRange, suggestion_context::SuggestionContext,
}; };
use crate::{ use crate::{
command_dispatcher::CommandDispatcher, command_dispatcher::CommandDispatcher,
@ -107,18 +107,18 @@ impl<'a, S> CommandContextBuilder<'a, S> {
} }
if self.range.end() < cursor { if self.range.end() < cursor {
if let Some(child) = &self.child { match &self.child {
child.find_suggestion_context(cursor) Some(child) => child.find_suggestion_context(cursor),
} else if let Some(last) = self.nodes.last() { _ => match self.nodes.last() {
SuggestionContext { Some(last) => SuggestionContext {
parent: Arc::clone(&last.node), parent: Arc::clone(&last.node),
start_pos: last.range.end() + 1, start_pos: last.range.end() + 1,
} },
} else { _ => SuggestionContext {
SuggestionContext { parent: Arc::clone(&self.root),
parent: Arc::clone(&self.root), start_pos: self.range.start(),
start_pos: self.range.start(), },
} },
} }
} else { } else {
let mut prev = &self.root; let mut prev = &self.root;

View file

@ -292,18 +292,27 @@ impl<S> PartialEq for CommandNode<S> {
} }
} }
if let Some(selfexecutes) = &self.command { match &self.command {
// idk how to do this better since we can't compare `dyn Fn`s Some(selfexecutes) => {
if let Some(otherexecutes) = &other.command { // idk how to do this better since we can't compare `dyn Fn`s
#[allow(ambiguous_wide_pointer_comparisons)] match &other.command {
if !Arc::ptr_eq(selfexecutes, otherexecutes) { Some(otherexecutes) =>
{
#[allow(ambiguous_wide_pointer_comparisons)]
if !Arc::ptr_eq(selfexecutes, otherexecutes) {
return false;
}
}
_ => {
return false;
}
}
}
_ => {
if other.command.is_some() {
return false; return false;
} }
} else {
return false;
} }
} else if other.command.is_some() {
return false;
} }
true true
} }

View file

@ -10,11 +10,13 @@ fn test_arguments() {
let builder = builder.then(argument.clone()); let builder = builder.then(argument.clone());
assert_eq!(builder.arguments().children.len(), 1); assert_eq!(builder.arguments().children.len(), 1);
let built_argument = Rc::new(argument.build()); let built_argument = Rc::new(argument.build());
assert!(builder assert!(
.arguments() builder
.children .arguments()
.values() .children
.any(|e| *e.read() == *built_argument)); .values()
.any(|e| *e.read() == *built_argument)
);
} }
// @Test // @Test

View file

@ -3,7 +3,7 @@ mod write;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{parse_macro_input, DeriveInput}; use syn::{DeriveInput, parse_macro_input};
#[proc_macro_derive(AzaleaRead, attributes(var))] #[proc_macro_derive(AzaleaRead, attributes(var))]
pub fn derive_azalearead(input: TokenStream) -> TokenStream { pub fn derive_azalearead(input: TokenStream) -> TokenStream {

View file

@ -1,5 +1,5 @@
use quote::{quote, ToTokens}; use quote::{ToTokens, quote};
use syn::{punctuated::Punctuated, token::Comma, Data, Field, FieldsNamed, Ident}; use syn::{Data, Field, FieldsNamed, Ident, punctuated::Punctuated, token::Comma};
fn read_named_fields( fn read_named_fields(
named: &Punctuated<Field, Comma>, named: &Punctuated<Field, Comma>,

View file

@ -1,6 +1,6 @@
use proc_macro2::Span; use proc_macro2::Span;
use quote::{quote, ToTokens}; use quote::{ToTokens, quote};
use syn::{punctuated::Punctuated, token::Comma, Data, Field, FieldsNamed, Ident}; use syn::{Data, Field, FieldsNamed, Ident, punctuated::Punctuated, token::Comma};
fn write_named_fields( fn write_named_fields(
named: &Punctuated<Field, Comma>, named: &Punctuated<Field, Comma>,

View file

@ -5,11 +5,11 @@ use std::{
io::{Cursor, Read}, io::{Cursor, Read},
}; };
use byteorder::{ReadBytesExt, BE}; use byteorder::{BE, ReadBytesExt};
use thiserror::Error; use thiserror::Error;
use tracing::warn; use tracing::warn;
use super::{UnsizedByteArray, MAX_STRING_LENGTH}; use super::{MAX_STRING_LENGTH, UnsizedByteArray};
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum BufReadError { pub enum BufReadError {
@ -19,7 +19,9 @@ pub enum BufReadError {
InvalidVarLong, InvalidVarLong,
#[error("Error reading bytes")] #[error("Error reading bytes")]
CouldNotReadBytes, CouldNotReadBytes,
#[error("The received encoded string buffer length is longer than maximum allowed ({length} > {max_length})")] #[error(
"The received encoded string buffer length is longer than maximum allowed ({length} > {max_length})"
)]
StringLengthTooLong { length: u32, max_length: u32 }, StringLengthTooLong { length: u32, max_length: u32 },
#[error("The received Vec length is longer than maximum allowed ({length} > {max_length})")] #[error("The received Vec length is longer than maximum allowed ({length} > {max_length})")]
VecLengthTooLong { length: u32, max_length: u32 }, VecLengthTooLong { length: u32, max_length: u32 },

View file

@ -2,7 +2,7 @@ use std::io::{Cursor, Write};
use uuid::Uuid; use uuid::Uuid;
use crate::{read::BufReadError, AzaleaRead, AzaleaWrite}; use crate::{AzaleaRead, AzaleaWrite, read::BufReadError};
pub trait SerializableUuid { pub trait SerializableUuid {
fn to_int_array(&self) -> [u32; 4]; fn to_int_array(&self) -> [u32; 4];

View file

@ -5,7 +5,7 @@ use std::{
use byteorder::{BigEndian, WriteBytesExt}; use byteorder::{BigEndian, WriteBytesExt};
use super::{UnsizedByteArray, MAX_STRING_LENGTH}; use super::{MAX_STRING_LENGTH, UnsizedByteArray};
fn write_utf_with_len(buf: &mut impl Write, string: &str, len: usize) -> Result<(), io::Error> { fn write_utf_with_len(buf: &mut impl Write, string: &str, len: usize) -> Result<(), io::Error> {
if string.len() > len { if string.len() > len {

View file

@ -1,6 +1,6 @@
use serde::Serialize; use serde::Serialize;
use crate::{style::Style, FormattedText}; use crate::{FormattedText, style::Style};
#[derive(Clone, Debug, PartialEq, Serialize, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Serialize, Eq, Hash)]
pub struct BaseComponent { pub struct BaseComponent {

View file

@ -2,7 +2,7 @@ use std::{fmt::Display, sync::LazyLock};
#[cfg(feature = "azalea-buf")] #[cfg(feature = "azalea-buf")]
use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
use serde::{de, Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize, de};
#[cfg(feature = "simdnbt")] #[cfg(feature = "simdnbt")]
use simdnbt::{Deserialize as _, FromNbtTag as _, Serialize as _}; use simdnbt::{Deserialize as _, FromNbtTag as _, Serialize as _};
use tracing::{debug, trace, warn}; use tracing::{debug, trace, warn};
@ -371,7 +371,9 @@ impl FormattedText {
} else if let Some(s) = primitive.string() { } else if let Some(s) = primitive.string() {
with_array.push(StringOrComponent::String(s.to_string())); with_array.push(StringOrComponent::String(s.to_string()));
} else { } else {
warn!("couldn't parse {item:?} as FormattedText because it has a disallowed primitive"); warn!(
"couldn't parse {item:?} as FormattedText because it has a disallowed primitive"
);
with_array.push(StringOrComponent::String("?".to_string())); with_array.push(StringOrComponent::String("?".to_string()));
} }
} else if let Some(c) = FormattedText::from_nbt_compound(item) { } else if let Some(c) = FormattedText::from_nbt_compound(item) {
@ -392,7 +394,9 @@ impl FormattedText {
} }
} }
} else { } else {
warn!("couldn't parse {with:?} as FormattedText because it's not a list of compounds"); warn!(
"couldn't parse {with:?} as FormattedText because it's not a list of compounds"
);
return None; return None;
} }
component = component =
@ -456,12 +460,11 @@ impl From<&simdnbt::Mutf8Str> for FormattedText {
impl AzaleaRead for FormattedText { impl AzaleaRead for FormattedText {
fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, BufReadError> { fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, BufReadError> {
let nbt = simdnbt::borrow::read_optional_tag(buf)?; let nbt = simdnbt::borrow::read_optional_tag(buf)?;
if let Some(nbt) = nbt { match nbt {
FormattedText::from_nbt_tag(nbt.as_tag()).ok_or(BufReadError::Custom( Some(nbt) => FormattedText::from_nbt_tag(nbt.as_tag()).ok_or(BufReadError::Custom(
"couldn't convert nbt to chat message".to_owned(), "couldn't convert nbt to chat message".to_owned(),
)) )),
} else { _ => Ok(FormattedText::default()),
Ok(FormattedText::default())
} }
} }
} }

View file

@ -2,7 +2,7 @@ use std::{collections::HashMap, fmt, sync::LazyLock};
#[cfg(feature = "azalea-buf")] #[cfg(feature = "azalea-buf")]
use azalea_buf::AzBuf; use azalea_buf::AzBuf;
use serde::{ser::SerializeStruct, Serialize, Serializer}; use serde::{Serialize, Serializer, ser::SerializeStruct};
use serde_json::Value; use serde_json::Value;
#[cfg(feature = "simdnbt")] #[cfg(feature = "simdnbt")]
use simdnbt::owned::{NbtCompound, NbtTag}; use simdnbt::owned::{NbtCompound, NbtTag};
@ -334,10 +334,15 @@ fn simdnbt_serialize_field(
default: impl simdnbt::ToNbtTag, default: impl simdnbt::ToNbtTag,
reset: bool, reset: bool,
) { ) {
if let Some(value) = value { match value {
compound.insert(name, value); Some(value) => {
} else if reset { compound.insert(name, value);
compound.insert(name, default); }
_ => {
if reset {
compound.insert(name, default);
}
}
} }
} }

View file

@ -1,8 +1,8 @@
use std::fmt::Display; use std::fmt::Display;
use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSerializer}; use serde::{__private::ser::FlatMapSerializer, Serialize, Serializer, ser::SerializeMap};
use crate::{base_component::BaseComponent, style::ChatFormatting, FormattedText}; use crate::{FormattedText, base_component::BaseComponent, style::ChatFormatting};
/// A component that contains text that's the same in all locales. /// A component that contains text that's the same in all locales.
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]

View file

@ -1,11 +1,11 @@
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSerializer}; use serde::{__private::ser::FlatMapSerializer, Serialize, Serializer, ser::SerializeMap};
#[cfg(feature = "simdnbt")] #[cfg(feature = "simdnbt")]
use simdnbt::Serialize as _; use simdnbt::Serialize as _;
use crate::{ use crate::{
base_component::BaseComponent, style::Style, text_component::TextComponent, FormattedText, FormattedText, base_component::BaseComponent, style::Style, text_component::TextComponent,
}; };
#[derive(Clone, Debug, PartialEq, Serialize, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Serialize, Eq, Hash)]

View file

@ -1,6 +1,6 @@
use azalea_chat::{ use azalea_chat::{
style::{Ansi, ChatFormatting, TextColor},
FormattedText, FormattedText,
style::{Ansi, ChatFormatting, TextColor},
}; };
use serde::Deserialize; use serde::Deserialize;
use serde_json::Value; use serde_json::Value;

View file

@ -2,8 +2,8 @@
use std::sync::Arc; use std::sync::Arc;
use azalea_auth::certs::{Certificates, FetchCertificatesError};
use azalea_auth::AccessTokenResponse; use azalea_auth::AccessTokenResponse;
use azalea_auth::certs::{Certificates, FetchCertificatesError};
use bevy_ecs::component::Component; use bevy_ecs::component::Component;
use parking_lot::Mutex; use parking_lot::Mutex;
use thiserror::Error; use thiserror::Error;

View file

@ -1,7 +1,8 @@
use azalea_core::{game_type::GameMode, tick::GameTick}; use azalea_core::{game_type::GameMode, tick::GameTick};
use azalea_entity::{ use azalea_entity::{
Attributes, Physics,
metadata::{ShiftKeyDown, Sprinting}, metadata::{ShiftKeyDown, Sprinting},
update_bounding_box, Attributes, Physics, update_bounding_box,
}; };
use azalea_physics::PhysicsSet; use azalea_physics::PhysicsSet;
use azalea_protocol::packets::game::s_interact::{self, ServerboundInteract}; use azalea_protocol::packets::game::s_interact::{self, ServerboundInteract};
@ -11,8 +12,8 @@ use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use crate::{ use crate::{
interact::SwingArmEvent, local_player::LocalGameMode, movement::MoveEventsSet, Client, interact::SwingArmEvent, local_player::LocalGameMode, movement::MoveEventsSet,
packet_handling::game::SendPacketEvent, respawn::perform_respawn, Client, packet_handling::game::SendPacketEvent, respawn::perform_respawn,
}; };
pub struct AttackPlugin; pub struct AttackPlugin;

View file

@ -7,6 +7,7 @@ use std::{
use azalea_chat::FormattedText; use azalea_chat::FormattedText;
use azalea_protocol::packets::{ use azalea_protocol::packets::{
Packet,
game::{ game::{
c_disguised_chat::ClientboundDisguisedChat, c_disguised_chat::ClientboundDisguisedChat,
c_player_chat::ClientboundPlayerChat, c_player_chat::ClientboundPlayerChat,
@ -14,7 +15,6 @@ use azalea_protocol::packets::{
s_chat::{LastSeenMessagesUpdate, ServerboundChat}, s_chat::{LastSeenMessagesUpdate, ServerboundChat},
s_chat_command::ServerboundChatCommand, s_chat_command::ServerboundChatCommand,
}, },
Packet,
}; };
use bevy_app::{App, Plugin, Update}; use bevy_app::{App, Plugin, Update};
use bevy_ecs::{ use bevy_ecs::{
@ -27,7 +27,7 @@ use uuid::Uuid;
use crate::{ use crate::{
client::Client, client::Client,
packet_handling::game::{handle_send_packet_event, SendPacketEvent}, packet_handling::game::{SendPacketEvent, handle_send_packet_event},
}; };
/// A chat packet, either a system message or a chat message. /// A chat packet, either a system message or a chat message.

View file

@ -19,11 +19,11 @@ use simdnbt::owned::BaseNbt;
use tracing::{error, trace}; use tracing::{error, trace};
use crate::{ use crate::{
InstanceHolder,
interact::handle_block_interact_event, interact::handle_block_interact_event,
inventory::InventorySet, inventory::InventorySet,
packet_handling::game::{handle_send_packet_event, SendPacketEvent}, packet_handling::game::{SendPacketEvent, handle_send_packet_event},
respawn::perform_respawn, respawn::perform_respawn,
InstanceHolder,
}; };
pub struct ChunkPlugin; pub struct ChunkPlugin;

View file

@ -14,29 +14,29 @@ use azalea_core::{
tick::GameTick, tick::GameTick,
}; };
use azalea_entity::{ use azalea_entity::{
EntityPlugin, EntityUpdateSet, EyeHeight, LocalEntity, Position,
indexing::{EntityIdIndex, EntityUuidIndex}, indexing::{EntityIdIndex, EntityUuidIndex},
metadata::Health, metadata::Health,
EntityPlugin, EntityUpdateSet, EyeHeight, LocalEntity, Position,
}; };
use azalea_physics::PhysicsPlugin; use azalea_physics::PhysicsPlugin;
use azalea_protocol::{ use azalea_protocol::{
ServerAddress,
common::client_information::ClientInformation, common::client_information::ClientInformation,
connect::{Connection, ConnectionError, Proxy}, connect::{Connection, ConnectionError, Proxy},
packets::{ packets::{
self, self, ClientIntention, ConnectionProtocol, PROTOCOL_VERSION, Packet,
config::{ClientboundConfigPacket, ServerboundConfigPacket}, config::{ClientboundConfigPacket, ServerboundConfigPacket},
game::ServerboundGamePacket, game::ServerboundGamePacket,
handshake::{ handshake::{
s_intention::ServerboundIntention, ClientboundHandshakePacket, ClientboundHandshakePacket, ServerboundHandshakePacket,
ServerboundHandshakePacket, s_intention::ServerboundIntention,
}, },
login::{ login::{
s_hello::ServerboundHello, s_key::ServerboundKey, ClientboundLoginPacket, s_hello::ServerboundHello, s_key::ServerboundKey,
s_login_acknowledged::ServerboundLoginAcknowledged, ClientboundLoginPacket, s_login_acknowledged::ServerboundLoginAcknowledged,
}, },
ClientIntention, ConnectionProtocol, Packet, PROTOCOL_VERSION,
}, },
resolver, ServerAddress, resolver,
}; };
use azalea_world::{Instance, InstanceContainer, InstanceName, PartialInstance}; use azalea_world::{Instance, InstanceContainer, InstanceName, PartialInstance};
use bevy_app::{App, Plugin, PluginGroup, PluginGroupBuilder, Update}; use bevy_app::{App, Plugin, PluginGroup, PluginGroupBuilder, Update};
@ -61,6 +61,7 @@ use tracing::{debug, error};
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
Account, PlayerInfo,
attack::{self, AttackPlugin}, attack::{self, AttackPlugin},
chat::ChatPlugin, chat::ChatPlugin,
chunks::{ChunkBatchInfo, ChunkPlugin}, chunks::{ChunkBatchInfo, ChunkPlugin},
@ -70,21 +71,20 @@ use crate::{
interact::{CurrentSequenceNumber, InteractPlugin}, interact::{CurrentSequenceNumber, InteractPlugin},
inventory::{Inventory, InventoryPlugin}, inventory::{Inventory, InventoryPlugin},
local_player::{ local_player::{
death_event, GameProfileComponent, Hunger, InstanceHolder, PermissionLevel, GameProfileComponent, Hunger, InstanceHolder, PermissionLevel, PlayerAbilities, TabList,
PlayerAbilities, TabList, death_event,
}, },
mining::{self, MinePlugin}, mining::{self, MinePlugin},
movement::{LastSentLookDirection, PhysicsState, PlayerMovePlugin}, movement::{LastSentLookDirection, PhysicsState, PlayerMovePlugin},
packet_handling::{ packet_handling::{
login::{self, InLoginState, LoginSendPacketQueue},
PacketHandlerPlugin, PacketHandlerPlugin,
login::{self, InLoginState, LoginSendPacketQueue},
}, },
player::retroactively_add_game_profile_component, player::retroactively_add_game_profile_component,
raw_connection::RawConnection, raw_connection::RawConnection,
respawn::RespawnPlugin, respawn::RespawnPlugin,
send_client_end::TickEndPlugin, send_client_end::TickEndPlugin,
task_pool::TaskPoolPlugin, task_pool::TaskPoolPlugin,
Account, PlayerInfo,
}; };
/// `Client` has the things that a user interacting with the library will want. /// `Client` has the things that a user interacting with the library will want.

View file

@ -44,7 +44,9 @@ fn handle_end_login_state(
let client_information = match query.get(entity).ok() { let client_information = match query.get(entity).ok() {
Some(i) => i, Some(i) => i,
None => { None => {
warn!("ClientInformation component was not set before leaving login state, using a default"); warn!(
"ClientInformation component was not set before leaving login state, using a default"
);
&ClientInformation::default() &ClientInformation::default()
} }
}; };

View file

@ -1,7 +1,7 @@
//! Disconnect a client from the server. //! Disconnect a client from the server.
use azalea_chat::FormattedText; use azalea_chat::FormattedText;
use azalea_entity::{metadata::PlayerMetadataBundle, EntityBundle, LocalEntity}; use azalea_entity::{EntityBundle, LocalEntity, metadata::PlayerMetadataBundle};
use bevy_app::{App, Plugin, PostUpdate}; use bevy_app::{App, Plugin, PostUpdate};
use bevy_ecs::{ use bevy_ecs::{
component::Component, component::Component,
@ -16,8 +16,8 @@ use derive_more::Deref;
use tracing::trace; use tracing::trace;
use crate::{ use crate::{
client::JoinedClientBundle, events::LocalPlayerEvents, raw_connection::RawConnection, InstanceHolder, client::JoinedClientBundle, events::LocalPlayerEvents,
InstanceHolder, raw_connection::RawConnection,
}; };
pub struct DisconnectPlugin; pub struct DisconnectPlugin;

View file

@ -6,7 +6,7 @@ use std::sync::Arc;
use azalea_chat::FormattedText; use azalea_chat::FormattedText;
use azalea_core::tick::GameTick; use azalea_core::tick::GameTick;
use azalea_protocol::packets::game::{ use azalea_protocol::packets::game::{
c_player_combat_kill::ClientboundPlayerCombatKill, ClientboundGamePacket, ClientboundGamePacket, c_player_combat_kill::ClientboundPlayerCombatKill,
}; };
use azalea_world::{InstanceName, MinecraftEntityId}; use azalea_world::{InstanceName, MinecraftEntityId};
use bevy_app::{App, Plugin, PreUpdate, Update}; use bevy_app::{App, Plugin, PreUpdate, Update};
@ -21,13 +21,13 @@ use derive_more::{Deref, DerefMut};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use crate::{ use crate::{
PlayerInfo,
chat::{ChatPacket, ChatReceivedEvent}, chat::{ChatPacket, ChatReceivedEvent},
disconnect::DisconnectEvent, disconnect::DisconnectEvent,
packet_handling::game::{ packet_handling::game::{
AddPlayerEvent, DeathEvent, KeepAliveEvent, PacketEvent, RemovePlayerEvent, AddPlayerEvent, DeathEvent, KeepAliveEvent, PacketEvent, RemovePlayerEvent,
UpdatePlayerEvent, UpdatePlayerEvent,
}, },
PlayerInfo,
}; };
// (for contributors): // (for contributors):

View file

@ -8,9 +8,9 @@ use azalea_core::{
position::{BlockPos, Vec3}, position::{BlockPos, Vec3},
}; };
use azalea_entity::{ use azalea_entity::{
clamp_look_direction, view_vector, Attributes, EyeHeight, LocalEntity, LookDirection, Position, Attributes, EyeHeight, LocalEntity, LookDirection, Position, clamp_look_direction, view_vector,
}; };
use azalea_inventory::{components, ItemStack, ItemStackData}; use azalea_inventory::{ItemStack, ItemStackData, components};
use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType}; use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType};
use azalea_protocol::packets::game::{ use azalea_protocol::packets::game::{
s_interact::InteractionHand, s_interact::InteractionHand,
@ -31,13 +31,13 @@ use derive_more::{Deref, DerefMut};
use tracing::warn; use tracing::warn;
use crate::{ use crate::{
Client,
attack::handle_attack_event, attack::handle_attack_event,
inventory::{Inventory, InventorySet}, inventory::{Inventory, InventorySet},
local_player::{LocalGameMode, PermissionLevel, PlayerAbilities}, local_player::{LocalGameMode, PermissionLevel, PlayerAbilities},
movement::MoveEventsSet, movement::MoveEventsSet,
packet_handling::game::{handle_send_packet_event, SendPacketEvent}, packet_handling::game::{SendPacketEvent, handle_send_packet_event},
respawn::perform_respawn, respawn::perform_respawn,
Client,
}; };
/// A plugin that allows clients to interact with blocks in the world. /// A plugin that allows clients to interact with blocks in the world.
@ -245,15 +245,16 @@ pub fn check_is_interaction_restricted(
// way of modifying that // way of modifying that
let held_item = inventory.held_item(); let held_item = inventory.held_item();
if let ItemStack::Present(item) = &held_item { match &held_item {
let block = instance.chunks.get_block_state(block_pos); ItemStack::Present(item) => {
let Some(block) = block else { let block = instance.chunks.get_block_state(block_pos);
// block isn't loaded so just say that it is restricted let Some(block) = block else {
return true; // block isn't loaded so just say that it is restricted
}; return true;
check_block_can_be_broken_by_item_in_adventure_mode(item, &block) };
} else { check_block_can_be_broken_by_item_in_adventure_mode(item, &block)
true }
_ => true,
} }
} }
GameMode::Spectator => true, GameMode::Spectator => true,

View file

@ -26,10 +26,10 @@ use bevy_ecs::{
use tracing::warn; use tracing::warn;
use crate::{ use crate::{
local_player::PlayerAbilities,
packet_handling::game::{handle_send_packet_event, SendPacketEvent},
respawn::perform_respawn,
Client, Client,
local_player::PlayerAbilities,
packet_handling::game::{SendPacketEvent, handle_send_packet_event},
respawn::perform_respawn,
}; };
pub struct InventoryPlugin; pub struct InventoryPlugin;
@ -124,10 +124,9 @@ impl Inventory {
/// ///
/// Use [`Self::menu_mut`] if you need a mutable reference. /// Use [`Self::menu_mut`] if you need a mutable reference.
pub fn menu(&self) -> &azalea_inventory::Menu { pub fn menu(&self) -> &azalea_inventory::Menu {
if let Some(menu) = &self.container_menu { match &self.container_menu {
menu Some(menu) => menu,
} else { _ => &self.inventory_menu,
&self.inventory_menu
} }
} }
@ -137,10 +136,9 @@ impl Inventory {
/// ///
/// Use [`Self::menu`] if you don't need a mutable reference. /// Use [`Self::menu`] if you don't need a mutable reference.
pub fn menu_mut(&mut self) -> &mut azalea_inventory::Menu { pub fn menu_mut(&mut self) -> &mut azalea_inventory::Menu {
if let Some(menu) = &mut self.container_menu { match &mut self.container_menu {
menu Some(menu) => menu,
} else { _ => &mut self.inventory_menu,
&mut self.inventory_menu
} }
} }
@ -286,10 +284,9 @@ impl Inventory {
carried_count -= new_carried.count - slot_item_count; carried_count -= new_carried.count - slot_item_count;
// we have to inline self.menu_mut() here to avoid the borrow checker // we have to inline self.menu_mut() here to avoid the borrow checker
// complaining // complaining
let menu = if let Some(menu) = &mut self.container_menu { let menu = match &mut self.container_menu {
menu Some(menu) => menu,
} else { _ => &mut self.inventory_menu,
&mut self.inventory_menu
}; };
*menu.slot_mut(slot_index as usize).unwrap() = *menu.slot_mut(slot_index as usize).unwrap() =
ItemStack::Present(new_carried); ItemStack::Present(new_carried);

View file

@ -35,8 +35,8 @@ pub mod test_simulation;
pub use account::{Account, AccountOpts}; pub use account::{Account, AccountOpts};
pub use azalea_protocol::common::client_information::ClientInformation; pub use azalea_protocol::common::client_information::ClientInformation;
pub use client::{ pub use client::{
start_ecs_runner, Client, DefaultPlugins, InConfigState, JoinError, JoinedClientBundle, Client, DefaultPlugins, InConfigState, JoinError, JoinedClientBundle, LocalPlayerBundle,
LocalPlayerBundle, StartClientOpts, TickBroadcast, StartClientOpts, TickBroadcast, start_ecs_runner,
}; };
pub use events::Event; pub use events::Event;
pub use local_player::{GameProfileComponent, Hunger, InstanceHolder, TabList}; pub use local_player::{GameProfileComponent, Hunger, InstanceHolder, TabList};

View file

@ -14,8 +14,8 @@ use tracing::error;
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
events::{Event as AzaleaEvent, LocalPlayerEvents},
ClientInformation, PlayerInfo, ClientInformation, PlayerInfo,
events::{Event as AzaleaEvent, LocalPlayerEvents},
}; };
/// A component that keeps strong references to our [`PartialInstance`] and /// A component that keeps strong references to our [`PartialInstance`] and

View file

@ -1,6 +1,6 @@
use azalea_block::{fluid_state::FluidState, Block, BlockState}; use azalea_block::{Block, BlockState, fluid_state::FluidState};
use azalea_core::{direction::Direction, game_type::GameMode, position::BlockPos, tick::GameTick}; use azalea_core::{direction::Direction, game_type::GameMode, position::BlockPos, tick::GameTick};
use azalea_entity::{mining::get_mine_progress, FluidOnEyes, Physics}; use azalea_entity::{FluidOnEyes, Physics, mining::get_mine_progress};
use azalea_inventory::ItemStack; use azalea_inventory::ItemStack;
use azalea_physics::PhysicsSet; use azalea_physics::PhysicsSet;
use azalea_protocol::packets::game::s_player_action::{self, ServerboundPlayerAction}; use azalea_protocol::packets::game::s_player_action::{self, ServerboundPlayerAction};
@ -10,15 +10,15 @@ use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use crate::{ use crate::{
Client,
interact::{ interact::{
can_use_game_master_blocks, check_is_interaction_restricted, CurrentSequenceNumber, CurrentSequenceNumber, HitResultComponent, SwingArmEvent, can_use_game_master_blocks,
HitResultComponent, SwingArmEvent, check_is_interaction_restricted,
}, },
inventory::{Inventory, InventorySet}, inventory::{Inventory, InventorySet},
local_player::{LocalGameMode, PermissionLevel, PlayerAbilities}, local_player::{LocalGameMode, PermissionLevel, PlayerAbilities},
movement::MoveEventsSet, movement::MoveEventsSet,
packet_handling::game::SendPacketEvent, packet_handling::game::SendPacketEvent,
Client,
}; };
/// A plugin that allows clients to break blocks in the world. /// A plugin that allows clients to break blocks in the world.

View file

@ -2,18 +2,18 @@ use std::backtrace::Backtrace;
use azalea_core::position::Vec3; use azalea_core::position::Vec3;
use azalea_core::tick::GameTick; use azalea_core::tick::GameTick;
use azalea_entity::{metadata::Sprinting, Attributes, Jumping}; use azalea_entity::{Attributes, Jumping, metadata::Sprinting};
use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position}; use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position};
use azalea_physics::{ai_step, PhysicsSet}; use azalea_physics::{PhysicsSet, ai_step};
use azalea_protocol::packets::game::{ServerboundPlayerCommand, ServerboundPlayerInput}; use azalea_protocol::packets::game::{ServerboundPlayerCommand, ServerboundPlayerInput};
use azalea_protocol::packets::{ use azalea_protocol::packets::{
Packet,
game::{ game::{
s_move_player_pos::ServerboundMovePlayerPos, s_move_player_pos::ServerboundMovePlayerPos,
s_move_player_pos_rot::ServerboundMovePlayerPosRot, s_move_player_pos_rot::ServerboundMovePlayerPosRot,
s_move_player_rot::ServerboundMovePlayerRot, s_move_player_rot::ServerboundMovePlayerRot,
s_move_player_status_only::ServerboundMovePlayerStatusOnly, s_move_player_status_only::ServerboundMovePlayerStatusOnly,
}, },
Packet,
}; };
use azalea_world::{MinecraftEntityId, MoveEntityError}; use azalea_world::{MinecraftEntityId, MoveEntityError};
use bevy_app::{App, Plugin, Update}; use bevy_app::{App, Plugin, Update};

View file

@ -14,12 +14,12 @@ use bevy_ecs::prelude::*;
use bevy_ecs::system::SystemState; use bevy_ecs::system::SystemState;
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
use crate::InstanceHolder;
use crate::client::InConfigState; use crate::client::InConfigState;
use crate::disconnect::DisconnectEvent; use crate::disconnect::DisconnectEvent;
use crate::local_player::Hunger; use crate::local_player::Hunger;
use crate::packet_handling::game::KeepAliveEvent; use crate::packet_handling::game::KeepAliveEvent;
use crate::raw_connection::RawConnection; use crate::raw_connection::RawConnection;
use crate::InstanceHolder;
#[derive(Event, Debug, Clone)] #[derive(Event, Debug, Clone)]
pub struct ConfigurationEvent { pub struct ConfigurationEvent {

View file

@ -13,21 +13,22 @@ use azalea_core::{
resource_location::ResourceLocation, resource_location::ResourceLocation,
}; };
use azalea_entity::{ use azalea_entity::{
indexing::{EntityIdIndex, EntityUuidIndex},
metadata::{apply_metadata, Health},
Dead, EntityBundle, EntityKind, LastSentPosition, LoadedBy, LocalEntity, LookDirection, Dead, EntityBundle, EntityKind, LastSentPosition, LoadedBy, LocalEntity, LookDirection,
Physics, Position, RelativeEntityUpdate, Physics, Position, RelativeEntityUpdate,
indexing::{EntityIdIndex, EntityUuidIndex},
metadata::{Health, apply_metadata},
}; };
use azalea_protocol::{ use azalea_protocol::{
packets::{ packets::{
Packet,
game::{ game::{
ClientboundGamePacket, ServerboundGamePacket,
c_player_combat_kill::ClientboundPlayerCombatKill, c_player_combat_kill::ClientboundPlayerCombatKill,
s_accept_teleportation::ServerboundAcceptTeleportation, s_accept_teleportation::ServerboundAcceptTeleportation,
s_configuration_acknowledged::ServerboundConfigurationAcknowledged, s_configuration_acknowledged::ServerboundConfigurationAcknowledged,
s_keep_alive::ServerboundKeepAlive, s_move_player_pos_rot::ServerboundMovePlayerPosRot, s_keep_alive::ServerboundKeepAlive, s_move_player_pos_rot::ServerboundMovePlayerPosRot,
s_pong::ServerboundPong, ClientboundGamePacket, ServerboundGamePacket, s_pong::ServerboundPong,
}, },
Packet,
}, },
read::deserialize_packet, read::deserialize_packet,
}; };
@ -38,6 +39,7 @@ use tracing::{debug, error, trace, warn};
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
ClientInformation, PlayerInfo,
chat::{ChatPacket, ChatReceivedEvent}, chat::{ChatPacket, ChatReceivedEvent},
chunks, chunks,
disconnect::DisconnectEvent, disconnect::DisconnectEvent,
@ -49,7 +51,6 @@ use crate::{
}, },
movement::{KnockbackEvent, KnockbackType}, movement::{KnockbackEvent, KnockbackType},
raw_connection::RawConnection, raw_connection::RawConnection,
ClientInformation, PlayerInfo,
}; };
/// An event that's sent when we receive a packet. /// An event that's sent when we receive a packet.
@ -427,11 +428,7 @@ pub fn process_packet_events(ecs: &mut World) {
**last_sent_position = **position; **last_sent_position = **position;
fn apply_change<T: Add<Output = T>>(base: T, condition: bool, change: T) -> T { fn apply_change<T: Add<Output = T>>(base: T, condition: bool, change: T) -> T {
if condition { if condition { base + change } else { change }
base + change
} else {
change
}
} }
let new_x = apply_change(position.x, p.relative.x, p.change.pos.x); let new_x = apply_change(position.x, p.relative.x, p.change.pos.x);
@ -655,9 +652,13 @@ pub fn process_packet_events(ecs: &mut World) {
let entity_in_ecs = entity_query.get(ecs_entity).is_ok(); let entity_in_ecs = entity_query.get(ecs_entity).is_ok();
if entity_in_ecs { if entity_in_ecs {
error!("LoadedBy for entity {entity_id:?} ({ecs_entity:?}) isn't in the ecs, but the entity is in entity_by_id"); error!(
"LoadedBy for entity {entity_id:?} ({ecs_entity:?}) isn't in the ecs, but the entity is in entity_by_id"
);
} else { } else {
error!("Entity {entity_id:?} ({ecs_entity:?}) isn't in the ecs, but the entity is in entity_by_id"); error!(
"Entity {entity_id:?} ({ecs_entity:?}) isn't in the ecs, but the entity is in entity_by_id"
);
} }
continue; continue;
}; };
@ -719,7 +720,10 @@ pub fn process_packet_events(ecs: &mut World) {
let Some(entity) = entity else { let Some(entity) = entity else {
// some servers like hypixel trigger this a lot :( // some servers like hypixel trigger this a lot :(
debug!("Server sent an entity data packet for an entity id ({}) that we don't know about", p.id); debug!(
"Server sent an entity data packet for an entity id ({}) that we don't know about",
p.id
);
continue; continue;
}; };
let entity_kind = *entity_kind_query.get(entity).unwrap(); let entity_kind = *entity_kind_query.get(entity).unwrap();
@ -1035,7 +1039,9 @@ pub fn process_packet_events(ecs: &mut World) {
for &id in &p.entity_ids { for &id in &p.entity_ids {
let Some(entity) = entity_id_index.remove(id) else { let Some(entity) = entity_id_index.remove(id) else {
debug!("Tried to remove entity with id {id} but it wasn't in the EntityIdIndex"); debug!(
"Tried to remove entity with id {id} but it wasn't in the EntityIdIndex"
);
continue; continue;
}; };
let Ok(mut loaded_by) = entity_query.get_mut(entity) else { let Ok(mut loaded_by) = entity_query.get_mut(entity) else {

View file

@ -4,11 +4,11 @@
use std::{collections::HashSet, sync::Arc}; use std::{collections::HashSet, sync::Arc};
use azalea_protocol::packets::{ use azalea_protocol::packets::{
login::{
s_custom_query_answer::ServerboundCustomQueryAnswer, ClientboundLoginPacket,
ServerboundLoginPacket,
},
Packet, Packet,
login::{
ClientboundLoginPacket, ServerboundLoginPacket,
s_custom_query_answer::ServerboundCustomQueryAnswer,
},
}; };
use bevy_ecs::{prelude::*, system::SystemState}; use bevy_ecs::{prelude::*, system::SystemState};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};

View file

@ -1,4 +1,4 @@
use azalea_entity::{metadata::Health, EntityUpdateSet}; use azalea_entity::{EntityUpdateSet, metadata::Health};
use bevy_app::{App, First, Plugin, PreUpdate, Update}; use bevy_app::{App, First, Plugin, PreUpdate, Update};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;

View file

@ -3,19 +3,20 @@
use std::io; use std::io;
use azalea_protocol::{ use azalea_protocol::{
ServerAddress,
connect::{Connection, ConnectionError, Proxy}, connect::{Connection, ConnectionError, Proxy},
packets::{ packets::{
ClientIntention, PROTOCOL_VERSION,
handshake::{ handshake::{
s_intention::ServerboundIntention, ClientboundHandshakePacket, ClientboundHandshakePacket, ServerboundHandshakePacket,
ServerboundHandshakePacket, s_intention::ServerboundIntention,
}, },
status::{ status::{
c_status_response::ClientboundStatusResponse, ClientboundStatusPacket, c_status_response::ClientboundStatusResponse,
s_status_request::ServerboundStatusRequest, ClientboundStatusPacket, s_status_request::ServerboundStatusRequest,
}, },
ClientIntention, PROTOCOL_VERSION,
}, },
resolver, ServerAddress, resolver,
}; };
use thiserror::Error; use thiserror::Error;

View file

@ -8,7 +8,7 @@ use bevy_ecs::{
}; };
use uuid::Uuid; use uuid::Uuid;
use crate::{packet_handling::game::AddPlayerEvent, GameProfileComponent}; use crate::{GameProfileComponent, packet_handling::game::AddPlayerEvent};
/// A player in the tab list. /// A player in the tab list.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -2,7 +2,7 @@ use azalea_protocol::packets::game::s_client_command::{self, ServerboundClientCo
use bevy_app::{App, Plugin, Update}; use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use crate::packet_handling::game::{handle_send_packet_event, SendPacketEvent}; use crate::packet_handling::game::{SendPacketEvent, handle_send_packet_event};
/// Tell the server that we're respawning. /// Tell the server that we're respawning.
#[derive(Event, Debug, Clone)] #[derive(Event, Debug, Clone)]

View file

@ -5,8 +5,8 @@ use std::marker::PhantomData;
use bevy_app::{App, Last, Plugin}; use bevy_app::{App, Last, Plugin};
use bevy_ecs::system::{NonSend, Resource}; use bevy_ecs::system::{NonSend, Resource};
use bevy_tasks::{ use bevy_tasks::{
tick_global_task_pools_on_main_thread, AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder,
TaskPoolBuilder, tick_global_task_pools_on_main_thread,
}; };
/// Setup of default task pools: `AsyncComputeTaskPool`, `ComputeTaskPool`, /// Setup of default task pools: `AsyncComputeTaskPool`, `ComputeTaskPool`,

View file

@ -25,9 +25,9 @@ use tokio::{sync::mpsc, time::sleep};
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
ClientInformation, GameProfileComponent, InConfigState, InstanceHolder, LocalPlayerBundle,
events::LocalPlayerEvents, events::LocalPlayerEvents,
raw_connection::{RawConnection, RawConnectionReader, RawConnectionWriter}, raw_connection::{RawConnection, RawConnectionReader, RawConnectionWriter},
ClientInformation, GameProfileComponent, InConfigState, InstanceHolder, LocalPlayerBundle,
}; };
/// A way to simulate a client in a server, used for some internal tests. /// A way to simulate a client in a server, used for some internal tests.

View file

@ -1,10 +1,10 @@
use azalea_client::{test_simulation::*, InConfigState}; use azalea_client::{InConfigState, test_simulation::*};
use azalea_core::{position::ChunkPos, resource_location::ResourceLocation}; use azalea_core::{position::ChunkPos, resource_location::ResourceLocation};
use azalea_entity::{metadata::Health, LocalEntity}; use azalea_entity::{LocalEntity, metadata::Health};
use azalea_protocol::packets::{ use azalea_protocol::packets::{
ConnectionProtocol,
config::{ClientboundFinishConfiguration, ClientboundRegistryData}, config::{ClientboundFinishConfiguration, ClientboundRegistryData},
game::ClientboundSetHealth, game::ClientboundSetHealth,
ConnectionProtocol,
}; };
use azalea_registry::DimensionType; use azalea_registry::DimensionType;
use azalea_world::InstanceName; use azalea_world::InstanceName;

View file

@ -1,10 +1,10 @@
use azalea_client::{test_simulation::*, InConfigState}; use azalea_client::{InConfigState, test_simulation::*};
use azalea_core::resource_location::ResourceLocation; use azalea_core::resource_location::ResourceLocation;
use azalea_entity::{metadata::Health, LocalEntity}; use azalea_entity::{LocalEntity, metadata::Health};
use azalea_protocol::packets::{ use azalea_protocol::packets::{
ConnectionProtocol,
config::{ClientboundFinishConfiguration, ClientboundRegistryData}, config::{ClientboundFinishConfiguration, ClientboundRegistryData},
game::ClientboundSetHealth, game::ClientboundSetHealth,
ConnectionProtocol,
}; };
use azalea_registry::DimensionType; use azalea_registry::DimensionType;
use bevy_log::tracing_subscriber; use bevy_log::tracing_subscriber;

View file

@ -91,18 +91,10 @@ pub fn to_degrees(radians: f64) -> f64 {
/// ///
/// This function exists because f64::signum doesn't check for 0. /// This function exists because f64::signum doesn't check for 0.
pub fn sign(num: f64) -> f64 { pub fn sign(num: f64) -> f64 {
if num == 0. { if num == 0. { 0. } else { num.signum() }
0.
} else {
num.signum()
}
} }
pub fn sign_as_int(num: f64) -> i32 { pub fn sign_as_int(num: f64) -> i32 {
if num == 0. { if num == 0. { 0 } else { num.signum() as i32 }
0
} else {
num.signum() as i32
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -9,8 +9,8 @@ use std::{collections::HashMap, io::Cursor};
use indexmap::IndexMap; use indexmap::IndexMap;
use simdnbt::{ use simdnbt::{
owned::{NbtCompound, NbtTag},
Deserialize, FromNbtTag, Serialize, ToNbtTag, Deserialize, FromNbtTag, Serialize, ToNbtTag,
owned::{NbtCompound, NbtTag},
}; };
use tracing::error; use tracing::error;

View file

@ -8,8 +8,8 @@ use std::{
use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError}; use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
use simdnbt::{owned::NbtTag, FromNbtTag, ToNbtTag}; use simdnbt::{FromNbtTag, ToNbtTag, owned::NbtTag};
#[derive(Hash, Clone, PartialEq, Eq)] #[derive(Hash, Clone, PartialEq, Eq)]
pub struct ResourceLocation { pub struct ResourceLocation {

View file

@ -1,5 +1,5 @@
use azalea_crypto::{create_cipher, decrypt_packet, encrypt_packet}; use azalea_crypto::{create_cipher, decrypt_packet, encrypt_packet};
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{Criterion, criterion_group, criterion_main};
fn bench(c: &mut Criterion) { fn bench(c: &mut Criterion) {
let (mut enc, dec) = create_cipher(b"0123456789abcdef"); let (mut enc, dec) = create_cipher(b"0123456789abcdef");

View file

@ -4,10 +4,10 @@ mod signing;
use aes::cipher::inout::InOutBuf; use aes::cipher::inout::InOutBuf;
use aes::{ use aes::{
cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit},
Aes128, Aes128,
cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit},
}; };
use rand::{rngs::OsRng, RngCore}; use rand::{RngCore, rngs::OsRng};
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
pub use signing::*; pub use signing::*;

View file

@ -2,8 +2,8 @@ use std::time::{SystemTime, UNIX_EPOCH};
use azalea_buf::{AzBuf, AzaleaWrite}; use azalea_buf::{AzBuf, AzaleaWrite};
use rsa::{ use rsa::{
signature::{RandomizedSigner, SignatureEncoding},
RsaPrivateKey, RsaPrivateKey,
signature::{RandomizedSigner, SignatureEncoding},
}; };
use sha2::Sha256; use sha2::Sha256;
use uuid::Uuid; use uuid::Uuid;

View file

@ -1,6 +1,6 @@
//! See <https://minecraft.fandom.com/wiki/Attribute>. //! See <https://minecraft.fandom.com/wiki/Attribute>.
use std::collections::{hash_map, HashMap}; use std::collections::{HashMap, hash_map};
use azalea_buf::AzBuf; use azalea_buf::AzBuf;
use azalea_core::resource_location::ResourceLocation; use azalea_core::resource_location::ResourceLocation;

View file

@ -17,7 +17,7 @@ use std::{
}; };
pub use attributes::Attributes; pub use attributes::Attributes;
use azalea_block::{fluid_state::FluidKind, BlockState}; use azalea_block::{BlockState, fluid_state::FluidKind};
use azalea_buf::AzBuf; use azalea_buf::AzBuf;
use azalea_core::{ use azalea_core::{
aabb::AABB, aabb::AABB,

View file

@ -2,7 +2,7 @@ use azalea_block::{Block, BlockBehavior};
use azalea_core::tier::get_item_tier; use azalea_core::tier::get_item_tier;
use azalea_registry as registry; use azalea_registry as registry;
use crate::{effects, FluidOnEyes, Physics}; use crate::{FluidOnEyes, Physics, effects};
/// How much progress is made towards mining the block per tick, as a /// How much progress is made towards mining the block per tick, as a
/// percentage. If this is 1 then the block gets broken instantly. /// percentage. If this is 1 then the block gets broken instantly.

View file

@ -181,19 +181,24 @@ pub fn remove_despawned_entities_from_indexes(
// remove the entity from the chunk index // remove the entity from the chunk index
let chunk = ChunkPos::from(*position); let chunk = ChunkPos::from(*position);
if let Some(entities_in_chunk) = instance.entities_by_chunk.get_mut(&chunk) { match instance.entities_by_chunk.get_mut(&chunk) {
if entities_in_chunk.remove(&entity) { Some(entities_in_chunk) => {
// remove the chunk if there's no entities in it anymore if entities_in_chunk.remove(&entity) {
if entities_in_chunk.is_empty() { // remove the chunk if there's no entities in it anymore
instance.entities_by_chunk.remove(&chunk); if entities_in_chunk.is_empty() {
instance.entities_by_chunk.remove(&chunk);
}
} else {
warn!(
"Tried to remove entity {entity:?} from chunk {chunk:?} but the entity was not there."
);
} }
} else { }
warn!( _ => {
"Tried to remove entity {entity:?} from chunk {chunk:?} but the entity was not there." debug!(
"Tried to remove entity {entity:?} from chunk {chunk:?} but the chunk was not found."
); );
} }
} else {
debug!("Tried to remove entity {entity:?} from chunk {chunk:?} but the chunk was not found.");
} }
// remove it from the uuid index // remove it from the uuid index
if entity_uuid_index.entity_by_uuid.remove(uuid).is_none() { if entity_uuid_index.entity_by_uuid.remove(uuid).is_none() {

View file

@ -3,7 +3,7 @@ mod relative_updates;
use std::collections::HashSet; use std::collections::HashSet;
use azalea_block::{fluid_state::FluidKind, BlockState}; use azalea_block::{BlockState, fluid_state::FluidKind};
use azalea_core::{ use azalea_core::{
position::{BlockPos, ChunkPos, Vec3}, position::{BlockPos, ChunkPos, Vec3},
tick::GameTick, tick::GameTick,
@ -17,8 +17,8 @@ pub use relative_updates::RelativeEntityUpdate;
use tracing::debug; use tracing::debug;
use crate::{ use crate::{
metadata::Health, Dead, EyeHeight, FluidOnEyes, LocalEntity, LookDirection, OnClimbable, Dead, EyeHeight, FluidOnEyes, LocalEntity, LookDirection, OnClimbable, Physics, Position,
Physics, Position, metadata::Health,
}; };
/// A Bevy [`SystemSet`] for various types of entity updates. /// A Bevy [`SystemSet`] for various types of entity updates.

View file

@ -8,7 +8,7 @@ use parse_macro::{DeclareMenus, Field};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::Span; use proc_macro2::Span;
use quote::quote; use quote::quote;
use syn::{parse_macro_input, Ident}; use syn::{Ident, parse_macro_input};
#[proc_macro] #[proc_macro]
pub fn declare_menus(input: TokenStream) -> TokenStream { pub fn declare_menus(input: TokenStream) -> TokenStream {

View file

@ -1,7 +1,6 @@
use syn::{ use syn::{
braced, Ident, LitInt, Token, braced,
parse::{Parse, ParseStream, Result}, parse::{Parse, ParseStream, Result},
Ident, LitInt, Token,
}; };
/// An identifier, colon, and number /// An identifier, colon, and number

View file

@ -42,10 +42,9 @@ where
} }
fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool { fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool {
let other_any: Box<dyn Any> = other; let other_any: Box<dyn Any> = other;
if let Some(other) = other_any.downcast_ref::<T>() { match other_any.downcast_ref::<T>() {
self == other Some(other) => self == other,
} else { _ => false,
false
} }
} }
} }

View file

@ -3,14 +3,14 @@ use std::ops::RangeInclusive;
use azalea_buf::AzBuf; use azalea_buf::AzBuf;
use crate::{ use crate::{
item::MaxStackSizeExt, AnvilMenuLocation, BeaconMenuLocation, BlastFurnaceMenuLocation, AnvilMenuLocation, BeaconMenuLocation, BlastFurnaceMenuLocation, BrewingStandMenuLocation,
BrewingStandMenuLocation, CartographyTableMenuLocation, Crafter3x3MenuLocation, CartographyTableMenuLocation, Crafter3x3MenuLocation, CraftingMenuLocation,
CraftingMenuLocation, EnchantmentMenuLocation, FurnaceMenuLocation, Generic3x3MenuLocation, EnchantmentMenuLocation, FurnaceMenuLocation, Generic3x3MenuLocation, Generic9x1MenuLocation,
Generic9x1MenuLocation, Generic9x2MenuLocation, Generic9x3MenuLocation, Generic9x4MenuLocation, Generic9x2MenuLocation, Generic9x3MenuLocation, Generic9x4MenuLocation, Generic9x5MenuLocation,
Generic9x5MenuLocation, Generic9x6MenuLocation, GrindstoneMenuLocation, HopperMenuLocation, Generic9x6MenuLocation, GrindstoneMenuLocation, HopperMenuLocation, ItemStack, ItemStackData,
ItemStack, ItemStackData, LecternMenuLocation, LoomMenuLocation, Menu, MenuLocation, LecternMenuLocation, LoomMenuLocation, Menu, MenuLocation, MerchantMenuLocation, Player,
MerchantMenuLocation, Player, PlayerMenuLocation, ShulkerBoxMenuLocation, SmithingMenuLocation, PlayerMenuLocation, ShulkerBoxMenuLocation, SmithingMenuLocation, SmokerMenuLocation,
SmokerMenuLocation, StonecutterMenuLocation, StonecutterMenuLocation, item::MaxStackSizeExt,
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -310,21 +310,24 @@ impl PartialEq for DataComponentPatch {
return false; return false;
} }
for (kind, component) in &self.components { for (kind, component) in &self.components {
if let Some(other_component) = other.components.get(kind) { match other.components.get(kind) {
// we can't use PartialEq, but we can use our own eq method Some(other_component) => {
if let Some(component) = component { // we can't use PartialEq, but we can use our own eq method
if let Some(other_component) = other_component { if let Some(component) = component {
if !component.eq((*other_component).clone()) { if let Some(other_component) = other_component {
if !component.eq((*other_component).clone()) {
return false;
}
} else {
return false; return false;
} }
} else { } else if other_component.is_some() {
return false; return false;
} }
} else if other_component.is_some() { }
_ => {
return false; return false;
} }
} else {
return false;
} }
} }
true true

View file

@ -1,21 +1,21 @@
use std::collections::HashSet; use std::collections::HashSet;
use azalea_block::{ use azalea_block::{
fluid_state::{FluidKind, FluidState},
BlockState, BlockState,
fluid_state::{FluidKind, FluidState},
}; };
use azalea_core::{ use azalea_core::{
aabb::AABB, aabb::AABB,
block_hit_result::BlockHitResult, block_hit_result::BlockHitResult,
direction::{Axis, Direction}, direction::{Axis, Direction},
math::{self, lerp, EPSILON}, math::{self, EPSILON, lerp},
position::{BlockPos, Vec3}, position::{BlockPos, Vec3},
}; };
use azalea_inventory::ItemStack; use azalea_inventory::ItemStack;
use azalea_world::ChunkStorage; use azalea_world::ChunkStorage;
use bevy_ecs::entity::Entity; use bevy_ecs::entity::Entity;
use crate::collision::{BlockWithShape, VoxelShape, EMPTY_SHAPE}; use crate::collision::{BlockWithShape, EMPTY_SHAPE, VoxelShape};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ClipContext { pub struct ClipContext {

View file

@ -1,6 +1,6 @@
use std::cmp::{self, Ordering}; use std::cmp::{self, Ordering};
use azalea_core::math::{gcd, lcm, EPSILON}; use azalea_core::math::{EPSILON, gcd, lcm};
use super::CubePointRange; use super::CubePointRange;

View file

@ -6,7 +6,7 @@ mod world_collisions;
use std::{ops::Add, sync::LazyLock}; use std::{ops::Add, sync::LazyLock};
use azalea_block::{fluid_state::FluidState, BlockState}; use azalea_block::{BlockState, fluid_state::FluidState};
use azalea_core::{ use azalea_core::{
aabb::AABB, aabb::AABB,
direction::Axis, direction::Axis,

View file

@ -3,12 +3,12 @@ use std::{cmp, num::NonZeroU32, sync::LazyLock};
use azalea_core::{ use azalea_core::{
block_hit_result::BlockHitResult, block_hit_result::BlockHitResult,
direction::{Axis, AxisCycle, Direction}, direction::{Axis, AxisCycle, Direction},
math::{binary_search, EPSILON}, math::{EPSILON, binary_search},
position::{BlockPos, Vec3}, position::{BlockPos, Vec3},
}; };
use super::mergers::IndexMerger; use super::mergers::IndexMerger;
use crate::collision::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB}; use crate::collision::{AABB, BitSetDiscreteVoxelShape, DiscreteVoxelShape};
pub struct Shapes; pub struct Shapes;

View file

@ -9,8 +9,8 @@ use azalea_core::{
use azalea_world::{Chunk, Instance}; use azalea_world::{Chunk, Instance};
use parking_lot::RwLock; use parking_lot::RwLock;
use super::{Shapes, BLOCK_SHAPE}; use super::{BLOCK_SHAPE, Shapes};
use crate::collision::{BlockWithShape, VoxelShape, AABB}; use crate::collision::{AABB, BlockWithShape, VoxelShape};
pub fn get_block_collisions(world: &Instance, aabb: AABB) -> Vec<VoxelShape> { pub fn get_block_collisions(world: &Instance, aabb: AABB) -> Vec<VoxelShape> {
let mut state = BlockCollisionsState::new(world, aabb); let mut state = BlockCollisionsState::new(world, aabb);
@ -27,12 +27,11 @@ pub fn get_block_collisions(world: &Instance, aabb: AABB) -> Vec<VoxelShape> {
let item_chunk_pos = ChunkPos::from(item.pos); let item_chunk_pos = ChunkPos::from(item.pos);
let block_state: BlockState = if item_chunk_pos == initial_chunk_pos { let block_state: BlockState = if item_chunk_pos == initial_chunk_pos {
if let Some(initial_chunk) = &initial_chunk { match &initial_chunk {
initial_chunk Some(initial_chunk) => initial_chunk
.get(&ChunkBlockPos::from(item.pos), state.world.chunks.min_y) .get(&ChunkBlockPos::from(item.pos), state.world.chunks.min_y)
.unwrap_or(BlockState::AIR) .unwrap_or(BlockState::AIR),
} else { _ => BlockState::AIR,
BlockState::AIR
} }
} else { } else {
state.get_block_state(item.pos) state.get_block_state(item.pos)

View file

@ -1,6 +1,6 @@
use azalea_block::{ use azalea_block::{
fluid_state::{FluidKind, FluidState},
BlockState, BlockState,
fluid_state::{FluidKind, FluidState},
}; };
use azalea_core::{ use azalea_core::{
direction::Direction, direction::Direction,

View file

@ -8,15 +8,15 @@ pub mod travel;
use std::collections::HashSet; use std::collections::HashSet;
use azalea_block::{fluid_state::FluidState, properties, Block, BlockState}; use azalea_block::{Block, BlockState, fluid_state::FluidState, properties};
use azalea_core::{ use azalea_core::{
math, math,
position::{BlockPos, Vec3}, position::{BlockPos, Vec3},
tick::GameTick, tick::GameTick,
}; };
use azalea_entity::{ use azalea_entity::{
metadata::Sprinting, move_relative, Attributes, InLoadedChunk, Jumping, LocalEntity, Attributes, InLoadedChunk, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, Pose,
LookDirection, OnClimbable, Physics, Pose, Position, Position, metadata::Sprinting, move_relative,
}; };
use azalea_world::{Instance, InstanceContainer, InstanceName}; use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_app::{App, Plugin}; use bevy_app::{App, Plugin};
@ -27,7 +27,7 @@ use bevy_ecs::{
world::Mut, world::Mut,
}; };
use clip::box_traverse_blocks; use clip::box_traverse_blocks;
use collision::{move_colliding, BlockWithShape, MoverType, VoxelShape, BLOCK_SHAPE}; use collision::{BLOCK_SHAPE, BlockWithShape, MoverType, VoxelShape, move_colliding};
/// A Bevy [`SystemSet`] for running physics that makes entities do things. /// A Bevy [`SystemSet`] for running physics that makes entities do things.
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
@ -476,11 +476,7 @@ fn get_friction_influenced_speed(
speed * (0.216f32 / (friction * friction * friction)) speed * (0.216f32 / (friction * friction * friction))
} else { } else {
// entity.flying_speed // entity.flying_speed
if is_sprinting { if is_sprinting { 0.025999999f32 } else { 0.02 }
0.025999999f32
} else {
0.02
}
} }
} }

View file

@ -1,16 +1,16 @@
use azalea_block::{Block, BlockState}; use azalea_block::{Block, BlockState};
use azalea_core::{aabb::AABB, position::Vec3}; use azalea_core::{aabb::AABB, position::Vec3};
use azalea_entity::{ use azalea_entity::{
metadata::Sprinting, move_relative, Attributes, InLoadedChunk, Jumping, LocalEntity, Attributes, InLoadedChunk, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, Pose,
LookDirection, OnClimbable, Physics, Pose, Position, Position, metadata::Sprinting, move_relative,
}; };
use azalea_world::{Instance, InstanceContainer, InstanceName}; use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use crate::{ use crate::{
collision::{move_colliding, MoverType},
get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement,
HandleRelativeFrictionAndCalculateMovementOpts, HandleRelativeFrictionAndCalculateMovementOpts,
collision::{MoverType, move_colliding},
get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement,
}; };
/// Move the entity with the given acceleration while handling friction, /// Move the entity with the given acceleration while handling friction,

View file

@ -1,9 +1,9 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{ use syn::{
bracketed, DeriveInput, Ident, Token, bracketed,
parse::{Parse, ParseStream, Result}, parse::{Parse, ParseStream, Result},
parse_macro_input, DeriveInput, Ident, Token, parse_macro_input,
}; };
fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> TokenStream { fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> TokenStream {

View file

@ -6,17 +6,17 @@ use std::{error::Error, sync::LazyLock};
use azalea_protocol::{ use azalea_protocol::{
connect::Connection, connect::Connection,
packets::{ packets::{
ClientIntention, PROTOCOL_VERSION, VERSION_NAME,
handshake::{ handshake::{
s_intention::ServerboundIntention, ClientboundHandshakePacket, ClientboundHandshakePacket, ServerboundHandshakePacket,
ServerboundHandshakePacket, s_intention::ServerboundIntention,
}, },
login::{s_hello::ServerboundHello, ServerboundLoginPacket}, login::{ServerboundLoginPacket, s_hello::ServerboundHello},
status::{ status::{
ServerboundStatusPacket,
c_pong_response::ClientboundPongResponse, c_pong_response::ClientboundPongResponse,
c_status_response::{ClientboundStatusResponse, Players, Version}, c_status_response::{ClientboundStatusResponse, Players, Version},
ServerboundStatusPacket,
}, },
ClientIntention, PROTOCOL_VERSION, VERSION_NAME,
}, },
read::ReadPacketError, read::ReadPacketError,
}; };

View file

@ -10,19 +10,19 @@ use azalea_auth::sessionserver::{ClientSessionServerError, ServerSessionServerEr
use azalea_crypto::{Aes128CfbDec, Aes128CfbEnc}; use azalea_crypto::{Aes128CfbDec, Aes128CfbEnc};
use thiserror::Error; use thiserror::Error;
use tokio::io::{AsyncWriteExt, BufStream}; use tokio::io::{AsyncWriteExt, BufStream};
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf, ReuniteError};
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf, ReuniteError};
use tracing::{error, info}; use tracing::{error, info};
use uuid::Uuid; use uuid::Uuid;
use crate::packets::ProtocolPacket;
use crate::packets::config::{ClientboundConfigPacket, ServerboundConfigPacket}; use crate::packets::config::{ClientboundConfigPacket, ServerboundConfigPacket};
use crate::packets::game::{ClientboundGamePacket, ServerboundGamePacket}; use crate::packets::game::{ClientboundGamePacket, ServerboundGamePacket};
use crate::packets::handshake::{ClientboundHandshakePacket, ServerboundHandshakePacket}; use crate::packets::handshake::{ClientboundHandshakePacket, ServerboundHandshakePacket};
use crate::packets::login::c_hello::ClientboundHello; use crate::packets::login::c_hello::ClientboundHello;
use crate::packets::login::{ClientboundLoginPacket, ServerboundLoginPacket}; use crate::packets::login::{ClientboundLoginPacket, ServerboundLoginPacket};
use crate::packets::status::{ClientboundStatusPacket, ServerboundStatusPacket}; use crate::packets::status::{ClientboundStatusPacket, ServerboundStatusPacket};
use crate::packets::ProtocolPacket; use crate::read::{ReadPacketError, deserialize_packet, read_raw_packet, try_read_raw_packet};
use crate::read::{deserialize_packet, read_raw_packet, try_read_raw_packet, ReadPacketError};
use crate::write::{serialize_packet, write_raw_packet}; use crate::write::{serialize_packet, write_raw_packet};
pub struct RawReadConnection { pub struct RawReadConnection {

View file

@ -115,9 +115,9 @@ mod tests {
use crate::{ use crate::{
packets::{ packets::{
game::s_chat::{LastSeenMessagesUpdate, ServerboundChat},
login::{s_hello::ServerboundHello, ServerboundLoginPacket},
Packet, Packet,
game::s_chat::{LastSeenMessagesUpdate, ServerboundChat},
login::{ServerboundLoginPacket, s_hello::ServerboundHello},
}, },
read::{compression_decoder, read_packet}, read::{compression_decoder, read_packet},
write::{compression_encoder, serialize_packet, write_packet}, write::{compression_encoder, serialize_packet, write_packet},
@ -136,7 +136,9 @@ mod tests {
assert_eq!( assert_eq!(
stream, stream,
[22, 0, 4, 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [
22, 0, 4, 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
); );
let mut stream = Cursor::new(stream); let mut stream = Cursor::new(stream);

View file

@ -4,8 +4,8 @@ use std::net::{IpAddr, SocketAddr};
use async_recursion::async_recursion; use async_recursion::async_recursion;
use hickory_resolver::{ use hickory_resolver::{
config::{ResolverConfig, ResolverOpts},
Name, TokioAsyncResolver, Name, TokioAsyncResolver,
config::{ResolverConfig, ResolverOpts},
}; };
use thiserror::Error; use thiserror::Error;

View file

@ -7,7 +7,7 @@ use std::{
use azalea_buf::AzaleaWriteVar; use azalea_buf::AzaleaWriteVar;
use azalea_crypto::Aes128CfbEnc; use azalea_crypto::Aes128CfbEnc;
use flate2::{bufread::ZlibEncoder, Compression}; use flate2::{Compression, bufread::ZlibEncoder};
use thiserror::Error; use thiserror::Error;
use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio::io::{AsyncWrite, AsyncWriteExt};
use tracing::trace; use tracing::trace;

View file

@ -1,11 +1,10 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{ use syn::{
braced, Attribute, Ident, LitStr, Token, braced,
parse::{Parse, ParseStream, Result}, parse::{Parse, ParseStream, Result},
parse_macro_input, parse_macro_input,
punctuated::Punctuated, punctuated::Punctuated,
Attribute, Ident, LitStr, Token,
}; };
struct RegistryItem { struct RegistryItem {

View file

@ -2,7 +2,7 @@ use std::hint::black_box;
use azalea_core::position::ChunkBlockPos; use azalea_core::position::ChunkBlockPos;
use azalea_world::{BitStorage, Chunk}; use azalea_world::{BitStorage, Chunk};
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{Criterion, criterion_group, criterion_main};
fn bench_chunks(c: &mut Criterion) { fn bench_chunks(c: &mut Criterion) {
c.bench_function("Chunk::set", |b| { c.bench_function("Chunk::set", |b| {

View file

@ -556,21 +556,31 @@ mod tests {
Some(Chunk::default()), Some(Chunk::default()),
&mut chunk_storage, &mut chunk_storage,
); );
assert!(chunk_storage assert!(
.get_block_state(&BlockPos { x: 0, y: 319, z: 0 }) chunk_storage
.is_some()); .get_block_state(&BlockPos { x: 0, y: 319, z: 0 })
assert!(chunk_storage .is_some()
.get_block_state(&BlockPos { x: 0, y: 320, z: 0 }) );
.is_none()); assert!(
assert!(chunk_storage chunk_storage
.get_block_state(&BlockPos { x: 0, y: 338, z: 0 }) .get_block_state(&BlockPos { x: 0, y: 320, z: 0 })
.is_none()); .is_none()
assert!(chunk_storage );
.get_block_state(&BlockPos { x: 0, y: -64, z: 0 }) assert!(
.is_some()); chunk_storage
assert!(chunk_storage .get_block_state(&BlockPos { x: 0, y: 338, z: 0 })
.get_block_state(&BlockPos { x: 0, y: -65, z: 0 }) .is_none()
.is_none()); );
assert!(
chunk_storage
.get_block_state(&BlockPos { x: 0, y: -64, z: 0 })
.is_some()
);
assert!(
chunk_storage
.get_block_state(&BlockPos { x: 0, y: -65, z: 0 })
.is_none()
);
} }
#[test] #[test]

View file

@ -53,31 +53,34 @@ impl InstanceContainer {
min_y: i32, min_y: i32,
default_registries: &RegistryHolder, default_registries: &RegistryHolder,
) -> Arc<RwLock<Instance>> { ) -> Arc<RwLock<Instance>> {
if let Some(existing_lock) = self.instances.get(&name).and_then(|world| world.upgrade()) { match self.instances.get(&name).and_then(|world| world.upgrade()) {
let existing = existing_lock.read(); Some(existing_lock) => {
if existing.chunks.height != height { let existing = existing_lock.read();
error!( if existing.chunks.height != height {
"Shared dimension height mismatch: {} != {height}", error!(
existing.chunks.height "Shared dimension height mismatch: {} != {height}",
); existing.chunks.height
);
}
if existing.chunks.min_y != min_y {
error!(
"Shared world min_y mismatch: {} != {min_y}",
existing.chunks.min_y
);
}
existing_lock.clone()
} }
if existing.chunks.min_y != min_y { _ => {
error!( let world = Arc::new(RwLock::new(Instance {
"Shared world min_y mismatch: {} != {min_y}", chunks: ChunkStorage::new(height, min_y),
existing.chunks.min_y entities_by_chunk: HashMap::new(),
); entity_by_id: IntMap::default(),
registries: default_registries.clone(),
}));
debug!("Added new instance {name}");
self.instances.insert(name, Arc::downgrade(&world));
world
} }
existing_lock.clone()
} else {
let world = Arc::new(RwLock::new(Instance {
chunks: ChunkStorage::new(height, min_y),
entities_by_chunk: HashMap::new(),
entity_by_id: IntMap::default(),
registries: default_registries.clone(),
}));
debug!("Added new instance {name}");
self.instances.insert(name, Arc::downgrade(&world));
world
} }
} }
} }

View file

@ -1,7 +1,7 @@
use azalea_block::{block_state::BlockState, BlockStates}; use azalea_block::{BlockStates, block_state::BlockState};
use azalea_core::position::{BlockPos, ChunkPos}; use azalea_core::position::{BlockPos, ChunkPos};
use crate::{iterators::ChunkIterator, palette::Palette, ChunkStorage, Instance}; use crate::{ChunkStorage, Instance, iterators::ChunkIterator, palette::Palette};
fn palette_maybe_has_block(palette: &Palette, block_states: &BlockStates) -> bool { fn palette_maybe_has_block(palette: &Palette, block_states: &BlockStates) -> bool {
match &palette { match &palette {

View file

@ -4,7 +4,7 @@ use azalea_block::BlockState;
use azalea_core::{math, position::ChunkBlockPos}; use azalea_core::{math, position::ChunkBlockPos};
use azalea_registry::tags::blocks::LEAVES; use azalea_registry::tags::blocks::LEAVES;
use crate::{chunk_storage::get_block_state_from_sections, BitStorage, Section}; use crate::{BitStorage, Section, chunk_storage::get_block_state_from_sections};
// (wg stands for worldgen) // (wg stands for worldgen)

View file

@ -6,8 +6,8 @@ use std::{
fmt::Debug, fmt::Debug,
}; };
use azalea_block::fluid_state::FluidState;
use azalea_block::BlockState; use azalea_block::BlockState;
use azalea_block::fluid_state::FluidState;
use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError}; use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
use azalea_core::position::{BlockPos, ChunkPos}; use azalea_core::position::{BlockPos, ChunkPos};
use azalea_core::registry_holder::RegistryHolder; use azalea_core::registry_holder::RegistryHolder;

View file

@ -2,7 +2,7 @@ use std::hint::black_box;
use azalea::pathfinder::mining::MiningCache; use azalea::pathfinder::mining::MiningCache;
pub use azalea_registry as registry; pub use azalea_registry as registry;
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{Criterion, criterion_group, criterion_main};
fn benchmark(c: &mut Criterion) { fn benchmark(c: &mut Criterion) {
let mining_cache = MiningCache::new(None); let mining_cache = MiningCache::new(None);

View file

@ -1,21 +1,21 @@
use std::{hint::black_box, sync::Arc, time::Duration}; use std::{hint::black_box, sync::Arc, time::Duration};
use azalea::{ use azalea::{
BlockPos,
pathfinder::{ pathfinder::{
astar::{self, a_star, PathfinderTimeout}, astar::{self, PathfinderTimeout, a_star},
goals::{BlockPosGoal, Goal}, goals::{BlockPosGoal, Goal},
mining::MiningCache, mining::MiningCache,
rel_block_pos::RelBlockPos, rel_block_pos::RelBlockPos,
world::CachedWorld, world::CachedWorld,
}, },
BlockPos,
}; };
use azalea_core::position::{ChunkBlockPos, ChunkPos}; use azalea_core::position::{ChunkBlockPos, ChunkPos};
use azalea_inventory::Menu; use azalea_inventory::Menu;
use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage}; use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage};
use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use criterion::{Bencher, Criterion, criterion_group, criterion_main};
use parking_lot::RwLock; use parking_lot::RwLock;
use rand::{rngs::StdRng, Rng, SeedableRng}; use rand::{Rng, SeedableRng, rngs::StdRng};
#[allow(dead_code)] #[allow(dead_code)]
fn generate_bedrock_world( fn generate_bedrock_world(

View file

@ -1,10 +1,10 @@
use azalea::{ use azalea::{
pathfinder::simulation::{SimulatedPlayerBundle, SimulationSet},
Vec3, Vec3,
pathfinder::simulation::{SimulatedPlayerBundle, SimulationSet},
}; };
use azalea_core::position::{ChunkBlockPos, ChunkPos}; use azalea_core::position::{ChunkBlockPos, ChunkPos};
use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage}; use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage};
use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use criterion::{Bencher, Criterion, criterion_group, criterion_main};
#[allow(dead_code)] #[allow(dead_code)]
fn generate_world(partial_chunks: &mut PartialChunkStorage, size: u32) -> ChunkStorage { fn generate_world(partial_chunks: &mut PartialChunkStorage, size: u32) -> ChunkStorage {

View file

@ -7,7 +7,9 @@ fn main() {
if toolchain.contains("nightly") { if toolchain.contains("nightly") {
return; return;
} else { } else {
panic!("Azalea currently requires nightly Rust. You can run `rustup override set nightly` to set the toolchain for this directory."); panic!(
"Azalea currently requires nightly Rust. You can run `rustup override set nightly` to set the toolchain for this directory."
);
} }
} }
@ -22,7 +24,9 @@ fn main() {
if rustc_command.status.success() { if rustc_command.status.success() {
let rustc_output = String::from_utf8(rustc_command.stdout).unwrap(); let rustc_output = String::from_utf8(rustc_command.stdout).unwrap();
if !rustc_output.contains("nightly") { if !rustc_output.contains("nightly") {
panic!("Azalea currently requires nightly Rust. Please check the documentation for your installation method and ensure you are using the nightly toolchain."); panic!(
"Azalea currently requires nightly Rust. Please check the documentation for your installation method and ensure you are using the nightly toolchain."
);
} }
} else { } else {
let rustc_output = String::from_utf8(rustc_command.stderr).unwrap(); let rustc_output = String::from_utf8(rustc_command.stderr).unwrap();

View file

@ -1,5 +1,5 @@
use azalea::nearest_entity::EntityFinder;
use azalea::ClientBuilder; use azalea::ClientBuilder;
use azalea::nearest_entity::EntityFinder;
use azalea::{Bot, LookAtEvent}; use azalea::{Bot, LookAtEvent};
use azalea_client::Account; use azalea_client::Account;
use azalea_core::tick::GameTick; use azalea_core::tick::GameTick;

View file

@ -2,9 +2,9 @@
use std::sync::Arc; use std::sync::Arc;
use azalea::{prelude::*, BlockPos}; use azalea::{BlockPos, prelude::*};
use azalea_inventory::operations::QuickMoveClick;
use azalea_inventory::ItemStack; use azalea_inventory::ItemStack;
use azalea_inventory::operations::QuickMoveClick;
use parking_lot::Mutex; use parking_lot::Mutex;
#[tokio::main] #[tokio::main]

View file

@ -2,12 +2,12 @@ pub mod combat;
pub mod debug; pub mod debug;
pub mod movement; pub mod movement;
use azalea::Client;
use azalea::GameProfileComponent;
use azalea::brigadier::prelude::*; use azalea::brigadier::prelude::*;
use azalea::chat::ChatPacket; use azalea::chat::ChatPacket;
use azalea::ecs::prelude::*; use azalea::ecs::prelude::*;
use azalea::entity::metadata::Player; use azalea::entity::metadata::Player;
use azalea::Client;
use azalea::GameProfileComponent;
use parking_lot::Mutex; use parking_lot::Mutex;
use crate::State; use crate::State;

View file

@ -3,12 +3,12 @@
use std::{env, fs::File, io::Write, thread, time::Duration}; use std::{env, fs::File, io::Write, thread, time::Duration};
use azalea::{ use azalea::{
BlockPos,
brigadier::prelude::*, brigadier::prelude::*,
entity::{LookDirection, Position}, entity::{LookDirection, Position},
interact::HitResultComponent, interact::HitResultComponent,
pathfinder::{ExecutingPath, Pathfinder}, pathfinder::{ExecutingPath, Pathfinder},
world::MinecraftEntityId, world::MinecraftEntityId,
BlockPos,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;

View file

@ -1,11 +1,11 @@
use std::time::Duration; use std::time::Duration;
use azalea::{ use azalea::{
BlockPos, SprintDirection, WalkDirection,
brigadier::prelude::*, brigadier::prelude::*,
entity::{EyeHeight, Position}, entity::{EyeHeight, Position},
pathfinder::goals::{BlockPosGoal, RadiusGoal, XZGoal}, pathfinder::goals::{BlockPosGoal, RadiusGoal, XZGoal},
prelude::*, prelude::*,
BlockPos, SprintDirection, WalkDirection,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;

View file

@ -1,6 +1,6 @@
use azalea::{ use azalea::{
ecs::prelude::*, ecs::prelude::*,
entity::{metadata::AbstractMonster, Dead, LocalEntity, Position}, entity::{Dead, LocalEntity, Position, metadata::AbstractMonster},
prelude::*, prelude::*,
world::{InstanceName, MinecraftEntityId}, world::{InstanceName, MinecraftEntityId},
}; };

View file

@ -29,13 +29,13 @@ use std::time::Duration;
use std::{env, process}; use std::{env, process};
use std::{sync::Arc, thread}; use std::{sync::Arc, thread};
use azalea::ClientInformation;
use azalea::brigadier::command_dispatcher::CommandDispatcher; use azalea::brigadier::command_dispatcher::CommandDispatcher;
use azalea::ecs::prelude::*; use azalea::ecs::prelude::*;
use azalea::pathfinder::PathfinderDebugParticles; use azalea::pathfinder::PathfinderDebugParticles;
use azalea::prelude::*; use azalea::prelude::*;
use azalea::swarm::prelude::*; use azalea::swarm::prelude::*;
use azalea::ClientInformation; use commands::{CommandSource, register_commands};
use commands::{register_commands, CommandSource};
use parking_lot::Mutex; use parking_lot::Mutex;
#[tokio::main] #[tokio::main]

View file

@ -1,6 +1,6 @@
use azalea_client::{ use azalea_client::{
packet_handling::{death_event_on_0_health, game::DeathEvent}, packet_handling::{death_event_on_0_health, game::DeathEvent},
respawn::{perform_respawn, PerformRespawnEvent}, respawn::{PerformRespawnEvent, perform_respawn},
}; };
use bevy_app::Update; use bevy_app::Update;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;

View file

@ -1,7 +1,7 @@
use azalea_block::{fluid_state::FluidKind, Block, BlockState}; use azalea_block::{Block, BlockState, fluid_state::FluidKind};
use azalea_client::{inventory::Inventory, Client}; use azalea_client::{Client, inventory::Inventory};
use azalea_entity::{FluidOnEyes, Physics}; use azalea_entity::{FluidOnEyes, Physics};
use azalea_inventory::{components, ItemStack, Menu}; use azalea_inventory::{ItemStack, Menu, components};
#[derive(Debug)] #[derive(Debug)]
pub struct BestToolResult { pub struct BestToolResult {

View file

@ -1,13 +1,13 @@
use std::f64::consts::PI; use std::f64::consts::PI;
use azalea_client::TickBroadcast;
use azalea_client::interact::SwingArmEvent; use azalea_client::interact::SwingArmEvent;
use azalea_client::mining::Mining; use azalea_client::mining::Mining;
use azalea_client::TickBroadcast;
use azalea_core::position::{BlockPos, Vec3}; use azalea_core::position::{BlockPos, Vec3};
use azalea_core::tick::GameTick; use azalea_core::tick::GameTick;
use azalea_entity::{ use azalea_entity::{
clamp_look_direction, metadata::Player, EyeHeight, Jumping, LocalEntity, LookDirection, EyeHeight, Jumping, LocalEntity, LookDirection, Position, clamp_look_direction,
Position, metadata::Player,
}; };
use azalea_physics::PhysicsSet; use azalea_physics::PhysicsSet;
use bevy_app::Update; use bevy_app::Update;
@ -185,8 +185,7 @@ fn look_at_listener(
direction_looking_at(&position.up(eye_height.into()), &event.position); direction_looking_at(&position.up(eye_height.into()), &event.position);
trace!( trace!(
"look at {:?} (currently at {:?})", "look at {:?} (currently at {:?})",
event.position, event.position, **position
**position
); );
*look_direction = new_look_direction; *look_direction = new_look_direction;
} }

View file

@ -2,12 +2,12 @@ use std::fmt::Debug;
use std::fmt::Formatter; use std::fmt::Formatter;
use azalea_client::{ use azalea_client::{
Client,
inventory::{CloseContainerEvent, ContainerClickEvent, Inventory}, inventory::{CloseContainerEvent, ContainerClickEvent, Inventory},
packet_handling::game::PacketEvent, packet_handling::game::PacketEvent,
Client,
}; };
use azalea_core::position::BlockPos; use azalea_core::position::BlockPos;
use azalea_inventory::{operations::ClickOperation, ItemStack, Menu}; use azalea_inventory::{ItemStack, Menu, operations::ClickOperation};
use azalea_protocol::packets::game::ClientboundGamePacket; use azalea_protocol::packets::game::ClientboundGamePacket;
use bevy_app::{App, Plugin, Update}; use bevy_app::{App, Plugin, Update};
use bevy_ecs::{component::Component, prelude::EventReader, system::Commands}; use bevy_ecs::{component::Component, prelude::EventReader, system::Commands};

Some files were not shown because too many files have changed in this diff Show more