예제 #1
0
        /// <summary>
        /// Increments messageNum.
        /// If greater than/equal to <see cref="AdvertThreshold"/>, send random (advertisement) message from the DB.
        /// </summary>
        /// <param name="args">Message arguments.</param>
        /// <returns>Task.</returns>
        private async Task GeneralSpamAsync(DiscordClient dClient, MessageCreateEventArgs args)
        {
            if (args.Author.IsBot || args.Channel.Id != SBGChannels.General)
            {
                return;
            }

            this.messageCounter += 1;

            if (this.messageCounter >= AdvertThreshold && args.Channel.Id == SBGChannels.General)
            {
                Random rnd = new Random();

                using IServiceScope scope = this.scopeFactory.CreateScope();
                using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();

                int messageCount = db.SpamMessages.Count();
                int random       = rnd.Next(0, messageCount);

                SpamMessage randomMessage = db.SpamMessages.Skip(random).FirstOrDefault();
                this.messageCounter = 0;

                await args.Channel.SendMessageAsync(randomMessage.Value);
            }
        }
예제 #2
0
        public async Task Execute()
        {
            DiscordGuild sbg = await this.dClient.GetGuildAsync(Guilds.SBG);

            DiscordRole ltpRole = sbg.GetRole(SBGRoles.LookingToPlay);

            List <DiscordMember> roleMembers = sbg.Members
                                               .Select(m => m.Value)
                                               .Where(m => m.Roles.Any(r => r.Id == ltpRole.Id))
                                               .ToList();
            List <LTPJoin> prunable;

            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            prunable = db.LTPJoins
                       .Where(l => roleMembers.Select(m => m.Id).Contains(l.UserId) && l.Timestamp <= DateTime.UtcNow.AddDays(-MaxDuration))
                       .ToList();

            foreach (DiscordMember member in roleMembers)
            {
                if (!prunable.Any(p => p.UserId == member.Id))
                {
                    continue;
                }

                await member.RevokeRoleAsync(ltpRole);

                this.bloonLog.Information(LogConsole.RoleEdits, ManageRoleEmojis.Demotion, $"**Role Demotion**: {member.Username} - LTP");
            }

            db.LTPJoins.RemoveRange(prunable);
            await db.SaveChangesAsync();
        }
예제 #3
0
        /// <summary>
        /// Track SBA activity for the inactivity job.
        /// </summary>
        /// <param name="args">Message arguments.</param>
        /// <returns>Task.</returns>
        private async Task TrackSBAAsync(DiscordClient dClient, MessageCreateEventArgs args)
        {
            if (args.Author.IsBot || args.Channel.Id != SBGChannels.SecretBaseAlpha)
            {
                return;
            }

            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            SBAInactivityTracking tracking = db.SBAInactivityTracking
                                             .Where(s => s.UserId == args.Author.Id)
                                             .FirstOrDefault();

            if (tracking == null)
            {
                tracking = new SBAInactivityTracking()
                {
                    UserId = args.Author.Id,
                };

                db.Add(tracking);
            }

            tracking.LastMessage = DateTime.UtcNow;
            await db.SaveChangesAsync();
        }
예제 #4
0
        private async Task OnGuildMemberAdded(DiscordClient dClient, GuildMemberAddEventArgs args)
        {
            if (args.Guild.Id != Guilds.SBG || args.Member.IsBot)
            {
                return;
            }

            IServiceScope scope   = this.scopeFactory.CreateScope();
            BloonContext  db      = scope.ServiceProvider.GetRequiredService <BloonContext>();
            List <ulong>  roleIds = await db.RoleMembers.AsNoTracking()
                                    .Where(r => r.MemberId == args.Member.Id)
                                    .Select(r => r.RoleId)
                                    .ToListAsync();

            List <string> addedRoleNames = new List <string>();

            for (int i = 0; i < roleIds.Count; i++)
            {
                if (args.Guild.Roles.TryGetValue(roleIds[i], out DiscordRole role) && role.Position < args.Guild.CurrentMember.Hierarchy)
                {
                    addedRoleNames.Add(role.Name);
                    await args.Member.GrantRoleAsync(role);
                }
            }

            if (addedRoleNames.Count == 0)
            {
                return;
            }

            await args.Guild.GetChannel(SBGChannels.Bloonside)
            .SendMessageAsync($"Granted **{string.Join(", ", addedRoleNames)}** to **{args.Member.Username}**.");
        }
예제 #5
0
        private async Task OnGuildBanAdded(DiscordClient dClient, GuildBanAddEventArgs args)
        {
            if (args.Guild.Id != Guilds.SBG)
            {
                return;
            }

            IServiceScope scope = this.scopeFactory.CreateScope();
            BloonContext  db    = scope.ServiceProvider.GetRequiredService <BloonContext>();
            await db.Database.ExecuteSqlRawAsync("DELETE FROM `role_member` WHERE `id` = {0}", args.Member.Id);
        }
예제 #6
0
        public override Task Enable()
        {
            using IServiceScope scope = this.provider.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            this.censorer.Init(db.Censors.ToList());
            this.cNext.RegisterCommands <CensorCommands>();
            this.dClient.MessageCreated       += this.CensorAsync;
            this.dClient.MessageReactionAdded += this.ProfanityFilterRemove;

            return(base.Enable());
        }
예제 #7
0
        public override Task Enable()
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            List <Faq> dbFaqs = db.Faqs.ToList();

            this.faqManager.Init(dbFaqs);
            //this.cNext.RegisterCommands<FAQCommands>();
            this.dClient.MessageCreated += this.ProcessFAQAsync;

            return(base.Enable());
        }
예제 #8
0
        public async Task InitializeAsync()
        {
            using IServiceScope scope = this.provider.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            List <FeatureStatus> featureStatuses = await db.FeatureStatuses
                                                   .ToListAsync();

            foreach (Type type in Assembly.GetEntryAssembly()
                     .GetTypes()
                     .Where(t => typeof(Feature).IsAssignableFrom(t) &&
                            !t.IsInterface &&
                            !t.IsAbstract)
                     .OrderBy(t => t.Name))
            {
                Feature feature = ActivatorUtilities.CreateInstance(this.provider, type) as Feature;

                if (this.features.Any(f => f.Name == feature.Name))
                {
                    throw new DuplicateNameException($"Duplicate feature name \"{feature.Name}\" for \"{type.Name}\"!");
                }

                FeatureStatus featureStatus = featureStatuses.Where(m => m.Name == feature.Name).FirstOrDefault();

                if (featureStatus == null)
                {
                    featureStatus = new FeatureStatus
                    {
                        Name    = feature.Name,
                        Enabled = true,
                    };

                    if (!feature.Protected)
                    {
                        db.FeatureStatuses.Add(featureStatus);
                    }
                }

                Log.Information("Loaded feature {0} - {1}", feature.Name.PadRight(32), featureStatus.Enabled);

                await feature.Initialize();

                if (featureStatus.Enabled)
                {
                    this.featuresToEnable.Add(feature);
                }

                this.features.Add(feature);
            }

            await db.SaveChangesAsync();
        }
예제 #9
0
        private async Task OnGuildMembersChunked(DiscordClient dClient, GuildMembersChunkEventArgs args)
        {
            if (args.Guild.Id != Guilds.SBG)
            {
                return;
            }

            IServiceScope scope = this.scopeFactory.CreateScope();
            BloonContext  db    = scope.ServiceProvider.GetRequiredService <BloonContext>();

            List <RoleMember> roleMembers = await db.RoleMembers
                                            .Where(r => args.Members.Select(m => m.Id).Contains(r.MemberId))
                                            .ToListAsync();

            db.RoleMembers.RemoveRange(roleMembers);

            foreach (DiscordMember member in args.Members)
            {
                IEnumerable <DiscordRole> roles = member.Roles.Where(r => ShouldPersist(args.Guild, r));

                if (!roles.Any() || member.IsBot)
                {
                    continue;
                }

                foreach (DiscordRole role in roles)
                {
                    RoleMember roleMember = roleMembers.Where(r => r.MemberId == member.Id && r.RoleId == role.Id)
                                            .FirstOrDefault();

                    if (roleMember != null)
                    {
                        db.Entry(roleMember).State = EntityState.Unchanged;
                    }
                    else
                    {
                        db.RoleMembers.Add(new RoleMember
                        {
                            MemberId = member.Id,
                            RoleId   = role.Id,
                        });
                    }
                }
            }

            await db.SaveChangesAsync();
        }
예제 #10
0
        public async Task <bool> TryStoreNewAsync(YouTubeVideo video)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            if (db.YoutubeVideos.Any(x => x.UID == video.UID))
            {
                Log.Information("No new YouTube videos");
                return(false);
            }

            Log.Information("[YOUTUBE] New Video!");

            db.YoutubeVideos.Add(video);
            await db.SaveChangesAsync();

            return(true);
        }
예제 #11
0
        /// <summary>
        /// Attempt to store the new helprace post in the DB. If entry exists with matching ID, don't store it.
        /// </summary>
        /// <param name="entry">A helprace post.</param>
        /// <returns>True or false if it stored it or not.</returns>
        public async Task <bool> TryStoreNewAsync(HelpracePost entry)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            if (db.HelpracePosts.Any(x => x.UID == entry.UID))
            {
                Log.Information("No new helprace posts");
                return(false);
            }

            Log.Information("[HELPRACE] Found new post. Adding {0}. Author: {1}", entry.UID, entry.Author);

            db.HelpracePosts.Add(entry);
            await db.SaveChangesAsync();

            return(true);
        }
예제 #12
0
        public async Task <bool> TryStoreNewAsync(WikiArticle entry)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            if (db.WikiArticles.Any(x => x.UID == entry.UID))
            {
                Log.Information("No new wiki posts found");
                return(false);
            }

            Log.Information("[WIKI] Post Found!");

            db.WikiArticles.Add(entry);
            await db.SaveChangesAsync();

            return(true);
        }
예제 #13
0
        public async Task <bool> TryStoreNewAsync(SocialItemWorkshopMap map)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            if (db.SocialItemWorkshopMap.Any(x => x.UID == map.UID))
            {
                Log.Information("No new Workshop maps");
                return(false);
            }

            Log.Information("[WORKSHOP] New Map!");

            db.SocialItemWorkshopMap.Add(map);
            await db.SaveChangesAsync();

            return(true);
        }
예제 #14
0
        public async Task <bool> TryStoreNewAsync(SteamNewsPost post)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            if (db.SteamNewsPosts.Any(x => x.UID == post.UID))
            {
                Log.Information("No new Steam posts");
                return(false);
            }

            Log.Information("[STEAM] New POST!");

            db.SteamNewsPosts.Add(post);
            await db.SaveChangesAsync();

            return(true);
        }
예제 #15
0
        private Task ManageNowPlayingAsync(DiscordClient dClient, PresenceUpdateEventArgs args)
        {
            _ = Task.Run(async() =>
            {
                // Ignore non-SBG events
                if (args.PresenceAfter.Guild.Id != Variables.Guilds.SBG)
                {
                    return;
                }

                bool wasPlaying = args.PresenceBefore?.Activities.Any(a => a.Name == "Intruder") ?? false;
                bool nowPlaying = args.PresenceAfter.Activities.Any(a => a.Name == "Intruder");

                if ((!wasPlaying && !nowPlaying) || (wasPlaying && nowPlaying))
                {
                    return;
                }

                DiscordRole nowPlayingRole = args.PresenceAfter.Guild.GetRole(SBGRoles.NowPlaying);
                DiscordMember member       = await args.PresenceAfter.Guild.GetMemberAsync(args.UserAfter.Id);

                // User started playing Intruder
                if (!wasPlaying && nowPlaying)
                {
                    await member.GrantRoleAsync(nowPlayingRole);
                    using IServiceScope scope = this.scopeFactory.CreateScope();
                    using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
                    LTPJoin join = db.LTPJoins.Where(l => l.UserId == args.UserAfter.Id).FirstOrDefault();

                    if (join != null)
                    {
                        join.Timestamp = DateTime.UtcNow;
                        await db.SaveChangesAsync();
                    }
                }

                // User stopped playing Intruder
                else if (wasPlaying && (!nowPlaying || args.PresenceAfter.Status == UserStatus.Invisible || args.PresenceAfter.Status == UserStatus.Offline))
                {
                    await member.RevokeRoleAsync(nowPlayingRole);
                }
            });

            return(Task.CompletedTask);
        }
예제 #16
0
        public async Task UpdateFeatureStatusAsync(string featureName, bool enabled)
        {
            using IServiceScope scope = this.provider.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            FeatureStatus featureStatus = await db.FeatureStatuses
                                          .Where(m => m.Name == featureName)
                                          .FirstOrDefaultAsync();

            if (featureStatus == null)
            {
                featureStatus = new FeatureStatus
                {
                    Name = featureName,
                };

                db.FeatureStatuses.Add(featureStatus);
            }

            featureStatus.Enabled = enabled;

            await db.SaveChangesAsync();
        }
예제 #17
0
        /// <summary>
        /// Try and store the Tweet in the database.
        /// </summary>
        /// <param name="tweet">Tweet.</param>
        /// <returns>Bool, if new or not.</returns>
        public async Task <bool> TryStoreNewAsync(Status tweet)
        {
            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            if (db.Tweets.Any(x => x.UID == tweet.StatusID.ToString(CultureInfo.CurrentCulture)))
            {
                Log.Information("No new tweets");
                return(false);
            }

            Log.Information("[TWITTER] New Tweet!");

            db.Tweets.Add(new Tweet()
            {
                UID       = tweet.StatusID.ToString(CultureInfo.CurrentCulture),
                Author    = tweet.User.Name,
                Title     = tweet.FullText,
                Timestamp = tweet.CreatedAt.ToUniversalTime(),
            });
            await db.SaveChangesAsync();

            return(true);
        }
예제 #18
0
        private async Task OnGuildMemberUpdated(DiscordClient dClient, GuildMemberUpdateEventArgs args)
        {
            if (args.Guild.Id != Guilds.SBG || args.RolesBefore.Count == args.RolesAfter.Count || args.Member.IsBot)
            {
                return;
            }

            bool roleAssigned = args.RolesBefore.Count < args.RolesAfter.Count;
            IEnumerable <DiscordRole> modifiedRoles = roleAssigned
                ? args.RolesAfter.Except(args.RolesBefore)
                : args.RolesBefore.Except(args.RolesAfter);

            IServiceScope scope = this.scopeFactory.CreateScope();
            BloonContext  db    = scope.ServiceProvider.GetRequiredService <BloonContext>();

            foreach (DiscordRole role in modifiedRoles.Where(m => ShouldPersist(args.Guild, m)))
            {
                RoleMember roleMember = await db.RoleMembers.Where(r => r.MemberId == args.Member.Id && r.RoleId == role.Id)
                                        .FirstOrDefaultAsync();

                if (roleMember == null && roleAssigned)
                {
                    db.RoleMembers.Add(new RoleMember
                    {
                        MemberId = args.Member.Id,
                        RoleId   = role.Id,
                    });
                }
                else if (roleMember != null && !roleAssigned)
                {
                    db.RoleMembers.Remove(roleMember);
                }
            }

            await db.SaveChangesAsync();
        }
예제 #19
0
 public FAQCommands(BloonContext db, FAQManager faqManager)
 {
     this.db         = db;
     this.faqManager = faqManager;
 }
예제 #20
0
 public LTPSlashCommand(BloonContext db)
 {
     this.db = db;
 }
예제 #21
0
        /// <summary>
        /// Finds the latest, new updated RedditPost. Should trigger whenever Guardbot can see the post.
        /// </summary>
        /// <param name="posts">Reddit Posts.</param>
        /// <returns>Reddit Embed containing Newly Discovered Post.</returns>
        private async Task NewUpdatedAsync(List <Post> posts)
        {
            if (posts.Count == 0)
            {
                Log.Information($"[REDDIT] No news posts!");
                return;
            }

            Log.Information("[REDDIT] Received {0} new post(s)!", posts.Count);

            DiscordChannel sbgGen = await this.dClient.GetChannelAsync(SBGChannels.General);

            foreach (Post post in posts)
            {
                if (post.Author == "GuardBloon")
                {
                    continue;
                }

                string postUrl = "https://reddit.com" + post.Permalink;

                DiscordEmbed redditEmbed = new DiscordEmbedBuilder
                {
                    Author = new DiscordEmbedBuilder.EmbedAuthor()
                    {
                        Name = post.Author,
                        Url  = postUrl,
                    },
                    Footer = new DiscordEmbedBuilder.EmbedFooter()
                    {
                        IconUrl = DiscordEmoji.FromGuildEmote(this.dClient, PlatformEmojis.Reddit).Url,
                        Text    = "/r/Intruder",
                    },
                    Color       = new DiscordColor(255, 69, 0),
                    Timestamp   = post.Created.ToUniversalTime(),
                    Description = $"[{post.Title}]({postUrl})",
                };

                using IServiceScope scope = this.scopeFactory.CreateScope();
                using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
                db.RedditPosts.Add(new RedditPost()
                {
                    UID       = post.Id,
                    Author    = post.Author,
                    Timestamp = post.Created.ToUniversalTime(),
                    Title     = post.Title,
                });

                await db.SaveChangesAsync();

                if (string.IsNullOrEmpty(post.Listing.Thumbnail) ||
                    post.Listing.Thumbnail == "self" ||
                    post.Listing.Thumbnail == "default")
                {
                    await sbgGen.SendMessageAsync(embed : redditEmbed);
                }
                else
                {
                    DiscordChannel sbgPNV = await this.dClient.GetChannelAsync(SBGChannels.PicsNVids);

                    redditEmbed = new DiscordEmbedBuilder(redditEmbed)
                    {
                        Thumbnail = new DiscordEmbedBuilder.EmbedThumbnail
                        {
                            Url = post.Listing.Thumbnail,
                        },
                    };

                    await sbgPNV.SendMessageAsync(embed : redditEmbed);
                }
            }

            Log.Information($"[REDDIT] Finished processing new posts!");
        }
예제 #22
0
 public CensorCommands(BloonContext db, Censorer censorer)
 {
     this.db       = db;
     this.censorer = censorer;
 }
예제 #23
0
        private async void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            List <ITimedJob> timedJobs = new List <ITimedJob>();

            using IServiceScope scope = this.factory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            List <Job> dbJobs = db.Jobs.ToList();

            foreach (ITimedJob timedJob in this.jobs)
            {
                string jobName = timedJob.GetType().FullName !;

                Job job = dbJobs.Where(j => j.Name == jobName).FirstOrDefault();

                if (job == null)
                {
                    job = new Job()
                    {
                        Name          = jobName,
                        LastExecution = DateTime.UnixEpoch.ToUniversalTime(),
                    };

                    db.Jobs.Add(job);
                }

                if ((DateTime.UtcNow - job.LastExecution).TotalMinutes >= timedJob.Interval)
                {
                    timedJobs.Add(timedJob);
                    job.LastExecution = DateTime.UtcNow;
                }
            }

            await db.SaveChangesAsync();

            if (timedJobs.Count > 0)
            {
                Task jobs = Task.WhenAll(timedJobs.Select(t => t.Execute()));

                try
                {
                    await jobs;
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    if (jobs.Exception != null)
                    {
                        for (int i = 0; i < jobs.Exception.InnerExceptions.Count; i++)
                        {
                            this.bloonLog.Error($"{jobs.Exception.InnerExceptions[i].ToString().Truncate(1500)}");
                        }
                    }
                    else
                    {
                        this.bloonLog.Error($"{ex.ToString().Truncate(1500)}");
                    }

                    Log.Error(jobs.Exception, "One or more jobs failed.");
                }

                // this.bloonLog.Information(LogConsole.Jobs, SBGEmojis.Bloon, $"Jobs finished:\n- {string.Join("\n- ", timedJobs.Select(j => $"{DiscordEmoji.FromGuildEmote(this.dClient, j.Emoji)} {j.GetType().Name}"))}");
            }
        }
예제 #24
0
 public LTPCommands(BloonContext db)
 {
     this.db = db;
 }
예제 #25
0
 public GeneralSlashCommands(BloonContext db)
 {
     this.db = db;
 }
예제 #26
0
        public async Task Execute()
        {
            DiscordGuild sbg = await this.dClient.GetGuildAsync(Guilds.SBG);

            DiscordRole    sbaRole    = sbg.GetRole(SBGRoles.SBA);
            DiscordChannel sbaChannel = await this.dClient.GetChannelAsync(SBGChannels.SecretBaseAlpha);

            List <DiscordMember> roleMembers = sbg.Members
                                               .Select(m => m.Value)
                                               .Where(m => m.Roles.Any(r => r.Id == sbaRole.Id))
                                               .ToList();
            Dictionary <ulong, SBAInactivityTracking> tracked;

            using IServiceScope scope = this.scopeFactory.CreateScope();
            using BloonContext db     = scope.ServiceProvider.GetRequiredService <BloonContext>();
            tracked = db.SBAInactivityTracking
                      .Where(s => roleMembers.Select(m => m.Id).Contains(s.UserId))
                      .ToDictionary(x => x.UserId, x => x);

            // Check each user within the guild with the SBA role. Wonder if this cares if the user is online or not?
            foreach (DiscordMember user in roleMembers)
            {
                if (!tracked.ContainsKey(user.Id))
                {
                    this.bloonLog.Information(LogConsole.RoleEdits, ManageRoleEmojis.Warning, $"**Inactivity Error**: No stored message for {user.Username} - SBA");
                    continue;
                }

                SBAInactivityTracking trackedUser = tracked[user.Id];

                double daysInactive = (DateTime.UtcNow - trackedUser.LastMessage).TotalDays;

                if (daysInactive < 14)
                {
                    continue;
                }

                double daysSinceLastWarning = trackedUser.WarningTimestamp.HasValue ? (DateTime.UtcNow - trackedUser.WarningTimestamp.Value).TotalDays : -1;

                // Last chance
                if (daysSinceLastWarning == -1 || daysSinceLastWarning >= 14)
                {
                    string dmMessage = "Hello agent,\n"
                                       + "It seems you haven't been active in the SuperbossGames Discord for over 2 weeks.\n"
                                       + "The 'Secret Base Alpha' role and access levels will be removed if you remain inactive!\n"
                                       + $"Last activity: {trackedUser.LastMessage.ToString("D", CultureInfo.InvariantCulture)}";

                    await this.SendDM(user, dmMessage, false);

                    this.bloonLog.Information(LogConsole.RoleEdits, ManageRoleEmojis.Warning, $"**Inactivity Warning**: {user.Username} - SBA");

                    trackedUser.WarningTimestamp = DateTime.Now;
                    db.Update(trackedUser);
                }

                // Too late
                else if (daysInactive >= 21 && daysSinceLastWarning >= 7)
                {
                    await user.RevokeRoleAsync(sbaRole);

                    string dmMessage = "Hello again,\n"
                                       + "Your 'Secret Base Alpha' role and access levels have been removed due to inactivity!\n"
                                       + "I'm truly sorry, but I have my orders.\n\n"
                                       + "P.S. I did warn you";
                    await this.SendDM(user, dmMessage, true);

                    db.Remove(trackedUser);

                    this.bloonLog.Information(LogConsole.RoleEdits, ManageRoleEmojis.Demotion, $"**Inactivity Role Demotion**: {user.Username} - SBA");
                }

                await db.SaveChangesAsync();
            }
        }
예제 #27
0
 public Z26Commands(BloonContext db)
 {
     this.db = db;
 }