Exemple #1
0
        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();
            }
        }
Exemple #2
0
        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);
        }
Exemple #4
0
 public void Init()
 {
     Log.Info("Game (re)initialised");
     _gameClock.Stop();
     _countDownClock.Stop();
     State = new ServerGameState();
 }
Exemple #5
0
 void TryEndGame(ServerGameState state)
 {
     if (state.SharedState.IsEnded)
     {
         _sessions.TryDelete(state.Session);
     }
 }
Exemple #6
0
        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;
            }
        }
Exemple #7
0
 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());
            }
        }
Exemple #9
0
    //向所有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);
    }
Exemple #10
0
        public void ProcessAttack(ServerGameState fullState, InteractionAttack interactionAttack)
        {
            var newEvent = new EventCharacterAttacks()
            {
                Attacker = interactionAttack.Attacker, Attacked = interactionAttack.Target
            };

            eventProcessor.ProcessEvent(fullState, newEvent);
        }
Exemple #11
0
 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);
        }
Exemple #13
0
 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);
                }
            }
        }
Exemple #15
0
 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);
         }
     }
 }
Exemple #16
0
 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);
                }
            }
        }
Exemple #18
0
        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);
        }
Exemple #20
0
        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();
        }
Exemple #21
0
 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");
        }
Exemple #23
0
        /// <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);
        }
Exemple #24
0
        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));
                }
            }
        }
Exemple #25
0
 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);
 }
Exemple #26
0
 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();
 }