diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index c4435636..80cada9b 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -53,6 +53,10 @@ pub mod serverbound_chat_command_packet; pub mod serverbound_chat_preview_packet; pub mod serverbound_custom_payload_packet; pub mod serverbound_keep_alive_packet; +pub mod serverbound_move_player_packet_pos; +pub mod serverbound_move_player_packet_pos_rot; +pub mod serverbound_move_player_packet_rot; +pub mod serverbound_move_player_packet_status_only; use packet_macros::declare_state_packets; @@ -63,6 +67,10 @@ declare_state_packets!( 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, }, Clientbound => { 0x00: clientbound_add_entity_packet::ClientboundAddEntityPacket, diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_packet_pos.rs b/azalea-protocol/src/packets/game/serverbound_move_player_packet_pos.rs new file mode 100644 index 00000000..65b28624 --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_move_player_packet_pos.rs @@ -0,0 +1,9 @@ +use packet_macros::{GamePacket, McBuf}; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundMovePlayerPacketPos { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_packet_pos_rot.rs b/azalea-protocol/src/packets/game/serverbound_move_player_packet_pos_rot.rs new file mode 100644 index 00000000..8070d1bf --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_move_player_packet_pos_rot.rs @@ -0,0 +1,11 @@ +use packet_macros::{GamePacket, McBuf}; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundMovePlayerPacketPosRot { + pub x: f64, + pub y: f64, + pub z: f64, + pub y_rot: f32, + pub x_rot: f32, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_packet_rot.rs b/azalea-protocol/src/packets/game/serverbound_move_player_packet_rot.rs new file mode 100644 index 00000000..0c444d03 --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_move_player_packet_rot.rs @@ -0,0 +1,8 @@ +use packet_macros::{GamePacket, McBuf}; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundMovePlayerPacketRot { + pub y_rot: f32, + pub x_rot: f32, + pub on_ground: bool, +} diff --git a/azalea-protocol/src/packets/game/serverbound_move_player_packet_status_only.rs b/azalea-protocol/src/packets/game/serverbound_move_player_packet_status_only.rs new file mode 100644 index 00000000..ef762caf --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_move_player_packet_status_only.rs @@ -0,0 +1,6 @@ +use packet_macros::{GamePacket, McBuf}; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundMovePlayerPacketStatusOnly { + pub on_ground: bool, +} diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py index 2aabf39a..c282bdb4 100644 --- a/codegen/lib/code/packet.py +++ b/codegen/lib/code/packet.py @@ -1,7 +1,9 @@ +from typing import Optional from lib.code.utils import burger_type_to_rust_type, write_packet_file from lib.utils import padded_hex, to_snake_case, to_camel_case, get_dir_location from lib.mappings import Mappings import os +import re def make_packet_mod_rs_line(packet_id: int, packet_class_name: str): @@ -29,34 +31,19 @@ def generate_packet(burger_packets, mappings: Mappings, target_packet_id, target f'#[derive(Clone, Debug, McBuf, {to_camel_case(state)}Packet)]') uses.add(f'packet_macros::{{{to_camel_case(state)}Packet, McBuf}}') - obfuscated_class_name = packet['class'].split('.')[0].split('$')[0] + obfuscated_class_name = packet['class'].split('.')[0] class_name = mappings.get_class( - obfuscated_class_name).split('.')[-1].split('$')[0] + obfuscated_class_name).split('.')[-1] + if '$' in class_name: + class_name = class_name.replace('$', '') generated_packet_code.append( f'pub struct {to_camel_case(class_name)} {{') for instruction in packet.get('instructions', []): if instruction['operation'] == 'write': - obfuscated_field_name = instruction['field'] - if '.' in obfuscated_field_name or ' ' in obfuscated_field_name or '(' in obfuscated_field_name: - generated_packet_code.append(f'// TODO: {instruction}') - continue - field_name = mappings.get_field( - obfuscated_class_name, obfuscated_field_name) - if not field_name: - generated_packet_code.append( - f'// TODO: unknown field {instruction}') - continue - - field_type = instruction['type'] - field_type_rs, is_var, instruction_uses = burger_type_to_rust_type( - field_type) - if is_var: - generated_packet_code.append('#[var]') - generated_packet_code.append( - f'pub {to_snake_case(field_name)}: {field_type_rs},') - uses.update(instruction_uses) + burger_instruction_to_code( + instruction, generated_packet_code, mappings, obfuscated_class_name, uses) else: generated_packet_code.append(f'// TODO: {instruction}') continue @@ -213,6 +200,41 @@ def get_packets(direction: str, state: str): return packet_ids, packet_class_names +def burger_instruction_to_code(instruction: dict, generated_packet_code: list[str], mappings: Mappings, obfuscated_class_name: str, uses: set): + field_type = instruction['type'] + field_type_rs, is_var, instruction_uses = burger_type_to_rust_type( + field_type) + + obfuscated_field_name = instruction['field'] + if '.' in obfuscated_field_name or ' ' in obfuscated_field_name or '(' in obfuscated_field_name: + field_type_rs, obfuscated_field_name = burger_field_to_type( + obfuscated_field_name) + if not field_type_rs: + generated_packet_code.append(f'// TODO: {instruction}') + return + field_name = mappings.get_field( + obfuscated_class_name, obfuscated_field_name) or mappings.get_field( + obfuscated_class_name.split('$')[0], obfuscated_field_name) + if not field_name: + generated_packet_code.append( + f'// TODO: unknown field {instruction}') + return + + if is_var: + generated_packet_code.append('#[var]') + generated_packet_code.append( + f'pub {to_snake_case(field_name)}: {field_type_rs},') + uses.update(instruction_uses) + + +def burger_field_to_type(field) -> tuple[Optional[str], str]: + # match `(x) ? 1 : 0` + match = re.match(r'\((.*)\) \? 1 : 0', field) + if match: + return ('bool', match.group(1)) + return None, field + + def change_packet_ids(id_map: dict[int, int], direction: str, state: str): existing_packet_ids, existing_packet_class_names = get_packets( direction, state)