-
Notifications
You must be signed in to change notification settings - Fork 7
/
pw.py
227 lines (204 loc) · 8.47 KB
/
pw.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
import argparse
import contextlib
import subprocess
import shutil
import sys
import os
def main():
parser = argparse.ArgumentParser(description="Compile, stage, and package PurpleWave and its JREs.")
parser.add_argument('--all', action='store_true', default=False, help='Perform all steps')
parser.add_argument('--jre', action='store_true', default=False, help='Step 1: (Skipped by default) Package lightweight JRE using jdeps+jlink, then stage them for packaging')
parser.add_argument('--maven', action='store_true', default=False, help='Step 2: Compile PurpleWave with Maven')
parser.add_argument('--schnail', action='store_true', default=False, help='Step 3: Compile SCHNAIL launcher')
parser.add_argument('--stage', action='store_true', default=False, help='Step 4: Record deployment information, construct EXE via launch4j, then copy bot binaries and deployment information')
parser.add_argument('--package', action='store_true', default=False, help='Step 5: Re-zip directories')
args = parser.parse_args()
did_anything = False
if args.all or args.jre:
did_anything = True
makejre()
if args.all or args.maven:
did_anything = True
maven_build()
if args.all or args.schnail:
did_anything = True
schnail()
if args.all or args.stage:
did_anything = True
stage()
if args.all or args.package:
did_anything = True
package()
if not did_anything:
maven_build()
schnail()
stage()
package()
def pathjoin(*args):
result = '/'.join(map(str, args))
while '//' in result:
result = result.replace('//', '/')
return result
file_launch4j = "c:/Program Files (x86)/Launch4j/Launch4jc.exe"
dir_jre = "c:/p/graalvm-jdk/"
dir_bwapidata = "c:/p/bw/bwapi-data/"
java_version = "21"
dir_pw = "c:/p/pw/"
dir_maven_target = "c:/p/pw/target/"
dir_scbwbots = "c:/Users/d/AppData/Roaming/scbw/bots/"
dir_localschnail = "c:/Program Files (x86)/SCHNAIL Client/bots/PurpleWave/"
dir_out = pathjoin(dir_pw, "out/")
dir_configs = pathjoin(dir_pw, "configs/")
dir_staging = pathjoin(dir_out, "staging/")
dir_jar = pathjoin(dir_out, "artifacts", "PurpleWave")
file_jar = pathjoin(dir_jar, "PurpleWave.jar")
def path_pw(path):
return pathjoin(dir_pw, path)
def path_out(path):
return pathjoin(dir_out, path)
def path_configs(path):
return pathjoin(dir_configs, path)
def path_staging(path):
return pathjoin(dir_staging, path)
def path_scbwbots(path):
return pathjoin(dir_scbwbots, path)
def log(*args, **kwargs):
print(*args, **kwargs, flush=True)
def logf(f, *args, **kwargs):
log(f.__name__, args, kwargs)
f(*args, **kwargs)
def rmtree(dir):
if os.path.exists(dir):
logf(shutil.rmtree, dir)
def maven_build():
log()
log("RUNNING MAVEN BUILD")
environment = os.environ.copy()
# Maven's default heap space is 512mb. We must increase it or compiler inlining will fail due to "Error while emitting"/"Java heap space"
environment["MAVEN_OPTS"] = "\"-Xmx1024m\""
logf(subprocess.run, ["mvn", "clean", "install"], cwd=dir_pw, env=environment, shell=True)
dir_jar = dir_maven_target
global file_jar
file_jar = pathjoin(dir_maven_target, "PurpleWave.jar")
logf(shutil.copy2, pathjoin(dir_maven_target, "PurpleWave-1.0.jar"), file_jar)
def makejre():
log()
log("MAKING JRE")
jdeps = pathjoin(dir_jre, "bin", "jdeps.exe")
log(jdeps)
jdeps_stdout = subprocess.run(
[ jdeps,
"--print-module-deps",
"--multi-release",
java_version,
"-recursive",
"-cp",
dir_jar,
file_jar ],
capture_output=True,
text=True).stdout
print(jdeps_stdout)
modules = jdeps_stdout.strip().split(',')
print(modules)
logf(rmtree, path_staging("jre"))
logf(
subprocess.run,
[ pathjoin(dir_jre, "bin", "jlink.exe"),
"--add-modules",
"jdk.management.agent," + ",".join(modules),
"--output",
path_staging("jre") ])
schnail_exe_source="PurpleWaveSCHNAILCPP.exe"
def schnail():
log()
log("BUILDING SCHNAIL LAUNCHER")
subprocess.run(file_launch4j + " "+ path_configs("launch4jSCHNAIL.xml"))
subprocess.run(["x86_64-w64-mingw32-g++", "-static", "-o", path_staging("PurpleWaveSCHNAILCPP.exe"), path_pw("/src/PurpleWaveSCHNAIL.exe.cpp")])
logf(shutil.copy2, path_staging(schnail_exe_source), path_staging("PurpleWaveSCHNAIL.exe"))
def stage():
log()
log("STAGING")
log("Post-build steps")
logf(shutil.copy2, file_jar, dir_staging)
with open(path_staging("revision.txt"), 'w') as revision_file:
subprocess.run(["git", "rev-parse", "HEAD"], stdout=revision_file, text=True, cwd=dir_pw)
with open(path_staging("timestamp.txt"), 'w') as timestamp_file:
subprocess.run(["date"], stdout=timestamp_file, text=True)
logf(shutil.copy2, file_jar, path_staging("PurpleWave.jar"))
log("Building EXE with Launch4J")
subprocess.run(file_launch4j + " "+ path_configs("launch4j.xml"))
log()
log("Populate local testing")
populate_bwapidata(dir_bwapidata)
logf(shutil.copy2, path_configs("PurpleWaveLocalMetal.config.json"), pathjoin(dir_bwapidata, "AI") )
log()
if os.path.exists(dir_scbwbots):
log("Populate SC-Docker")
for race in ["Protoss", "Terran", "Zerg", "Random"]:
name = f"Purple{race}"
log(race)
log(name)
dir_bot_bwapidata = path_scbwbots(name)
populate_bwapidata(dir_bot_bwapidata)
logf(shutil.copy2, path_configs("bot.json"), dir_bot_bwapidata)
logf(shutil.copy2, path_configs("PurpleWaveLocalDocker.config.json"), pathjoin(dir_bot_bwapidata, "ai"))
# Customize bot.json
bot_json = pathjoin(dir_bot_bwapidata, "bot.json")
content = ""
with open(bot_json, 'r') as file:
content = file.read().replace("Protoss", race).replace("PurpleWave", name)
with open(bot_json, 'w') as file:
file.write(content)
else:
log("Did not find SC-Docker")
log()
if (os.path.exists(dir_localschnail)):
log("Populate SCHNAIL")
#populate_bwapidata(dir_localschnail, dir_localschnail)
#logf(shutil.copy2, path_configs("PurpleWaveSCHNAIL.config.json"), dir_localschnail)
#logf(shutil.copy2, path_staging("PurpleWaveSCHNAIL.exe"), dir_localschnail)
else:
log("Did not find SCHNAIL")
def populate_bwapidata(dir_bwapidata, dir_ai=None):
dir_ai = pathjoin(dir_bwapidata, "ai") if dir_ai is None else dir_ai
log(dir_bwapidata)
log(dir_ai)
logf(os.makedirs, dir_ai, exist_ok=True)
logf(shutil.copy2, path_configs("bwapi.dll"), dir_bwapidata)
logf(shutil.copy2, path_staging("PurpleWave.jar"), dir_ai)
logf(shutil.copy2, path_staging("timestamp.txt"), dir_ai)
logf(shutil.copy2, path_staging("revision.txt"), dir_ai)
logf(shutil.copy2, path_configs("run_proxy.bat"), dir_ai)
logf(shutil.copy2, path_configs("run64.bat"), dir_ai)
logf(shutil.copy2, path_configs("run32.bat"), dir_ai)
def package():
log()
log("PACKAGING")
for package in ["AIIDE", "BASIL", "SSCAIT", "SCHNAIL"]:
package_name = f"PurpleWave{package}"
package_dir = path_staging(package_name)
log(package_name)
log(package_dir)
logf(rmtree, package_dir)
logf(os.makedirs, package_dir)
populate_bwapidata(package_dir, package_dir)
logf(shutil.copy2, path_configs(f"{package_name}.config.json"), package_dir)
if package in ["AIIDE"]:
logf(shutil.copytree, path_staging("jre"), pathjoin(package_dir, "jre"))
open(pathjoin(package_dir, "PurpleWave.dll"), 'w').close()
# TODO: AIIDE does not want the bwapi.dll
if package in ["SCHNAIL"]:
logf(shutil.copy2, path_staging(schnail_exe_source), pathjoin(package_dir, "PurpleWaveSCHNAIL.exe"))
log()
log("Replacing zips")
for package in ["AIIDE", "BASIL", "SSCAIT", "SCHNAIL"]:
package_name = f"PurpleWave{package}"
package_dir = path_staging(package_name)
log(package_name)
log(package_dir)
with contextlib.suppress(FileNotFoundError):
logf(os.remove, path_staging(f"{package_name}.zip"))
logf(shutil.make_archive, path_staging(package_name), 'zip', path_staging(package_name))
logf(rmtree, path_staging(package_name))
if __name__ == "__main__":
main()