diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-07-29 04:56:21 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-29 04:56:21 +0000 |
| commit | aadf2de3cb751d563e743599a7fb345c08010f5a (patch) | |
| tree | aec2a9485c5057f1c148b87e23ee07a7a6b4978b | |
| parent | 3e43fc6c502573f9d48d801087e72cded37a30b8 (diff) | |
| parent | 2211021105a7ce0ce9fcbc18f3b4f03b0f991a10 (diff) | |
| download | azalea-drasl-aadf2de3cb751d563e743599a7fb345c08010f5a.tar.xz | |
Merge pull request #8 from mat-1/1.19.1
Support 1.19.1. Signing stuff isn't implemented but auth isn't even in Azalea yet so that's fine.
29 files changed, 373 insertions, 120 deletions
@@ -145,6 +145,7 @@ dependencies = [ "rand", "rsa_public_encrypt_pkcs1", "sha-1", + "uuid", ] [[package]] @@ -7,7 +7,7 @@ A collection of Rust crates primarily for creating Minecraft bots. </p> <!-- The line below is automatically read and updated by the migrate script, so don't change it manually. --> -*Currently supported Minecraft version: `1.19`.* +*Currently supported Minecraft version: `1.19.1`.* ## ⚠️ Azalea is still super unfinished, you probably shouldn't use it diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs index f07b1bce..3eb86a90 100644 --- a/azalea-block/src/lib.rs +++ b/azalea-block/src/lib.rs @@ -8,7 +8,7 @@ use std::mem; impl BlockState { /// Transmutes a u32 to a block state. - /// + /// /// # Safety /// The `state_id` should be a valid block state. #[inline] diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index e2967a10..b904fa92 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -100,6 +100,7 @@ impl Client { ServerboundHelloPacket { username: account.username.clone(), public_key: None, + profile_id: None, } .get(), ) @@ -534,7 +535,7 @@ impl Client { dimension.move_entity_with_delta(p.entity_id, &p.delta)?; } - GamePacket::ClientboundMoveEntityPosRotPacket(p) => { + GamePacket::ClientboundMoveEntityPosrotPacket(p) => { let mut dimension_lock = client.dimension.lock()?; let dimension = dimension_lock.as_mut().unwrap(); diff --git a/azalea-crypto/Cargo.toml b/azalea-crypto/Cargo.toml index ee652565..7b77eb3b 100644 --- a/azalea-crypto/Cargo.toml +++ b/azalea-crypto/Cargo.toml @@ -13,3 +13,4 @@ num-bigint = "^0.4.3" rand = {version = "^0.8.4", features = ["getrandom"]} rsa_public_encrypt_pkcs1 = "0.4.0" sha-1 = "^0.10.0" +uuid = "^1.1.2" diff --git a/azalea-crypto/src/lib.rs b/azalea-crypto/src/lib.rs index a5e797e8..9a17a472 100644 --- a/azalea-crypto/src/lib.rs +++ b/azalea-crypto/src/lib.rs @@ -7,7 +7,7 @@ use aes::{ }; use rand::{rngs::OsRng, RngCore}; use sha1::{Digest, Sha1}; -pub use signing::SaltSignaturePair; +pub use signing::*; fn generate_secret_key() -> [u8; 16] { let mut key = [0u8; 16]; diff --git a/azalea-crypto/src/signing.rs b/azalea-crypto/src/signing.rs index 535f9f1d..3bad08c9 100644 --- a/azalea-crypto/src/signing.rs +++ b/azalea-crypto/src/signing.rs @@ -1,24 +1,19 @@ -use azalea_buf::{McBufReadable, McBufWritable}; -use std::io::{Read, Write}; +use azalea_buf::McBuf; +use uuid::Uuid; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, McBuf)] pub struct SaltSignaturePair { pub salt: u64, pub signature: Vec<u8>, } -impl McBufReadable for SaltSignaturePair { - fn read_from(buf: &mut impl Read) -> Result<Self, String> { - let salt = u64::read_from(buf)?; - let signature = Vec::<u8>::read_from(buf)?; - Ok(SaltSignaturePair { salt, signature }) - } +#[derive(Clone, Debug, Default, McBuf)] +pub struct MessageSignature { + pub bytes: Vec<u8>, } -impl McBufWritable for SaltSignaturePair { - fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - self.salt.write_into(buf)?; - self.signature.write_into(buf)?; - Ok(()) - } +#[derive(Clone, Debug, McBuf)] +pub struct SignedMessageHeader { + pub previous_signature: Option<MessageSignature>, + pub sender: Uuid, } diff --git a/azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs new file mode 100644 index 00000000..06a641f1 --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_custom_chat_completions_packet.rs @@ -0,0 +1,15 @@ +use azalea_buf::McBuf; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ClientboundCustomChatCompletionsPacket { + pub action: Action, + pub entries: Vec<String>, +} + +#[derive(Clone, Debug, McBuf, Copy)] +pub enum Action { + Add = 0, + Remove = 1, + Set = 2, +} diff --git a/azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs new file mode 100644 index 00000000..6e7ab6b7 --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_delete_chat_packet.rs @@ -0,0 +1,8 @@ +use azalea_buf::McBuf; +use azalea_crypto::MessageSignature; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ClientboundDeleteChatPacket { + pub message_signature: MessageSignature, +} diff --git a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs index adb6e33b..1c998226 100644 --- a/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_light_update_packet.rs @@ -1,5 +1,4 @@ -use azalea_buf::BitSet; -use azalea_buf::McBuf; +use azalea_buf::{BitSet, McBuf}; use packet_macros::GamePacket; #[derive(Clone, Debug, McBuf, GamePacket)] diff --git a/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs b/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs index e3422ac0..3dbfaff6 100644 --- a/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_move_entity_posrot_packet.rs @@ -4,7 +4,7 @@ use packet_macros::GamePacket; /// This packet is sent by the server when an entity moves less then 8 blocks. #[derive(Clone, Debug, McBuf, GamePacket)] -pub struct ClientboundMoveEntityPosRotPacket { +pub struct ClientboundMoveEntityPosrotPacket { #[var] pub entity_id: u32, pub delta: PositionDelta8, diff --git a/azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs new file mode 100644 index 00000000..bd0bc1f3 --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_player_chat_header_packet.rs @@ -0,0 +1,10 @@ +use azalea_buf::McBuf; +use azalea_crypto::{MessageSignature, SignedMessageHeader}; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ClientboundPlayerChatHeaderPacket { + pub header: SignedMessageHeader, + pub header_signature: MessageSignature, + pub body_digest: Vec<u8>, +} diff --git a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs index 4aac93f4..68f0ea21 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs @@ -1,22 +1,99 @@ -use azalea_buf::McBuf; +use azalea_buf::{BitSet, McBuf, McBufReadable, McBufVarWritable}; +use azalea_buf::{McBufVarReadable, McBufWritable}; use azalea_chat::component::Component; -use azalea_crypto::SaltSignaturePair; +use azalea_crypto::{MessageSignature, SignedMessageHeader}; use packet_macros::GamePacket; +use std::io::{Read, Write}; +use uuid::Uuid; #[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundPlayerChatPacket { - pub signed_content: Component, + pub message: PlayerChatMessage, + pub chat_type: ChatTypeBound, +} + +#[derive(Copy, Clone, Debug, McBuf)] +pub enum ChatType { + Chat = 0, + SayCommand = 1, + MsgCommandIncoming = 2, + MsgCommandOutgoing = 3, + TeamMsgCommandIncoming = 4, + TeamMsgCommandOutgoing = 5, + EmoteCommand = 6, +} + +#[derive(Clone, Debug, McBuf)] +pub struct ChatTypeBound { + pub chat_type: ChatType, + pub name: Component, + pub target_name: Option<Component>, +} + +#[derive(Clone, Debug, McBuf)] +pub struct PlayerChatMessage { + pub signed_header: SignedMessageHeader, + pub header_signature: MessageSignature, + pub signed_body: SignedMessageBody, pub unsigned_content: Option<Component>, - #[var] - pub type_id: i32, - pub sender: ChatSender, + pub filter_mask: FilterMask, +} + +#[derive(Clone, Debug, McBuf)] +pub struct SignedMessageBody { + pub content: ChatMessageContent, pub timestamp: u64, - pub salt_signature: SaltSignaturePair, + pub salt: u64, + pub last_seen: Vec<LastSeenMessagesEntry>, } #[derive(Clone, Debug, McBuf)] -pub struct ChatSender { - pub uuid: uuid::Uuid, - pub name: Component, - pub team_name: Option<Component>, +pub struct LastSeenMessagesEntry { + pub profile_id: Uuid, + pub last_signature: MessageSignature, +} + +#[derive(Clone, Debug, McBuf)] +pub struct LastSeenMessagesUpdate { + pub last_seen: Vec<LastSeenMessagesEntry>, + pub last_received: Option<LastSeenMessagesEntry>, +} + +#[derive(Clone, Debug, McBuf)] +pub struct ChatMessageContent { + pub plain: String, + /// Only sent if the decorated message is different than the plain. + pub decorated: Option<Component>, +} + +#[derive(Clone, Debug)] +pub enum FilterMask { + PassThrough, + FullyFiltered, + PartiallyFiltered(BitSet), +} + +impl McBufReadable for FilterMask { + fn read_from(buf: &mut impl Read) -> Result<Self, String> { + let filter_mask = u32::var_read_from(buf)?; + match filter_mask { + 0 => Ok(FilterMask::PassThrough), + 1 => Ok(FilterMask::FullyFiltered), + 2 => Ok(FilterMask::PartiallyFiltered(BitSet::read_from(buf)?)), + _ => Err("Invalid filter mask".to_string()), + } + } +} +impl McBufWritable for FilterMask { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + FilterMask::PassThrough => 0u32.var_write_into(buf)?, + FilterMask::FullyFiltered => 1u32.var_write_into(buf)?, + FilterMask::PartiallyFiltered(bits) => { + 2u32.var_write_into(buf)?; + bits.write_into(buf)?; + } + } + Ok(()) + } } diff --git a/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs index 1dddfc1e..ed91733e 100644 --- a/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_server_data_packet.rs @@ -7,4 +7,5 @@ pub struct ClientboundServerDataPacket { pub motd: Option<Component>, pub icon_base64: Option<String>, pub previews_chat: bool, + pub enforces_secure_chat: bool, } diff --git a/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs index c531fa1e..8318b7d4 100644 --- a/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_system_chat_packet.rs @@ -5,6 +5,5 @@ use packet_macros::GamePacket; #[derive(Clone, Debug, McBuf, GamePacket)] pub struct ClientboundSystemChatPacket { pub content: Component, - #[var] - pub type_id: i32, + pub overlay: bool, } diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index f407a697..0b5c4d3e 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -6,8 +6,10 @@ pub mod clientbound_block_update_packet; pub mod clientbound_change_difficulty_packet; pub mod clientbound_chat_preview_packet; pub mod clientbound_container_set_content_packet; +pub mod clientbound_custom_chat_completions_packet; pub mod clientbound_custom_payload_packet; pub mod clientbound_declare_commands_packet; +pub mod clientbound_delete_chat_packet; pub mod clientbound_disconnect_packet; pub mod clientbound_entity_event_packet; pub mod clientbound_entity_velocity_packet; @@ -23,6 +25,7 @@ pub mod clientbound_move_entity_pos_packet; pub mod clientbound_move_entity_posrot_packet; pub mod clientbound_move_entity_rot_packet; pub mod clientbound_player_abilities_packet; +pub mod clientbound_player_chat_header_packet; pub mod clientbound_player_chat_packet; pub mod clientbound_player_info_packet; pub mod clientbound_player_position_packet; @@ -51,7 +54,9 @@ pub mod clientbound_update_recipes_packet; pub mod clientbound_update_tags_packet; pub mod clientbound_update_view_distance_packet; pub mod serverbound_accept_teleportation_packet; +pub mod serverbound_chat_ack_packet; pub mod serverbound_chat_command_packet; +pub mod serverbound_chat_packet; pub mod serverbound_chat_preview_packet; pub mod serverbound_custom_payload_packet; pub mod serverbound_keep_alive_packet; @@ -66,14 +71,16 @@ declare_state_packets!( GamePacket, Serverbound => { 0x00: serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, - 0x03: serverbound_chat_command_packet::ServerboundChatCommandPacket, - 0x05: serverbound_chat_preview_packet::ServerboundChatPreviewPacket, - 0x0c: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, - 0x11: serverbound_keep_alive_packet::ServerboundKeepAlivePacket, - 0x13: serverbound_move_player_packet_pos::ServerboundMovePlayerPacketPos, - 0x14: serverbound_move_player_packet_pos_rot::ServerboundMovePlayerPacketPosRot, - 0x15: serverbound_move_player_packet_rot::ServerboundMovePlayerPacketRot, - 0x16: serverbound_move_player_packet_status_only::ServerboundMovePlayerPacketStatusOnly, + 0x03: serverbound_chat_ack_packet::ServerboundChatAckPacket, + 0x04: serverbound_chat_command_packet::ServerboundChatCommandPacket, + 0x05: serverbound_chat_packet::ServerboundChatPacket, + 0x06: serverbound_chat_preview_packet::ServerboundChatPreviewPacket, + 0x0d: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, + 0x12: serverbound_keep_alive_packet::ServerboundKeepAlivePacket, + 0x14: serverbound_move_player_packet_pos::ServerboundMovePlayerPacketPos, + 0x15: serverbound_move_player_packet_pos_rot::ServerboundMovePlayerPacketPosRot, + 0x16: serverbound_move_player_packet_rot::ServerboundMovePlayerPacketRot, + 0x17: serverbound_move_player_packet_status_only::ServerboundMovePlayerPacketStatusOnly, }, Clientbound => { 0x00: clientbound_add_entity_packet::ClientboundAddEntityPacket, @@ -85,48 +92,51 @@ declare_state_packets!( 0x0c: clientbound_chat_preview_packet::ClientboundChatPreviewPacket, 0x0f: clientbound_declare_commands_packet::ClientboundDeclareCommandsPacket, 0x11: clientbound_container_set_content_packet::ClientboundContainerSetContentPacket, - 0x15: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, - 0x17: clientbound_disconnect_packet::ClientboundDisconnectPacket, - 0x18: clientbound_entity_event_packet::ClientboundEntityEventPacket, - 0x1b: clientbound_game_event_packet::ClientboundGameEventPacket, - 0x1d: clientbound_initialize_border_packet::ClientboundInitializeBorderPacket, - 0x1e: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, - 0x1f: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, - 0x20: clientbound_level_event_packet::ClientboundLevelEventPacket, - 0x21: clientbound_level_particles_packet::ClientboundLevelParticlesPacket, - 0x22: clientbound_light_update_packet::ClientboundLightUpdatePacket, - 0x23: clientbound_login_packet::ClientboundLoginPacket, - 0x26: clientbound_move_entity_pos_packet::ClientboundMoveEntityPosPacket, - 0x27: clientbound_move_entity_posrot_packet::ClientboundMoveEntityPosRotPacket, - 0x28: clientbound_move_entity_rot_packet::ClientboundMoveEntityRotPacket, - 0x2f: clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket, - 0x30: clientbound_player_chat_packet::ClientboundPlayerChatPacket, - 0x34: clientbound_player_info_packet::ClientboundPlayerInfoPacket, - 0x36: clientbound_player_position_packet::ClientboundPlayerPositionPacket, - 0x37: clientbound_recipe_packet::ClientboundRecipePacket, - 0x38: clientbound_remove_entities_packet::ClientboundRemoveEntitiesPacket, - 0x3c: clientbound_rotate_head_packet::ClientboundRotateHeadPacket, - 0x3d: clientbound_section_blocks_update_packet::ClientboundSectionBlocksUpdatePacket, - 0x3f: clientbound_server_data_packet::ClientboundServerDataPacket, - 0x47: clientbound_set_carried_item_packet::ClientboundSetCarriedItemPacket, - 0x48: clientbound_set_chunk_cache_center_packet::ClientboundSetChunkCacheCenterPacket, - 0x49: clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket, - 0x4a: clientbound_set_default_spawn_position_packet::ClientboundSetDefaultSpawnPositionPacket, - 0x4b: clientbound_set_display_chat_preview_packet::ClientboundSetDisplayChatPreviewPacket, - 0x4d: clientbound_set_entity_data_packet::ClientboundSetEntityDataPacket, - 0x4e: clientbound_set_entity_link_packet::ClientboundSetEntityLinkPacket, - 0x4f: clientbound_entity_velocity_packet::ClientboundEntityVelocityPacket, - 0x50: clientbound_set_equipment_packet::ClientboundSetEquipmentPacket, - 0x51: clientbound_set_experience_packet::ClientboundSetExperiencePacket, - 0x52: clientbound_set_health_packet::ClientboundSetHealthPacket, - 0x59: clientbound_set_time_packet::ClientboundSetTimePacket, - 0x5d: clientbound_sound_packet::ClientboundSoundPacket, - 0x5f: clientbound_system_chat_packet::ClientboundSystemChatPacket, - 0x63: clientbound_teleport_entity_packet::ClientboundTeleportEntityPacket, - 0x64: clientbound_update_advancements_packet::ClientboundUpdateAdvancementsPacket, - 0x65: clientbound_update_attributes_packet::ClientboundUpdateAttributesPacket, - 0x66: clientbound_update_mob_effect_packet::ClientboundUpdateMobEffectPacket, - 0x67: clientbound_update_recipes_packet::ClientboundUpdateRecipesPacket, - 0x68: clientbound_update_tags_packet::ClientboundUpdateTagsPacket, + 0x15: clientbound_custom_chat_completions_packet::ClientboundCustomChatCompletionsPacket, + 0x16: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, + 0x18: clientbound_delete_chat_packet::ClientboundDeleteChatPacket, + 0x19: clientbound_disconnect_packet::ClientboundDisconnectPacket, + 0x1a: clientbound_entity_event_packet::ClientboundEntityEventPacket, + 0x1d: clientbound_game_event_packet::ClientboundGameEventPacket, + 0x1f: clientbound_initialize_border_packet::ClientboundInitializeBorderPacket, + 0x20: clientbound_keep_alive_packet::ClientboundKeepAlivePacket, + 0x21: clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, + 0x22: clientbound_level_event_packet::ClientboundLevelEventPacket, + 0x23: clientbound_level_particles_packet::ClientboundLevelParticlesPacket, + 0x24: clientbound_light_update_packet::ClientboundLightUpdatePacket, + 0x25: clientbound_login_packet::ClientboundLoginPacket, + 0x28: clientbound_move_entity_pos_packet::ClientboundMoveEntityPosPacket, + 0x29: clientbound_move_entity_posrot_packet::ClientboundMoveEntityPosrotPacket, + 0x2a: clientbound_move_entity_rot_packet::ClientboundMoveEntityRotPacket, + 0x31: clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket, + 0x32: clientbound_player_chat_header_packet::ClientboundPlayerChatHeaderPacket, + 0x33: clientbound_player_chat_packet::ClientboundPlayerChatPacket, + 0x37: clientbound_player_info_packet::ClientboundPlayerInfoPacket, + 0x39: clientbound_player_position_packet::ClientboundPlayerPositionPacket, + 0x3a: clientbound_recipe_packet::ClientboundRecipePacket, + 0x3b: clientbound_remove_entities_packet::ClientboundRemoveEntitiesPacket, + 0x3f: clientbound_rotate_head_packet::ClientboundRotateHeadPacket, + 0x40: clientbound_section_blocks_update_packet::ClientboundSectionBlocksUpdatePacket, + 0x42: clientbound_server_data_packet::ClientboundServerDataPacket, + 0x4a: clientbound_set_carried_item_packet::ClientboundSetCarriedItemPacket, + 0x4b: clientbound_set_chunk_cache_center_packet::ClientboundSetChunkCacheCenterPacket, + 0x4c: clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket, + 0x4d: clientbound_set_default_spawn_position_packet::ClientboundSetDefaultSpawnPositionPacket, + 0x4e: clientbound_set_display_chat_preview_packet::ClientboundSetDisplayChatPreviewPacket, + 0x50: clientbound_set_entity_data_packet::ClientboundSetEntityDataPacket, + 0x51: clientbound_set_entity_link_packet::ClientboundSetEntityLinkPacket, + 0x52: clientbound_entity_velocity_packet::ClientboundEntityVelocityPacket, + 0x53: clientbound_set_equipment_packet::ClientboundSetEquipmentPacket, + 0x54: clientbound_set_experience_packet::ClientboundSetExperiencePacket, + 0x55: clientbound_set_health_packet::ClientboundSetHealthPacket, + 0x5c: clientbound_set_time_packet::ClientboundSetTimePacket, + 0x60: clientbound_sound_packet::ClientboundSoundPacket, + 0x62: clientbound_system_chat_packet::ClientboundSystemChatPacket, + 0x66: clientbound_teleport_entity_packet::ClientboundTeleportEntityPacket, + 0x67: clientbound_update_advancements_packet::ClientboundUpdateAdvancementsPacket, + 0x68: clientbound_update_attributes_packet::ClientboundUpdateAttributesPacket, + 0x69: clientbound_update_mob_effect_packet::ClientboundUpdateMobEffectPacket, + 0x6a: clientbound_update_recipes_packet::ClientboundUpdateRecipesPacket, + 0x6b: clientbound_update_tags_packet::ClientboundUpdateTagsPacket, } ); diff --git a/azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs new file mode 100644 index 00000000..921ca4c7 --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_chat_ack_packet.rs @@ -0,0 +1,8 @@ +use crate::packets::game::clientbound_player_chat_packet::LastSeenMessagesUpdate; +use azalea_buf::McBuf; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundChatAckPacket { + pub last_seen_messages: LastSeenMessagesUpdate, +} diff --git a/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs index 6371463b..1639deae 100644 --- a/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs +++ b/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs @@ -1,19 +1,22 @@ -use std::collections::HashMap; - use azalea_buf::McBuf; +use azalea_crypto::MessageSignature; use packet_macros::GamePacket; +use super::clientbound_player_chat_packet::LastSeenMessagesUpdate; + #[derive(Clone, Debug, McBuf, GamePacket)] pub struct ServerboundChatCommandPacket { pub command: String, // TODO: Choose a real timestamp type pub timestamp: u64, - pub argument_signatures: ArgumentSignatures, + pub salt: i64, + pub argument_signatures: Vec<ArgumentSignature>, pub signed_preview: bool, + pub last_seen_messages: LastSeenMessagesUpdate, } #[derive(Clone, Debug, McBuf)] -pub struct ArgumentSignatures { - pub salt: u64, - pub signatures: HashMap<String, Vec<u8>>, +pub struct ArgumentSignature { + pub name: String, + pub signature: MessageSignature, } diff --git a/azalea-protocol/src/packets/game/serverbound_chat_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_packet.rs new file mode 100644 index 00000000..f0c99b14 --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_chat_packet.rs @@ -0,0 +1,14 @@ +use crate::packets::game::clientbound_player_chat_packet::LastSeenMessagesUpdate; +use azalea_buf::McBuf; +use azalea_crypto::MessageSignature; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundChatPacket { + pub message: String, + pub timestamp: u64, + pub salt: u64, + pub signature: MessageSignature, + pub signed_preview: bool, + pub last_seen_messages: LastSeenMessagesUpdate, +} diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs index 57a3e4d8..0f6f9a50 100755 --- a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs +++ b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs @@ -1,10 +1,12 @@ use azalea_buf::McBuf; use packet_macros::LoginPacket; +use uuid::Uuid; #[derive(Clone, Debug, McBuf, LoginPacket)] pub struct ServerboundHelloPacket { pub username: String, pub public_key: Option<ProfilePublicKeyData>, + pub profile_id: Option<Uuid>, } #[derive(Clone, Debug, McBuf)] diff --git a/azalea-protocol/src/packets/mod.rs b/azalea-protocol/src/packets/mod.rs index cf405e98..fbccc087 100755..100644 --- a/azalea-protocol/src/packets/mod.rs +++ b/azalea-protocol/src/packets/mod.rs @@ -7,7 +7,7 @@ use crate::connect::PacketFlow; use azalea_buf::{McBufWritable, Readable, Writable}; use std::io::{Read, Write}; -pub const PROTOCOL_VERSION: u32 = 759; +pub const PROTOCOL_VERSION: u32 = 760; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ConnectionProtocol { diff --git a/bot/src/main.rs b/bot/src/main.rs index 3ff30908..0f3ea31a 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -6,7 +6,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "localhost:56150"; + let address = "localhost:25565"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py index de8254e7..ffa7841c 100644 --- a/codegen/lib/code/packet.py +++ b/codegen/lib/code/packet.py @@ -110,7 +110,8 @@ def set_packets(packet_ids: list[int], packet_class_names: list[str], direction: 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 = f'../azalea-protocol/src/packets/{state}/mod.rs' + 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 = [] @@ -140,6 +141,7 @@ def set_packets(packet_ids: list[int], packet_class_names: list[str], direction: 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 @@ -164,7 +166,8 @@ def set_packets(packet_ids: list[int], packet_class_names: list[str], direction: def get_packets(direction: str, state: str): - mod_rs_dir = f'../azalea-protocol/src/packets/{state}/mod.rs' + 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() @@ -268,3 +271,28 @@ def remove_packet_ids(removing_packet_ids: list[int], direction: str, state: str new_packet_class_names.append(packet_class_name) set_packets(new_packet_ids, new_packet_class_names, direction, state) + + +def are_packet_instructions_identical(old_packet, new_packet): + old_packet = old_packet or [] + new_packet = new_packet or [] + + if len(old_packet) != len(new_packet): + return False + + for old_field, new_field in zip(old_packet, new_packet): + if old_field['operation'] != new_field['operation']: + return False + if new_field['operation'] == 'write': + if burger_type_to_rust_type(old_field.get('type')) != burger_type_to_rust_type(new_field.get('type')): + return False + else: + # comparing is too complicated here since it's possible the type has variables + # so we just don't + pass + + if 'instructions' in old_field and 'instructions' in new_field: + if not are_packet_instructions_identical(old_field['instructions'], new_field['instructions']): + return False + + return True diff --git a/codegen/lib/code/utils.py b/codegen/lib/code/utils.py index ecfff4fb..0c22d7ba 100644 --- a/codegen/lib/code/utils.py +++ b/codegen/lib/code/utils.py @@ -62,8 +62,7 @@ def burger_type_to_rust_type(burger_type): burger_type[:-2]) field_type_rs = f'Vec<{field_type_rs}>' else: - print('Unknown field type:', burger_type) - exit() + raise Exception(f'Unknown field type: {burger_type}') return field_type_rs, is_var, uses diff --git a/codegen/lib/code/version.py b/codegen/lib/code/version.py index 511d30d1..13d9472d 100644 --- a/codegen/lib/code/version.py +++ b/codegen/lib/code/version.py @@ -36,7 +36,7 @@ def set_version_id(version_id: str) -> None: def get_protocol_version() -> str: # azalea-protocol/src/packets/mod.rs # pub const PROTOCOL_VERSION: u32 = 758; - with open('../azalea-protocol/src/packets/mod.rs', 'r') as f: + with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'r') as f: mod_rs = f.read().splitlines() for line in mod_rs: if line.strip().startswith('pub const PROTOCOL_VERSION'): @@ -46,7 +46,7 @@ def get_protocol_version() -> str: def set_protocol_version(protocol_version: str) -> None: - with open('../azalea-protocol/src/packets/mod.rs', 'r') as f: + with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'r') as f: mod_rs = f.read().splitlines() for i, line in enumerate(mod_rs): if line.strip().startswith('pub const PROTOCOL_VERSION'): @@ -56,5 +56,5 @@ def set_protocol_version(protocol_version: str) -> None: raise Exception( 'Could not find protocol version in azalea-protocol/src/packets/mod.rs') - with open('../azalea-protocol/src/packets/mod.rs', 'w') as f: + with open(get_dir_location('../azalea-protocol/src/packets/mod.rs'), 'w') as f: f.write('\n'.join(mod_rs)) diff --git a/codegen/lib/download.py b/codegen/lib/download.py index e9712f8d..d9e2e63f 100644 --- a/codegen/lib/download.py +++ b/codegen/lib/download.py @@ -1,4 +1,5 @@ from lib.utils import get_dir_location +import xml.etree.ElementTree as ET from .mappings import Mappings import requests import json @@ -118,11 +119,39 @@ def get_yarn_data(version_id: str): return version +def get_fabric_api_versions(): + # https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml + if not os.path.exists(get_dir_location('downloads/fabric_api_versions.json')): + print('\033[92mDownloading Fabric API versions...\033[m') + fabric_api_versions_xml_text = requests.get( + 'https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml').text + # parse xml + fabric_api_versions_data_xml = ET.fromstring( + fabric_api_versions_xml_text) + fabric_api_versions = [] + + versioning_el = fabric_api_versions_data_xml.find('versioning') + assert versioning_el + versions_el = versioning_el.find('versions') + assert versions_el + + for version_el in versions_el.findall('version'): + fabric_api_versions.append(version_el.text) + + with open(get_dir_location('downloads/fabric_api_versions.json'), 'w') as f: + f.write(json.dumps(fabric_api_versions)) + else: + with open(get_dir_location('downloads/fabric_api_versions.json'), 'r') as f: + fabric_api_versions = json.loads(f.read()) + return fabric_api_versions + + def clear_version_cache(): print('\033[92mClearing version cache...\033[m') files = [ 'version_manifest.json', - 'yarn_versions.json' + 'yarn_versions.json', + 'fabric_api_versions.json' ] for file in files: if os.path.exists(get_dir_location(f'downloads/{file}')): diff --git a/codegen/lib/extract.py b/codegen/lib/extract.py index 893b8d5c..4c2d2399 100644 --- a/codegen/lib/extract.py +++ b/codegen/lib/extract.py @@ -1,6 +1,6 @@ # Extracting data from the Minecraft jars -from lib.download import get_server_jar, get_burger, get_client_jar, get_generator_mod, get_yarn_data +from lib.download import get_server_jar, get_burger, get_client_jar, get_generator_mod, get_yarn_data, get_fabric_api_versions from lib.utils import get_dir_location import json import os @@ -61,7 +61,9 @@ def get_generator_mod_data(version_id: str, category: str): # looks like 1.19+build.1 yarn_version = yarn_data['version'] - # the mod has the minecraft version hard-coded by default, so we just change the gradle.properties + fabric_api_version = get_fabric_api_versions()[-1] + + # the mod has the minecraft version hard-coded by default, so we just change the gradle.properties and fabric.mod.json with open(get_dir_location(f'{generator_mod_dir}/gradle.properties'), 'r') as f: lines = f.readlines() with open(get_dir_location(f'{generator_mod_dir}/gradle.properties'), 'w') as f: @@ -70,7 +72,15 @@ def get_generator_mod_data(version_id: str, category: str): line = f'minecraft_version={version_id}\n' if line.startswith('yarn_mappings='): line = f'yarn_mappings={yarn_version}\n' + if line.startswith('fabric_version='): + line = f'fabric_version={fabric_api_version}\n' f.write(line) + # edit the fabric.mod.json to support this version + with open(get_dir_location(f'{generator_mod_dir}/src/main/resources/fabric.mod.json'), 'r') as f: + fabric_mod_json = json.load(f) + fabric_mod_json['depends']['minecraft'] = '*' + with open(get_dir_location(f'{generator_mod_dir}/src/main/resources/fabric.mod.json'), 'w') as f: + json.dump(fabric_mod_json, f, indent=2) os.system( f'cd {generator_mod_dir} && gradlew runServer' diff --git a/codegen/migrate.py b/codegen/migrate.py index e5b17770..2dacc208 100644 --- a/codegen/migrate.py +++ b/codegen/migrate.py @@ -9,6 +9,14 @@ import sys lib.download.clear_version_cache() +if len(sys.argv) == 1: + print('\033[91mYou must provide a version to migrate to.\033[m') + version_manifest = lib.download.get_version_manifest() + newest_version = version_manifest['latest']['snapshot'] + print(f'Hint: newest version is \033[1m{newest_version}\033[m') + exit() + + old_version_id = lib.code.version.get_version_id() old_mappings = lib.download.get_mappings_for_version(old_version_id) old_burger_data = lib.extract.get_burger_data_for_version(old_version_id) @@ -21,18 +29,24 @@ new_packet_list = list(new_burger_data[0]['packets']['packet'].values()) old_packets: dict[PacketIdentifier, str] = {} +old_packets_data: dict[PacketIdentifier, dict] = {} new_packets: dict[PacketIdentifier, str] = {} +new_packets_data: dict[PacketIdentifier, dict] = {} for packet in old_packet_list: assert packet['class'].endswith('.class') packet_name = old_mappings.get_class(packet['class'][:-6]) - old_packets[PacketIdentifier( - packet['id'], packet['direction'].lower(), fix_state(packet['state']))] = packet_name + packet_ident = PacketIdentifier( + packet['id'], packet['direction'].lower(), fix_state(packet['state'])) + old_packets[packet_ident] = packet_name + old_packets_data[packet_ident] = packet for packet in new_packet_list: assert packet['class'].endswith('.class') packet_name = new_mappings.get_class(packet['class'][:-6]) - new_packets[PacketIdentifier( - packet['id'], packet['direction'].lower(), fix_state(packet['state']))] = packet_name + packet_ident = PacketIdentifier( + packet['id'], packet['direction'].lower(), fix_state(packet['state'])) + new_packets[packet_ident] = packet_name + new_packets_data[packet_ident] = packet # find removed packets removed_packets: list[PacketIdentifier] = [] @@ -65,13 +79,22 @@ for (direction, state), packets in group_packets(list(changed_packets.keys())).i print() -# find added packets -added_packets: list[PacketIdentifier] = [] -for packet, packet_name in new_packets.items(): +# find added/changed packets +added_or_changed_packets: list[PacketIdentifier] = [] +for new_packet, packet_name in new_packets.items(): + old_packet = None + for old_packet_tmp, old_packet_name in old_packets.items(): + if old_packet_name == packet_name: + old_packet = old_packet_tmp + break + if packet_name not in old_packets.values(): - added_packets.append(packet) - print('Added packet:', packet, packet_name) -for packet in added_packets: + added_or_changed_packets.append(new_packet) + print('Added packet:', new_packet, packet_name) + elif old_packet and not lib.code.packet.are_packet_instructions_identical(new_packets_data[new_packet].get('instructions'), old_packets_data[old_packet].get('instructions')): + added_or_changed_packets.append(new_packet) + print('Changed packet:', new_packet, packet_name) +for packet in added_or_changed_packets: lib.code.packet.generate_packet( new_burger_data[0]['packets']['packet'], new_mappings, packet.packet_id, packet.direction, packet.state) diff --git a/examples/craft_dig_straight_down.rs b/examples/craft_dig_straight_down.rs index 54bf0015..47c4fe28 100644 --- a/examples/craft_dig_straight_down.rs +++ b/examples/craft_dig_straight_down.rs @@ -1,15 +1,35 @@ use azalea::{Bot, Event}; -let bot = Bot::offline("bot"); -// or let bot = azalea::Bot::microsoft("access token").await; +struct Context { + pub started: bool +} + +#[tokio::main] +async fn main() { + let bot = Bot::offline("bot"); + // or let bot = azalea::Bot::microsoft("access token").await; + + bot.join("localhost".try_into().unwrap()).await.unwrap(); -bot.join("localhost".try_into().unwrap()).await.unwrap(); + let ctx = Arc::new(Mutex::new(Context { started: false })); -loop { - match bot.next().await { + loop { + tokio::spawn(handle_event(bot.next().await, bot, ctx.clone())); + } +} + + +async fn handle_event(event: &Event, bot: &Bot, ctx: Arc<Context>) { + match event { Event::Message(m) { if m.username == bot.player.username { return }; if m.message = "go" { + // make sure we only start once + let ctx_lock = ctx.lock().unwrap(); + if ctx_lock.started { return }; + ctx_lock.started = true; + drop(ctx_lock); + bot.goto_goal( pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0)) ).await; @@ -34,4 +54,4 @@ loop { }, _ => {} } -} +}
\ No newline at end of file |
