forked from BurnySc2/python-sc2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpaths.py
More file actions
117 lines (91 loc) · 3.57 KB
/
paths.py
File metadata and controls
117 lines (91 loc) · 3.57 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
import logging
import os
import platform
import re
import subprocess
from pathlib import Path
logger = logging.getLogger(__name__)
BASEDIR = {
"Windows": "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",
"Darwin": "/Library/Application Support/Blizzard/StarCraft II/ExecuteInfo.txt",
"Linux": None,
"WineLinux": None,
}
BINPATH = {
"Windows": "SC2_x64.exe",
"Darwin": "SC2.app/Contents/MacOS/SC2",
"Linux": "SC2_x64",
"WineLinux": "SC2_x64.exe",
}
CWD = {"Windows": "Support64", "Darwin": None, "Linux": None, "WineLinux": "Support64"}
PF = os.environ.get("SC2PF", platform.system())
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_dir = os.path.dirname(os.environ.get("WINE"))
# translate cwd from Unix to Windows path
win_cwd = subprocess.run(
[os.path.join(runner_dir, "winepath"), "-w", cwd], capture_output=True, text=True
).stdout.rstrip()
return [os.environ.get("WINE"), "start", "/d", win_cwd, "/unix"]
return []
def latest_executeble(versions_dir, base_build=None):
latest = None
if base_build is not None:
try:
latest = (
int(base_build[4:]),
max(p for p in versions_dir.iterdir() if p.is_dir() and p.name.startswith(str(base_build))),
)
except ValueError:
pass
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(f"Your SC2 binary is too old. Upgrade to 3.16.1 or newer.")
exit(1)
return path / BINPATH[PF]
class _MetaPaths(type):
""""Lazily loads paths to allow importing the library even if SC2 isn't installed."""
def __setup(self):
if PF not in BASEDIR:
logger.critical(f"Unsupported platform '{PF}'")
exit(1)
try:
base = os.environ.get("SC2PATH")
if base is None and USERPATH[PF] is not None:
einfo = str(Path.home().expanduser()) + 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 not os.path.exists(base):
base = None
if base is None:
base = 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.")
exit(1)
def __getattr__(self, attr):
self.__setup()
return getattr(self, attr)
class Paths(metaclass=_MetaPaths):
"""Paths for SC2 folders, lazily loaded using the above metaclass."""