trainerbase 3.14.1__tar.gz → 3.16.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {trainerbase-3.14.1 → trainerbase-3.16.0}/PKG-INFO +1 -1
- {trainerbase-3.14.1 → trainerbase-3.16.0}/pyproject.toml +2 -2
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/common/helpers.py +14 -1
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/common/keyboard.py +2 -2
- trainerbase-3.16.0/trainerbase/common/rainbow.py +94 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/helpers.py +20 -3
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/injections.py +3 -1
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/misc.py +12 -10
- trainerbase-3.16.0/trainerbase/gui/rainbow.py +22 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/main.py +12 -5
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/scriptengine.py +1 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/LICENSE +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/README.md +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/__init__.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/codeinjection.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/common/__init__.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/common/abc.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/common/teleport.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/config.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gameobject.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/__init__.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/objects.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/scripts.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/speedhack.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/teleport.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/gui/types.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/memory.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/process.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/speedhack.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase/tts.py +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase_vendor/FASM.EXE +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase_vendor/speedhack32.dll +0 -0
- {trainerbase-3.14.1 → trainerbase-3.16.0}/trainerbase_vendor/speedhack64.dll +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "trainerbase"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.16.0"
|
|
4
4
|
description = "Framework for creating game trainers/mods"
|
|
5
5
|
authors = ["v01d <v01d@v01d.ru>", "doomayka <zd@doomayka.ru>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -17,7 +17,7 @@ include = [
|
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
[tool.poetry.group.dev.dependencies]
|
|
20
|
-
ruff = "^0.4.
|
|
20
|
+
ruff = "^0.4.10"
|
|
21
21
|
|
|
22
22
|
[tool.ruff]
|
|
23
23
|
src = ["trainerbase"]
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
from collections.abc import Iterator, Sequence
|
|
1
|
+
from collections.abc import Callable, Iterator, Sequence
|
|
2
|
+
from contextlib import suppress
|
|
3
|
+
from functools import wraps
|
|
2
4
|
from typing import overload
|
|
3
5
|
from uuid import uuid4
|
|
4
6
|
|
|
7
|
+
from pymem.exception import MemoryReadError, MemoryWriteError
|
|
8
|
+
|
|
5
9
|
from trainerbase.gameobject import AbstractReadableObject, GameObject
|
|
6
10
|
from trainerbase.memory import POINTER_SIZE, Address, allocate, pm
|
|
7
11
|
|
|
@@ -119,3 +123,12 @@ def regenerate(
|
|
|
119
123
|
):
|
|
120
124
|
if current_value.value < max_value.value:
|
|
121
125
|
current_value.value += max(round(max_value.value * percent / 100), min_value)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def suppress_memory_exceptions[**P, T](callback: Callable[P, T]) -> Callable[P, T | None]:
|
|
129
|
+
@wraps(callback)
|
|
130
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T | None:
|
|
131
|
+
with suppress(MemoryReadError, MemoryWriteError):
|
|
132
|
+
return callback(*args, **kwargs)
|
|
133
|
+
|
|
134
|
+
return wrapper
|
|
@@ -24,7 +24,7 @@ class SimpleSwitchable(Switchable):
|
|
|
24
24
|
|
|
25
25
|
class SimpleHotkeyHandler(AbstractKeyboardHandler):
|
|
26
26
|
def __init__(self, callback: Callable[[], None], hotkey: str):
|
|
27
|
-
self.
|
|
27
|
+
self.callback = callback
|
|
28
28
|
self._hotkey = hotkey
|
|
29
29
|
|
|
30
30
|
@property
|
|
@@ -34,7 +34,7 @@ class SimpleHotkeyHandler(AbstractKeyboardHandler):
|
|
|
34
34
|
|
|
35
35
|
@override
|
|
36
36
|
def handle(self):
|
|
37
|
-
add_hotkey(self._hotkey, self.
|
|
37
|
+
add_hotkey(self._hotkey, self.callback)
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class ReleaseHotkeySwitch(AbstractKeyboardHandler):
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from collections.abc import Iterable, Iterator
|
|
2
|
+
from itertools import cycle
|
|
3
|
+
|
|
4
|
+
from dearpygui import dearpygui as dpg
|
|
5
|
+
|
|
6
|
+
from trainerbase.scriptengine import Script, rainbow_script_engine
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type TagList = list[int | str]
|
|
10
|
+
type Color = tuple[int, int, int]
|
|
11
|
+
type Colors = Iterable[Color]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GradientUpdater:
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self.tags: TagList | None = None
|
|
17
|
+
self.colors: list[Color] | None = None
|
|
18
|
+
self.index_iter: Iterator[int] | None = None
|
|
19
|
+
self.initial_color: Color | None = None
|
|
20
|
+
self.initial_delta: tuple[int, int, int] | None = None
|
|
21
|
+
self.color_length: int | None = None
|
|
22
|
+
|
|
23
|
+
def __call__(self):
|
|
24
|
+
if self.tags is None or self.colors is None:
|
|
25
|
+
raise RuntimeError("Call setup(...)")
|
|
26
|
+
|
|
27
|
+
for tag, color in zip(self.tags, self.get_colors(len(self.tags))):
|
|
28
|
+
dpg.configure_item(tag, color=color)
|
|
29
|
+
|
|
30
|
+
def setup(
|
|
31
|
+
self,
|
|
32
|
+
*,
|
|
33
|
+
tags: TagList | None = None,
|
|
34
|
+
initial_color: Color | None = None,
|
|
35
|
+
initial_delta: tuple[int, int, int] | None = None,
|
|
36
|
+
color_length: int | None = None,
|
|
37
|
+
) -> None:
|
|
38
|
+
if tags is not None:
|
|
39
|
+
self.tags = tags
|
|
40
|
+
self.colors = self.generate_colors(len(tags))
|
|
41
|
+
self.index_iter = cycle(range(len(self.colors)))
|
|
42
|
+
|
|
43
|
+
if initial_color is not None:
|
|
44
|
+
self.initial_color = initial_color
|
|
45
|
+
|
|
46
|
+
if initial_delta is not None:
|
|
47
|
+
self.initial_delta = initial_delta
|
|
48
|
+
|
|
49
|
+
if color_length is not None:
|
|
50
|
+
self.color_length = color_length
|
|
51
|
+
|
|
52
|
+
def generate_colors(self, length: int) -> list[Color]:
|
|
53
|
+
if self.initial_color is None or self.initial_delta is None or self.color_length is None:
|
|
54
|
+
raise RuntimeError("Call setup(...)")
|
|
55
|
+
|
|
56
|
+
red, green, blue = self.initial_color
|
|
57
|
+
delta_red, delta_green, delta_blue = self.initial_delta
|
|
58
|
+
|
|
59
|
+
colors = []
|
|
60
|
+
|
|
61
|
+
for _ in range(length // 2):
|
|
62
|
+
for _ in range(self.color_length):
|
|
63
|
+
colors.append((red, green, blue))
|
|
64
|
+
|
|
65
|
+
red, delta_red = self.next_color_channel_value(red, delta_red)
|
|
66
|
+
green, delta_green = self.next_color_channel_value(green, delta_green)
|
|
67
|
+
blue, delta_blue = self.next_color_channel_value(blue, delta_blue)
|
|
68
|
+
|
|
69
|
+
colors = colors + colors[::-1]
|
|
70
|
+
|
|
71
|
+
return colors
|
|
72
|
+
|
|
73
|
+
def get_colors(self, n: int) -> Colors:
|
|
74
|
+
if self.colors is None or self.index_iter is None:
|
|
75
|
+
raise RuntimeError("Call setup(...)")
|
|
76
|
+
|
|
77
|
+
index = next(self.index_iter)
|
|
78
|
+
|
|
79
|
+
colors = self.colors[index : index + n]
|
|
80
|
+
|
|
81
|
+
if len(colors) < n:
|
|
82
|
+
colors += self.colors[: n - len(colors)]
|
|
83
|
+
|
|
84
|
+
return colors
|
|
85
|
+
|
|
86
|
+
def next_color_channel_value(self, current: int, delta: int) -> tuple[int, int]:
|
|
87
|
+
if not (0 <= current + delta <= 255):
|
|
88
|
+
delta = -delta
|
|
89
|
+
|
|
90
|
+
return current + delta, delta
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
gradient_updater = GradientUpdater()
|
|
94
|
+
rainbow_script_engine.register_script(Script(gradient_updater, enabled=True))
|
|
@@ -3,6 +3,8 @@ from functools import wraps
|
|
|
3
3
|
|
|
4
4
|
from dearpygui import dearpygui as dpg
|
|
5
5
|
|
|
6
|
+
from trainerbase.common.rainbow import Color, gradient_updater
|
|
7
|
+
from trainerbase.gui.rainbow import RainbowUI
|
|
6
8
|
from trainerbase.gui.types import AbstractUIComponent
|
|
7
9
|
|
|
8
10
|
|
|
@@ -11,10 +13,17 @@ def add_components(*components: AbstractUIComponent):
|
|
|
11
13
|
component.add_to_ui()
|
|
12
14
|
|
|
13
15
|
|
|
14
|
-
def simple_trainerbase_menu(
|
|
15
|
-
|
|
16
|
+
def simple_trainerbase_menu(
|
|
17
|
+
window_title: str,
|
|
18
|
+
width: int,
|
|
19
|
+
height: int,
|
|
20
|
+
rainbow_initial_color: Color = (1, 255, 125),
|
|
21
|
+
rainbow_initial_delta: tuple[int, int, int] = (1, 1, 1),
|
|
22
|
+
rainbow_color_length: int = 3,
|
|
23
|
+
):
|
|
24
|
+
def menu_decorator(initializer: Callable[[], None]):
|
|
16
25
|
@wraps(initializer)
|
|
17
|
-
def run_menu_wrapper(on_initialized: Callable):
|
|
26
|
+
def run_menu_wrapper(on_initialized: Callable[[], None]):
|
|
18
27
|
dpg.create_context()
|
|
19
28
|
dpg.create_viewport(
|
|
20
29
|
title=window_title,
|
|
@@ -34,6 +43,14 @@ def simple_trainerbase_menu(window_title: str, width: int, height: int):
|
|
|
34
43
|
horizontal_scrollbar=True,
|
|
35
44
|
autosize=True,
|
|
36
45
|
):
|
|
46
|
+
gradient_updater.setup(
|
|
47
|
+
initial_color=rainbow_initial_color,
|
|
48
|
+
initial_delta=rainbow_initial_delta,
|
|
49
|
+
color_length=rainbow_color_length,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
add_components(RainbowUI(width, gradient_updater))
|
|
53
|
+
|
|
37
54
|
initializer()
|
|
38
55
|
|
|
39
56
|
dpg.set_primary_window("menu", value=True)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from traceback import print_exc
|
|
1
2
|
from typing import override
|
|
2
3
|
from uuid import uuid4
|
|
3
4
|
|
|
@@ -41,8 +42,9 @@ class CodeInjectionUI(AbstractUIComponent):
|
|
|
41
42
|
|
|
42
43
|
try:
|
|
43
44
|
change_codeinjection_state()
|
|
44
|
-
except (MemoryReadError, MemoryWriteError):
|
|
45
|
+
except (MemoryReadError, MemoryWriteError, ValueError):
|
|
45
46
|
dpg.set_value(self.dpg_tag, not dpg.get_value(self.dpg_tag))
|
|
47
|
+
print_exc()
|
|
46
48
|
|
|
47
49
|
def on_hotkey_press(self):
|
|
48
50
|
dpg.set_value(self.dpg_tag, not dpg.get_value(self.dpg_tag))
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from typing import override
|
|
2
|
-
from uuid import uuid4
|
|
3
2
|
|
|
4
3
|
from dearpygui import dearpygui as dpg
|
|
5
4
|
|
|
6
|
-
from trainerbase.common.keyboard import
|
|
5
|
+
from trainerbase.common.keyboard import (
|
|
6
|
+
AbstractKeyboardHandler,
|
|
7
|
+
ReleaseHotkeySwitch,
|
|
8
|
+
ShortLongHotkeyPressSwitch,
|
|
9
|
+
SimpleHotkeyHandler,
|
|
10
|
+
)
|
|
7
11
|
from trainerbase.gui.types import AbstractUIComponent
|
|
8
12
|
|
|
9
13
|
|
|
@@ -33,27 +37,25 @@ class TextUI(AbstractUIComponent):
|
|
|
33
37
|
|
|
34
38
|
|
|
35
39
|
class HotkeyHandlerUI(AbstractUIComponent):
|
|
36
|
-
DPG_TAG_PREFIX = "switch__"
|
|
37
|
-
|
|
38
40
|
def __init__(
|
|
39
41
|
self,
|
|
40
42
|
handler: AbstractKeyboardHandler,
|
|
41
43
|
label: str,
|
|
42
44
|
):
|
|
43
45
|
self.handler = handler
|
|
44
|
-
self.dpg_tag_press = f"{self.DPG_TAG_PREFIX}{uuid4()}_press"
|
|
45
|
-
self.dpg_tag_hold = f"{self.DPG_TAG_PREFIX}{uuid4()}_hold"
|
|
46
46
|
self.label = label
|
|
47
47
|
|
|
48
48
|
@override
|
|
49
49
|
def add_to_ui(self) -> None:
|
|
50
50
|
match self.handler:
|
|
51
51
|
case ShortLongHotkeyPressSwitch():
|
|
52
|
-
dpg.add_text(f"Hold [{self.handler.hotkey}] Enable {self.label}"
|
|
53
|
-
dpg.add_text(f"Press [{self.handler.hotkey}] Toggle {self.label}"
|
|
52
|
+
dpg.add_text(f"Hold [{self.handler.hotkey}] Enable {self.label}")
|
|
53
|
+
dpg.add_text(f"Press [{self.handler.hotkey}] Toggle {self.label}")
|
|
54
54
|
case ReleaseHotkeySwitch():
|
|
55
|
-
dpg.add_text(f"[{self.handler.hotkey}] Toggle {self.label}"
|
|
55
|
+
dpg.add_text(f"[{self.handler.hotkey}] Toggle {self.label}")
|
|
56
|
+
case SimpleHotkeyHandler():
|
|
57
|
+
dpg.add_button(label=f"[{self.handler.hotkey}] {self.label}", callback=self.handler.callback)
|
|
56
58
|
case _:
|
|
57
|
-
dpg.add_text(f"[{self.handler.hotkey}] {self.label}"
|
|
59
|
+
dpg.add_text(f"[{self.handler.hotkey}] {self.label}")
|
|
58
60
|
|
|
59
61
|
self.handler.handle()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import override
|
|
2
|
+
|
|
3
|
+
from dearpygui import dearpygui as dpg
|
|
4
|
+
|
|
5
|
+
from trainerbase.common.rainbow import GradientUpdater
|
|
6
|
+
from trainerbase.gui.types import AbstractUIComponent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RainbowUI(AbstractUIComponent):
|
|
10
|
+
def __init__(self, width: int, gradient_updater: GradientUpdater) -> None:
|
|
11
|
+
self.gradient_updater = gradient_updater
|
|
12
|
+
self.width = width
|
|
13
|
+
|
|
14
|
+
@override
|
|
15
|
+
def add_to_ui(self) -> None:
|
|
16
|
+
dpg.add_spacer()
|
|
17
|
+
dpg.add_spacer()
|
|
18
|
+
tags = [dpg.draw_line([-10.0 + i, 0.0], [1.0 + i, 0.0], thickness=2) for i in range(self.width)]
|
|
19
|
+
|
|
20
|
+
self.gradient_updater.setup(tags=tags)
|
|
21
|
+
|
|
22
|
+
return super().add_to_ui()
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
from collections.abc import Callable
|
|
2
2
|
from os import _exit as force_exit
|
|
3
|
-
from
|
|
4
|
-
from traceback import format_exc
|
|
3
|
+
from traceback import print_exc
|
|
5
4
|
from typing import NoReturn
|
|
6
5
|
|
|
7
6
|
from trainerbase.codeinjection import safely_eject_all_code_injections
|
|
8
7
|
from trainerbase.gameobject import update_frozen_objects
|
|
9
8
|
from trainerbase.gui.objects import update_displayed_objects
|
|
10
9
|
from trainerbase.process import show_message_and_shutdown_if_process_exited
|
|
11
|
-
from trainerbase.scriptengine import
|
|
10
|
+
from trainerbase.scriptengine import (
|
|
11
|
+
Script,
|
|
12
|
+
process_healthcheck_script_engine,
|
|
13
|
+
rainbow_script_engine,
|
|
14
|
+
system_script_engine,
|
|
15
|
+
)
|
|
12
16
|
from trainerbase.speedhack import SpeedHack
|
|
13
17
|
|
|
14
18
|
|
|
@@ -20,6 +24,8 @@ def run( # pylint: disable=too-complex
|
|
|
20
24
|
def on_shutdown() -> NoReturn:
|
|
21
25
|
system_script_engine.stop()
|
|
22
26
|
process_healthcheck_script_engine.stop()
|
|
27
|
+
rainbow_script_engine.stop()
|
|
28
|
+
|
|
23
29
|
safely_eject_all_code_injections()
|
|
24
30
|
SpeedHack.disable()
|
|
25
31
|
|
|
@@ -31,12 +37,13 @@ def run( # pylint: disable=too-complex
|
|
|
31
37
|
def on_gui_initialized() -> None:
|
|
32
38
|
system_script_engine.start()
|
|
33
39
|
process_healthcheck_script_engine.start()
|
|
40
|
+
rainbow_script_engine.start()
|
|
34
41
|
|
|
35
42
|
if on_gui_initialized_hook is not None:
|
|
36
43
|
try:
|
|
37
44
|
on_gui_initialized_hook()
|
|
38
45
|
except Exception:
|
|
39
|
-
|
|
46
|
+
print_exc()
|
|
40
47
|
on_shutdown()
|
|
41
48
|
|
|
42
49
|
system_script_engine.register_script(Script(update_frozen_objects, enabled=True))
|
|
@@ -46,6 +53,6 @@ def run( # pylint: disable=too-complex
|
|
|
46
53
|
try:
|
|
47
54
|
run_gui(on_gui_initialized)
|
|
48
55
|
except Exception:
|
|
49
|
-
|
|
56
|
+
print_exc()
|
|
50
57
|
|
|
51
58
|
on_shutdown()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|