mirror of
https://github.com/bnowakow/GT7-Scripts.git
synced 2025-12-17 01:27:04 +00:00
Merge pull request #4 from IlIllII/patch-1
Patch 1 - added a python script
This commit is contained in:
39
python_scripts/README.md
Normal file
39
python_scripts/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# race_in_circles
|
||||
|
||||
The `race_in_circles.py` script allows you to automate racing circular tracks using pyautogui and PS Remote Play. NOTE: The track MUST be circular. I think the script should work on any platform.
|
||||
|
||||
## Instructions
|
||||
|
||||
All you need to do is open PS Remote Play and then navigate to the race start screen for the track you want to automate. This is the screen with `Start`, `Settings`, and `Exit` buttons. Make sure that the remote play window is in the middle of your primary monitor because the script clicks the center of the screen to get the winow's focus.
|
||||
|
||||
Next, open a terminal with administrator privileges (I had to use administrator privileges, but you might not have to). Navigate to the directory containing this script and run it:
|
||||
|
||||
```bash
|
||||
py race_in_circles.py
|
||||
```
|
||||
|
||||
Voila! You are now racing in circles.
|
||||
|
||||
By default this will race around a circular track with left turns for 200 seconds before navigating through the menus to restart the race. You can change the behavior by passing some command line arguments.
|
||||
|
||||
- To change the side of the track you hug, you can pass the flag `--direction=DIRECTION`. By default you hug the `right` rail. You can also simply pass `-left` or `-l` or `-right` or `-r`.
|
||||
- You can change the duration with `--duration=DURATION`, where `DURATION` is the number of seconds that the race takes. You can also simply pass a number, like `200`. To get a sense for how long the race takes, start the script with a long duration, say `1000` seconds, and see how long it takes to navigate the course and then restart the script using the new duration (you should add some padding to account for collisions, maybe +10 seconds to be safe).
|
||||
|
||||
The following command will automate a 120 second race where you hug the left hand rail of the course:
|
||||
|
||||
```bash
|
||||
py race_in_circles.py --direction=left --duration=120
|
||||
```
|
||||
|
||||
Another command that does the same thing:
|
||||
|
||||
```bash
|
||||
py race_in_circles.py -left 120
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
Right now the script simply navigates through the menus for standard races and runs a race based on timing, meaning if you spin out or something the timing will likely be off.
|
||||
|
||||
If you want to automate a different event, say a championship series, you can edit the script with new menu navigation commands. These are self explanatory in the script.
|
||||
|
||||
137
python_scripts/race_in_circles.py
Normal file
137
python_scripts/race_in_circles.py
Normal file
@@ -0,0 +1,137 @@
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
import pyautogui
|
||||
|
||||
# Default parameters - these can be overridden with command
|
||||
# line arguments. See end of script for details.
|
||||
RACE_DURATION = 200
|
||||
DIRECTION = "right"
|
||||
SILENCE = False
|
||||
|
||||
|
||||
def press(key: str) -> None:
|
||||
"""Press a key.
|
||||
|
||||
Using vanilla `pyautogui.press()` will not register the keystroke
|
||||
because GT requires you hold a keypress for a small duration."""
|
||||
with pyautogui.hold(key):
|
||||
time.sleep(0.2)
|
||||
|
||||
|
||||
def hold(key: str, duration: float) -> None:
|
||||
"""Hold a key for some duration."""
|
||||
|
||||
with pyautogui.hold(key):
|
||||
time.sleep(duration)
|
||||
|
||||
|
||||
def ride_rail(direction: str) -> None:
|
||||
"""
|
||||
This will drive a car around any convex hull while hugging
|
||||
the `direction` rail. If you pass `left`, your car will hug
|
||||
the left rail, thus allowing you to go around righthand turns.
|
||||
"""
|
||||
|
||||
race_start = time.time()
|
||||
with pyautogui.hold("up"):
|
||||
while time.time() - race_start < RACE_DURATION:
|
||||
hold(direction, (random.randrange(200) / 1000))
|
||||
time.sleep((random.randrange(100) / 100))
|
||||
|
||||
|
||||
def race(direction: str) -> None:
|
||||
"""`direction` is the rail to hug, not the direction to turn!"""
|
||||
|
||||
ride_rail(direction)
|
||||
|
||||
|
||||
def end_race() -> None:
|
||||
"""Navigate through post-race menus and replay."""
|
||||
|
||||
commands = [
|
||||
"enter",
|
||||
"enter",
|
||||
"enter",
|
||||
"enter",
|
||||
"enter",
|
||||
"enter",
|
||||
"enter",
|
||||
"right",
|
||||
"enter",
|
||||
"down",
|
||||
"down",
|
||||
"down",
|
||||
"left",
|
||||
"left",
|
||||
"enter",
|
||||
]
|
||||
for command in commands:
|
||||
press(command)
|
||||
time.sleep((random.randrange(500) / 1000) + 2)
|
||||
|
||||
|
||||
def start_race(first: bool) -> None:
|
||||
"""Initiate race from the start race menu."""
|
||||
if first:
|
||||
# Click center of screen to focus remote play window.
|
||||
# You can reposition and resize remote play window, just
|
||||
# make sure you update where you click. I don't know how to
|
||||
# use pyautogui in headless mode.
|
||||
width, height = pyautogui.size()
|
||||
center = width / 2, height / 2
|
||||
pyautogui.moveTo(center)
|
||||
pyautogui.click()
|
||||
time.sleep(1)
|
||||
|
||||
# This is the button sequence you press when the 'replay'
|
||||
# button IS NOT visible on the race start screen.
|
||||
press("down")
|
||||
press("down")
|
||||
press("down")
|
||||
press("left")
|
||||
press("enter")
|
||||
else:
|
||||
# This is the button sequence you press when the 'replay'
|
||||
# button IS visible on the race start screen.
|
||||
press("down")
|
||||
press("down")
|
||||
press("down")
|
||||
press("left")
|
||||
press("left")
|
||||
press("enter")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
args = sys.argv
|
||||
for arg in args[1:]:
|
||||
if "=" in arg:
|
||||
flag, value = arg.split("=")
|
||||
if flag == "--direction":
|
||||
DIRECTION = value
|
||||
if flag == "--duration" and value.isdigit():
|
||||
RACE_DURATION = int(value)
|
||||
else:
|
||||
if arg == "-left" or arg == "-l":
|
||||
DIRECTION = "left"
|
||||
if arg == "-right" or arg == "-r":
|
||||
DIRECTION = "right"
|
||||
if arg == "-silence":
|
||||
SILENCE = True
|
||||
if arg.isdigit():
|
||||
RACE_DURATION = int(value)
|
||||
|
||||
first = True
|
||||
while True:
|
||||
start = time.time()
|
||||
start_race(first)
|
||||
first = False
|
||||
race(DIRECTION)
|
||||
end_race()
|
||||
end = time.time()
|
||||
duration = end - start
|
||||
print(duration, flush=True)
|
||||
|
||||
if not SILENCE:
|
||||
print(f"{(((60*60) / duration)):.2f} races/hour", flush=True)
|
||||
Reference in New Issue
Block a user