aboutsummaryrefslogtreecommitdiff
path: root/codegen/lib/code
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-03-25 11:17:39 -0500
committerGitHub <noreply@github.com>2025-03-25 11:17:39 -0500
commitef357fdf3667f3ded03203fc0f7cdec48a01ad8f (patch)
tree6e7429c62a22fec1988278f63554c93bdd905a5d /codegen/lib/code
parent8af265e48bf9f3d5263c074d034770e4216bb3f3 (diff)
downloadazalea-drasl-ef357fdf3667f3ded03203fc0f7cdec48a01ad8f.tar.xz
1.21.5 (#198)
* 25w02a * move item_components codegen to a different module * remove outdated test * 25w03a * start updating to 24w09b * 1.21.5-pre2 * fix broken packets * 1.21.5-rc2 * merge main * delete unused acket_handling * 1.21.5
Diffstat (limited to 'codegen/lib/code')
-rwxr-xr-xcodegen/lib/code/blocks.py7
-rw-r--r--codegen/lib/code/entity.py30
-rw-r--r--codegen/lib/code/item_components.py164
-rwxr-xr-xcodegen/lib/code/packet.py37
4 files changed, 217 insertions, 21 deletions
diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py
index 181ce774..aaa95ffa 100755
--- a/codegen/lib/code/blocks.py
+++ b/codegen/lib/code/blocks.py
@@ -33,8 +33,7 @@ def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blo
for property_id in list(block_data_report.get('properties', {}).keys()):
property_variants = block_data_report['properties'][property_id]
- property_struct_name = get_property_struct_name(
- block_id, property_id, property_variants)
+ property_struct_name = get_property_struct_name(block_id, property_id, property_variants)
if property_struct_name in properties:
if not properties[property_struct_name] == property_variants:
@@ -192,6 +191,10 @@ def get_property_struct_name(block_id: str, property_id: str, property_variants:
return 'TrialSpawnerState'
if property_variants == ['inactive', 'active', 'unlocking', 'ejecting']:
return 'VaultState'
+ if property_variants == ['start', 'log', 'fail', 'accept']:
+ return 'TestMode'
+ if property_variants == ['save', 'load', 'corner', 'data']:
+ return 'StructureMode'
if 'harp' in property_variants and 'didgeridoo' in property_variants:
return 'Sound'
if is_list_of_string_integers(property_variants):
diff --git a/codegen/lib/code/entity.py b/codegen/lib/code/entity.py
index a1f5525d..c27c4ce7 100644
--- a/codegen/lib/code/entity.py
+++ b/codegen/lib/code/entity.py
@@ -103,23 +103,24 @@ def generate_entity_metadata(burger_entities_data: dict, mappings: Mappings):
// This file is generated from codegen/lib/code/entity.py.
// Don't change it manually!
-use crate::particle::Particle;
-
-use super::{
- ArmadilloStateKind, EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion,
- Rotations, SnifferStateKind, VillagerData,
-};
use azalea_chat::FormattedText;
use azalea_core::{
direction::Direction,
position::{BlockPos, Vec3},
};
use azalea_inventory::ItemStack;
+use azalea_registry::DataRegistry;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use thiserror::Error;
use uuid::Uuid;
+use super::{
+ ArmadilloStateKind, EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Quaternion,
+ Rotations, SnifferStateKind, VillagerData,
+};
+use crate::particle::Particle;
+
#[derive(Error, Debug)]
pub enum UpdateMetadataError {
#[error("Wrong type ({0:?})")]
@@ -410,12 +411,15 @@ impl From<EntityDataValue> for UpdateMetadataError {
# some types don't have Default implemented
if type_name == 'CompoundTag':
default = 'simdnbt::owned::NbtCompound::default()'
- elif type_name == 'CatVariant':
- default = 'azalea_registry::CatVariant::Tabby'
- elif type_name == 'PaintingVariant':
- default = 'azalea_registry::PaintingVariant::Kebab'
- elif type_name == 'FrogVariant':
- default = 'azalea_registry::FrogVariant::Temperate'
+ # elif type_name == 'CatVariant':
+ # # TODO: the default should be Tabby but we don't have a way to get that from here
+ # default = 'azalea_registry::CatVariant::new_raw(0)'
+ # elif type_name == 'PaintingVariant':
+ # default = 'azalea_registry::PaintingVariant::Kebab'
+ # elif type_name == 'FrogVariant':
+ # default = 'azalea_registry::FrogVariant::Temperate'
+ elif type_name.endswith('Variant'):
+ default = f'azalea_registry::{type_name}::new_raw(0)'
elif type_name == 'VillagerData':
default = 'VillagerData { kind: azalea_registry::VillagerKind::Plains, profession: azalea_registry::VillagerProfession::None, level: 0 }'
else:
@@ -430,7 +434,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
default = f'BlockPos::new{default}'
elif type_name == 'OptionalBlockPos': # Option<BlockPos>
default = f'Some(BlockPos::new{default})' if default != 'Empty' else 'None'
- elif type_name == 'OptionalUuid':
+ elif type_name == 'OptionalLivingEntityReference':
default = f'Some(uuid::uuid!({default}))' if default != 'Empty' else 'None'
elif type_name == 'OptionalUnsignedInt':
default = f'OptionalUnsignedInt(Some({default}))' if default != 'Empty' else 'OptionalUnsignedInt(None)'
diff --git a/codegen/lib/code/item_components.py b/codegen/lib/code/item_components.py
new file mode 100644
index 00000000..3d4bf6a6
--- /dev/null
+++ b/codegen/lib/code/item_components.py
@@ -0,0 +1,164 @@
+import lib.code.inventory
+import lib.code.registry
+import lib.code.version
+import lib.code.packet
+import lib.code.utils
+import lib.code.tags
+import lib.download
+import lib.extract
+import lib.utils
+
+
+ITEM_COMPONENTS_DIR = 'azalea-inventory/src/components.rs'
+
+def generate(version_id: str):
+ expected_variants = get_expected_variants(version_id)
+ actual_variants = get_actual_variants()
+
+ new_variants = []
+ removed_variants = []
+
+ for variant in expected_variants:
+ if variant not in actual_variants:
+ new_variants.append(variant)
+ for variant in actual_variants:
+ if variant not in expected_variants:
+ removed_variants.append(variant)
+
+ print('New variants:')
+ for variant in new_variants:
+ print('-', variant)
+ print()
+ print('Removed variants:')
+ for variant in removed_variants:
+ print('-', variant)
+ print()
+
+ for variant in removed_variants:
+ print(f'Removing {variant}...')
+ remove_variant(variant)
+ for variant in new_variants:
+ print(f'Adding {variant}...')
+ add_variant(variant)
+
+ lib.code.utils.fmt()
+
+ print('Done!')
+
+def get_expected_variants(version_id: str):
+ expected_variants = []
+ registries = lib.extract.get_registries_report(version_id)
+
+ registry = registries['minecraft:data_component_type']
+ registry_entries = sorted(
+ registry['entries'].items(), key=lambda x: x[1]['protocol_id'])
+ for variant_name, _variant in registry_entries:
+ variant_struct_name = lib.utils.to_camel_case(variant_name.split(':')[-1])
+ expected_variants.append(variant_struct_name)
+
+ return expected_variants
+
+def get_actual_variants():
+ actual_variants = []
+ with open(ITEM_COMPONENTS_DIR, 'r') as f:
+ code = f.read().split('\n')
+
+ in_match = False
+ for line in code:
+ if in_match:
+ if line == ' })':
+ break
+ variant_line_prefix = ' DataComponentKind::'
+ if line.startswith(variant_line_prefix):
+ variant = line[len(variant_line_prefix):].split(' ', 1)[0]
+ actual_variants.append(variant)
+ elif line == ' Ok(match kind {':
+ in_match = True
+
+ return actual_variants
+
+def remove_variant(variant: str):
+ with open(ITEM_COMPONENTS_DIR, 'r') as f:
+ code = f.read().split('\n')
+
+ first_line_with_variant = None
+ line_after_variant = None
+
+ in_match = False
+ for i, line in enumerate(list(code)):
+ if in_match:
+ if line == ' })':
+ line_after_variant = i
+ break
+ variant_line_prefix = ' DataComponentKind::'
+ if line.startswith(variant_line_prefix):
+ if first_line_with_variant is not None:
+ line_after_variant = i
+ break
+ variant_name = line[len(variant_line_prefix):].split(' ', 1)[0]
+ if variant_name == variant:
+ first_line_with_variant = i
+ elif line == ' Ok(match kind {':
+ in_match = True
+
+ if first_line_with_variant is None:
+ raise ValueError(f'Variant {variant} not found')
+ if line_after_variant is None:
+ raise ValueError(f'Couldn\'t find end of variant {variant}')
+
+ code = code[:first_line_with_variant] + code[line_after_variant:]
+
+ # now remove the struct
+ line_before_struct = None # this is the #[derive] line
+ line_after_struct = None # impl DataComponent for ... {\n...\n}
+ for i, line in enumerate(list(code)):
+ if line == f'pub struct {variant} {{' or line == f'pub struct {variant};':
+ line_before_struct = i - 1
+ elif line == f'impl DataComponent for {variant} {{':
+ line_after_struct = i + 3
+ break
+ if line_before_struct is None:
+ raise ValueError(f'Couldn\'t find struct {variant}')
+ if line_after_struct is None:
+ raise ValueError(f'Couldn\'t find impl DataComponent for {variant}')
+
+ code = code[:line_before_struct] + code[line_after_struct:]
+
+ with open(ITEM_COMPONENTS_DIR, 'w') as f:
+ f.write('\n'.join(code))
+
+def add_variant(variant: str):
+ with open(ITEM_COMPONENTS_DIR, 'r') as f:
+ code = f.read().split('\n')
+
+ in_match = False
+ last_line_in_match = None
+ for i, line in enumerate(list(code)):
+ if in_match:
+ if line == ' })':
+ last_line_in_match = i
+ break
+ elif line == ' Ok(match kind {':
+ in_match = True
+
+ if last_line_in_match is None:
+ raise ValueError('Couldn\'t find end of match')
+
+ code = code[:last_line_in_match] + [
+ f' DataComponentKind::{variant} => Box::new({variant}::azalea_read(buf)?),',
+ ] + code[last_line_in_match:]
+
+ # now insert the struct
+ code.append('')
+ code.append('#[derive(Clone, PartialEq, AzBuf)]')
+ code.append(f'pub struct {variant} {{')
+ code.append(' pub todo: todo!(), // see DataComponents.java')
+ code.append('}')
+ code.append(f'impl DataComponent for {variant} {{')
+ code.append(f' const KIND: DataComponentKind = DataComponentKind::{variant};')
+ code.append('}')
+
+ with open(ITEM_COMPONENTS_DIR, 'w') as f:
+ f.write('\n'.join(code))
+
+ lib.code.utils.fmt()
diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py
index 1d60378a..5ae2d41f 100755
--- a/codegen/lib/code/packet.py
+++ b/codegen/lib/code/packet.py
@@ -14,6 +14,8 @@ MOJMAP_TO_AZALEA_STATE_NAME_MAPPING = {
}
AZALEA_TO_MOJMAP_STATE_NAME_MAPPING = {v: k for k, v in MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.items()}
+PACKETS_DIR = '../azalea-protocol/src/packets'
+
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]
@@ -24,7 +26,7 @@ def generate_packet(packets_report, packet_name, direction, state):
packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet'
packet_struct_name = to_camel_case(f'{direction}_{packet_name}')
- packet_module_name = f'{direction[0]}_{packet_name}'
+ packet_module_name = get_packet_module_name(packet_name, direction)
code.append(f'use azalea_buf::AzBuf;')
code.append(f'use azalea_protocol_macros::{packet_derive_name};')
@@ -42,11 +44,16 @@ def generate_packet(packets_report, packet_name, direction, state):
# 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):
+def get_packet_module_name(packet_name: str, direction: str):
+ return f'{direction[0]}_{packet_name}'
+
+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')
+
+ expected_packet_module_names = set()
+ state_dir = get_dir_location(f'{PACKETS_DIR}/{state}')
+ mod_rs_dir = get_dir_location(f'{state_dir}/mod.rs')
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', {}))
@@ -61,10 +68,12 @@ def set_packets(packets_report):
code.append(' Clientbound => [')
for packet_id, packet_name in enumerate(clientbound_packets):
code.append(f' {packet_name}, // {padded_hex(packet_id)}')
+ expected_packet_module_names.add(get_packet_module_name(packet_name, 'clientbound'))
code.append(' ],')
code.append(' Serverbound => [')
for packet_id, packet_name in enumerate(serverbound_packets):
code.append(f' {packet_name}, // {padded_hex(packet_id)}')
+ expected_packet_module_names.add(get_packet_module_name(packet_name, 'serverbound'))
code.append(' ]')
code.append(');')
code.append('')
@@ -72,6 +81,23 @@ def set_packets(packets_report):
with open(mod_rs_dir, 'w') as f:
f.write('\n'.join(code))
+ existing_packet_module_names = set()
+ # iterate over the directory
+ for file in os.listdir(state_dir):
+ if file.endswith('.rs') and file != 'mod.rs':
+ existing_packet_module_names.add(file[:-len('.rs')])
+ for packet_module_name in expected_packet_module_names - existing_packet_module_names:
+ direction = None
+ if packet_module_name.startswith('c_'):
+ direction = 'clientbound'
+ elif packet_module_name.startswith('s_'):
+ direction = 'serverbound'
+ else:
+ raise Exception(f'Invalid packet module name: {packet_module_name}')
+ packet = packet_module_name[2:]
+ generate_packet(packets_report, packet, direction, state)
+
+
def packet_direction_report_to_packet_names(report):
name_to_id = {}
for resource_location, packet in report.items():
@@ -82,8 +108,7 @@ def packet_direction_report_to_packet_names(report):
return names_sorted
def get_packets(direction: str, state: str):
- mod_rs_dir = get_dir_location(
- f'../azalea-protocol/src/packets/{state}/mod.rs')
+ mod_rs_dir = get_dir_location(f'{PACKETS_DIR}/{state}/mod.rs')
with open(mod_rs_dir, 'r') as f:
mod_rs = f.read().splitlines()