trainerbase 3.13.0__tar.gz → 3.14.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 (31) hide show
  1. {trainerbase-3.13.0 → trainerbase-3.14.0}/PKG-INFO +1 -1
  2. {trainerbase-3.13.0 → trainerbase-3.14.0}/pyproject.toml +1 -1
  3. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/codeinjection.py +7 -2
  4. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/common/helpers.py +17 -4
  5. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/helpers.py +3 -2
  6. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/memory.py +36 -2
  7. {trainerbase-3.13.0 → trainerbase-3.14.0}/LICENSE +0 -0
  8. {trainerbase-3.13.0 → trainerbase-3.14.0}/README.md +0 -0
  9. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/__init__.py +0 -0
  10. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/common/__init__.py +0 -0
  11. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/common/abc.py +0 -0
  12. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/common/keyboard.py +0 -0
  13. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/common/teleport.py +0 -0
  14. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/config.py +0 -0
  15. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gameobject.py +0 -0
  16. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/__init__.py +0 -0
  17. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/injections.py +0 -0
  18. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/misc.py +0 -0
  19. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/objects.py +0 -0
  20. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/scripts.py +0 -0
  21. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/speedhack.py +0 -0
  22. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/teleport.py +0 -0
  23. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/gui/types.py +0 -0
  24. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/main.py +0 -0
  25. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/process.py +0 -0
  26. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/scriptengine.py +0 -0
  27. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/speedhack.py +0 -0
  28. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase/tts.py +0 -0
  29. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase_vendor/FASM.EXE +0 -0
  30. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase_vendor/speedhack32.dll +0 -0
  31. {trainerbase-3.13.0 → trainerbase-3.14.0}/trainerbase_vendor/speedhack64.dll +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trainerbase
3
- Version: 3.13.0
3
+ Version: 3.14.0
4
4
  Summary: Framework for creating game trainers/mods
5
5
  Home-page: https://gitlab.com/python-trainers/trainer-base
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "trainerbase"
3
- version = "3.13.0"
3
+ version = "3.14.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"
@@ -8,7 +8,7 @@ from typing import ClassVar, Final, Self, override
8
8
 
9
9
  from pymem.exception import MemoryWriteError
10
10
 
11
- from trainerbase.memory import ARCH, ConvertibleToAddress, ensure_address, pm
11
+ from trainerbase.memory import ARCH, ConvertibleToAddress, allocate, ensure_address, pm
12
12
 
13
13
 
14
14
  FASM_EXECUTABLE_PATH: Final[Path] = Path(__file__).resolve().parent.parent / "trainerbase_vendor" / "FASM.EXE"
@@ -67,9 +67,11 @@ class AllocatingCodeInjection(AbstractCodeInjection): # pylint: disable=too-man
67
67
  self,
68
68
  address: ConvertibleToAddress,
69
69
  code_to_inject: Code,
70
+ *,
70
71
  original_code_length: int = 0,
71
72
  new_memory_size: int = 1024,
72
73
  is_long_x64_jump_needed: bool | None = None,
74
+ experimental_allocate_nearest_to_injection_point: bool = False,
73
75
  ):
74
76
  if is_long_x64_jump_needed is None:
75
77
  is_long_x64_jump_needed = pm.is_64_bit
@@ -88,11 +90,14 @@ class AllocatingCodeInjection(AbstractCodeInjection): # pylint: disable=too-man
88
90
  self.new_memory_address: int = 0
89
91
  self.injection_point: int = 0
90
92
 
93
+ self._experimental_allocate_nearest_to_injection_point = experimental_allocate_nearest_to_injection_point
94
+
91
95
  @override
92
96
  def inject(self):
93
97
  self.injection_point = self.address.resolve()
94
98
 
95
- self.new_memory_address: int = pm.allocate(self.new_memory_size)
99
+ nearest_to = self.injection_point if self._experimental_allocate_nearest_to_injection_point else None
100
+ self.new_memory_address: int = allocate(self.new_memory_size, nearest_to=nearest_to)
96
101
 
97
102
  self.original_code = pm.read_bytes(self.injection_point, self.original_code_length)
98
103
 
@@ -1,4 +1,5 @@
1
1
  from collections.abc import Iterator, Sequence
2
+ from typing import overload
2
3
  from uuid import uuid4
3
4
 
4
5
  from trainerbase.gameobject import AbstractReadableObject, GameObject
@@ -30,11 +31,17 @@ class ASMArrayManager(Sequence):
30
31
  def __len__(self) -> int:
31
32
  return self.array_length
32
33
 
33
- def __getitem__(self, index: int) -> Address: # type: ignore TODO: Support slices
34
- element_address = self.get_pointer_to_element(index)
35
- target_address = Address(element_address, self.offsets, self.add)
34
+ @overload
35
+ def __getitem__(self, index: int) -> Address: ...
36
36
 
37
- return Address(target_address.resolve())
37
+ @overload
38
+ def __getitem__(self, index: slice) -> list[Address]: ...
39
+
40
+ def __getitem__(self, index: int | slice) -> Address | list[Address]:
41
+ if isinstance(index, int):
42
+ return self.get_address_of_element(index)
43
+
44
+ return [self.get_address_of_element(i) for i in range(index.start, index.stop, index.step)]
38
45
 
39
46
  def __iter__(self) -> Iterator[Address]:
40
47
  for index in range(len(self)):
@@ -43,6 +50,12 @@ class ASMArrayManager(Sequence):
43
50
  def get_pointer_to_element(self, index: int) -> int:
44
51
  return self.array_address + self.element_size * index
45
52
 
53
+ def get_address_of_element(self, index: int) -> Address:
54
+ element_address = self.get_pointer_to_element(index)
55
+ target_address = Address(element_address, self.offsets, self.add)
56
+
57
+ return Address(target_address.resolve())
58
+
46
59
  def generate_asm_append_code(self, from_register: str) -> str:
47
60
  array_address_register = "rbx" if pm.is_64_bit else "ebx"
48
61
  array_index_register = "rcx" if pm.is_64_bit else "ecx"
@@ -18,10 +18,9 @@ def simple_trainerbase_menu(window_title: str, width: int, height: int):
18
18
  dpg.create_context()
19
19
  dpg.create_viewport(
20
20
  title=window_title,
21
- min_width=width,
22
- min_height=height,
23
21
  width=width,
24
22
  height=height,
23
+ resizable=False,
25
24
  )
26
25
  dpg.setup_dearpygui()
27
26
 
@@ -33,9 +32,11 @@ def simple_trainerbase_menu(window_title: str, width: int, height: int):
33
32
  no_move=True,
34
33
  no_title_bar=True,
35
34
  horizontal_scrollbar=True,
35
+ autosize=True,
36
36
  ):
37
37
  initializer()
38
38
 
39
+ dpg.set_primary_window("menu", value=True)
39
40
  dpg.show_viewport()
40
41
 
41
42
  on_initialized()
@@ -6,6 +6,8 @@ from typing import Final, Self, assert_never, cast, override
6
6
 
7
7
  from pymem.pattern import pattern_scan_all, pattern_scan_module
8
8
  from pymem.process import module_from_name
9
+ from pymem.ressources.kernel32 import SetLastError, VirtualAllocEx
10
+ from pymem.ressources.structure import MEMORY_PROTECTION, MEMORY_STATE
9
11
 
10
12
  from trainerbase.process import _pm as pm
11
13
 
@@ -19,6 +21,9 @@ type ConvertibleToAddress = AbstractAddress | int | bytes | str
19
21
 
20
22
  read_pointer = cast(Callable[[int], int], pm.read_ulonglong if pm.is_64_bit else pm.read_uint)
21
23
 
24
+ __set_last_error = cast(Callable[[int], None], SetLastError)
25
+ __virtual_alloc_ex = cast(Callable[..., int], VirtualAllocEx)
26
+
22
27
 
23
28
  class AbstractAddress(ABC):
24
29
  @abstractmethod
@@ -166,8 +171,8 @@ def ensure_address(obj: ConvertibleToAddress) -> AbstractAddress:
166
171
  raise TypeError(f"Cannot create AbstractAddress from {type(obj)}")
167
172
 
168
173
 
169
- def allocate(size: int = POINTER_SIZE, count: int = 1) -> int:
170
- return pm.allocate(size * count)
174
+ def allocate(size: int = POINTER_SIZE, count: int = 1, nearest_to: int | None = None) -> int:
175
+ return __pm_allocate_memory(cast(int, pm.process_handle), size * count, nearest_to)
171
176
 
172
177
 
173
178
  def get_module_address(module_name: str) -> int:
@@ -181,3 +186,32 @@ def get_module_address(module_name: str) -> int:
181
186
  return 0
182
187
 
183
188
  return module_info.lpBaseOfDll
189
+
190
+
191
+ def __pm_allocate_memory(
192
+ handle: int,
193
+ size: int,
194
+ nearest_to: int | None = None,
195
+ allocation_type: MEMORY_STATE | None = None,
196
+ protection_type: MEMORY_PROTECTION | None = None,
197
+ ):
198
+ """
199
+ Pymem fork.
200
+
201
+ Reserves or commits a region of memory within the virtual address space of a specified process.
202
+ The function initializes the memory it allocates to zero, unless MEM_RESET is used.
203
+
204
+ https://msdn.microsoft.com/en-us/library/windows/desktop/aa366890%28v=vs.85%29.aspx
205
+ """
206
+
207
+ if allocation_type is None:
208
+ allocation_type = MEMORY_STATE.MEM_COMMIT
209
+
210
+ if protection_type is None:
211
+ protection_type = MEMORY_PROTECTION.PAGE_EXECUTE_READWRITE
212
+
213
+ __set_last_error(0)
214
+
215
+ address = __virtual_alloc_ex(handle, nearest_to, size, allocation_type.value, protection_type.value)
216
+
217
+ return address
File without changes
File without changes