public void SendMessage(string serializedMessage) { try { BesiegedMessage message = serializedMessage.FromXml<BesiegedMessage>(); if (message is GenericServerMessage && (message as GenericServerMessage).MessageEnum == ServerMessage.ServerMessageEnum.StartServer) { m_ServerCallback = OperationContext.Current.GetCallbackChannel<IClient>(); GenericServerMessage started = new GenericServerMessage() { MessageEnum = ServerMessage.ServerMessageEnum.ServerStarted }; m_ServerCallback.SendMessage(started.ToXml()); m_IsServerInitialized.Value = true; //StartProcessingMessages(); ProcessMessages(); } else if (message is ConnectMessage) { IClient callback = OperationContext.Current.GetCallbackChannel<IClient>(); string clientId = Guid.NewGuid().ToString(); ConnectedClient connectedClient = new ConnectedClient((message as ConnectMessage).Name, clientId, callback); AggregateMessage aggregate = new AggregateMessage(); GenericClientMessage success = new GenericClientMessage() { ClientId = clientId, MessageEnum = ClientMessage.ClientMessageEnum.ConnectSuccessful }; aggregate.MessageList.Add(success); if (m_Games.Count > 0) // notify the client of any pre-existing game instances that they might be able to join { foreach (KeyValuePair<string, BesiegedGameInstance> game in m_Games) { if (!game.Value.IsGameInstanceFull) { string capacity = string.Format("{0}/{1} players", game.Value.Players.Count, game.Value.MaxPlayers); GameInfoMessage gameInfo = new GameInfoMessage(game.Value.GameId, game.Value.Name, capacity, false, game.Value.Password != string.Empty ? true : false); aggregate.MessageList.Add(gameInfo); } } } callback.SendMessage(aggregate.ToXml()); ConsoleLogger.Push(string.Format("{0} has joined the server", connectedClient.Name)); m_ConnectedClients.GetOrAdd(clientId, connectedClient); // Add an entry to the global client hook } else { m_MessageQueue.Add(message); } } catch (Exception ex) { ErrorLogger.Push(ex); } }
public void RemovePlayer(string clientId) { if (clientId == m_GameCreatorClientId) { GenericClientMessage disbanded = new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.GameDisbanded }; NotifyAllPlayers(disbanded.ToXml()); BesiegedServer.DisbandGame(GameId); } else { Player player = Players.FirstOrDefault(x => x.ClientId == clientId); Players.Remove(player); ConsoleLogger.Push(string.Format("{0} with ClientId {1} has left game {2}", player.Name, player.ClientId, Name)); AggregateMessage aggregate = new AggregateMessage(); GenericClientMessage remove = new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.RemovePlayer, ClientId = player.ClientId }; ClientChatMessage chatMessage = new ClientChatMessage() { Contents = string.Format("* {0} has left the game *", player.Name) }; aggregate.MessageList.Add(remove); aggregate.MessageList.Add(chatMessage); NotifyAllPlayers(aggregate.ToXml()); ColorPool.Push(player.PlayerColor); player.Callback.SendMessage((new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.TransitionToMultiplayerMenuState }).ToXml()); player = null; m_GameMachine.Fire(Trigger.PlayerLeft); } }
private void ConfigureMachine() { m_GameMachine = new StateMachine<State, Trigger>(() => m_CurrentState, newState => m_CurrentState = newState); ProcessMessages(); #region WaitingForPlayers m_GameMachine.Configure(State.WaitingForPlayers) .Permit(Trigger.AllPlayersReady, State.AllPlayersReady) .OnEntryFrom(Trigger.PlayerNotReady, x => { GenericClientMessage waiting = new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.PlayerNotReady }; LookupPlayerById(m_GameCreatorClientId).Callback.SendMessage(waiting.ToXml()); }) .OnEntryFrom(Trigger.PlayerLeft, x => { SendUpdatedGameInfo(); }) .PermitReentry(Trigger.PlayerLeft) .Ignore(Trigger.PlayerNotReady) .Ignore(Trigger.CreatorPressedStart); #endregion #region AllPlayersReady m_GameMachine.Configure(State.AllPlayersReady) .OnEntry(x => { GenericClientMessage ready = new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.AllPlayersReady }; LookupPlayerById(m_GameCreatorClientId).Callback.SendMessage(ready.ToXml()); }) .Permit(Trigger.PlayerNotReady, State.WaitingForPlayers) .Permit(Trigger.PlayerLeft, State.WaitingForPlayers) .Permit(Trigger.CreatorPressedStart, State.GameStarted); #endregion #region GameStarted m_GameMachine.Configure(State.GameStarted) .OnEntry(x => { List<KeyValuePair<string, Army.ArmyTypeEnum>> PlayerInfos = new List<KeyValuePair<string, Army.ArmyTypeEnum>>(); foreach (Player player in Players) { PlayerInfos.Add(new KeyValuePair<string, Army.ArmyTypeEnum>(player.ClientId, player.ArmyType)); m_PlayerTurnOrder.Enqueue(player.ClientId); } GameState = new GameState(PlayerInfos); pathFinder = new PathFinder(GameState); ConsoleLogger.Push(String.Format("Game {0} has been started", Name)); NotifyAllPlayers(new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.TransitionToLoadingState }.ToXml()); // switch all the players to loading while we send the gamestate ClientGameStateMessage gamestate = new ClientGameStateMessage() { State = GameState }; GenericClientMessage start = new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.StartGame }; AggregateMessage aggregate = new AggregateMessage(); aggregate.MessageList.Add(gamestate); aggregate.MessageList.Add(start); NotifyAllPlayers(aggregate.ToXml()); m_GameMachine.Fire(Trigger.GameStarted); }) .Permit(Trigger.GameStarted, State.PlayerTurn) .Ignore(Trigger.PlayerNotReady); #endregion #region PlayerTurn m_GameMachine.Configure(State.PlayerTurn) .PermitReentry(Trigger.PlayerTurn) .Permit(Trigger.PlayerLeft, State.Reconfigure) .Permit(Trigger.StartBattlePhase, State.BattlePhase) .Permit(Trigger.Cheatcode, State.EndGame) .OnEntry(x => { // notify the current player that its their turn m_CurrentPlayerId = m_PlayerTurnOrder.Dequeue(); LookupPlayerById(m_CurrentPlayerId).Callback.SendMessage((new GenericClientMessage() { MessageEnum = ClientMessage.ClientMessageEnum.ActiveTurn }).ToXml()); // notify all other players that they have to wait foreach (string playerId in m_PlayerTurnOrder) { LookupPlayerById(playerId).Callback.SendMessage((new WaitingForTurnMessage() { ActivePlayerName = LookupPlayerById(m_CurrentPlayerId).Name }).ToXml()); } // add the current player back on the queue m_PlayerTurnOrder.Enqueue(m_CurrentPlayerId); }); #endregion m_GameMachine.Configure(State.BattlePhase) .OnEntry(x => { }); #region EndGame m_GameMachine.Configure(State.EndGame) .OnEntry(x => { var winner = LookupPlayerById(m_WinnerId); var gameOverMessage = new GameOverMessage() { WinnerId = m_WinnerId, WinnerName = winner.Name }; NotifyAllPlayers(gameOverMessage.ToXml()); }); #endregion #region Reconfigure m_GameMachine.Configure(State.Reconfigure) .OnEntry(x => { // this state allows us to reconfigure the players involved in the game in case someone leaves or is defeated Queue<string> tempPlayers = new Queue<string>(); foreach (string playerId in m_PlayerTurnOrder) { if (Players.FirstOrDefault(p => p.ClientId == playerId) != null) { tempPlayers.Enqueue(playerId); } } if (tempPlayers.Count > 0) { m_PlayerTurnOrder.Clear(); m_PlayerTurnOrder = tempPlayers; m_GameMachine.Fire(Trigger.PlayerTurn); } }) .Permit(Trigger.PlayerTurn, State.PlayerTurn); #endregion }
public void AddPlayer(ConnectedClient client) { Player player = new Player(client.Name, client.ClientId, client.Callback, ColorPool.Pop()); Players.Add(player); ConsoleLogger.Push(string.Format("{0} with ClientId {1} has joined game {2}", player.Name, player.ClientId, Name)); SendUpdatedGameInfo(); player.IsReady.ValueChanged += (from, to) => { PlayerInfoMessage playerInfo = new PlayerInfoMessage() { ClientId = player.ClientId, Name = player.Name, Color = player.PlayerColor, IsReady = to }; NotifyAllPlayers(playerInfo.ToXml()); if (to) { CheckIfAllAreReady(); } else { m_GameMachine.Fire(Trigger.PlayerNotReady); } }; AggregateMessage aggregate = new AggregateMessage(); PlayerGameInfoMessage playerGameInfo = new PlayerGameInfoMessage() { GameId = this.GameId, IsCreator = (Players.Count == 1) ? true : false }; aggregate.MessageList.Add(playerGameInfo); PlayerInfoMessage playerInfoMessage = new PlayerInfoMessage() { ClientId = player.ClientId, Name = player.Name, Color = player.PlayerColor, IsReady = false }; foreach (Player p in Players) { if (p.ClientId != player.ClientId) { p.Callback.SendMessage(playerInfoMessage.ToXml()); } aggregate.MessageList.Add(new PlayerInfoMessage() { ClientId = p.ClientId, Name = p.Name, Color = p.PlayerColor, IsReady = p.IsReady.Value }); } player.Callback.SendMessage(aggregate.ToXml()); }