trainerbase 4.2.5__tar.gz → 4.4.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.
Files changed (40) hide show
  1. {trainerbase-4.2.5 → trainerbase-4.4.0}/LICENSE +2 -2
  2. {trainerbase-4.2.5 → trainerbase-4.4.0}/PKG-INFO +5 -5
  3. {trainerbase-4.2.5 → trainerbase-4.4.0}/pyproject.toml +3 -4
  4. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gameobject.py +1 -7
  5. trainerbase-4.4.0/trainerbase/gui/misc.py +143 -0
  6. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/speedhack.py +30 -1
  7. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/scriptengine.py +1 -1
  8. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/speedhack.py +2 -7
  9. trainerbase-4.2.5/trainerbase/gui/misc.py +0 -80
  10. {trainerbase-4.2.5 → trainerbase-4.4.0}/.gitignore +0 -0
  11. {trainerbase-4.2.5 → trainerbase-4.4.0}/README.md +0 -0
  12. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/__init__.py +0 -0
  13. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/abc.py +0 -0
  14. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/codeinjection.py +0 -0
  15. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/__init__.py +0 -0
  16. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/abc.py +0 -0
  17. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/helpers.py +0 -0
  18. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/keyboard.py +0 -0
  19. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/rainbow.py +0 -0
  20. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/tapper.py +0 -0
  21. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/teleport.py +0 -0
  22. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/config.py +0 -0
  23. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/__init__.py +0 -0
  24. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/helpers.py +0 -0
  25. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/injections.py +0 -0
  26. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/objects.py +0 -0
  27. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/rainbow.py +0 -0
  28. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/scripts.py +0 -0
  29. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/tapper.py +0 -0
  30. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/teleport.py +0 -0
  31. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/types.py +0 -0
  32. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/logger.py +0 -0
  33. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/main.py +0 -0
  34. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/memory.py +0 -0
  35. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/process.py +0 -0
  36. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/py.typed +0 -0
  37. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/tts.py +0 -0
  38. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase_vendor/FASM.EXE +0 -0
  39. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase_vendor/speedhack32.dll +0 -0
  40. {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase_vendor/speedhack64.dll +0 -0
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 - 2024 v01d
4
- Copyright (c) 2022 - 2024 doomayka
3
+ Copyright (c) 2021 - 2025 v01d
4
+ Copyright (c) 2022 - 2025 doomayka
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  of this software and associated documentation files (the "Software"), to deal
@@ -1,19 +1,19 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: trainerbase
3
- Version: 4.2.5
3
+ Version: 4.4.0
4
4
  Summary: Framework for creating game trainers/mods
5
5
  Project-URL: Homepage, https://gitlab.com/python-trainers/
6
6
  Project-URL: Repository, https://gitlab.com/python-trainers/trainer-base
7
7
  Author-email: v01d <v01d@v01d.ru>, doomayka <zd@doomayka.ru>
8
- License: MIT
9
- Classifier: Programming Language :: Python :: 3.12
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
10
  Classifier: Programming Language :: Python :: 3.13
11
11
  Classifier: Programming Language :: Python :: Implementation :: CPython
12
12
  Requires-Python: >=3.13
13
13
  Requires-Dist: dearpygui>=2.0.0
14
14
  Requires-Dist: keyboard>=0.13.5
15
15
  Requires-Dist: mouse>=0.7.1
16
- Requires-Dist: psutil>=6.1.0
16
+ Requires-Dist: psutil>=6.1.1
17
17
  Requires-Dist: pyinjector>=1.3.0
18
18
  Requires-Dist: pymem>=1.14.0
19
19
  Requires-Dist: pyttsx3>=2.98
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "trainerbase"
3
- version = "4.2.5"
3
+ version = "4.4.0"
4
4
  description = "Framework for creating game trainers/mods"
5
5
  license = "MIT"
6
6
  authors = [
@@ -13,7 +13,7 @@ dependencies = [
13
13
  "dearpygui>=2.0.0",
14
14
  "keyboard>=0.13.5",
15
15
  "mouse>=0.7.1",
16
- "psutil>=6.1.0",
16
+ "psutil>=6.1.1",
17
17
  "pyinjector>=1.3.0",
18
18
  "pymem>=1.14.0",
19
19
  "pyttsx3>=2.98",
@@ -21,7 +21,6 @@ dependencies = [
21
21
 
22
22
  classifiers = [
23
23
  "Programming Language :: Python :: Implementation :: CPython",
24
- "Programming Language :: Python :: 3.12",
25
24
  "Programming Language :: Python :: 3.13",
26
25
  ]
27
26
 
@@ -74,5 +73,5 @@ build-backend = "hatchling.build"
74
73
 
75
74
  [dependency-groups]
76
75
  dev = [
77
- "ruff>=0.8.2",
76
+ "ruff>=0.8.6",
78
77
  ]
@@ -52,13 +52,7 @@ class GameObject[PymemType, TrainerBaseType](AbstractReadableObject[TrainerBaseT
52
52
  self.value_range = value_range
53
53
 
54
54
  def __repr__(self):
55
- return (
56
- f"<{self.__class__.__name__}"
57
- f" at {hex(self.address.resolve())}:"
58
- f" value={self.value},"
59
- f" frozen={self.frozen}"
60
- ">"
61
- )
55
+ return f"<{self.__class__.__name__} at {hex(self.address.resolve())}: value={self.value}, frozen={self.frozen}>"
62
56
 
63
57
  def after_read(self, value: PymemType) -> TrainerBaseType:
64
58
  return cast(TrainerBaseType, value)
@@ -0,0 +1,143 @@
1
+ from collections.abc import Callable
2
+ from typing import Any, override
3
+
4
+ from dearpygui import dearpygui as dpg
5
+
6
+ from trainerbase.common.keyboard import (
7
+ AbstractKeyboardHandler,
8
+ GameBoolReleaseHotkeySwitch,
9
+ ReleaseHotkeySwitch,
10
+ ShortLongHotkeyPressSwitch,
11
+ SimpleHotkeyHandler,
12
+ )
13
+ from trainerbase.gameobject import GameBool
14
+ from trainerbase.gui.helpers import add_components
15
+ from trainerbase.gui.objects import GameObjectUI
16
+ from trainerbase.gui.types import AbstractUIComponent
17
+
18
+
19
+ class SeparatorUI(AbstractUIComponent):
20
+ def __init__(self, empty_lines_before: int = 1, empty_lines_after: int = 0):
21
+ self._empty_lines_before = empty_lines_before
22
+ self._empty_lines_after = empty_lines_after
23
+
24
+ @override
25
+ def add_to_ui(self) -> None:
26
+ for _ in range(self._empty_lines_before):
27
+ dpg.add_text()
28
+
29
+ dpg.add_separator()
30
+
31
+ for _ in range(self._empty_lines_after):
32
+ dpg.add_text()
33
+
34
+
35
+ class TextUI(AbstractUIComponent):
36
+ def __init__(self, text: str = ""):
37
+ self.text = text
38
+
39
+ @override
40
+ def add_to_ui(self) -> None:
41
+ dpg.add_text(self.text)
42
+
43
+
44
+ class HotkeyHandlerUI(AbstractUIComponent):
45
+ def __init__(
46
+ self,
47
+ handler: AbstractKeyboardHandler,
48
+ label: str,
49
+ ):
50
+ self.handler = handler
51
+ self.label = label
52
+
53
+ @override
54
+ def add_to_ui(self) -> None:
55
+ match self.handler:
56
+ case ShortLongHotkeyPressSwitch():
57
+ dpg.add_text(f"Press/Hold [{self.handler.hotkey}] Toggle/Enable {self.label}")
58
+ case ReleaseHotkeySwitch():
59
+ dpg.add_text(f"[{self.handler.hotkey}] Toggle {self.label}")
60
+ case SimpleHotkeyHandler():
61
+ dpg.add_button(
62
+ label=f"[{self.handler.hotkey}] {self.label}",
63
+ callback=self._ensure_callable_has_dunder_code(self.handler.callback),
64
+ )
65
+ case _:
66
+ dpg.add_text(f"[{self.handler.hotkey}] {self.label}")
67
+
68
+ self.handler.handle()
69
+
70
+ @staticmethod
71
+ def _ensure_callable_has_dunder_code(callable_object: Callable[[], None]) -> Callable[[], None]:
72
+ """
73
+ DPG add_button has `callback` arg. In this case `callback.__code__` is required.
74
+ """
75
+
76
+ if hasattr(callable, "__code__"):
77
+ callback_with_dunder_code = callable_object
78
+ else:
79
+
80
+ def callback_with_dunder_code():
81
+ callable_object()
82
+
83
+ return callback_with_dunder_code
84
+
85
+
86
+ class HorizontalUI(AbstractUIComponent):
87
+ def __init__(self, *components: AbstractUIComponent):
88
+ self.components = components
89
+
90
+ @override
91
+ def add_to_ui(self) -> None:
92
+ with dpg.group(horizontal=True):
93
+ add_components(*self.components)
94
+
95
+ return super().add_to_ui()
96
+
97
+
98
+ class SwitchableGameBoolUI(AbstractUIComponent):
99
+ def __init__(
100
+ self,
101
+ gameobject: GameBool,
102
+ toggle_hotkey: str,
103
+ label: str,
104
+ freeze_hotkey: str | None = None,
105
+ set_hotkey: str | None = None,
106
+ *,
107
+ default_setter_input_value: Any = 0,
108
+ before_set: Callable | None = None,
109
+ tts_on_hotkey: bool = True,
110
+ setter_input_width: int = 220,
111
+ toggle_text: str = "Toggle",
112
+ ):
113
+ self.gameobject = gameobject
114
+ self.toggle_hotkey = toggle_hotkey
115
+ self.toggle_text = toggle_text
116
+
117
+ self.pure_label = label
118
+ self.freeze_hotkey = freeze_hotkey
119
+ self.set_hotkey = set_hotkey
120
+ self.default_setter_input_value = default_setter_input_value
121
+ self.before_set = before_set
122
+ self.tts_on_hotkey = tts_on_hotkey
123
+ self.setter_input_width = setter_input_width
124
+
125
+ @override
126
+ def add_to_ui(self) -> None:
127
+ add_components(
128
+ HorizontalUI(
129
+ HotkeyHandlerUI(GameBoolReleaseHotkeySwitch(self.gameobject, self.toggle_hotkey), self.toggle_text),
130
+ GameObjectUI(
131
+ self.gameobject,
132
+ self.pure_label,
133
+ self.freeze_hotkey,
134
+ self.set_hotkey,
135
+ default_setter_input_value=self.default_setter_input_value,
136
+ before_set=self.before_set,
137
+ tts_on_hotkey=self.tts_on_hotkey,
138
+ setter_input_width=self.setter_input_width,
139
+ ),
140
+ )
141
+ )
142
+
143
+ return super().add_to_ui()
@@ -1,8 +1,9 @@
1
+ from functools import partial
1
2
  from typing import override
2
3
 
3
4
  from dearpygui import dearpygui as dpg
4
5
 
5
- from trainerbase.common.keyboard import ShortLongHotkeyPressSwitch, Switchable
6
+ from trainerbase.common.keyboard import ShortLongHotkeyPressSwitch, SimpleHotkeyHandler, Switchable
6
7
  from trainerbase.gui.helpers import add_components
7
8
  from trainerbase.gui.misc import HotkeyHandlerUI
8
9
  from trainerbase.gui.types import AbstractUIComponent
@@ -34,9 +35,15 @@ class SpeedHackUI(AbstractUIComponent):
34
35
  speedhack: SpeedHack | None = None,
35
36
  key: str = "Delete",
36
37
  default_factor_input_value: float = 3.0,
38
+ next_preset_hotkey: str | None = "Shift+PageUp",
39
+ previous_preset_hotkey: str | None = "Shift+PageDown",
37
40
  ):
38
41
  self.speedhack = SpeedHack() if speedhack is None else speedhack
42
+
39
43
  self.key = key
44
+ self.next_preset_hotkey = next_preset_hotkey
45
+ self.previous_preset_hotkey = previous_preset_hotkey
46
+
40
47
  self.default_factor_input_value = default_factor_input_value
41
48
  self.handler = ShortLongHotkeyPressSwitch(
42
49
  SpeedHackUISwitch(self.speedhack, self.DPG_TAG_SPEEDHACK_FACTOR_INPUT),
@@ -47,6 +54,19 @@ class SpeedHackUI(AbstractUIComponent):
47
54
  def add_to_ui(self) -> None:
48
55
  add_components(HotkeyHandlerUI(self.handler, "SpeedHack"))
49
56
 
57
+ if self.next_preset_hotkey is not None and self.previous_preset_hotkey is not None:
58
+ with dpg.group(horizontal=True):
59
+ add_components(
60
+ HotkeyHandlerUI(
61
+ SimpleHotkeyHandler(partial(self.change_preset, -1), self.previous_preset_hotkey),
62
+ "Preset -",
63
+ ),
64
+ HotkeyHandlerUI(
65
+ SimpleHotkeyHandler(partial(self.change_preset, 1), self.next_preset_hotkey),
66
+ "Preset +",
67
+ ),
68
+ )
69
+
50
70
  dpg.add_input_double(
51
71
  tag=self.DPG_TAG_SPEEDHACK_FACTOR_INPUT,
52
72
  label="SpeedHack Factor",
@@ -68,6 +88,15 @@ class SpeedHackUI(AbstractUIComponent):
68
88
  callback=self.on_preset_change,
69
89
  )
70
90
 
91
+ def change_preset(self, diff: int):
92
+ new_preset_index = dpg.get_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT) + diff
93
+
94
+ if not (0 <= new_preset_index < len(self.PRESETS)):
95
+ return
96
+
97
+ dpg.set_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT, new_preset_index)
98
+ self.on_preset_change()
99
+
71
100
  def on_preset_change(self):
72
101
  new_factor = self.PRESETS[dpg.get_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT)]
73
102
  dpg.set_value(self.DPG_TAG_SPEEDHACK_FACTOR_INPUT, new_factor)
@@ -36,7 +36,7 @@ class SimpleScript(AbstractBaseScript):
36
36
  self.enabled = enabled
37
37
 
38
38
  def __repr__(self):
39
- return f"<Script {getattr(self._callback, "__name__", "Anon function-based script")}: enabled={self.enabled}>"
39
+ return f"<Script {getattr(self._callback, '__name__', 'Anon function-based script')}: enabled={self.enabled}>"
40
40
 
41
41
  @override
42
42
  def __call__(self):
@@ -4,11 +4,9 @@ from typing import Final, Self, cast
4
4
 
5
5
  from pyinjector import inject
6
6
  from pymem.exception import MemoryWriteError
7
- from pymem.process import module_from_name
8
- from pymem.ressources.structure import MODULEINFO
9
7
 
10
8
  from trainerbase.gameobject import GameDouble
11
- from trainerbase.memory import ARCH
9
+ from trainerbase.memory import ARCH, get_module_address
12
10
  from trainerbase.process import pm
13
11
 
14
12
 
@@ -36,10 +34,7 @@ class SpeedHack:
36
34
 
37
35
  def _inject(self) -> int:
38
36
  inject(cast(int, pm.process_id), str(SPEEDHACK_DLL_PATH))
39
-
40
- speedhack_address = cast(MODULEINFO, module_from_name(pm.process_handle, SPEEDHACK_DLL_MODULE_NAME)).lpBaseOfDll
41
-
42
- return speedhack_address
37
+ return get_module_address(SPEEDHACK_DLL_MODULE_NAME)
43
38
 
44
39
  @property
45
40
  def factor(self):
@@ -1,80 +0,0 @@
1
- from collections.abc import Callable
2
- from typing import override
3
-
4
- from dearpygui import dearpygui as dpg
5
-
6
- from trainerbase.common.keyboard import (
7
- AbstractKeyboardHandler,
8
- ReleaseHotkeySwitch,
9
- ShortLongHotkeyPressSwitch,
10
- SimpleHotkeyHandler,
11
- )
12
- from trainerbase.gui.types import AbstractUIComponent
13
-
14
-
15
- class SeparatorUI(AbstractUIComponent):
16
- def __init__(self, empty_lines_before: int = 1, empty_lines_after: int = 0):
17
- self._empty_lines_before = empty_lines_before
18
- self._empty_lines_after = empty_lines_after
19
-
20
- @override
21
- def add_to_ui(self) -> None:
22
- for _ in range(self._empty_lines_before):
23
- dpg.add_text()
24
-
25
- dpg.add_separator()
26
-
27
- for _ in range(self._empty_lines_after):
28
- dpg.add_text()
29
-
30
-
31
- class TextUI(AbstractUIComponent):
32
- def __init__(self, text: str = ""):
33
- self.text = text
34
-
35
- @override
36
- def add_to_ui(self) -> None:
37
- dpg.add_text(self.text)
38
-
39
-
40
- class HotkeyHandlerUI(AbstractUIComponent):
41
- def __init__(
42
- self,
43
- handler: AbstractKeyboardHandler,
44
- label: str,
45
- ):
46
- self.handler = handler
47
- self.label = label
48
-
49
- @override
50
- def add_to_ui(self) -> None:
51
- match self.handler:
52
- case ShortLongHotkeyPressSwitch():
53
- dpg.add_text(f"Hold [{self.handler.hotkey}] Enable {self.label}")
54
- dpg.add_text(f"Press [{self.handler.hotkey}] Toggle {self.label}")
55
- case ReleaseHotkeySwitch():
56
- dpg.add_text(f"[{self.handler.hotkey}] Toggle {self.label}")
57
- case SimpleHotkeyHandler():
58
- dpg.add_button(
59
- label=f"[{self.handler.hotkey}] {self.label}",
60
- callback=self._ensure_callable_has_dunder_code(self.handler.callback),
61
- )
62
- case _:
63
- dpg.add_text(f"[{self.handler.hotkey}] {self.label}")
64
-
65
- self.handler.handle()
66
-
67
- @staticmethod
68
- def _ensure_callable_has_dunder_code(callable_object: Callable[[], None]) -> Callable[[], None]:
69
- """
70
- DPG add_button has `callback` arg. In this case `callback.__code__` is required.
71
- """
72
-
73
- if hasattr(callable, "__code__"):
74
- callback_with_dunder_code = callable_object
75
- else:
76
-
77
- def callback_with_dunder_code():
78
- callable_object()
79
-
80
- return callback_with_dunder_code
File without changes
File without changes