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