-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added logic to traverse the dimensions directory tree #251
Conversation
@@ -33,5 +39,15 @@ def game_version_string(self) -> str: | |||
except Exception: | |||
return f"Java Forge Unknown Version" | |||
|
|||
def _register_modded_dimensions(self): | |||
for path, directories, files in os.walk(os.path.join(self.path, "dimensions")): | |||
if set(("data", "entities", "poi", "region")).issubset(set(directories)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified to the following
if {"data", "entities", "poi", "region"}.issubset(directories):
@@ -33,5 +39,15 @@ def game_version_string(self) -> str: | |||
except Exception: | |||
return f"Java Forge Unknown Version" | |||
|
|||
def _register_modded_dimensions(self): | |||
for path, directories, files in os.walk(os.path.join(self.path, "dimensions")): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
files
isn't used so this can be an _
if set(("data", "entities", "poi", "region")).issubset(set(directories)): | ||
dimension_path_split = path.split(os.sep) | ||
dimensions_directory_index = dimension_path_split.index("dimensions") | ||
dimension_name = f"{dimension_path_split[dimensions_directory_index + 1]}:{'/'.join(dimension_path_split[dimensions_directory_index + 2:])}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably add a check if we are at least two directories deep otherwise this will error
for path, directories, files in os.walk(os.path.join(self.path, "dimensions")): | ||
if set(("data", "entities", "poi", "region")).issubset(set(directories)): | ||
dimension_path_split = path.split(os.sep) | ||
dimensions_directory_index = dimension_path_split.index("dimensions") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You compute the relpath
further down. The indexes will be constant in that output.
If only the region directory is required this can be compacted down to a glob. |
I haven't tested this but this is how I would implement it def _register_modded_dimensions(self):
for region_path in glob.glob(
os.path.join(glob.escape(self.path), "dimensions", "*", "**", "region"),
recursive=True
):
dim_path = os.path.dirname(region_path)
if not {"data", "entities", "poi", "region"}.issubset(filter(os.path.isdir, os.listdir(dim_path))):
continue
rel_dim_path = os.path.relpath(dim_path, self.path)
_, dimension, *base_name = rel_dim_path.split(os.sep)
dimension_name = f"{dimension}:{'/'.join(base_name)}"
self._register_dimension(
os.path.dirname(rel_dim_path), dimension_name
) |
Yeah I can test that glob code and see if it needs any additional changes but from a quick look it looks like it will work. I'll amend this later tonight |
…antJGC with tweaks for it to properly check if the required paths are directories
…the check in-case /region is a file and not a directory
for basename in os.listdir(dim_path) | ||
if os.path.isdir(os.path.join(dim_path, basename)) | ||
) | ||
if not {"region"}.issubset(child_dir_names): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you only check one directory it should be.
The os.path.dirname in the last line was also wrong.
def _register_modded_dimensions(self):
for region_path in glob.glob(
os.path.join(glob.escape(self.path), "dimensions", "*", "**", "region"),
recursive=True,
):
if not os.path.isdir(region_path):
continue
dim_path = os.path.dirname(region_path)
rel_dim_path = os.path.relpath(dim_path, self.path)
_, namespace, *base_name = rel_dim_path.split(os.sep)
dimension_name = f"{namespace}:{'/'.join(base_name)}"
self._register_dimension(rel_dim_path, dimension_name)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add this in tomorrow when I get the chance! I wanted to keep the directory check in and decided to keep the set approach in-case other directories would need to be added in the future but I think this is good and we can just do that change if/when it would be needed
`"*", "*", "**"` is required to match at least two directories deep. dirname should not be on the last line. dirname there would give a different directory.
Delved into the code to work out why the tests were breaking. |
Moved the modded dimension finding code into the vanilla class. The tests were breaking because the code was implemented in the constructor. This code should be in the level reloading method.
Ah gotcha, is there a particular reason why the tests just started to fail? They were passing fine until the commit where we only check the region directory. I also think the logic should still be contained in |
Your code caused a modded dimension to get registered twice (once in your code and once in the vanilla code) which triggered another issue. I don't think I finished implementing the reloading code so there are a number of issues. It shouldn't do any harm in the vanilla class and is less likely to get broken when I refactor those classes. I want to refactor the level wrappers so that the constructors don't actually load the world. They just initialise some default values. |
This code changes now traverses the
dimensions
directory tree and searches for the following directories to exist to determine if the parent directory is a dimension:data
,entities
,poi
andregion
Notes:
anvil_world/format.py
here but I put it into theanvil_forge_world.py
file for now since it's Forge specific. Feel free to let me know if you want me to migrate itResolves Amulet-Team/Amulet-Map-Editor#922