mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
update codegen and use resourcelocation names for packets
This commit is contained in:
parent
170ffb07d0
commit
f8cd7ed1de
45 changed files with 665 additions and 646 deletions
|
@ -11,7 +11,7 @@ use std::{
|
|||
io::{Cursor, Write},
|
||||
};
|
||||
|
||||
use azalea_buf::{BufReadError, AzaleaRead, AzaleaReadVar, AzaleaWriteVar, AzaleaWrite};
|
||||
use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
|
||||
pub use behavior::BlockBehavior;
|
||||
pub use generated::{blocks, properties};
|
||||
pub use range::BlockStates;
|
||||
|
|
|
@ -3,9 +3,7 @@ use std::io::{Cursor, Write};
|
|||
use std::{collections::HashSet, hash::Hash};
|
||||
|
||||
#[cfg(feature = "azalea-buf")]
|
||||
use azalea_buf::{
|
||||
BufReadError, AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWriteVar, AzaleaWrite,
|
||||
};
|
||||
use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
|
||||
#[cfg(feature = "azalea-buf")]
|
||||
use azalea_chat::FormattedText;
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ mod write;
|
|||
|
||||
pub use azalea_buf_macros::*;
|
||||
pub use definitions::*;
|
||||
pub use read::{BufReadError, AzaleaRead, AzaleaReadVar};
|
||||
pub use read::{AzaleaRead, AzaleaReadVar, BufReadError};
|
||||
pub use serializable_uuid::*;
|
||||
pub use write::{AzaleaWriteVar, AzaleaWrite};
|
||||
pub use write::{AzaleaWrite, AzaleaWriteVar};
|
||||
|
||||
// const DEFAULT_NBT_QUOTA: u32 = 2097152;
|
||||
const MAX_STRING_LENGTH: u16 = 32767;
|
||||
|
|
|
@ -196,9 +196,7 @@ impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaRead + Send> AzaleaRead for Hash
|
|||
}
|
||||
}
|
||||
|
||||
impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaReadVar + Send> AzaleaReadVar
|
||||
for HashMap<K, V>
|
||||
{
|
||||
impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaReadVar + Send> AzaleaReadVar for HashMap<K, V> {
|
||||
fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
||||
let length = i32::azalea_read_var(buf)? as usize;
|
||||
let mut contents = HashMap::with_capacity(usize::min(length, 65536));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
#[cfg(feature = "azalea-buf")]
|
||||
use azalea_buf::{BufReadError, AzaleaRead, AzaleaWrite};
|
||||
use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||
#[cfg(feature = "simdnbt")]
|
||||
|
|
|
@ -17,13 +17,13 @@ use azalea_entity::{
|
|||
};
|
||||
use azalea_physics::PhysicsPlugin;
|
||||
use azalea_protocol::{
|
||||
common::ClientInformation,
|
||||
common::client_information::ClientInformation,
|
||||
connect::{Connection, ConnectionError, Proxy},
|
||||
packets::{
|
||||
config::{ClientboundConfigPacket, ServerboundConfigPacket},
|
||||
game::ServerboundGamePacket,
|
||||
handshake::{
|
||||
s_client_intention::ServerboundClientIntention, ClientboundHandshakePacket,
|
||||
s_intention::ServerboundIntention, ClientboundHandshakePacket,
|
||||
ServerboundHandshakePacket,
|
||||
},
|
||||
login::{
|
||||
|
@ -349,7 +349,7 @@ impl Client {
|
|||
JoinError,
|
||||
> {
|
||||
// handshake
|
||||
conn.write(ServerboundClientIntention {
|
||||
conn.write(ServerboundIntention {
|
||||
protocol_version: PROTOCOL_VERSION,
|
||||
hostname: address.host.clone(),
|
||||
port: address.port,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use azalea_buf::AzaleaWrite;
|
||||
use azalea_core::resource_location::ResourceLocation;
|
||||
use azalea_protocol::{
|
||||
common::ClientInformation,
|
||||
common::client_information::ClientInformation,
|
||||
packets::config::{
|
||||
s_client_information::ServerboundClientInformation,
|
||||
s_custom_payload::ServerboundCustomPayload,
|
||||
|
|
|
@ -30,7 +30,7 @@ pub mod respawn;
|
|||
pub mod task_pool;
|
||||
|
||||
pub use account::{Account, AccountOpts};
|
||||
pub use azalea_protocol::common::ClientInformation;
|
||||
pub use azalea_protocol::common::client_information::ClientInformation;
|
||||
pub use client::{
|
||||
start_ecs_runner, Client, DefaultPlugins, JoinError, JoinedClientBundle, StartClientOpts,
|
||||
TickBroadcast,
|
||||
|
|
|
@ -216,6 +216,8 @@ pub fn process_packet_events(ecs: &mut World) {
|
|||
})
|
||||
.unwrap();
|
||||
}
|
||||
ClientboundConfigPacket::ServerLinks(_) => {}
|
||||
ClientboundConfigPacket::CustomReportDetails(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1458,7 +1458,7 @@ pub fn process_packet_events(ecs: &mut World) {
|
|||
ClientboundGamePacket::TabList(_) => {}
|
||||
ClientboundGamePacket::TagQuery(_) => {}
|
||||
ClientboundGamePacket::TakeItemEntity(_) => {}
|
||||
ClientboundGamePacket::Bundle(_) => {}
|
||||
ClientboundGamePacket::BundleDelimiter(_) => {}
|
||||
ClientboundGamePacket::DamageEvent(_) => {}
|
||||
ClientboundGamePacket::HurtAnimation(_) => {}
|
||||
|
||||
|
@ -1471,7 +1471,7 @@ pub fn process_packet_events(ecs: &mut World) {
|
|||
ClientboundGamePacket::PongResponse(_) => {}
|
||||
ClientboundGamePacket::StoreCookie(_) => {}
|
||||
ClientboundGamePacket::Transfer(_) => {}
|
||||
ClientboundGamePacket::MoveMinecart(_) => {}
|
||||
ClientboundGamePacket::MoveMinecartAlongTrack(_) => {}
|
||||
ClientboundGamePacket::SetHeldSlot(_) => {}
|
||||
ClientboundGamePacket::SetPlayerInventory(_) => {}
|
||||
ClientboundGamePacket::ProjectilePower(_) => {}
|
||||
|
|
|
@ -6,7 +6,7 @@ use azalea_protocol::{
|
|||
connect::{Connection, ConnectionError, Proxy},
|
||||
packets::{
|
||||
handshake::{
|
||||
s_client_intention::ServerboundClientIntention, ClientboundHandshakePacket,
|
||||
s_intention::ServerboundIntention, ClientboundHandshakePacket,
|
||||
ServerboundHandshakePacket,
|
||||
},
|
||||
status::{
|
||||
|
@ -74,7 +74,7 @@ pub async fn ping_server_with_connection(
|
|||
mut conn: Connection<ClientboundHandshakePacket, ServerboundHandshakePacket>,
|
||||
) -> Result<ClientboundStatusResponse, PingError> {
|
||||
// send the client intention packet and switch to the status state
|
||||
conn.write(ServerboundClientIntention {
|
||||
conn.write(ServerboundIntention {
|
||||
protocol_version: PROTOCOL_VERSION,
|
||||
hostname: address.host.clone(),
|
||||
port: address.port,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::io::{Cursor, Write};
|
||||
|
||||
use azalea_buf::{BufReadError, AzBuf, AzaleaRead, AzaleaWrite};
|
||||
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
|
||||
|
||||
/// Represents Java's BitSet, a list of bits.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, AzBuf)]
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
io::{Cursor, Write},
|
||||
};
|
||||
|
||||
use azalea_buf::{BufReadError, AzaleaRead, AzaleaWrite};
|
||||
use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
|
||||
|
||||
#[derive(Hash, Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Difficulty {
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::{
|
|||
str::FromStr,
|
||||
};
|
||||
|
||||
use azalea_buf::{BufReadError, AzBuf, AzaleaRead, AzaleaWrite};
|
||||
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
|
|
@ -648,7 +648,8 @@ mod tests {
|
|||
azalea_block::blocks::StoneSlab {
|
||||
kind: azalea_block::properties::Type::Top,
|
||||
waterlogged: false,
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
assert!(
|
||||
block_state.is_some(),
|
||||
|
@ -704,7 +705,8 @@ mod tests {
|
|||
west: azalea_block::properties::WallWest::Low,
|
||||
up: false,
|
||||
waterlogged: false,
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
assert!(
|
||||
block_state.is_some(),
|
||||
|
@ -765,7 +767,8 @@ mod tests {
|
|||
west: azalea_block::properties::WallWest::Low,
|
||||
up: false,
|
||||
waterlogged: false,
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
assert!(
|
||||
block_state.is_some(),
|
||||
|
|
|
@ -109,14 +109,9 @@ pub fn derive_c_config_packet(input: TokenStream) -> TokenStream {
|
|||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PacketListItem {
|
||||
module: Ident,
|
||||
name: Ident,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct PacketList {
|
||||
packets: Vec<PacketListItem>,
|
||||
packets: Vec<Ident>,
|
||||
}
|
||||
|
||||
impl Parse for PacketList {
|
||||
|
@ -124,15 +119,10 @@ impl Parse for PacketList {
|
|||
let mut packets = vec![];
|
||||
|
||||
// example:
|
||||
// c_change_difficulty::ClientboundChangeDifficultyPacket,
|
||||
|
||||
// c_change_difficulty
|
||||
while let Ok(module) = input.parse::<Ident>() {
|
||||
input.parse::<Token![::]>()?;
|
||||
// ClientboundChangeDifficultyPacket
|
||||
let name = input.parse::<Ident>()?;
|
||||
packets.push(PacketListItem { module, name });
|
||||
|
||||
// change_difficulty,
|
||||
// keep_alive,
|
||||
while let Ok(packet_name) = input.parse::<Ident>() {
|
||||
packets.push(packet_name);
|
||||
if input.parse::<Token![,]>().is_err() {
|
||||
break;
|
||||
}
|
||||
|
@ -145,8 +135,8 @@ impl Parse for PacketList {
|
|||
#[derive(Debug)]
|
||||
struct DeclareStatePackets {
|
||||
name: Ident,
|
||||
serverbound: PacketList,
|
||||
clientbound: PacketList,
|
||||
serverbound: PacketList,
|
||||
}
|
||||
|
||||
impl Parse for DeclareStatePackets {
|
||||
|
@ -154,26 +144,32 @@ impl Parse for DeclareStatePackets {
|
|||
let name = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
let s_token: Ident = input.parse()?;
|
||||
if s_token != "Serverbound" {
|
||||
return Err(syn::Error::new(s_token.span(), "Expected `Serverbound`"));
|
||||
}
|
||||
input.parse::<Token![=>]>()?;
|
||||
let content;
|
||||
bracketed!(content in input);
|
||||
let serverbound = content.parse()?;
|
||||
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
let c_token: Ident = input.parse()?;
|
||||
if c_token != "Clientbound" {
|
||||
return Err(syn::Error::new(c_token.span(), "Expected `Clientbound`"));
|
||||
let clientbound_token: Ident = input.parse()?;
|
||||
if clientbound_token != "Clientbound" {
|
||||
return Err(syn::Error::new(
|
||||
clientbound_token.span(),
|
||||
"Expected `Clientbound`",
|
||||
));
|
||||
}
|
||||
input.parse::<Token![=>]>()?;
|
||||
let content;
|
||||
bracketed!(content in input);
|
||||
let clientbound = content.parse()?;
|
||||
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
let serverbound_token: Ident = input.parse()?;
|
||||
if serverbound_token != "Serverbound" {
|
||||
return Err(syn::Error::new(
|
||||
serverbound_token.span(),
|
||||
"Expected `Serverbound`",
|
||||
));
|
||||
}
|
||||
input.parse::<Token![=>]>()?;
|
||||
let content;
|
||||
bracketed!(content in input);
|
||||
let serverbound = content.parse()?;
|
||||
|
||||
Ok(DeclareStatePackets {
|
||||
name,
|
||||
serverbound,
|
||||
|
@ -185,89 +181,55 @@ impl Parse for DeclareStatePackets {
|
|||
pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeclareStatePackets);
|
||||
|
||||
let s_state_name = Ident::new(&format!("Serverbound{}", input.name), input.name.span());
|
||||
let c_state_name = Ident::new(&format!("Clientbound{}", input.name), input.name.span());
|
||||
let clientbound_state_name =
|
||||
Ident::new(&format!("Clientbound{}", input.name), input.name.span());
|
||||
let serverbound_state_name =
|
||||
Ident::new(&format!("Serverbound{}", input.name), input.name.span());
|
||||
|
||||
let state_name_litstr = syn::LitStr::new(&input.name.to_string(), input.name.span());
|
||||
|
||||
let has_s_packets = !input.serverbound.packets.is_empty();
|
||||
let has_c_packets = !input.clientbound.packets.is_empty();
|
||||
let has_clientbound_packets = !input.clientbound.packets.is_empty();
|
||||
let has_serverbound_packets = !input.serverbound.packets.is_empty();
|
||||
|
||||
let mut mod_and_use_statements_contents = quote!();
|
||||
let mut s_enum_contents = quote!();
|
||||
let mut c_enum_contents = quote!();
|
||||
let mut s_id_match_contents = quote!();
|
||||
let mut c_id_match_contents = quote!();
|
||||
let mut s_write_match_contents = quote!();
|
||||
let mut c_write_match_contents = quote!();
|
||||
let mut s_read_match_contents = quote!();
|
||||
let mut c_read_match_contents = quote!();
|
||||
let mut clientbound_enum_contents = quote!();
|
||||
let mut serverbound_enum_contents = quote!();
|
||||
let mut clientbound_id_match_contents = quote!();
|
||||
let mut serverbound_id_match_contents = quote!();
|
||||
let mut clientbound_write_match_contents = quote!();
|
||||
let mut serverbound_write_match_contents = quote!();
|
||||
let mut clientbound_read_match_contents = quote!();
|
||||
let mut serverbound_read_match_contents = quote!();
|
||||
|
||||
for (id, PacketListItem { module, name }) in input.serverbound.packets.iter().enumerate() {
|
||||
for (id, packet_name) in input.clientbound.packets.iter().enumerate() {
|
||||
let id = id as u32;
|
||||
let name_litstr = syn::LitStr::new(&name.to_string(), name.span());
|
||||
let variant_name = variant_name_from(name);
|
||||
|
||||
let struct_name = packet_name_to_struct_name(packet_name, "clientbound");
|
||||
let module_name = packet_name_to_module_name(packet_name, "clientbound");
|
||||
let variant_name = packet_name_to_variant_name(packet_name);
|
||||
let packet_name_litstr = syn::LitStr::new(&packet_name.to_string(), packet_name.span());
|
||||
|
||||
mod_and_use_statements_contents.extend(quote! {
|
||||
pub mod #module;
|
||||
pub use #module::#name;
|
||||
pub mod #module_name;
|
||||
pub use #module_name::#struct_name;
|
||||
});
|
||||
|
||||
s_enum_contents.extend(quote! {
|
||||
#variant_name(#module::#name),
|
||||
clientbound_enum_contents.extend(quote! {
|
||||
#variant_name(#module_name::#struct_name),
|
||||
});
|
||||
s_id_match_contents.extend(quote! {
|
||||
#s_state_name::#variant_name(_packet) => #id,
|
||||
clientbound_id_match_contents.extend(quote! {
|
||||
#clientbound_state_name::#variant_name(_packet) => #id,
|
||||
});
|
||||
s_write_match_contents.extend(quote! {
|
||||
#s_state_name::#variant_name(packet) => packet.write(buf),
|
||||
clientbound_write_match_contents.extend(quote! {
|
||||
#clientbound_state_name::#variant_name(packet) => packet.write(buf),
|
||||
});
|
||||
s_read_match_contents.extend(quote! {
|
||||
clientbound_read_match_contents.extend(quote! {
|
||||
#id => {
|
||||
let data = #module::#name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse {
|
||||
let data = #module_name::#struct_name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse {
|
||||
source: e,
|
||||
packet_id: #id,
|
||||
backtrace: Box::new(std::backtrace::Backtrace::capture()),
|
||||
packet_name: #name_litstr.to_string(),
|
||||
})?;
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let mut leftover = Vec::new();
|
||||
let _ = std::io::Read::read_to_end(buf, &mut leftover);
|
||||
if !leftover.is_empty() {
|
||||
return Err(Box::new(crate::read::ReadPacketError::LeftoverData { packet_name: #name_litstr.to_string(), data: leftover }));
|
||||
}
|
||||
}
|
||||
data
|
||||
},
|
||||
});
|
||||
}
|
||||
for (id, PacketListItem { module, name }) in input.clientbound.packets.iter().enumerate() {
|
||||
let id = id as u32;
|
||||
let name_litstr = syn::LitStr::new(&name.to_string(), name.span());
|
||||
let variant_name = variant_name_from(name);
|
||||
|
||||
mod_and_use_statements_contents.extend(quote! {
|
||||
pub mod #module;
|
||||
pub use #module::#name;
|
||||
});
|
||||
|
||||
c_enum_contents.extend(quote! {
|
||||
#variant_name(#module::#name),
|
||||
});
|
||||
c_id_match_contents.extend(quote! {
|
||||
#c_state_name::#variant_name(_packet) => #id,
|
||||
});
|
||||
c_write_match_contents.extend(quote! {
|
||||
#c_state_name::#variant_name(packet) => packet.write(buf),
|
||||
});
|
||||
c_read_match_contents.extend(quote! {
|
||||
#id => {
|
||||
let data = #module::#name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse {
|
||||
source: e,
|
||||
packet_id: #id,
|
||||
backtrace: Box::new(std::backtrace::Backtrace::capture()),
|
||||
packet_name: #name_litstr.to_string(),
|
||||
packet_name: #packet_name_litstr.to_string(),
|
||||
})?;
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
|
@ -277,7 +239,7 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
|||
return Err(
|
||||
Box::new(
|
||||
crate::read::ReadPacketError::LeftoverData {
|
||||
packet_name: #name_litstr.to_string(),
|
||||
packet_name: #packet_name_litstr.to_string(),
|
||||
data: leftover
|
||||
}
|
||||
)
|
||||
|
@ -288,20 +250,62 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
|||
},
|
||||
});
|
||||
}
|
||||
for (id, packet_name) in input.serverbound.packets.iter().enumerate() {
|
||||
let id = id as u32;
|
||||
|
||||
if !has_s_packets {
|
||||
s_id_match_contents.extend(quote! {
|
||||
let struct_name = packet_name_to_struct_name(packet_name, "serverbound");
|
||||
let module_name = packet_name_to_module_name(packet_name, "serverbound");
|
||||
let variant_name = packet_name_to_variant_name(packet_name);
|
||||
let packet_name_litstr = syn::LitStr::new(&packet_name.to_string(), packet_name.span());
|
||||
|
||||
mod_and_use_statements_contents.extend(quote! {
|
||||
pub mod #module_name;
|
||||
pub use #module_name::#struct_name;
|
||||
});
|
||||
|
||||
serverbound_enum_contents.extend(quote! {
|
||||
#variant_name(#module_name::#struct_name),
|
||||
});
|
||||
serverbound_id_match_contents.extend(quote! {
|
||||
#serverbound_state_name::#variant_name(_packet) => #id,
|
||||
});
|
||||
serverbound_write_match_contents.extend(quote! {
|
||||
#serverbound_state_name::#variant_name(packet) => packet.write(buf),
|
||||
});
|
||||
serverbound_read_match_contents.extend(quote! {
|
||||
#id => {
|
||||
let data = #module_name::#struct_name::read(buf).map_err(|e| crate::read::ReadPacketError::Parse {
|
||||
source: e,
|
||||
packet_id: #id,
|
||||
backtrace: Box::new(std::backtrace::Backtrace::capture()),
|
||||
packet_name: #packet_name_litstr.to_string(),
|
||||
})?;
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let mut leftover = Vec::new();
|
||||
let _ = std::io::Read::read_to_end(buf, &mut leftover);
|
||||
if !leftover.is_empty() {
|
||||
return Err(Box::new(crate::read::ReadPacketError::LeftoverData { packet_name: #packet_name_litstr.to_string(), data: leftover }));
|
||||
}
|
||||
}
|
||||
data
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if !has_serverbound_packets {
|
||||
serverbound_id_match_contents.extend(quote! {
|
||||
_ => unreachable!("This enum is empty and can't exist.")
|
||||
});
|
||||
s_write_match_contents.extend(quote! {
|
||||
serverbound_write_match_contents.extend(quote! {
|
||||
_ => unreachable!("This enum is empty and can't exist.")
|
||||
});
|
||||
}
|
||||
if !has_c_packets {
|
||||
c_id_match_contents.extend(quote! {
|
||||
if !has_clientbound_packets {
|
||||
clientbound_id_match_contents.extend(quote! {
|
||||
_ => unreachable!("This enum is empty and can't exist.")
|
||||
});
|
||||
c_write_match_contents.extend(quote! {
|
||||
clientbound_write_match_contents.extend(quote! {
|
||||
_ => unreachable!("This enum is empty and can't exist.")
|
||||
});
|
||||
}
|
||||
|
@ -310,33 +314,33 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
|||
#mod_and_use_statements_contents
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum #s_state_name
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#s_enum_contents
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum #c_state_name
|
||||
pub enum #clientbound_state_name
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#c_enum_contents
|
||||
#clientbound_enum_contents
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum #serverbound_state_name
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#serverbound_enum_contents
|
||||
}
|
||||
};
|
||||
|
||||
contents.extend(quote! {
|
||||
#[allow(unreachable_code)]
|
||||
impl crate::packets::ProtocolPacket for #s_state_name {
|
||||
impl crate::packets::ProtocolPacket for #serverbound_state_name {
|
||||
fn id(&self) -> u32 {
|
||||
match self {
|
||||
#s_id_match_contents
|
||||
#serverbound_id_match_contents
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
|
||||
match self {
|
||||
#s_write_match_contents
|
||||
#serverbound_write_match_contents
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,20 +348,20 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
|||
fn read(
|
||||
id: u32,
|
||||
buf: &mut std::io::Cursor<&[u8]>,
|
||||
) -> Result<#s_state_name, Box<crate::read::ReadPacketError>>
|
||||
) -> Result<#serverbound_state_name, Box<crate::read::ReadPacketError>>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Ok(match id {
|
||||
#s_read_match_contents
|
||||
#serverbound_read_match_contents
|
||||
_ => return Err(Box::new(crate::read::ReadPacketError::UnknownPacketId { state_name: #state_name_litstr.to_string(), id })),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::packets::Packet<#s_state_name> for #s_state_name {
|
||||
impl crate::packets::Packet<#serverbound_state_name> for #serverbound_state_name {
|
||||
/// No-op, exists so you can pass a packet enum when a Packet<> is expected.
|
||||
fn into_variant(self) -> #s_state_name {
|
||||
fn into_variant(self) -> #serverbound_state_name {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -365,16 +369,16 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
|||
|
||||
contents.extend(quote! {
|
||||
#[allow(unreachable_code)]
|
||||
impl crate::packets::ProtocolPacket for #c_state_name {
|
||||
impl crate::packets::ProtocolPacket for #clientbound_state_name {
|
||||
fn id(&self) -> u32 {
|
||||
match self {
|
||||
#c_id_match_contents
|
||||
#clientbound_id_match_contents
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
|
||||
match self {
|
||||
#c_write_match_contents
|
||||
#clientbound_write_match_contents
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -382,12 +386,12 @@ pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
|||
fn read(
|
||||
id: u32,
|
||||
buf: &mut std::io::Cursor<&[u8]>,
|
||||
) -> Result<#c_state_name, Box<crate::read::ReadPacketError>>
|
||||
) -> Result<#clientbound_state_name, Box<crate::read::ReadPacketError>>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Ok(match id {
|
||||
#c_read_match_contents
|
||||
#clientbound_read_match_contents
|
||||
_ => return Err(Box::new(crate::read::ReadPacketError::UnknownPacketId { state_name: #state_name_litstr.to_string(), id })),
|
||||
})
|
||||
}
|
||||
|
@ -407,3 +411,48 @@ fn variant_name_from(name: &syn::Ident) -> syn::Ident {
|
|||
}
|
||||
syn::Ident::new(&variant_name, name.span())
|
||||
}
|
||||
|
||||
fn packet_name_to_struct_name(name: &syn::Ident, direction: &str) -> syn::Ident {
|
||||
let struct_name_snake = format!("{direction}_{name}");
|
||||
let struct_name = to_camel_case(&struct_name_snake);
|
||||
syn::Ident::new(&struct_name, name.span())
|
||||
}
|
||||
fn packet_name_to_module_name(name: &syn::Ident, direction: &str) -> syn::Ident {
|
||||
let module_name_snake = format!("{}_{name}", direction.chars().next().unwrap());
|
||||
let module_name = to_snake_case(&module_name_snake);
|
||||
syn::Ident::new(&module_name, name.span())
|
||||
}
|
||||
fn packet_name_to_variant_name(name: &syn::Ident) -> syn::Ident {
|
||||
let variant_name = to_camel_case(&name.to_string());
|
||||
syn::Ident::new(&variant_name, name.span())
|
||||
}
|
||||
|
||||
fn to_camel_case(snake_case: &str) -> String {
|
||||
let mut camel_case = String::new();
|
||||
let mut capitalize_next = true;
|
||||
for c in snake_case.chars() {
|
||||
if c == '_' {
|
||||
capitalize_next = true;
|
||||
} else {
|
||||
if capitalize_next {
|
||||
camel_case.push(c.to_ascii_uppercase());
|
||||
} else {
|
||||
camel_case.push(c);
|
||||
}
|
||||
capitalize_next = false;
|
||||
}
|
||||
}
|
||||
camel_case
|
||||
}
|
||||
fn to_snake_case(camel_case: &str) -> String {
|
||||
let mut snake_case = String::new();
|
||||
for c in camel_case.chars() {
|
||||
if c.is_ascii_uppercase() {
|
||||
snake_case.push('_');
|
||||
snake_case.push(c.to_ascii_lowercase());
|
||||
} else {
|
||||
snake_case.push(c);
|
||||
}
|
||||
}
|
||||
snake_case
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use azalea_protocol::{
|
|||
connect::Connection,
|
||||
packets::{
|
||||
handshake::{
|
||||
s_client_intention::ServerboundClientIntention, ClientboundHandshakePacket,
|
||||
s_intention::ServerboundIntention, ClientboundHandshakePacket,
|
||||
ServerboundHandshakePacket,
|
||||
},
|
||||
login::{s_hello::ServerboundHello, ServerboundLoginPacket},
|
||||
|
@ -74,7 +74,7 @@ async fn handle_connection(stream: TcpStream) -> anyhow::Result<()> {
|
|||
// the server or is going to join the game.
|
||||
let intent = match conn.read().await {
|
||||
Ok(packet) => match packet {
|
||||
ServerboundHandshakePacket::ClientIntention(packet) => {
|
||||
ServerboundHandshakePacket::Intention(packet) => {
|
||||
info!(
|
||||
"New connection: {0}, Version {1}, {2:?}",
|
||||
ip.ip(),
|
||||
|
@ -100,21 +100,17 @@ async fn handle_connection(stream: TcpStream) -> anyhow::Result<()> {
|
|||
match conn.read().await {
|
||||
Ok(p) => match p {
|
||||
ServerboundStatusPacket::StatusRequest(_) => {
|
||||
conn.write(
|
||||
ClientboundStatusResponse {
|
||||
description: PROXY_DESC.into(),
|
||||
favicon: PROXY_FAVICON.clone(),
|
||||
players: PROXY_PLAYERS.clone(),
|
||||
version: PROXY_VERSION.clone(),
|
||||
enforces_secure_chat: PROXY_SECURE_CHAT,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
conn.write(ClientboundStatusResponse {
|
||||
description: PROXY_DESC.into(),
|
||||
favicon: PROXY_FAVICON.clone(),
|
||||
players: PROXY_PLAYERS.clone(),
|
||||
version: PROXY_VERSION.clone(),
|
||||
enforces_secure_chat: PROXY_SECURE_CHAT,
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
ServerboundStatusPacket::PingRequest(p) => {
|
||||
conn.write(ClientboundPongResponse { time: p.time }.into())
|
||||
.await?;
|
||||
conn.write(ClientboundPongResponse { time: p.time }).await?;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -178,7 +174,7 @@ async fn handle_connection(stream: TcpStream) -> anyhow::Result<()> {
|
|||
|
||||
async fn transfer(
|
||||
mut inbound: TcpStream,
|
||||
intent: ServerboundClientIntention,
|
||||
intent: ServerboundIntention,
|
||||
hello: ServerboundHello,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let outbound = TcpStream::connect(PROXY_ADDR).await?;
|
||||
|
@ -189,10 +185,10 @@ async fn transfer(
|
|||
// received earlier to the proxy target
|
||||
let mut outbound_conn: Connection<ClientboundHandshakePacket, ServerboundHandshakePacket> =
|
||||
Connection::wrap(outbound);
|
||||
outbound_conn.write(intent.into()).await?;
|
||||
outbound_conn.write(intent).await?;
|
||||
|
||||
let mut outbound_conn = outbound_conn.login();
|
||||
outbound_conn.write(hello.into()).await?;
|
||||
outbound_conn.write(hello).await?;
|
||||
|
||||
let mut outbound = outbound_conn.unwrap()?;
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//! Some serializable data types that are used by several packets.
|
||||
|
||||
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite};
|
||||
use azalea_core::bitset::FixedBitSet;
|
||||
use bevy_ecs::component::Component;
|
4
azalea-protocol/src/common/mod.rs
Normal file
4
azalea-protocol/src/common/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
//! Some serializable data types that are used by several packets.
|
||||
|
||||
pub mod client_information;
|
||||
pub mod server_links;
|
28
azalea-protocol/src/common/server_links.rs
Normal file
28
azalea-protocol/src/common/server_links.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_chat::FormattedText;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf)]
|
||||
pub struct ServerLinkEntry {
|
||||
pub kind: ServerLinkKind,
|
||||
pub link: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, AzBuf)]
|
||||
pub enum ServerLinkKind {
|
||||
Known(KnownLinkKind),
|
||||
Component(FormattedText),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, AzBuf)]
|
||||
pub enum KnownLinkKind {
|
||||
BugReport,
|
||||
CommunityGuidelines,
|
||||
Support,
|
||||
Status,
|
||||
Feedback,
|
||||
Community,
|
||||
Website,
|
||||
Forums,
|
||||
News,
|
||||
Announcements,
|
||||
}
|
|
@ -111,6 +111,7 @@ mod tests {
|
|||
packets::{
|
||||
game::s_chat::{LastSeenMessagesUpdate, ServerboundChat},
|
||||
login::{s_hello::ServerboundHello, ServerboundLoginPacket},
|
||||
Packet,
|
||||
},
|
||||
read::{compression_decoder, read_packet},
|
||||
write::{compression_encoder, serialize_packet, write_packet},
|
||||
|
@ -121,10 +122,9 @@ mod tests {
|
|||
let packet = ServerboundHello {
|
||||
name: "test".to_string(),
|
||||
profile_id: Uuid::nil(),
|
||||
}
|
||||
.into();
|
||||
};
|
||||
let mut stream = Vec::new();
|
||||
write_packet(&packet, &mut stream, None, &mut None)
|
||||
write_packet(&packet.into_variant(), &mut stream, None, &mut None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -146,7 +146,7 @@ mod tests {
|
|||
name: "test".to_string(),
|
||||
profile_id: Uuid::nil(),
|
||||
}
|
||||
.into();
|
||||
.into_variant();
|
||||
let mut stream = Vec::new();
|
||||
write_packet(&packet, &mut stream, None, &mut None)
|
||||
.await
|
||||
|
@ -170,13 +170,16 @@ mod tests {
|
|||
async fn test_read_long_compressed_chat() {
|
||||
let compression_threshold = 256;
|
||||
|
||||
let buf = serialize_packet(&ServerboundChat {
|
||||
message: "a".repeat(256),
|
||||
timestamp: 0,
|
||||
salt: 0,
|
||||
signature: None,
|
||||
last_seen_messages: LastSeenMessagesUpdate::default(),
|
||||
})
|
||||
let buf = serialize_packet(
|
||||
&ServerboundChat {
|
||||
message: "a".repeat(256),
|
||||
timestamp: 0,
|
||||
salt: 0,
|
||||
signature: None,
|
||||
last_seen_messages: LastSeenMessagesUpdate::default(),
|
||||
}
|
||||
.into_variant(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let buf = compression_encoder(&buf, compression_threshold).unwrap();
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use azalea_buf::AzBuf;
|
||||
use azalea_protocol_macros::ClientboundConfigPacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)]
|
||||
pub struct ClientboundCustomReportDetails {
|
||||
pub details: HashMap<String, String>,
|
||||
}
|
9
azalea-protocol/src/packets/config/c_server_links.rs
Normal file
9
azalea-protocol/src/packets/config/c_server_links.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_protocol_macros::ClientboundConfigPacket;
|
||||
|
||||
use crate::common::server_links::ServerLinkEntry;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)]
|
||||
pub struct ClientboundServerLinks {
|
||||
pub links: Vec<ServerLinkEntry>,
|
||||
}
|
|
@ -1,32 +1,36 @@
|
|||
// NOTE: This file is generated automatically by codegen/packet.py.
|
||||
// Don't edit it directly!
|
||||
|
||||
use azalea_protocol_macros::declare_state_packets;
|
||||
|
||||
declare_state_packets!(
|
||||
ConfigPacket,
|
||||
Serverbound => [
|
||||
s_client_information::ServerboundClientInformation,
|
||||
s_cookie_response::ServerboundCookieResponse,
|
||||
s_custom_payload::ServerboundCustomPayload,
|
||||
s_finish_configuration::ServerboundFinishConfiguration,
|
||||
s_keep_alive::ServerboundKeepAlive,
|
||||
s_pong::ServerboundPong,
|
||||
s_resource_pack::ServerboundResourcePack,
|
||||
s_select_known_packs::ServerboundSelectKnownPacks,
|
||||
],
|
||||
declare_state_packets!(ConfigPacket,
|
||||
Clientbound => [
|
||||
c_cookie_request::ClientboundCookieRequest,
|
||||
c_custom_payload::ClientboundCustomPayload,
|
||||
c_disconnect::ClientboundDisconnect,
|
||||
c_finish_configuration::ClientboundFinishConfiguration,
|
||||
c_keep_alive::ClientboundKeepAlive,
|
||||
c_ping::ClientboundPing,
|
||||
c_reset_chat::ClientboundResetChat,
|
||||
c_registry_data::ClientboundRegistryData,
|
||||
c_resource_pack_pop::ClientboundResourcePackPop,
|
||||
c_resource_pack_push::ClientboundResourcePackPush,
|
||||
c_store_cookie::ClientboundStoreCookie,
|
||||
c_transfer::ClientboundTransfer,
|
||||
c_update_enabled_features::ClientboundUpdateEnabledFeatures,
|
||||
c_update_tags::ClientboundUpdateTags,
|
||||
c_select_known_packs::ClientboundSelectKnownPacks,
|
||||
keep_alive,
|
||||
registry_data,
|
||||
reset_chat,
|
||||
resource_pack_pop,
|
||||
resource_pack_push,
|
||||
select_known_packs,
|
||||
server_links,
|
||||
disconnect,
|
||||
finish_configuration,
|
||||
ping,
|
||||
cookie_request,
|
||||
update_enabled_features,
|
||||
update_tags,
|
||||
transfer,
|
||||
store_cookie,
|
||||
custom_payload,
|
||||
custom_report_details,
|
||||
],
|
||||
Serverbound => [
|
||||
keep_alive,
|
||||
resource_pack,
|
||||
select_known_packs,
|
||||
finish_configuration,
|
||||
client_information,
|
||||
cookie_response,
|
||||
pong,
|
||||
custom_payload,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_protocol_macros::ServerboundConfigPacket;
|
||||
|
||||
use crate::common::ClientInformation;
|
||||
use crate::common::client_information::ClientInformation;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundConfigPacket, PartialEq, Eq)]
|
||||
pub struct ServerboundClientInformation {
|
||||
|
|
|
@ -2,4 +2,4 @@ use azalea_buf::AzBuf;
|
|||
use azalea_protocol_macros::ClientboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundBundle {}
|
||||
pub struct ClientboundBundleDelimiter;
|
|
@ -3,7 +3,7 @@ use azalea_core::position::Vec3;
|
|||
use azalea_protocol_macros::ClientboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundMoveMinecart {
|
||||
pub struct ClientboundMoveMinecartAlongTrack {
|
||||
#[var]
|
||||
pub entity_id: u32,
|
||||
pub lerp_steps: Vec<MinecartStep>,
|
|
@ -1,34 +1,9 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_chat::FormattedText;
|
||||
use azalea_protocol_macros::ClientboundGamePacket;
|
||||
|
||||
use crate::common::server_links::ServerLinkEntry;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundServerLinks {
|
||||
pub links: Vec<ServerLinkEntry>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, AzBuf)]
|
||||
pub struct ServerLinkEntry {
|
||||
pub kind: ServerLinkKind,
|
||||
pub link: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, AzBuf)]
|
||||
pub enum ServerLinkKind {
|
||||
Known(KnownLinkKind),
|
||||
Component(FormattedText),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, AzBuf)]
|
||||
pub enum KnownLinkKind {
|
||||
BugReport,
|
||||
CommunityGuidelines,
|
||||
Support,
|
||||
Status,
|
||||
Feedback,
|
||||
Community,
|
||||
Website,
|
||||
Forums,
|
||||
News,
|
||||
Announcements,
|
||||
}
|
||||
|
|
|
@ -1,202 +1,204 @@
|
|||
// NOTE: This file is generated automatically by codegen/packet.py.
|
||||
// Don't edit it directly!
|
||||
|
||||
use azalea_protocol_macros::declare_state_packets;
|
||||
|
||||
// see GameProtocols.java in the decompiled vanilla source
|
||||
|
||||
declare_state_packets!(
|
||||
GamePacket,
|
||||
Serverbound => [
|
||||
s_accept_teleportation::ServerboundAcceptTeleportation,
|
||||
s_block_entity_tag_query::ServerboundBlockEntityTagQuery,
|
||||
s_select_bundle_item::ServerboundSelectBundleItem,
|
||||
s_change_difficulty::ServerboundChangeDifficulty,
|
||||
s_chat_ack::ServerboundChatAck,
|
||||
s_chat_command::ServerboundChatCommand,
|
||||
s_chat_command_signed::ServerboundChatCommandSigned,
|
||||
s_chat::ServerboundChat,
|
||||
s_chat_session_update::ServerboundChatSessionUpdate,
|
||||
s_chunk_batch_received::ServerboundChunkBatchReceived,
|
||||
s_client_command::ServerboundClientCommand,
|
||||
s_client_tick_end::ServerboundTickEnd,
|
||||
s_client_information::ServerboundClientInformation,
|
||||
s_command_suggestion::ServerboundCommandSuggestion,
|
||||
s_configuration_acknowledged::ServerboundConfigurationAcknowledged,
|
||||
s_container_button_click::ServerboundContainerButtonClick,
|
||||
s_container_click::ServerboundContainerClick,
|
||||
s_container_close::ServerboundContainerClose,
|
||||
s_container_slot_state_changed::ServerboundContainerSlotStateChanged,
|
||||
s_cookie_response::ServerboundCookieResponse,
|
||||
s_custom_payload::ServerboundCustomPayload,
|
||||
s_debug_sample_subscription::ServerboundDebugSampleSubscription,
|
||||
s_edit_book::ServerboundEditBook,
|
||||
s_entity_tag_query::ServerboundEntityTagQuery,
|
||||
s_interact::ServerboundInteract,
|
||||
s_jigsaw_generate::ServerboundJigsawGenerate,
|
||||
s_keep_alive::ServerboundKeepAlive,
|
||||
s_lock_difficulty::ServerboundLockDifficulty,
|
||||
s_move_player_pos::ServerboundMovePlayerPos,
|
||||
s_move_player_pos_rot::ServerboundMovePlayerPosRot,
|
||||
s_move_player_rot::ServerboundMovePlayerRot,
|
||||
s_move_player_status_only::ServerboundMovePlayerStatusOnly,
|
||||
s_move_vehicle::ServerboundMoveVehicle,
|
||||
s_paddle_boat::ServerboundPaddleBoat,
|
||||
s_pick_item::ServerboundPickItem,
|
||||
s_ping_request::ServerboundPingRequest,
|
||||
s_place_recipe::ServerboundPlaceRecipe,
|
||||
s_player_abilities::ServerboundPlayerAbilities,
|
||||
s_player_action::ServerboundPlayerAction,
|
||||
s_player_command::ServerboundPlayerCommand,
|
||||
s_player_input::ServerboundPlayerInput,
|
||||
s_pong::ServerboundPong,
|
||||
s_recipe_book_change_settings::ServerboundRecipeBookChangeSettings,
|
||||
s_recipe_book_seen_recipe::ServerboundRecipeBookSeenRecipe,
|
||||
s_rename_item::ServerboundRenameItem,
|
||||
s_resource_pack::ServerboundResourcePack,
|
||||
s_seen_advancements::ServerboundSeenAdvancements,
|
||||
s_select_trade::ServerboundSelectTrade,
|
||||
s_set_beacon::ServerboundSetBeacon,
|
||||
s_set_carried_item::ServerboundSetCarriedItem,
|
||||
s_set_command_block::ServerboundSetCommandBlock,
|
||||
s_set_command_minecart::ServerboundSetCommandMinecart,
|
||||
s_set_creative_mode_slot::ServerboundSetCreativeModeSlot,
|
||||
s_set_jigsaw_block::ServerboundSetJigsawBlock,
|
||||
s_set_structure_block::ServerboundSetStructureBlock,
|
||||
s_sign_update::ServerboundSignUpdate,
|
||||
s_swing::ServerboundSwing,
|
||||
s_teleport_to_entity::ServerboundTeleportToEntity,
|
||||
s_use_item_on::ServerboundUseItemOn,
|
||||
s_use_item::ServerboundUseItem,
|
||||
],
|
||||
declare_state_packets!(GamePacket,
|
||||
Clientbound => [
|
||||
c_bundle::ClientboundBundle,
|
||||
c_add_entity::ClientboundAddEntity,
|
||||
c_add_experience_orb::ClientboundAddExperienceOrb,
|
||||
c_animate::ClientboundAnimate,
|
||||
c_award_stats::ClientboundAwardStats,
|
||||
c_block_changed_ack::ClientboundBlockChangedAck,
|
||||
c_block_destruction::ClientboundBlockDestruction,
|
||||
c_block_entity_data::ClientboundBlockEntityData,
|
||||
c_block_event::ClientboundBlockEvent,
|
||||
c_block_update::ClientboundBlockUpdate,
|
||||
c_boss_event::ClientboundBossEvent,
|
||||
c_change_difficulty::ClientboundChangeDifficulty,
|
||||
c_chunk_batch_finished::ClientboundChunkBatchFinished,
|
||||
c_chunk_batch_start::ClientboundChunkBatchStart,
|
||||
c_chunks_biomes::ClientboundChunksBiomes,
|
||||
c_clear_titles::ClientboundClearTitles,
|
||||
c_command_suggestions::ClientboundCommandSuggestions,
|
||||
c_commands::ClientboundCommands,
|
||||
c_container_close::ClientboundContainerClose,
|
||||
c_container_set_content::ClientboundContainerSetContent,
|
||||
c_container_set_data::ClientboundContainerSetData,
|
||||
c_container_set_slot::ClientboundContainerSetSlot,
|
||||
c_cookie_request::ClientboundCookieRequest,
|
||||
c_cooldown::ClientboundCooldown,
|
||||
c_custom_chat_completions::ClientboundCustomChatCompletions,
|
||||
c_custom_payload::ClientboundCustomPayload,
|
||||
c_damage_event::ClientboundDamageEvent,
|
||||
c_debug_sample::ClientboundDebugSample,
|
||||
c_delete_chat::ClientboundDeleteChat,
|
||||
c_disconnect::ClientboundDisconnect,
|
||||
c_disguised_chat::ClientboundDisguisedChat,
|
||||
c_entity_event::ClientboundEntityEvent,
|
||||
c_entity_position_sync::ClientboundEntityPositionSync,
|
||||
c_explode::ClientboundExplode,
|
||||
c_forget_level_chunk::ClientboundForgetLevelChunk,
|
||||
c_game_event::ClientboundGameEvent,
|
||||
c_horse_screen_open::ClientboundHorseScreenOpen,
|
||||
c_hurt_animation::ClientboundHurtAnimation,
|
||||
c_initialize_border::ClientboundInitializeBorder,
|
||||
c_keep_alive::ClientboundKeepAlive,
|
||||
c_level_chunk_with_light::ClientboundLevelChunkWithLight,
|
||||
c_level_event::ClientboundLevelEvent,
|
||||
c_level_particles::ClientboundLevelParticles,
|
||||
c_light_update::ClientboundLightUpdate,
|
||||
c_login::ClientboundLogin,
|
||||
c_map_item_data::ClientboundMapItemData,
|
||||
c_merchant_offers::ClientboundMerchantOffers,
|
||||
c_move_entity_pos::ClientboundMoveEntityPos,
|
||||
c_move_entity_pos_rot::ClientboundMoveEntityPosRot,
|
||||
c_move_minecart::ClientboundMoveMinecart,
|
||||
c_move_entity_rot::ClientboundMoveEntityRot,
|
||||
c_move_vehicle::ClientboundMoveVehicle,
|
||||
c_open_book::ClientboundOpenBook,
|
||||
c_open_screen::ClientboundOpenScreen,
|
||||
c_open_sign_editor::ClientboundOpenSignEditor,
|
||||
c_ping::ClientboundPing,
|
||||
c_pong_response::ClientboundPongResponse,
|
||||
c_place_ghost_recipe::ClientboundPlaceGhostRecipe,
|
||||
c_player_abilities::ClientboundPlayerAbilities,
|
||||
c_player_chat::ClientboundPlayerChat,
|
||||
c_player_combat_end::ClientboundPlayerCombatEnd,
|
||||
c_player_combat_enter::ClientboundPlayerCombatEnter,
|
||||
c_player_combat_kill::ClientboundPlayerCombatKill,
|
||||
c_player_info_remove::ClientboundPlayerInfoRemove,
|
||||
c_player_info_update::ClientboundPlayerInfoUpdate,
|
||||
c_player_look_at::ClientboundPlayerLookAt,
|
||||
c_player_position::ClientboundPlayerPosition,
|
||||
c_player_rotation::ClientboundPlayerRotation,
|
||||
c_recipe_book_add::ClientboundRecipeBookAdd,
|
||||
c_recipe_book_remove::ClientboundRecipeBookRemove,
|
||||
c_recipe_book_settings::ClientboundRecipeBookSettings,
|
||||
c_remove_entities::ClientboundRemoveEntities,
|
||||
c_remove_mob_effect::ClientboundRemoveMobEffect,
|
||||
c_reset_score::ClientboundResetScore,
|
||||
c_resource_pack_pop::ClientboundResourcePackPop,
|
||||
c_resource_pack_push::ClientboundResourcePackPush,
|
||||
c_respawn::ClientboundRespawn,
|
||||
c_rotate_head::ClientboundRotateHead,
|
||||
c_section_blocks_update::ClientboundSectionBlocksUpdate,
|
||||
c_select_advancements_tab::ClientboundSelectAdvancementsTab,
|
||||
c_server_data::ClientboundServerData,
|
||||
c_set_action_bar_text::ClientboundSetActionBarText,
|
||||
c_set_border_center::ClientboundSetBorderCenter,
|
||||
c_set_border_lerp_size::ClientboundSetBorderLerpSize,
|
||||
c_set_border_size::ClientboundSetBorderSize,
|
||||
c_set_border_warning_delay::ClientboundSetBorderWarningDelay,
|
||||
c_set_border_warning_distance::ClientboundSetBorderWarningDistance,
|
||||
c_set_camera::ClientboundSetCamera,
|
||||
c_set_chunk_cache_center::ClientboundSetChunkCacheCenter,
|
||||
c_set_chunk_cache_radius::ClientboundSetChunkCacheRadius,
|
||||
c_set_cursor_item::ClientboundSetCursorItem,
|
||||
c_set_default_spawn_position::ClientboundSetDefaultSpawnPosition,
|
||||
c_set_display_objective::ClientboundSetDisplayObjective,
|
||||
c_set_entity_data::ClientboundSetEntityData,
|
||||
c_set_entity_link::ClientboundSetEntityLink,
|
||||
c_set_entity_motion::ClientboundSetEntityMotion,
|
||||
c_set_equipment::ClientboundSetEquipment,
|
||||
c_set_experience::ClientboundSetExperience,
|
||||
c_set_health::ClientboundSetHealth,
|
||||
c_set_held_slot::ClientboundSetHeldSlot,
|
||||
c_set_objective::ClientboundSetObjective,
|
||||
c_set_passengers::ClientboundSetPassengers,
|
||||
c_set_player_inventory::ClientboundSetPlayerInventory,
|
||||
c_set_player_team::ClientboundSetPlayerTeam,
|
||||
c_set_score::ClientboundSetScore,
|
||||
c_set_simulation_distance::ClientboundSetSimulationDistance,
|
||||
c_set_subtitle_text::ClientboundSetSubtitleText,
|
||||
c_set_time::ClientboundSetTime,
|
||||
c_set_title_text::ClientboundSetTitleText,
|
||||
c_set_titles_animation::ClientboundSetTitlesAnimation,
|
||||
c_sound_entity::ClientboundSoundEntity,
|
||||
c_sound::ClientboundSound,
|
||||
c_start_configuration::ClientboundStartConfiguration,
|
||||
c_stop_sound::ClientboundStopSound,
|
||||
c_store_cookie::ClientboundStoreCookie,
|
||||
c_system_chat::ClientboundSystemChat,
|
||||
c_tab_list::ClientboundTabList,
|
||||
c_tag_query::ClientboundTagQuery,
|
||||
c_take_item_entity::ClientboundTakeItemEntity,
|
||||
c_teleport_entity::ClientboundTeleportEntity,
|
||||
c_ticking_state::ClientboundTickingState,
|
||||
c_ticking_step::ClientboundTickingStep,
|
||||
c_transfer::ClientboundTransfer,
|
||||
c_update_advancements::ClientboundUpdateAdvancements,
|
||||
c_update_attributes::ClientboundUpdateAttributes,
|
||||
c_update_mob_effect::ClientboundUpdateMobEffect,
|
||||
c_update_recipes::ClientboundUpdateRecipes,
|
||||
c_update_tags::ClientboundUpdateTags,
|
||||
c_projectile_power::ClientboundProjectilePower,
|
||||
c_custom_report_details::ClientboundCustomReportDetails,
|
||||
c_server_links::ClientboundServerLinks
|
||||
damage_event,
|
||||
game_event,
|
||||
map_item_data,
|
||||
tab_list,
|
||||
tag_query,
|
||||
take_item_entity,
|
||||
add_entity,
|
||||
add_experience_orb,
|
||||
debug_sample,
|
||||
delete_chat,
|
||||
keep_alive,
|
||||
level_chunk_with_light,
|
||||
level_event,
|
||||
level_particles,
|
||||
merchant_offers,
|
||||
recipe_book_add,
|
||||
recipe_book_remove,
|
||||
recipe_book_settings,
|
||||
remove_entities,
|
||||
remove_mob_effect,
|
||||
reset_score,
|
||||
resource_pack_pop,
|
||||
resource_pack_push,
|
||||
respawn,
|
||||
section_blocks_update,
|
||||
select_advancements_tab,
|
||||
server_data,
|
||||
server_links,
|
||||
set_action_bar_text,
|
||||
set_border_center,
|
||||
set_border_lerp_size,
|
||||
set_border_size,
|
||||
set_border_warning_delay,
|
||||
set_border_warning_distance,
|
||||
set_camera,
|
||||
set_chunk_cache_center,
|
||||
set_chunk_cache_radius,
|
||||
set_cursor_item,
|
||||
set_default_spawn_position,
|
||||
set_display_objective,
|
||||
set_entity_data,
|
||||
set_entity_link,
|
||||
set_entity_motion,
|
||||
set_equipment,
|
||||
set_experience,
|
||||
set_health,
|
||||
set_held_slot,
|
||||
set_objective,
|
||||
set_passengers,
|
||||
set_player_inventory,
|
||||
set_player_team,
|
||||
set_score,
|
||||
set_simulation_distance,
|
||||
set_subtitle_text,
|
||||
set_time,
|
||||
set_title_text,
|
||||
set_titles_animation,
|
||||
teleport_entity,
|
||||
change_difficulty,
|
||||
chunk_batch_finished,
|
||||
chunk_batch_start,
|
||||
chunks_biomes,
|
||||
disconnect,
|
||||
disguised_chat,
|
||||
light_update,
|
||||
ping,
|
||||
ticking_state,
|
||||
ticking_step,
|
||||
block_changed_ack,
|
||||
block_destruction,
|
||||
block_entity_data,
|
||||
block_event,
|
||||
block_update,
|
||||
clear_titles,
|
||||
place_ghost_recipe,
|
||||
player_abilities,
|
||||
player_chat,
|
||||
player_combat_end,
|
||||
player_combat_enter,
|
||||
player_combat_kill,
|
||||
player_info_remove,
|
||||
player_info_update,
|
||||
player_look_at,
|
||||
player_position,
|
||||
player_rotation,
|
||||
animate,
|
||||
entity_event,
|
||||
entity_position_sync,
|
||||
initialize_border,
|
||||
boss_event,
|
||||
command_suggestions,
|
||||
commands,
|
||||
container_close,
|
||||
container_set_content,
|
||||
container_set_data,
|
||||
container_set_slot,
|
||||
cookie_request,
|
||||
cooldown,
|
||||
forget_level_chunk,
|
||||
horse_screen_open,
|
||||
login,
|
||||
move_entity_pos,
|
||||
move_entity_pos_rot,
|
||||
move_entity_rot,
|
||||
move_minecart_along_track,
|
||||
move_vehicle,
|
||||
pong_response,
|
||||
rotate_head,
|
||||
sound,
|
||||
sound_entity,
|
||||
open_book,
|
||||
open_screen,
|
||||
open_sign_editor,
|
||||
update_advancements,
|
||||
update_attributes,
|
||||
update_mob_effect,
|
||||
update_recipes,
|
||||
update_tags,
|
||||
projectile_power,
|
||||
transfer,
|
||||
start_configuration,
|
||||
stop_sound,
|
||||
store_cookie,
|
||||
bundle_delimiter,
|
||||
custom_chat_completions,
|
||||
custom_payload,
|
||||
custom_report_details,
|
||||
hurt_animation,
|
||||
award_stats,
|
||||
explode,
|
||||
system_chat,
|
||||
],
|
||||
Serverbound => [
|
||||
paddle_boat,
|
||||
accept_teleportation,
|
||||
edit_book,
|
||||
debug_sample_subscription,
|
||||
keep_alive,
|
||||
recipe_book_change_settings,
|
||||
recipe_book_seen_recipe,
|
||||
rename_item,
|
||||
resource_pack,
|
||||
seen_advancements,
|
||||
select_trade,
|
||||
set_beacon,
|
||||
set_carried_item,
|
||||
set_command_block,
|
||||
set_command_minecart,
|
||||
set_creative_mode_slot,
|
||||
set_jigsaw_block,
|
||||
set_structure_block,
|
||||
teleport_to_entity,
|
||||
change_difficulty,
|
||||
chat,
|
||||
chat_ack,
|
||||
chat_command,
|
||||
chat_command_signed,
|
||||
chat_session_update,
|
||||
chunk_batch_received,
|
||||
jigsaw_generate,
|
||||
pick_item_from_block,
|
||||
pick_item_from_entity,
|
||||
ping_request,
|
||||
sign_update,
|
||||
block_entity_tag_query,
|
||||
client_command,
|
||||
client_information,
|
||||
client_tick_end,
|
||||
place_recipe,
|
||||
player_abilities,
|
||||
player_action,
|
||||
player_command,
|
||||
player_input,
|
||||
player_loaded,
|
||||
entity_tag_query,
|
||||
interact,
|
||||
command_suggestion,
|
||||
configuration_acknowledged,
|
||||
container_button_click,
|
||||
container_click,
|
||||
container_close,
|
||||
container_slot_state_changed,
|
||||
cookie_response,
|
||||
lock_difficulty,
|
||||
move_player_pos,
|
||||
move_player_pos_rot,
|
||||
move_player_rot,
|
||||
move_player_status_only,
|
||||
move_vehicle,
|
||||
pong,
|
||||
use_item,
|
||||
use_item_on,
|
||||
bundle_item_selected,
|
||||
custom_payload,
|
||||
swing,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@ use azalea_buf::AzBuf;
|
|||
use azalea_protocol_macros::ServerboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
|
||||
pub struct ServerboundSelectBundleItem {
|
||||
pub struct ServerboundBundleItemSelected {
|
||||
#[var]
|
||||
pub slot_id: i32,
|
||||
#[var]
|
|
@ -1,7 +1,7 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_protocol_macros::ServerboundGamePacket;
|
||||
|
||||
use crate::common::ClientInformation;
|
||||
use crate::common::client_information::ClientInformation;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
|
||||
pub struct ServerboundClientInformation {
|
||||
|
|
|
@ -2,4 +2,4 @@ use azalea_buf::AzBuf;
|
|||
use azalea_protocol_macros::ServerboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
|
||||
pub struct ServerboundTickEnd {}
|
||||
pub struct ServerboundClientTickEnd {}
|
||||
|
|
|
@ -2,7 +2,7 @@ use azalea_buf::AzBuf;
|
|||
use azalea_protocol_macros::ServerboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
|
||||
pub struct ServerboundPickItem {
|
||||
pub struct ServerboundPickItemFromBlock {
|
||||
#[var]
|
||||
pub slot: u32,
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_protocol_macros::ServerboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
|
||||
pub struct ServerboundPickItemFromEntity {
|
||||
#[var]
|
||||
pub id: u32,
|
||||
pub include_data: bool,
|
||||
}
|
5
azalea-protocol/src/packets/game/s_player_loaded.rs
Normal file
5
azalea-protocol/src/packets/game/s_player_loaded.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
use azalea_buf::AzBuf;
|
||||
use azalea_protocol_macros::ServerboundGamePacket;
|
||||
|
||||
#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
|
||||
pub struct ServerboundPlayerLoaded;
|
|
@ -1,9 +1,12 @@
|
|||
// NOTE: This file is generated automatically by codegen/packet.py.
|
||||
// Don't edit it directly!
|
||||
|
||||
use azalea_protocol_macros::declare_state_packets;
|
||||
|
||||
declare_state_packets!(
|
||||
HandshakePacket,
|
||||
Serverbound => [
|
||||
s_client_intention::ServerboundClientIntention,
|
||||
declare_state_packets!(HandshakePacket,
|
||||
Clientbound => [
|
||||
],
|
||||
Clientbound => []
|
||||
Serverbound => [
|
||||
intention,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -6,7 +6,7 @@ use azalea_protocol_macros::ServerboundHandshakePacket;
|
|||
use crate::packets::ClientIntention;
|
||||
|
||||
#[derive(Hash, Clone, Debug, AzBuf, ServerboundHandshakePacket)]
|
||||
pub struct ServerboundClientIntention {
|
||||
pub struct ServerboundIntention {
|
||||
#[var]
|
||||
pub protocol_version: i32,
|
||||
pub hostname: String,
|
|
@ -1,20 +1,22 @@
|
|||
// NOTE: This file is generated automatically by codegen/packet.py.
|
||||
// Don't edit it directly!
|
||||
|
||||
use azalea_protocol_macros::declare_state_packets;
|
||||
|
||||
declare_state_packets!(
|
||||
LoginPacket,
|
||||
Serverbound => [
|
||||
s_hello::ServerboundHello,
|
||||
s_key::ServerboundKey,
|
||||
s_custom_query_answer::ServerboundCustomQueryAnswer,
|
||||
s_login_acknowledged::ServerboundLoginAcknowledged,
|
||||
s_cookie_response::ServerboundCookieResponse,
|
||||
],
|
||||
declare_state_packets!(LoginPacket,
|
||||
Clientbound => [
|
||||
c_login_disconnect::ClientboundLoginDisconnect,
|
||||
c_hello::ClientboundHello,
|
||||
c_login_finished::ClientboundLoginFinished,
|
||||
c_login_compression::ClientboundLoginCompression,
|
||||
c_custom_query::ClientboundCustomQuery,
|
||||
c_cookie_request::ClientboundCookieRequest,
|
||||
hello,
|
||||
cookie_request,
|
||||
login_compression,
|
||||
login_disconnect,
|
||||
login_finished,
|
||||
custom_query,
|
||||
],
|
||||
Serverbound => [
|
||||
hello,
|
||||
key,
|
||||
cookie_response,
|
||||
login_acknowledged,
|
||||
custom_query_answer,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
// NOTE: This file is generated automatically by codegen/packet.py.
|
||||
// Don't edit it directly!
|
||||
|
||||
use azalea_protocol_macros::declare_state_packets;
|
||||
|
||||
declare_state_packets!(
|
||||
StatusPacket,
|
||||
Serverbound => [
|
||||
s_status_request::ServerboundStatusRequest,
|
||||
s_ping_request::ServerboundPingRequest,
|
||||
],
|
||||
declare_state_packets!(StatusPacket,
|
||||
Clientbound => [
|
||||
c_status_response::ClientboundStatusResponse,
|
||||
c_pong_response::ClientboundPongResponse,
|
||||
pong_response,
|
||||
status_response,
|
||||
],
|
||||
Serverbound => [
|
||||
ping_request,
|
||||
status_request,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
|||
};
|
||||
|
||||
use azalea_block::BlockState;
|
||||
use azalea_buf::{BufReadError, AzaleaRead, AzaleaWrite};
|
||||
use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
|
||||
use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos};
|
||||
use nohash_hasher::IntMap;
|
||||
use parking_lot::RwLock;
|
||||
|
|
18
codegen/genpackets.py
Executable file
18
codegen/genpackets.py
Executable file
|
@ -0,0 +1,18 @@
|
|||
import lib.code.version
|
||||
import lib.code.packet
|
||||
import lib.code.utils
|
||||
import lib.download
|
||||
import lib.extract
|
||||
|
||||
def generate():
|
||||
version_id = lib.code.version.get_version_id()
|
||||
packets_report = lib.extract.get_packets_report(version_id)
|
||||
|
||||
lib.code.packet.set_packets(packets_report)
|
||||
|
||||
lib.code.utils.fmt()
|
||||
|
||||
print('Done!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
generate()
|
|
@ -9,179 +9,80 @@ import re
|
|||
def make_packet_mod_rs_line(packet_id: int, packet_class_name: str):
|
||||
return f' {padded_hex(packet_id)}: {to_snake_case(packet_class_name)}::{to_camel_case(packet_class_name)},'
|
||||
|
||||
MOJMAP_TO_AZALEA_STATE_NAME_MAPPING = {
|
||||
# shorter name, i like it more
|
||||
'configuration': 'config',
|
||||
# in the files mojang calls the directory "game" so we do that too
|
||||
'play': 'game'
|
||||
}
|
||||
AZALEA_TO_MOJMAP_STATE_NAME_MAPPING = {v: k for k, v in MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.items()}
|
||||
|
||||
def fix_state(state: str):
|
||||
return {'PLAY': 'game'}.get(state, state.lower())
|
||||
def generate_packet(packets_report, packet_name, direction, state):
|
||||
mojmap_state = AZALEA_TO_MOJMAP_STATE_NAME_MAPPING.get(state, state)
|
||||
_packet_report = packets_report[mojmap_state][direction]['minecraft:' + packet_name]
|
||||
|
||||
code = []
|
||||
uses = set()
|
||||
|
||||
def generate_packet(burger_packets, mappings: Mappings, target_packet_id, target_packet_direction, target_packet_state):
|
||||
for packet in burger_packets.values():
|
||||
if packet['id'] != target_packet_id:
|
||||
continue
|
||||
packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet'
|
||||
|
||||
direction = packet['direction'].lower() # serverbound or clientbound
|
||||
state = fix_state(packet['state'])
|
||||
packet_struct_name = to_camel_case(f'{direction}_{packet_name}')
|
||||
packet_module_name = f'{direction[0]}_{packet_name}'
|
||||
|
||||
if state != target_packet_state or direction != target_packet_direction:
|
||||
continue
|
||||
code.append(f'use azalea_buf::AzBuf;')
|
||||
code.append(f'use azalea_protocol_macros::{packet_derive_name};')
|
||||
code.append('')
|
||||
|
||||
code.append(
|
||||
f'#[derive(Clone, Debug, AzBuf, {packet_derive_name})]')
|
||||
code.append(
|
||||
f'pub struct {packet_struct_name} {{')
|
||||
code.append(' TODO')
|
||||
code.append('}')
|
||||
|
||||
generated_packet_code = []
|
||||
uses = set()
|
||||
extra_code = []
|
||||
print(code)
|
||||
write_packet_file(state, packet_module_name, '\n'.join(code))
|
||||
|
||||
packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet'
|
||||
|
||||
generated_packet_code.append(
|
||||
f'#[derive(Clone, Debug, AzBuf, {packet_derive_name})]')
|
||||
uses.add(f'azalea_protocol_macros::{packet_derive_name}')
|
||||
uses.add(f'azalea_buf::AzBuf')
|
||||
|
||||
obfuscated_class_name = packet['class'].split('.')[0]
|
||||
class_name = mappings.get_class(
|
||||
obfuscated_class_name).split('.')[-1]
|
||||
if '$' in class_name:
|
||||
class_name, extra_part = class_name.split('$')
|
||||
if class_name.endswith('Packet'):
|
||||
class_name = class_name[:-
|
||||
len('Packet')] + extra_part + 'Packet'
|
||||
|
||||
generated_packet_code.append(
|
||||
f'pub struct {to_camel_case(class_name)} {{')
|
||||
|
||||
# call burger_instruction_to_code for each instruction
|
||||
i = -1
|
||||
instructions = packet.get('instructions', [])
|
||||
while (i + 1) < len(instructions):
|
||||
i += 1
|
||||
|
||||
if instructions[i]['operation'] == 'write':
|
||||
skip = burger_instruction_to_code(
|
||||
instructions, i, generated_packet_code, mappings, obfuscated_class_name, uses, extra_code)
|
||||
if skip:
|
||||
i += skip
|
||||
else:
|
||||
generated_packet_code.append(f'// TODO: {instructions[i]}')
|
||||
|
||||
generated_packet_code.append('}')
|
||||
|
||||
if uses:
|
||||
# empty line before the `use` statements
|
||||
generated_packet_code.insert(0, '')
|
||||
for use in uses:
|
||||
generated_packet_code.insert(0, f'use {use};')
|
||||
for line in extra_code:
|
||||
generated_packet_code.append(line)
|
||||
|
||||
print(generated_packet_code)
|
||||
write_packet_file(state, to_snake_case(class_name),
|
||||
'\n'.join(generated_packet_code))
|
||||
print()
|
||||
# this won't handle writing to the packets/{state}/mod.rs file since we'd need to know the full packet list
|
||||
|
||||
def set_packets(packets_report):
|
||||
for mojmap_state in packets_report:
|
||||
state = MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.get(mojmap_state, mojmap_state)
|
||||
mod_rs_dir = get_dir_location(
|
||||
f'../azalea-protocol/src/packets/{state}/mod.rs')
|
||||
with open(mod_rs_dir, 'r') as f:
|
||||
mod_rs = f.read().splitlines()
|
||||
|
||||
pub_mod_line = f'pub mod {to_snake_case(class_name)};'
|
||||
if pub_mod_line not in mod_rs:
|
||||
mod_rs.insert(0, pub_mod_line)
|
||||
packet_mod_rs_line = make_packet_mod_rs_line(
|
||||
packet['id'], class_name)
|
||||
serverbound_packets = packet_direction_report_to_packet_names(packets_report[mojmap_state]['serverbound'])
|
||||
clientbound_packets = packet_direction_report_to_packet_names(packets_report[mojmap_state].get('clientbound', {}))
|
||||
|
||||
in_serverbound = False
|
||||
in_clientbound = False
|
||||
for i, line in enumerate(mod_rs):
|
||||
if line.strip() == 'Serverbound => {':
|
||||
in_serverbound = True
|
||||
continue
|
||||
elif line.strip() == 'Clientbound => {':
|
||||
in_clientbound = True
|
||||
continue
|
||||
elif line.strip() in ('}', '},'):
|
||||
if (in_serverbound and direction == 'serverbound') or (in_clientbound and direction == 'clientbound'):
|
||||
mod_rs.insert(i, packet_mod_rs_line)
|
||||
break
|
||||
in_serverbound = in_clientbound = False
|
||||
continue
|
||||
code = []
|
||||
code.append('// NOTE: This file is generated automatically by codegen/packet.py.')
|
||||
code.append("// Don't edit it directly!")
|
||||
code.append('')
|
||||
code.append('use azalea_protocol_macros::declare_state_packets;')
|
||||
code.append('')
|
||||
code.append(f'declare_state_packets!({to_camel_case(state)}Packet,')
|
||||
code.append(' Clientbound => [')
|
||||
for packet_name in clientbound_packets:
|
||||
code.append(f' {packet_name},')
|
||||
code.append(' ],')
|
||||
code.append(' Serverbound => [')
|
||||
for packet_name in serverbound_packets:
|
||||
code.append(f' {packet_name},')
|
||||
code.append(' ]')
|
||||
code.append(');')
|
||||
code.append('')
|
||||
|
||||
if line.strip() == '' or line.strip().startswith('//') or (not in_serverbound and direction == 'serverbound') or (not in_clientbound and direction == 'clientbound'):
|
||||
continue
|
||||
|
||||
line_packet_id_hex = line.strip().split(':')[0]
|
||||
assert line_packet_id_hex.startswith('0x')
|
||||
line_packet_id = int(line_packet_id_hex[2:], 16)
|
||||
if line_packet_id > packet['id']:
|
||||
mod_rs.insert(i, packet_mod_rs_line)
|
||||
break
|
||||
|
||||
with open(mod_rs_dir, 'w') as f:
|
||||
f.write('\n'.join(mod_rs))
|
||||
|
||||
|
||||
def set_packets(packet_ids: list[int], packet_class_names: list[str], direction: str, state: str):
|
||||
assert len(packet_ids) == len(packet_class_names)
|
||||
|
||||
# ids are repeated
|
||||
assert len(packet_ids) == len(set(packet_ids))
|
||||
|
||||
# sort the packets by id
|
||||
packet_ids, packet_class_names = [list(x) for x in zip(
|
||||
*sorted(zip(packet_ids, packet_class_names), key=lambda pair: pair[0]))] # type: ignore
|
||||
|
||||
mod_rs_dir = get_dir_location(
|
||||
f'../azalea-protocol/src/packets/{state}/mod.rs')
|
||||
with open(mod_rs_dir, 'r') as f:
|
||||
mod_rs = f.read().splitlines()
|
||||
new_mod_rs = []
|
||||
|
||||
required_modules = []
|
||||
|
||||
ignore_lines = False
|
||||
|
||||
for line in mod_rs:
|
||||
if line.strip() == 'Serverbound => {':
|
||||
new_mod_rs.append(line)
|
||||
if direction == 'serverbound':
|
||||
ignore_lines = True
|
||||
for packet_id, packet_class_name in zip(packet_ids, packet_class_names):
|
||||
new_mod_rs.append(
|
||||
make_packet_mod_rs_line(packet_id, packet_class_name)
|
||||
)
|
||||
required_modules.append(packet_class_name)
|
||||
else:
|
||||
ignore_lines = False
|
||||
continue
|
||||
elif line.strip() == 'Clientbound => {':
|
||||
new_mod_rs.append(line)
|
||||
if direction == 'clientbound':
|
||||
ignore_lines = True
|
||||
for packet_id, packet_class_name in zip(packet_ids, packet_class_names):
|
||||
new_mod_rs.append(
|
||||
make_packet_mod_rs_line(packet_id, packet_class_name)
|
||||
)
|
||||
required_modules.append(packet_class_name)
|
||||
else:
|
||||
ignore_lines = False
|
||||
continue
|
||||
elif line.strip() in ('}', '},'):
|
||||
ignore_lines = False
|
||||
elif line.strip().startswith('pub mod '):
|
||||
continue
|
||||
|
||||
if not ignore_lines:
|
||||
new_mod_rs.append(line)
|
||||
# 0x00: c_status_response::ClientboundStatusResponsePacket,
|
||||
if line.strip().startswith('0x'):
|
||||
required_modules.append(
|
||||
line.strip().split(':')[1].split('::')[0].strip())
|
||||
|
||||
for i, required_module in enumerate(required_modules):
|
||||
if required_module not in mod_rs:
|
||||
new_mod_rs.insert(i, f'pub mod {required_module};')
|
||||
|
||||
with open(mod_rs_dir, 'w') as f:
|
||||
f.write('\n'.join(new_mod_rs))
|
||||
with open(mod_rs_dir, 'w') as f:
|
||||
f.write('\n'.join(code))
|
||||
|
||||
def packet_direction_report_to_packet_names(report):
|
||||
name_to_id = {}
|
||||
for resource_location, packet in report.items():
|
||||
packet_id = packet['protocol_id']
|
||||
name_to_id[resource_location.split(':')[-1]] = packet_id
|
||||
|
||||
names_sorted = [name for name in sorted(name_to_id.keys(), key=lambda item: item[1])]
|
||||
return names_sorted
|
||||
|
||||
def get_packets(direction: str, state: str):
|
||||
mod_rs_dir = get_dir_location(
|
||||
|
|
|
@ -166,8 +166,8 @@ def burger_type_to_rust_type(burger_type, field_name: Optional[str] = None, inst
|
|||
return field_type_rs, is_var, uses, extra_code
|
||||
|
||||
|
||||
def write_packet_file(state, packet_name_snake_case, code):
|
||||
with open(get_dir_location(f'../azalea-protocol/src/packets/{state}/{packet_name_snake_case}.rs'), 'w') as f:
|
||||
def write_packet_file(state, packet_module_name, code):
|
||||
with open(get_dir_location(f'../azalea-protocol/src/packets/{state}/{packet_module_name}.rs'), 'w') as f:
|
||||
f.write(code)
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Extracting data from the Minecraft jars
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from lib.download import get_mappings_for_version, get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
|
||||
from lib.download import get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
|
||||
from lib.utils import get_dir_location, to_camel_case, upper_first_letter
|
||||
from zipfile import ZipFile
|
||||
import subprocess
|
||||
|
@ -23,17 +23,16 @@ def generate_data_from_server_jar(version_id: str):
|
|||
|
||||
|
||||
def get_block_states_report(version_id: str):
|
||||
generate_data_from_server_jar(version_id)
|
||||
with open(get_dir_location(f'__cache__/generated-{version_id}/reports/blocks.json'), 'r') as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
return get_report(version_id, 'blocks')
|
||||
def get_registries_report(version_id: str):
|
||||
return get_report(version_id, 'registries')
|
||||
def get_packets_report(version_id: str):
|
||||
return get_report(version_id, 'packets')
|
||||
def get_report(version_id: str, name: str):
|
||||
generate_data_from_server_jar(version_id)
|
||||
with open(get_dir_location(f'__cache__/generated-{version_id}/reports/registries.json'), 'r') as f:
|
||||
with open(get_dir_location(f'__cache__/generated-{version_id}/reports/{name}.json'), 'r') as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def get_registry_tags(version_id: str, name: str):
|
||||
generate_data_from_server_jar(version_id)
|
||||
tags_directory = get_dir_location(f'__cache__/generated-{version_id}/data/minecraft/tags/{name}')
|
||||
|
|
|
@ -5,18 +5,20 @@ import lib.download
|
|||
import lib.extract
|
||||
import sys
|
||||
|
||||
version_id = lib.code.version.get_version_id()
|
||||
def generate():
|
||||
version_id = lib.code.version.get_version_id()
|
||||
|
||||
mappings = lib.download.get_mappings_for_version(version_id)
|
||||
burger_data = lib.extract.get_burger_data_for_version(version_id)
|
||||
packets_report = lib.extract.get_packets_report(version_id)
|
||||
|
||||
burger_packets_data = burger_data[0]['packets']['packet']
|
||||
packet_id, direction, state = int(sys.argv[1], 0), sys.argv[2], sys.argv[3]
|
||||
print(
|
||||
f'Generating code for packet id: {packet_id} with direction {direction} and state {state}')
|
||||
lib.code.packet.generate_packet(burger_packets_data, mappings,
|
||||
packet_id, direction, state)
|
||||
packet_id, direction, state = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
print(
|
||||
f'Generating code for packet id: {packet_id} with direction {direction} and state {state}')
|
||||
lib.code.packet.generate_packet(packets_report, packet_id, direction, state)
|
||||
lib.code.packet.set_packets(packets_report)
|
||||
|
||||
lib.code.utils.fmt()
|
||||
lib.code.utils.fmt()
|
||||
|
||||
print('Done!')
|
||||
print('Done!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
generate()
|
||||
|
|
Loading…
Add table
Reference in a new issue