View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.tournament;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.text.SimpleDateFormat;
6   import java.util.Date;
7   import java.util.List;
8   import java.util.logging.Level;
9   import java.util.regex.Pattern;
10  
11  import org.apache.commons.io.FileUtils;
12  
13  import com.martiansoftware.jsap.FlaggedOption;
14  import com.martiansoftware.jsap.JSAP;
15  import com.martiansoftware.jsap.JSAPException;
16  import com.martiansoftware.jsap.JSAPResult;
17  import com.martiansoftware.jsap.Switch;
18  
19  import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
20  import cz.cuni.amis.pogamut.ut2004.tournament.deathmatch.UT2004DeathMatch1v1;
21  
22  public class UT2004DeathMatch1v1Console {
23  	
24  	private static final char ARG_UT2004_HOME_DIR_SHORT = 'u';
25  	
26  	private static final String ARG_UT2004_HOME_DIR_LONG = "ut2004-home-dir";
27  	
28  	private static final char ARG_BOT1_JAR_SHORT = 'a';
29  	
30  	private static final String ARG_BOT1_JAR_LONG = "bot1-jar";
31  	
32  	private static final char ARG_BOT1_NAME_SHORT = 'b';
33  	
34  	private static final String ARG_BOT1_NAME_LONG = "bot1-name";
35  	
36  	private static final char ARG_BOT2_JAR_SHORT = 'c';
37  	
38  	private static final String ARG_BOT2_JAR_LONG = "bot2-jar";
39  	
40  	private static final char ARG_BOT2_NAME_SHORT = 'd';
41  	
42  	private static final String ARG_BOT2_NAME_LONG = "bot2-name";
43  	
44  	private static final char ARG_MAP_NAME_SHORT = 'm';
45  	
46  	private static final String ARG_MAP_NAME_LONG = "map-name";
47  	
48  	private static final char ARG_MATCH_NAME_SHORT = 'n';
49  	
50  	private static final String ARG_MATCH_NAME_LONG = "match-name";
51  	
52  	private static final char ARG_RESULT_DIR_SHORT = 'r';
53  	
54  	private static final String ARG_RESULT_DIR_LONG = "result-directory";
55  	
56  	private static final char ARG_SERVER_NAME_SHORT = 's';
57  	
58  	private static final String ARG_SERVER_NAME_LONG = "server-name";
59  	
60  	private static final char ARG_FRAG_LIMIT_SHORT = 'f';
61  	
62  	private static final String ARG_FRAG_LIMIT_LONG = "frag-limit";
63  	
64  	private static final char ARG_TIMEOUT_MINUTES_SHORT = 't';
65  	
66  	private static final String ARG_TIMEOUT_MINUTES_LONG = "timeout-minutes";
67  	
68  	private static final char ARG_HUMAN_LIKE_LOG_SHORT = 'h';
69  	
70  	private static final String ARG_HUMAN_LIKE_LOG_LONG = "human-like-log";
71  	
72  	private static final char ARG_UT2004_PORT_SHORT = 'p';
73  	
74  	private static final String ARG_UT2004_PORT_LONG = "ut2004-port";
75  
76  	private static JSAP jsap;
77  
78  	private static boolean headerOutput = false;
79  
80  	private static String ut2004HomeDir;
81  
82  	private static String bot1Jar;
83  
84  	private static String bot1Name;
85  
86  	private static String bot2Jar;
87  
88  	private static String bot2Name;
89  
90  	private static String map;
91  
92  	private static String serverName;
93  
94  	private static String resultDir;
95  
96  	private static String matchName;
97  	
98  	private static int fragLimit;
99  	
100 	private static int timeoutMinutes;
101 
102 	private static JSAPResult config;
103 
104 	private static File ut2004HomeDirFile;
105 
106 	private static File bot1JarFile;
107 
108 	private static File bot2JarFile;
109 
110 	private static File mapsDirFile;
111 
112 	private static File mapFile;
113 
114 	private static File ut2004SystemDirFile;
115 
116 	private static File ut2004IniFile;
117 
118 	private static boolean humanLikeLog;
119 
120 	private static int ut2004Port;	
121 	
122 	private static void fail(String errorMessage) {
123 		fail(errorMessage, null);
124 	}
125 
126 	private static void fail(String errorMessage, Throwable e) {
127 		header();
128 		System.out.println("ERROR: " + errorMessage);
129 		System.out.println();
130 		if (e != null) {
131 			e.printStackTrace();
132 			System.out.println("");
133 		}		
134         System.out.println("Usage: java -jar ut2004-tournament-1v1....jar ");
135         System.out.println("                " + jsap.getUsage());
136         System.out.println();
137         System.out.println(jsap.getHelp());
138         System.out.println();
139         throw new RuntimeException("FAILURE: " + errorMessage);
140 	}
141 
142 	private static void header() {
143 		if (headerOutput) return;
144 		System.out.println();
145 		System.out.println("=================================");
146 		System.out.println("Pogamut UT2004 1v1 Match Executor");
147 		System.out.println("=================================");
148 		System.out.println();
149 		headerOutput = true;
150 	}
151 	
152 	private static void initJSAP() throws JSAPException {
153 		jsap = new JSAP();
154 		    	
155     	FlaggedOption opt1 = new FlaggedOption(ARG_UT2004_HOME_DIR_LONG)
156         	.setStringParser(JSAP.STRING_PARSER)
157         	.setRequired(true) 
158         	.setShortFlag(ARG_UT2004_HOME_DIR_SHORT)
159         	.setLongFlag(ARG_UT2004_HOME_DIR_LONG);    
160         opt1.setHelp("UT2004 home directory containing GameBots2004 (System/GameBots2004.u) present.");
161         
162         jsap.registerParameter(opt1);
163         
164         FlaggedOption opt2 = new FlaggedOption(ARG_BOT1_JAR_LONG)
165 	    	.setStringParser(JSAP.STRING_PARSER)
166 	    	.setRequired(true) 
167 	    	.setShortFlag(ARG_BOT1_JAR_SHORT)
168 	    	.setLongFlag(ARG_BOT1_JAR_LONG);    
169         opt2.setHelp("PATH/TO/JAR/file containing the 1st bot.");
170     
171         jsap.registerParameter(opt2);
172         
173         FlaggedOption opt3 = new FlaggedOption(ARG_BOT1_NAME_LONG)
174 	    	.setStringParser(JSAP.STRING_PARSER)
175 	    	.setRequired(true) 
176 	    	.setShortFlag(ARG_BOT1_NAME_SHORT)
177 	    	.setLongFlag(ARG_BOT1_NAME_LONG);    
178 	    opt3.setHelp("Name that should be given to the 1st bot.");
179 
180 	    jsap.registerParameter(opt3);
181     
182 	    FlaggedOption opt4 = new FlaggedOption(ARG_BOT2_JAR_LONG)
183 	    	.setStringParser(JSAP.STRING_PARSER)
184 	    	.setRequired(true) 
185 	    	.setShortFlag(ARG_BOT2_JAR_SHORT)
186 	    	.setLongFlag(ARG_BOT2_JAR_LONG);    
187 	    opt4.setHelp("PATH/TO/JAR/file containing the 2nd bot.");
188 	
189 	    jsap.registerParameter(opt4);
190 	    
191 	    FlaggedOption opt5 = new FlaggedOption(ARG_BOT2_NAME_LONG)
192 	    	.setStringParser(JSAP.STRING_PARSER)
193 	    	.setRequired(true) 
194 	    	.setShortFlag(ARG_BOT2_NAME_SHORT)
195 	    	.setLongFlag(ARG_BOT2_NAME_LONG);    
196 	    opt5.setHelp("Name that should be given to the 2nd bot.");
197 	
198 	    jsap.registerParameter(opt5);
199     
200 	    FlaggedOption opt6 = new FlaggedOption(ARG_MAP_NAME_LONG)
201 	    	.setStringParser(JSAP.STRING_PARSER)
202 	    	.setRequired(true) 
203 	    	.setShortFlag(ARG_MAP_NAME_SHORT)
204 	    	.setLongFlag(ARG_MAP_NAME_LONG);    
205 	    opt6.setHelp("Map where the game should be played (e.g. DM-1on1-Albatross).");
206 	
207 	    jsap.registerParameter(opt6);
208         
209 	    FlaggedOption opt7 = new FlaggedOption(ARG_MATCH_NAME_LONG)
210 	    	.setStringParser(JSAP.STRING_PARSER)
211 	    	.setRequired(false) 
212 	    	.setShortFlag(ARG_MATCH_NAME_SHORT)
213 	    	.setLongFlag(ARG_MATCH_NAME_LONG)
214 	    	.setDefault("DMMatch1v1");    
215 	    opt7.setHelp("Name of the match == output folder for the results.");
216 	
217 	    jsap.registerParameter(opt7);
218 	    
219 	    FlaggedOption opt8 = new FlaggedOption(ARG_RESULT_DIR_LONG)
220 	    	.setStringParser(JSAP.STRING_PARSER)
221 	    	.setRequired(false) 
222 	    	.setShortFlag(ARG_RESULT_DIR_SHORT)
223 	    	.setLongFlag(ARG_RESULT_DIR_LONG)
224 	    	.setDefault(".");
225 	    opt8.setHelp("PATH/TO/directory where to output results (does not need to exist).");
226 	
227 	    jsap.registerParameter(opt8);
228 	    
229 	    FlaggedOption opt9 = new FlaggedOption(ARG_SERVER_NAME_LONG)
230 			.setStringParser(JSAP.STRING_PARSER)
231 			.setRequired(false) 
232 			.setShortFlag(ARG_SERVER_NAME_SHORT)
233 			.setLongFlag(ARG_SERVER_NAME_LONG)
234 			.setDefault("DMMatch1v1");
235 		opt9.setHelp("Server name that should be advertised via LAN.");
236 		
237 		jsap.registerParameter(opt9);
238 		
239 		FlaggedOption opt10 = new FlaggedOption(ARG_FRAG_LIMIT_LONG)
240 			.setStringParser(JSAP.INTEGER_PARSER)
241 			.setRequired(false) 
242 			.setShortFlag(ARG_FRAG_LIMIT_SHORT)
243 			.setLongFlag(ARG_FRAG_LIMIT_LONG)
244 			.setDefault("20");
245 		opt10.setHelp("Frag limit for the match.");
246 		
247 		jsap.registerParameter(opt10);
248 		
249 		FlaggedOption opt11 = new FlaggedOption(ARG_TIMEOUT_MINUTES_LONG)
250 			.setStringParser(JSAP.INTEGER_PARSER)
251 			.setRequired(false) 
252 			.setShortFlag(ARG_TIMEOUT_MINUTES_SHORT)
253 			.setLongFlag(ARG_TIMEOUT_MINUTES_LONG)
254 			.setDefault("20");
255 		opt11.setHelp("Match timeout in minutes.");
256 		
257 		jsap.registerParameter(opt11);
258 		
259 		Switch opt12 = new Switch(ARG_HUMAN_LIKE_LOG_LONG)
260 			.setShortFlag(ARG_HUMAN_LIKE_LOG_SHORT)
261 			.setLongFlag(ARG_HUMAN_LIKE_LOG_LONG)
262 			.setDefault("false");
263 		opt12.setHelp("Whether to produce log for 'HumanLike Project' analysis.");
264 		
265 		jsap.registerParameter(opt12);
266 		
267 		FlaggedOption opt13 = new FlaggedOption(ARG_UT2004_PORT_LONG)
268 			.setStringParser(JSAP.INTEGER_PARSER)
269 			.setRequired(false) 
270 			.setShortFlag(ARG_UT2004_PORT_SHORT)
271 			.setLongFlag(ARG_UT2004_PORT_LONG)
272 			.setDefault("7777");
273 		opt13.setHelp("UT2004 port for the dedicated server (1-32000).");
274 		
275 		jsap.registerParameter(opt13);
276 	}
277 
278 	private static void readConfig(String[] args) {
279 		System.out.println("Parsing command arguments.");
280 		
281 		try {
282 	    	config = jsap.parse(args);
283 	    } catch (Exception e) {
284 	    	fail(e.getMessage());
285 	    	System.out.println("");
286 	    	e.printStackTrace();
287 	    	throw new RuntimeException("FAILURE!");
288 	    }
289 		
290 		if (!config.success()) {
291     		fail("Invalid arguments specified.");	    		
292     	}
293 		
294 		ut2004HomeDir = config.getString(ARG_UT2004_HOME_DIR_LONG);
295 	    bot1Jar = config.getString(ARG_BOT1_JAR_LONG);
296 	    bot1Name = config.getString(ARG_BOT1_NAME_LONG);
297 	    bot2Jar = config.getString(ARG_BOT2_JAR_LONG);
298 	    bot2Name = config.getString(ARG_BOT2_NAME_LONG);
299 	    map = config.getString(ARG_MAP_NAME_LONG);
300 	    serverName = config.getString(ARG_SERVER_NAME_LONG);
301 	    resultDir = config.getString(ARG_RESULT_DIR_LONG);
302 	    matchName = config.getString(ARG_MATCH_NAME_LONG);
303 	    fragLimit = config.getInt(ARG_FRAG_LIMIT_LONG);
304 	    timeoutMinutes = config.getInt(ARG_TIMEOUT_MINUTES_LONG);
305 	    humanLikeLog = config.getBoolean(ARG_HUMAN_LIKE_LOG_LONG);
306 	    ut2004Port = config.getInt(ARG_UT2004_PORT_LONG);
307 	}
308 	
309 	private static void sanityChecks() {
310 		System.out.println("Sanity checks...");
311 		
312 	    ut2004HomeDirFile = new File(ut2004HomeDir);
313 	    if (!ut2004HomeDirFile.exists() || !ut2004HomeDirFile.isDirectory()) {
314 	    	fail("UT2004 directory was not found at '" + ut2004HomeDirFile.getAbsolutePath() + "', path resolved from configuration read as '" + ut2004HomeDir + "'.");
315 	    }
316 	    System.out.println("-- UT2004 directory found at '" + ut2004HomeDirFile.getAbsolutePath() + "'");
317 	    
318 	    ut2004SystemDirFile = new File(ut2004HomeDirFile, "System");
319 	    if (!ut2004SystemDirFile.exists() || !ut2004SystemDirFile.isDirectory()) {
320 	    	fail("UT2004/System directory was not found at '" + ut2004SystemDirFile.getAbsolutePath() + "', invalid UT2004 installation.");
321 	    }
322 	    System.out.println("-- UT2004/System directory found at '" + ut2004SystemDirFile.getAbsolutePath() + "'");
323 	    
324 	    ut2004IniFile = new File(ut2004SystemDirFile, "UT2004.ini");
325 	    if (!ut2004IniFile.exists() || !ut2004IniFile.isFile()) {
326 	    	fail("UT2004/System/UT2004.ini file was not found at '" + ut2004IniFile.getAbsolutePath() + "', invalid UT2004 installation.");
327 	    }
328 	    System.out.println("-- UT2004/System/UT2004.ini file found at '" + ut2004SystemDirFile.getAbsolutePath() + "'");
329 	    
330 	    bot1JarFile = new File(bot1Jar);
331 	    if (!bot1JarFile.exists() || !bot1JarFile.isFile()) {
332 	    	fail("Bot1 jar file was not found at '"+ bot1JarFile.getAbsolutePath() + "', path resolved from configuration read as '" + bot1Jar + "'.");
333 	    }
334 	    System.out.println("-- Bot1 jar file found at '" + bot1JarFile.getAbsolutePath() + "'");
335 	    
336 	    bot2JarFile = new File(bot2Jar);
337 	    if (!bot2JarFile.exists() || !bot2JarFile.isFile()) {
338 	    	fail("Bot2 jar file was not found at '"+ bot2JarFile.getAbsolutePath() + "', path resolved from configuration read as '" + bot2Jar + "'.");
339 	    }
340 	    System.out.println("-- Bot2 jar file found at '" + bot2JarFile.getAbsolutePath() + "'");
341 	    
342 	    if (bot1Name == null || bot1Name.isEmpty()) {
343 	    	fail("Bot1 invalid name '" + bot1Name +"' specified.");
344 	    }
345 	    System.out.println("-- Bot1 name set as '" + bot1Name + "'");
346 	    
347 	    if (bot2Name == null || bot2Name.isEmpty()) {
348 	    	fail("Bot2 invalid name '" + bot1Name +"' specified.");
349 	    }
350 	    System.out.println("-- Bot2 name set as '" + bot2Name + "'");
351 	    
352 	    if (bot1Name.equalsIgnoreCase(bot2Name)) {
353 	    	fail("Bot1 has the name '" + bot1Name + "', which is the same (case-insensitive) as Bot2 name '" + bot2Name + "'.");
354 	    }
355 	    System.out.println("-- Bot1+2 names ok");	    
356 	    
357 	    mapsDirFile = new File(ut2004HomeDirFile, "Maps");
358 	    if (!mapsDirFile.exists() || !mapsDirFile.isDirectory()) {
359 	    	fail("UT2004/Maps directory was not found at '" + mapsDirFile.getAbsolutePath() + "', invalid UT2004 installation.");
360 	    }
361 	    System.out.println("-- UT2004/Maps directory found at '" + mapsDirFile.getAbsolutePath() + "'");
362 	    
363 	    mapFile = new File(mapsDirFile, map + ".ut2");
364 	    if (!mapFile.exists() || !mapFile.isFile()) {
365 	    	fail("Specified map '" + map + "' was not found within UT2004/Maps dir at '" + mapFile.getAbsoluteFile() + "', could not execute the match.");
366 	    }
367 	    System.out.println("-- Map '" + map + "' found at '" + mapFile.getAbsolutePath() + "'");
368 	    
369 	    if (matchName == null || matchName.isEmpty()) {
370 	    	fail("Invalid match name '" + matchName + "' specified.");
371 	    }
372 	    System.out.println("-- Match name set as '" + matchName + "'");
373 	    
374 	    if (serverName == null || serverName.isEmpty()) {
375 	    	fail("Invalid server name '" + serverName + "' specified.");
376 	    }
377 	    System.out.println("-- Server name set as '" + serverName + "'");
378 	    
379 	    if (fragLimit < 1) {
380 	    	fail("Invalid frag limit '" + fragLimit +"' specified, must be >= 1.");
381 	    }
382 	    System.out.println("-- Frag limit set as '" + fragLimit + "'");
383 	    
384 	    if (timeoutMinutes < 1) {
385 	    	fail("Invalid time limit '" + timeoutMinutes +"' specified, must be >= 1.");
386 	    }
387 	    System.out.println("-- Timeout set as '" + timeoutMinutes + "' minutes.");
388 	    
389 	    if (ut2004Port < 1 || ut2004Port > 32000) {
390 	    	fail("Invalid UT2004 port specified '" + ut2004Port + "', must be 1 <= port <= 32000.");
391 	    }
392 	    System.out.println("-- UT2004 port set as '" + ut2004Port + "'");
393 
394 	    System.out.println("Sanity checks OK!");
395 	}
396 	
397 	private static void setUT2004Ini() {
398 		Date date = new Date(System.currentTimeMillis());
399 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
400 		File ut2004IniBackup = new File(ut2004SystemDirFile, "UT2004.ini." + sdf.format(date) + ".bak");
401 		
402 		System.out.println("Backing up '" + ut2004IniFile.getAbsolutePath() + "' into '" + ut2004IniBackup.getAbsolutePath() + "' ...");
403 		try {
404 			FileUtils.copyFile(ut2004IniFile, ut2004IniBackup);
405 		} catch (IOException e) {
406 			throw new RuntimeException("Failed to backup UT2004.ini", e);
407 		}
408 				
409 		System.out.println("Reading '" + ut2004IniFile.getAbsolutePath() + "' ...");
410 		List<String> lines;
411 		try {
412 			lines = FileUtils.readLines(ut2004IniFile);
413 		} catch (IOException e) {
414 			throw new RuntimeException("Failed to read UT2004.ini", e);
415 		}
416 		System.out.println(lines.size() + " lines read.");
417 		
418 		System.out.println("Searching for UT2004 Port and ServerName ...");
419 		
420 		// 0 -> nothing
421 		// 1 -> section URL
422 		// 2 -> section Engine.GameReplicationInfo
423 		int state = 0;
424 		
425 		Pattern patternSection = Pattern.compile("^\\s*\\[\\s*[^]]*\\s*\\]\\s*$");
426 		Pattern patternSectionURL = Pattern.compile("^\\s*\\[\\s*" + UT2004Ini.Section_URL + "\\s*\\]\\s*$");
427 		Pattern patternSectionEngineGameReplicationInfo = Pattern.compile("^\\s*\\[\\s*" + UT2004Ini.Section_Engine_GameReplicationInfo + "\\s*\\]\\s*$");
428 		Pattern patternPort = Pattern.compile("^\\s*" + UT2004Ini.Key_Port + "\\s*=\\s*.*$");
429 		Pattern patternServerName = Pattern.compile("^\\s*" + UT2004Ini.Key_ServerName + "\\s*=\\s*.*$");
430 		Pattern patternShortName = Pattern.compile("^\\s*" + UT2004Ini.Key_ShortName + "\\s*=\\s*.*$");
431 		
432 		boolean portFound = false;
433 		boolean nameFound = false;
434 		boolean shortNameFound = false;
435 		
436 		for (int lineNum = 0; 
437 				// IF lineNum == lines.size() 
438 				// => perform one more state switch to add possibly missing keys
439 			 lineNum <= lines.size()
440 			    // IF all set
441 				// => break;
442 			 && (!(portFound && nameFound && shortNameFound)); 
443 			++lineNum
444 		) {		
445 						
446 			
447 			// current line probed
448 			String line = lineNum < lines.size() ? lines.get(lineNum).trim() : null;
449 			
450 			// sanity check
451 			if (lineNum < lines.size() && line == null) {
452 				continue;
453 			}
454 			
455 			if (lineNum == lines.size() || patternSection.matcher(line).matches()) {
456 				switch (state) {
457 				case 0:
458 					break;
459 				case 1:
460 					if (!portFound) {
461 						lines.add(lineNum, UT2004Ini.Key_Port + "=" + ut2004Port);
462 						portFound = true;
463 						++lineNum;
464 					}
465 					break;
466 				case 2:
467 					if (!nameFound) {
468 						lines.add(lineNum, UT2004Ini.Key_ServerName + "=" + serverName);
469 						nameFound = true;
470 						++lineNum;
471 					}
472 					if (!shortNameFound) {
473 						lines.add(lineNum, UT2004Ini.Key_ShortName + "=" + serverName);
474 						shortNameFound = true;
475 						++lineNum;
476 					}
477 					break;
478 				}
479 				if (lineNum == lines.size()) {
480 					break;
481 				}
482 				if (line == null) {
483 					continue;
484 				}
485 				if (patternSectionURL.matcher(line).matches()) {
486 					state = 1;					
487 				} else
488 				if (patternSectionEngineGameReplicationInfo.matcher(line).matches()) {
489 					state = 2;
490 				} else {
491 					state = 0;
492 				}
493 				continue;
494 			}
495 			
496 			switch (state) {
497 			case 0: 
498 				continue;
499 			case 1: 
500 				if (!portFound && patternPort.matcher(line).matches()) {
501 					lines.set(lineNum, UT2004Ini.Key_Port + "=" + ut2004Port);
502 					portFound = true;
503 				}
504 				continue;
505 			case 2:
506 				if (!nameFound && patternServerName.matcher(line).matches()) {
507 					lines.set(lineNum, UT2004Ini.Key_ServerName + "=" + serverName);
508 					nameFound = true;
509 				} else
510 				if (!shortNameFound && patternShortName.matcher(line).matches()) {
511 					lines.set(lineNum, UT2004Ini.Key_ShortName + "=" + serverName);
512 					shortNameFound = true;
513 				}
514 				continue;
515 			default:
516 				continue;
517 			}
518 		}
519 		
520 		if (!portFound) {
521 			throw new RuntimeException("Failed to set UT2004 port!");
522 		}
523 		if (!nameFound) {
524 			throw new RuntimeException("Failed to set UT2004 ServerName!");
525 		}
526 		
527 		System.out.println("UT2004 Port and ServerName set.");
528 		System.out.println("Rewriting '" + ut2004IniFile.getAbsolutePath() + "' ...");
529 		try {
530 			FileUtils.writeLines(ut2004IniFile, lines);
531 		} catch (IOException e) {
532 			throw new RuntimeException("Failed to write UT2004.ini", e);
533 		}		
534 		
535 		System.out.println("UT2004 Port and ServerName set.");
536 	}
537 	
538 	private static void executeMatch() {		
539 		UT2004DeathMatch1v1 match = new UT2004DeathMatch1v1(ut2004HomeDir, map, bot1Name, bot1Jar, bot2Name, bot2Jar);
540 	    match.setOutputDir(resultDir);
541 	    match.setMatchName(matchName);
542 	    match.setFragLimit(fragLimit);
543 	    match.setTimeLimitInMinutes(timeoutMinutes);
544 	    match.setHumanLikeLogEnabled(humanLikeLog);
545 	    
546 	    match.getLog().setLevel(Level.WARNING);
547 	    match.getLog().addConsoleHandler();
548 	    
549 	    System.out.println("EXECUTING MATCH!");
550 	    
551 	    match.run();
552 	}
553 	
554 	public static void main(String[] args) throws JSAPException {
555 //      FOR TESTING		
556 //		args = new String[] {
557 //			"-u",
558 //			"D:\\Games\\UT2004-Devel",
559 //			"-a",
560 //			"D:\\Workspaces\\Pogamut-Trunk\\Main\\PogamutUT2004Examples\\04-HunterBot\\target\\ut2004-04-hunter-bot-3.3.1-SNAPSHOT.one-jar.jar",
561 //			"-b",
562 //			"HunterBot1",
563 //			"-c",
564 //			"D:\\Workspaces\\Pogamut-Trunk\\Main\\PogamutUT2004Examples\\04-HunterBot\\target\\ut2004-04-hunter-bot-3.3.1-SNAPSHOT.one-jar.jar",
565 //			"-d",
566 //			"HunterBot2",
567 //			"-m",
568 //			"DM-TrainingDay",
569 //			"-r",
570 //			"./results",
571 //          "-n",
572 //          "MatchName",
573 //			"-s",
574 //			"HunterServer",
575 //			"-f",
576 //			"5",
577 //			"-t",
578 //			"5",
579 //			"-h",			
580 //		};
581 		
582 		initJSAP();
583 	    
584 	    header();
585 	    
586 	    readConfig(args);
587 	    
588 	    sanityChecks();
589 	    
590 	    setUT2004Ini();
591 	    
592 	    executeMatch();
593 	}
594 	
595 }