-
Couldn't load subscription status.
- Fork 44
Feat zip peeking #416
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
Feat zip peeking #416
Conversation
The plan is to automate the creation of hooks for each function in all GDScripts.
Vanilla functions are renamed, and at the bottom of the script, mod loader hooks are generated. These hooks replace the vanilla functions and handle calls to the `callable_stack`.
Currently, I'm stuck on this approach because the method list's return property does not contain any information if there is no return type defined for the method.
That seems to work for filtering out methods that have a return.
Without removing the `class_name` before initializing the script on export, I get this parse error: `hides a global script class`. With these code changes, I get `Value of type [script_path] cannot be assigned to a variable of type [class_name]` if there is a self-assignment somewhere in the script.
Also added a check for static functions and currently working on recognizing inner classes.
check the `type_hint` and add it if it's present.
To check if the function has no space before `func` or `static`, used to ignore functions in inner classes. Later, we might want to figure out a way to include these.
Also removed extra comma in args list
until now all scripts received the "Mod Loader Hooks" header at the bottom even when no changes where made.
used to ignore setter funcs
Also refactored some of the function/field names to improved the modding experience
added getter method, made both static and moved getter/setter check to is_moddable check
improved performance by exiting early when nothing is hooked
and a first style and type pass
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.
Massive rework - thanks a lot! 🩵 This will require intensive testing, but I’m sure with this implemented in Dome Keeper, we will find all the issues 😄
I’ll start testing this with my projects. Currently, I don’t see anything holding us back from merging it 👍
| "Loading any resource packs (.zip/.pck) with `load_resource_pack` will WIPE the entire virtual res:// directory. ", | ||
| "If you have any unpacked mods in ", _ModLoaderPath.get_unpacked_mods_dir_path(), ", they will not be loaded. ", | ||
| "Please unpack your mod ZIPs instead, and add them to ", _ModLoaderPath.get_unpacked_mods_dir_path()), LOG_NAME) | ||
| ModLoaderStore.has_shown_editor_zips_warning = true |
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.
Does only_once not work in this case?
godot-mod-loader/addons/mod_loader/api/log.gd
Line 135 in d7a28c3
| static func warning(message: String, mod_name: String, only_once := false) -> void: |
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.
it should, yeah. i didn't change anything here, just moved it.
| # Application's Steam ID, used if workshop is enabled | ||
| steam_id = 0, | ||
| # Application's version following semver | ||
| semantic_version = "0.0.0", |
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.
what if a game uses non semantic version numbers?
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.
then they can either leave it like this, which essentially disables version checking, implement their own logic since we can't preemtively cover all strange version standards, or switch to semver, which is probably the easiest. it's the main version standard for a reason
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.
Maybe we could add an option to enable or disable this, or even allow the developer to implement their own validation. Just a thought for the future.
Co-authored-by: KANAjetzt <41547570+KANAjetzt@users.noreply.github.com>
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.
followup pr todo
- move manifest file loading to file.gd
- fix reload mods
- doc comments for hooks
- use log
only_onceinstead ofModLoaderStore.has_shown_editor_zips_warning
| "Loading any resource packs (.zip/.pck) with `load_resource_pack` will WIPE the entire virtual res:// directory. ", | ||
| "If you have any unpacked mods in ", _ModLoaderPath.get_unpacked_mods_dir_path(), ", they will not be loaded. ", | ||
| "Please unpack your mod ZIPs instead, and add them to ", _ModLoaderPath.get_unpacked_mods_dir_path()), LOG_NAME) | ||
| ModLoaderStore.has_shown_editor_zips_warning = true |
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.
it should, yeah. i didn't change anything here, just moved it.
| # Application's Steam ID, used if workshop is enabled | ||
| steam_id = 0, | ||
| # Application's version following semver | ||
| semantic_version = "0.0.0", |
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.
then they can either leave it like this, which essentially disables version checking, implement their own logic since we can't preemtively cover all strange version standards, or switch to semver, which is probably the easiest. it's the main version standard for a reason
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.
Are we sure about "macOS" working correctly over "macos"?
| var game_install_directory := OS.get_executable_path().get_base_dir() | ||
|
|
||
| if OS.get_name() == "OSX": | ||
| if OS.get_name() == "macOS": |
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.
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.
yep, that's get_name() though, not the flag. confused me too. we should probably decide on a single one - i think it was originally chosen because has_feature was the same with web and without, which has changed since
| return {} | ||
| ModLoaderLog.error("Can't open workshop folder %s (Error: %s)" % [workshop_folder_path, error_string(DirAccess.get_open_error())], LOG_NAME) | ||
| return [] | ||
| var workshop_dir_listdir_error := workshop_dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547 |
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.
Nitpick: workshop_dir_listdir_error could just be result or error
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.
no new todos i'll fix those right away
| var game_install_directory := OS.get_executable_path().get_base_dir() | ||
|
|
||
| if OS.get_name() == "OSX": | ||
| if OS.get_name() == "macOS": |
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.
yep, that's get_name() though, not the flag. confused me too. we should probably decide on a single one - i think it was originally chosen because has_feature was the same with web and without, which has changed since


big pr with some suboptimal mixing of things to get them fixed for dome, sorry about those.
the core of the zip peeking pr is about having info about mod metadata before the mod is loaded by load_resource_pack. this lets us compare the game version (and other data, in following prs) from the zip with the one set by the game. if a version mismatch is detected the mod won't be loaded, which will reduce crashes.
this basically flips the order of operations around from previously
to
optimally this would be the new process, but i had to take a few shortcuts to quickly get it ready for the dome patch
shortcut way
Other notes for the future