-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMain.java
173 lines (148 loc) · 8.1 KB
/
Main.java
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
// Please do not modify this file.
// Instead have a look at `README.md` for how to start writing you AI.
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import org.json.JSONObject;
import joueur.BaseAI;
import joueur.BaseGame;
import joueur.Client;
import joueur.ErrorCode;
import joueur.ANSIColorCoder;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;
class JoueurJava {
public static void main(String[] args) throws IOException {
ArgumentParser parser = ArgumentParsers.newArgumentParser("Joueur.Java")
.description("Runs the Java client with options. Must a provide a game name to play on the server.");
parser.addArgument("game").dest("game").required(true)
.help("the name of the game you want to play on the server");
parser.addArgument("-s", "--server").dest("server").setDefault("localhost")
.help("the hostname or the server you want to connect to e.g. locahost:3000");
parser.addArgument("-p", "--port").dest("port").type(Integer.class).setDefault(3000)
.help("the port to connect to on the server. Can be defined on the server arg via server:port");
parser.addArgument("-n", "--name").dest("playerName").help(
"the name you want to use as your AI\'s player name. This over-rides the name you set in your code");
parser.addArgument("-i", "--index").dest("index").type(Integer.class).setDefault(-1)
.help("the player number you want to be, with 0 being the first player");
parser.addArgument("-w", "--password").dest("password")
.help("the password required for authentication on official servers");
parser.addArgument("-r", "--session").dest("session").setDefault("*")
.help("the requested game session you want to play on the server");
parser.addArgument("--aiSettings").dest("aiSettings")
.help("Any settings for the AI. Delimit pairs by an ampersand (key=value&otherKey=otherValue)");
parser.addArgument("--gameSettings").dest("gameSettings").help(
"Any settings for the game server to force. Must be url parms formatted (key=value&otherKey=otherValue)");
parser.addArgument("--printIO").dest("printIO").action(Arguments.storeTrue())
.help("(debugging) print IO through the TCP socket to the terminal");
String gameAlias = "", server = "localhost", requestedSession = "*", playerName = "Java Player",
password = null, aiSettings = null, gameSettings = null;
int port = 3000, playerIndex = -1;
boolean printIO = false;
try {
Namespace parsedArgs = parser.parseArgs(args);
gameAlias = parsedArgs.getString("game");
server = parsedArgs.getString("server");
requestedSession = parsedArgs.getString("session");
playerName = parsedArgs.getString("playerName");
playerIndex = parsedArgs.getInt("index");
password = parsedArgs.getString("password");
port = parsedArgs.getInt("port");
printIO = parsedArgs.getBoolean("printIO");
aiSettings = parsedArgs.getString("aiSettings");
gameSettings = parsedArgs.getString("gameSettings");
} catch (ArgumentParserException e) {
ErrorCode.handleError(e, ErrorCode.INVALID_ARGS, "Invalid Args");
}
if (server.contains(":")) {
String[] split = server.split(":");
server = split[0];
port = Integer.parseInt(split[1]);
}
Client client = Client.getInstance();
client.connect(server, port, printIO);
client.send("alias", gameAlias);
String gameName = (String) client.waitForEvent("named");
BaseGame game = null;
String gameVersion = "";
try {
Class<?> gameClass = Class.forName("games." + client.lowercaseFirst(gameName) + ".Game");
Constructor<?> gameConstructor = gameClass.getDeclaredConstructors()[0];
gameConstructor.setAccessible(true);
game = (BaseGame) gameConstructor.newInstance(new Object[0]);
Field gameVersionField = gameClass.getField("gameVersion");
gameVersion = (String) gameVersionField.get(null);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SecurityException
| IllegalArgumentException | InvocationTargetException | NoSuchFieldException e) {
client.handleError(e, ErrorCode.GAME_NOT_FOUND,
"Could not create Game via reflection for game '" + gameName + "'");
}
BaseAI ai = null;
try {
Class<?> aiClass = Class.forName("games." + client.lowercaseFirst(gameName) + ".AI");
Constructor<?> aiConstructor = aiClass.getDeclaredConstructors()[0];
aiConstructor.setAccessible(true);
ai = (BaseAI) aiConstructor.newInstance(new Object[0]);
} catch (Exception e) {
client.handleError(e, ErrorCode.AI_ERRORED,
"Could not create AI via reflection for game '" + gameName + "'");
}
client.setup(game, ai);
ai.setSettings(aiSettings);
if (playerName == null || playerName.isEmpty()) {
playerName = ai.getName();
if (playerName == null || playerName.isEmpty()) {
playerName = "Java Player"; // to make sure they have a name
}
}
JSONObject playData = new JSONObject();
playData.put("gameName", gameName);
playData.put("password", password);
playData.put("playerName", playerName);
if (playerIndex > -1) {
playData.put("playerIndex", playerIndex);
}
playData.put("requestedSession", requestedSession);
playData.put("gameSettings", gameSettings);
playData.put("clientType", "Java");
client.send("play", playData);
JSONObject lobbiedData = (JSONObject) client.waitForEvent("lobbied");
String serverGameVersion = lobbiedData.getString("gameVersion");
if (!gameVersion.equals(serverGameVersion)) {
System.out.println(
ANSIColorCoder.FG_YELLOW.apply()
+ "WARNING: Game versions do not match."
+ "\n-> Your local game version is: " + serverGameVersion.substring(0, 8)
+ "\n-> Game Server's game version is: " + gameVersion.substring(0, 8)
+ "\n\nVersion mismatch means that unexpected crashes may happen due to differing game structures!"
+ ANSIColorCoder.reset()
);
}
gameName = lobbiedData.getString("gameName");
String gameSession = lobbiedData.getString("gameSession");
System.out.println(ANSIColorCoder.FG_CYAN.apply() + "In lobby for game '" + gameName + "' in session '"
+ gameSession + "'." + ANSIColorCoder.reset());
JSONObject constants = lobbiedData.getJSONObject("constants");
client.gameManager.setConstants(constants);
JSONObject startData = (JSONObject) client.waitForEvent("start");
// set the AI's game and player via reflection
try {
ai.getClass().getField("game").set(ai, game);
ai.getClass().getField("player").set(ai, game.gameObjects.get(startData.getString("playerID")));
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
client.handleError(e, ErrorCode.REFLECTION_FAILED, "Could not set reflected Game and Player for AI.");
}
client.start();
try {
ai.start();
ai.gameUpdated();
} catch (Exception e) {
client.handleError(e, ErrorCode.REFLECTION_FAILED, "AI threw exception during initial start");
}
client.play();
}
}