/// <summary> /// Refusing a connection. /// Returns an UNDEFINED player packet /// </summary> /// <param name="model">The client model</param> public ReversiClientModel RefuseConnection(ReversiClientModel model) { //PlayerModel newplayer = DataTransmission.DeserializeData<PlayerModel>(client); //Console.WriteLine("... GameServer: Refusing connection for " + newplayer.Name + ". Maximum number of server connections exceeded."); //if (client != null) //{ // newplayer.IDType = Players.UNDEFINED; // try // { // DataTransmission.SerializeData<PlayerModel>(newplayer, client); // } // catch // { // throw new SocketException(); // } //} //Remove the player from the WaitingList //foreach (PlayerModel p in WaitingList) //{ // if (p.Socket == client) // { // WaitingList.Remove(p); // break; // } //} //client.Close(); // close the socket return(model); }
/// <summary> /// Determines whether a connection should be accepted or refused /// </summary> /// <param name="model">The model to accept or refuse</param> /// <param name="status">The returned status of this connection request</param> public ReversiClientModel AcceptOrRefuseConnection(ReversiClientModel model, out ConnectionStatusTypes status) { string str = model.ConnectionSocket.Client.Handle.ToString(); Console.WriteLine(str); if ((model.ConnectionSocket == null)) { status = ConnectionStatusTypes.StatusConnectionError; return(null); } // Send a connection declined message for too many connections if (ConnectedClientModelList.Count > ServerSettings.MaxServerConnections) { model = RefuseConnection(model); status = ConnectionStatusTypes.StatusConnectionRefused; } // Otherwise accept the connection else { model = AcceptConnection(model); status = ConnectionStatusTypes.StatusConnectionAccepted; } model.CurrentStatus = status; return(model); }
/// <summary> /// Refuse a connection and close the socket /// </summary> /// <param name="newModel"></param> public ReversiClientModel RefuseConnection(ReversiClientModel newModel) { // And immediately return it without updating the ID newModel.CurrentStatus = ConnectionStatusTypes.StatusConnectionRefused; try { DataTransmission.SerializeData <ReversiClientModel>(newModel, newModel.ConnectionSocket); } catch { throw new SocketException(); } newModel.ConnectionSocket.Close(); ClientDisconnectedEventArgs args = new ClientDisconnectedEventArgs { client = newModel, TimeOfDisconnect = DateTime.Now }; OnClientDisconnected(args); return(newModel); }
/// <summary> /// The main thread handle for this reversi server. /// </summary> public override void HandleServerThread() { Console.WriteLine("Server " + Id + ": Starting HandleServerThread"); while (!ShouldShutdown) { if (ConnectedClientModelList.Count == 0) { //Console.WriteLine("No clients on ReversiServerManager " + Id); Thread.Sleep(ServerSettings.ServerUpdatePulseDelay); continue; } //// Check for enough clients to place on a server //Console.WriteLine("RSM currently has " + ConnectedClientModelList.Count + " clients connected to it..."); // Get the oldest client ReversiClientModel oldestClientModel = (ReversiClientModel)GetOldestClientModelFromConnectedList(); Console.WriteLine("-- Oldest available client is: " + oldestClientModel.Id); // Find an available game server or create a new one ReversiGameServerModel availableServer = (ReversiGameServerModel)GetAvailableServer(ServerTypes.ServerGameserver); Console.WriteLine("-- Available server is: " + availableServer.Id); // Move the client model to a reversi game server.... availableServer.AddClientModelToServer(oldestClientModel); Console.WriteLine("-- Adding client " + oldestClientModel.Id + " to game server " + availableServer.Id); // And remove it from the connected list RemoveClientModelFromConnectedList(oldestClientModel); //Console.WriteLine("-- Client removed from ReversiServerManager list"); } }
static void Main() { Console.WriteLine("Launching Application"); Manager = new ReversiServerManagerModel(); Manager.ConfigureManager(); Manager.ListenerSocket = Manager.StartManager(); // Returns the TcoListener for this server Manager.StartServer(); // Now listen for incoming connections and add them to the connections list as they come in. // The server managers HandleServerThread will assign them to appropriate game and/or chat servers. while (!Manager.ShouldShutdown) { // Listen for connections TcpClient newTcpClientSocket = Manager.ListenForConnections(); // Receive the response from the client, and readd the connection socket to the object since it's not serialized. ReversiClientModel newTcpClientModel = DataTransmission.DeserializeData <ReversiClientModel>(newTcpClientSocket); newTcpClientModel.ConnectionSocket = newTcpClientSocket; // Determine what we should do with the connection and send the appropriate response newTcpClientModel = Manager.AcceptOrRefuseConnection(newTcpClientModel, out var status); // If the connection was accepted then add the model to the connected models list if (status == ConnectionStatusTypes.StatusConnectionAccepted) { Manager.AddClientModelToConnectionList(newTcpClientModel); Console.WriteLine("Server manager #" + Manager.Id + " has accepted client " + newTcpClientModel.Id + "."); } else if (status == ConnectionStatusTypes.StatusConnectionRefused) { Console.WriteLine("Server manager #" + Manager.Id + " has refused client" + newTcpClientModel.Id + "."); } // List our connected clients for testing. Console.WriteLine(Manager.ListConnectedClients()); // Dispose of the temporary client newTcpClientModel = null; } // Shutdown the server manager Manager.Shutdown(); }
/// <summary> /// Accepts a connection request /// </summary> /// <param name="newModel"></param> public ReversiClientModel AcceptConnection(ReversiClientModel newModel) { // And updating the ID and status newModel.CurrentStatus = ConnectionStatusTypes.StatusConnectionAccepted; newModel.ClientPlayer.PlayerId = newModel.NextId(); // updates the players ID here. try { DataTransmission.SerializeData <ReversiClientModel>(newModel, newModel.ConnectionSocket); } catch { newModel.CurrentStatus = ConnectionStatusTypes.StatusConnectionError; } ClientConnectedEventArgs args = new ClientConnectedEventArgs { client = newModel, TimeOfConnection = DateTime.Now }; OnClientConnected(args); return(newModel); }
//private static List<TcpClient> GatherPlayerSocketList(List<PlayerModel> p) //{ // List<TcpClient> temp = new List<TcpClient>(); // // Once two players have connected, start the game with the two players. // foreach (PlayerModel item in p) // { // TcpClient socket = GetSocketByPlayerID(item.PlayerID); // Console.WriteLine("...... " + item.Name + " is " + item.IDType); // item.Socket = socket; // save the socket reference for the game // temp.Add(socket); // } // return temp; //} public override void Update() { var temp = ConnectedClientModelList; ReversiClientModel client = (ReversiClientModel)GetOldestClientModelFromConnectedList(); Console.WriteLine(client.ClientPlayer.DisplayPlayerInfo()); if (!WaitingList.Contains(client)) { WaitingList.Add(client); RemoveClientModelFromServer(client); } // If insufficient players have joined, add to wait list... if (WaitingList.Count < ReversiSettings.ReversiPlayersPerGame) { // Do nothing here } // If two players and no running game, start the game if ((WaitingList.Count == ReversiSettings.ReversiPlayersPerGame) && RunningGames.Count == 0) { Console.WriteLine("-- GameServer: Creating 1st game"); MovePlayersFromWaitingToStaging(); // Create the game thread to handle this matchup and // Populate the players Thread gameThread = new Thread(InitializeMatchup); // Start the game gameThread.Start(StagingArea); } // If a game is already running, add the player to the waiting list... if (RunningGames.Count > 0) { Console.WriteLine("-- GameServer: A game is already running so add client to waiting list"); } // If someone already in the waiting list, and another player joins, allow option for players to start their own game... if (WaitingList.Count == ReversiSettings.ReversiPlayersPerGame) { Console.WriteLine("-- Sending option to Wait List for additional games to be created..."); // TODO: Send choice to waiting list about whether to keep waiting or to start a new game... // Continue waiting... // Or start a game with waiting list } string str = string.Empty; str += "-------------------------------\n"; foreach (ReversiClientModel item in WaitingList) { str += item.ClientPlayer.PlayerId + " -- " + item.ClientPlayer.Name + "\n"; } str += "-------------------------------\n"; Console.WriteLine(str); }
///// <summary> ///// Removes a player from the staging area to the gameroom. ///// </summary> //private static void RemovePlayersFromStaging() //{ // for (int i = ReversiSettings.ReversiPlayersPerGame - 1; i >= 0; i--) // { // StagingArea.RemoveAt(i); // } //} /// <summary> /// The main thread routine for each game /// </summary> /// <param name="data">The game staging area list of client models</param> private void InitializeMatchup(object data) { List <ReversiClientModel> clientModels = (List <ReversiClientModel>)data; //// Create the game instance which moves the players to the game room ReversiGameModel game = new ReversiGameModel(clientModels); RunningGames.Add(game.GameId, game); // add the game to the dictionary of running games Console.WriteLine("... GameServer: Matchup pairing complete. Game " + game.GameId.ToString() + " is ready to start."); Console.WriteLine(game.DisplayGameInfoComplete()); // Send the game object to each of the clients. foreach (KeyValuePair <int, ClientModel> item in game.CurrentPlayersList) { ReversiClientModel client = (ReversiClientModel)item.Value; // Send the game data to each of the players Console.WriteLine("Sending initial game matchup to players"); DataTransmission.SerializeData <ReversiGameModel>(game, client.ConnectionSocket); // And remove the players from the Staging area. StagingArea.Remove(client); } //// The main game loop. Process individual moves here List <TcpClient> sockets = game.GetPlayersSocketList(); while (!game.GameIsOver) { // If the game is paused ignore the user input if (game.GameIsPaused == true) { continue; } if (game.GameOverCheckRequired) { if (game.CheckGameOver(game.CurrentPlayer) == true) { Console.WriteLine("No available moves for " + game.CurrentPlayer); game.GameIsOver = true; break; } Console.WriteLine("Valid moves available for " + game.CurrentPlayer); game.AvailableMovesList.ForEach(Console.WriteLine); game.GameOverCheckRequired = false; } // If the current turn is valid and complete, switch to the next player if (game.TurnComplete) { Console.WriteLine(game.Gameboard.DrawGameboardString()); game.NextPlayer(); game.TurnComplete = false; game.GameOverCheckRequired = true; // Update the game model for all players... SendGameToAll(game); } List <ClientModel> disconnectList = new List <ClientModel>(); foreach (KeyValuePair <int, ClientModel> item in game.CurrentPlayersList) { ClientModel client = item.Value; Socket s = client.ConnectionSocket.Client; // Check for disconnected sockets if (!SocketConnected(s)) { Console.WriteLine("GameServer: (GameID #" + game.GameId + ")"); disconnectList.Add(client); } } // Remove any disconnected players from the game... foreach (ClientModel disconnectClient in disconnectList) { ClientDisconnectedEventArgs args = new ClientDisconnectedEventArgs { client = disconnectClient, TimeOfDisconnect = DateTime.Now }; game.GameIsPaused = true; OnClientDisconnected(args); game.RemovePlayerFromGame(((ClientModel)disconnectClient)); try { disconnectClient.ConnectionSocket.Close(); } catch { // Do nothing } } // Now proceed through the current player list, looking for moves sent by the clients foreach (KeyValuePair <int, ClientModel> item in game.CurrentPlayersList) { NetworkStream stream; try { stream = item.Value.ConnectionSocket.GetStream(); } catch (ObjectDisposedException e) { // Catches a disposed socket possibility here in case it hasn't been fully disposed yet. continue; } if (stream.DataAvailable) { GameMoveModel move = DataTransmission.DeserializeData <GameMoveModel>(item.Value.ConnectionSocket); Console.WriteLine("GameServer: (GameID #" + game.GameId + ")" + move.ByPlayer + " move request received"); if (move.ByPlayer == game.CurrentPlayer) { game.CurrentMoveIndex = move.MoveIndex; // Check that the move was valid. if (game.PlayTurn()) { Console.WriteLine("GameServer: (GameID #" + game.GameId + ")" + move.ByPlayer + " submitted a valid move"); game.TurnComplete = true; game.CurrentMoveIndex = move.MoveIndex; } } else { Console.WriteLine("GameServer: (GameID #" + game.GameId + ") Move received by opponent. Ignoring..."); } } } } // At this point the game is over. Console.WriteLine("The game is over..."); }