Example #1
0
        public static async Task SendWarAndSaveAsync(MainRepository repo, CountryWar war)
        {
            MapLog mapLog = null;

            await repo.CountryDiplomacies.SetWarAsync(war);

            if ((war.Status == CountryWarStatus.InReady && war.RequestedStopCountryId == 0) || war.Status == CountryWarStatus.Stoped)
            {
                // 戦争を周りに通知
                var country1 = await repo.Country.GetAliveByIdAsync(war.RequestedCountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                var country2 = await repo.Country.GetAliveByIdAsync(war.InsistedCountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                mapLog = new MapLog
                {
                    ApiGameDateTime = (await repo.System.GetAsync()).GameDateTime,
                    Date            = DateTime.Now,
                    IsImportant     = true,
                };
                if (war.Status == CountryWarStatus.InReady)
                {
                    if (war.RequestedStopCountryId == 0)
                    {
                        mapLog.EventType = EventType.WarInReady;
                        if (war.Mode == CountryWarMode.Religion)
                        {
                            mapLog.Message = "<country>" + country1.Name + "</country> は、<date>" + war.StartGameDate.ToString() + "</date> より <country>" + country2.Name + "</country> と宗教戦争を開始します";
                        }
                        else
                        {
                            mapLog.Message = "<country>" + country1.Name + "</country> は、<date>" + war.StartGameDate.ToString() + "</date> より <country>" + country2.Name + "</country> へ侵攻します";
                        }
                        await PushNotificationService.SendCountryAsync(repo, "宣戦布告", $"{war.StartGameDate.ToString()} より {country2.Name} と戦争します", country1.Id);

                        await PushNotificationService.SendCountryAsync(repo, "宣戦布告", $"{war.StartGameDate.ToString()} より {country1.Name} と戦争します", country2.Id);
                    }
                }
                else if (war.Status == CountryWarStatus.Stoped)
                {
                    mapLog.EventType = EventType.WarStopped;
                    mapLog.Message   = "<country>" + country1.Name + "</country> と <country>" + country2.Name + "</country> の戦争は停戦しました";
                    await PushNotificationService.SendCountryAsync(repo, "停戦", $"{country2.Name} との戦争は停戦しました", country1.Id);

                    await PushNotificationService.SendCountryAsync(repo, "停戦", $"{country1.Name} との戦争は停戦しました", country2.Id);
                }
                await repo.MapLog.AddAsync(mapLog);
            }

            await repo.SaveChangesAsync();

            await StatusStreaming.Default.SendAllAsync(ApiData.From(war));

            if (mapLog != null)
            {
                await StatusStreaming.Default.SendAllAsync(ApiData.From(mapLog));

                await AnonymousStreaming.Default.SendAllAsync(ApiData.From(mapLog));
            }
        }
        public async Task <IEnumerable <uint> > GetPenaltyCountries(
            [FromBody] CountryWar assumptionWar = null)
        {
            using (var repo = MainRepository.WithRead())
            {
                var chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError);

                var countries = await CountryService.GetPenaltyCountriesAsync(repo, assumptionWar);

                return(countries);
            }
        }
Example #3
0
 /// <summary>
 /// 戦争を設定する
 /// </summary>
 /// <param name="war">新しい戦争</param>
 public async Task SetWarAsync(CountryWar war)
 {
   try
   {
     var old = await this.GetCountryWarAsync(war.RequestedCountryId, war.InsistedCountryId);
     old.Some(o =>
     {
       this.container.Context.CountryWars.Remove(o);
     });
     if (war.Status != CountryWarStatus.None)
     {
       await this.container.Context.CountryWars.AddAsync(war);
     }
   }
   catch (Exception ex)
   {
     this.container.Error(ex);
   }
 }
        public async Task SetCountryWarAsync(
            [FromRoute] uint targetId,
            [FromBody] CountryWar param)
        {
            CountryWar war;
            Optional <CountryAlliance> alliance;
            MapLog mapLog = null;

            if (param.Status != CountryWarStatus.InReady &&
                param.Status != CountryWarStatus.StopRequesting &&
                param.Status != CountryWarStatus.Stoped)
            {
                ErrorCode.InvalidParameterError.Throw();
            }

            using (var repo = MainRepository.WithReadAndWrite())
            {
                var system = await repo.System.GetAsync();

                if (system.IsSoftStoped)
                {
                    ErrorCode.SystemSoftStopedError.Throw();
                }

                var self = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError);

                var myPosts = await repo.Country.GetCharacterPostsAsync(self.Id);

                if (!myPosts.Any(p => p.Type.CanDiplomacy()))
                {
                    ErrorCode.NotPermissionError.Throw();
                }

                if (system.IsBattleRoyaleMode)
                {
                    // 全国戦争中に戦争操作はできない
                    ErrorCode.InvalidOperationError.Throw();
                }

                if (system.RuleSet != GameRuleSet.Religion && param.Mode == CountryWarMode.Religion)
                {
                    // 宗教戦争は宗教ルールでないと布告できない
                    ErrorCode.RuleSetError.Throw();
                }

                var towns = await repo.Town.GetAllAsync();

                var myCountry = await repo.Country.GetAliveByIdAsync(self.CountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                var target = await repo.Country.GetAliveByIdAsync(targetId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                var wars = await repo.CountryDiplomacies.GetAllWarsAsync();

                var old = await repo.CountryDiplomacies.GetCountryWarAsync(self.CountryId, targetId);

                alliance = await repo.CountryDiplomacies.GetCountryAllianceAsync(self.CountryId, targetId);

                old.Some((o) =>
                {
                    if (o.Status == param.Status)
                    {
                        ErrorCode.MeaninglessOperationError.Throw();
                    }

                    if ((o.Status == CountryWarStatus.Available || o.Status == CountryWarStatus.InReady) &&
                        param.Status == CountryWarStatus.InReady)
                    {
                        // 重複して宣戦布告はできない
                        ErrorCode.MeaninglessOperationError.Throw();
                    }
                    else if (o.Status == CountryWarStatus.StopRequesting && param.Status == CountryWarStatus.Stoped &&
                             o.RequestedStopCountryId == self.CountryId)
                    {
                        // 自分の停戦要求を自分で承認できない
                        ErrorCode.NotPermissionError.Throw();
                    }
                    else if (o.Status == CountryWarStatus.Stoped && param.Status == CountryWarStatus.StopRequesting)
                    {
                        // 一度決まった停戦を撤回できない
                        ErrorCode.NotPermissionError.Throw();
                    }

                    if (o.Status == CountryWarStatus.Stoped && param.Status == CountryWarStatus.InReady)
                    {
                        // 停戦後の再布告
                        if (param.StartGameDate.ToInt() < system.IntGameDateTime + 12 * 12 + 1 ||
                            param.StartGameDate.Year < Config.StartYear + Config.UpdateStartYear + Config.CountryBattleStopDuring / 12)
                        {
                            // 開戦が早すぎる
                            ErrorCode.InvalidParameterError.Throw();
                        }
                        else if (param.StartGameDate.ToInt() > system.IntGameDateTime + 12 * 24)
                        {
                            // 開戦が遅すぎる
                            ErrorCode.InvalidParameterError.Throw();
                        }
                    }
                    else if (o.Status == CountryWarStatus.StopRequesting && param.Status == CountryWarStatus.InReady)
                    {
                        // 停戦撤回または拒否
                        if (o.StartGameDate.ToInt() <= system.GameDateTime.ToInt())
                        {
                            // 開戦後の場合は開戦扱い
                            param.Status = CountryWarStatus.Available;
                        }
                    }

                    param.RequestedStopCountryId = o.RequestedStopCountryId;
                    if (param.Status == CountryWarStatus.StopRequesting)
                    {
                        param.RequestedStopCountryId = self.CountryId;
                    }

                    param.RequestedCountryId = o.RequestedCountryId;
                    param.InsistedCountryId  = o.InsistedCountryId;
                    param.StartGameDate      = o.StartGameDate;
                    param.Mode = o.Mode;
                });
                old.None(() =>
                {
                    if (param.Mode == CountryWarMode.Religion)
                    {
                        if (myCountry.Religion == ReligionType.Any || myCountry.Religion == ReligionType.None)
                        {
                            // 国教を持たない国は宗教戦争を布告できない
                            ErrorCode.InvalidOperationError.Throw();
                        }

                        if (target.Religion == myCountry.Religion)
                        {
                            // 同じ宗教の国には宗教戦争を布告できない
                            ErrorCode.ReligionError.Throw();
                        }
                    }

                    if (wars.Where(w => w.Status == CountryWarStatus.Available || w.Status == CountryWarStatus.InReady || w.Status == CountryWarStatus.StopRequesting)
                        .Where(w => w.IsJoin(myCountry.Id) || w.IsJoin(target.Id))
                        .Any(w => w.Mode != param.Mode))
                    {
                        // 就業戦争と通常戦争を両方することはできない
                        ErrorCode.InvalidWarModeError.Throw();
                    }

                    if (!towns.GetAroundCountries(towns.Where(t => t.CountryId == param.InsistedCountryId)).Contains(param.RequestedCountryId))
                    {
                        // 飛び地布告
                        ErrorCode.InvalidOperationError.Throw();
                    }

                    if (param.Status == CountryWarStatus.StopRequesting || param.Status == CountryWarStatus.Stoped)
                    {
                        // 存在しない戦争を停戦にはできない
                        ErrorCode.NotPermissionError.Throw();
                    }
                    else if (param.StartGameDate.ToInt() < system.IntGameDateTime + 12 * 12 + 1 ||
                             param.StartGameDate.Year < Config.StartYear + Config.UpdateStartYear + Config.CountryBattleStopDuring / 12)
                    {
                        // 開戦が早すぎる
                        ErrorCode.InvalidParameterError.Throw();
                    }
                    else if (param.StartGameDate.ToInt() > system.IntGameDateTime + 12 * 24)
                    {
                        // 開戦が遅すぎる
                        ErrorCode.InvalidParameterError.Throw();
                    }
                });

                alliance.Some((a) =>
                {
                    if (a.Status == CountryAllianceStatus.Available ||
                        a.Status == CountryAllianceStatus.ChangeRequesting ||
                        a.Status == CountryAllianceStatus.InBreaking)
                    {
                        // 同盟が有効中
                        ErrorCode.NotPermissionError.Throw();
                    }
                    if (a.Status == CountryAllianceStatus.Requesting)
                    {
                        // 自動で同盟申請を却下する
                        a.Status = CountryAllianceStatus.Broken;
                    }
                });

                war = new CountryWar
                {
                    RequestedCountryId     = param.RequestedCountryId,
                    InsistedCountryId      = param.InsistedCountryId,
                    StartGameDate          = param.StartGameDate,
                    Status                 = param.Status,
                    RequestedStopCountryId = param.RequestedStopCountryId,
                    Mode = param.Mode,
                };

                await CountryService.SendWarAndSaveAsync(repo, war);
            }

            if (alliance.HasData)
            {
                var a = alliance.Data;
                await StatusStreaming.Default.SendCountryAsync(ApiData.From(a), a.RequestedCountryId);

                await StatusStreaming.Default.SendCountryAsync(ApiData.From(a), a.InsistedCountryId);
            }
        }
Example #5
0
        public static async Task <IReadOnlyList <uint> > GetPenaltyCountriesAsync(MainRepository repo, CountryWar assumptionWar = null)
        {
            return(Enumerable.Empty <uint>().ToArray());

            /*
             * var reinforcements = (await repo.Reinforcement.GetAllAsync()).Where(r => r.Status == ReinforcementStatus.Active);
             * var characters = (await repo.Character.GetAllAliveAsync()).Where(c => c.DeleteTurn < 200 && (c.AiType == CharacterAiType.Human || c.AiType == CharacterAiType.Administrator));
             * var countries = (await repo.Country.GetAllAsync()).Where(c => !c.HasOverthrown);
             * var wars = (await repo.CountryDiplomacies.GetAllWarsAsync())
             * .Where(w => !countries.Any(c => c.Id == w.RequestedCountryId && c.AiType == CountryAiType.Farmers))
             * .Where(w => w.Status != CountryWarStatus.Stoped && w.Status != CountryWarStatus.None);
             * if (assumptionWar != null)
             * {
             * wars = wars
             *  .Where(w => !(w.IsJoin(assumptionWar.InsistedCountryId) && w.IsJoin(assumptionWar.RequestedCountryId)))
             *  .Append(assumptionWar)
             *  .Where(w => w.Status != CountryWarStatus.Stoped && w.Status != CountryWarStatus.None);
             * }
             *
             * var penaltyWarCountries = new List<uint>();
             *
             * // 複数国による同時宣戦を行っている国を抽出
             * var cooperateWarCountries = wars
             * .GroupBy(w => w.InsistedCountryId)
             * .Where(g => g.Count() >= 2)
             * .SelectMany(g => g.Select(w => w.RequestedCountryId))
             * .Distinct();
             *
             * // 過剰援軍にペナルティ
             * var reinforcementsOfCountry = characters
             * .GroupBy(c => c.CountryId)
             * .GroupJoin(reinforcements, c => c.Key, r => r.RequestedCountryId, (c, rs) => new { CountryId = c.Key, Reinforcements = rs, Characters = c, });
             * foreach (var data in reinforcementsOfCountry)
             * {
             * IEnumerable<uint> GetEnemies(IEnumerable<uint> countryIds)
             * {
             *  return wars
             *    .Where(w => countryIds.Any(c => w.IsJoin(c)))
             *    .SelectMany(w => new uint[] { w.InsistedCountryId, w.RequestedCountryId, })
             *    .Except(countryIds)
             *    .Distinct();
             * }
             *
             * // 敵(自分が相手する国)
             * var countries1 = GetEnemies(new uint[] { data.CountryId, });
             *
             * // 敵の敵(味方)
             * var countries2 = GetEnemies(countries1);
             *
             * // 敵の敵の敵(味方の敵)
             * var countries3 = GetEnemies(countries2);
             *
             * var warTargetCountries = countries3
             *  .Join(reinforcementsOfCountry, a => a, b => b.CountryId, (aa, bb) => bb);
             * var mySideCountries = countries2
             *  .Join(reinforcementsOfCountry, a => a, b => b.CountryId, (aa, bb) => bb);
             *
             * if (warTargetCountries.Any() && mySideCountries.Any())
             * {
             *  var warTargetsCharacterCount = warTargetCountries.Sum(c => c.Characters.Count());
             *  var warTargetsReinforcementCount = warTargetCountries.Sum(c => c.Reinforcements.Count());
             *  var mySideCharacterCount = mySideCountries.Sum(c => c.Characters.Count());
             *  var mySideReinforcementCount = mySideCountries.Sum(c => c.Reinforcements.Count());
             *
             *  var isPenalty = false;
             *
             *  // 単純な過剰援軍
             *  if (mySideReinforcementCount > 0 && mySideCharacterCount > warTargetsCharacterCount + 3)
             *  {
             *    isPenalty = true;
             *  }
             *  // 複数国同時布告による事実上の過剰援軍
             *  else if (cooperateWarCountries.Contains(data.CountryId) &&
             *    mySideCharacterCount > warTargetsCharacterCount + 5)
             *  {
             *    isPenalty = true;
             *  }
             *
             *  if (isPenalty)
             *  {
             *    penaltyWarCountries.Add(data.CountryId);
             *  }
             * }
             * }
             *
             * return penaltyWarCountries;
             */
        }