private void CheckTriggers(ServerGameState state, EventBase ev) { var myEventFilter = new PredicatedEvent() { Event = ev, Filter = ev.GetFilter(), Side = PredicateSide.Friendly }; var oppEventFilter = new PredicatedEvent() { Event = ev, Filter = ev.GetFilter(), Side = PredicateSide.Enemy }; var myTriggeredEvents = state.Me.Triggers.GetAssociatedEvents(myEventFilter); var oppTriggeredEvents = state.Opp.Triggers.GetAssociatedEvents(oppEventFilter); if (myTriggeredEvents.Any() || oppTriggeredEvents.Any()) { // TODO: form and re-query chain of events // TODO: check the event orders / orders of minion appearances // TODO: re-call ProcessEvent() for each triggered event and return the resulting events throw new NotImplementedException(); } }
public ServerGameState Build() { var gameState = new GameState(_users, _turnOwner); var serverGameState = new ServerGameState(_session, gameState, _bot); return(serverGameState); }
private bool IsAttackStillValid(ServerGameState state, EventCharacterAttacks eventAttack) { // TODO: Process other types of attack (only Minion -> Player attacks are supported the moment) var attackingMinion = state.Me.Minions.FirstOrDefault(x => x.Id == eventAttack.Attacker); var attackedOpponentFace = state.Opp.Player; if (attackingMinion == null) { logger.Log(LogType.Services, LogSeverity.Info, $"EventCharacterAttack was cancelled because attacker was not found"); return(false); } if (attackedOpponentFace.Id != eventAttack.Attacked) { logger.Log(LogType.Services, LogSeverity.Info, $"EventCharacterAttack was cancelled because attacked character was not found"); return(false); } if (attackedOpponentFace.Health <= 0) { logger.Log(LogType.Services, LogSeverity.Info, $"EventCharacterAttack was cancelled because attacked character is already dead"); return(false); } return(true); }
public void Init() { Log.Info("Game (re)initialised"); _gameClock.Stop(); _countDownClock.Stop(); State = new ServerGameState(); }
void TryEndGame(ServerGameState state) { if (state.SharedState.IsEnded) { _sessions.TryDelete(state.Session); } }
private void ProcessPlayCard(ServerGameState state, EventCardPlayed playCardEvent) { state.Me.LastTurnEvents.Add(playCardEvent); var card = playCardEvent.Card; switch (card.Type) { case CardType.Spell: break; case CardType.Minion: var minion = new Minion(card as CardMinion, state.Me.MinionOrderNumber++); logger.Log(LogType.Services, LogSeverity.Info, $"{minion.Card.Name} is summoned"); state.Me.Minions.Insert(playCardEvent.MinionPosition.Value, minion); ProcessEvent(state, new EventMinionSummoned() { MinionId = minion.Id }); break; case CardType.Weapon: break; case CardType.Hero: break; } }
IGameAction GetActionForVersion(ServerGameState state, int version) { if (state.Actions.Count > version) { return(_games.FilterAction(state.Actions[version], User.Identity.Name)); } return(null); }
public void ToDTO() { ServerGameState dto = new ServerGameState(); foreach (Player player in PlayerRepository.Players) { dto.Players.Add(player.ToDTO()); } }
//向所有client更新玩家状态,收到的消息甚至包括客户端本地玩家状态,除了hp等关键信息可以不处理 void PlayerStateUpdate() { Protocol.ServerGameState state = new ServerGameState(); state.info = new PlayerInfo[lm.playerCount]; lm.AchievePlayerInfo(state.info, -1); GameMsg msg = new GameMsg(GameMsg.MsgType.ServerGameState, state); SendToAllClientsInGame(msg, UnityEngine.Networking.QosType.StateUpdate); }
public void ProcessAttack(ServerGameState fullState, InteractionAttack interactionAttack) { var newEvent = new EventCharacterAttacks() { Attacker = interactionAttack.Attacker, Attacked = interactionAttack.Target }; eventProcessor.ProcessEvent(fullState, newEvent); }
void AddAction(ServerGameState state, IGameAction action) { state.Actions.Add(action); _logger.LogDebug( "[{0}] User: '******', action: {2} (state v.{3})", state.Session, action.User, action.ToString(), state.SharedState.Version); TryAddShowCardAction(state, action); TryAddBotAction(state); }
public ServerGameState GetGameStateDTO() { ServerGameState dto = new ServerGameState(); for (int i = 0; i < Players.Values.Count; i++) { dto.Players.Add(Players.Values.ToList()[i]); } return(dto); }
void TryAddBotAction(ServerGameState state) { if ((state != null) && (state.BotUser != null)) { var gameState = state.SharedState; var botAction = state.BotUser.GetAction(gameState); if (botAction != null) { TryApplyAction(state, botAction); } } }
public void FromDTO(ServerGameState dto) { foreach (ServerPlayer playerDto in dto.Players) { Player player = PlayerRepository.Players.Find(p => p.Name.Equals(playerDto.Name)); if (player != null && !player.IsMainPlayer) { player.RefreshData(playerDto); } } }
void OnDateEvent(Protocol.GameMsg msg, int connection) { if (msg.type == GameMsg.MsgType.PlayerJoin) { //新增玩家 PlayerJoin join = msg.content as PlayerJoin; if (join != null) { OnRemotePlayerJoin(join); } } else if (msg.type == GameMsg.MsgType.PlayerQuit) {//移出 PlayerQuit quit = msg.content as PlayerQuit; if (quit != null) { OnRemotePlayerQuit(quit); } } else if (msg.type == GameMsg.MsgType.ServerGameState) { //更新 ServerGameState state = msg.content as ServerGameState; if (state != null) { OnUpdateGameInfo(state); } } else if (msg.type == GameMsg.MsgType.InitServerGameInfo) { //开始游戏 InitServerGameInfo state = msg.content as InitServerGameInfo; if (state != null) { OnInitClientGame(state); } } else if (msg.type == GameMsg.MsgType.Damage) { HitPlayer hit = msg.content as HitPlayer; if (hit != null) { OnDamage(hit); } } else if (msg.type == GameMsg.MsgType.Shoot) { PlayerShoot shoot = msg.content as PlayerShoot; if (shoot != null) { OnShoot(shoot); } } }
public bool TryApplyAction(ServerGameState state, IGameAction action) { if (state != null) { var gameState = state.SharedState; if (gameState.TryApply(action)) { AddAction(state, action); TryEndGame(state); return(true); } } return(false); }
// ======================================================================== // =========================== UPDATES (MULTIPLAYER) ====================== // ======================================================================== private void UpdatePlayers(ServerGameState stateDTO) { foreach (var dto in stateDTO.Players) { Player player = PlayerRepository.Players.Find(p => p.Name.Equals(dto.Name)); if (player != null && !MainPlayer.Equals(player)) { player.RefreshData(dto); } if (player == null) { Player tmpPlayer = new Player(dto); PlayerRepository.Players.Add(tmpPlayer); } } }
private Game() { GameParameters = new GameParameters(); _gameClock = new Timer(); _gameClock.Elapsed += GameTick; _gameClock.Stop(); _countDownClock = new Timer(); _countDownClock.Interval = 1000; _countDownClock.Elapsed += CountdownTick; _countDownClock.Stop(); _gameStopWatch = new Stopwatch(); State = new ServerGameState(); _shellCounter = 0; _time = 0; }
public void ProcessPlayCard(ServerGameState fullState, InteractionPlayCard interactionPlayCard) { var me = fullState.Me; var opp = fullState.Opp; var card = me.Hand.First(x => x.Id == interactionPlayCard.CardId); logger.Log(LogType.Services, LogSeverity.Info, $"{me.Player.Name} plays {card.Name} for {card.Cost} mana"); me.Mana.SpendMana(card.Cost); me.Hand.Remove(card); var newEvent = new EventCardPlayed() { Card = card, MinionPosition = interactionPlayCard.MinionPosition }; eventProcessor.ProcessEvent(fullState, newEvent); }
static void Main(string[] args) { Console.Title = "Project Victoria Server"; Logger.SetPrinter(new Printer()); Logger.SetFilter(""); Logger.Log(LogLevel.L2_Info, "\n --- Server Started --- \n", ""); // -- Set up Networking _networkManager = NetworkManager.GetInstance(); // -- Set up GameState _serverGameState = ServerGameState.GetInstance(); // -- Command loop -- Blocking!!! CommandManager commandManager = new CommandManager(); // -- Close down _networkManager.CloseSocket(); }
void OnUpdateGameInfo(ServerGameState state) { if (initRecieved) { foreach (PlayerInfo info in state.info) { Player player = lm.GetPlayer(info.id); if (player != null) { if (player.playerType == PlayerType.Remote) { // 状态设置 RemotePlayerController rpc = player.GetComponent <RemotePlayerController>(); rpc.ApplyRemoteInfo(info); } } } } }
public void ProcessInteraction(ServerGameState fullState, InteractionBase interaction) { switch (interaction.Type) { case InteractionType.Attack: attackProcessor.ProcessAttack(fullState, interaction as InteractionAttack); return; case InteractionType.PlayCard: playCardProcessor.ProcessPlayCard(fullState, interaction as InteractionPlayCard); return; case InteractionType.EndTurn: endTurnProcessor.ProcessEndTurn(fullState, interaction as InteractionEndTurn); return; } throw new ArgumentOutOfRangeException("interaction.Type", interaction.Type, "Unsupported interaction type"); }
/// <summary> /// Processes the events recursively /// </summary> /// <param name="state"></param> /// <param name="ev"></param> /// <returns>Returned events are already processed ones</returns> public void ProcessEvent(ServerGameState state, EventBase ev) { logger.Log(LogType.Services, LogSeverity.Info, $"Processing event {ev.ToString()}"); CheckTriggers(state, ev); //TODO: support other events switch (ev.Type) { case GameEventType.CardPlayed: ProcessPlayCard(state, ev as EventCardPlayed); return; case GameEventType.CharacterAttacks: attackProcessor.ProcessAttack(state, ev as EventCharacterAttacks); return; } state.Me.LastTurnEvents.Add(ev); }
void TryAddShowCardAction(ServerGameState state, IGameAction action) { var expandAction = action as IExpandCardAction; if ((expandAction != null) && (!string.IsNullOrEmpty(expandAction.ExpandUser))) { state.SharedState.Version++; var card = state.SharedState.Users.Find(u => u.Name == expandAction.ExpandUser).HandSet.Last(); _logger.LogDebug( "[{0}] ExpandCardAction: user: '******' (hand: {2}), card: {3}", state.Session, expandAction.ExpandUser, expandAction.ExpandHand, card.Type); if (expandAction.ExpandHand) { state.Actions.Add(new ShowHandCardAction(expandAction.ExpandUser, card)); } if (expandAction.ExpandTable) { state.Actions.Add(new ShowTableCardAction(expandAction.ExpandUser, card)); } } }
public bool TryAdd(ServerGameState game) { if ((game == null) || (string.IsNullOrEmpty(game.Session))) { return(false); } if (_games.ContainsKey(game.Session)) { return(false); } try { if (_games.TryAdd(game.Session, game)) { _logger.LogDebug( "Game for session '{0}' is created (first turn to: '{1}')", game.Session, game.SharedState.TurnOwner); TryAddBotAction(game); return(true); } } catch (Exception e) { _logger.LogWarning("TryAdd: {0}", e); } return(false); }
public ClientGameState PrepareGameState(ServerGameState fullState) { return(new ClientGameState() { Me = new ClientPlayerState { Player = fullState.Me.Player, Minions = fullState.Me.Minions, Mana = fullState.Me.Mana, DeckSize = fullState.Me.Deck.Count, Hand = fullState.Me.Hand, Events = fullState.Me.Events }, Opp = new ClientOpponentState() { Player = fullState.Opp.Player, Minions = fullState.Opp.Minions, Mana = fullState.Opp.Mana, DeckSize = fullState.Opp.Deck.Count, HandSize = fullState.Opp.Hand.Count, VisibleEvents = PrepareEventsForExternalUser(fullState.Opp.Events) } }); }
public void ProcessAttack(ServerGameState state, EventCharacterAttacks eventAttack) { // TODO: Process other types of attack (only Minion -> Player attacks are supported the moment) if (!IsAttackStillValid(state, eventAttack)) { return; } // 1. Attack state.Me.LastTurnEvents.Add(eventAttack); // 2. Got Attacked var characterGotAttackedEvent = new EventCharacterGotAttacked() { Attacked = eventAttack.Attacked, Attacker = eventAttack.Attacker }; eventProcessor.ProcessEvent(state, characterGotAttackedEvent); if (!IsAttackStillValid(state, eventAttack)) { return; } // 3. Deal Damage var characterDealsDamageEvent = new EventCharacterDealsDamage() { Damaged = eventAttack.Attacked, Damager = eventAttack.Attacker }; eventProcessor.ProcessEvent(state, characterDealsDamageEvent); if (!IsAttackStillValid(state, eventAttack)) { return; } //TODO: process it inside EventCharacterDealsDamage var attackingMinion = state.Me.Minions.FirstOrDefault(x => x.Id == eventAttack.Attacker); logger.Log(LogType.Services, LogSeverity.Info, $"{attackingMinion.Card.Name} attacks {state.Me.Player.Name} for {attackingMinion.Attack} damage"); // 4 Got Damaged //TODO: check if the damage event actually happened and was not somehow nullified var characterDamagedEvent = new EventCharacterDamaged() { Damaged = eventAttack.Attacked, Damager = eventAttack.Attacker }; eventProcessor.ProcessEvent(state, characterDamagedEvent); //TODO: process it inside EventCharacterDamaged state.Opp.Player.Health -= attackingMinion.Attack; logger.Log(LogType.Services, LogSeverity.Info, $"{state.Opp.Player.Name} Health reduced to {state.Opp.Player.Health} hp"); // 5. Check if Opp died if (state.Opp.Player.Health <= 0) { var charactedDiedEvent = new EventCharacterDied() { DiedCharacter = eventAttack.Attacked }; eventProcessor.ProcessEvent(state, charactedDiedEvent); } else { var characterSurvivedDamage = new EventCharacterSurvivedDamage(); eventProcessor.ProcessEvent(state, characterSurvivedDamage); } // 6. After Attack Event var afterAttackEvent = new EventCharacterAfterAttack(); eventProcessor.ProcessEvent(state, afterAttackEvent); }
public GameResult HostTheGame( PlayerInitializer playerInitializer1, PlayerInitializer playerInitializer2, IUserInteractor playerInteractor1, IUserInteractor playerInteractor2) { logger.Log(LogType.Arbiter, LogSeverity.Info, "Game started"); this.playerInteractor1 = playerInteractor1; this.playerInteractor2 = playerInteractor2; var deckValidation1 = deckValidator.ValidateDeck(playerInitializer1.Deck, playerInitializer1.Class); var deckValidation2 = deckValidator.ValidateDeck(playerInitializer2.Deck, playerInitializer2.Class); if (!deckValidation1.IsOk || !deckValidation2.IsOk) { //TODO: figure out where to log the validator messages return(new GameResult() { IsOk = false }); } player1State = gameStatePreparator.Initialize(playerInitializer1); player2State = gameStatePreparator.Initialize(playerInitializer2); //TODO: gamble the right of first turn. //TODO: implement mulligan and initial draw here //TODO: add service for draws and fatigue for (int i = 0; i < ruleSet.HandStartingSize; i++) { var randomCardIndex = new Random().Next(0, player1State.Deck.Count); var card = player1State.Deck[randomCardIndex]; player1State.Deck.RemoveAt(randomCardIndex); player1State.Hand.Add(card); var randomCardIndex2 = new Random().Next(0, player2State.Deck.Count); var card2 = player2State.Deck[randomCardIndex2]; player2State.Deck.RemoveAt(randomCardIndex2); player2State.Hand.Add(card); } isPlayerOneActive = true; var internalTurnNumber = 1; while (internalTurnNumber++ < ruleSet.TurnMaxCountPerGame) { var state = new ServerGameState() { Me = ActivePlayerState, Opp = PassivePlayerState }; state.Me.Events.Add(internalTurnNumber, new List <EventBase>()); logger.Log(LogType.Arbiter, LogSeverity.Info, $"Turn {internalTurnNumber / 2} started for {state.Me.Player.Name}"); // Add new non-empty mana crystal if (state.Me.Mana.PermanentManaCrystals < ruleSet.ManaStorageMaxCrystals) { state.Me.Mana.AddManaCrystals(1, false); } // Refresh Permanent Mana Crystals state.Me.Mana.RefreshPermanentManaCrystals(); //TODO: draw the card from the deck var randomCardIndex = new Random().Next(0, state.Me.Deck.Count); var card = state.Me.Deck[randomCardIndex]; state.Me.Deck.RemoveAt(randomCardIndex); state.Me.Hand.Add(card); //TODO: start of turn events here //TODO: update the state to both users //TODO: send the events var stateForActiveUser = gameStatePreparator.PrepareGameState(state); ActivePlayerInteractor.Update(stateForActiveUser); //TODO: add time limit for a user to interact while (true) { var interaction = ActivePlayerInteractor.Interact(); var interactionValidation = userInteractionProcessor.ValidateInteraction(stateForActiveUser, interaction); if (!interactionValidation.IsOk) { //TODO: figure out where to log the validator messages return(new GameResult() { IsOk = false }); } if (interaction is InteractionEndTurn) { break; } //TODO: send the events to other user userInteractionProcessor.ProcessInteraction(state, interaction); if (state.Me.LastTurnEvents.Any(x => x is EventCharacterDied && (x as EventCharacterDied).DiedCharacter == state.Opp.Player.Id)) { logger.Log(LogType.Arbiter, LogSeverity.Info, $"{state.Me.Player.Name} Won"); logger.Log(LogType.Arbiter, LogSeverity.Info, $"After Game State: {JsonConvert.SerializeObject(state)}"); // TODO: find a more approriate way to stop the game return(new GameResult() { IsOk = true, IsFirstPlayerWon = isPlayerOneActive, FinalState = state }); } stateForActiveUser = gameStatePreparator.PrepareGameState(state); ActivePlayerInteractor.Update(stateForActiveUser); } // Burn Unused Mana state.Me.Mana.BurnTemporaryCrystals(); //TODO: end of turn events here isPlayerOneActive = !isPlayerOneActive; } return(null); }
public void ProcessEndTurn(ServerGameState fullState, InteractionEndTurn interactionEndTurn) { throw new NotImplementedException(); }