/// <summary> /// Default constructor. /// </summary> /// <param name="args">Arguments for the simulation.</param> public HeadlessServer(SimulationArguments args) : base(args) { _GameParams = args.Parameters; // Add new event on player connection PlayerConnected += (p, s, chs) => CheckStart(); }
/// <summary> /// Default constructor. /// </summary> public GameServer(SimulationArguments args) { Executor = new GameExecutor(); Executor.GameStartedEvent += Executor_GameStartedEvent; Executor.MoveStartedEvent += Executor_MoveStartedEvent; Executor.TilePlacedEvent += Executor_TilePlacedEvent; Executor.FollowerPlacedEvent += Executor_FollowerPlacedEvent; Executor.FollowerRemovedEvent += Executor_FollowerRemovedEvent; Executor.MovePassedEvent += Executor_MovePassedEvent; Executor.GameEndedEvent += Executor_GameEndedEvent; Socket = new ServerSocket(); Socket.ClientConnected += Socket_ClientConnected; Socket.ClientDisconnected += Socket_ClientDisconnected; Socket.MessageReceived += Socket_MessageReceived; PlayersInGame = new Dictionary <PlayerColor, ClientHandlerSocket>(); PlayersNames = new Dictionary <PlayerColor, string>(); MessageHandlerThread = new Thread(new ThreadStart(MessageHandlingLoop)); HasMessageResetEvent = new ManualResetEventSlim(); CurrentState = ServerState.BEFORE_LOBBY; // Make the settings based on the arguments _Port = args.Port; _PlayerLimit = args.PlayerCount; _EnabledColors = new List <PlayerColor>(args.EnabledColors); // Save file must be set first, because game loader will repeat the game events if (args.SaveGame) { SetSaveFile(args.SaveFileName); } if (args.LoadGame) { _LoadedResponses = LoadGame(args, args.LoadFileName); args.Parameters = Executor.CurrentGameState.Params.Copy(); _Loaded = true; } }
/// <summary> /// Default constructor. /// </summary> /// <param name="server">Game server controled by the form.</param> /// <param name="arguments">Default simulation arguments.</param> public SettingsForm(GameServer server, SimulationArguments arguments) { InitializeComponent(); _Server = server; server.PlayerConnected += Server_PlayerConnected; server.PlayerDisconnected += Server_PlayerDisconnected; server.StateChanged += Server_StateChanged; _Parameters = arguments.Parameters; _Controls = new List <Tuple <PlayerColor, Button, TextBox> >() { new Tuple <PlayerColor, Button, TextBox>(PlayerColor.RED, btnDisP1, tbP1), new Tuple <PlayerColor, Button, TextBox>(PlayerColor.GREEN, btnDisP2, tbP2), new Tuple <PlayerColor, Button, TextBox>(PlayerColor.BLUE, btnDisP3, tbP3), new Tuple <PlayerColor, Button, TextBox>(PlayerColor.YELLOW, btnDisP4, tbP4), new Tuple <PlayerColor, Button, TextBox>(PlayerColor.BLACK, btnDisP5, tbP5) }; // Local function decimal Clamp(int val, decimal min, decimal max) => (val > max ? max : (val < min ? min : val)); // Set the default values by arguments: numPlayers.Value = Clamp(arguments.PlayerCount, numPlayers.Minimum, numPlayers.Maximum); numFollowers.Value = Clamp(_Parameters.FollowerAmount, numFollowers.Minimum, numFollowers.Maximum); cbTileSet.SelectedIndex = 0; tbPort.Text = arguments.Port.ToString(); cbSave.Checked = arguments.SaveGame; btnSave.Text = _SaveFileName = arguments.SaveFileName; Restart(); FormClosed += (o, ev) => { _Server.Restart(); Application.Exit(); }; }
/// <summary> /// Loads game history file and sets game parameters accordingly. /// </summary> /// <param name="args">Arguments of the simulation program.</param> /// <param name="filename">Name of file where the history and settings should be loaded from.</param> private List <ServerResponse> LoadGame(SimulationArguments args, string filename) { var gameLoader = new GameHistoryLoader(); return(gameLoader.LoadGame(args, Executor, filename)); }
public List<ServerResponse> LoadGame(SimulationArguments args, GameExecutor executor, string filename) { var serializer = new XmlSerializer(typeof(ServerResponse)); List<ServerResponse> responses = new List<ServerResponse>(); using (var reader = new StreamReader(filename)) { var msgs = reader.ReadToEnd() .Split(new string[] { "</Response>" }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x + "</Response>"); bool any = false; bool hasParams = false; foreach (var msg in msgs) { try { var response = (ServerResponse)serializer.Deserialize(new StringReader(msg)); responses.Add(response); switch (response.Type) { case ServerResponseType.GAME_START: if (any) throw new Exception(); args.Parameters = response.Parameters; args.EnabledColors = response.Parameters.PlayerOrder.ToList(); args.PlayerCount = args.EnabledColors.Count; args.Parameters.TileSet = TileSetType.STANDARD_PASSIVE; hasParams = true; executor.StartGame(args.Parameters); break; case ServerResponseType.MOVE_START: // nothing, tileset is given break; case ServerResponseType.TILE_PLACEMENT: executor.PlaceTile(response.Color, response.Scheme, response.Coords, response.Orientation); break; case ServerResponseType.FOLLOWER_PLACEMENT: executor.PlaceFollower(response.Color, response.Coords, response.RegionId); break; case ServerResponseType.FOLLOWER_REMOVEMENT: executor.RemoveFollower(response.Color, response.Coords); break; case ServerResponseType.NO_FOLLOWER_PLACEMENT: executor.NoFollowerPlacement(response.Color); break; case ServerResponseType.GAME_RESUME: case ServerResponseType.GAME_PAUSE: case ServerResponseType.GAME_HISTORY: // Skip this break; default: throw new Exception(); } any = true; } catch { throw new ArgumentException("Save file is corrupted."); } } if (!hasParams) throw new ArgumentException("Save file contains no game setting infomration."); executor.ChangeTileSetType(TileSetType.STANDARD); } return responses; }
/// <summary> /// Parses argument name and acts by the given argument. /// </summary> /// <param name="alreadySet">Already set parameters.</param> /// <param name="result">Already parsed arguments.</param> /// <param name="arg">Argument name.</param> /// <returns>Next expected argument.</returns> private ArgumentParserState ParseArgument(List <char> alreadySet, SimulationArguments result, string arg) { switch (arg.ToLower()) { case "-h": case "--headless": if (alreadySet.Contains('h')) { throw new ArgumentException("Cannot set the same parameter twice: Headless mode."); } result.IsHeadless = true; return(ArgumentParserState.ARGUMENT); case "-p": case "--port": if (alreadySet.Contains('p')) { throw new ArgumentException("Cannot set the same parameter twice: Port number."); } return(ArgumentParserState.PORT); case "-c": case "--player-count": if (alreadySet.Contains('c')) { throw new ArgumentException("Cannot set the same parameter twice: Player count."); } return(ArgumentParserState.PLAYER_COUNT); case "-r": case "--colors": if (alreadySet.Contains('r')) { throw new ArgumentException("Cannot set the same parameter twice: Player colors."); } return(ArgumentParserState.PLAYER_COLORS); case "-f": case "--follower-count": if (alreadySet.Contains('f')) { throw new ArgumentException("Cannot set the same parameter twice: Follower count."); } return(ArgumentParserState.FOLLOWER_COUNT); case "-t": case "--tile-set": if (alreadySet.Contains('t')) { throw new ArgumentException("Cannot set the same parameter twice: Tile set."); } return(ArgumentParserState.TILE_SET); case "-s": case "--save-file": if (alreadySet.Contains('s')) { throw new ArgumentException("Cannot set the same parameter twice: Save file name."); } return(ArgumentParserState.SAVE_FILE); case "-l": case "--load-file": if (alreadySet.Contains('s')) { throw new ArgumentException("Cannot set the same parameter twice: Load file name."); } return(ArgumentParserState.LOAD_FILE); } throw new ArgumentException($"Unexpected argument on the input: {arg}."); }