Skip to content

Commit 2447339

Browse files
authored
Merge pull request #41 from apple1417/master
fix spinner options not working, pull in updates
2 parents e1bba5c + 1e33ef7 commit 2447339

12 files changed

+141
-41
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ project(oak_mod_manager)
55
set(UNREALSDK_ARCH x64)
66
set(UNREALSDK_UE_VERSION UE4)
77
set(EXPLICIT_PYTHON_ARCH amd64)
8-
set(EXPLICIT_PYTHON_VERSION 3.13.0)
8+
set(EXPLICIT_PYTHON_VERSION 3.13.1)
99

1010
add_subdirectory(libs/pyunrealsdk)
1111

Readme.md

+11-8
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,25 @@ When developing, it's recommended to point pyunrealsdk directly at this repo. To
1515

1616
1. Navigate to the plugins folder - `<game>\OakGame\Binaries\Win64\Plugins\`
1717

18-
2. Edit `python3XX._pth`, replacing `..\..\..\..\sdk_mods` with `<path to repo>\src`. If you have a
19-
debug build, also edit `python3XX_d._pth`.
18+
2. Create/edit `unrealsdk.user.toml`, adding the following:
19+
```toml
20+
[pyunrealsdk]
21+
init_script = "<path to repo>\\src\\__main__.py"
22+
```
2023

21-
3. Edit `unrealsdk.env`, setting `PYUNREALSDK_INIT_SCRIPT=<path to repo>\src\__main__.py`.
24+
3. (Optional) Update `pyunrealsdk.pyexec_root` to the same folder, to make sure pyexec commands go
25+
where you expect.
2226

23-
4. (Optional) Edit `unrealsdk.env`, adding/updating
24-
`OAK_MOD_MANAGER_EXTRA_FOLDERS=["C:\\path\\to\\new\\mod\\folder"]`, pointing at your old
25-
`sdk_mods` folder. This is a json list of paths to folders to load, though note it must stay on
26-
one line.
27+
4. (Optional) Add the path to your old `sdk_mods` folder to the `mod_manager.extra_folders` array,
28+
so they continue getting loaded.
2729

2830
5. (Optional) Copy/symlink your original settings folder into `src\settings` - settings are only
2931
loaded from the base mods folder.
3032

3133
Once you've done this, you can modify the python files in place.
3234

33-
To build the native modules:
35+
## Native code
36+
The mod manager uses a few native modules. To edit these, or even just the base pyunrealsdk code:
3437

3538
1. Initialize the git submodules.
3639
```sh

changelog.md

+58
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,63 @@
11
# Changelog
22

3+
## v1.6: (codename tbd)
4+
5+
### BL3 Mod Menu v1.5
6+
- Fixed the handling of spinner option updates, so that they're actually usable.
7+
8+
### [Mods Base v1.6](https://github.com/bl-sdk/mods_base/blob/master/Readme.md#v16)
9+
> - Changed default type of `HookType` generic type hint to any, so that by default pre and post hooks
10+
> can be combined under the same type. As an example, previously if you passed an explicit hook list
11+
> to `build_mod`, the type hinting would only accept a list where all hooks were of the same type.
12+
>
13+
> - Fixed that defining an option, keybind, hook, or command as a class member, and then constructing
14+
> it via the `build_mod` factory, would pass empty lists to the constructor and thus prevent the
15+
> auto member collection from running.
16+
>
17+
> - Changed the display version to be sourced from `mod_manager.display_version` in the unrealsdk
18+
> config file, rather than an environment variable.
19+
>
20+
> - Gave `@command` and `ArgParseCommand.add_argument` default type hinting for the args they forward.
21+
22+
### Keybinds v2.4
23+
- Linting fixes.
24+
25+
### [pyunrealsdk v1.5.0](https://github.com/bl-sdk/pyunrealsdk/blob/master/changelog.md#v150)
26+
> - Deprecated `unrealsdk.hooks.inject_next_call` in favour of a new
27+
> `unrealsdk.hooks.prevent_hooking_direct_calls` context manager.
28+
>
29+
> - The `WeakPointer` constructor can now be called with no args, to create a null pointer.
30+
>
31+
> - As with unrealsdk, reworked the configuration system to no longer rely on environment variables.
32+
> All sdk configuration is now also done through the `unrealsdk.toml`.
33+
>
34+
> The full contents of the unrealsdk config are parsed and exposed to Python in `unrealsdk.config`.
35+
36+
### [unrealsdk v1.5.0](https://github.com/bl-sdk/unrealsdk/blob/master/changelog.md#v150)
37+
> - Completely reworked the configuration system.
38+
>
39+
> Environment variables and the `unrealsdk.env` are no longer used, due to issues with them not fully
40+
> propagating within the same process. The new configuration now uses an `unrealsdk.toml` instead.
41+
>
42+
> Also added support for a user specific override file - `unrealsdk.user.toml`. This allows projects
43+
> to ship their own `unrealsdk.toml`, without overwriting user's settings on update.
44+
>
45+
> - `unrealsdk::hook_manager::inject_next_call` is now thread local.
46+
>
47+
> - Fixed that `unrealsdk::commands::has_command` and `unrealsdk::commands::remove_command` were case
48+
> sensitive, while `unrealsdk::commands::add_command` and the callbacks were not. Commands should be
49+
> now be case insensitive everywhere.
50+
>
51+
> - Fixed that the executed command message of custom sdk commands would not appear in console if you
52+
> increased the minimum log level, and that they may have appeared out of order with respects to
53+
> native engine messages.
54+
>
55+
> - Added an additional console command hook in BL2, to cover commands not run directly via console.
56+
>
57+
> - Renamed the `unrealsdk.locking_process_event` (previously `UNREALSDK_LOCKING_PROCESS_EVENT`)
58+
> setting to `unrealsdk.locking_function_calls`, and expanded it's scope to cover all function
59+
> calls. This fixes a few more possibilities for lockups.
60+
361
## v1.5: Time Skip
462

563
### General

manager_pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
[project]
77
name = "oak_mod_manager"
8-
version = "1.5"
8+
version = "1.6"
99
authors = [{ name = "bl-sdk" }]
1010

1111
[tool.sdkmod]

prepare_release.py

+62-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
import json
23
import re
34
import shutil
45
import subprocess
@@ -74,30 +75,55 @@ def cmake_install(build_dir: Path) -> None:
7475

7576

7677
@cache
77-
def get_git_repo_version() -> str:
78+
def get_git_commit_hash(identifier: str | None = None) -> str:
7879
"""
79-
Gets a version string representing the current state of the git repo.
80+
Gets the full commit hash of the current git repo.
8081
82+
Args:
83+
identifier: The identifier of the commit to get, or None to get the latest.
8184
Returns:
82-
The version string.
85+
The commit hash.
8386
"""
84-
commit_hash = subprocess.run(
85-
["git", "show", "-s", "--format=%H"],
87+
args = ["git", "show", "-s", "--format=%H"]
88+
if identifier is not None:
89+
args.append(identifier)
90+
91+
return subprocess.run(
92+
args,
93+
cwd=Path(__file__).parent,
8694
check=True,
8795
stdout=subprocess.PIPE,
8896
encoding="utf8",
8997
).stdout.strip()
9098

99+
100+
@cache
101+
def check_git_is_dirty() -> bool:
102+
"""
103+
Checks if the git repo is dirty.
104+
105+
Returns:
106+
True if the repo is dirty.
107+
"""
91108
# This command returns the list of modified files, so any output means dirty
92-
is_dirty = any(
109+
return any(
93110
subprocess.run(
94111
["git", "status", "--porcelain"],
112+
cwd=Path(__file__).parent,
95113
check=True,
96114
stdout=subprocess.PIPE,
97115
).stdout,
98116
)
99117

100-
return commit_hash[:8] + (", dirty" if is_dirty else "")
118+
119+
def get_git_repo_version() -> str:
120+
"""
121+
Gets a version string representing the current state of the git repo.
122+
123+
Returns:
124+
The version string.
125+
"""
126+
return get_git_commit_hash()[:8] + (", dirty" if check_git_is_dirty() else "")
101127

102128

103129
def iter_mod_files(mod_folder: Path, debug: bool) -> Iterator[Path]:
@@ -132,21 +158,31 @@ def iter_mod_files(mod_folder: Path, debug: bool) -> Iterator[Path]:
132158

133159

134160
def _zip_init_script(zip_file: ZipFile) -> None:
135-
output_init_script = ZIP_MODS_FOLDER / INIT_SCRIPT.name
136-
zip_file.write(INIT_SCRIPT, output_init_script)
137-
unrealsdk_env = (
138-
# Path.relative_to doesn't work when where's no common base, need to use os.path
139-
# While the file goes in the plugins folder, this path is relative to *the executable*
140-
f"PYUNREALSDK_INIT_SCRIPT={path.relpath(output_init_script, ZIP_EXECUTABLE_FOLDER)}\n"
141-
f"PYUNREALSDK_PYEXEC_ROOT={path.relpath(ZIP_MODS_FOLDER, ZIP_EXECUTABLE_FOLDER)}\n"
142-
)
161+
zip_file.write(INIT_SCRIPT, ZIP_MODS_FOLDER / INIT_SCRIPT.name)
162+
163+
164+
def _zip_config_file(zip_file: ZipFile) -> None:
165+
# Path.relative_to doesn't work when where's no common base, need to use os.path
166+
# While the file goes in the plugins folder, this path is relative to *the executable*
167+
init_script_path = path.relpath(ZIP_MODS_FOLDER / INIT_SCRIPT.name, ZIP_EXECUTABLE_FOLDER)
168+
pyexec_root = path.relpath(ZIP_MODS_FOLDER, ZIP_EXECUTABLE_FOLDER)
143169

144-
# We also define the display version via an env var, do that here too
145170
version_number = tomllib.loads(PYPROJECT_FILE.read_text())["project"]["version"]
146171
git_version = get_git_repo_version()
147-
unrealsdk_env += f"MOD_MANAGER_DISPLAY_VERSION={version_number} ({git_version})\n"
172+
display_version = f"{version_number} ({git_version})"
173+
174+
# Tomllib doesn't support dumping yet, so we have to create it as a string
175+
# Using `json.dumps` to escape strings, since it should be mostly compatible
176+
config = (
177+
f"[pyunrealsdk]\n"
178+
f"init_script = {json.dumps(init_script_path)}\n"
179+
f"pyexec_root = {json.dumps(pyexec_root)}\n"
180+
f"\n"
181+
f"[mod_manager]\n"
182+
f"display_version = {json.dumps(display_version)}\n"
183+
)
148184

149-
zip_file.writestr(str(ZIP_PLUGINS_FOLDER / "unrealsdk.env"), unrealsdk_env)
185+
zip_file.writestr(str(ZIP_PLUGINS_FOLDER / "unrealsdk.toml"), config)
150186

151187

152188
def _zip_mod_folders(zip_file: ZipFile, mod_folders: Sequence[Path], debug: bool) -> None:
@@ -247,6 +283,7 @@ def zip_release(
247283

248284
with ZipFile(output, "w", ZIP_DEFLATED, compresslevel=9) as zip_file:
249285
_zip_init_script(zip_file)
286+
_zip_config_file(zip_file)
250287
_zip_mod_folders(zip_file, mod_folders, debug)
251288
_zip_stubs(zip_file)
252289
_zip_settings(zip_file)
@@ -287,21 +324,23 @@ def zip_release(
287324
)
288325
args = parser.parse_args()
289326

327+
if check_git_is_dirty():
328+
print("WARNING: git repo is dirty")
329+
290330
install_dir = INSTALL_DIR_BASE / str(args.preset)
291331

292332
if not args.skip_install:
293333
shutil.rmtree(install_dir, ignore_errors=True)
294334
cmake_install(BUILD_DIR_BASE / args.preset)
295335

296336
assert install_dir.exists() and install_dir.is_dir(), "install dir doesn't exist"
297-
298337
# Zip up all the requested files
299-
COMMON_FOLDERS = (BASE_MOD, KEYBINDS, UI_UTILS)
338+
COMMON_FOLDERS = (BASE_MOD, CONSOLE_MENU, KEYBINDS, UI_UTILS)
300339

301340
for prefix, arg, mods in (
302-
("bl3", args.bl3, (*COMMON_FOLDERS, BL3_MENU, CONSOLE_MENU)),
303-
("wl", args.wl, (*COMMON_FOLDERS, CONSOLE_MENU)),
304-
("unified", args.unified, (*COMMON_FOLDERS, BL3_MENU, CONSOLE_MENU)),
341+
("bl3", args.bl3, (*COMMON_FOLDERS, BL3_MENU)),
342+
("wl", args.wl, COMMON_FOLDERS),
343+
("unified", args.unified, (*COMMON_FOLDERS, BL3_MENU)),
305344
):
306345
if not arg:
307346
continue

src/bl3_mod_menu/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"__version_info__",
88
]
99

10-
__version_info__: tuple[int, int] = (1, 4)
10+
__version_info__: tuple[int, int] = (1, 5)
1111
__version__: str = f"{__version_info__[0]}.{__version_info__[1]}"
1212
__author__: str = "bl-sdk"
1313

src/bl3_mod_menu/native/outer_menu.pyi

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ from unrealsdk.unreal import UObject
44

55
__all__: tuple[str, ...] = (
66
"add_menu_item",
7-
"set_add_menu_item_callback",
87
"begin_configure_menu_items",
9-
"set_menu_state",
108
"get_menu_state",
9+
"set_add_menu_item_callback",
10+
"set_menu_state",
1111
)
1212

1313
type _AddMenuItemCallback = Callable[[UObject, str, str, bool, int], int]

src/bl3_mod_menu/options_callbacks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def unimplemented_option_clicked( # noqa: C901 - imo the match is rated too hig
7171
value = round(value)
7272
option.value = value
7373
case SpinnerOption():
74-
assert button.Class.Name == "GbxGFxListItemComboBox"
74+
assert button.Class.Name == "GbxGFxListItemSpinner"
7575
option.value = option.choices[get_spinner_selected_idx(button)]
7676
case KeybindOption():
7777
handle_keybind_press(obj, option)

src/keybinds/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"__version_info__",
1414
)
1515

16-
__version_info__: tuple[int, int] = (2, 3)
16+
__version_info__: tuple[int, int] = (2, 4)
1717
__version__: str = f"{__version_info__[0]}.{__version_info__[1]}"
1818
__author__: str = "bl-sdk"
1919

src/keybinds/keybinds.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ from unrealsdk.hooks import Block
88
from mods_base import EInputEvent
99

1010
__all__: tuple[str, ...] = (
11-
"register_keybind",
1211
"deregister_keybind",
12+
"register_keybind",
1313
)
1414

1515
_KeybindHandle = NewType("_KeybindHandle", object)

0 commit comments

Comments
 (0)