Skip to content

Commit 564bd37

Browse files
authored
Update and rename main.py to game_manager.py
1 parent fe69cc6 commit 564bd37

File tree

2 files changed

+134
-270
lines changed

2 files changed

+134
-270
lines changed

game_manager.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import subprocess
2+
import os
3+
import shutil
4+
import logging
5+
from config_manager import ConfigManager
6+
7+
class GameManager:
8+
def __init__(self, proton_manager):
9+
self.proton_manager = proton_manager
10+
self.config_manager = ConfigManager()
11+
12+
def add_game(self, game):
13+
games = self.config_manager.load_games()
14+
games.append(game)
15+
self.config_manager.save_games(games)
16+
logging.info(f"Added game: {game['name']}")
17+
18+
def remove_game(self, name):
19+
games = self.config_manager.load_games()
20+
games = [g for g in games if g['name'] != name]
21+
self.config_manager.save_games(games)
22+
logging.info(f"Removed game: {name}")
23+
24+
def launch_game(self, game, gamescope=False):
25+
runner = game['runner']
26+
exe = game['exe']
27+
app_id = game.get('app_id', '')
28+
prefix = game.get('prefix', '')
29+
launch_options = game.get('launch_options', '').split()
30+
env = os.environ.copy()
31+
32+
# Validate inputs
33+
if runner != 'Steam' and not os.path.exists(exe):
34+
raise Exception(f"Executable does not exist: {exe}")
35+
if runner == 'Steam' and not app_id:
36+
raise Exception("Steam App ID not set")
37+
38+
# Set up environment for Wine/Proton
39+
if runner in ['Wine'] or 'Proton' in runner:
40+
if not prefix:
41+
raise Exception("Prefix not set for Wine/Proton runner")
42+
try:
43+
os.makedirs(prefix, exist_ok=True)
44+
# Fix ownership if running as root with sudo
45+
if os.geteuid() == 0 and 'SUDO_UID' in os.environ:
46+
user_id = os.environ['SUDO_UID']
47+
group_id = os.environ['SUDO_GID']
48+
subprocess.run(['chown', '-R', f'{user_id}:{group_id}', prefix], check=True)
49+
protonfixes_dir = os.path.expanduser('~/.config/protonfixes')
50+
os.makedirs(protonfixes_dir, exist_ok=True)
51+
subprocess.run(['chown', '-R', f'{user_id}:{group_id}', protonfixes_dir], check=True)
52+
except Exception as e:
53+
raise Exception(f"Failed to set up prefix or protonfixes: {e}")
54+
env['WINEPREFIX'] = prefix
55+
if game.get('enable_dxvk', False):
56+
env['WINEDLLOVERRIDES'] = 'd3d11=n,b;dxgi=n,b'
57+
env['WINEESYNC'] = '1' if game.get('enable_esync', self.config_manager.settings['enable_esync']) else '0'
58+
env['WINEFSYNC'] = '1' if game.get('enable_fsync', self.config_manager.settings['enable_fsync']) else '0'
59+
env['DXVK_ASYNC'] = '1' if game.get('enable_dxvk_async', self.config_manager.settings['enable_dxvk_async']) else '0'
60+
61+
# Build command
62+
cmd = []
63+
if gamescope:
64+
if not shutil.which('gamescope'):
65+
raise Exception("Gamescope is not installed. Please install it via your package manager (e.g., dnf install gamescope).")
66+
cmd = ['gamescope']
67+
options_to_remove = []
68+
if '--adaptive-sync' in launch_options:
69+
cmd.append('--adaptive-sync')
70+
options_to_remove.append('--adaptive-sync')
71+
if '--force-grab-cursor' in launch_options:
72+
cmd.append('--force-grab-cursor')
73+
options_to_remove.append('--force-grab-cursor')
74+
width_idx = next((i for i, opt in enumerate(launch_options) if opt.startswith('--width=')), None)
75+
if width_idx is not None:
76+
cmd.append('-W')
77+
cmd.append(launch_options[width_idx].split('=')[1])
78+
options_to_remove.append(launch_options[width_idx])
79+
height_idx = next((i for i, opt in enumerate(launch_options) if opt.startswith('--height=')), None)
80+
if height_idx is not None:
81+
cmd.append('-H')
82+
cmd.append(launch_options[height_idx].split('=')[1])
83+
options_to_remove.append(launch_options[height_idx])
84+
if '--fullscreen' in launch_options:
85+
cmd.append('-f')
86+
options_to_remove.append('--fullscreen')
87+
if '--bigpicture' in launch_options:
88+
cmd.extend(['-e', '-f'])
89+
options_to_remove.append('--bigpicture')
90+
# Remove processed options
91+
launch_options = [opt for opt in launch_options if opt not in options_to_remove]
92+
cmd.append('--')
93+
94+
try:
95+
if runner == 'Native':
96+
cmd.extend([exe] + launch_options)
97+
elif runner == 'Wine':
98+
if not shutil.which('wine'):
99+
raise Exception("Wine not installed. Please install it (e.g., dnf install wine).")
100+
cmd.extend(['wine', exe] + launch_options)
101+
elif runner == 'Flatpak':
102+
if not shutil.which('flatpak'):
103+
raise Exception("Flatpak not installed. Please install it (e.g., dnf install flatpak).")
104+
cmd.extend(['flatpak', 'run', exe] + launch_options)
105+
elif runner == 'Steam':
106+
if shutil.which('flatpak') and not shutil.which('steam'):
107+
cmd.extend(['flatpak', 'run', 'com.valvesoftware.Steam', '-applaunch', app_id] + launch_options)
108+
elif shutil.which('steam'):
109+
cmd.extend(['steam', '-applaunch', app_id] + launch_options)
110+
else:
111+
raise Exception("Steam or Flatpak not installed. Please install Steam (e.g., flatpak install flathub com.valvesoftware.Steam).")
112+
else: # Proton
113+
proton_bin = self.proton_manager.get_proton_path(runner)
114+
if not os.path.exists(proton_bin):
115+
raise Exception(f"Proton binary not found for {runner}")
116+
# Set up Steam environment for Proton
117+
steam_dir = os.path.expanduser('~/.local/share/Steam')
118+
os.makedirs(os.path.join(steam_dir, 'steamapps/compatdata'), exist_ok=True)
119+
env['STEAM_COMPAT_CLIENT_INSTALL_PATH'] = steam_dir
120+
env['STEAM_COMPAT_DATA_PATH'] = prefix
121+
env['STEAM_RUNTIME'] = os.path.join(steam_dir, 'ubuntu12_32/steam-runtime')
122+
ld_library_path = os.path.join(steam_dir, 'ubuntu12_32') + ':' + os.path.join(steam_dir, 'ubuntu12_64')
123+
env['LD_LIBRARY_PATH'] = ld_library_path + ':' + env.get('LD_LIBRARY_PATH', '')
124+
cmd.extend([proton_bin, 'waitforexitandrun', exe] + launch_options)
125+
126+
# Execute command
127+
log_file = os.path.join(self.config_manager.logs_dir, f"{game['name'].replace(' ', '_')}.log")
128+
with open(log_file, 'w') as f:
129+
process = subprocess.Popen(cmd, env=env, stdout=f, stderr=f)
130+
logging.info(f"Launched game: {game['name']} with cmd: {' '.join(cmd)}")
131+
except Exception as e:
132+
logging.error(f"Failed to launch {game['name']}: {e}")
133+
print(f"Error launching {game['name']}: {e}")
134+
raise

0 commit comments

Comments
 (0)