mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
	
	
		
			158 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			158 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import os | ||
|  | import platform | ||
|  | import re | ||
|  | import sys | ||
|  | from contextlib import suppress | ||
|  | from pathlib import Path | ||
|  | 
 | ||
|  | from worlds._sc2common.bot import logger | ||
|  | 
 | ||
|  | from . import wsl | ||
|  | 
 | ||
|  | BASEDIR = { | ||
|  |     "Windows": "C:/Program Files (x86)/StarCraft II", | ||
|  |     "WSL1": "/mnt/c/Program Files (x86)/StarCraft II", | ||
|  |     "WSL2": "/mnt/c/Program Files (x86)/StarCraft II", | ||
|  |     "Darwin": "/Applications/StarCraft II", | ||
|  |     "Linux": "~/StarCraftII", | ||
|  |     "WineLinux": "~/.wine/drive_c/Program Files (x86)/StarCraft II", | ||
|  | } | ||
|  | 
 | ||
|  | USERPATH = { | ||
|  |     "Windows": "Documents\\StarCraft II\\ExecuteInfo.txt", | ||
|  |     "WSL1": "Documents/StarCraft II/ExecuteInfo.txt", | ||
|  |     "WSL2": "Documents/StarCraft II/ExecuteInfo.txt", | ||
|  |     "Darwin": "Library/Application Support/Blizzard/StarCraft II/ExecuteInfo.txt", | ||
|  |     "Linux": None, | ||
|  |     "WineLinux": None, | ||
|  | } | ||
|  | 
 | ||
|  | BINPATH = { | ||
|  |     "Windows": "SC2_x64.exe", | ||
|  |     "WSL1": "SC2_x64.exe", | ||
|  |     "WSL2": "SC2_x64.exe", | ||
|  |     "Darwin": "SC2.app/Contents/MacOS/SC2", | ||
|  |     "Linux": "SC2_x64", | ||
|  |     "WineLinux": "SC2_x64.exe", | ||
|  | } | ||
|  | 
 | ||
|  | CWD = { | ||
|  |     "Windows": "Support64", | ||
|  |     "WSL1": "Support64", | ||
|  |     "WSL2": "Support64", | ||
|  |     "Darwin": None, | ||
|  |     "Linux": None, | ||
|  |     "WineLinux": "Support64", | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | def platform_detect(): | ||
|  |     pf = os.environ.get("SC2PF", platform.system()) | ||
|  |     if pf == "Linux": | ||
|  |         return wsl.detect() or pf | ||
|  |     return pf | ||
|  | 
 | ||
|  | 
 | ||
|  | PF = platform_detect() | ||
|  | 
 | ||
|  | 
 | ||
|  | def get_home(): | ||
|  |     """Get home directory of user, using Windows home directory for WSL.""" | ||
|  |     if PF in {"WSL1", "WSL2"}: | ||
|  |         return wsl.get_wsl_home() or Path.home().expanduser() | ||
|  |     return Path.home().expanduser() | ||
|  | 
 | ||
|  | 
 | ||
|  | def get_user_sc2_install(): | ||
|  |     """Attempts to find a user's SC2 install if their OS has ExecuteInfo.txt""" | ||
|  |     if USERPATH[PF]: | ||
|  |         einfo = str(get_home() / Path(USERPATH[PF])) | ||
|  |         if os.path.isfile(einfo): | ||
|  |             with open(einfo) as f: | ||
|  |                 content = f.read() | ||
|  |             if content: | ||
|  |                 base = re.search(r" = (.*)Versions", content).group(1) | ||
|  |                 if PF in {"WSL1", "WSL2"}: | ||
|  |                     base = str(wsl.win_path_to_wsl_path(base)) | ||
|  | 
 | ||
|  |                 if os.path.exists(base): | ||
|  |                     return base | ||
|  |     return None | ||
|  | 
 | ||
|  | 
 | ||
|  | def get_env(): | ||
|  |     # TODO: Linux env conf from: https://github.com/deepmind/pysc2/blob/master/pysc2/run_configs/platforms.py | ||
|  |     return None | ||
|  | 
 | ||
|  | 
 | ||
|  | def get_runner_args(cwd): | ||
|  |     if "WINE" in os.environ: | ||
|  |         runner_file = Path(os.environ.get("WINE")) | ||
|  |         runner_file = runner_file if runner_file.is_file() else runner_file / "wine" | ||
|  |         """
 | ||
|  |         TODO Is converting linux path really necessary? | ||
|  |         That would convert | ||
|  |         '/home/burny/Games/battlenet/drive_c/Program Files (x86)/StarCraft II/Support64' | ||
|  |         to | ||
|  |         'Z:\\home\\burny\\Games\\battlenet\\drive_c\\Program Files (x86)\\StarCraft II\\Support64' | ||
|  |         """
 | ||
|  |         return [runner_file, "start", "/d", cwd, "/unix"] | ||
|  |     return [] | ||
|  | 
 | ||
|  | 
 | ||
|  | def latest_executeble(versions_dir, base_build=None): | ||
|  |     latest = None | ||
|  | 
 | ||
|  |     if base_build is not None: | ||
|  |         with suppress(ValueError): | ||
|  |             latest = ( | ||
|  |                 int(base_build[4:]), | ||
|  |                 max(p for p in versions_dir.iterdir() if p.is_dir() and p.name.startswith(str(base_build))), | ||
|  |             ) | ||
|  | 
 | ||
|  |     if base_build is None or latest is None: | ||
|  |         latest = max((int(p.name[4:]), p) for p in versions_dir.iterdir() if p.is_dir() and p.name.startswith("Base")) | ||
|  | 
 | ||
|  |     version, path = latest | ||
|  | 
 | ||
|  |     if version < 55958: | ||
|  |         logger.critical("Your SC2 binary is too old. Upgrade to 3.16.1 or newer.") | ||
|  |         sys.exit(1) | ||
|  |     return path / BINPATH[PF] | ||
|  | 
 | ||
|  | 
 | ||
|  | class _MetaPaths(type): | ||
|  |     """"Lazily loads paths to allow importing the library even if SC2 isn't installed.""" | ||
|  | 
 | ||
|  |     # pylint: disable=C0203 | ||
|  |     def __setup(self): | ||
|  |         if PF not in BASEDIR: | ||
|  |             logger.critical(f"Unsupported platform '{PF}'") | ||
|  |             sys.exit(1) | ||
|  | 
 | ||
|  |         try: | ||
|  |             base = os.environ.get("SC2PATH") or get_user_sc2_install() or BASEDIR[PF] | ||
|  |             self.BASE = Path(base).expanduser() | ||
|  |             self.EXECUTABLE = latest_executeble(self.BASE / "Versions") | ||
|  |             self.CWD = self.BASE / CWD[PF] if CWD[PF] else None | ||
|  | 
 | ||
|  |             self.REPLAYS = self.BASE / "Replays" | ||
|  | 
 | ||
|  |             if (self.BASE / "maps").exists(): | ||
|  |                 self.MAPS = self.BASE / "maps" | ||
|  |             else: | ||
|  |                 self.MAPS = self.BASE / "Maps" | ||
|  |         except FileNotFoundError as e: | ||
|  |             logger.critical(f"SC2 installation not found: File '{e.filename}' does not exist.") | ||
|  |             sys.exit(1) | ||
|  | 
 | ||
|  |     # pylint: disable=C0203 | ||
|  |     def __getattr__(self, attr): | ||
|  |         # pylint: disable=E1120 | ||
|  |         self.__setup() | ||
|  |         return getattr(self, attr) | ||
|  | 
 | ||
|  | 
 | ||
|  | class Paths(metaclass=_MetaPaths): | ||
|  |     """Paths for SC2 folders, lazily loaded using the above metaclass.""" |