Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update main.py #29

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 78 additions & 107 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,142 +1,113 @@
"""
@Author https://github.com/DougTheDruid
@Source https://github.com/DougTheDruid/SoT-ESP-Framework
For community support, please contact me on Discord: DougTheDruid#2784
"""
from base64 import b64decode
import pyglet
import argparse
from pyglet.text import Label
from pyglet.gl import Config
from helpers import SOT_WINDOW, SOT_WINDOW_H, SOT_WINDOW_W, main_batch, \
version, logger, initialize_window
from sot_hack import SoTMemoryReader

# Command-line argument parsing for better control over debug and fps settings
parser = argparse.ArgumentParser(description='ESP Framework for SoT')
parser.add_argument('--fps', type=int, default=60, help='Target FPS for the program')
parser.add_argument('--debug', action='store_true', help='Enable debug mode')
args = parser.parse_args()

# The FPS __Target__ for the program.
FPS_TARGET = 60
# The FPS __Target__ for the program, adjustable via command-line argument
FPS_TARGET = args.fps

# See explanation in Main, toggle for a non-graphical debug
DEBUG = False
# Debug flag controlled via command-line argument
DEBUG = args.debug

# Pyglet clock used to track time via FPS
clock = pyglet.clock.Clock()


def generate_all(_):
"""
Triggers an entire read_actors call in our SoT Memory Reader. Will
re-populate all of the display objects if something entered the screen
or render distance.
"""
smr.read_actors()

try:
smr.read_actors()
except Exception as e:
logger.error(f"Error reading actors: {e}")

def update_graphics(_):
"""
Our main graphical loop which updates all of our "interesting" items.
During a "full run" (update_all()), a list of the objects near us and we
care about is generated. Each of those objects has a ".update()" method
we use to re-poll data for that item (required per display_object.py)
Main graphical loop to update all interesting items.
Each object in smr.display_objects has an .update() method to refresh its data.
"""
# Update our players coordinate information
smr.update_my_coords()

# Initialize a list of items which are no longer valid in this loop
to_remove = []

# For each actor that is stored from the most recent run of read_actors
for actor in smr.display_objects:
# Call the update function within the actor object
actor.update(smr.my_coords)

# If the actor isn't the actor we expect (per .update), prepare to nuke
if actor.to_delete:
to_remove.append(actor)

# Clean up any items which arent valid anymore
for removable in to_remove:
smr.display_objects.remove(removable)

try:
smr.update_my_coords()
to_remove = []

# Update each actor and mark those to be removed
for actor in smr.display_objects:
actor.update(smr.my_coords)
if actor.to_delete:
to_remove.append(actor)

# Remove invalid actors
for removable in to_remove:
smr.display_objects.remove(removable)
except Exception as e:
logger.error(f"Error updating graphics: {e}")

if __name__ == '__main__':
logger.info(
b64decode("RG91Z1RoZURydWlkJ3MgRVNQIEZyYW1ld29yayBTdGFydGluZw==").decode("utf-8")
)
logger.info(f"Hack Version: {version}")

# Initialize our SoT Hack object, and do a first run of reading actors
# Initialize SoT Hack object and do the first run of reading actors
smr = SoTMemoryReader()

# Custom Debug mode for using a literal python interpreter debugger
# to validate our fields. Does not generate a GUI.
# Debug mode bypasses the GUI and runs the reading process in a loop
if DEBUG:
logger.info("Running in Debug mode. No graphical interface will be displayed.")
while True:
smr.read_actors()

# You may want to add/modify this custom config per the pyglet docs to
# disable vsync or other options: https://tinyurl.com/45tcx6eu
config = Config(double_buffer=True, depth_size=24, alpha_size=8)

# Create an overlay window with Pyglet at the same size as our SoT Window
window = pyglet.window.Window(SOT_WINDOW_W, SOT_WINDOW_H,
vsync=False, style='overlay', config=config,
caption="DougTheDruid's ESP Framework")
hwnd = window._hwnd # pylint: disable=protected-access

# Move our window to the same location that our SoT Window is at
window.set_location(SOT_WINDOW[0], SOT_WINDOW[1])

@window.event
def on_draw():
"""
The event which our window uses to determine what to draw on the
screen. First clears the screen, then updates our player count, then
draws both our batch (think of a canvas) & fps display
"""
window.clear()

# Update our player count Label & crew list
if smr.crew_data:
player_count.text = f"Player Count: {smr.crew_data.total_players}"
# crew_list.text = smr.crew_data.crew_str

# Draw our main batch & FPS counter at the bottom left
main_batch.draw()
fps_display.draw()

# Initializing the window for writing
init = initialize_window()

# We schedule an "update all" to scan all actors every 5seconds
pyglet.clock.schedule_interval(generate_all, 5)

# We schedule a check to make sure the game is still running every 3 seconds
pyglet.clock.schedule_interval(smr.rm.check_process_is_active, 3)

# We schedule a basic graphics load which is responsible for updating
# the actors we are interested in (from our generate_all). Runs as fast as possible
pyglet.clock.schedule(update_graphics)

# Adds an FPS counter at the bottom left corner of our pyglet window
# Note: May not translate to actual FPS, but rather FPS of the program
fps_display = pyglet.window.FPSDisplay(window)

# Our base player_count label in the top-right of our screen. Updated
# in on_draw(). Use a default of "Initializing", which will update once the
# hack is actually running
player_count = Label("...Initializing Framework...",
x=SOT_WINDOW_W * 0.85,
y=SOT_WINDOW_H * 0.9, batch=main_batch)

# The label for showing all players on the server under the count
# This purely INITIALIZES it does not inherently update automatically
if False: # pylint: disable=using-constant-test
crew_list = Label("", x=SOT_WINDOW_W * 0.85,
y=(SOT_WINDOW_H-25) * 0.9, batch=main_batch, width=300,
multiline=True)
# Note: The width of 300 is the max pixel width of a single line
# before auto-wrapping the text to the next line. Updated in on_draw()

# Runs our application, targeting a specific refresh rate (1/60 = 60fps)
pyglet.app.run(interval=1/FPS_TARGET)
# Note - ***Nothing past here will execute as app.run() is a loop***
try:
smr.read_actors()
except Exception as e:
logger.error(f"Error in Debug mode: {e}")
else:
# Set pyglet window config, can modify vsync and other options here
config = Config(double_buffer=True, depth_size=24, alpha_size=8)
window = pyglet.window.Window(SOT_WINDOW_W, SOT_WINDOW_H,
vsync=False, style='overlay', config=config,
caption="DougTheDruid's ESP Framework")
hwnd = window._hwnd # pylint: disable=protected-access
window.set_location(SOT_WINDOW[0], SOT_WINDOW[1])

@window.event
def on_draw():
"""
Window event to draw content. Updates player count and draws the batch & FPS display.
"""
window.clear()
if smr.crew_data:
player_count.text = f"Player Count: {smr.crew_data.total_players}"
main_batch.draw()
fps_display.draw()

# Initialize the window
init = initialize_window()

# Schedule actor update every 5 seconds and process check every 3 seconds
pyglet.clock.schedule_interval(generate_all, 5)
pyglet.clock.schedule_interval(smr.rm.check_process_is_active, 3)

# Schedule continuous graphics updates as fast as possible
pyglet.clock.schedule(update_graphics)

# Add FPS counter to the window
fps_display = pyglet.window.FPSDisplay(window)

# Initialize player count label
player_count = Label("...Initializing Framework...",
x=SOT_WINDOW_W * 0.85,
y=SOT_WINDOW_H * 0.9, batch=main_batch)

# Run the application with a specified FPS target
pyglet.app.run(interval=1/FPS_TARGET)