trainerbase 3.2.0__tar.gz → 3.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trainerbase
3
- Version: 3.2.0
3
+ Version: 3.4.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.2.0"
3
+ version = "3.4.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"
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from subprocess import DEVNULL
4
4
  from subprocess import run as run_executable
5
5
  from tempfile import TemporaryDirectory
6
- from typing import Self, override
6
+ from typing import Never, Self, override
7
7
 
8
8
  from pymem.exception import MemoryWriteError
9
9
 
@@ -65,28 +65,40 @@ class AllocatingCodeInjection(AbstractCodeInjection): # pylint: disable=too-man
65
65
  code_to_inject: Code,
66
66
  original_code_length: int = 0,
67
67
  new_memory_size: int = 1024,
68
- is_long_x64_jump_needed: bool = False,
68
+ is_long_x64_jump_needed: Never = Never,
69
69
  ):
70
+ if is_long_x64_jump_needed is not Never:
71
+ raise Exception(
72
+ "Since TrainerBase 3.4.0 is_long_x64_jump_needed has been deprecated."
73
+ " Now there is not need to manually pop and push rax. That's why you must"
74
+ " rewrite injections based on manual pop rax, push rax and then remove is_long_x64_jump_needed"
75
+ " argument"
76
+ )
77
+
70
78
  self.address = ensure_address(address)
79
+
71
80
  self.code_to_inject = compile_asm(code_to_inject)
81
+
82
+ if not pm.is_WoW64:
83
+ self.code_to_inject = compile_asm("pop rax") + self.code_to_inject + compile_asm("push rax")
84
+
72
85
  self.original_code: bytes = b""
73
86
 
74
87
  self.original_code_length = original_code_length
75
88
  self.new_memory_size = new_memory_size
76
89
  self.new_memory_address: int = 0
77
- self.is_long_x64_jump_needed = is_long_x64_jump_needed
78
90
 
79
91
  @override
80
92
  def inject(self):
81
93
  self.original_code = pm.read_bytes(self.address.resolve(), self.original_code_length)
82
94
  self.new_memory_address: int = pm.allocate(self.new_memory_size)
83
95
 
84
- if self.is_long_x64_jump_needed:
85
- new_mem_jump_code_generator = get_long_x64_jump_to_new_mem_code
86
- jump_back_code_generator = get_long_x64_jump_back_code
87
- else:
96
+ if pm.is_WoW64:
88
97
  new_mem_jump_code_generator = get_simple_jump_code
89
98
  jump_back_code_generator = get_simple_jump_code
99
+ else:
100
+ new_mem_jump_code_generator = get_long_x64_jump_to_new_mem_code
101
+ jump_back_code_generator = get_long_x64_jump_back_code
90
102
 
91
103
  jump_to_new_mem = compile_asm(new_mem_jump_code_generator(self.new_memory_address))
92
104
  jumper_length = len(jump_to_new_mem)
@@ -97,7 +109,7 @@ class AllocatingCodeInjection(AbstractCodeInjection): # pylint: disable=too-man
97
109
  raise ValueError(f"Jumper length > original code length: {jumper_length} > {self.original_code_length}")
98
110
 
99
111
  jump_back_address = self.address.resolve() + jumper_length
100
- if self.is_long_x64_jump_needed:
112
+ if not pm.is_WoW64:
101
113
  jump_back_address -= 1
102
114
 
103
115
  jump_back = compile_asm(jump_back_code_generator(jump_back_address))
@@ -28,10 +28,6 @@ from trainerbase.speedhack import SpeedHack
28
28
  from trainerbase.tts import say
29
29
 
30
30
 
31
- TAG_TELEPORT_LABELS = "__teleport_labels"
32
- TAG_SPEEDHACK_FACTOR_INPUT = "tag_speedhack_factor_input"
33
-
34
-
35
31
  class AbstractUIComponent(ABC):
36
32
  @abstractmethod
37
33
  def add_to_ui(self) -> None:
@@ -211,12 +207,14 @@ class GameObjectUI(AbstractUIComponent):
211
207
 
212
208
 
213
209
  class TeleportUI(AbstractUIComponent):
210
+ DPG_TAG_TELEPORT_LABELS = "__teleport_labels"
211
+
214
212
  def __init__(
215
213
  self,
216
214
  tp: Teleport,
217
- hotkey_save_position: str | None = None,
218
- hotkey_set_saved_position: str | None = None,
219
- hotkey_dash: str | None = None,
215
+ hotkey_save_position: str | None = "Insert",
216
+ hotkey_set_saved_position: str | None = "Home",
217
+ hotkey_dash: str | None = "End",
220
218
  tts_on_hotkey: bool = True,
221
219
  ):
222
220
  self.tp = tp
@@ -261,7 +259,7 @@ class TeleportUI(AbstractUIComponent):
261
259
  say("Dash!")
262
260
 
263
261
  def on_goto_label(self):
264
- self.tp.goto(dpg.get_value(TAG_TELEPORT_LABELS))
262
+ self.tp.goto(dpg.get_value(self.DPG_TAG_TELEPORT_LABELS))
265
263
 
266
264
  def _tp_add_save_set_position_hotkeys_if_needed(self):
267
265
  if self.hotkey_save_position is None or self.hotkey_set_saved_position is None:
@@ -289,14 +287,20 @@ class TeleportUI(AbstractUIComponent):
289
287
 
290
288
  with dpg.group(horizontal=True):
291
289
  dpg.add_button(label="Go To", callback=self.on_goto_label)
292
- dpg.add_combo(label="Labels", tag=TAG_TELEPORT_LABELS, items=labels, default_value=labels[0])
290
+ dpg.add_combo(label="Labels", tag=self.DPG_TAG_TELEPORT_LABELS, items=labels, default_value=labels[0])
293
291
 
294
292
 
295
293
  class SpeedHackUI(AbstractUIComponent):
296
- def __init__(self, speedhack: SpeedHack, key: str):
294
+ DPG_TAG_SPEEDHACK_FACTOR_INPUT = "tag_speedhack_factor_input"
295
+ DPG_TAG_SPEEDHACK_PRESET_INPUT = "tag_speedhack_preset_input"
296
+
297
+ PRESETS: tuple[float, ...] = (0.1, 0.2, 0.3, 0.5, 1.0, 2.0, 3.0, 5.0, 10.0, 20.0, 50.0)
298
+
299
+ def __init__(self, speedhack: SpeedHack, key: str = "Delete", default_factor_input_value: float = 3.0):
297
300
  self.speedhack = speedhack
298
301
  self.key = key
299
- self.switch = ShortLongPressSwitch(SpeedHackUISwitch(speedhack, TAG_SPEEDHACK_FACTOR_INPUT), key)
302
+ self.default_factor_input_value = default_factor_input_value
303
+ self.switch = ShortLongPressSwitch(SpeedHackUISwitch(speedhack, self.DPG_TAG_SPEEDHACK_FACTOR_INPUT), key)
300
304
 
301
305
  @override
302
306
  def add_to_ui(self) -> None:
@@ -304,17 +308,41 @@ class SpeedHackUI(AbstractUIComponent):
304
308
  dpg.add_text(f"Press [{self.key}] Toggle SpeedHack")
305
309
 
306
310
  dpg.add_input_double(
307
- tag=TAG_SPEEDHACK_FACTOR_INPUT,
311
+ tag=self.DPG_TAG_SPEEDHACK_FACTOR_INPUT,
308
312
  label="SpeedHack Factor",
309
313
  min_value=0.0,
310
314
  max_value=100.0,
311
- default_value=3.0,
315
+ default_value=self.default_factor_input_value,
312
316
  min_clamped=True,
313
317
  max_clamped=True,
318
+ callback=self.on_factor_change,
319
+ )
320
+
321
+ dpg.add_slider_int(
322
+ tag=self.DPG_TAG_SPEEDHACK_PRESET_INPUT,
323
+ label="Preset",
324
+ min_value=0,
325
+ max_value=len(self.PRESETS) - 1,
326
+ clamped=True,
327
+ default_value=self.get_closest_preset_index(self.default_factor_input_value),
328
+ callback=self.on_preset_change,
314
329
  )
315
330
 
316
331
  self.switch.handle()
317
332
 
333
+ def on_preset_change(self):
334
+ new_factor = self.PRESETS[dpg.get_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT)]
335
+ dpg.set_value(self.DPG_TAG_SPEEDHACK_FACTOR_INPUT, new_factor)
336
+
337
+ def on_factor_change(self):
338
+ new_factor = dpg.get_value(self.DPG_TAG_SPEEDHACK_FACTOR_INPUT)
339
+ closest_preset_index = self.get_closest_preset_index(new_factor)
340
+ dpg.set_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT, closest_preset_index)
341
+
342
+ def get_closest_preset_index(self, factor: float) -> int:
343
+ closest_preset = min(self.PRESETS, key=lambda preset: abs(preset - factor))
344
+ return self.PRESETS.index(closest_preset)
345
+
318
346
 
319
347
  class SpeedHackUISwitch(Switchable):
320
348
  def __init__(self, speedhack: SpeedHack, dpg_tag: str):
@@ -154,3 +154,7 @@ def ensure_address(obj: ConvertibleToAddress) -> AbstractAddress:
154
154
  return AOBScan(obj)
155
155
  case _:
156
156
  raise TypeError(f"Cannot create AbstractAddress from {type(obj)}")
157
+
158
+
159
+ def allocate_pointer() -> int:
160
+ return pm.allocate(POINTER_SIZE)
File without changes
File without changes