package org.ggp.base.apps.utilities; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.ggp.base.server.GameServer; import org.ggp.base.util.game.Game; import org.ggp.base.util.game.GameRepository; import org.ggp.base.util.gdl.factory.exceptions.GdlFormatException; import org.ggp.base.util.match.Match; import org.ggp.base.util.statemachine.Role; import org.ggp.base.util.statemachine.exceptions.GoalDefinitionException; import org.ggp.base.util.symbol.factory.exceptions.SymbolFormatException; /** * GameServerRunner is a utility program that lets you start up a match * directly from the command line. It takes the following arguments: * * args[0] = tournament name, for storing results * args[1] = game key, for loading the game * args[2] = start clock, in seconds * args[3] = play clock, in seconds * args[4,5,6] = host, port, name for player 1 * args[7,8,9] = host, port, name for player 2 * etc... * * @author Evan Cox * @author Sam Schreiber */ public final class GameServerRunner { private GameServerRunner() { } public static void main(String[] args) throws IOException, SymbolFormatException, GdlFormatException, InterruptedException, GoalDefinitionException { // Extract the desired configuration from the command line. String tourneyName = args[0]; String gameKey = args[1]; Game game = GameRepository.getDefaultRepository().getGame(gameKey); int startClock = Integer.valueOf(args[2]); int playClock = Integer.valueOf(args[3]); if ((args.length - 4) % 3 != 0) { throw new RuntimeException("Invalid number of player arguments of the form host/port/name."); } List<String> hostNames = new ArrayList<String>(); List<String> playerNames = new ArrayList<String>(); List<Integer> portNumbers = new ArrayList<Integer>(); String matchName = tourneyName + "." + gameKey + "." + System.currentTimeMillis(); for (int i = 4; i < args.length; i += 3) { String hostname = args[i]; Integer port = Integer.valueOf(args[i + 1]); String name = args[i + 2]; hostNames.add(hostname); portNumbers.add(port); playerNames.add(name); } int expectedRoles = Role.computeRoles(game.getRules()).size(); if (hostNames.size() != expectedRoles) { throw new RuntimeException("Invalid number of players for game " + gameKey + ": " + hostNames.size() + " vs " + expectedRoles); } Match match = new Match(matchName, -1, startClock, playClock, game, ""); match.setPlayerNamesFromHost(playerNames); // Actually run the match, using the desired configuration. GameServer server = new GameServer(match, hostNames, portNumbers); server.start(); server.join(); // Open up the directory for this tournament. // Create a "scores" file if none exists. File f = new File(tourneyName); if (!f.exists()) { f.mkdir(); f = new File(tourneyName + "/scores"); f.createNewFile(); } // Open up the XML file for this match, and save the match there. f = new File(tourneyName + "/" + matchName + ".xml"); if (f.exists()) f.delete(); BufferedWriter bw = new BufferedWriter(new FileWriter(f)); bw.write(match.toXML()); bw.flush(); bw.close(); // Open up the JSON file for this match, and save the match there. f = new File(tourneyName + "/" + matchName + ".json"); if (f.exists()) f.delete(); bw = new BufferedWriter(new FileWriter(f)); bw.write(match.toJSON()); bw.flush(); bw.close(); // Save the goals in the "/scores" file for the tournament. bw = new BufferedWriter(new FileWriter(tourneyName + "/scores", true)); List<Integer> goals = server.getGoals(); String goalStr = ""; String playerStr = ""; for (int i = 0; i < goals.size(); i++) { Integer goal = server.getGoals().get(i); goalStr += Integer.toString(goal); playerStr += playerNames.get(i); if (i != goals.size() - 1) { playerStr += ","; goalStr += ","; } } bw.write(playerStr + "=" + goalStr); bw.flush(); bw.close(); } }