private static async Task <GuildUser> ValidateCanEarnEXP(IUserMessage message, Guild guild) { if (message is null || guild is null || !(message.Author is IGuildUser guildAuthor)) { throw new InvalidOperationException(); } var guildUser = await GuildUsers.GetAsync(guildAuthor); bool inCooldown = await guildUser.XP.GetXPCooldown(); if (guildUser is null || inCooldown || message.Content.Length <= guild.XP.MessageLengthThreshold) { throw new InvalidOperationException("User cannot earn EXP."); } bool channelIsBlacklisted = guild.XP.ExemptChannels.Any(id => id == message.Channel.Id); bool roleIsBlackListed = guild.XP.ExemptRoles.Any(id => guildAuthor.RoleIds.Any(roleId => roleId == id)); if (channelIsBlacklisted || roleIsBlackListed) { throw new InvalidOperationException("Channel or role cannot earn EXP."); } return(guildUser); }
public static async Task CheckRuleAgreement(Guild guild, SocketGuildUser socketGuildUser, SocketReaction reaction) { try { if (socketGuildUser is null || socketGuildUser.IsBot || reaction?.MessageId != guild.Admin.Rulebox.MessageId) { return; } var user = await GuildUsers.GetAsync(socketGuildUser); if (reaction.Emote.Name == guild.Admin.Rulebox.AgreeEmote) { var role = socketGuildUser.Guild.Roles.First(r => r.Id == guild.Admin.Rulebox.Role); await socketGuildUser.AddRoleAsync(role); } else if (reaction.Emote.Name == guild.Admin.Rulebox.DisagreeEmote) { var roles = socketGuildUser.Roles.ToList(); roles.RemoveAt(0); var bot = socketGuildUser.Guild.GetUser(Global.Client.CurrentUser.Id); if (guild.Admin.Rulebox.RemoveRolesOnDisagree && socketGuildUser.Hierarchy <= bot.Hierarchy) { await socketGuildUser.RemoveRolesAsync(roles); } if (guild.Admin.Rulebox.KickOnDisagree && socketGuildUser.Hierarchy <= bot.Hierarchy) { await user.KickAsync($"Please agree to the rules to use `{socketGuildUser.Guild.Name}`.", Global.Client.CurrentUser); } } await GuildUsers.Save(user); } catch (Exception ex) { await Debug.LogErrorAsync("rulebox", ex.StackTrace); } }
public async Task ShowRankEXP(int rank) { try { if (rank <= 0) { throw new ArgumentException("Rank cannot be less than 0"); } var rankedUsers = await GuildUsers.GetRankedGuildUsersAsync(Context.Guild); if (rank > rankedUsers.Count) { throw new ArgumentException("Rank exceeds number of ranked users"); } var target = rankedUsers[rank - 1]; if (target is null) { throw new InvalidOperationException($"User at rank `{rank}` could not be found"); } string imageURL = $"{Global.Config.DashboardURL}/api/servers/{target.Guild.Id}/users/{target.Id}/xp-card"; var stream = await CommandUtils.DownloadData(imageURL); await Context.Channel.SendFileAsync(stream, "server-xp-card.png"); } catch (ArgumentException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public async Task BanUser(SocketGuildUser target, string duration = "1d", [Remainder] string reason = "No reason provided.") { try { var user = await GuildUsers.GetAsync(target); var banDuration = CommandUtils.ParseDuration(duration); if (user.Status.IsBanned) { throw new InvalidOperationException($"User is banned"); } var targetHighest = target.Hierarchy; var senderHighest = (Context.Message.Author as SocketGuildUser).Hierarchy; if (targetHighest >= senderHighest) { throw new InvalidOperationException($"Higher rank user cannot be banned"); } else { await user.BanAsync(banDuration, reason, Context.User); await ReplyAsync(await EmbedHandler.CreateBasicEmbed(ModuleName, $"Banned {target.Mention} for `{duration}` - `{reason}`.", Color.Orange)); } } catch (InvalidOperationException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public static async Task ValidateForEXPAsync(IUserMessage message, Guild guild) { var guildUser = await ValidateCanEarnEXP(message, guild); var user = await Users.GetAsync(message.Author as SocketUser); guildUser.Status.LastMessage = message.Content; guildUser.XP.LastXPMsg = DateTime.Now; int oldLevel = guildUser.XP.Level; guildUser.XP.EXP += guild.XP.EXPPerMessage; int newLevel = guildUser.XP.Level; guildUser.Status.MessageCount++; user.MessageCount++; await GuildUsers.Save(guildUser); await Users.Save(user); if (oldLevel != newLevel) { await SendLevelUpMessageAsync(message, guild, guildUser, oldLevel, newLevel); } }
public static async Task ValidateUsername(Guild guild, SocketGuildUser oldUser) { try { var guildUser = oldUser.Guild.GetUser(oldUser.Id); if (!ContentIsExplicit(guild, guildUser.Nickname) && !ContentIsExplicit(guild, guildUser.Username)) { return; } var user = await GuildUsers.GetAsync(guildUser); if (guild.Moderation.Auto.ResetNickname) { try { await guildUser.ModifyAsync(u => u.Nickname = guildUser.Username); } catch {} } var dmChannel = await guildUser.GetOrCreateDMChannelAsync(); await PunishUser(guild.Moderation.Auto.ExplicitUsernamePunishment, user, "Explicit display name"); await user.WarnAsync("Explicit display name", Global.Client.CurrentUser); } catch (Exception) {} }
public bool RemoveGuildUser(IGuildUser iuser) { var user = FindGuildUser(iuser); if (user == null) { return(false); } GuildUsers.Remove(user); return(true); }
public async Task Test() { var user = await GuildUsers.GetAsync(Context.User as SocketGuildUser); string details = ""; details += TestAnnounce(details); details += TestStaffLogs(details, user); details += TestAutoMod(details, user); await ReplyAsync(details); }
private async Task ResetUser(SocketGuildUser target) { if (target is null) { throw new InvalidOperationException("User not found"); } else { await GuildUsers.ResetAsync(target); await ReplyAsync(await EmbedHandler.CreateBasicEmbed(ModuleName, "User account reset", Color.Orange)); } }
public async Task <GuildUser> GetOrCreateGuildUserAsync(ulong userId, ulong guildId) { if (await GuildUsers.FindAsync(userId, guildId) is { } user) { return(user); } user = new GuildUser(userId, guildId); GuildUsers.Add(user); await SaveChangesAsync(); return(user); }
public async Task UnmuteUser(SocketGuildUser target, [Remainder] string reason = "No reason provided.") { try { var user = await GuildUsers.GetAsync(target); if (!user.Status.IsMuted) { throw new InvalidOperationException($"User is not muted"); } await user.UnmuteAsync(reason, Context.User); await ReplyAsync(await EmbedHandler.CreateBasicEmbed(ModuleName, $"Unmuted {target.Mention} - `{reason}`.", Color.Orange)); } catch (InvalidOperationException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public async Task KickUser(SocketGuildUser target, [Remainder] string reason = "No reason provided.") { try { var user = await GuildUsers.GetAsync(target); if (target.GuildPermissions.Administrator) { throw new InvalidOperationException($"Admins can't be kicked."); } await user.KickAsync(reason, Context.User); await ReplyAsync(await EmbedHandler.CreateBasicEmbed(ModuleName, $"Kicked {target.Mention} - `{reason}`.", Color.Orange)); } catch (InvalidOperationException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public GuildUser GetGuildUser(IGuildUser iuser) { var user = FindGuildUser(iuser); if (user == null) { user = new GuildUser(iuser); user.User = FindUser(iuser); if (user.User == null) { user.User = new User(iuser); Users.Add(user.User); } GuildUsers.Add(user); } return(user); }
public async Task User(SocketGuildUser target = null, [Remainder] string action = "") { try { target ??= Context.User as SocketGuildUser; var user = await GuildUsers.GetAsync(target); if (action == "reset") { await ResetUser(target); return; } var embed = new EmbedBuilder() .WithThumbnailUrl(target.GetAvatarUrl()) .WithColor(Color.Orange) .WithTitle($"**{target.Username}**") .AddField("Warnings", user.Status.WarningsCount, inline: true); embed.AddField("Is Banned", user.Status.IsBanned, inline: true); if (user.Status.IsBanned) { var ban = user.Status.Bans.Last(); embed.AddField("Ban Reason", ban.Reason, inline: true); embed.AddField("Start of Ban", ban.Start, inline: true); embed.AddField("End of Ban", ban.End, inline: true); } embed.AddField("Is Muted", user.Status.IsMuted, inline: true); if (user.Status.IsMuted) { var mute = user.Status.Mutes.Last(); embed.AddField("Mute Reason", mute.Reason, inline: true); embed.AddField("Start of Mute", mute.Start, inline: true); embed.AddField("End of Mute", mute.End, inline: true); } var userInCooldown = await user.XP.GetXPCooldown(); embed.AddField("In XP Cooldown", userInCooldown, inline: true); await ReplyAsync(embed); } catch (ArgumentException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public async Task Leaderboard(int page = 1) { try { var guild = await Guilds.GetAsync(Context.Guild); if (page < 1 || page > guild.XP.MaxLeaderboardPage) { throw new ArgumentException($"Leaderboard page must between 1 and {guild.XP.MaxLeaderboardPage}"); } int usersPerPage = 10; int pageStartIndex = (page * usersPerPage) - usersPerPage; int pageEndIndex = page * usersPerPage; var users = await GuildUsers.GetGuildUsersAsync(Context.Guild); users = users.OrderByDescending(u => u.XP.EXP).ToList(); string details = "\n"; for (int i = pageStartIndex; i < pageEndIndex; i++) { if (i >= users.Count) { details += $"**#{i + 1}** - N/A\n"; continue; } var user = users[i]; var socketGuildUser = Context.Guild.GetUser(user.ID); details += $"**#{i + 1}** - {user.XP.EXP} XP - {socketGuildUser?.Mention ?? "N/A"}\n"; } var embed = new EmbedBuilder(); embed.WithColor(Color.Teal); embed.AddField($"🏆 **{ Context.Guild.Name} Leaderboard **", details, inline: false); embed.AddField("View Leaderboard", $"{Global.Config.DashboardURL}/servers/{Context.Guild.Id}/leaderboard"); embed.WithThumbnailUrl(Context.Guild.IconUrl); embed.WithFooter($"Page {page}/{guild.XP.MaxLeaderboardPage} • Users with XP: {users.Count}"); await ReplyAsync(embed); } catch (ArgumentException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public static async Task OnReactionRemoved(Cacheable <IUserMessage, ulong> before, ISocketMessageChannel channel, SocketReaction reaction) { try { var socketGuildUser = reaction.User.Value as SocketGuildUser; var user = await GuildUsers.GetAsync(socketGuildUser); var guild = await Guilds.GetAsync(socketGuildUser.Guild); if (!socketGuildUser.IsBot && reaction.MessageId == guild.Admin.Rulebox.MessageId && reaction.Emote.Name == guild.Admin.Rulebox.AgreeEmote) { var roles = socketGuildUser.Roles.ToList(); roles.RemoveAt(0); await socketGuildUser.RemoveRolesAsync(roles); } await GuildUsers.Save(user); } catch (Exception ex) { await Debug.LogErrorAsync("rulebox", ex.StackTrace); } }
public static async Task AnnounceUserLeft(SocketGuildUser guildUser) { var user = await GuildUsers.GetAsync(guildUser); if (guildUser as SocketUser == Global.Client.CurrentUser || user.Status.IsBanned) { return; } var guild = await Guilds.GetAsync(guildUser.Guild); string imageURL = $"{Global.Config.DashboardURL}/api/servers/{guildUser.Guild.Id}/users/{guildUser.Id}/goodbye"; var stream = await CommandUtils.DownloadData(imageURL); var channel = guildUser.Guild.GetTextChannel(guild.General.Announce.Goodbyes.Channel) ?? guildUser.Guild.SystemChannel ?? guildUser.Guild.DefaultChannel; await(channel as ISocketMessageChannel)?.SendFileAsync(stream, "goodbye.png"); }
public static async Task ValidateMessage(SocketMessage message) { try { if (message is null || !(message.Author is SocketGuildUser guildAuthor) || guildAuthor.IsBot) { return; } var user = await GuildUsers.GetAsync(guildAuthor); var guild = await Guilds.GetAsync(guildAuthor.Guild); var autoMod = guild.Moderation.Auto; ValidateUserNotExempt(guildAuthor, guild); if (autoMod.SpamNotification) { await SendSpamNotification(message, guildAuthor, guild); } var messageValidation = GetContentValidation(guild, message.Content, user); if (messageValidation != null) { ValidateChannelNotExempt((FilterType)messageValidation, guildAuthor.Guild, guild); ValidateRoleNotExempt((FilterType)messageValidation, guildAuthor, guild); var filter = guild.Moderation.Auto.Filters.FirstOrDefault(f => f.Filter == messageValidation); await PunishUser(filter.Punishment, user, messageValidation.ToString().ToSentenceCase()); try { await message.DeleteAsync(); } // 404 - there may be other auto mod bots -> message already deleted catch {} finally { await user.XP.ExtendXPCooldown(); } } user.Status.LastMessage = message.Content; await GuildUsers.Save(user); } catch (InvalidOperationException) {} catch (Exception) {}//{ await Debug.LogAsync("auto", LogSeverity.Error, ex); } }
public static async Task LogKick(SocketGuildUser discordUser, Punishment kick = null) { try { var user = await GuildUsers.GetAsync(discordUser as SocketGuildUser); kick ??= user?.Status.Kicks.LastOrDefault(); if (kick is null) { return; } var socketGuild = discordUser.Guild; var guild = await Guilds.GetAsync(discordUser.Guild); var log = ValidateLog(guild, socketGuild, LogEvent.Kick); var embed = CreatePunishmentEmbed(kick, discordUser, log.Colour, LogEvent.Kick); await log.Channel.SendMessageAsync(embed : embed); } catch (Exception) {} }
public static async Task LogBan(SocketUser socketUser, SocketGuild socketGuild, Punishment ban = null) { try { if (socketUser is null) { return; } var user = await GuildUsers.GetAsync(socketUser as SocketGuildUser); var guild = await Guilds.GetAsync(socketGuild); var log = ValidateLog(guild, socketGuild, LogEvent.Ban); ban ??= user.Status.Bans.LastOrDefault(); var embed = CreateTimestampPunishmentEmbed(socketUser, ban, log); await log.Channel.SendMessageAsync(embed : embed.Build()); } catch (Exception) {} }
public async Task MuteUser(SocketGuildUser target, string duration = "1d", [Remainder] string reason = "No reason provided.") { try { var user = await GuildUsers.GetAsync(target) ?? new GuildUser(target); var muteDuration = CommandUtils.ParseDuration(duration); if (target.GuildPermissions.Administrator) { throw new InvalidOperationException($"Admins cannot be muted"); } if (!user.Status.IsMuted) { throw new InvalidOperationException($"User is not muted"); } await user.MuteAsync(muteDuration, reason, Context.User); await ReplyAsync(await EmbedHandler.CreateBasicEmbed(ModuleName, $"Muted {target.Mention} for `{duration}` - `{reason}`", Color.Green)); } catch (InvalidOperationException ex) { await ReplyAsync(EmbedHandler.CreateErrorEmbed(ModuleName, ex.Message)); } }
public static async Task LogMessageDeletion(Cacheable <IMessage, ulong> message, ISocketMessageChannel channel) { try { if (!message.HasValue) { return; } var guildAuthor = message.Value.Author as SocketGuildUser; if (guildAuthor is null || guildAuthor.IsBot) { return; } var socketGuild = guildAuthor.Guild; var guild = await Guilds.GetAsync(socketGuild); string prefix = guild.General.CommandPrefix; bool isCommand = message.Value.Content.Substring(0, prefix.Length).Contains(prefix); if (guild.General.RemoveCommandMessages && isCommand || isCommand) { return; } var user = await GuildUsers.GetAsync(guildAuthor); var log = ValidateLog(guild, socketGuild, LogEvent.MessageDeleted); string validation = Auto.GetContentValidation(guild, message.Value.Content.ToString(), user).ToString(); string reason = string.IsNullOrEmpty(validation) ? "User Removed" : validation.ToSentenceCase(); var embed = CreateMessageDeletedEmbed(message, channel, reason, log.Colour); await log.Channel.SendMessageAsync(embed : embed); } catch (Exception) {} }
public GuildUser FindGuildUser(IGuildUser iuser) { Check.NotNull(iuser); return(GuildUsers.FirstOrDefault(u => (u.Id == iuser.Id) && (u.GuildId == iuser.Guild.Id))); }