trainerbase 3.12.0__tar.gz → 3.13.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.12.0 → trainerbase-3.13.0}/PKG-INFO +1 -1
- {trainerbase-3.12.0 → trainerbase-3.13.0}/pyproject.toml +1 -1
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/codeinjection.py +7 -12
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/common/helpers.py +1 -1
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/common/teleport.py +9 -6
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/teleport.py +23 -9
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/process.py +14 -8
- {trainerbase-3.12.0 → trainerbase-3.13.0}/LICENSE +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/README.md +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/__init__.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/common/__init__.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/common/abc.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/common/keyboard.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/config.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gameobject.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/__init__.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/helpers.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/injections.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/misc.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/objects.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/scripts.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/speedhack.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/gui/types.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/main.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/memory.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/scriptengine.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/speedhack.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase/tts.py +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase_vendor/FASM.EXE +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase_vendor/speedhack32.dll +0 -0
- {trainerbase-3.12.0 → trainerbase-3.13.0}/trainerbase_vendor/speedhack64.dll +0 -0
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
from subprocess import DEVNULL
|
|
5
5
|
from subprocess import run as run_executable
|
|
6
6
|
from tempfile import TemporaryDirectory
|
|
7
|
-
from typing import ClassVar, Final,
|
|
7
|
+
from typing import ClassVar, Final, Self, override
|
|
8
8
|
|
|
9
9
|
from pymem.exception import MemoryWriteError
|
|
10
10
|
|
|
@@ -69,21 +69,16 @@ class AllocatingCodeInjection(AbstractCodeInjection): # pylint: disable=too-man
|
|
|
69
69
|
code_to_inject: Code,
|
|
70
70
|
original_code_length: int = 0,
|
|
71
71
|
new_memory_size: int = 1024,
|
|
72
|
-
is_long_x64_jump_needed:
|
|
72
|
+
is_long_x64_jump_needed: bool | None = None,
|
|
73
73
|
):
|
|
74
|
-
if is_long_x64_jump_needed is
|
|
75
|
-
|
|
76
|
-
"Since TrainerBase 3.4.0 is_long_x64_jump_needed has been deprecated."
|
|
77
|
-
" Now there is not need to manually pop and push rax. That's why you must"
|
|
78
|
-
" rewrite injections based on manual pop rax, push rax and then remove is_long_x64_jump_needed"
|
|
79
|
-
" argument"
|
|
80
|
-
)
|
|
74
|
+
if is_long_x64_jump_needed is None:
|
|
75
|
+
is_long_x64_jump_needed = pm.is_64_bit
|
|
81
76
|
|
|
77
|
+
self.is_long_x64_jump_needed = is_long_x64_jump_needed
|
|
82
78
|
self.address = ensure_address(address)
|
|
83
|
-
|
|
84
79
|
self.code_to_inject = compile_asm(code_to_inject)
|
|
85
80
|
|
|
86
|
-
if
|
|
81
|
+
if self.is_long_x64_jump_needed:
|
|
87
82
|
self.code_to_inject = compile_asm("pop rax") + self.code_to_inject + compile_asm("push rax")
|
|
88
83
|
|
|
89
84
|
self.original_code: bytes = b""
|
|
@@ -101,7 +96,7 @@ class AllocatingCodeInjection(AbstractCodeInjection): # pylint: disable=too-man
|
|
|
101
96
|
|
|
102
97
|
self.original_code = pm.read_bytes(self.injection_point, self.original_code_length)
|
|
103
98
|
|
|
104
|
-
if
|
|
99
|
+
if self.is_long_x64_jump_needed:
|
|
105
100
|
jump_to_new_mem = compile_asm(get_long_x64_jump_to_new_mem_code(self.new_memory_address))
|
|
106
101
|
jumper_length = len(jump_to_new_mem)
|
|
107
102
|
jump_back_address = self.injection_point + jumper_length - 1
|
|
@@ -63,7 +63,7 @@ class ASMArrayManager(Sequence):
|
|
|
63
63
|
# The solution was to first save the address into a register before reading/writing a value from it.
|
|
64
64
|
# In order not to use another register, existing ones were reused,
|
|
65
65
|
# which, unfortunately, can be misleading.
|
|
66
|
-
# But it was decided that using a new register would make the code even less
|
|
66
|
+
# But it was decided that using a new register would make the code even less clear
|
|
67
67
|
# and potentially more error-prone.
|
|
68
68
|
|
|
69
69
|
asm = f"""
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import Hashable
|
|
1
2
|
from itertools import repeat, starmap
|
|
2
3
|
from math import sqrt
|
|
3
4
|
from operator import add, mul
|
|
@@ -65,7 +66,7 @@ class Teleport:
|
|
|
65
66
|
self.player_z = player_z
|
|
66
67
|
self.labels = {} if labels is None else labels
|
|
67
68
|
|
|
68
|
-
self.
|
|
69
|
+
self.saved_positions: dict[Hashable, Coords] = {}
|
|
69
70
|
|
|
70
71
|
self.dash_coefficients = Vector3(5, 5, 5) if dash_coefficients is None else dash_coefficients
|
|
71
72
|
self.previous_position: Coords | None = None
|
|
@@ -89,18 +90,20 @@ class Teleport:
|
|
|
89
90
|
|
|
90
91
|
self.set_coords(*self.labels[label])
|
|
91
92
|
|
|
92
|
-
def save_position(self) -> None:
|
|
93
|
-
self.
|
|
93
|
+
def save_position(self, key: Hashable = 0) -> None:
|
|
94
|
+
self.saved_positions[key] = self.get_coords()
|
|
94
95
|
|
|
95
|
-
def restore_saved_position(self) -> bool:
|
|
96
|
+
def restore_saved_position(self, key: Hashable = 0) -> bool:
|
|
96
97
|
"""
|
|
97
98
|
Returns False if position is not saved else True
|
|
98
99
|
"""
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
saved_position = self.saved_positions.get(key)
|
|
102
|
+
|
|
103
|
+
if saved_position is None:
|
|
101
104
|
return False
|
|
102
105
|
|
|
103
|
-
self.set_coords(*
|
|
106
|
+
self.set_coords(*saved_position)
|
|
104
107
|
|
|
105
108
|
return True
|
|
106
109
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from collections.abc import Hashable
|
|
2
|
+
from functools import partial
|
|
1
3
|
from typing import override
|
|
2
4
|
|
|
3
5
|
from dearpygui import dearpygui as dpg
|
|
@@ -20,12 +22,14 @@ class TeleportUI(AbstractUIComponent):
|
|
|
20
22
|
hotkey_save_position: str | None = "Insert",
|
|
21
23
|
hotkey_set_saved_position: str | None = "Home",
|
|
22
24
|
hotkey_dash: str | None = "End",
|
|
25
|
+
hotkey_secondary_position_modifier: str = "Shift",
|
|
23
26
|
*,
|
|
24
27
|
tts_on_hotkey: bool = True,
|
|
25
28
|
):
|
|
26
29
|
self.tp = tp
|
|
27
30
|
self.hotkey_save_position = hotkey_save_position
|
|
28
31
|
self.hotkey_set_saved_position = hotkey_set_saved_position
|
|
32
|
+
self.hotkey_secondary_position_modifier = hotkey_secondary_position_modifier
|
|
29
33
|
self.hotkey_dash = hotkey_dash
|
|
30
34
|
self.tts_on_hotkey = tts_on_hotkey
|
|
31
35
|
|
|
@@ -47,14 +51,14 @@ class TeleportUI(AbstractUIComponent):
|
|
|
47
51
|
def on_clip_coords(self):
|
|
48
52
|
dpg.set_clipboard_text(repr(self.tp.get_coords()))
|
|
49
53
|
|
|
50
|
-
def on_hotkey_save_position_press(self):
|
|
51
|
-
self.tp.save_position()
|
|
54
|
+
def on_hotkey_save_position_press(self, key: Hashable):
|
|
55
|
+
self.tp.save_position(key)
|
|
52
56
|
|
|
53
57
|
if self.tts_on_hotkey:
|
|
54
58
|
say("Position saved")
|
|
55
59
|
|
|
56
|
-
def on_hotkey_set_saved_position_press(self):
|
|
57
|
-
is_position_restored = self.tp.restore_saved_position()
|
|
60
|
+
def on_hotkey_set_saved_position_press(self, key: Hashable):
|
|
61
|
+
is_position_restored = self.tp.restore_saved_position(key)
|
|
58
62
|
|
|
59
63
|
if self.tts_on_hotkey:
|
|
60
64
|
say("Position restored" if is_position_restored else "Save position at first")
|
|
@@ -71,11 +75,21 @@ class TeleportUI(AbstractUIComponent):
|
|
|
71
75
|
if self.hotkey_save_position is None or self.hotkey_set_saved_position is None:
|
|
72
76
|
return
|
|
73
77
|
|
|
74
|
-
add_hotkey(self.hotkey_save_position, self.on_hotkey_save_position_press)
|
|
75
|
-
add_hotkey(self.hotkey_set_saved_position, self.on_hotkey_set_saved_position_press)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
add_hotkey(self.hotkey_save_position, partial(self.on_hotkey_save_position_press, 0))
|
|
79
|
+
add_hotkey(self.hotkey_set_saved_position, partial(self.on_hotkey_set_saved_position_press, 0))
|
|
80
|
+
|
|
81
|
+
hotkey_secondary_position_hint = ""
|
|
82
|
+
if self.hotkey_secondary_position_modifier:
|
|
83
|
+
hotkey_save_secondary_position = f"{self.hotkey_secondary_position_modifier} + {self.hotkey_save_position}"
|
|
84
|
+
hotkey_set_secondary_saved_position = (
|
|
85
|
+
f"{self.hotkey_secondary_position_modifier} + {self.hotkey_set_saved_position}"
|
|
86
|
+
)
|
|
87
|
+
hotkey_secondary_position_hint = f"[{self.hotkey_secondary_position_modifier} +] "
|
|
88
|
+
add_hotkey(hotkey_save_secondary_position, partial(self.on_hotkey_save_position_press, 1))
|
|
89
|
+
add_hotkey(hotkey_set_secondary_saved_position, partial(self.on_hotkey_set_saved_position_press, 1))
|
|
90
|
+
|
|
91
|
+
dpg.add_text(f"[{hotkey_secondary_position_hint}{self.hotkey_save_position}] Save Position")
|
|
92
|
+
dpg.add_text(f"[{hotkey_secondary_position_hint}{self.hotkey_set_saved_position}] Restore Position")
|
|
79
93
|
|
|
80
94
|
def _tp_add_dash_hotkeys_if_needed(self):
|
|
81
95
|
if self.hotkey_dash is None:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
1
2
|
from itertools import cycle
|
|
2
3
|
from os import _exit as force_exit
|
|
3
4
|
from typing import cast
|
|
@@ -19,17 +20,22 @@ def attach_to_process() -> Pymem:
|
|
|
19
20
|
|
|
20
21
|
print("Waiting for process in:", process_names)
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
with suppress(KeyboardInterrupt):
|
|
24
|
+
for process_name in cycle(process_names):
|
|
25
|
+
try:
|
|
26
|
+
pm = Pymem(
|
|
27
|
+
process_name,
|
|
28
|
+
exact_match=pymem_config["exact_match"],
|
|
29
|
+
ignore_case=pymem_config["ignore_case"],
|
|
30
|
+
)
|
|
31
|
+
except ProcessNotFound:
|
|
32
|
+
continue
|
|
27
33
|
|
|
28
|
-
|
|
34
|
+
print(f"Found {process_name}, pid: {pm.process_id}")
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
return pm
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
force_exit(0)
|
|
33
39
|
|
|
34
40
|
|
|
35
41
|
def show_message_and_shutdown_if_process_exited():
|
|
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
|
|
File without changes
|
|
File without changes
|