aboutsummaryrefslogtreecommitdiff
path: root/codegen/lib/code/packet.py
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2024-11-27 19:31:40 -0600
committerGitHub <noreply@github.com>2024-11-27 19:31:40 -0600
commit08958c2278b15ebeac8a964f392ebb792e479b61 (patch)
tree4ae3664cea38d7fd1a8f1e95ed06fac04ffe519e /codegen/lib/code/packet.py
parent139d77d3c2b0922fba5e9d4fa2bd9819d78bd773 (diff)
downloadazalea-drasl-08958c2278b15ebeac8a964f392ebb792e479b61.tar.xz
Refactor azalea-protocol (#190)
* start updating to 1.21.4 * fix block codegen and stop using block data from burger * rename packet related modules and structs to be simpler * ItemSlot -> ItemStack for more consistency with mojmap * .get() -> .into_packet() * simplify declare_state_packets by removing packet ids * rename read_from and write_into to azalea_read and azalea_write * rename McBufReadable and McBufWritable to AzaleaRead and AzaleaWrite * McBuf -> AzBuf * remove most uses of into_variant * update codegen and use resourcelocation names for packets * implement #[limit(i)] attribute for AzBuf derive macro * fixes for 1.21.4 * fix examples * update some physics code and fix ChatType * remove unused imports in codegen * re-add some things to migrate.py and update +mc version numbers automatically * downgrade to 1.21.3 lol
Diffstat (limited to 'codegen/lib/code/packet.py')
-rwxr-xr-xcodegen/lib/code/packet.py241
1 files changed, 71 insertions, 170 deletions
diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py
index b34d3455..71bc3a70 100755
--- a/codegen/lib/code/packet.py
+++ b/codegen/lib/code/packet.py
@@ -9,179 +9,80 @@ import re
def make_packet_mod_rs_line(packet_id: int, packet_class_name: str):
return f' {padded_hex(packet_id)}: {to_snake_case(packet_class_name)}::{to_camel_case(packet_class_name)},'
-
-def fix_state(state: str):
- return {'PLAY': 'game'}.get(state, state.lower())
-
-
-def generate_packet(burger_packets, mappings: Mappings, target_packet_id, target_packet_direction, target_packet_state):
- for packet in burger_packets.values():
- if packet['id'] != target_packet_id:
- continue
-
- direction = packet['direction'].lower() # serverbound or clientbound
- state = fix_state(packet['state'])
-
- if state != target_packet_state or direction != target_packet_direction:
- continue
-
- generated_packet_code = []
- uses = set()
- extra_code = []
-
- packet_derive_name = f'{to_camel_case(direction)}{to_camel_case(state)}Packet'
-
- generated_packet_code.append(
- f'#[derive(Clone, Debug, McBuf, {packet_derive_name})]')
- uses.add(f'azalea_protocol_macros::{packet_derive_name}')
- uses.add(f'azalea_buf::McBuf')
-
- obfuscated_class_name = packet['class'].split('.')[0]
- class_name = mappings.get_class(
- obfuscated_class_name).split('.')[-1]
- if '$' in class_name:
- class_name, extra_part = class_name.split('$')
- if class_name.endswith('Packet'):
- class_name = class_name[:-
- len('Packet')] + extra_part + 'Packet'
-
- generated_packet_code.append(
- f'pub struct {to_camel_case(class_name)} {{')
-
- # call burger_instruction_to_code for each instruction
- i = -1
- instructions = packet.get('instructions', [])
- while (i + 1) < len(instructions):
- i += 1
-
- if instructions[i]['operation'] == 'write':
- skip = burger_instruction_to_code(
- instructions, i, generated_packet_code, mappings, obfuscated_class_name, uses, extra_code)
- if skip:
- i += skip
- else:
- generated_packet_code.append(f'// TODO: {instructions[i]}')
-
- generated_packet_code.append('}')
-
- if uses:
- # empty line before the `use` statements
- generated_packet_code.insert(0, '')
- for use in uses:
- generated_packet_code.insert(0, f'use {use};')
- for line in extra_code:
- generated_packet_code.append(line)
-
- print(generated_packet_code)
- write_packet_file(state, to_snake_case(class_name),
- '\n'.join(generated_packet_code))
- print()
-
+MOJMAP_TO_AZALEA_STATE_NAME_MAPPING = {
+ # shorter name, i like it more
+ 'configuration': 'config',
+ # in the files mojang calls the directory "game" so we do that too
+ 'play': 'game'
+}
+AZALEA_TO_MOJMAP_STATE_NAME_MAPPING = {v: k for k, v in MOJMAP_TO_AZALEA_STATE_NAME_MAPPING.items()}
+
+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]
+
+ code = []
+ uses = set()
+
+ 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}'
+
+ code.append(f'use azalea_buf::AzBuf;')
+ code.append(f'use azalea_protocol_macros::{packet_derive_name};')
+ code.append('')
+
+ code.append(
+ f'#[derive(Clone, Debug, AzBuf, {packet_derive_name})]')
+ code.append(
+ f'pub struct {packet_struct_name} {{')
+ code.append(' TODO')
+ code.append('}')
+
+ print(code)
+ write_packet_file(state, packet_module_name, '\n'.join(code))
+
+ # 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):
+ 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')
- with open(mod_rs_dir, 'r') as f:
- mod_rs = f.read().splitlines()
-
- pub_mod_line = f'pub mod {to_snake_case(class_name)};'
- if pub_mod_line not in mod_rs:
- mod_rs.insert(0, pub_mod_line)
- packet_mod_rs_line = make_packet_mod_rs_line(
- packet['id'], class_name)
-
- in_serverbound = False
- in_clientbound = False
- for i, line in enumerate(mod_rs):
- if line.strip() == 'Serverbound => {':
- in_serverbound = True
- continue
- elif line.strip() == 'Clientbound => {':
- in_clientbound = True
- continue
- elif line.strip() in ('}', '},'):
- if (in_serverbound and direction == 'serverbound') or (in_clientbound and direction == 'clientbound'):
- mod_rs.insert(i, packet_mod_rs_line)
- break
- in_serverbound = in_clientbound = False
- continue
-
- if line.strip() == '' or line.strip().startswith('//') or (not in_serverbound and direction == 'serverbound') or (not in_clientbound and direction == 'clientbound'):
- continue
-
- line_packet_id_hex = line.strip().split(':')[0]
- assert line_packet_id_hex.startswith('0x')
- line_packet_id = int(line_packet_id_hex[2:], 16)
- if line_packet_id > packet['id']:
- mod_rs.insert(i, packet_mod_rs_line)
- break
-
- with open(mod_rs_dir, 'w') as f:
- f.write('\n'.join(mod_rs))
-
-
-def set_packets(packet_ids: list[int], packet_class_names: list[str], direction: str, state: str):
- assert len(packet_ids) == len(packet_class_names)
-
- # ids are repeated
- assert len(packet_ids) == len(set(packet_ids))
-
- # sort the packets by id
- 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 = 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 = []
-
- required_modules = []
-
- ignore_lines = False
-
- for line in mod_rs:
- if line.strip() == 'Serverbound => {':
- new_mod_rs.append(line)
- if direction == 'serverbound':
- ignore_lines = True
- for packet_id, packet_class_name in zip(packet_ids, packet_class_names):
- 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
- elif line.strip() == 'Clientbound => {':
- new_mod_rs.append(line)
- if direction == 'clientbound':
- ignore_lines = True
- for packet_id, packet_class_name in zip(packet_ids, packet_class_names):
- 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
- elif line.strip() in ('}', '},'):
- ignore_lines = False
- elif line.strip().startswith('pub mod '):
- continue
-
- if not ignore_lines:
- new_mod_rs.append(line)
- # 0x00: clientbound_status_response_packet::ClientboundStatusResponsePacket,
- if line.strip().startswith('0x'):
- required_modules.append(
- line.strip().split(':')[1].split('::')[0].strip())
-
- for i, required_module in enumerate(required_modules):
- if required_module not in mod_rs:
- new_mod_rs.insert(i, f'pub mod {required_module};')
-
- with open(mod_rs_dir, 'w') as f:
- f.write('\n'.join(new_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', {}))
+
+ code = []
+ code.append('// NOTE: This file is generated automatically by codegen/packet.py.')
+ code.append("// Don't edit it directly!")
+ code.append('')
+ code.append('use azalea_protocol_macros::declare_state_packets;')
+ code.append('')
+ code.append(f'declare_state_packets!({to_camel_case(state)}Packet,')
+ code.append(' Clientbound => [')
+ for packet_name in clientbound_packets:
+ code.append(f' {packet_name},')
+ code.append(' ],')
+ code.append(' Serverbound => [')
+ for packet_name in serverbound_packets:
+ code.append(f' {packet_name},')
+ code.append(' ]')
+ code.append(');')
+ code.append('')
+
+ with open(mod_rs_dir, 'w') as f:
+ f.write('\n'.join(code))
+
+def packet_direction_report_to_packet_names(report):
+ name_to_id = {}
+ for resource_location, packet in report.items():
+ packet_id = packet['protocol_id']
+ name_to_id[resource_location.split(':')[-1]] = packet_id
+
+ names_sorted = [name for name in sorted(name_to_id, key=lambda x: name_to_id[x])]
+ return names_sorted
def get_packets(direction: str, state: str):
mod_rs_dir = get_dir_location(