public async Task DeleteCountryBbsAsync( [FromRoute] uint id) { ThreadBbsItem message; Character chara; using (var repo = MainRepository.WithReadAndWrite()) { chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); var item = await repo.ThreadBbs.GetByIdAsync(id).GetOrErrorAsync(ErrorCode.NodeNotFoundError); if (item.CharacterId != chara.Id) { var posts = await repo.Country.GetCharacterPostsAsync(chara.Id); var characterPosts = posts.Select(p => p.Type); if (!characterPosts.Any(p => p == CountryPostType.Monarch || p == CountryPostType.Warrior)) { ErrorCode.NotPermissionError.Throw(); } } message = item; repo.ThreadBbs.Remove(item); await repo.SaveChangesAsync(); } message.IsRemove = true; await StatusStreaming.Default.SendCountryAsync(ApiData.From(message), chara.CountryId); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { if (character.CountryId == 0) { await game.CharacterLogAsync($"国庫に金を納入しようとしましたが、無所属は実行できません"); return; } var countryOptional = await repo.Country.GetByIdAsync(character.CountryId); if (!countryOptional.HasData) { await game.CharacterLogAsync($"ID: <num>{character.CountryId}</num> の国は存在しません。<emerge>管理者にお問い合わせください</emerge>"); return; } var country = countryOptional.Data; if (country.HasOverthrown) { await game.CharacterLogAsync($"国庫に金を納入しようとしましたが、あなたの所属国 <country>{country.Name}</country> はすでに滅亡しています"); return; } var policies = await repo.Country.GetPoliciesAsync(country.Id); var max = 1000_0000; // CountryService.GetCountrySafeMax(policies.Where(p => p.Status == CountryPolicyStatus.Available).Select(p => p.Type)); var money = options.FirstOrDefault(o => o.Type == 1)?.NumberValue ?? 0; if (money > character.Money) { await game.CharacterLogAsync($"国庫に金 <num>{money}</num> を納入しようとしましたが、所持金が足りません"); return; } if (country.SafeMoney + money > max) { money = max - country.SafeMoney; if (money < 0) { // 支配とか災害とかで上限が下がることがある money = 0; } } country.SafeMoney += money; character.Money -= money; character.Contribution += 30; character.SkillPoint++; await game.CharacterLogAsync($"国庫に金 <num>{money}</num> を納入しました"); await StatusStreaming.Default.SendCountryAsync(ApiData.From(country), country.Id); return; }
public static async Task <CharacterItem> DivideResourceAndSaveAsync(MainRepository repo, CharacterItem item, int resourceSize) { if (item.Resource <= resourceSize) { return(item); } item.Resource -= resourceSize; var newItem = new CharacterItem { Type = item.Type, Status = item.Status, CharacterId = item.CharacterId, TownId = item.TownId, IntLastStatusChangedGameDate = item.IntLastStatusChangedGameDate, Resource = resourceSize, }; await GenerateItemAndSaveAsync(repo, newItem); await StatusStreaming.Default.SendAllAsync(ApiData.From(newItem)); await StatusStreaming.Default.SendAllAsync(ApiData.From(item)); return(newItem); }
public async Task PostGlobalChatMessageAsync( [FromBody] ChatMessage param) { var ip = this.HttpContext.Connection.RemoteIpAddress?.ToString(); ChatMessage message; Character chara; if (string.IsNullOrEmpty(param.Message) || param.Message?.Length > 400) { ErrorCode.NumberRangeError.Throw(new ErrorCode.RangeErrorParameter("message", param.Message.Length, 1, 400)); } using (var repo = MainRepository.WithReadAndWrite()) { chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); if (await repo.BlockAction.IsBlockedAsync(chara.Id, BlockActionType.StopGlobalChat)) { ErrorCode.BlockedActionError.Throw(); } message = await ChatService.PostChatMessageAsync(repo, param, chara, ip, ChatMessageType.Global, param.TypeData); await repo.SaveChangesAsync(); } await StatusStreaming.Default.SendAllAsync(ApiData.From(message)); }
public static async Task SetCharacterPendingAsync(MainRepository repo, CharacterItem item, Character chara) { if (item.Status == CharacterItemStatus.CharacterHold || item.Status == CharacterItemStatus.CharacterPending) { if (item.CharacterId == chara.Id) { return; } var oldChara = await repo.Character.GetByIdAsync(item.CharacterId); if (oldChara.HasData) { await ReleaseCharacterAsync(repo, item, oldChara.Data); } } var system = await repo.System.GetAsync(); item.Status = CharacterItemStatus.CharacterPending; item.CharacterId = chara.Id; item.TownId = 0; item.LastStatusChangedGameDate = system.GameDateTime; await CharacterService.StreamCharacterAsync(repo, chara); await StatusStreaming.Default.SendAllAsync(ApiData.From(item)); }
public static async Task StreamCharacterAsync(MainRepository repo, Character character) { // 同じ都市にいる他国の武将への通知、移動前の都市に滞在かつ違う国の武将への都市移動の通知は、以下の処理の中に含まれるので特段の対処は不要 var icon = (await repo.Character.GetCharacterAllIconsAsync(character.Id)).GetMainOrFirst(); var town = await repo.Town.GetByIdAsync(character.TownId); var townCharacters = await repo.Town.GetCharactersAsync(character.TownId); // この武将の所属する国の武将 await StatusStreaming.Default.SendCountryExceptForCharacterAsync(ApiData.From(new CharacterForAnonymous(character, icon.Data, CharacterShareLevel.SameCountry)), character.CountryId, character.Id); // 都市の武将 await StatusStreaming.Default.SendCharacterAsync(ApiData.From(new CharacterForAnonymous(character, icon.Data, character.AiType != CharacterAiType.SecretaryScouter ? CharacterShareLevel.SameTown : CharacterShareLevel.Anonymous)), townCharacters.Where(tc => tc.Id != character.Id && tc.CountryId != character.CountryId).Select(tc => tc.Id)); if (town.HasData && town.Data.CountryId != character.CountryId) { // この都市を所有している国の武将 await StatusStreaming.Default.SendCountryExceptForCharacterAsync(ApiData.From(new CharacterForAnonymous(character, icon.Data, character.AiType != CharacterAiType.SecretaryScouter ? CharacterShareLevel.SameCountryTownOtherCountry : CharacterShareLevel.Anonymous)), town.Data?.CountryId ?? 0, townCharacters.Where(tc => tc.CountryId == town.Data?.CountryId).Select(tc => tc.Id)); } // 本人と違う国で、かつ同じ都市にいない武将 await StatusStreaming.Default.SendAllExceptForCharactersAndCountryAsync(ApiData.From(new CharacterForAnonymous(character, icon.Data, CharacterShareLevel.Anonymous)), townCharacters.Select(tc => tc.Id), new uint[] { town.Data?.CountryId ?? 0, character.CountryId, }); // 本人 await StatusStreaming.Default.SendCharacterAsync(ApiData.From(character), character.Id); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var items = await repo.Character.GetItemsAsync(character.Id); var item = items.FirstOrDefault(i => i.Type == CharacterItemType.TimeChanger); if (item == null || item.Resource <= 0) { if (item != null) { await ItemService.SpendCharacterAsync(repo, item, character); } await game.CharacterLogAsync("静養しようとしましたが、コマンド実行に必要なアイテムを所持していません"); return; } var system = await repo.System.GetAsync(); var time = RandomService.Next(0, Config.UpdateTime * 100_000) / 100_000.0; character.LastUpdated = system.CurrentMonthStartDateTime.AddSeconds(time - Config.UpdateTime); item.Resource--; if (item.Resource <= 0) { await ItemService.SpendCharacterAsync(repo, item, character); } else { await StatusStreaming.Default.SendCharacterAsync(ApiData.From(item), character.Id); } await game.CharacterLogAsync($"更新時刻を月開始の <num>{(int)time}</num> 秒後に変更しました。アイテム残り: <num>{item.Resource}</num>"); }
public async Task SetMuteKeywordsAsync([FromBody] MuteKeyword keyword) { if (keyword == null) { ErrorCode.LackOfParameterError.Throw(); } using (var repo = MainRepository.WithReadAndWrite()) { var chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); keyword.CharacterId = this.AuthData.CharacterId; var old = await repo.Mute.GetCharacterKeywordAsync(chara.Id); if (old.HasData) { old.Data.Keywords = keyword.Keywords; } else { await repo.Mute.AddAsync(keyword); } await repo.SaveChangesAsync(); } await StatusStreaming.Default.SendCharacterAsync(ApiData.From(keyword), keyword.CharacterId); }
public override void OnException(ExceptionContext context) { base.OnException(context); if (!(context.Exception is SangokuKmyException exception)) { exception = new SangokuKmyException(context.Exception, ErrorCode.InternalError); } this.logger.LogError(exception, $"{context.HttpContext.Request.Method} [{(context.HttpContext.Request.Path.HasValue ? context.HttpContext.Request.Path.Value : "no-path")}]"); try { context.HttpContext.Response.StatusCode = exception.StatusCode; context.Result = new JsonResult(ApiData.From(new ApiError { Code = exception.ErrorCode.Code, Data = exception.AdditionalData })); } catch { context.HttpContext.Response.StatusCode = 500; context.Result = new JsonResult(ApiData.From(new ApiError { Code = -1, Data = default(object) })); } context.ExceptionHandled = true; }
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 static async Task SendTownWarAndSaveAsync(MainRepository repo, TownWar war) { await repo.CountryDiplomacies.SetTownWarAsync(war); await repo.SaveChangesAsync(); await StatusStreaming.Default.SendCountryAsync(ApiData.From(war), war.RequestedCountryId); }
public async Task UpdateItemStatusAsync( [FromBody] IssueBbsItem param) { IssueBbsItem message; Character chara; using (var repo = MainRepository.WithReadAndWrite()) { chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); if (chara.AiType != CharacterAiType.Administrator) { ErrorCode.NotPermissionError.Throw(); } message = await repo.IssueBbs.GetByIdAsync(param.Id).GetOrErrorAsync(ErrorCode.NodeNotFoundError); if (param.Status != IssueStatus.Undefined) { message.Status = param.Status; } if (param.Category != IssueCategory.Undefined) { message.Category = param.Category; } if (param.Period != 0 || param.Milestone != IssueMilestone.Unknown) { var system = await repo.System.GetAsync(); if (param.Milestone == IssueMilestone.CurrentPeriod) { message.Period = system.Period; message.BetaVersion = system.BetaVersion; } else if (param.Milestone == IssueMilestone.NextPeriod) { var period = system.IsNextPeriodBeta ? system.Period : system.Period + 1; var beta = system.IsNextPeriodBeta ? system.BetaVersion + 1 : 0; message.Period = (short)period; message.BetaVersion = (short)beta; } else if (param.Milestone == IssueMilestone.Clear) { message.Period = 0; message.BetaVersion = 0; } else { message.Period = param.Period; message.BetaVersion = param.BetaVersion; } } await repo.SaveChangesAsync(); } await StatusStreaming.Default.SendAllAsync(ApiData.From(message)); }
public async Task RemoveMuteAsync([FromBody] Mute mute) { var ip = this.HttpContext.Connection.RemoteIpAddress?.ToString(); IList <ChatMessage> chats = null; IEnumerable <Character> admins = null; if (mute == null) { ErrorCode.LackOfParameterError.Throw(); } using (var repo = MainRepository.WithReadAndWrite()) { var chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); var mutes = await repo.Mute.GetCharacterAsync(chara.Id); var target = mutes.FirstOrDefault(m => m.Id == mute.Id || (m.TargetCharacterId != 0 && m.TargetCharacterId == mute.TargetCharacterId) || (m.ChatMessageId != 0 && m.ChatMessageId == mute.ChatMessageId) || (m.ThreadBbsItemId != 0 && m.ThreadBbsItemId == mute.ThreadBbsItemId) || (m.IssueBbsItemId != 0 && m.IssueBbsItemId == mute.IssueBbsItemId)); if (target == null) { ErrorCode.InvalidOperationError.Throw(); } mute = target; repo.Mute.Remove(target); if (target.Type == MuteType.Reported) { admins = await repo.Character.GetAdministratorsAsync(); chats = new List <ChatMessage>(); foreach (var admin in admins) { chats.Add(await ChatService.PostChatMessageAsync(repo, new ChatMessage { Message = $"[b][s]【報告解除】[-s][-b]\n\nMute ID: {mute.Id}", }, chara, ip, ChatMessageType.Private, admin.Id, admin.Id)); } } await repo.SaveChangesAsync(); } mute.Type = MuteType.None; await StatusStreaming.Default.SendCharacterAsync(ApiData.From(mute), mute.CharacterId); if (admins != null && chats != null) { await StatusStreaming.Default.SendCharacterAsync(chats.Select(c => ApiData.From(c)), admins.Select(a => a.Id)); } }
public static async Task RemoveAsync(MainRepository repo, uint unitId) { var members = await repo.Unit.GetMembersAsync(unitId); repo.Unit.RemoveUnit(unitId); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(new ApiSignal { Type = SignalType.UnitRemoved, }), members.Select(um => um.CharacterId)); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var townIdOptional = options.FirstOrDefault(p => p.Type == 1).ToOptional(); if (character.Money < 200) { await game.CharacterLogAsync("偵察に必要な金が足りません"); } if (!townIdOptional.HasData) { await game.CharacterLogAsync("偵察のパラメータが不正です。<emerge>管理者にお問い合わせください</emerge>"); } else { var townOptional = await repo.Town.GetByIdAsync((uint)townIdOptional.Data.NumberValue); if (!townOptional.HasData) { await game.CharacterLogAsync("ID:" + townIdOptional.Data + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); } else { var town = townOptional.Data; var scoutedTown = ScoutedTown.From(townOptional.Data); scoutedTown.ScoutedDateTime = game.GameDateTime; scoutedTown.ScoutedCountryId = character.CountryId; scoutedTown.ScoutMethod = ScoutMethod.SpyCommand; await repo.ScoutedTown.AddScoutAsync(scoutedTown); await repo.SaveChangesAsync(); var savedScoutedTown = (await repo.ScoutedTown.GetByTownIdAsync(townOptional.Data.Id, character.CountryId)).Data; if (savedScoutedTown != null) { await StatusStreaming.Default.SendCountryAsync(ApiData.From(savedScoutedTown), character.CountryId); } var items = await repo.CharacterItem.GetByTownIdAsync(town.Id); var itemInfos = items.GetInfos(); await game.CharacterLogAsync($"都市 {town.Name} を偵察しました"); await game.CharacterLogAsync($"都市 {town.Name} のアイテム: {string.Join(", ", itemInfos.Select(i => i.Name))}"); character.Money -= 200; character.Contribution += 40; character.AddIntellectEx(50); character.SkillPoint++; } } }
public async Task <ApiArrayData <ChatMessage> > GetPrivateChatMessagesAsync( [FromQuery] uint sinceId = default, [FromQuery] int count = default) { IEnumerable <ChatMessage> messages; using (var repo = MainRepository.WithRead()) { messages = await repo.ChatMessage.GetPrivateMessagesAsync(this.AuthData.CharacterId, sinceId, count); } return(ApiData.From(messages)); }
public static async Task DenyCountryPromotions(MainRepository repo, Country country) { var promotions = (await repo.ChatMessage.GetPromotionMessagesAsync(country.Id)).Where(p => p.Type == ChatMessageType.Promotion); foreach (var p in promotions) { p.Type = ChatMessageType.PromotionDenied; await StatusStreaming.Default.SendCharacterAsync(ApiData.From(p), p.TypeData); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(p), p.TypeData2); } }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { if (character.Money < 50) { await game.CharacterLogAsync("金が足りません。<num>50</num> 必要です"); return; } var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (townOptional.HasData) { var town = townOptional.Data; if (town.CountryId != character.CountryId) { await game.CharacterLogAsync("<town>" + town.Name + "</town>で訓練しようとしましたが、自国の都市ではありません"); return; } var add = (int)(character.Leadership / 6.0f + RandomService.Next(0, character.Leadership) / 6.0f); if (add < 1) { add = 1; } var charas = await repo.Town.GetCharactersAsync(town.Id); foreach (var chara in charas.Where(c => c.CountryId == character.CountryId)) { chara.Proficiency = (short)Math.Min(100, chara.Proficiency + add); if (chara.Id != character.Id) { await game.CharacterLogByIdAsync(chara.Id, $"<character>{character.Name}</character> による合同訓練で、訓練が <num>+{add}</num> 上がりました"); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(chara), chara.Id); } } // 経験値、金の増減 character.Money -= 50; character.Contribution += 30; character.AddLeadershipEx(50); character.SkillPoint++; await game.CharacterLogAsync("訓練を <num>+" + add + "</num> 上げました"); } else { await game.CharacterLogAsync("ID:" + character.TownId + " の都市は存在しません。<emerge>管理者にお問い合わせください</emerge>"); } }
public async Task <ApiArrayData <ChatMessage> > GetGlobalChatMessagesAsync( [FromQuery] uint sinceId = default, [FromQuery] int type = default, [FromQuery] int count = default) { IEnumerable <ChatMessage> messages; using (var repo = MainRepository.WithRead()) { messages = await repo.ChatMessage.GetGlobalMessagesAsync(sinceId, type, count); } return(ApiData.From(messages)); }
public override async Task ExecuteAsync(MainRepository repo, Character character, IEnumerable <CharacterCommandParameter> options, CommandSystemData game) { var townOptional = await repo.Town.GetByIdAsync(character.TownId); if (!townOptional.HasData) { await game.CharacterLogAsync("ID: " + character.TownId + " の都市は存在しません。<emerge>管理者に連絡してください</emerge>"); } else if (character.SoldierNumber <= 0) { await game.CharacterLogAsync("守備には、最低でも 1 人以上の兵士が必要です"); } else { var town = townOptional.Data; if (town.CountryId != character.CountryId) { await game.CharacterLogAsync("自国の都市以外を守備することはできません"); } else { character.Contribution += 25; character.AddLeadershipEx(50); character.SkillPoint++; var def = await repo.Town.SetDefenderAsync(character.Id, town.Id); await game.CharacterLogAsync("<town>" + town.Name + "</town> の守備につきました"); def.Status = TownDefenderStatus.Available; var townCharas = await repo.Town.GetCharactersAsync(town.Id); await StatusStreaming.Default.SendCountryAsync(ApiData.From(def), character.CountryId); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(def), townCharas.Where(tc => tc.Id != character.Id && tc.CountryId != character.CountryId).Select(tc => tc.Id)); var wars = await repo.CountryDiplomacies.GetAllWarsAsync(); if (wars.Any(w => (w.InsistedCountryId == character.CountryId || w.RequestedCountryId == character.CountryId) && (w.Status != CountryWarStatus.None && w.Status != CountryWarStatus.Stoped)) && RandomService.Next(0, 128) == 0) { var info = await ItemService.PickTownHiddenItemAsync(repo, character.TownId, character); if (info.HasData) { await game.CharacterLogAsync($"<town>{town.Name}</town> に隠されたアイテム {info.Data.Name} を手に入れました"); } } } } }
public async Task <ApiArrayData <ChatMessage> > GetCountryChatMessagesAsync( [FromQuery] uint sinceId = default, [FromQuery] int count = default) { IEnumerable <ChatMessage> messages; using (var repo = MainRepository.WithRead()) { var chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); messages = await repo.ChatMessage.GetCountryMessagesAsync(chara.CountryId, sinceId, count); } return(ApiData.From(messages)); }
public static async Task <CharacterLog> AddCharacterLogAsync(MainRepository repo, GameDateTime current, uint id, string message) { var log = new CharacterLog { GameDateTime = current, DateTime = DateTime.Now, CharacterId = id, Message = message, }; await repo.Character.AddCharacterLogAsync(log); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(log), id); return(log); }
public async Task <ApiData <AuthenticationData> > Entry( [FromBody] EntryData param) { var ip = this.HttpContext.Connection.RemoteIpAddress?.ToString(); using (var repo = MainRepository.WithReadAndWrite()) { await EntryService.EntryAsync(repo, ip, param.Character, param.Icon, param.Password, param.Country, param.InvitationCode, param.IsCountryFree); await repo.SaveChangesAsync(); var authData = await AuthenticationService.WithIdAndPasswordAsync(repo, param.Character.AliasId, param.Password, ip); return(ApiData.From(authData)); } }
public async Task DischargeUnitMemberAsync( [FromRoute] uint unitId, [FromRoute] uint charaId) { using (var repo = MainRepository.WithReadAndWrite()) { var old = await repo.Unit.GetByIdAsync(unitId); if (!old.HasData) { ErrorCode.UnitNotFoundError.Throw(); } var unit = old.Data; var members = await repo.Unit.GetMembersAsync(unitId); if (!members.Any(u => u.Post == UnitMemberPostType.Leader && u.CharacterId == this.AuthData.CharacterId)) { ErrorCode.NotPermissionError.Throw(); } if (this.AuthData.CharacterId == charaId) { ErrorCode.InvalidOperationError.Throw(); } UnitService.Leave(repo, charaId); var log = new CharacterLog { CharacterId = charaId, DateTime = DateTime.Now, GameDateTime = (await repo.System.GetAsync()).GameDateTime, Message = $"部隊 {unit.Name} から除隊されました", }; await repo.Character.AddCharacterLogAsync(log); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(log), charaId); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(new ApiSignal { Type = SignalType.UnitDischarged, }), charaId); await repo.SaveChangesAsync(); } }
private static async Task RunCountryPolicyAsync(MainRepository repo, Country country, CountryPolicyType type) { if (type == CountryPolicyType.TotalMobilization || type == CountryPolicyType.TotalMobilization2) { foreach (var chara in await repo.Country.GetCharactersAsync(country.Id)) { chara.SoldierNumber = chara.Leadership; chara.Proficiency = 100; var formation = await repo.Character.GetFormationAsync(chara.Id, chara.FormationType); formation.Experience += 5000; await CharacterService.StreamCharacterAsync(repo, chara); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(formation), chara.Id); } await LogService.AddMapLogAsync(repo, true, EventType.Policy, $"<country>{country.Name}</country> は、国民総動員を発動しました"); } else if (type == CountryPolicyType.TotalMobilizationWall || type == CountryPolicyType.TotalMobilizationWall2) { foreach (var town in await repo.Town.GetByCountryIdAsync(country.Id)) { town.Technology = town.TechnologyMax; town.Wall = town.WallMax; await StatusStreaming.Default.SendTownToAllAsync(ApiData.From(town), repo); } await LogService.AddMapLogAsync(repo, true, EventType.Policy, $"<country>{country.Name}</country> は、城壁作業員総動員を発動しました"); } else if (type == CountryPolicyType.Austerity || type == CountryPolicyType.Austerity2) { foreach (var chara in await repo.Country.GetCharactersAsync(country.Id)) { chara.Money += 20_0000; await CharacterService.StreamCharacterAsync(repo, chara); } await LogService.AddMapLogAsync(repo, true, EventType.Policy, $"<country>{country.Name}</country> は、緊縮財政を発動しました"); } var info = CountryPolicyTypeInfoes.Get(type); if (info.HasData && info.Data.Effects.Any(e => e.Type == CountryPolicyEffectType.SubBuildingSizeMax)) { country.TownSubBuildingExtraSpace += (short)info.Data.Effects .Where(e => e.Type == CountryPolicyEffectType.SubBuildingSizeMax) .Sum(e => e.Value); } }
public static async Task ReleaseCharacterAsync(MainRepository repo, CharacterSkill item, Character chara) { var strong = (short)item.GetSumOfValues(CharacterSkillEffectType.Strong); var intellect = (short)item.GetSumOfValues(CharacterSkillEffectType.Intellect); var leadership = (short)item.GetSumOfValues(CharacterSkillEffectType.Leadership); var popularity = (short)item.GetSumOfValues(CharacterSkillEffectType.Popularity); chara.Strong -= strong; chara.Intellect -= intellect; chara.Leadership -= leadership; chara.Popularity -= popularity; item.Status = CharacterSkillStatus.Undefined; await StatusStreaming.Default.SendCharacterAsync(ApiData.From(chara), chara.Id); await StatusStreaming.Default.SendCharacterAsync(ApiData.From(item), chara.Id); }
public static async Task RequestResetAsync(MainRepository repo, uint unifiedCountryId) { var system = await repo.System.GetAsync(); system.IsWaitingReset = true; system.IsBattleRoyaleMode = false; var currentMonth = system.CurrentMonthStartDateTime; var todayResetHour = new DateTime(currentMonth.Year, currentMonth.Month, currentMonth.Day, 20, 0, 0, 0); var resetHour = todayResetHour.AddDays(currentMonth.Hour < 20 ? 1 : 2); var sinceResetTime = resetHour - currentMonth; var resetTurn = (int)Math.Round(sinceResetTime.TotalMinutes / 10.0f); system.ResetGameDateTime = GameDateTime.FromInt(system.GameDateTime.ToInt() + resetTurn); await RecordHistoryAsync(repo, system, unifiedCountryId); await StatusStreaming.Default.SendAllAsync(ApiData.From(system)); }
private static async Task ReleaseCharacterAsync(MainRepository repo, CharacterItem item, Character chara, CharacterItemStatus newStatus) { if ((item.Status != CharacterItemStatus.CharacterHold && item.Status != CharacterItemStatus.CharacterPending) || (chara != null && item.CharacterId != chara.Id)) { return; } if (chara != null && item.Status == CharacterItemStatus.CharacterHold) { var strong = (short)item.GetSumOfValues(CharacterItemEffectType.Strong); var intellect = (short)item.GetSumOfValues(CharacterItemEffectType.Intellect); var leadership = (short)item.GetSumOfValues(CharacterItemEffectType.Leadership); var popularity = (short)item.GetSumOfValues(CharacterItemEffectType.Popularity); chara.Strong -= strong; chara.Intellect -= intellect; chara.Leadership -= leadership; chara.Popularity -= popularity; } item.Status = newStatus; item.CharacterId = 0; if (newStatus == CharacterItemStatus.TownHidden || newStatus == CharacterItemStatus.TownOnSale) { if (chara == null) { var towns = await repo.Town.GetAllAsync(); item.TownId = RandomService.Next(towns).Id; } else { item.TownId = chara.TownId; } } if (chara != null) { await CharacterService.StreamCharacterAsync(repo, chara); } await StatusStreaming.Default.SendAllAsync(ApiData.From(item)); }
public async Task PostOtherCountryChatMessageAsync( [FromRoute] uint id, [FromBody] ChatMessage param) { var ip = this.HttpContext.Connection.RemoteIpAddress?.ToString(); ChatMessage message; Character chara; if (string.IsNullOrEmpty(param.Message) || param.Message?.Length > 400) { ErrorCode.NumberRangeError.Throw(new ErrorCode.RangeErrorParameter("message", param.Message.Length, 1, 400)); } using (var repo = MainRepository.WithReadAndWrite()) { chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); if (await repo.BlockAction.IsBlockedAsync(chara.Id, BlockActionType.StopCountryChat)) { ErrorCode.BlockedActionError.Throw(); } var to = await repo.Country.GetAliveByIdAsync(id).GetOrErrorAsync(ErrorCode.CountryNotFoundError); var country = await repo.Country.GetAliveByIdAsync(id).GetOrErrorAsync(ErrorCode.CountryNotFoundError); var posts = (await repo.Country.GetPostsAsync(chara.CountryId)).Where(p => p.CharacterId == chara.Id); if (!posts.Any(p => p.Type.CanDiplomacy())) { ErrorCode.NotPermissionError.Throw(); } message = await ChatService.PostChatMessageAsync(repo, param, chara, ip, ChatMessageType.OtherCountry, chara.CountryId, id); await repo.SaveChangesAsync(); } await StatusStreaming.Default.SendCountryAsync(ApiData.From(message), chara.CountryId); await StatusStreaming.Default.SendCountryAsync(ApiData.From(message), id); }
public async Task PostPrivateChatMessageAsync( [FromRoute] uint id, [FromBody] ChatMessage param) { var ip = this.HttpContext.Connection.RemoteIpAddress?.ToString(); ChatMessage message; Character chara; if (string.IsNullOrEmpty(param.Message) || param.Message?.Length > 400) { ErrorCode.NumberRangeError.Throw(new ErrorCode.RangeErrorParameter("message", param.Message.Length, 1, 400)); } using (var repo = MainRepository.WithReadAndWrite()) { chara = await repo.Character.GetByIdAsync(this.AuthData.CharacterId).GetOrErrorAsync(ErrorCode.LoginCharacterNotFoundError); var to = await repo.Character.GetByIdAsync(id).GetOrErrorAsync(ErrorCode.CharacterNotFoundError); if (chara.Id == to.Id) { // 自分に対して個人宛は送れない ErrorCode.MeaninglessOperationError.Throw(); } if (await repo.BlockAction.IsBlockedAsync(chara.Id, BlockActionType.StopPrivateChatWithoutAdministrator)) { if (to.AiType != CharacterAiType.Administrator) { ErrorCode.BlockedActionError.Throw(); } } message = await ChatService.PostChatMessageAsync(repo, param, chara, ip, ChatMessageType.Private, chara.Id, id); await repo.SaveChangesAsync(); } await StatusStreaming.Default.SendCharacterAsync(ApiData.From(message), new uint[] { chara.Id, id, }); }