public bool Handle(DomainEventHandlerData <BattleEvent> @event)
        {
            var snap   = @event.Snapshot as GameAggregate;
            var castle = snap?.Castles.FirstOrDefault(e => e.Id == @event.EventObject.AtCastleId);

            if (castle?.Siege?.Soldiers == null)
            {
                return(false);
            }
            var attacking = castle.Siege.Soldiers;
            var defending = castle.Soldiers.Where(e => !e.IsDead).ToList();
            // boost strength
            var hero = castle.Heroes?.FirstOrDefault(e => e.Army != castle.Army);
            var attackingBoostStrength = hero == null ? 0 : _repository.GetHeroById(hero.UserId, hero.Id.ToString())?.Leadership ?? 0;

            hero = castle.Heroes?.FirstOrDefault(e => e.Army == castle.Army);
            var defendingBoostStrength = hero == null ? 0 : _repository.GetHeroById(hero.UserId, hero.Id.ToString())?.Leadership ?? 0;

            var battle = _gameDomainService.AttackSequence(@event.EventObject.Id,
                                                           castle,
                                                           castle.Siege.OwnerUserId,
                                                           castle.OwnerUserId,
                                                           attacking,
                                                           defending,
                                                           attackingBooststrength: attackingBoostStrength,
                                                           defendingBooststrength: defendingBoostStrength);

            // attacking win
            if (attacking.Count(e => !e.IsDead && e.CastleTroopType.Health > 0) > 0)
            {
                // add event
                // for user
                _domain.AddEvent(snap.Id, new OccupiedCastleEvent(castle.Siege.OwnerUserId, castle.Id, battle, DateTime.UtcNow));
                // for old owner of castle
                if (!string.IsNullOrEmpty(castle.OwnerUserId))
                {
                    _domain.AddEvent(snap.Id, new CastleHasBeenOccupiedEvent(castle.OwnerUserId, castle.Id, battle, DateTime.UtcNow));
                }
            }
            else
            {
                // defending win
                castle.Soldiers = castle.Soldiers.Where(e => e.CastleTroopType.Health > 0 && !e.IsDead).ToList();
                castle.UpdateSoldierAmount();
                _gameDomainService.CreateSoldierIfNeed(snap);
                // for depending
                if (!string.IsNullOrEmpty(castle.OwnerUserId))
                {
                    _domain.AddEvent(snap.Id, new DefendedCastleEvent(castle.OwnerUserId, castle.Id, battle, DateTime.UtcNow));
                }
                // for attacking
                _domain.AddEvent(snap.Id, new FailedAttackCastleEvent(castle.Siege.OwnerUserId, castle.Id, battle, DateTime.UtcNow));
            }
            return(true);
        }
        public bool Handle(DomainEventHandlerData <BattleVersusSiegeEvent> @event)
        {
            var snap   = @event.Snapshot as GameAggregate;
            var castle = snap?.Castles.FirstOrDefault(e => e.Id == @event.EventObject.CastleId);

            if (castle?.Siege.Soldiers == null)
            {
                return(false);
            }
            var attacking = @event.EventObject.Battalion;
            var defending = castle.Siege.Soldiers;

            // boost strength
            var attackingArmy          = snap.UserId == @event.EventObject.AttackingUserId ? Army.Blue : Army.Red;
            var hero                   = castle.Heroes?.FirstOrDefault(e => e.Army == attackingArmy);
            var attackingBoostStrength = hero == null ? 0 : _repository.GetHeroById(hero.UserId, hero.Id.ToString())?.Leadership ?? 0;

            var defendingArmy = snap.UserId == castle.Siege.OwnerUserId ? Army.Blue : Army.Red;

            hero = castle.Heroes?.FirstOrDefault(e => e.Army == defendingArmy);
            var defendingBoostStrength = hero == null ? 0 : _repository.GetHeroById(hero.UserId, hero.Id.ToString())?.Leadership ?? 0;

            var battle = _gameDomainService.AttackSequence(@event.EventObject.Id,
                                                           castle,
                                                           @event.EventObject.AttackingUserId,
                                                           castle.Siege.OwnerUserId,
                                                           attacking,
                                                           defending,
                                                           attackingBoostStrength,
                                                           defendingBoostStrength);

            // attacking win
            if (attacking.Count(e => !e.IsDead && e.CastleTroopType.Health > 0) > 0)
            {
                var liveSoldiers = attacking.Where(e => e.CastleTroopType.Health > 0).ToList();
                // event for attacking
                _domain.AddEvent(snap.Id, new OccupiedSiegeInCastleEvent(
                                     @event.EventObject.AttackingUserId,
                                     castle.Id,
                                     battle,
                                     liveSoldiers, DateTime.UtcNow));
                // for old siege
                _domain.AddEvent(snap.Id, new SiegeHasBeenOccupiedEvent(castle.Siege.OwnerUserId,
                                                                        castle.Id,
                                                                        battle,
                                                                        DateTime.UtcNow));
            }
            else
            {
                // defending win
                // for defending
                _domain.AddEvent(snap.Id, new DefendedSiegeEvent(
                                     castle.Id, battle, castle.Siege.OwnerUserId));
                // for attacking
                _domain.AddEvent(snap.Id, new FailedAttackSiegeEvent(
                                     @event.EventObject.AttackingUserId,
                                     castle.Id,
                                     battle));
            }
            return(true);
        }