Skip to content
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

Textures Not Loading (Flatpak Version) #1107

Open
EvilSupahFly opened this issue Oct 8, 2024 · 9 comments
Open

Textures Not Loading (Flatpak Version) #1107

EvilSupahFly opened this issue Oct 8, 2024 · 9 comments
Labels
state: triage the severity of this ticket needs evaluating type: bug Something isn't working

Comments

@EvilSupahFly
Copy link

EvilSupahFly commented Oct 8, 2024

Bug Report:

Water and Lava blocks aren't loading, but only in the Flatpak version.

Current Behaviour:

Water and Lava blocks aren't loading, but only in the Flatpak version.

Expected behavior:

Water and Lava blocks should load.

Steps To Reproduce:

Install the Flatpak version and run it

Environment:

  • OS: Linux
  • Minecraft Platform: Java
  • Minecraft Version: 1.19.4
  • Amulet Version: 0.10.36 (Flatpak)

Additional context

I had thought this issue resolved after updating Amulet's base code for the Flatpak from .35 to .36, having seen the error go away on my testing rig. However, another user informed me the issue persisted for him, even after the .36 update.

So I modified resource_pack_manager.py again (by changing log.error to log.exception), as suggested in #1098 and ran Flatpak Amulet through the Python Debugger in Flatpak's version of Python (it runs 3.12 internally in Freedesktop 24.08, which is what I build against).

While the full results are in the GIST linked below, the part that probably is of interest is this part, which repeats for all the water and lava blocks Amulet finds:

ERROR - Failed to load block model {'model': 'minecraft:block/water'}
'/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
Traceback (most recent call last):
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 235, in _get_model
    return self._load_blockstate_model(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 326, in _load_blockstate_model
    model = copy.deepcopy(self._load_block_model(model_path))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 423, in _load_block_model
    if self._texture_is_transparent[texture_path][1]:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: '/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
ERROR - Failed to load block model {'model': 'minecraft:block/lava'}
'/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png'
Traceback (most recent call last):
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 235, in _get_model
    return self._load_blockstate_model(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 326, in _load_blockstate_model
    model = copy.deepcopy(self._load_block_model(model_path))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 423, in _load_block_model
    if self._texture_is_transparent[texture_path][1]:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: '/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png'

I've provided the Flatpak read/write access to the user's $HOME folder, but now I'm wondering if the Flatpak needs an extra set of permissions for somewhere else? If Amulet is trying to copy files within the Flatpak sandbox, it won't work as the sandbox itself is mounted as read-only. Generally speaking, however, Flatpak stores everything in $HOME/.var/app/ in a folder for each sandbox.

Screenshot from 2024-10-08 19-36-42

That includes the defaults for water and lava:
Screenshot from 2024-10-08 19-41-17

Everything is in there - I double checked.

Attachments

Not really an attachment, but the complete terminal log is available here on GIST.

@EvilSupahFly EvilSupahFly added state: triage the severity of this ticket needs evaluating type: bug Something isn't working labels Oct 8, 2024
@gentlegiantJGC
Copy link
Member

So it is looking up that string in a dictionary but it isn't there.
The dictionary is populated here.
https://github.com/gentlegiantJGC/Minecraft-Model-Reader/blob/fe3214554c3666065cf0647c5af30f0bf0948a35/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py#L129

Looks like the path in your screenshots has a prefix that isn't in the string. Could that be the problem?

@EvilSupahFly
Copy link
Author

That must be the /app that is part of all Flatpak sandboxes. I had assumed the paths were relative to Amulet's install location within Python's framework, but Flatpak messes with that a bit, it would seem.

@EvilSupahFly
Copy link
Author

I'm not seeing any hard-coded paths. All the path definitions appear to be relative to the location the resource pack manager API is running from, which should count $HOME/.var/app/$app_ID when running inside the sandbox, which as far as I understand it, should be / as far as the app itself is concerned.

I'll have to check the Flatpak documentation again because I have a suspicion that I've missed something in the manifest.

@EvilSupahFly
Copy link
Author

EvilSupahFly commented Oct 9, 2024

So... If Amulet is unable to create or write to CACHE_DIR, would that cause this error? If so, making the default location sandbox-writable or moving it to somewhere the sandbox can already write to should fix this, if that's the case.

I'll make the changes after work and see what happens.

Edit: I'll have to see how - or if - this impacts Bedrock worlds too, since I haven't tested any (not that Linux players would be running Bedrock though).

@EvilSupahFly
Copy link
Author

When stepping through, I see paths being set during the initial execution, but they too seem to be relative to $HOME/.var/$app_id, which - being in the user's HOME directory - is writable by default.

> /app/lib/python3.12/site-packages/amulet_map_editor/__main__.py(84)main()
-> data_dir = platformdirs.user_data_dir("AmuletMapEditor", "AmuletTeam")
(Pdb) n
> /app/lib/python3.12/site-packages/amulet_map_editor/__main__.py(85)main()
-> os.environ.setdefault("DATA_DIR", data_dir)
(Pdb) n
> /app/lib/python3.12/site-packages/amulet_map_editor/__main__.py(86)main()
-> config_dir = platformdirs.user_config_dir("AmuletMapEditor", "AmuletTeam")
(Pdb) n
> /app/lib/python3.12/site-packages/amulet_map_editor/__main__.py(87)main()
-> if config_dir == data_dir:
(Pdb) print(f"{data_dir}")
/home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet-flatpak/data/AmuletMapEditor
(Pdb) print(f"{config_dir}")
/home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet-flatpak/config/AmuletMapEditor
[...]
> /app/lib/python3.12/site-packages/platformdirs/unix.py(96)user_cache_dir()
-> if not path.strip():
(Pdb) print(f"{path}")
/home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet-flatpak/cache
(Pdb) s
> /app/lib/python3.12/site-packages/platformdirs/unix.py(98)user_cache_dir()
-> return self._append_app_name_and_version(path)
[...]
(Pdb) s
> /app/lib/python3.12/site-packages/platformdirs/api.py(78)_append_app_name_and_version()
-> self._optionally_create_directory(path)
(Pdb) print(f"{path}")
/home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet-flatpak/cache/AmuletMapEditor
[...]
> /app/lib/python3.12/site-packages/platformdirs/unix.py(122)user_log_dir()
-> self._optionally_create_directory(path)
(Pdb) s
--Call--
> /app/lib/python3.12/site-packages/platformdirs/api.py(81)_optionally_create_directory()
-> def _optionally_create_directory(self, path: str) -> None:
(Pdb) s
> /app/lib/python3.12/site-packages/platformdirs/api.py(82)_optionally_create_directory()
-> if self.ensure_exists:
(Pdb) s
--Return--
> /app/lib/python3.12/site-packages/platformdirs/api.py(82)_optionally_create_directory()->None
-> if self.ensure_exists:
(Pdb) s
> /app/lib/python3.12/site-packages/platformdirs/unix.py(123)user_log_dir()
-> return path
(Pdb) print(f"{path}")
/home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet-flatpak/.local/state/AmuletMapEditor/log
[...]
--Return--
> <frozen genericpath>(22)exists()->True
(Pdb) s
> <frozen os>(224)makedirs()
(Pdb) s
> <frozen os>(225)makedirs()
(Pdb) s
FileExistsError: [Errno 17] File exists: '/home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet-flatpak/.local/state/AmuletMapEditor/log'
> <frozen os>(225)makedirs()

So the directory structure isn't the issue. It has no problems finding anything inside the sandbox, as my periodic print statements from PDB show that it accepts $HOME/.var/$app_id as a valid starting point.

In an effort to see what was going on under the hood, I dumped the entire log to a file, but since it was 80,000 lines, I snipped it at the top of the resource pack access (see this GIST) and I can see that it's loading the downloaded textures into the cache with no problem, proving that it's neither a permissions issue, or a write-access issue, and you can see that it finds all the pertinent .JSON and .PNG files. The built-in fix for water and lava, however, still fails, even with the modified sandbox permissions and I don't understand why.

All the paths are relative to Amulet, and all the files are where they're supposed to be within the sandbox structure, which is identical (save for running from $HOME/.var/$app_id) to the version of Amulet installed by PIP in my VENV.

@EvilSupahFly
Copy link
Author

EvilSupahFly commented Oct 15, 2024

So, I've tweaked the resource pack model manager to print some more (excessively) detailed information on paths and file access, and here's what I have, after narrowing down over 90,000 lines from the debug output to these sixty or so:

texture_relative_path = #rail
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/rail_corner.png
texture_relative_path = #rail
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/rail_corner.png
<minecraft_model_reader.api.mesh.block.block_mesh.BlockMesh object at 0xe7adc73bfb0> = copy.deepcopy(self._load_block_model(minecraft:block/rail_corner))
model_path_list = ['minecraft', 'block/water']

model_path_list = ['block/cube_all']

model_path_list = ['block/cube']

model_path_list = ['block/block']

texture_relative_path = #down
texture_path = /app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png
ERROR - Failed to load block model {'model': 'minecraft:block/water'}
'/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
Traceback (most recent call last):
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 246, in _get_model
    return self._load_blockstate_model(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 337, in _load_blockstate_model
    model = copy.deepcopy(self._load_block_model(model_path))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 437, in _load_block_model
    if self._texture_is_transparent[texture_path][1]:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: '/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
ERROR - Failed to load block model {'model': 'minecraft:block/water'}
'/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
Traceback (most recent call last):
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 246, in _get_model
    return self._load_blockstate_model(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 337, in _load_blockstate_model
    model = copy.deepcopy(self._load_block_model(model_path))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 437, in _load_block_model
    if self._texture_is_transparent[texture_path][1]:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: '/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
Texture path retrieved: /app/lib/python3.12/site-packages/minecraft_model_reader/api/image/missing_no.png
BlockMesh created with texture path: /app/lib/python3.12/site-packages/minecraft_model_reader/api/image/missing_no.png
model_path_list = ['minecraft', 'block/iron_door_bottom_right']

model_path_list = ['minecraft', 'block/door_bottom_right']

texture_relative_path = #bottom
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/iron_door_bottom.png
texture_relative_path = #bottom
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/iron_door_bottom.png
texture_relative_path = #bottom
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/iron_door_bottom.png
texture_relative_path = #bottom
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/iron_door_bottom.png
texture_relative_path = #bottom
texture_path = /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/iron_door_bottom.png
<minecraft_model_reader.api.mesh.block.block_mesh.BlockMesh object at 0xe7adc1e1e50> = copy.deepcopy(self._load_block_model(minecraft:block/iron_door_bottom_right))

After still not understanding why it fails to load water and lava, I thought up a clever work around: I grabbed the 1.21 Vanilla resource pack from CurseForge, saved it to Amuet's resource pack add-on folder, and reloaded Amulet, but that didn't change anything and the textures are still missing.

@EvilSupahFly
Copy link
Author

I can see from the extensive debug barf that textures are being loaded from two different locations. The ones being downloaded are being saved to /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/, and those are being read just fine.

However, the bundled ones such as water and lava are being read from their "install location" inside the flatpak: /app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/.

I thought that manually copying them over to /home/evilsupahfly/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/ might help, but it made no difference.

Unrelated but still important: wxPython got a patch yesterday which resolves some issues for Linux users using Wayland instead of X by patching (officially this time) a twenty-year-old piece of code, so you may want to update the wxPython version requirement for Amulet. I don't know it impacted non-Flatpak users though. This is the error Wayland users would get:

Unable to access the X Display, is $DISPLAY set properly?

@EvilSupahFly
Copy link
Author

EvilSupahFly commented Nov 25, 2024

I believe with the changes I've made to the Minecraft Model Reader, the missing textures are finally resolved. I'm just waiting on the final build to complete on my EndeavourOS test machine in order to verify but so far on Linux Mint, it works. I'm sure there's a better way to do this, but for now, it gets the job done.

@EvilSupahFly
Copy link
Author

EvilSupahFly commented Dec 1, 2024

I just inadvertently solved my problem by creating a venv (literally) at /app so I could mirror the structure inside the sandbox as closely as possible, and after checking the logs, I've discovered a key difference. THE key difference, in fact.

When running from PIP, Amulet is installed to
/app/lib/python3.13/site-packages/

When Amulet is installed inside the Flatpak, the location is changed to
/app/usr/lib/python3.12/site-packages/

I guess not all the paths are relative after all. I feel like an idiot now because it was so obvious. It was right there in every error message, every time.

I'm just not sure where this is defined. I'm exploring two options now. One is a way to override the sandbox location from /usr/lib to /lib and the other is to try and locate where inside Amulet this is defined (assuming it's been hard-coded) and change it there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: triage the severity of this ticket needs evaluating type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants