-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpaths.py
153 lines (120 loc) · 4.49 KB
/
paths.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
import os
import platform
import re
from pathlib import Path
from loguru import logger
import sc2.wsl as 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 == "WSL1" or PF == "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 == "WSL1" or PF == "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:
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") 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.")
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."""