From dbb2092ac002790c07ad21cf7d12aabb477a2e74 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Sat, 20 Aug 2022 15:17:07 -0500 Subject: Implement ALL packets (#16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add a couple more packets and improve codegen * enums in packet codegen * fix enums and MORE PACKETS * make unsigned numbers the default * codegen can make hashmaps * UnsizedByteArray in codegen * Vec and Option * enum codgen works in more situations * ServerboundInteractPacket * Fix error with new error system * More packets * more packets * more packets * guess what was added * yeah it's more packets * add more packets * packets * start adding ClientboundBossEventPacket * finish boss event packet * improve codegen for linux * start on command suggestions packet * rename declare_commands to commands * más paquetes * fix generating custom payload packet * more packets * mehr Pakete * improve codegen for movement packets * rename move packets to have "packet" at the end * fix some unused variable warns * addere plus facis * pli da pakoj * plus de paquets * più pacchetti * make ChatFormatting a macro in azalea-chat * change a match to matches! macro * update SetPlayerTeam to use ChatFormatting * ClientboundSetScorePacket & fix clippy warnings * finish game state :tada: * add remaining packets for other states * fix error in ping.rs --- codegen/lib/code/utils.py | 102 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 14 deletions(-) (limited to 'codegen/lib/code/utils.py') diff --git a/codegen/lib/code/utils.py b/codegen/lib/code/utils.py index 0c22d7ba..e4671488 100644 --- a/codegen/lib/code/utils.py +++ b/codegen/lib/code/utils.py @@ -1,22 +1,31 @@ -from lib.utils import get_dir_location +from lib.utils import to_camel_case, to_snake_case, get_dir_location +from lib.mappings import Mappings +from typing import Optional import os # utilities specifically for codegen -def burger_type_to_rust_type(burger_type): +def burger_type_to_rust_type(burger_type, field_name: Optional[str] = None, instruction=None, mappings: Optional[Mappings] = None, obfuscated_class_name: Optional[str] = None): is_var = False uses = set() + # extra code, like enum definitions + extra_code = [] + + should_be_signed = False + if field_name and any(map(lambda w: w in {'x', 'y', 'z', 'xa', 'ya', 'za'}, to_snake_case(field_name).split('_'))): + # coordinates are signed + should_be_signed = True if burger_type == 'byte': - field_type_rs = 'i8' + field_type_rs = 'i8' if should_be_signed else 'u8' elif burger_type == 'short': - field_type_rs = 'i16' + field_type_rs = 'i16' if should_be_signed else 'u16' elif burger_type == 'int': - field_type_rs = 'i32' + field_type_rs = 'i32' if should_be_signed else 'u32' elif burger_type == 'long': - field_type_rs = 'i64' + field_type_rs = 'i64' if should_be_signed else 'u64' elif burger_type == 'float': field_type_rs = 'f32' elif burger_type == 'double': @@ -24,10 +33,10 @@ def burger_type_to_rust_type(burger_type): elif burger_type == 'varint': is_var = True - field_type_rs = 'i32' + field_type_rs = 'i32' if should_be_signed else 'u32' elif burger_type == 'varlong': is_var = True - field_type_rs = 'i64' + field_type_rs = 'i64' if should_be_signed else 'u64' elif burger_type == 'boolean': field_type_rs = 'bool' @@ -39,7 +48,7 @@ def burger_type_to_rust_type(burger_type): uses.add('azalea_chat::component::Component') elif burger_type == 'identifier': field_type_rs = 'ResourceLocation' - uses.add('azalea_core::resource_location::ResourceLocation') + uses.add('azalea_core::ResourceLocation') elif burger_type == 'uuid': field_type_rs = 'Uuid' uses.add('uuid::Uuid') @@ -53,17 +62,82 @@ def burger_type_to_rust_type(burger_type): uses.add('azalea_core::Slot') elif burger_type == 'metadata': field_type_rs = 'EntityMetadata' - uses.add('crate::mc_buf::EntityMetadata') - elif burger_type == 'enum': - # enums are too complicated, leave those to the user + uses.add('azalea_entity::EntityMetadata') + elif burger_type == 'abstract': field_type_rs = 'todo!()' + elif burger_type == 'enum': + if not instruction or not mappings or not obfuscated_class_name: + field_type_rs = 'todo!("enum")' + else: + # generate the whole enum :) + print(instruction) + enum_field = instruction['field'] + # enums with a.b() as the field + if '.' in enum_field: + enum_first_part_name = mappings.get_field_type( + obfuscated_class_name, enum_field.split('.')[0]) + enum_first_part_obfuscated_name = mappings.get_class_from_deobfuscated_name( + enum_first_part_name) + print('enum_first_part_obfuscated_name', + enum_first_part_obfuscated_name) + enum_name = mappings.get_method_type( + enum_first_part_obfuscated_name, enum_field.split('.')[1].split('(')[0], '') + + print('hm', enum_name) + else: + enum_name = mappings.get_field_type( + obfuscated_class_name, enum_field) + print('enum_name', enum_name) + enum_obfuscated_name = mappings.get_class_from_deobfuscated_name( + enum_name) + print('enum_obfuscated_name', enum_obfuscated_name) + enum_variants = [] + for obfuscated_field_name in mappings.fields[enum_obfuscated_name]: + field_name = mappings.get_field( + enum_obfuscated_name, obfuscated_field_name) + + # get the type just to make sure it's actually a variant and not something else + field_type = mappings.get_field_type( + enum_obfuscated_name, obfuscated_field_name) + if field_type != enum_name: + continue + + enum_variants.append(field_name) + + field_type_rs = to_camel_case( + enum_name.split('.')[-1].split('$')[-1]) + extra_code.append('') + extra_code.append(f'#[derive(McBuf, Clone, Copy, Debug)]') + extra_code.append(f'pub enum {field_type_rs} {{') + for index, variant in enumerate(enum_variants): + extra_code.append( + f' {to_camel_case(variant.lower())}={index},') + extra_code.append('}') + elif burger_type.endswith('[]'): - field_type_rs, is_var, uses = burger_type_to_rust_type( + field_type_rs, is_var, uses, extra_code = burger_type_to_rust_type( burger_type[:-2]) field_type_rs = f'Vec<{field_type_rs}>' + + # sometimes burger gives us a slightly incorrect type + if mappings and instruction: + if field_type_rs == 'Vec': + field = instruction['field'] + if field.endswith('.copy()'): + field = field[:-7] + try: + array_type = mappings.get_field_type( + obfuscated_class_name, field) + except KeyError: + print('Error getting array type', field) + return field_type_rs, is_var, uses, extra_code + if array_type == 'net.minecraft.network.FriendlyByteBuf': + field_type_rs = 'UnsizedByteArray' + uses.add('azalea_buf::UnsizedByteArray') + else: raise Exception(f'Unknown field type: {burger_type}') - return field_type_rs, is_var, uses + return field_type_rs, is_var, uses, extra_code def write_packet_file(state, packet_name_snake_case, code): -- cgit v1.2.3