diff --git a/Readme.md b/Readme.md index 6150def..f41309b 100644 --- a/Readme.md +++ b/Readme.md @@ -22,14 +22,15 @@ game specific things: ### v1.9 - Added a new `CoopSupport.HostOnly` value. +- Added a helper `RestartToDisable` mod class, for mods which need a restart to fully disable. + - Specifying a custom class when calling `build_mod` now type hints returning an instance of it, instead of just `Mod`. - `SliderOption`s now throw if initialized with a step larger than their allowed range. -- Added `_(to|from)_json()` methods to all options. - -- Changed settings saving and loading to use above methods. +- Added `_(to|from)_json()` methods to all options, and changed settings saving and loading to use + them. ### v1.8 - Fixed that nested and grouped options' children would not get their `.mod` attribute set. diff --git a/__init__.py b/__init__.py index 52f4244..c231b3a 100644 --- a/__init__.py +++ b/__init__.py @@ -31,7 +31,7 @@ from .hook import HookType, bind_all_hooks, hook from .html_to_plain_text import html_to_plain_text from .keybinds import EInputEvent, KeybindType, keybind -from .mod import CoopSupport, Game, Library, Mod, ModType +from .mod import CoopSupport, Game, Library, Mod, ModType, RestartToDisable from .mod_factory import build_mod from .mod_list import ( deregister_mod, @@ -77,6 +77,7 @@ "Mod", "ModType", "NestedOption", + "RestartToDisable", "SliderOption", "SpinnerOption", "ValueOption", diff --git a/mod.py b/mod.py index 44a0486..e050a3c 100644 --- a/mod.py +++ b/mod.py @@ -334,3 +334,30 @@ def get_status(self) -> str: if Game.get_current() not in self.supported_games: return "Incompatible" return "Loaded" + + +@dataclass +class RestartToDisable(Mod): + """ + Helper subclass for mods which cannot be fully disabled without restarting the game. + + Mods will still run the normal enable/disable logic. However, after being disabled, the status + will show that the mod requires a restart. + """ + + _ever_enabled: bool = field(default=False, init=False, repr=False) + + def enable(self) -> None: + """Called to enable the mod.""" + super().enable() + + # In case we weren't allowed to enable + if self.is_enabled: + self._ever_enabled = True + + def get_status(self) -> str: + """Gets the current status of this mod.""" + if self._ever_enabled and not self.is_enabled: + return "Disabling on Restart" + + return super().get_status()