Skip to content

Commit 1ed8b3a

Browse files
committed
redid comments & misc pylget updates
1 parent 80b979e commit 1ed8b3a

File tree

10 files changed

+185
-136
lines changed

10 files changed

+185
-136
lines changed

FAQ.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,25 @@ to get there also mentioned in the readme.md (Prerequisites section)
66

77
Check the following:
88
1. By default, it works for the Microsoft version of the game, there is a variable to toggle if you are using Steam.
9-
Does this apply to you?
9+
Does this apply to you? Did you change the toggle?
1010
2. Validate you have a pyglet window that is opening and there are no errors in the python window
11-
3. Have you made sure all of your window sizes have been updated according to the readme?
12-
4. Have you corrected the tests of faith mentioned in the readme.md (Prerequisites section)?
13-
5. Are you running in windowed mode?
11+
3. Have you corrected the tests of faith mentioned in the readme.md (Prerequisites section)?
12+
4. Are you running in windowed mode?
13+
14+
### Rendered items in the hack (text/circles) are fuzzy and larger than they should be
15+
If you have windows scaling on (for a large/high DPI monitor), you may need to make a small change to python to avoid
16+
your pyglet window also scaling:
17+
1. Navigate to your python folder (Mine is `C:\Python37` for example)
18+
2. Right-click your `python.exe` application and select "Properties"
19+
3. Select the "Compatibility" tab at the top
20+
4. Select "Change high DPI Setting"
21+
5. Check the box labelled "Override high DPI scaling behavior. Scaling performed by:"
22+
6. Select "Application" in the dropdown
23+
7. Select "OK"
24+
8. Select "Apply" and then "OK"
1425

1526
### What do I do first?
16-
First, you should get the hack to a state where all of the features mentioned in the readme are working as expected.
27+
First, you should get the hack to a state where all the features mentioned in the readme are working as expected.
1728
Once you are familiar with the hack and how the code operates, I would take a look through the below list, pick one small
1829
component to implement, and give it your best shot. Ask for help on Discord
1930

README.md

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Doug's Python SoT ESP Framework
2-
Hello all! This is a framework to develop an SoT ESP Hack, all utilizing Python 3.7.9. This is a trimmed down version
2+
Hello all! This is a framework to develop an SoT ESP Hack, all utilizing Python. This is a trimmed down version
33
of a personal creation I utilize actively. This is a great foundation for someone who is looking to get started in
4-
ESP hacks for Sea of Thieves, and should be loaded with comments to help you grasp the "how" and "why" of basic
4+
ESP hacks for Sea of Thieves and maybe even other UE4 games! The code should be loaded with comments to help you grasp the "how" and "why" of basic
55
memory editing and data display with Python. While this is intended for use within Sea of Thieves specifically, there is a lot
6-
of resources utilized which could be useful in memory reading/editing for almost any game/program :D
6+
of resources utilized which could be useful in memory reading/editing for almost any game/program.
77

8-
This hack has the following implemented:
8+
This hack has the following implemented:
99
- Get the location of ships in render distance and display them on screen
10+
- Display a count of the players on the server
1011
- Display a list of all players on the server
1112

1213
This is intentionally left as a framework and not a full-featured hack for a few reasons:
@@ -15,7 +16,7 @@ This is intentionally left as a framework and not a full-featured hack for a few
1516
3. Much of the code is very well documented to help you understand the "how" of the hacks inner workings; as a
1617
result many resources on hacking forums will give you guidelines for implementing new functionality; I did it myself,
1718
you can to
18-
4. I have undergone 3 or 4 major interations of this same code. **I am still learning** and re-writing functionality all
19+
4. I have undergone 5 or 6 major interations of this same code. **I am still learning** and re-writing functionality all
1920
the time; a smaller code base is much more simple to maintain
2021

2122
I do ask that if you decided to take this into your own personal development, encourage others to think for themselves a
@@ -29,22 +30,22 @@ Microsoft version. If you are using the Steam version, you will need to change t
2930
of SoTHack.py
3031

3132
### Why Python?!
32-
Python is at its root a more user-friendly (IMO) version of C. Hypothetically, we can perform any C action using python,
33+
Python is at its more user-friendly version of C. Hypothetically, we can perform any C action using python,
3334
but make it more readible and beginner-friendly. I am also much more comfortable developing in Python and saw this as
3435
an opportunity to challenge myself.
3536

3637
### Prerequisites
37-
In theory, all you need to get started in using this hack is Python 3.7.9, and to install the requirement found in the
38-
requirements.txt. The base framework relies on a 4k main monitor. You MAY need to make some minor changes in
39-
the code to accomidate your display configuration (helpers.py, top of file). I personally run all of my Python from PyCharm, and
40-
start/stop the code execution through the built-in Run and Stop functionality. You may choose to implement proper
41-
"closing" functionality using pyglet.
38+
In theory, all you need to get started in using this hack is Python 3.7.9 (have also verified in 3.9.6), and to install
39+
the requirement found in the requirements.txt. The base framework should automatically create an overlay over your SoT window,
40+
regardless of size. You MAY need to make some minor changes in the code to accomidate your display configuration
41+
(helpers.py, top of file). I personally run all of my Python from PyCharm, and start/stop the code execution
42+
through the built-in Run and Stop functionality. You may choose to implement proper "closing" functionality using pyglet.
4243

4344
***As a test of faith, to get this code fully-functional you must modify one line of code and remove another entirely.
4445
This is a VERY small countermeasure to ensure this framework is actually used as intended.***
4546

4647
### How to execute
47-
At the time of writting, the script is built for a version of SoT with ~5 weeks left in Season 2 and given you have the
48+
At the time of writting, the script is built for a version of SoT with ~6 weeks left in Season 3 and given you have the
4849
necessary pre-requisites, should execute with no major issues. Simply run `main.py` once you are in a server.
4950

5051
### How to update for new SoT Versions
@@ -71,12 +72,12 @@ your issues.
7172
### cAn i GeT bAnNeD?!
7273
TL;DR: Yes. You _can_ get banned, such is the risk of cheating.
7374

74-
Longer version: As is, this code purely utilizes a read-only state for the computers memory. With hundreds of hours utilizing these same read-only permissions, I have never been
75+
Longer version: As is, this code purely utilizes a read-only state for the computer's memory. With hundreds of hours utilizing these same read-only permissions, I have never been
7576
banned, nor concerned for being banned. Does that guarentee you won't be? No. Does that guarentee you won't change something (like trying to write memory) that will cause you to
76-
get banned? No. If you arent sure what something does, or why something is done a certain way, do some research on the potential impact of changing it before actually changing it.
77+
get banned? No. If you aren't sure what something does, or why something is done a certain way, do some research on the potential impact of changing it before actually changing it.
7778

7879
### Can you help me implement X feature?
79-
No. I learned utilizing already posted questions/comments easily found online, you can as well. This framework is meant for people who want to put in the work and learn something,
80+
No. I learned to utilize already posted questions/comments easily found online, you can as well. This framework is meant for people who want to put in the work and learn something,
8081
not recieve a hand-out. You also may be able to see the FAQ.md for some useful information.
8182
For community support, please contact me on Discord: DougTheDruid#2784
8283

@@ -88,22 +89,19 @@ update methods every so often (or every frame).
8889

8990
The `SoTMemoryReader` object gets data about the game world, but has a main game loop function called `read_actors`.
9091
This method is responsible for determining how many actors there are, and reading data about all of those actors. For
91-
Actors we are interested in knowing more about, we create a relevant class-object to track their information. We also
92+
actors we are interested in knowing more about, we create a relevant class-object to track their information. We also
9293
use that object to build display information for Pyglet to utilize.
9394

9495
Largely speaking, if you want to see the flow of the code, start at `main.py` and work your way down into the objects
9596
and other files.
9697

97-
*This is an early build using Pyglet and probably isn't super optimized.*
98+
*This is an early build using Pyglet and I am still working to optimize some of the code*
9899

99100
### Pyglet Todo
100-
1. In `ship.py`, for some reason I was unable to use `.visibile = False` for the text similarly to the circle visiblity.
101-
So I ended up setting the text-size to 0. How do we make this better?
102-
2. Currently we are replacing spaces in play names with `-`'s, this has to do with the multiline functionality
101+
1. Currently we are replacing spaces in play names with `-`'s, this has to do with the multiline functionality
103102
specified for `player_list` creation in `main.py`. Can you make a specific doc format to get around this weirdness?
104-
3. Gummy set the window attibutes to LWA_Alpha vs ColorKey, then set the DirectX alpha flags to do the transparency.
103+
2. Gummy set the window attibutes to LWA_Alpha vs ColorKey, then set the DirectX alpha flags to do the transparency.
105104
Can something similar with with this & OpenGL (which pyglet uses)?
106-
4. Add typehints & update docstrings for new stuff
107105

108106
### Structs
109107
Instead of rebuilding structures similarly to how you would in C or C++, I utilize something fairly frequently in my
@@ -127,7 +125,7 @@ Note: [See other `Structs` format information here](https://docs.python.org/3/li
127125
If you are interested in helping maintain this code base, first off, thank you! My only asks are as follows:
128126
1. Document your additions/changes in accordance with what exists
129127
2. Utilize Pylint and the provided pylintrc file to ensure your code is 10/10 compliant prior to submittion of a PR
130-
3. Keep the framework a framework, do not add new features outside of those listed in the "TODO" section
128+
3. Keep the framework a framework, do not add new features outside those listed in the "TODO" section
131129
4. Create "Issues" if something strikes you as incorrect or needing improvement. Also consider looking at issues for
132130
opportunities to contribute
133131

display_object.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,41 @@
1111

1212
class DisplayObject(metaclass=abc.ABCMeta):
1313
"""
14-
Class responsible for the base functionality of pulling data from
15-
our memory objects. These are typically identical regardless of the actor
16-
type we are looking at
14+
Parent class to objects like Ship's. Responsible for the base functionality
15+
of pulling data from our memory objects. These are typically identical
16+
regardless of the actor type we are looking at; as such would be
17+
considered "common" and reduces redundant code.
1718
"""
1819

1920
def __init__(self, memory_reader: ReadMemory):
2021
"""
21-
Parent class to objects like Ship's. Helpful as the methods found here
22-
would be considered "common" and reduces redundent code.
22+
Some of our DisplayObject calls need to make memory reads, so we will
23+
ser out memory reader as a class variable.
2324
:param memory_reader: The SoT MemoryHelper object we are utilizing to
2425
read memory data from the game
2526
"""
26-
self.m_r = memory_reader
27+
self.rm = memory_reader
2728

28-
def _get_actor_id(self, address):
29+
def _get_actor_id(self, address: int) -> int:
2930
"""
3031
Function to get the AActor's ID, used to validate the ID hasnt chaned
3132
while running a "quick" scan
32-
:param address: the base address for a given AActor
33+
:param int address: the base address for a given AActor
3334
:rtype: int
3435
:return: The AActors ID
3536
"""
36-
return self.m_r.read_int(
37+
return self.rm.read_int(
3738
address + OFFSETS.get('AActor.actorId')
3839
)
3940

4041
def _get_root_comp_address(self, address: int) -> int:
4142
"""
4243
Function to get an AActor's root component memory address
43-
:param address: the base address for a given AActor
44+
:param int address: the base address for a given AActor
4445
:rtype: int
4546
:return: the address of an AActors root component
4647
"""
47-
return self.m_r.read_ptr(
48+
return self.rm.read_ptr(
4849
address + OFFSETS.get("AActor.rootComponent")
4950
)
5051

@@ -55,10 +56,10 @@ def _coord_builder(self, root_comp_ptr: int, offset: int) -> dict:
5556
:param int offset: Offset from root component to beginning of coords,
5657
Often determined manually with Cheat Engine
5758
:rtype: dict
58-
:return: A dictionary contianing the coordinate information
59+
:return: A dictionary containing the coordinate information
5960
for a specific actor
6061
"""
61-
actor_bytes = self.m_r.read_bytes(root_comp_ptr + offset, 24)
62+
actor_bytes = self.rm.read_bytes(root_comp_ptr + offset, 24)
6263
unpacked = struct.unpack("<ffffff", actor_bytes)
6364

6465
coordinate_dict = {"x": unpacked[0] / 100, "y": unpacked[1] / 100,
@@ -68,5 +69,6 @@ def _coord_builder(self, root_comp_ptr: int, offset: int) -> dict:
6869
@abc.abstractmethod
6970
def update(self, my_coords):
7071
"""
71-
72+
Required implementation method that we can call to update
73+
the objects data in a quick fashion vs scanning every actor.
7274
"""

helpers.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,35 @@
1414
"SHIPS_ENABLED": False,
1515
}
1616

17+
# Offset values for the text labels from the circles we draw to the screen
1718
TEXT_OFFSET_X = 13
1819
TEXT_OFFSET_Y = -5
1920

20-
# Information on your monitor height and width. Used here and
21-
# in main.py to display data to the screen. May need to manually override if
22-
# wonky
21+
# Information on SoT height and width. Used here and in main.py to display
22+
# data to the screen. May need to manually override if wonky
2323
window = win32gui.FindWindow(None, "Sea of Thieves")
24-
SOT_WINDOW = win32gui.GetWindowRect(window)
24+
SOT_WINDOW = win32gui.GetWindowRect(window) # (x1, y1, x2, y2)
2525
SOT_WINDOW_H = SOT_WINDOW[3]-SOT_WINDOW[1]
2626
SOT_WINDOW_W = SOT_WINDOW[2]-SOT_WINDOW[0]
2727

28+
# Creates a pyglet "Batch" that we draw our information to. Effectively serves
29+
# as a piece of paper, so we save render cost because its 2D
2830
main_batch = Batch()
2931

30-
32+
# Load our offset json file
3133
with open("offsets.json") as infile:
3234
OFFSETS = json.load(infile)
3335

3436

3537
def dot(array_1: list, array_2: list) -> float:
3638
"""
37-
Python-converted version of Gummy's External SoT v2 vMatrix Dot method:
38-
https://tinyurl.com/hcpafjs
39-
39+
Python-converted version of Gummy's External SoT v2 vMatrix Dot method (No
40+
Longer Avail). Takes two lists and multiplies the same index across both
41+
lists, and adds them together. (Need Source)
42+
:param list array_1: Presumably some array about our player position
43+
:param list array_2: Presumably some array about the dest actor position
4044
:rtype: float
45+
:return: The result of a math equation between those two arrays
4146
"""
4247
if array_2[0] == 0 and array_2[1] == 0 and array_2[2] == 0:
4348
return 0.0
@@ -52,7 +57,7 @@ def object_to_screen(player: dict, actor: dict) -> tuple:
5257
an object should be displayed. Assumes your screen is 2560x1440
5358
5459
Python-converted version of Gummy's External SoT v2 WorldToScreen method:
55-
https://tinyurl.com/3bef29jd
60+
(No Longer Avail; Need Source)
5661
5762
:param player: The player coordinate dictionary
5863
:param actor: An actor coordinate dictionary
@@ -105,11 +110,11 @@ def make_v_matrix(rot: dict) -> list:
105110
Builds data around how the camera is currently rotated.
106111
107112
Python-converted version of Gummy's External SoT v2 Matrix method:
108-
https://tinyurl.com/3bt9brm3
113+
(No Longer Avail; Need Source)
109114
110115
:param rot: The player objects camera rotation information
111116
:rtype: list
112-
:return:
117+
:return: A list of lists containing data about the rotation of our actor
113118
"""
114119
rad_pitch = (rot[0] * math.pi / 180)
115120
rad_yaw = (rot[1] * math.pi / 180)
@@ -137,15 +142,19 @@ def make_v_matrix(rot: dict) -> list:
137142
return matrix
138143

139144

140-
def calculate_distance(obj_to: dict, obj_from: dict) -> float:
145+
def calculate_distance(obj_to: dict, obj_from: dict) -> int:
141146
"""
142147
Determines the distances From one object To another in meters, rounding
143148
to whatever degree of precision you request
149+
(**2 == ^2)
150+
151+
Note: Can convert the int() to a round() if you want more precision
144152
145153
:param obj_to: A coordinate dict for the object we are going "to"
146154
:param obj_from: A coordinate dict for the object we are going "from"
155+
:rtype: int
147156
:return: the distance in meters from obj_from to obj_to
148157
"""
149-
return int(math.sqrt(math.pow((obj_to.get("x") - obj_from.get("x")), 2) +
150-
math.pow((obj_to.get("y") - obj_from.get("y")), 2) +
151-
math.pow((obj_to.get("z") - obj_from.get("z")), 2)))
158+
return int(math.sqrt((obj_to.get("x") - obj_from.get("x"))**2 +
159+
(obj_to.get("y") - obj_from.get("y"))**2 +
160+
(obj_to.get("z") - obj_from.get("z"))**2))

0 commit comments

Comments
 (0)