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);
        }
Exemple #3
0
 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 :(");
            }
        }
Exemple #6
0
        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
            }
        }
Exemple #7
0
 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 :( ");
            }
        }
Exemple #11
0
        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);
                }
            }
        }
Exemple #14
0
        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 :( ");
            }
        }
Exemple #15
0
        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);
                }
            }
        }
Exemple #16
0
        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);
            }
        }
Exemple #17
0
        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();
        }
Exemple #18
0
        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"));
                }
            }
        }
Exemple #19
0
        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 :(");
            }
        }
Exemple #20
0
        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 :( ");
            }
        }