-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.py
242 lines (193 loc) · 8.86 KB
/
functions.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
import json
import time
import pyautogui
import win32process
import psutil
import random
import os
def check_user_data():
"""
Checks if the user data file exists and if it contains a valid executable path to the FNaF World executable.
If the user data file is not found or is invalid, prompts the user to start the game to create a new user data file.
Raises:
FileNotFoundError: If the user data file is not found.
ValueError: If the user data file contains an invalid executable path.
"""
try:
# Check if the user data file exists and if it contains a valid executable path
assert os.path.isfile("user.json")
with open("user.json", "r") as f:
data = json.load(f)
exePath = data.get("exePath")
if not os.path.isfile(exePath) or exePath is None:
raise ValueError
except (AssertionError, FileNotFoundError):
# If the user data file is not found, prompt the user to start the game to create a new user data file
pyautogui.alert(
title="Alert", text="No user data file found.\nPlease start the game to use this program")
get_game_path()
except ValueError:
# If the user data file is invalid, prompt the user to start the game to create a new user data file
pyautogui.alert(
title="Alert", text="The user data file is invalid.\nPlease start the game to use this program")
get_game_path()
def get_game_path():
"""
Finds the path to the FNaF World executable and saves it to a user data file.
Raises:
Exception: If the executable path is not found.
"""
hwnd = []
# Loop until the FNaF World window is found
while hwnd == []:
hwnd = pyautogui.getWindowsWithTitle("FNaF World")
if len(hwnd) > 0:
hwnd = win32process.GetWindowThreadProcessId(hwnd[0]._hWnd)[1]
exePath = None
# Get the process ID of the FNaF World window and find the executable path
for process in psutil.process_iter():
try:
if process.pid == hwnd:
exePath = process.exe()
break
except (psutil.AccessDenied, psutil.NoSuchProcess):
exePath = None
# Raise an exception if the executable path is not found
if exePath is None:
raise Exception("Could not find FNaF World process")
# Get the name of the executable and save the path and name to a user data file
exeName = os.path.basename(exePath)
data = {"exePath": exePath, "exeName": exeName}
with open("user.json", "w") as f:
json.dump(data, f)
def isGameOpened():
# Get list of current processes using psutil
processes = [process.name() for process in psutil.process_iter()]
# Get the name of the game from the user data file
with open("user.json", "r") as f:
data = json.load(f)
gameName = data.get("exeName")
return gameName in processes
class InferenceActions:
def __init__(self, model):
"""
Initializes the Inference class with a given model.
Parameters:
model (detectron2.engine.defaults.DefaultPredictor): The model to use for inference.
"""
self.model = model
def runInference(self, img, returnParams=False):
"""
Runs the given image through the model and returns the detection results.
Parameters:
img (PIL.Image): The image to run through the model.
returnParams (bool): Whether or not to return the detection details.
Returns:
Detectron2.utils.visualizer.GenericMask: The detection results.
dict: A dictionary containing the detection details (if returnParams is True).
"""
# Run the image through the model
inferenceResults = self.model(img)
# Return the detection details if prompted by the user
if returnParams:
parameters = {
"center": [(int((box[2] + box[0]) / 2), int((box[3] + box[1]) / 2)) for box in inferenceResults.xyxy[0]],
"conf": list(inferenceResults.pandas().xyxy[0].confidence),
"name": list(inferenceResults.pandas().xyxy[0].name)
}
return inferenceResults, parameters
else:
return inferenceResults
def getCurrentStatus(self, parametersDict):
"""
Determines the current status of the game based on the given parameters dictionary.
Parameters:
parametersDict (dict): A dictionary containing the detection details of the current game screen.
Returns:
str: A string representing the current status of the game.
"""
statusOptions = {
'Overworld': 'Overworld',
'New Challenger': 'Encountered Challenger',
'Victory': 'Battle End Screen',
'Health': 'In Battle',
'Lolbit Shop': 'Shopping'
}
return "Picking Option" if all(option in parametersDict["name"] for option in ["Health", "Fighting Option"]) else next((option for label, option in statusOptions.items() if label in parametersDict["name"]), "Clueless")
class Modules:
def __init__(self) -> None:
self.previous_key = None
self.last_seen = None
self.activated = {
'AutoRoam': False,
'AutoFight': False
}
def promptModules(self):
"""
Prompts the user to enable or disable the AutoFight and AutoRoam modules.
Returns:
None
"""
self.activated['AutoFight'] = pyautogui.confirm(
title="Enable Module", text="Do you want to enable the fighting module?", buttons=["Yes", "No"]) == "Yes"
self.activated['AutoRoam'] = pyautogui.confirm(
title="Enable Module", text="Do you want to enable the roaming module?\nWARNING: Having a text prompt open while the module is running will cause the inputs to be sent to the prompt.", buttons=["Yes", "No"]) == "Yes"
def runModules(self, parameters, status):
"""
Runs the AutoFight and AutoRoam modules if they are enabled.
Parameters:
parameters (dict): A dictionary containing the detection details of the current game screen.
status (str): A string representing the current status of the game.
Returns:
None
"""
if self.activated['AutoFight']:
self.AutoFight(parameters, status)
if self.activated['AutoRoam']:
self.AutoRoam(parameters, status)
def clickWarp(self, number):
pyautogui.click(1817, 30 + (number * 110))
def AutoFight(self, parameters, status):
"""
Picks a fighting option at random from the available options on the screen.
Parameters:
parameters (dict): A dictionary containing the detection details of the current game screen.
status (str): A string representing the current status of the game.
Returns:
None
"""
if status == 'Picking Option':
indexes = [i for i, name in enumerate(parameters["name"]) if name == 'Fighting Option']
option_picked = random.choice(indexes)
pyautogui.click(parameters["center"][option_picked])
def AutoRoam(self, parameters, status):
"""
Moves the player character randomly in the overworld or attempts to return to a known state if the program doesn't know the current status.
Parameters:
parameters (dict): A dictionary containing the detection details of the current game screen.
status (str): A string representing the current status of the game.
Returns:
None
"""
controls = ['w', 'a', 's', 'd']
if self.last_seen is not None and time.time() - self.last_seen > 30:
self.clickWarp(random.randint(1, 6))
else:
self.last_seen = time.time()
# Add function to avoid repeating code blocks
def press(key, delay = None):
pyautogui.keyDown(key)
if delay != None:
time.sleep(delay)
pyautogui.keyUp(key)
# If the user is in the overworld, move in a random direction and save the key pressed
if status == 'Overworld':
key = random.choice(controls)
press(key, random.uniform(0, 1.5))
self.previous_key = key
elif status == 'Clueless':
# Keep pressing the previous key until the AI has returned to the overworld, or press a random key if there isn't a previous key
press(controls[(controls.index(self.previous_key) + 2) % len(controls)] if self.previous_key != None else random.choice(controls), 0.5)
# If the user enters a shop, click the Done button to exit
elif status == 'Shopping' and 'Done Button' in parameters['name']:
pyautogui.click(parameters['center'][parameters['name'].index('Done Button')])