-
Notifications
You must be signed in to change notification settings - Fork 7
/
Main.cs
161 lines (138 loc) · 7.35 KB
/
Main.cs
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
// Please do not modify this file.
// Instead have a look at `README.md` for how to start writing you AI.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using Newtonsoft.Json;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
namespace Joueur.cs
{
internal class Program
{
private static void Main(string[] args)
{
ArgParser argParser = new ArgParser(args, "Runs the C# client with options. Must a provide a game name to play on the server.", new[] {
new ArgParser.Argument(new[] {"game"}, "game", "the name of the game you want to play on the server", true),
new ArgParser.Argument(new[] {"-s", "--server"}, "server", "the url to the server you want to connect to e.g. locahost:3000", false, "127.0.0.1"),
new ArgParser.Argument(new[] {"-p", "--port"}, "port", "the port to connect to on the server. Can be defined on the server arg via server:port", false, 3000),
new ArgParser.Argument(new[] {"-n", "--name"}, "name", "the name you want to use as your AI\'s player name. This over-rides the name you set in your code"),
new ArgParser.Argument(new[] {"-i", "--index"}, "index", "the player number you want to be, with 0 being the first player", false, -1),
new ArgParser.Argument(new[] {"-r", "--session"}, "requestedSession", "the requested game session you want to play on the server", false, "*"),
new ArgParser.Argument(new[] {"-w", "--password"}, "password", "the password required for authentication on official servers"),
new ArgParser.Argument(new[] {"--gameSettings"}, "gameSettings", "Any settings for the game server to force. Must be url parms formatted (key=value&otherKey=otherValue)"),
new ArgParser.Argument(new[] {"--aiSettings"}, "aiSettings", "Any settings for the AI. Delimit pairs by an ampersand (key=value&otherKey=otherValue)"),
new ArgParser.Argument(new[] {"--printIO"}, "printIO", "(debugging) print IO through the TCP socket to the terminal", false, null, ArgParser.Argument.Store.True),
}, (int)ErrorHandler.ErrorCode.INVALID_ARGS);
string gameAlias = argParser.GetValue<string>("game");
string server = argParser.GetValue<string>("server");
string playerName = argParser.GetValue<string>("name");
int playerIndex = argParser.GetValue<int>("index");
string requestedSession = argParser.GetValue<string>("requestedSession");
string password = argParser.GetValue<string>("password");
string aiSettings = argParser.GetValue<string>("aiSettings");
string gameSettings = argParser.GetValue<string>("gameSettings");
int port = argParser.GetValue<int>("port");
bool printIO = argParser.GetValue<bool>("printIO");
if (server.Contains(":"))
{
var split = server.Split(':');
server = split[0];
port = Int32.Parse(split[1]);
}
Client client = Client.Instance;
client.Connect(server, port, printIO);
client.Send("alias", gameAlias);
string gameName = client.WaitForEvent("named").ToString();
BaseGame game;
string gameVersion;
try
{
Type gameType = Type.GetType("Joueur.cs.Games." + gameName + ".Game");
game = (BaseGame)Activator.CreateInstance(gameType, true);
gameVersion = gameType.GetField("GameVersion", BindingFlags.NonPublic | BindingFlags.Static).GetValue(game).ToString();
}
catch (Exception exception)
{
ErrorHandler.HandleError(ErrorHandler.ErrorCode.GAME_NOT_FOUND, exception, "Could not create Game for game name '" + gameName + "'");
return;
}
BaseAI ai;
try
{
Type aiType = Type.GetType("Joueur.cs.Games." + gameName + ".AI");
ai = (BaseAI)Activator.CreateInstance(aiType, true);
}
catch (Exception exception)
{
ErrorHandler.HandleError(ErrorHandler.ErrorCode.AI_ERRORED, exception, "Could create AI for game name '" + gameName + "'");
return;
}
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Connecting to: " + server + ":" + port);
Console.ResetColor();
client.Setup(game, ai);
typeof(BaseAI).GetMethod("SetSettings", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(ai, new object[] { aiSettings });
if (string.IsNullOrWhiteSpace(playerName))
{
playerName = ai.GetName();
}
client.Send("play", new ServerMessages.SendPlay
{
playerName = playerName,
playerIndex = playerIndex,
gameName = gameName,
password = password,
gameSettings = gameSettings,
requestedSession = requestedSession
}
);
var lobbiedData = (ServerMessages.LobbiedData)client.WaitForEvent("lobbied");
if (gameVersion != lobbiedData.gameVersion) {
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(
String.Format(@"WARNING: Game versions do not match.
-> Your local game version is: {0}
-> Game Server's game version is: {1}
Version mismatch means that unexpected crashes may happen due to differing game structures!",
lobbiedData.gameVersion.Substring(0, 8),
gameVersion.Substring(0, 8))
);
Console.ResetColor();
}
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("In lobby for game '" + lobbiedData.gameName + "' in session '" + lobbiedData.gameSession + "'.");
Console.ResetColor();
// hackish way to set the client in the game. we don't want to expose public methods that competitors may see via intellisense and try to use
client.GameManager.SetConstants(lobbiedData.constants);
var startData = (ServerMessages.StartData)client.WaitForEvent("start");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Game is starting.");
Console.ResetColor();
// set the AI's game and player via reflection
try
{
ai.GetType().GetField("Game").SetValue(ai, game);
ai.GetType().GetField("Player").SetValue(ai, game.GameObjects[startData.playerID]);
}
catch (Exception exception)
{
ErrorHandler.HandleError(ErrorHandler.ErrorCode.REFLECTION_FAILED, exception, "Could not set the Game and Player for the AI during game startup.");
}
try
{
ai.Start();
ai.GameUpdated();
}
catch (Exception exception)
{
ErrorHandler.HandleError(ErrorHandler.ErrorCode.AI_ERRORED, exception, "AI errored during initial game start.");
}
client.Play();
}
}
}