-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDSXGameDetection.py
More file actions
127 lines (98 loc) · 6.21 KB
/
DSXGameDetection.py
File metadata and controls
127 lines (98 loc) · 6.21 KB
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
import psutil
import time
import win32gui
import win32process
import subprocess
if __name__ == "__main__":
DSXConsolePath = r"T:\Jeux\Steam\steamapps\common\DSX\Main_v3_Beta\Console\DSX_Console.exe"
ControllerMacAddresses = [
"A0:FA:9C:36:B1:85"
]
monitored = {
r"T:\Jeux\Epic Games\rocketleague\Binaries\Win64\RocketLeague.exe": "Passthru - DS4",
r"C:\Program Files\Java\jdk-21\bin\javaw.exe": "MINECRAFT moduilt hybrid A"
}
MultipleGameDetectionManagement = True # ⚠️ It's an additional feature that I added, recommend to let it ON or it will struggle with more than 1 game detected.
RestorePreviousProfile = True # If enabled, when no game is detected it will re-apply the profile that was set for the controller.
HighDelay = 5 # Delay used between each verification of the list of running processes.
LowDelay = 1 # Delay used between each verification of the currently focused window when "MultipleGameDetectionManagement" is enabled and 2 or more detected games are running.
# -------------- Settings ↑
previous_profiles = None
current_profile = None # Variable used to track internally the last profile that was applied, to not apply it twice in a row.
verification_interval_reset = round(HighDelay / LowDelay)
verification_interval = -1 # When multiple games are detected, the loop will speed up "LowDelay" to start tracking the focused window. This Variable ensure that the process detection stay at "HighDelay" by skipping loops
delay = HighDelay
NoGameDetected = 1 # When this Variable change to 0, the previous profiles will be Stored.
NewControllerDetected = False # This Variable does absolutely nothing but assuming that turning on a new controller results in NewControllerDetected = True, this would correct any problem associated with turning on a controller while a game is already detected. It would also be important to restore the profile of a controller stored in previous_profiles before switching it off if RestorePreviousProfile = True
def update_to(profile_name):
global NewControllerDetected
global current_profile
print(f"Selected : \"{profile_name}\"")
if (current_profile != profile_name or NewControllerDetected) and profile_name != None: # If profile is not applied yet, applies it.
if isinstance(profile_name, (dict, list)): # If profile_name is set to the "previous_profiles" json.
current_profile = None
for controller, profile in profile_name.items():
print(f" ● Restoring \"{profile}\" to {controller}")
subprocess.run(
f'"{DSXConsolePath}" /silent /changeProfile "{controller}" "{profile}"',
shell=True
)
return
current_profile = profile_name
for controller in ControllerMacAddresses: # Apply the profile to every Controller.
print(f" ● Applying \"{profile_name}\" to {controller}")
subprocess.run(
f'"{DSXConsolePath}" /silent /changeProfile "{controller}" "{profile_name}"',
shell=True
)
NewControllerDetected = False
def store_previous_profiles():
print(" ○ Previous profiles saved")
global previous_profiles
previous_profiles = {
"A0:FA:9C:36:B1:85": "Passthru - Native"
}
# ⚠️ "Passthru - Native" is my personal default profile for everything, in a real implementation it would use the name of the currently in use profile for each controller. Also, on this program the option to restore profile is set gloabally. to enable it depending on the game like it's currently in DSX, this part would need to avoid storing the previous profile when needed, depending on which game is selected. But it hoonestly feel like a unnecessary headache to make it work correctly with MultipleGameDetectionManagement, wich is a more useful feature imo
while True:
if verification_interval < 1:
running_apps = set()
for process in psutil.process_iter(): # List all processes that have a defined profile.
try:
name = process.exe()
if name in monitored:
running_apps.add(name)
if NoGameDetected == 1:
NoGameDetected = 0
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
if NoGameDetected == 0:
store_previous_profiles()
NoGameDetected = -1
verification_interval -= 1
else:
verification_interval -= 1
if verification_interval < 0:
print(f"Detected : {running_apps if running_apps != set() else None}")
else:
print(f"{verification_interval + 1} loops before process check")
if len(running_apps) > 1 and MultipleGameDetectionManagement: # If multiple games are detected
delay = LowDelay
try:
_, pid = win32process.GetWindowThreadProcessId(win32gui.GetForegroundWindow())
focused_process = psutil.Process(pid) # Retrieve the process related to the active window.
except:
print("Can't access, executing process check on next loop")
verification_interval = 0
if focused_process.exe() in monitored: # If the focused process as a profile, select it.
update_to(monitored[focused_process.exe()])
if verification_interval < 0:
verification_interval = verification_interval_reset
elif len(running_apps) > 0 : # If 1 game is detected
delay = HighDelay
update_to(monitored[next(iter(running_apps))])
else: # If not game is detected
delay = HighDelay
NoGameDetected = 1
if RestorePreviousProfile and current_profile != None:
update_to(previous_profiles)
time.sleep(delay)