aboutsummaryrefslogtreecommitdiff
path: root/codegen/lib
diff options
context:
space:
mode:
Diffstat (limited to 'codegen/lib')
-rwxr-xr-xcodegen/lib/code/blocks.py13
-rw-r--r--codegen/lib/code/entity.py18
-rw-r--r--codegen/lib/code/language.py8
-rwxr-xr-xcodegen/lib/code/packet.py3
-rwxr-xr-xcodegen/lib/code/registry.py41
-rwxr-xr-xcodegen/lib/code/shapes.py65
-rwxr-xr-xcodegen/lib/code/utils.py6
-rwxr-xr-xcodegen/lib/download.py14
-rwxr-xr-xcodegen/lib/extract.py242
9 files changed, 288 insertions, 122 deletions
diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py
index c32a3bbc..d5fca732 100755
--- a/codegen/lib/code/blocks.py
+++ b/codegen/lib/code/blocks.py
@@ -20,7 +20,6 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: li
new_make_block_states_macro_code = []
new_make_block_states_macro_code.append('make_block_states! {')
-
# Find properties
properties = {}
@@ -84,7 +83,6 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: li
new_make_block_states_macro_code.append(
f' "{property_name}" => {property_shape_code},')
-
new_make_block_states_macro_code.append(' },')
# Block codegen
@@ -101,7 +99,6 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: li
if state.get('default'):
default_property_variants = state.get('properties', {})
-
properties_code = '{'
for property_name in list(block_data_report.get('properties', {}).keys()):
property_burger = None
@@ -163,6 +160,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: li
with open(BLOCKS_RS_DIR, 'w') as f:
f.write('\n'.join(new_code))
+
def get_property_struct_name(property: Optional[dict], block_data_burger: dict, property_variants: list[str], mappings: Mappings) -> str:
# these are hardcoded because otherwise they cause conflicts
# some names inspired by https://github.com/feather-rs/feather/blob/main/feather/blocks/src/generated/table.rs
@@ -184,16 +182,23 @@ def get_property_struct_name(property: Optional[dict], block_data_burger: dict,
return 'ChestType'
if property_variants == ['compare', 'subtract']:
return 'ComparatorType'
+ if 'harp' in property_variants and 'didgeridoo' in property_variants:
+ return 'Sound'
if property is None:
return ''.join(map(to_camel_case, property_variants))
- property_name = None
for class_name in [block_data_burger['class']] + block_data_burger['super']:
property_name = mappings.get_field(
class_name, property['field_name'])
if property_name:
break
+ if property_name is None:
+ if 'declared_in' in property:
+ property_name = mappings.get_field(
+ property['declared_in'], property['field_name'])
+ if property_name is None:
+ property_name = property['name']
assert property_name
property_name = to_camel_case(property_name.lower())
if property['type'] == 'int':
diff --git a/codegen/lib/code/entity.py b/codegen/lib/code/entity.py
index 9b976ef6..6616c8d7 100644
--- a/codegen/lib/code/entity.py
+++ b/codegen/lib/code/entity.py
@@ -11,7 +11,8 @@ 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'},
+ {'name': 'Int', 'type': 'i32', 'var': True},
+ {'name': 'Long', 'type': 'i64'},
{'name': 'Float', 'type': 'f32'},
{'name': 'String', 'type': 'String'},
{'name': 'Component', 'type': 'Component'},
@@ -23,11 +24,11 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
{'name': 'OptionalBlockPos', 'type': 'Option<BlockPos>'},
{'name': 'Direction', 'type': 'Direction'},
{'name': 'OptionalUuid', 'type': 'Option<Uuid>'},
- {'name': 'OptionalBlockState', 'type': 'Option<BlockState>'},
+ {'name': 'BlockState', 'type': 'BlockState'},
{'name': 'CompoundTag', 'type': 'azalea_nbt::Tag'},
{'name': 'Particle', 'type': 'Particle'},
{'name': 'VillagerData', 'type': 'VillagerData'},
- {'name': 'OptionalUnsignedInt', 'type': 'Option<u32>'},
+ {'name': 'OptionalUnsignedInt', 'type': 'OptionalUnsignedInt'},
{'name': 'Pose', 'type': 'Pose'},
{'name': 'CatVariant', 'type': 'azalea_registry::CatVariant'},
{'name': 'FrogVariant', 'type': 'azalea_registry::FrogVariant'},
@@ -40,7 +41,8 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
code.append("// Don't change it manually!")
code.append('')
code.append('#![allow(clippy::clone_on_copy, clippy::derivable_impls)]')
- code.append('use super::{EntityDataValue, Rotations, VillagerData, Pose};')
+ code.append(
+ 'use super::{EntityDataValue, Rotations, VillagerData, OptionalUnsignedInt, Pose};')
code.append('use azalea_block::BlockState;')
code.append('use azalea_chat::Component;')
code.append('use azalea_core::{BlockPos, Direction, Particle, Slot};')
@@ -185,6 +187,8 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
default = 'azalea_registry::PaintingVariant::Kebab'
elif type_name == 'FrogVariant':
default = 'azalea_registry::FrogVariant::Temperate'
+ elif type_name == 'VillagerData':
+ default = 'VillagerData { kind: azalea_registry::VillagerType::Plains, profession: azalea_registry::VillagerProfession::None, level: 0 }'
else:
default = 'Default::default()'
else:
@@ -200,11 +204,11 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
elif type_name == 'OptionalUuid':
default = f'Some(uuid::uuid!({default}))' if default != 'Empty' else 'None'
elif type_name == 'OptionalUnsignedInt':
- default = f'Some({default})' if default != 'Empty' else 'None'
+ default = f'OptionalUnsignedInt(Some({default}))' if default != 'Empty' else 'OptionalUnsignedInt(None)'
elif type_name == 'ItemStack':
default = f'Slot::Present({default})' if default != 'Empty' else 'Slot::Empty'
- elif type_name == 'OptionalBlockState':
- default = f'Some({default})' if default != 'Empty' else 'None'
+ elif type_name == 'BlockState':
+ default = f'{default}' if default != 'Empty' else 'BlockState::Air'
elif type_name == 'OptionalComponent':
default = f'Some({default})' if default != 'Empty' else 'None'
elif type_name == 'CompoundTag':
diff --git a/codegen/lib/code/language.py b/codegen/lib/code/language.py
new file mode 100644
index 00000000..d27dde81
--- /dev/null
+++ b/codegen/lib/code/language.py
@@ -0,0 +1,8 @@
+from lib.utils import get_dir_location
+import json
+
+LANGUAGE_DIR = get_dir_location('../azalea-language/src/en_us.json')
+
+def write_language(contents: dict):
+ with open(LANGUAGE_DIR, 'w') as f:
+ f.write(json.dumps(contents, indent=' ')) \ No newline at end of file
diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py
index 4beccd35..48572aed 100755
--- a/codegen/lib/code/packet.py
+++ b/codegen/lib/code/packet.py
@@ -247,9 +247,10 @@ def burger_instruction_to_code(instructions: list[dict], index: int, generated_p
# figure out what kind of iterator it is
loop_instructions = next_next_instruction['instructions']
if len(loop_instructions) == 2:
- entry_type_rs, is_var, uses, extra_code = burger_type_to_rust_type(
+ entry_type_rs, is_var, value_uses, extra_code = burger_type_to_rust_type(
loop_instructions[1]['type'], None, loop_instructions[1], mappings, obfuscated_class_name)
field_type_rs = f'Vec<{entry_type_rs}>'
+ uses.update(value_uses)
elif len(loop_instructions) == 3:
is_map = loop_instructions[0]['type'].startswith(
'Map.Entry<')
diff --git a/codegen/lib/code/registry.py b/codegen/lib/code/registry.py
index c22eefe9..4df82c09 100755
--- a/codegen/lib/code/registry.py
+++ b/codegen/lib/code/registry.py
@@ -9,8 +9,45 @@ REGISTRIES_DIR = get_dir_location('../azalea-registry/src/lib.rs')
def generate_registries(registries: dict):
code = []
- code.append('use azalea_registry_macros::registry;')
- code.append('')
+ code.append('''// This file is automatically generated in codegen/lib/code/registry.py
+
+use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
+use azalea_registry_macros::registry;
+use std::io::{Cursor, Write};
+
+pub trait Registry
+where
+ Self: Sized,
+{
+ fn from_u32(value: u32) -> Option<Self>;
+ fn to_u32(&self) -> u32;
+}
+
+/// A registry that might not be present. This is transmitted as a single
+/// varint in the protocol.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct OptionalRegistry<T: Registry>(Option<T>);
+
+impl<T: Registry> McBufReadable for OptionalRegistry<T> {
+ fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
+ Ok(OptionalRegistry(match u32::var_read_from(buf)? {
+ 0 => None,
+ value => Some(
+ T::from_u32(value - 1)
+ .ok_or(BufReadError::UnexpectedEnumVariant { id: value as i32 })?,
+ ),
+ }))
+ }
+}
+impl<T: Registry> McBufWritable for OptionalRegistry<T> {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ match &self.0 {
+ None => 0u32.var_write_into(buf),
+ Some(value) => (value.to_u32() + 1).var_write_into(buf),
+ }
+ }
+}
+''')
for registry_name, registry in registries.items():
# registry!(Block, {
diff --git a/codegen/lib/code/shapes.py b/codegen/lib/code/shapes.py
index 83521dac..06170552 100755
--- a/codegen/lib/code/shapes.py
+++ b/codegen/lib/code/shapes.py
@@ -7,8 +7,8 @@ COLLISION_BLOCKS_RS_DIR = get_dir_location(
'../azalea-physics/src/collision/blocks.rs')
-def generate_block_shapes(blocks: dict, shapes: dict, block_states_report, block_datas_burger, mappings: Mappings):
- blocks, shapes = simplify_shapes(blocks, shapes)
+def generate_block_shapes(blocks: dict, shapes: dict, aabbs: dict, block_states_report, block_datas_burger, mappings: Mappings):
+ blocks, shapes = simplify_shapes(blocks, shapes, aabbs)
code = generate_block_shapes_code(
blocks, shapes, block_states_report, block_datas_burger, mappings)
@@ -16,33 +16,54 @@ def generate_block_shapes(blocks: dict, shapes: dict, block_states_report, block
f.write(code)
-def simplify_shapes(blocks: dict, shapes: dict):
- shape_to_new_id = {}
+def simplify_shapes(blocks: dict, shapes: dict, aabbs: dict):
new_id_increment = 0
new_shapes = {}
old_id_to_new_id = {}
- for shape_id, shape in sorted(shapes.items(), key=lambda shape: int(shape[0])):
- # tuples are hashable
- shape_as_tuple = tuple(map(tuple, shape))
- if shape_as_tuple not in shape_to_new_id:
- shape_to_new_id[shape_as_tuple] = new_id_increment
- old_id_to_new_id[shape_id] = new_id_increment
- new_shapes[new_id_increment] = shape
- new_id_increment += 1
- else:
- old_id_to_new_id[shape_id] = shape_to_new_id[shape_as_tuple]
+ old_id_to_new_id[None] = 0
+ new_shapes[0] = ()
+ new_id_increment += 1
+
+ used_shape_ids = set()
+ # determine the used shape ids
+ for block_id, block_data in blocks.items():
+ block_id = block_id.split(':')[-1]
+ block_shapes = [state.get('collision_shape')
+ for state in block_data['states'].values()]
+ for s in block_shapes:
+ used_shape_ids.add(s)
+
+ for shape_id, shape in enumerate(shapes):
+ if shape_id not in used_shape_ids: continue
+ # pixlyzer gives us shapes as an index or list of indexes into the
+ # aabbs list
+ # and aabbs look like { "from": number or [x, y, z], "to": (number or vec3) }
+ # convert them to [x1, y1, z1, x2, y2, z2]
+ shape = [shape] if isinstance(shape, int) else shape
+ shape = [aabbs[shape_aabb] for shape_aabb in shape]
+ shape = tuple([(
+ (tuple(part['from']) if isinstance(
+ part['from'], list) else ((part['from'],)*3))
+ + (tuple(part['to']) if isinstance(part['to'], list)
+ else ((part['to'],)*3))
+ ) for part in shape])
+
+ old_id_to_new_id[shape_id] = new_id_increment
+ new_shapes[new_id_increment] = shape
+ new_id_increment += 1
# now map the blocks to the new shape ids
- for block_id, shape_ids in blocks.items():
- if isinstance(shape_ids, int):
- blocks[block_id] = old_id_to_new_id[str(shape_ids)]
- else:
- blocks[block_id] = [old_id_to_new_id[str(shape_id)]
- for shape_id in shape_ids]
+ new_blocks = {}
+ for block_id, block_data in blocks.items():
+ block_id = block_id.split(':')[-1]
+ block_shapes = [state.get('collision_shape')
+ for state in block_data['states'].values()]
+ new_blocks[block_id] = [old_id_to_new_id[shape_id]
+ for shape_id in block_shapes]
- return blocks, new_shapes
+ return new_blocks, new_shapes
def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, block_datas_burger, mappings: Mappings):
@@ -116,7 +137,7 @@ def generate_code_for_shape(shape_id: str, parts: list[list[float]]):
code = ''
code += f'static SHAPE{shape_id}: Lazy<VoxelShape> = Lazy::new(|| {{'
steps = []
- if parts == []:
+ if parts == ():
steps.append('collision::empty_shape()')
else:
steps.append(f'collision::box_shape({make_arguments(parts[0])})')
diff --git a/codegen/lib/code/utils.py b/codegen/lib/code/utils.py
index 66b18eed..5550cdb2 100755
--- a/codegen/lib/code/utils.py
+++ b/codegen/lib/code/utils.py
@@ -63,6 +63,12 @@ def burger_type_to_rust_type(burger_type, field_name: Optional[str] = None, inst
elif burger_type == 'metadata':
field_type_rs = 'EntityMetadata'
uses.add('azalea_entity::EntityMetadata')
+ elif burger_type == 'bitset':
+ if instruction:
+ length = instruction['length']
+ field_type_rs = f'todo!("fixed bitset of length {length}")'
+ else:
+ field_type_rs = 'todo!("fixed bitset")'
elif burger_type == 'abstract':
field_type_rs = 'todo!()'
elif burger_type == 'enum':
diff --git a/codegen/lib/download.py b/codegen/lib/download.py
index 5988f8ec..aec3a648 100755
--- a/codegen/lib/download.py
+++ b/codegen/lib/download.py
@@ -19,15 +19,15 @@ def get_burger():
f'cd {get_dir_location("downloads")} && git clone https://github.com/pokechu22/Burger && cd Burger && git pull')
print('\033[92mInstalling dependencies...\033[m')
- os.system('cd downloads/Burger && pip install six jawa')
+ os.system(f'cd {get_dir_location("downloads")}/Burger && pip install six jawa')
-def get_generator_mod():
- if not os.path.exists(get_dir_location('downloads/minecraft-data-generator-server')):
- print('\033[92mDownloading u9g/minecraft-data-generator-server...\033[m')
+def get_pixlyzer():
+ if not os.path.exists(get_dir_location('downloads/pixlyzer')):
+ print('\033[92mDownloading bixilon/pixlyzer...\033[m')
os.system(
- f'cd {get_dir_location("downloads")} && git clone https://github.com/u9g/minecraft-data-generator-server && cd minecraft-data-generator-server && git pull')
- return get_dir_location('downloads/minecraft-data-generator-server')
+ f'cd {get_dir_location("downloads")} && git clone https://gitlab.bixilon.de/bixilon/pixlyzer.git && cd pixlyzer && git pull')
+ return get_dir_location('downloads/pixlyzer')
def get_version_manifest():
@@ -180,4 +180,4 @@ def clear_version_cache():
os.system(
f'cd {get_dir_location("downloads/Burger")} && git pull')
os.system(
- f'cd {get_dir_location("downloads/minecraft-data-generator-server")} && git pull')
+ f'cd {get_dir_location("downloads/pixlyzer")} && git pull')
diff --git a/codegen/lib/extract.py b/codegen/lib/extract.py
index e66b9400..7cbeff30 100755
--- a/codegen/lib/extract.py
+++ b/codegen/lib/extract.py
@@ -1,9 +1,11 @@
# Extracting data from the Minecraft jars
-from lib.download import get_server_jar, get_burger, get_client_jar, get_generator_mod, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
+from lib.download import get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
from lib.utils import get_dir_location
+from zipfile import ZipFile
import subprocess
import json
+import sys
import re
import os
@@ -59,103 +61,185 @@ def determine_python_command():
'Couldn\'t determine python command to use to run burger with!')
+def run_python_command_and_download_deps(command):
+ print('>', command)
+ for _ in range(10):
+ p = subprocess.Popen(
+ command,
+ stderr=subprocess.PIPE,
+ shell=True
+ )
+
+ stderr = b''
+ while True:
+ data = p.stderr.read()
+ if data == b'':
+ break
+ print(data.decode(), end='', flush=True)
+ stderr += data
+
+ regex_match = re.search(
+ r'ModuleNotFoundError: No module named \'(\w+?)\'', stderr.decode())
+ if not regex_match:
+ out, err = p.communicate()
+ if out:
+ print(out)
+ if err:
+ print(err)
+ break
+ missing_lib = regex_match.group(1)
+ print('Missing required lib:', missing_lib)
+ os.system(
+ f'{determine_python_command()} -m pip install {missing_lib}')
+ print('ok')
+
+
def get_burger_data_for_version(version_id: str):
if not os.path.exists(get_dir_location(f'downloads/burger-{version_id}.json')):
get_burger()
get_client_jar(version_id)
- for _ in range(10):
- r = subprocess.run(
- f'cd {get_dir_location("downloads/Burger")} && {determine_python_command()} munch.py ../client-{version_id}.jar --output ../burger-{version_id}.json',
- capture_output=True,
- shell=True
- )
- regex_match = re.search(
- r'ModuleNotFoundError: No module named \'(\w+?)\'', r.stderr.decode())
- if not regex_match:
- break
- missing_lib = regex_match.group(1)
- print('Missing required lib for Burger:', missing_lib)
- os.system(
- f'{determine_python_command()} -m pip install {missing_lib}')
+ print('\033[92mRunning Burger...\033[m')
+ run_python_command_and_download_deps(
+ f'cd {get_dir_location("downloads/Burger")} && {determine_python_command()} munch.py {get_dir_location("downloads")}/client-{version_id}.jar --output {get_dir_location("downloads")}/burger-{version_id}.json'
+ )
with open(get_dir_location(f'downloads/burger-{version_id}.json'), 'r') as f:
return json.load(f)
-def get_generator_mod_data(version_id: str, category: str):
+def get_pixlyzer_data(version_id: str, category: str):
'''
- Gets data from u9g's data generator mod. Note that this is not very stable, and it requires Yarn to release updates first.
+ Gets data from Pixlyzer. Note that this requires Yarn to release updates first.
'''
- target_dir = get_dir_location(f'downloads/generator-mod-{version_id}')
+ target_dir = get_dir_location(f'downloads/pixlyzer-{version_id}')
if not os.path.exists(get_dir_location(target_dir)):
- generator_mod_dir = get_generator_mod()
-
- yarn_data = get_yarn_data(version_id)
- if not yarn_data:
- raise Exception(
- 'Fabric/Yarn hasn\'t been updated to this version yet.')
- # looks like 1.19+build.1
- yarn_version = yarn_data['version']
-
- fabric_api_version = get_fabric_api_versions()[-1]
- fabric_loader_version = get_fabric_loader_versions()[0]
-
- # the mod has the minecraft version hard-coded by default, so we just change the gradle.properties and fabric.mod.json
- with open(get_dir_location(f'{generator_mod_dir}/gradle.properties'), 'r') as f:
- lines = f.readlines()
- with open(get_dir_location(f'{generator_mod_dir}/gradle.properties'), 'w') as f:
- for line in lines:
- if line.startswith('minecraft_version='):
- line = f'minecraft_version={version_id}\n'
- if line.startswith('yarn_mappings='):
- line = f'yarn_mappings={yarn_version}\n'
- if line.startswith('fabric_version='):
- line = f'fabric_version={fabric_api_version}\n'
- if line.startswith('loader_version='):
- line = f'loader_version={fabric_loader_version}\n'
- f.write(line)
- # edit the fabric.mod.json to support this version
- with open(get_dir_location(f'{generator_mod_dir}/src/main/resources/fabric.mod.json'), 'r') as f:
- fabric_mod_json = json.load(f)
- fabric_mod_json['depends']['minecraft'] = '*'
- with open(get_dir_location(f'{generator_mod_dir}/src/main/resources/fabric.mod.json'), 'w') as f:
- json.dump(fabric_mod_json, f, indent=2)
-
- try:
- os.system(f'cd {generator_mod_dir} && chmod u+x ./gradlew')
- except:
- pass
-
- # set the server port to something other than 25565 so it doesn't
- # conflict with anything else that's running
- try:
- os.makedirs(get_dir_location(f'{generator_mod_dir}/run'))
- except:
- pass
- with open(get_dir_location(f'{generator_mod_dir}/run/server.properties'), 'w') as f:
- f.write('server-port=56553')
-
- # make sure we have perms to run this file
- # (on windows it fails but keeps running)
- os.system(f'cd {generator_mod_dir} && chmod u+x ./gradlew')
- try:
- subprocess.run(
- [f'cd {generator_mod_dir} && ./gradlew runServer'],
- check=True,
- shell=True
- )
- except Exception as e:
- os.system(f'cd {generator_mod_dir} && gradlew runServer')
+ pixlyzer_dir = get_pixlyzer()
+ # for some reason pixlyzer doesn't work right unless the mvn clean
+ # instruction looks like that
+ # and pixlyzer.py doesn't do it right
+
+ # map jar + download dependencies
+ run_python_command_and_download_deps(
+ f'cd {pixlyzer_dir}/wrapper && {determine_python_command()} PixLyzer.py --only-version={version_id} --dont-compile --only-map'
+ )
+ # update the pom.xml <dependencies>
+ # list directories in pixlyzer/wrapper/data/data/dependencies/libraries
+ pom_xml_dependencies = '''<dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-test-junit</artifactId>
+ <version>1.7.21</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib-jdk8</artifactId>
+ <version>1.7.21</version>
+ </dependency>
+
+ <dependency>
+ <groupId>net.minecraft</groupId>
+ <artifactId>client</artifactId>
+ <version>${minecraft.version}</version>
+ <scope>system</scope>
+ <systemPath>${project.basedir}/wrapper/data/data/${minecraft.version}_yarn/${minecraft.version}-exhibitionism.jar</systemPath>
+ </dependency>
+ <dependency>
+ <groupId>de.bixilon</groupId>
+ <artifactId>mbf-kotlin</artifactId>
+ <version>0.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.objenesis</groupId>
+ <artifactId>objenesis</artifactId>
+ <version>3.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.12.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.14.0</version>
+ </dependency>
+ <dependency>
+ <groupId>de.bixilon</groupId>
+ <artifactId>kutil</artifactId>
+ <version>1.17.1</version>
+ </dependency>'''
+ # walk dir f'{pixlyzer_dir}/wrapper/data/data/dependencies/libraries'
+ for root, dirs, files in os.walk(f'{pixlyzer_dir}/wrapper/data/data/dependencies/libraries'):
+ for file in files:
+ full_path = os.path.join(
+ root.replace('\\', '/').replace(
+ f'{pixlyzer_dir}/wrapper/data/data/dependencies/libraries/'.replace('\\', '/'), ''),
+ file
+ ).replace('\\', '/')
+ print(full_path)
+ if not full_path.endswith('.jar'):
+ continue
+ split_path = full_path.split('/')
+ group = ''
+ for group_index in range(0, len(split_path) - 3):
+ group += split_path[group_index] + '.'
+ if group.endswith('.'):
+ group = group[:-1]
+ artifact = split_path[-3]
+ version = split_path[-2]
+ path = '${project.basedir}/wrapper/data/data/dependencies/libraries/' + full_path
+ pom_xml_dependencies += """
+ <dependency>
+ <groupId>""" + group + """</groupId>
+ <artifactId>""" + artifact + """</artifactId>
+ <version>""" + version + """</version>
+ <scope>system</scope>
+ <systemPath>""" + path + """</systemPath>
+ </dependency>
+ """
+ print('pom_xml_dependencies', pom_xml_dependencies)
+ assert pom_xml_dependencies != ''
+ pom_xml = open(f'{pixlyzer_dir}/pom.xml', 'r').read()
+ pom_xml = re.sub(
+ '<dependencies>.*?</dependencies>', f'<dependencies>{pom_xml_dependencies}</dependencies>', pom_xml, flags=re.DOTALL)
+ open(f'{pixlyzer_dir}/pom.xml', 'w').write(pom_xml)
+
+ # compile
+ os.system(
+ f'cd {pixlyzer_dir} && mvn clean -Dmaven.repo.local=. verify')
+ # run pixlyzer.py again lol
+ run_python_command_and_download_deps(
+ f'cd {pixlyzer_dir}/wrapper && {determine_python_command()} PixLyzer.py --only-version={version_id} --no-compile'
+ )
+
+ source_dir = get_dir_location(
+ f'{pixlyzer_dir}/wrapper/data/version/{version_id}')
+
+ if not os.path.exists(source_dir):
+ print('PixLyzer failed, no output!')
+ exit()
if os.path.exists(target_dir):
os.unlink(target_dir)
os.rename(
- get_dir_location(
- f'{generator_mod_dir}/run/minecraft-data/{version_id}'),
+ source_dir,
target_dir
)
- with open(f'{target_dir}/{category}.json', 'r') as f:
+ with open(f'{target_dir}/{category}.min.json', 'r') as f:
return json.load(f)
+
+
+def get_file_from_jar(version_id: str, file_dir: str):
+ get_client_jar(version_id)
+ with ZipFile(get_dir_location(f'downloads/client-{version_id}.jar')) as z:
+ with z.open(file_dir) as f:
+ return f.read()
+
+
+def get_en_us_lang(version_id: str):
+ return json.loads(
+ get_file_from_jar(version_id, 'assets/minecraft/lang/en_us.json')
+ )