Beispiel #1
0
 /// <summary>
 /// 同盟関係を設定する
 /// </summary>
 /// <param name="alliance">新しい同盟関係</param>
 public async Task SetAllianceChangingValueAsync(CountryAlliance alliance)
 {
   try
   {
     var old = await this.GetCountryAllianceChangingValueAsync(alliance.RequestedCountryId, alliance.InsistedCountryId);
     old.Some(o =>
     {
       this.container.Context.CountryAlliances.Remove(o);
     });
     if (alliance.Status != CountryAllianceStatus.None)
     {
       await this.container.Context.CountryAlliances.AddAsync(alliance);
     }
   }
   catch (Exception ex)
   {
     this.container.Error(ex);
   }
 }
        public async Task SetCountryAllianceAsync(
            [FromRoute] uint targetId,
            [FromBody] CountryAlliance param)
        {
            CountryAlliance            alliance;
            MapLog                     mapLog = null;
            Optional <CountryAlliance> old    = default;

            if (param.Status != CountryAllianceStatus.Available &&
                param.Status != CountryAllianceStatus.ChangeRequesting &&
                param.Status != CountryAllianceStatus.Dismissed &&
                param.Status != CountryAllianceStatus.InBreaking &&
                param.Status != CountryAllianceStatus.Requesting &&
                param.Status != CountryAllianceStatus.Changed &&
                param.Status != CountryAllianceStatus.None)
            {
                ErrorCode.InvalidParameterError.Throw();
            }

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

                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();
                }

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

                if (target.AiType != CountryAiType.Human)
                {
                    // 人間の国以外に同盟を申請することはできない
                    ErrorCode.InvalidOperationError.Throw();
                }

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

                var changeTo = await repo.CountryDiplomacies.GetCountryAllianceChangingValueAsync(self.CountryId, targetId);

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

                if (old.HasData &&
                    old.Data.Status != CountryAllianceStatus.Broken &&
                    old.Data.Status != CountryAllianceStatus.Dismissed &&
                    old.Data.Status != CountryAllianceStatus.None)
                {
                    var o = old.Data;

                    if ((param.Status == CountryAllianceStatus.Available || param.Status == CountryAllianceStatus.ChangeRequesting || param.Status == CountryAllianceStatus.Changed) &&
                        o.Status == CountryAllianceStatus.Requesting)
                    {
                        if (self.CountryId == o.RequestedCountryId)
                        {
                            // 自分で自分の要求を承認しようとした
                            ErrorCode.NotPermissionError.Throw();
                        }
                    }
                    else if (param.Status == CountryAllianceStatus.InBreaking &&
                             (o.Status != CountryAllianceStatus.Available && o.Status != CountryAllianceStatus.ChangeRequesting))
                    {
                        // 結んでいないのに破棄はエラー
                        ErrorCode.NotPermissionError.Throw();
                    }
                    else if ((param.Status == CountryAllianceStatus.None || param.Status == CountryAllianceStatus.Requesting) &&
                             (o.Status == CountryAllianceStatus.Available || o.Status == CountryAllianceStatus.ChangeRequesting))
                    {
                        // 結んでいるものを一瞬でなかったことにするのはエラー
                        ErrorCode.NotPermissionError.Throw();
                    }
                    else if (param.Status == o.Status && param.Status == CountryAllianceStatus.Available)
                    {
                        // 再承認はできない
                        ErrorCode.MeaninglessOperationError.Throw();
                    }
                    else if (param.Status == CountryAllianceStatus.Changed)
                    {
                        if (!changeTo.HasData || o.Status != CountryAllianceStatus.ChangeRequesting)
                        {
                            // 変更提案していないのに承諾はできない
                            ErrorCode.InvalidOperationError.Throw();
                        }
                        else if (changeTo.Data.RequestedCountryId == self.CountryId)
                        {
                            // 自分の変更要求を自分で承認できない
                            ErrorCode.InvalidOperationError.Throw();
                        }
                    }

                    if (param.Status == CountryAllianceStatus.Available || param.Status == CountryAllianceStatus.InBreaking)
                    {
                        param.BreakingDelay = o.BreakingDelay;
                        param.IsPublic      = o.IsPublic;
                        param.CanMissionary = o.CanMissionary;
                        param.Memo          = o.Memo;
                    }
                    else if (param.Status == CountryAllianceStatus.Changed)
                    {
                        param.BreakingDelay = changeTo.Data.BreakingDelay;
                        param.IsPublic      = changeTo.Data.IsPublic;
                        param.CanMissionary = changeTo.Data.CanMissionary;
                        param.Memo          = changeTo.Data.Memo;
                    }
                }
                else
                {
                    if (param.Status != CountryAllianceStatus.Requesting)
                    {
                        // 同盟を結んでいない場合、同盟の要求以外にできることはない
                        ErrorCode.NotPermissionError.Throw();
                    }

                    war.Some((w) =>
                    {
                        if (w.Status == CountryWarStatus.Available ||
                            w.Status == CountryWarStatus.InReady ||
                            w.Status == CountryWarStatus.StopRequesting)
                        {
                            // 戦争中
                            ErrorCode.NotPermissionError.Throw();
                        }
                    });
                }

                alliance = new CountryAlliance
                {
                    RequestedCountryId = self.CountryId,
                    InsistedCountryId  = targetId,
                    BreakingDelay      = param.BreakingDelay,
                    IsPublic           = param.IsPublic,
                    CanMissionary      = param.CanMissionary,
                    Memo   = param.Memo,
                    Status = param.Status == CountryAllianceStatus.Changed ? CountryAllianceStatus.Available : param.Status,
                };
                if (param.Status != CountryAllianceStatus.ChangeRequesting)
                {
                    await repo.CountryDiplomacies.SetAllianceAsync(alliance);
                }
                else
                {
                    alliance.ChangeTargetId = old.Data.Id;
                    alliance.Status         = CountryAllianceStatus.ChangeRequestingValue;
                    old.Data.Status         = CountryAllianceStatus.ChangeRequesting;
                    await repo.CountryDiplomacies.SetAllianceChangingValueAsync(alliance);
                }

                // 同盟関係を周りに通知
                if (alliance.IsPublic && old.HasData && alliance.Status != CountryAllianceStatus.ChangeRequestingValue)
                {
                    if (old.Data.Status == CountryAllianceStatus.Requesting &&
                        alliance.Status == CountryAllianceStatus.Available)
                    {
                        var country1 = await repo.Country.GetByIdAsync(alliance.RequestedCountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                        var country2 = await repo.Country.GetByIdAsync(alliance.InsistedCountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                        mapLog = new MapLog
                        {
                            ApiGameDateTime = (await repo.System.GetAsync()).GameDateTime,
                            Date            = DateTime.Now,
                            EventType       = EventType.AllianceStart,
                            IsImportant     = true,
                            Message         = "<country>" + country1.Name + "</country> と <country>" + country2.Name + "</country> は、同盟を締結しました",
                        };
                        await repo.MapLog.AddAsync(mapLog);
                    }
                }

                await repo.SaveChangesAsync();
            }

            // 同盟関係を周りに通知
            if (alliance.IsPublic && alliance.Status != CountryAllianceStatus.ChangeRequestingValue)
            {
                await StatusStreaming.Default.SendAllAsync(ApiData.From(alliance));

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

                    await AnonymousStreaming.Default.SendAllAsync(ApiData.From(mapLog));
                }
            }
            else
            {
                await StatusStreaming.Default.SendCountryAsync(ApiData.From(alliance), alliance.RequestedCountryId);

                await StatusStreaming.Default.SendCountryAsync(ApiData.From(alliance), alliance.InsistedCountryId);
            }

            if (alliance.Status == CountryAllianceStatus.ChangeRequestingValue && old.HasData)
            {
                await StatusStreaming.Default.SendCountryAsync(ApiData.From(old.Data), alliance.RequestedCountryId);

                await StatusStreaming.Default.SendCountryAsync(ApiData.From(old.Data), alliance.InsistedCountryId);
            }
        }