-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from monkeyman192/pattern_update
initially add patterns for some funcs as well as the internal ones
- Loading branch information
Showing
35 changed files
with
3,980 additions
and
2,987 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
name: NMSpy | ||
|
||
on: | ||
# Run on all branches except for the gh-pages branch | ||
push: | ||
paths-ignore: | ||
- '*.md' | ||
branches-ignore: | ||
- 'gh-pages' | ||
tags: | ||
- '*' | ||
|
||
jobs: | ||
build_test: | ||
name: Build artefacts | ||
runs-on: Windows-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
py_ver: [{version: '3.9'}] # , {version: '3.10'}, {version: '3.11'}] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
- name: Set up Python ${{ matrix.py_ver.version}} | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: "${{ matrix.py_ver.version}}" | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip uv | ||
uv sync --frozen --group dev | ||
- name: Build Python ${{ matrix.py_ver.version}} wheel | ||
run: uv build | ||
- name: Lint and format code | ||
run: uv run python -m twine check ./dist/* | ||
# uv run ruff check ./NMSpy | ||
# uv run ruff format --check ./NMSpy | ||
# uv run python -m twine check ./dist/* | ||
- name: Upload Wheels | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: python-package-distributions | ||
path: dist/ | ||
release: | ||
name: Release NMSpy wheels and source build to PyPI | ||
# Only run this job if the commit was tagged. | ||
if: startsWith(github.ref, 'refs/tags') | ||
needs: | ||
- build_test | ||
runs-on: ubuntu-latest | ||
environment: | ||
name: pypi | ||
url: https://pypi.org/p/NMSpy | ||
permissions: | ||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing | ||
steps: | ||
- name: Download files for release | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: python-package-distributions | ||
path: dist/ | ||
- name: Publish package distributions to PyPI | ||
uses: pypa/gh-action-pypi-publish@release/v1 | ||
with: | ||
attestations: true | ||
|
||
test-release: | ||
name: Release NMSpy wheels and source build to test-PyPI | ||
needs: | ||
- build_test | ||
runs-on: ubuntu-latest | ||
environment: | ||
name: testpypi | ||
url: https://test.pypi.org/p/NMSpy | ||
permissions: | ||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing | ||
steps: | ||
- name: Download files for release | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: python-package-distributions | ||
path: dist/ | ||
- name: Publish package distributions to PyPI | ||
uses: pypa/gh-action-pypi-publish@release/v1 | ||
with: | ||
repository-url: https://test.pypi.org/legacy/ | ||
attestations: true | ||
verbose: true |
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 +1 @@ | ||
include nmspy/pymhf.cfg | ||
include nmspy/pymhf.toml |
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,63 +1,68 @@ | ||
import logging | ||
import ctypes | ||
from dataclasses import dataclass | ||
|
||
from pymhf.core.hooking import disable, on_key_pressed | ||
from pymhf.core.memutils import map_struct | ||
from pymhf.core.hooking import on_key_pressed | ||
from pymhf.core.mod_loader import ModState | ||
from nmspy import NMSMod | ||
from pymhf.core.calling import call_function | ||
import pymhf.core.hooking | ||
from pymhf import FUNCDEF | ||
from pymhf.core.module_data import module_data | ||
from pymhf.gui import FLOAT | ||
import nmspy.data.functions.hooks as hooks | ||
|
||
# A quick mod used to change the gravity multiplier on all planets simultaneously, utilizing pyMHF's auto-gui. | ||
|
||
logger = logging.getLogger("GravMod") | ||
|
||
|
||
@dataclass | ||
class gravModState(ModState): #A special class inheriting from ModState which persists between mod Hot Reloads, allowing mod developers to cache pointers, values etc. | ||
Gravity: int = 1 | ||
planetAddresses= list() | ||
class gravModState(ModState): | ||
# A special class inheriting from ModState which persists between mod Hot Reloads, allowing mod developers | ||
# to cache pointers, values etc. | ||
gravity: int = 1 | ||
planetAddresses: list[int] = [] | ||
|
||
|
||
@disable | ||
class gravityManipulator(NMSMod): | ||
#General "Nice To Have"s | ||
# General "Nice To Have"s | ||
__author__ = "ThatBomberBoi" | ||
__description__ = "Gravity Manipulator" | ||
__version__ = "0.1" | ||
__NMSPY_required_version__ = "0.7.0" | ||
__version__ = "0.2" | ||
__NMSPY_required_version__ = "0.7.0" | ||
|
||
#Create an instance of the persistant ModState Class in your mod class. | ||
state = gravModState() | ||
# Create an instance of the persistant ModState Class in your mod class. | ||
state = gravModState() | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self.should_print = False | ||
|
||
#Used to define a Float Type with a label in the Mod GUI, autogenerated by pyMHF. | ||
# Used to define a Float Type with a label in the Mod GUI, autogenerated by pyMHF. | ||
@property | ||
@FLOAT("Gravity Multiplier:") | ||
def gravMult(self): | ||
return self.state.Gravity | ||
return self.state.gravity | ||
|
||
#Used to actually update the persisted value with the one input by the user in the GUI. | ||
# Used to actually update the persisted value with the one input by the user in the GUI. | ||
@gravMult.setter | ||
def gravMult(self, value): | ||
self.state.Gravity = value | ||
|
||
#Define the FUNCDEF for the function you want to hook, including the return-type and arguments as identified via decompilers (e.x. IDA). | ||
regionSetupFuncDef = FUNCDEF(restype=None, argtypes=[ctypes.c_ulonglong]) | ||
self.state.gravity = value | ||
|
||
#The decorator used to tie a hook to a function. The tied function gets called whenever the in-game function is called. Requires a Function Signature as generated by plugins such as SigMakerEx for IDA. | ||
# If the function you're hooking hasn't changed since 4.13 - Fractals, you can use this lil trick I've done here, and save yourself having to manually write out a FUNCDEF. | ||
@pymhf.core.hooking.manual_hook(name="cGcPlanet::SetupRegionMap", pattern="48 89 5C 24 10 48 89 6C 24 18 56 57 41 56 48 83 EC 40 48 8B D9 8B", func_def=module_data.FUNC_CALL_SIGS["cGcPlanet::SetupRegionMap"], detour_time="after") | ||
def onRegionMap(self, this): #Include each in-game function's arguments seperately in the function, or use *args to inspect all arguments without knowing them prior. | ||
logging.info(f"Generated A Planet!") | ||
# Functions are hooked by specifying the function to be hooked from the list of in game functions | ||
# available. You can specify whether you want your detour to run either before or after the original | ||
# function as shown below. | ||
@hooks.cGcPlanet.SetupRegionMap.after | ||
def onRegionMap(self, this): | ||
# Include each in-game function's arguments seperately in the function, or use *args to get all | ||
# arguments without knowing them prior. | ||
# In this case we know that the argument is `this` which is a pointer to the instance of `cGcPlanet` | ||
# which is automatically passed into this function by the game. | ||
logger.info(f"Generated A Planet!") | ||
self.state.planetAddresses.append(this) | ||
logging.debug(f"Found {len(self.state.planetAddresses)} Planets So Far") | ||
logger.debug(f"Found {len(self.state.planetAddresses)} Planets So Far") | ||
|
||
@on_key_pressed("o") | ||
def modifyGravity(self): | ||
for i in self.state.planetAddresses: | ||
call_function("cGcPlanet::UpdateGravity", i, self.state.Gravity, pattern="40 53 48 83 EC 40 83 B9 78") #Used to call an in-game function directly from your mod code. You will need to provide the arguments for the in-game function, as well as the function signature. | ||
logging.info(f"Set Planetary Gravity Multiplier To {self.state.Gravity} For All Planets") | ||
for ptr in self.state.planetAddresses: | ||
# Call an in-game function directly from your mod code. | ||
# You will need to provide the arguments for the in-game function | ||
call_function("cGcPlanet::UpdateGravity", ptr, self.state.gravity) | ||
logger.info(f"Set Planetary Gravity Multiplier To {self.state.gravity} For All Planets") |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.