From 12a9c8ce65b58f0c600fd7b9fc5d454ce228b420 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Tue, 14 Mar 2023 16:33:03 -0500 Subject: 1.19.4 (#57) * 23w03a * 23w04a * 23w05a * 23w06a * fix * 23w07a mojang broke their json data generator so some stuff is missing * didn't mean to commit that file here * 1.19.4-pre2 * fix * 1.19.4-pre3 * fix * how did these packets get here * 1.19.4-pre4 * 1.19.4-rc1 * 1.19.4-rc2 * 1.19.4-rc3 * merge main * remove debugging code * 1.19.4 --- codegen/lib/code/entity.py | 178 +++++++++++++++++++++++++++++++-------------- 1 file changed, 124 insertions(+), 54 deletions(-) (limited to 'codegen/lib/code/entity.py') diff --git a/codegen/lib/code/entity.py b/codegen/lib/code/entity.py index e3e88edf..23a94c52 100644 --- a/codegen/lib/code/entity.py +++ b/codegen/lib/code/entity.py @@ -1,4 +1,6 @@ from lib.utils import to_camel_case, to_snake_case, get_dir_location, upper_first_letter +from lib.code.packet import burger_instruction_to_code +from lib.code.utils import burger_type_to_rust_type from lib.mappings import Mappings from typing import Optional import re @@ -6,35 +8,91 @@ import re METADATA_RS_DIR = get_dir_location( '../azalea-world/src/entity/metadata.rs') - -def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings): - # TODO: auto generate this and use it for generating the EntityDataValue enum - metadata_types = [ - {'name': 'Byte', 'type': 'u8'}, - {'name': 'Int', 'type': 'i32', 'var': True}, - {'name': 'Long', 'type': 'i64'}, - {'name': 'Float', 'type': 'f32'}, - {'name': 'String', 'type': 'String'}, - {'name': 'FormattedText', 'type': 'FormattedText'}, - {'name': 'OptionalFormattedText', 'type': 'Option'}, - {'name': 'ItemStack', 'type': 'Slot'}, - {'name': 'Boolean', 'type': 'bool'}, - {'name': 'Rotations', 'type': 'Rotations'}, - {'name': 'BlockPos', 'type': 'BlockPos'}, - {'name': 'OptionalBlockPos', 'type': 'Option'}, - {'name': 'Direction', 'type': 'Direction'}, - {'name': 'OptionalUuid', 'type': 'Option'}, - {'name': 'BlockState', 'type': 'BlockState'}, - {'name': 'CompoundTag', 'type': 'azalea_nbt::Tag'}, - {'name': 'Particle', 'type': 'Particle'}, - {'name': 'VillagerData', 'type': 'VillagerData'}, - {'name': 'OptionalUnsignedInt', 'type': 'OptionalUnsignedInt'}, - {'name': 'Pose', 'type': 'Pose'}, - {'name': 'CatVariant', 'type': 'azalea_registry::CatVariant'}, - {'name': 'FrogVariant', 'type': 'azalea_registry::FrogVariant'}, - {'name': 'GlobalPos', 'type': 'GlobalPos'}, - {'name': 'PaintingVariant', 'type': 'azalea_registry::PaintingVariant'} - ] +DATA_RS_DIR = get_dir_location( + '../azalea-world/src/entity/data.rs') + +def generate_metadata_names(burger_dataserializers: dict, mappings: Mappings): + serializer_names = [None] * len(burger_dataserializers) + for burger_serializer in burger_dataserializers.values(): + print(burger_serializer) + + # burger gives us the wrong class, so we do this instead + data_serializers_class = mappings.get_class_from_deobfuscated_name('net.minecraft.network.syncher.EntityDataSerializers') + mojmap_name = mappings.get_field(data_serializers_class, burger_serializer['field']).lower() + + if mojmap_name == 'component': + mojmap_name = 'formatted_text' + elif mojmap_name == 'optional_component': + mojmap_name = 'optional_formatted_text' + + serializer_names[burger_serializer['id']] = upper_first_letter(to_camel_case(mojmap_name)) + return serializer_names + +def parse_metadata_types_from_code(): + with open(DATA_RS_DIR, 'r') as f: + lines = f.read().splitlines() + + data = [] + + in_enum = False + for line in lines: + if line == 'pub enum EntityDataValue {': + in_enum = True + elif line == '}': + in_enum = False + elif in_enum: + line = line.strip() + if line.startswith('//'): continue + name, type = line.rstrip('),').split('(') + is_var = False + if type.startswith('#[var] '): + is_var = True + type = type[len('#[var] '):] + data.append({ + 'name': name, + 'type': type, + 'var': is_var + }) + print(data) + return data + +def generate_entity_metadata(burger_entities_data: dict, mappings: Mappings): + burger_entity_metadata = burger_entities_data['entity'] + + new_metadata_names = generate_metadata_names(burger_entities_data['dataserializers'], mappings) + parsed_metadata_types = parse_metadata_types_from_code() + + parsed_metadata_names = [] + for t in parsed_metadata_types: + parsed_metadata_names.append(t['name']) + + with open(DATA_RS_DIR, 'r') as f: + lines = f.read().splitlines() + # add the metadata names that weren't there before to the end of the enum. + # this technically might cause them to be in the wrong order but i decided + # making it correct while preserving comments was too annoying so i didn't + added_metadata_names = [] + for n in new_metadata_names: + if n not in parsed_metadata_names: + added_metadata_names.append(n) + if added_metadata_names != []: + in_enum = False + for i, line in enumerate(list(lines)): + if line == 'pub enum EntityDataValue {': + in_enum = True + elif in_enum and line == '}': + in_enum = False + for n in added_metadata_names: + lines.insert(i, f'{n}(TODO),') + i += 1 + print(lines) + with open(DATA_RS_DIR, 'w') as f: + f.write('\n'.join(lines)) + print('Expected metadata types:\n' + '\n'.join(new_metadata_names)) + print('Updated metadata types in azalea-world/src/entity/data.rs, go make sure they\'re correct and then press enter') + input() + + metadata_types = parse_metadata_types_from_code() code = [] code.append('''#![allow(clippy::single_match)] @@ -42,10 +100,12 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings): // This file is generated from codegen/lib/code/entity.py. // Don't change it manually! -use super::{EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Rotations, VillagerData}; -use azalea_block::BlockState; +use super::{ + EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion, Rotations, + SnifferState, VillagerData +}; use azalea_chat::FormattedText; -use azalea_core::{BlockPos, Direction, Particle, Slot}; +use azalea_core::{BlockPos, Direction, Particle, Slot, Vec3}; use bevy_ecs::{bundle::Bundle, component::Component}; use derive_more::{Deref, DerefMut}; use thiserror::Error; @@ -74,9 +134,9 @@ impl From for UpdateMetadataError { # build the duplicate_field_names set previous_field_names = set() duplicate_field_names = set() - for entity_id in burger_entity_data.keys(): + for entity_id in burger_entity_metadata.keys(): field_name_map[entity_id] = {} - for field_name_or_bitfield in get_entity_metadata_names(entity_id, burger_entity_data, mappings).values(): + for field_name_or_bitfield in get_entity_metadata_names(entity_id, burger_entity_metadata, mappings).values(): if isinstance(field_name_or_bitfield, str): if field_name_or_bitfield in previous_field_names: duplicate_field_names.add(field_name_or_bitfield) @@ -99,8 +159,8 @@ impl From for UpdateMetadataError { raise Exception(f'{name} should only exist once') # and now figure out what to rename them to - for entity_id in burger_entity_data.keys(): - for index, field_name_or_bitfield in get_entity_metadata_names(entity_id, burger_entity_data, mappings).items(): + for entity_id in burger_entity_metadata.keys(): + for index, field_name_or_bitfield in get_entity_metadata_names(entity_id, burger_entity_metadata, mappings).items(): if isinstance(field_name_or_bitfield, str): new_field_name = field_name_or_bitfield if new_field_name == 'type': @@ -129,14 +189,14 @@ impl From for UpdateMetadataError { return field_name_map[entity_ids_for_all_field_names_or_bitfields[index]][name] return name - parents = get_entity_parents(entity_id, burger_entity_data) + parents = get_entity_parents(entity_id, burger_entity_metadata) for parent_id in list(reversed(parents)): - for index, name_or_bitfield in get_entity_metadata_names(parent_id, burger_entity_data, mappings).items(): + for index, name_or_bitfield in get_entity_metadata_names(parent_id, burger_entity_metadata, mappings).items(): assert index == len(all_field_names_or_bitfields) all_field_names_or_bitfields.append(name_or_bitfield) entity_ids_for_all_field_names_or_bitfields.append(parent_id) entity_metadatas.extend(get_entity_metadata( - parent_id, burger_entity_data)) + parent_id, burger_entity_metadata)) parent_id = parents[1] if len(parents) > 1 else None # now add all the fields/component structs @@ -264,7 +324,7 @@ impl From for UpdateMetadataError { if parent_struct_name: code.append( f' parent: {parent_struct_name}MetadataBundle,') - for index, name_or_bitfield in get_entity_metadata_names(entity_id, burger_entity_data, mappings).items(): + for index, name_or_bitfield in get_entity_metadata_names(entity_id, burger_entity_metadata, mappings).items(): if isinstance(name_or_bitfield, str): name_or_bitfield = maybe_rename_field( name_or_bitfield, index) @@ -310,7 +370,7 @@ impl From for UpdateMetadataError { # if it has a parent, put it (do recursion) # parent: AbstractCreatureBundle { ... }, this_entity_parent_ids = get_entity_parents( - this_entity_id, burger_entity_data) + this_entity_id, burger_entity_metadata) this_entity_parent_id = this_entity_parent_ids[1] if len( this_entity_parent_ids) > 1 else None if this_entity_parent_id: @@ -322,7 +382,7 @@ impl From for UpdateMetadataError { code.append( ' },') - for index, name_or_bitfield in get_entity_metadata_names(this_entity_id, burger_entity_data, mappings).items(): + for index, name_or_bitfield in get_entity_metadata_names(this_entity_id, burger_entity_metadata, mappings).items(): default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get( 'default', 'Default::default()') if isinstance(name_or_bitfield, str): @@ -367,11 +427,21 @@ impl From for UpdateMetadataError { elif type_name == 'ItemStack': default = f'Slot::Present({default})' if default != 'Empty' else 'Slot::Empty' elif type_name == 'BlockState': - default = f'{default}' if default != 'Empty' else 'BlockState::AIR' + default = f'{default}' if default != 'Empty' else 'azalea_block::BlockState::AIR' + elif type_name == 'OptionalBlockState': + default = f'{default}' if default != 'Empty' else 'azalea_block::BlockState::AIR' elif type_name == 'OptionalFormattedText': default = f'Some({default})' if default != 'Empty' else 'None' elif type_name == 'CompoundTag': default = f'azalea_nbt::Tag::Compound({default})' if default != 'Empty' else 'azalea_nbt::Tag::Compound(Default::default())' + elif type_name == 'Quaternion': + default = f'Quaternion {{ x: {float(default["x"])}, y: {float(default["y"])}, z: {float(default["z"])}, w: {float(default["w"])} }}' + elif type_name == 'Vector3': + default = f'Vec3 {{ x: {float(default["x"])}, y: {float(default["y"])}, z: {float(default["z"])} }}' + elif type_name == 'Byte': + # in 1.19.4 TextOpacity is a -1 by default + if default < 0: + default += 128 if name in single_use_imported_types: code.append(f' {name}: {default},') else: @@ -395,7 +465,7 @@ impl From for UpdateMetadataError { code.append('') # parent_field_name = None - for entity_id in burger_entity_data: + for entity_id in burger_entity_metadata: new_entity(entity_id) # and now make the main apply_metadata @@ -419,7 +489,7 @@ impl From for UpdateMetadataError { items: Vec, ) -> Result<(), UpdateMetadataError> {{ match entity_kind {{''') - for entity_id in burger_entity_data: + for entity_id in burger_entity_metadata: if entity_id.startswith('~'): # not actually an entity continue @@ -446,7 +516,7 @@ impl From for UpdateMetadataError { code.append( 'pub fn apply_default_metadata(entity: &mut bevy_ecs::system::EntityCommands, kind: azalea_registry::EntityKind) {') code.append(' match kind {') - for entity_id in burger_entity_data: + for entity_id in burger_entity_metadata: if entity_id.startswith('~'): # not actually an entity continue @@ -464,22 +534,22 @@ impl From for UpdateMetadataError { f.write('\n'.join(code)) -def get_entity_parents(entity_id: str, burger_entity_data: dict): +def get_entity_parents(entity_id: str, burger_entity_metadata: dict): parents = [] while entity_id: parents.append(entity_id) - entity_id = get_entity_parent(entity_id, burger_entity_data) + entity_id = get_entity_parent(entity_id, burger_entity_metadata) return parents -def get_entity_parent(entity_id: str, burger_entity_data: dict): - entity_metadata = burger_entity_data[entity_id]['metadata'] +def get_entity_parent(entity_id: str, burger_entity_metadata: dict): + entity_metadata = burger_entity_metadata[entity_id]['metadata'] first_metadata = entity_metadata[0] return first_metadata.get('entity') -def get_entity_metadata(entity_id: str, burger_entity_data: dict): - entity_metadata = burger_entity_data[entity_id]['metadata'] +def get_entity_metadata(entity_id: str, burger_entity_metadata: dict): + entity_metadata = burger_entity_metadata[entity_id]['metadata'] entity_useful_metadata = [] for metadata_item in entity_metadata: if 'data' in metadata_item: @@ -494,8 +564,8 @@ def get_entity_metadata(entity_id: str, burger_entity_data: dict): # returns a dict of {index: (name or bitfield)} -def get_entity_metadata_names(entity_id: str, burger_entity_data: dict, mappings: Mappings): - entity_metadata = burger_entity_data[entity_id]['metadata'] +def get_entity_metadata_names(entity_id: str, burger_entity_metadata: dict, mappings: Mappings): + entity_metadata = burger_entity_metadata[entity_id]['metadata'] mapped_metadata_names = {} for metadata_item in entity_metadata: -- cgit v1.2.3