-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
gh-19: Add ability to run individual files as mods
- Loading branch information
Showing
23 changed files
with
800 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Single-file mods | ||
|
||
While `pymhf` is designed to be used to create libraries upon which mods can be made, for smaller scale projects or small tests, this is not convenient. | ||
To accomodate this, `pymhf` can run a single file containing a mod. | ||
|
||
This file **MAY** have the following attributes defined in it to simplify the defintions: | ||
|
||
`__pymhf_func_binary__` (`str`): The name of the binary all the function offsets/patterns are to be found relative to/in. If provided this will be the default for all functions, however any `manual_hook` with a different value provided will supersede this value. | ||
`__pymhf_func_offsets__` (`dict[str, Union[int, dict[str, int]]]`): A lookup containing the function names and offsets. Generally the keys will be the function names that you want to call the function by, and the values will simply be the offset relative to the start of the binary. For overloads the value can be another dictionary with keys being some identifier for the overload (eg. the argument types), and the values being the offsets. | ||
`__pymhf_func_call_sigs__` (`dict[str, Union[FUNCDEF, dict[str, FUNCDEF]]]`): A lookup containing the function names and function call signatures. The keys will be the function names that you want to call the function by, and the values will either be the `FUNCDEF` itself, or a dictionary similar to the `__pymhf_func_offsets__` mapping. | ||
`__pymhf_func_patterns__` (`dict[str, Union[str, dict[str, str]]]`): A lookup containing the function names and byte patterns to find the functions at. The keys will be the function names that you want to call the function by, and the values will be either a string containing the pattern, or a dictionary similar to the `__pymhf_func_offsets__` mapping. | ||
|
||
Note that none of these are mandatory, however they do simplify the code in the file a decent amount and keep the file more easy to maintain. | ||
|
||
Below is an example single-file mod for the game No Man's Sky: | ||
|
||
```py | ||
# /// script | ||
# dependencies = ["pymhf"] | ||
# | ||
# [tool.pymhf] | ||
# exe = "NMS.exe" | ||
# steam_gameid = 275850 | ||
# start_paused = false | ||
# | ||
# [tool.pymhf.logging] | ||
# log_dir = "." | ||
# log_level = "info" | ||
# window_name_override = "NMS test mod" | ||
# /// | ||
|
||
from logging import getLogger | ||
|
||
from pymhf import Mod, load_mod_file | ||
from pymhf.core.hooking import on_key_pressed | ||
|
||
logger = getLogger("testmod") | ||
|
||
|
||
class MyMod(Mod): | ||
@on_key_pressed("p") | ||
def press_p(self): | ||
logger.info("Pressed P now!") | ||
|
||
|
||
if __name__ == "__main__": | ||
load_mod_file(__file__) | ||
``` | ||
|
||
This mod clearly has very little functionality, but the above highlights the minimum requirements to make a single-file mod using `pymhf`. | ||
|
||
To run this mod it is **strongly** recommended to use [uv](https://github.com/astral-sh/uv) as it has full support for inline script metadata. | ||
|
||
The steps to run the above script from scratch (ie. with no `uv` installed) are as follows: | ||
|
||
``` | ||
python -m pip install uv | ||
uv run script.py | ||
``` | ||
|
||
In the above ensure that the `python` command runs a python version between 3.9 and 3.11 INCLUSIVE. | ||
Replace `script.py` with the name of the script as it was saved. | ||
|
||
To modify the above script, the only values that really need to be changed are the `steam_gameid` and `exe` values. | ||
|
||
If the game is being ran via steam, replace `steam_gameid` with the value found in steam, and set `exe` to be the name of the game binary. | ||
If the game or program is not run through steam, remove the `steam_gameid` value and instead set `exe` and the absolute path to the binary. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,4 @@ | ||
import os | ||
import os.path as op | ||
from concurrent.futures import ThreadPoolExecutor | ||
|
||
import pymhf.core._internal as _internal | ||
|
||
# TODO: Move somewhere else? Not sure where but this doesn't really fit here... | ||
executor: ThreadPoolExecutor = None # type: ignore | ||
|
||
mod_save_dir = op.join(_internal.CFG_DIR, "MOD_SAVES") | ||
if not op.exists(mod_save_dir): | ||
os.makedirs(mod_save_dir) |
Oops, something went wrong.