public async Task <GZipStream> GetNationStatesDumpStream(NationStatesDumpType type) { var eventId = LogEventIdProvider.GetRandomLogEventId(); try { string url = "https://www.nationstates.net/pages/"; if (type == NationStatesDumpType.Nations) { url += "nations.xml.gz"; _logger.LogInformation(eventId, LogMessageBuilder.Build(eventId, "Retrieval of latest Nation dump requested")); } else if (type == NationStatesDumpType.Regions) { url += "regions.xml.gz"; _logger.LogInformation(eventId, LogMessageBuilder.Build(eventId, "Retrieval of latest Region dump requested")); } else { throw new NotImplementedException($"Retrieval for DumpType {type} not implemented yet."); } var stream = await ExecuteRequestWithStreamResult(url, eventId); var compressed = new GZipStream(stream, CompressionMode.Decompress); return(compressed); } finally { LogEventIdProvider.ReleaseEventId(eventId); } }
private Task DiscordClient_Log(LogMessage arg) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.DiscordLogEvent); string message = LogMessageBuilder.Build(id, $"[{arg.Source}] {arg.Message}"); switch (arg.Severity) { case LogSeverity.Critical: _logger.LogCritical(id, message); break; case LogSeverity.Error: _logger.LogError(id, message); break; case LogSeverity.Warning: _logger.LogWarning(id, message); break; case LogSeverity.Info: _logger.LogInformation(id, message); break; default: _logger.LogDebug(id, $"Severity: {arg.Severity.ToString()} {message}"); break; } return(Task.CompletedTask); }
public DumpDataService(ILogger <DumpDataService> logger, NationStatesApiService apiService) { _logger = logger; _apiService = apiService; defaultEventId = LogEventIdProvider.GetEventIdByType(LoggingEvent.DumpDataServiceAction); _logger.LogInformation(defaultEventId, GetLogMessage("--- DumpDataService started ---")); }
public DumpDataService(ILogger <DumpDataService> logger, NationStatesApiService apiService, IOptions <AppSettings> config) { _logger = logger; _apiService = apiService; _appconf = config.Value; _defaultEventId = LogEventIdProvider.GetEventIdByType(LoggingEvent.DumpDataServiceAction); _logger.LogInformation(_defaultEventId, GetLogMessage("--- DumpDataService started ---")); }
public async Task GetBasicStats(params string[] args) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.GetRegionStats); try { string regionName = string.Join(" ", args); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"BasicRegionStats for {regionName} requested.")); XmlDocument regionStats = await dataService.GetRegionStatsAsync(regionName, id); if (regionStats != null) { var name = regionStats.GetElementsByTagName("NAME")[0].InnerText; var numnations = regionStats.GetElementsByTagName("NUMNATIONS")[0].InnerText; var wadelegate = regionStats.GetElementsByTagName("DELEGATE")[0].InnerText; var founder = regionStats.GetElementsByTagName("FOUNDER")[0].InnerText; var founded = regionStats.GetElementsByTagName("FOUNDED")[0].InnerText; var flagUrl = regionStats.GetElementsByTagName("FLAG")[0].InnerText; var power = regionStats.GetElementsByTagName("POWER")[0].InnerText; var tags = regionStats.GetElementsByTagName("TAGS")[0].ChildNodes; var tagList = ""; for (int i = 0; i < tags.Count; i++) { tagList += BaseApiService.FromID(tags.Item(i).InnerText) + ", "; } tagList = tagList.Remove(tagList.Length - 2); var regionUrl = $"https://www.nationstates.net/region={BaseApiService.ToID(regionName)}"; var builder = new EmbedBuilder(); builder.WithThumbnailUrl(flagUrl); builder.WithTitle($"BasicStats for Region"); builder.WithDescription($"**[{name}]({regionUrl})** {Environment.NewLine}" + $"[{numnations} nations]({regionUrl}/page=list_nations) | {founded} | Power: {power}"); builder.AddField("Founder", $"[{await GetFullNationName(founder, id)}](https://www.nationstates.net/nation={BaseApiService.ToID(founder)})"); builder.AddField("Delegate", await GetDelegateNationString(wadelegate, id)); builder.WithFooter($"NationStatesApiBot {AppSettings.VERSION} by drehtisch"); builder.WithColor(new Color(_rnd.Next(0, 256), _rnd.Next(0, 256), _rnd.Next(0, 256))); await ReplyAsync(embed : builder.Build()); } else { var builder = new EmbedBuilder(); builder.WithTitle($"Something went wrong."); builder.WithDescription("Probably no such region."); await ReplyAsync(embed : builder.Build()); } } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "A critical error occured.")); await ReplyAsync("Something went wrong. Sorry :("); } }
private async Task EnsurePoolFilledAsync() { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.EnsurePoolFilled); List <REGION> regionsToRecruitFrom = await GetRegionToRecruitFromAsync(id); while (IsRecruiting) { bool fillingUp = false; int counter = 0; int pendingCount = NationManager.GetNationCountByStatusName("pending"); while (pendingCount < _config.MinimumRecruitmentPoolSize) { if (!fillingUp) { fillingUp = true; _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Filling up pending pool now from {pendingCount} to {_config.MinimumRecruitmentPoolSize}")); } PoolStatus = "Filling up with random nations"; var regionId = _rnd.Next(regionsToRecruitFrom.Count); var region = regionsToRecruitFrom.ElementAt(regionId); string nationName; do { var nationId = _rnd.Next(region.NATIONNAMES.Count); nationName = region.NATIONNAMES.ElementAt(nationId); }while (await NationManager.IsNationPendingSkippedSendOrFailedAsync(nationName) || await IsNationRecruitableAsync(new Nation() { Name = nationName, StatusTime = DateTime.UtcNow }, id)); var nation = await NationManager.GetNationAsync(nationName); if (nation != null) { await NationManager.SetNationStatusToAsync(nation, "pending"); } else { await NationManager.AddUnknownNationsAsPendingAsync(new List <string>() { nationName }, true); } counter++; pendingCount = NationManager.GetNationCountByStatusName("pending"); _logger.LogDebug(id, LogMessageBuilder.Build(id, $"Added nation '{nationName}' to pending. Now at {pendingCount} from minimum {_config.MinimumRecruitmentPoolSize}.")); } if (fillingUp) { _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Filled up pending pool to minimum. (Added {counter} nations to pending.)")); PoolStatus = "Waiting for new nations"; } await Task.Delay(1800000); //30 min } }
public RecruitmentService(ILogger <RecruitmentService> logger, IOptions <AppSettings> appSettings, NationStatesApiService apiService, DumpDataService dumpDataService) { _logger = logger; _config = appSettings.Value; _apiService = apiService; _dumpDataService = dumpDataService; _defaulEventId = LogEventIdProvider.GetEventIdByType(LoggingEvent.APIRecruitment); _rnd = new Random(); if (!_config.EnableRecruitment) { RecruitmentStatus = "Disabled"; } }
public async Task <List <Nation> > GetRecruitableNationsAsync(int number, bool isAPI) { List <Nation> returnNations = new List <Nation>(); var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.GetRecruitableNations); try { _logger.LogDebug(id, LogMessageBuilder.Build(id, $"{number} recruitable nations requested")); List <Nation> pendingNations = new List <Nation>(); if (pendingNations.Count == 0) { pendingNations = NationManager.GetNationsByStatusName("pending"); } while (returnNations.Count < number) { var picked = pendingNations.Take(1); var nation = picked.Count() > 0 ? picked.ToArray()[0] : null; if (nation != null) { if (await IsNationRecruitableAsync(nation, id)) { returnNations.Add(nation); if (IsReceivingRecruitableNations && !isAPI) { currentRNStatus.CurrentCount++; } } pendingNations.Remove(nation); returnNations = returnNations.Distinct().ToList(); } else { if (pendingNations.Count == 0) { _logger.LogCritical(id, "No more nations in pending pool !"); return(returnNations); } else { _logger.LogCritical(id, "Picked nation was null !"); } } } } catch (Exception ex) { _logger.LogError(id, ex, LogMessageBuilder.Build(id, "An error occured.")); } return(returnNations); }
public async Task ProcessMessageAsync(object message) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.UserMessage); try { if (message is SocketUserMessage socketMsg) { var context = new SocketCommandContext(DiscordClient, socketMsg); if (Reactive) { _logger.LogDebug(id, LogMessageBuilder.Build(id, $"{socketMsg.Author.Username} in {socketMsg.Channel.Name}: {socketMsg.Content}")); if (await IsRelevantAsync(message, context.User)) { //Disables Reactiveness of the bot to commands. Ignores every command until waked up using the /wakeup command. if (await _permManager.IsBotAdminAsync(context.User) && socketMsg.Content == $"{_config.SeperatorChar}sleep") { await context.Client.SetStatusAsync(UserStatus.DoNotDisturb); await context.Channel.SendMessageAsync($"Ok! Going to sleep now. Wake me up later with {_config.SeperatorChar}wakeup."); Reactive = false; } else { await commandService.ExecuteAsync(context, 1, Program.ServiceProvider); } } } else { if (await _permManager.IsBotAdminAsync(context.User) && socketMsg.Content == $"{_config.SeperatorChar}wakeup") { Reactive = true; await context.Client.SetStatusAsync(UserStatus.Online); await context.Channel.SendMessageAsync("Hey! I'm back."); } else if (await IsRelevantAsync(message, context.User) && context.Client.Status == UserStatus.DoNotDisturb && !await _permManager.IsBotAdminAsync(context.User)) { await context.Channel.SendMessageAsync(AppSettings.SLEEPTEXT); } } } } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "A critical error occured.")); } }
public async Task DoGetRNStatusAsync() { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.RNSCommand); try { await ReplyAsync(_recruitmentService.GetRNStatus()); } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "A critical error occured")); await ReplyAsync($"Something went wrong :( "); } }
public static async Task RemoveUserFromDbAsync(string userId) { using (var dbContext = new BotDbContext(_config)) { var user = await dbContext.Users.FirstOrDefaultAsync(u => u.DiscordUserId == userId); if (user != null) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.UserDbAction); dbContext.Remove(user); await dbContext.SaveChangesAsync(); logger.LogInformation(id, LogMessageBuilder.Build(id, $"Removed User {userId} from database")); } } }
public async Task <bool> WouldReceiveTelegram(string nationName) { XmlDocument result = await _apiService.GetWouldReceiveTelegramAsync(nationName); if (result != null) { XmlNodeList canRecruitNodeList = result.GetElementsByTagName("TGCANRECRUIT"); return(canRecruitNodeList[0].InnerText == "1"); } else { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.WouldReceiveTelegram); _logger.LogWarning(id, LogMessageBuilder.Build(id, $"Result of GetWouldReceiveTelegramAsync '{nationName}' were null")); return(false); } }
protected async Task <HttpResponseMessage> ExecuteGetRequestAsync(string url, EventId?eventId) { bool releaseId = false; var logId = eventId != null ? (EventId)eventId : LogEventIdProvider.GetRandomLogEventId(); lastAPIRequest = DateTime.UtcNow; if (eventId == null) { releaseId = true; } try { using (var client = new HttpClient()) { _logger.LogDebug(logId, LogMessageBuilder.Build(logId, $"Executing Request to {url}")); client.DefaultRequestHeaders.Add("User-Agent", $"NationStatesApiBot/{AppSettings.VERSION}"); client.DefaultRequestHeaders.Add("User-Agent", $"(contact { _config.Contact};)"); var response = await client.GetAsync(url); if (!response.IsSuccessStatusCode) { _logger.LogError(logId, LogMessageBuilder.Build(logId, $"Request finished with response: {(int) response.StatusCode}: {response.ReasonPhrase}")); } else { _logger.LogDebug(logId, LogMessageBuilder.Build(logId, $"Request finished with response: {(int) response.StatusCode}: {response.ReasonPhrase}")); } if ((int)response.StatusCode == 429) { _logger.LogDebug(logId, LogMessageBuilder.Build(logId, $"Retry in {response.Headers.RetryAfter.Delta} seconds.")); } if (((int)response.StatusCode).ToString().StartsWith("5")) { throw new ApplicationException($"Server Side Error while Executing Request => {(int) response.StatusCode}: {response.ReasonPhrase}"); } return(response); } } finally { if (releaseId) { LogEventIdProvider.ReleaseEventId(logId); } } }
public async Task DoGetRNStatus() { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.RNSCommand); try { if (await _permManager.IsAllowedAsync(PermissionType.ManageRecruitment, Context.User)) { await ReplyAsync(_recruitmentService.GetRNStatus()); } else { await ReplyAsync(AppSettings.PERMISSION_DENIED_RESPONSE); } } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "An critical error occured")); await ReplyAsync($"Something went wrong :( "); } }
public async Task <bool> IsAllowedAsync(PermissionType permissionType, SocketUser user) { if (await IsBotAdminAsync(user)) { return(true); } else { using (var dbContext = new BotDbContext(_config)) { var perms = await GetAllPermissionsToAUserAsync(user.Id.ToString(), dbContext); var result = perms.Select(p => p.Id).Contains((long)permissionType); if (!result) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.PermissionDenied); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Permission: '{permissionType.ToString()}' denied for user with id '{user.Id}'")); } return(result); } } }
private async Task GetNewNationsAsync() { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.GetNewNations); while (IsRecruiting) { try { await _apiService.WaitForActionAsync(NationStatesApiRequestType.GetNewNations); PoolStatus = "Filling up with new nations"; var result = await _apiService.GetNewNationsAsync(id); await AddNationToPendingAsync(id, result, false); PoolStatus = "Waiting for new nations"; } catch (Exception ex) { _logger.LogError(id, ex, LogMessageBuilder.Build(id, "An error occured.")); } await Task.Delay(300000); } }
public async Task RevokePermissionAsync(string discordUserId, Permission permission, BotDbContext dbContext) { var user = await dbContext.Users.FirstOrDefaultAsync(u => u.DiscordUserId == discordUserId); if (user == null) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.UserDbAction); _logger.LogWarning(id, LogMessageBuilder.Build(id, $"Revoke Permission: DiscordUserId '{discordUserId}' not found in DB")); return; } var perm = user.UserPermissions.FirstOrDefault(p => p.Permission.Id == permission.Id); if (perm == null) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.UserDbAction); _logger.LogWarning(id, LogMessageBuilder.Build(id, $"Revoke Permission: Permission.Id '{permission.Id}' not found in user.UserPermissions")); return; } var update = dbContext.Users.Update(user); update.Entity.UserPermissions.Remove(perm); await dbContext.SaveChangesAsync(); }
public static async Task AddUserToDbAsync(string userId) { if (!await IsUserInDbAsync(userId)) //check { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.UserDbAction); using (var dbContext = new BotDbContext(_config)) { var user = new User() { DiscordUserId = userId }; await dbContext.Users.AddAsync(user); await dbContext.SaveChangesAsync(); var defaultUserRole = await dbContext.Roles.FirstOrDefaultAsync(r => r.Description == "Default-User"); if (defaultUserRole == null) { defaultUserRole = new Role() { Description = "Default-User" }; await dbContext.Roles.AddAsync(defaultUserRole); } var userRole = new UserRoles() { User = user, Role = defaultUserRole, RoleId = defaultUserRole.Id }; user.Roles.Add(userRole); dbContext.Users.Update(user); await dbContext.SaveChangesAsync(); logger.LogInformation(id, LogMessageBuilder.Build(id, $"Added User {userId} to database")); } } }
public async Task GetBasicStatsAsync(params string[] args) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.GetRegionStats); try { string regionName = string.Join(" ", args); if (string.IsNullOrWhiteSpace(regionName)) { regionName = _defaultRegionName; } var mention = false; if (DumpDataService.IsUpdating) { await ReplyAsync("Currently updating region information. This may take a few minutes. You will be pinged once the information is available."); mention = true; } _logger.LogInformation(id, LogMessageBuilder.Build(id, $"BasicRegionStats for {regionName} requested.")); XmlDocument regionStats = await _dataService.GetRegionStatsAsync(regionName, id); var region = await _dumpDataService.GetRegionAsync(BaseApiService.ToID(regionName)); if (regionStats != null && region != null) { var name = regionStats.GetElementsByTagName("NAME").Item(0)?.InnerText; var numnations = regionStats.GetElementsByTagName("NUMNATIONS").Item(0)?.InnerText; var wadelegate = regionStats.GetElementsByTagName("DELEGATE").Item(0)?.InnerText; var founder = region.FOUNDER; var founded = regionStats.GetElementsByTagName("FOUNDED").Item(0)?.InnerText; var flagUrl = region.FLAG; var power = regionStats.GetElementsByTagName("POWER").Item(0)?.InnerText; var waNationCount = region.WANATIONS.Count(); var endoCount = region.WANATIONS.Sum(n => n.ENDORSEMENTS.Count); var census = regionStats.GetElementsByTagName("CENSUS").Item(0)?.ChildNodes; var regionalAvgInfluence = census.Item(0)?.ChildNodes.Item(0)?.InnerText; var regionUrl = $"https://www.nationstates.net/region={BaseApiService.ToID(regionName)}"; var builder = new EmbedBuilder { ThumbnailUrl = flagUrl, Title = name, Url = regionUrl }; if (!string.IsNullOrWhiteSpace(founder) && founder != "0") { string founderString = await GetFounderStringAsync(id, founder); builder.AddField("Founder", $"{founderString}", true); } if (!string.IsNullOrWhiteSpace(founded) && founded != "0") { builder.AddField("Founded", $"{founded}", true); } builder.AddField("Nations", $"[{numnations}]({regionUrl}/page=list_nations)", true); if (!string.IsNullOrWhiteSpace(regionalAvgInfluence) && double.TryParse(regionalAvgInfluence, NumberStyles.Number, _locale, out double avgInfluenceValue) && int.TryParse(numnations, out int numnationsValue)) { var powerValue = avgInfluenceValue * numnationsValue; var powerValueString = powerValue > 1000 ? (powerValue / 1000.0).ToString("0.000", _locale) + "k" : powerValue.ToString(_locale); builder.AddField("Regional Power", $"{power} | {powerValueString} Points", true); } else { builder.AddField("Regional Power", $"{power}", true); } var endoCountString = endoCount > 1000 ? (endoCount / 1000.0).ToString("0.000", _locale) + "k" : endoCount.ToString(_locale); builder.AddField("World Assembly*", $"{waNationCount} member{(waNationCount > 1 ? "s" : string.Empty)} | {endoCountString} endos", true); if (!string.IsNullOrWhiteSpace(wadelegate) && wadelegate != "0") { var delegatetuple = await GetDelegateNationStringAsync(wadelegate, id); builder.AddField($"WA Delegate", $"[{delegatetuple.Item1}](https://www.nationstates.net/nation={BaseApiService.ToID(wadelegate)}) | {delegatetuple.Item2}"); } builder.WithFooter(DiscordBotService.FooterString); builder.WithColor(new Color(_rnd.Next(0, 256), _rnd.Next(0, 256), _rnd.Next(0, 256))); builder.AddField("Datasource", "API, * Dump", true); builder.AddField("As of", "Just now, * " + DateTime.UtcNow.Subtract(DumpDataService.LastDumpUpdateTimeUtc).ToString("h'h 'm'm 's's'") + " ago", true); builder.AddField("Next Update in", "On demand, * " + DumpDataService.NextDumpDataUpdate.ToString("h'h 'm'm 's's'"), true); await ReplyAsync(embed : builder.Build()); } else { var builder = new EmbedBuilder(); builder.WithTitle($"Something went wrong."); builder.WithDescription("No API or No Dump data received. Probably no such region."); await ReplyAsync(embed : builder.Build()); } if (mention) { await ReplyAsync($"{Context.User.Mention}"); } } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "A critical error occured.")); await ReplyAsync("Something went wrong. Sorry :("); } }
public async Task DoGetRecruitableNations([Remainder, Summary("Number of nations to be returned")] int number) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.RNCommand); List <Nation> returnNations = new List <Nation>(); try { if (await _permManager.IsAllowedAsync(PermissionType.ManageRecruitment, Context.User)) { if (!_recruitmentService.IsReceivingRecruitableNations) { if (number <= 120) { var currentRN = new RNStatus { IssuedBy = Context.User.Username, FinalCount = number, StartedAt = DateTimeOffset.UtcNow, AvgTimePerFoundNation = TimeSpan.FromSeconds(2) }; _recruitmentService.StartReceiveRecruitableNations(currentRN); await ReplyAsync($"{actionQueued}{Environment.NewLine}{Environment.NewLine}You can request the status of this command using /rns. Finish expected in approx. (mm:ss): {currentRN.ExpectedIn().ToString(@"mm\:ss")}"); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"{number} recruitable nations requested.")); returnNations = await _recruitmentService.GetRecruitableNationsAsync(number, false); foreach (var nation in returnNations) { await NationManager.SetNationStatusToAsync(nation, "reserved_manual"); } StringBuilder builder = new StringBuilder(); builder.AppendLine("-----"); var firstReplyStart = $"<@{Context.User.Id}> Your action just finished.{Environment.NewLine}Changed status of {returnNations.Count} nations from 'pending' to 'reserved_manual'.{Environment.NewLine}Recruitable Nations are (each segment for 1 telegram):{Environment.NewLine}"; int replyCount = (number / 40) + (number % 40 != 0 ? 1 : 0); int currentReply = 1; for (int i = 1; i <= returnNations.Count; i++) { var nation = returnNations[i - 1]; if (i % 8 == 0) { builder.AppendLine($"{nation.Name}"); builder.AppendLine("-----"); } else { builder.Append($"{nation.Name}, "); } if (i % 40 == 0) { if (i / 40 == 1) { await ReplyAsync($"{firstReplyStart} Reply {currentReply}/{replyCount}{Environment.NewLine}{builder.ToString()}"); } else { await ReplyAsync($"Reply {currentReply}/{replyCount}{Environment.NewLine}{builder.ToString()}"); } builder.Clear(); currentReply++; } } if (returnNations.Count < 40) { await ReplyAsync($"{firstReplyStart}{builder.ToString()}"); } else { if (number % 40 != 0) { await ReplyAsync($"Reply {currentReply}/{replyCount}{Environment.NewLine}{builder.ToString()}"); } } if (returnNations.Count < number) { await ReplyAsync($"{Environment.NewLine}- - - - -{Environment.NewLine}WARNING: No more nations in pending nations pool."); } } else { await ReplyAsync($"{number} exceeds the maximum of 120 Nations (15 Telegrams a 8 recipients) to be returned."); } } else { await ReplyAsync($"There is already a /rn command running. Try again later."); } } else { await ReplyAsync(AppSettings.PERMISSION_DENIED_RESPONSE); } } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "An critical error occured")); await ReplyAsync($"Something went wrong :( "); foreach (var nation in returnNations) { await NationManager.SetNationStatusToAsync(nation, "pending"); } } finally { _recruitmentService.StopReceiveRecruitableNations(); } }
public async Task GetBasicStatsAsync(params string[] args) { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.GetNationStats); try { string nationName = string.Join(" ", args); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"BasicNationStats for {nationName} requested.")); XmlDocument nationStats = await _apiDataService.GetNationStatsAsync(nationName, id); if (nationStats != null) { var demonymplural = nationStats.GetElementsByTagName("DEMONYM2PLURAL")[0].InnerText; var category = nationStats.GetElementsByTagName("CATEGORY")[0].InnerText; var flagUrl = nationStats.GetElementsByTagName("FLAG")[0].InnerText; var fullname = nationStats.GetElementsByTagName("FULLNAME")[0].InnerText; var population = nationStats.GetElementsByTagName("POPULATION")[0].InnerText; var region = nationStats.GetElementsByTagName("REGION")[0].InnerText; var founded = nationStats.GetElementsByTagName("FOUNDED")[0].InnerText; var lastActivity = nationStats.GetElementsByTagName("LASTACTIVITY")[0].InnerText; var Influence = nationStats.GetElementsByTagName("INFLUENCE")[0].InnerText; var wa = nationStats.GetElementsByTagName("UNSTATUS")[0].InnerText; var freedom = nationStats.GetElementsByTagName("FREEDOM")[0].ChildNodes; var civilStr = freedom[0].InnerText; var economyStr = freedom[1].InnerText; var politicalStr = freedom[2].InnerText; var census = nationStats.GetElementsByTagName("CENSUS")[0].ChildNodes; var civilRights = census[0].ChildNodes[0].InnerText; var economy = census[1].ChildNodes[0].InnerText; var politicalFreedom = census[2].ChildNodes[0].InnerText; var influenceValue = census[3].ChildNodes[0].InnerText; var endorsementCount = census[4].ChildNodes[0].InnerText; var residency = census[5].ChildNodes[0].InnerText; var residencyDbl = Convert.ToDouble(residency, _locale); var residencyYears = (int)(residencyDbl / 365.242199); var populationdbl = Convert.ToDouble(population); var nationUrl = $"https://www.nationstates.net/nation={BaseApiService.ToID(nationName)}"; var regionUrl = $"https://www.nationstates.net/region={BaseApiService.ToID(region)}"; var builder = new EmbedBuilder(); builder.WithThumbnailUrl(flagUrl); builder.WithTitle($"BasicStats for Nation"); builder.WithDescription($"**[{fullname}]({nationUrl})** {Environment.NewLine}" + $"{(populationdbl / 1000.0 < 1 ? populationdbl : populationdbl / 1000.0).ToString(_locale)} {(populationdbl / 1000.0 < 1 ? "million" : "billion")} {demonymplural} | " + $"Founded {founded} | " + $"Last active {lastActivity}"); builder.AddField("Region", $"[{region}]({regionUrl}) ", true); int residencyDays = (int)(residencyDbl % 365.242199); builder.AddField("Residency", $"Resident for " + $"{(residencyYears < 1 ? "" : $"{residencyYears} year" + $"{(residencyYears > 1 ? "s" : "")}")} " + $"{residencyDays} { (residencyDays != 1 ? $"days" : "day")}", true ); builder.AddField(category, $"C: {civilStr} ({civilRights}) | E: {economyStr} ({economy}) | P: {politicalStr} ({politicalFreedom})"); var waVoteString = ""; if (wa == "WA Member") { var gaVote = nationStats.GetElementsByTagName("GAVOTE")[0].InnerText; var scVote = nationStats.GetElementsByTagName("SCVOTE")[0].InnerText; if (!string.IsNullOrWhiteSpace(gaVote)) { waVoteString += $"GA Vote: {gaVote} | "; } if (!string.IsNullOrWhiteSpace(scVote)) { waVoteString += $"SC Vote: {scVote} | "; } } builder.AddField(wa, $"{waVoteString} {endorsementCount} endorsements | {influenceValue} Influence ({Influence})", true); builder.WithFooter(DiscordBotService.FooterString); builder.WithColor(new Color(_rnd.Next(0, 256), _rnd.Next(0, 256), _rnd.Next(0, 256))); await ReplyAsync(embed : builder.Build()); } else { var builder = new EmbedBuilder(); builder.WithTitle($"Something went wrong."); builder.WithDescription("Probably no such nation."); await ReplyAsync(embed : builder.Build()); } }
public async Task DoGetRecruitableNationsAsync([Remainder, Summary("Number of nations to be returned")] int number) { //await ReplyAsync("The /rn command needed to be disabled because of major issues with the manual recruitment system. Drehtisch will fix those issue asap. Sorry :("); Console.ResetColor(); var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.RNCommand); List <Nation> returnNations = new List <Nation>(); try { if (await _permManager.IsAllowedAsync(PermissionType.ManageRecruitment, Context.User)) { if (!_recruitmentService.IsReceivingRecruitableNations) { try { if (number <= 120) { var currentRN = new RNStatus { IssuedBy = Context.User.Username, FinalCount = number, StartedAt = DateTimeOffset.UtcNow, AvgTimePerFoundNation = TimeSpan.FromSeconds(2) }; var channel = await Context.User.GetOrCreateDMChannelAsync(); _recruitmentService.StartReceiveRecruitableNations(currentRN); await ReplyAsync($"{_actionQueued}{Environment.NewLine}{Environment.NewLine}You can request the status of this command using /rns. Finish expected in approx. (mm:ss): {currentRN.ExpectedIn():mm\\:ss}"); StringBuilder builder = new StringBuilder(); var counter = 0; await foreach (var nation in _recruitmentService.GetRecruitableNationsAsync(number, false, id)) { counter++; builder.Append($"{nation.Name}, "); if (counter % 8 == 0) { await channel.SendMessageAsync(builder.ToString()); builder.Clear(); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Dispatched {counter}/{number} nations to {Context.User.Username}")); } await NationManager.SetNationStatusToAsync(nation, "reserved_manual"); } if (builder.Length > 0) { await channel.SendMessageAsync(builder.ToString()); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Dispatched {counter}/{number} nations to {Context.User.Username}")); } if (counter < number) { await ReplyAsync($"Something went wrong didn't received as much nations as requested."); } } else { await ReplyAsync($"{number} exceeds the maximum of 120 Nations (15 Telegrams a 8 recipients) to be returned."); } } finally { _recruitmentService.StopReceiveRecruitableNations(); } } else { await ReplyAsync($"There is already a /rn command running. Try again later."); } } else { await ReplyAsync(AppSettings._permissionDeniedResponse); } } catch (Exception ex) { _logger.LogCritical(id, ex, LogMessageBuilder.Build(id, "A critical error occured")); await ReplyAsync($"Something went wrong. Sorry :( "); } }