1 package cz.cuni.amis.pogamut.ut2004.tournament.match;
2
3 import java.io.File;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Map.Entry;
11
12 import cz.cuni.amis.pogamut.base.utils.Pogamut;
13 import cz.cuni.amis.pogamut.ut2004.tournament.GameBots2004Ini;
14 import cz.cuni.amis.pogamut.ut2004.tournament.UT2004Ini;
15 import cz.cuni.amis.pogamut.ut2004.tournament.utils.UT2004TournamentProperty;
16 import cz.cuni.amis.pogamut.ut2004.utils.UCCWrapperConf;
17 import cz.cuni.amis.utils.Const;
18 import cz.cuni.amis.utils.NullCheck;
19 import cz.cuni.amis.utils.SafeEquals;
20 import cz.cuni.amis.utils.exception.PogamutException;
21 import cz.cuni.amis.utils.token.IToken;
22 import cz.cuni.amis.utils.token.Tokens;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class UT2004MatchConfig {
38
39 public enum BotType {
40 BOT,
41 NATIVE,
42 HUMAN
43 }
44
45 protected File outputDirectory = new File("./results/matches");
46
47 protected IToken matchId = Tokens.get("DMMatch");
48
49 protected UCCWrapperConf uccConf = new UCCWrapperConf();
50
51 protected UT2004Ini ut2004Ini;
52
53 protected GameBots2004Ini gb2004Ini;
54
55 protected Map<IToken, UT2004BotConfig> bots = new HashMap<IToken, UT2004BotConfig>();
56
57 protected Map<IToken, UT2004NativeBotConfig> nativeBots = new HashMap<IToken, UT2004NativeBotConfig>();
58
59 protected Map<IToken, UT2004HumanConfig> humans = new HashMap<IToken, UT2004HumanConfig>();
60
61 private boolean humanLikeLogEnabled;
62
63 public UT2004MatchConfig() {
64 String unrealHome = Pogamut.getPlatform().getProperty(UT2004TournamentProperty.UT2004_DIR.getKey());
65 if (unrealHome != null) {
66 uccConf.setUnrealHome(unrealHome);
67 }
68
69 File ut2004File = new File(unrealHome + "/System/UT2004.ini");
70 if (ut2004File.isFile() && ut2004File.exists()) {
71 ut2004Ini = new UT2004Ini(ut2004File);
72 } else {
73 ut2004Ini = new UT2004Ini();
74 }
75
76 gb2004Ini = new GameBots2004Ini();
77 }
78
79
80
81
82
83 public UT2004MatchConfig(UT2004MatchConfig orig) {
84 this.matchId = orig.matchId;
85 this.uccConf = new UCCWrapperConf(orig.getUccConf());
86 this.ut2004Ini = new UT2004Ini(orig.getUT2004Ini());
87 this.gb2004Ini = new GameBots2004Ini(orig.getGb2004Ini());
88 for (Entry<IToken, UT2004BotConfig> bot : orig.getBots().entrySet()) {
89 this.bots.put(bot.getKey(), new UT2004BotConfig(bot.getValue()));
90 }
91 for (Entry<IToken, UT2004NativeBotConfig> bot : orig.getNativeBots().entrySet()) {
92 this.nativeBots.put(bot.getKey(), new UT2004NativeBotConfig(bot.getValue()));
93 }
94 for (Entry<IToken, UT2004HumanConfig> bot : orig.getHumans().entrySet()) {
95 this.humans.put(bot.getKey(), new UT2004HumanConfig(bot.getValue()));
96 }
97 }
98
99 @Override
100 public int hashCode() {
101 return matchId == null ? super.hashCode() : matchId.hashCode();
102 }
103
104 @Override
105 public boolean equals(Object obj) {
106 if (this == obj) return true;
107 if (obj == null) return false;
108 if (!(obj instanceof UT2004MatchConfig)) return false;
109 return SafeEquals.equals(matchId, ((UT2004MatchConfig)obj).getMatchId());
110 }
111
112 public File getOutputDirectory() {
113 return outputDirectory;
114 }
115
116 public IToken getMatchId() {
117 return matchId;
118 }
119
120 public void setMatchId(IToken matchId) {
121 this.matchId = matchId;
122 }
123
124 public void setMatchId(String matchId) {
125 this.matchId = Tokens.get(matchId);
126 }
127
128 public UCCWrapperConf getUccConf() {
129 return uccConf;
130 }
131
132
133
134
135
136 public GameBots2004Ini getGb2004Ini() {
137 return gb2004Ini;
138 }
139
140
141
142
143
144 public UT2004Ini getUT2004Ini() {
145 return ut2004Ini;
146 }
147
148 public Map<IToken, UT2004BotConfig> getBots() {
149 return bots;
150 }
151
152 public Map<IToken, UT2004NativeBotConfig> getNativeBots() {
153 return nativeBots;
154 }
155
156 public Map<IToken, UT2004HumanConfig> getHumans() {
157 return humans;
158 }
159
160
161
162
163
164
165
166
167 public List<IToken> getAllBotIds() {
168 List<IToken> bots = new ArrayList<IToken>(getBots().keySet());
169 List<IToken> nativeBots = new ArrayList<IToken>(getNativeBots().keySet());
170 List<IToken> humans = new ArrayList<IToken>(getHumans().keySet());
171 Collections.sort(bots, new Comparator<IToken>() {
172 @Override
173 public int compare(IToken o1, IToken o2) {
174 return o1.getToken().compareTo(o2.getToken());
175 }
176 });
177 Collections.sort(nativeBots, new Comparator<IToken>() {
178 @Override
179 public int compare(IToken o1, IToken o2) {
180 return o1.getToken().compareTo(o2.getToken());
181 }
182 });
183 Collections.sort(humans, new Comparator<IToken>() {
184 @Override
185 public int compare(IToken o1, IToken o2) {
186 return o1.getToken().compareTo(o2.getToken());
187 }
188 });
189 List<IToken> botIds = new ArrayList<IToken>(bots);
190 botIds.addAll(nativeBots);
191 botIds.addAll(humans);
192 return botIds;
193 }
194
195 public UT2004MatchConfig setOutputDirectory(File outputDirectory) {
196 this.outputDirectory = outputDirectory;
197 return this;
198 }
199
200 public UT2004MatchConfig setUccConf(UCCWrapperConf uccConf) {
201 this.uccConf = uccConf;
202 return this;
203 }
204
205
206
207
208
209 public UT2004MatchConfig setGb2004Ini(GameBots2004Ini gb2004Ini) {
210 this.gb2004Ini = gb2004Ini;
211 return this;
212 }
213
214 public UT2004MatchConfig setBots(Map<IToken, UT2004BotConfig> bots) {
215 this.bots = bots;
216 return this;
217 }
218
219 public UT2004MatchConfig setNativeBots(Map<IToken, UT2004NativeBotConfig> nativeBots) {
220 this.nativeBots = nativeBots;
221 return this;
222 }
223
224 public UT2004MatchConfig clearBots() {
225 this.bots.clear();
226 return this;
227 }
228
229 public UT2004MatchConfig clearNativeBots() {
230 this.nativeBots.clear();
231 return this;
232 }
233
234 public UT2004MatchConfig clearHumans() {
235 this.humans.clear();
236 return this;
237 }
238
239
240
241
242
243
244 public UT2004MatchConfig addBot(UT2004BotConfig... bots) {
245 if (bots == null) return this;
246 for (UT2004BotConfig bot : bots) {
247 NullCheck.check(bot.getBotId(), "bot.getBotId()");
248 if (this.bots.containsKey(bot.getBotId())) {
249 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing custom bot configuration under this ID. If you need to override it, use setBot().", this);
250 }
251 if (this.nativeBots.containsKey(bot.getBotId())) {
252 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing native bot configuration under this ID. If you need to override it, use setBot().", this);
253 }
254 if (this.humans.containsKey(bot.getBotId())) {
255 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing human configuration under this ID. If you need to override it, use setBot().", this);
256 }
257 this.bots.put(bot.getBotId(), bot);
258 }
259 return this;
260 }
261
262
263
264
265
266
267
268 public UT2004MatchConfig setBot(UT2004BotConfig... bots) {
269 if (bots == null) return this;
270 for (UT2004BotConfig bot : bots) {
271 NullCheck.check(bot.getBotId(), "bot.getBotId()");
272 nativeBots.remove(bot.getBotId());
273 humans.remove(bot.getBotId());
274 this.bots.put(bot.getBotId(), bot);
275 }
276 return this;
277 }
278
279
280
281
282
283
284 public UT2004MatchConfig addNativeBot(UT2004NativeBotConfig... bots) {
285 if (bots == null) return this;
286 for (UT2004NativeBotConfig bot : bots) {
287 NullCheck.check(bot.getBotId(), "bot.getBotId()");
288 if (this.bots.containsKey(bot.getBotId())) {
289 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing custom bot configuration under this ID. If you need to override it, use setNativeBot().", this);
290 }
291 if (this.nativeBots.containsKey(bot.getBotId())) {
292 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing native bot configuration under this ID. If you need to override it, use setNativeBot().", this);
293 }
294 if (this.humans.containsKey(bot.getBotId())) {
295 throw new PogamutException("Can't add another bot under the id " + bot.getBotId().getToken() + ", there is already an existing human configuration under this ID. If you need to override it, use setNativeBot().", this);
296 }
297 this.nativeBots.put(bot.getBotId(), bot);
298 }
299 return this;
300 }
301
302
303
304
305
306
307 public UT2004MatchConfig setNativeBot(UT2004NativeBotConfig... bots) {
308 if (bots == null) return this;
309 for (UT2004NativeBotConfig bot : bots) {
310 NullCheck.check(bot.getBotId(), "bot.getBotId()");
311 this.bots.remove(bot.getBotId());
312 humans.remove(bot.getBotId());
313 this.nativeBots.put(bot.getBotId(), bot);
314 }
315 return this;
316 }
317
318
319
320
321
322
323 public UT2004MatchConfig addHuman(UT2004HumanConfig... humans) {
324 if (humans == null) return this;
325 for (UT2004HumanConfig human : humans) {
326 NullCheck.check(human.getHumanId(), "human.getHumanId()");
327 if (this.bots.containsKey(human.getHumanId())) {
328 throw new PogamutException("Can't add another bot under the id " + human.getHumanId().getToken() + ", there is already an existing custom bot configuration under this ID. If you need to override it, use setNativeBot().", this);
329 }
330 if (this.nativeBots.containsKey(human.getHumanId())) {
331 throw new PogamutException("Can't add another bot under the id " + human.getHumanId().getToken() + ", there is already an existing native bot configuration under this ID. If you need to override it, use setNativeBot().", this);
332 }
333 if (this.humans.containsKey(human.getHumanId())) {
334 throw new PogamutException("Can't add another bot under the id " + human.getHumanId().getToken() + ", there is already an existing human configuration under this ID. If you need to override it, use setNativeBot().", this);
335 }
336 this.humans.put(human.getHumanId(), human);
337 }
338 return this;
339 }
340
341
342
343
344
345
346
347 public UT2004MatchConfig setHuman(UT2004HumanConfig... humans) {
348 if (humans == null) return this;
349 for (UT2004HumanConfig human : humans) {
350 NullCheck.check(human.getHumanId(), "human.getHumanId()");
351 this.bots.remove(human.getHumanId());
352 this.nativeBots.remove(human.getHumanId());
353 this.humans.put(human.getHumanId(), human);
354 }
355 return this;
356 }
357
358 public boolean isBot(IToken botId) {
359 return bots.containsKey(botId);
360 }
361
362 public boolean isNativeBot(IToken botId) {
363 return nativeBots.containsKey(botId);
364 }
365
366 public boolean isHuman(IToken botId) {
367 return humans.containsKey(botId);
368 }
369
370 public BotType getBotType(IToken botId) {
371 if (isBot(botId)) return BotType.BOT;
372 if (isNativeBot(botId)) return BotType.NATIVE;
373 if (isHuman(botId)) return BotType.HUMAN;
374 return null;
375 }
376
377 public boolean isHumanLikeLogEnabled() {
378 return humanLikeLogEnabled;
379 }
380
381 public UT2004MatchConfig setHumanLikeLogEnabled(boolean humanLikeLog) {
382 this.humanLikeLogEnabled = humanLikeLog;
383 return this;
384 }
385
386
387
388
389
390 protected final StringBuffer validationBuffer = new StringBuffer();
391
392 protected boolean validationError = false;
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 protected void validateInner() {
408 if (matchId == null) {
409 validationError = true;
410 validationBuffer.append(Const.NEW_LINE);
411 validationBuffer.append("Match ID is NULL");
412 }
413 for (UT2004BotConfig config : bots.values()) {
414 if (config.getBotId() == null) {
415 validationError = true;
416 validationBuffer.append(Const.NEW_LINE);
417 validationBuffer.append("One of custom bots has NULL bot-id.");
418 }
419 if (config.getPathToBotJar() == null) {
420 validationError = true;
421 validationBuffer.append(Const.NEW_LINE);
422 validationBuffer.append(config.getBotId() == null ? "One of custom bots" : "Bot " + config.getBotId().getToken() + " has NULL path-to-jar.");
423 } else {
424 if (!config.isBotJarExist()) {
425 validationError = true;
426 validationBuffer.append(Const.NEW_LINE);
427 validationBuffer.append(config.getBotId() == null ? "One of custom bots" : "Bot " + config.getBotId().getToken() + " has path-to-jar pointing to non-existing file " + config.getJarFile().getAbsolutePath());
428 }
429 }
430 }
431 for (UT2004NativeBotConfig config : nativeBots.values()) {
432 if (config.getBotId() == null) {
433 validationError = true;
434 validationBuffer.append(Const.NEW_LINE);
435 validationBuffer.append("One of native bots has NULL bot-id.");
436 }
437 }
438 if (gb2004Ini == null) {
439 validationError = true;
440 validationBuffer.append(Const.NEW_LINE);
441 validationBuffer.append("GameBots2004Ini is NULL.");
442 }
443 if (uccConf == null) {
444 validationError = true;
445 validationBuffer.append(Const.NEW_LINE);
446 validationBuffer.append("UccWrapper is NULL.");
447 } else {
448 if (uccConf.getUnrealHome() == null) {
449 validationError = true;
450 validationBuffer.append(Const.NEW_LINE);
451 validationBuffer.append("UccWrapper does not have UnrealHome set, is NULL.");
452 } else {
453 File uccHome = new File(uccConf.getUnrealHome());
454 if (!uccHome.exists() || !uccHome.isDirectory()) {
455 validationError = true;
456 validationBuffer.append(Const.NEW_LINE);
457 validationBuffer.append("UccWrapper.UnrealHome does not point to directory, used path: " + uccHome.getAbsolutePath());
458 } else {
459 File uccHome2 = new File(uccConf.getUnrealHome() + File.separator + "System");
460 if (!uccHome2.exists() || !uccHome2.isDirectory()) {
461 validationError = true;
462 validationBuffer.append(Const.NEW_LINE);
463 validationBuffer.append("UccWrapper.UnrealHome" + File.separator + "System does not point to directory, used path: " + uccHome2.getAbsolutePath());
464 } else {
465 File gb = new File(uccConf.getUnrealHome() + File.separator + "System" + File.separator + "GameBots2004.u");
466 if (!gb.exists() || !gb.isFile()) {
467 validationError = true;
468 validationBuffer.append(Const.NEW_LINE);
469 validationBuffer.append("GameBots2004 was not installed into specified UT2004, the file GameBots2004.u was not found at: " + gb.getAbsolutePath());
470 }
471 }
472 }
473 }
474 }
475 if (bots.size() + nativeBots.size() + humans.size() < 2) {
476 validationError = true;
477 validationBuffer.append(Const.NEW_LINE);
478 validationBuffer.append("There are not enough bot specified for the match. Custom bots: " + bots.size() + ", native bots: " + nativeBots.size() + ", humans: " + humans.size() + ". There must be at least 2 bots/humans to perform the match!");
479 }
480 }
481
482
483
484
485
486
487
488 public final void validate() {
489 synchronized(validationBuffer) {
490 validationError = false;
491 if (validationBuffer.length() > 0) {
492 validationBuffer.delete(0, validationBuffer.length());
493 }
494 validateInner();
495 if (validationError) {
496 throw new PogamutException(this + " validation error!" + validationBuffer.toString(), this);
497 }
498 }
499 }
500
501 }