forked from IlIllII/GT7-Race-Automation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
140 lines (116 loc) · 3.76 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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 arg[0] != "-":
print("Please pass arguments using the appropriate syntax: [--flag=value]")
else:
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)