public async Task TempBanWarnUser([RequireHierarchy] UserRef userRef, TimeSpan time, float size, [Remainder] string reason) { if (time.TotalMinutes < 1) { await ReplyAsync("Can't temp-ban for less than a minute"); return; } if (!(Context.Message.Author as IGuildUser).HasAdmin()) { ModerationSettings settings = Context.Guild.LoadFromFile <ModerationSettings>(false); if (settings?.maxTempAction != null && time > settings.maxTempAction) { await ReplyAsync("You are not allowed to punish for that long"); return; } } await userRef.Warn(size, reason, Context.Channel as ITextChannel, "Discord"); TempActionList actions = Context.Guild.LoadFromFile <TempActionList>(true); if (actions.tempBans.Any(tempBan => tempBan.User == userRef.ID)) { await ReplyAsync($"{userRef.Name()} is already temp-banned (the warn did go through)"); return; } await userRef.TempBan(time, reason, Context, actions); Context.Message.DeleteOrRespond($"Temporarily banned {userRef.Mention()} for {time.LimitedHumanize(3)} because of {reason}", Context.Guild); }
public async Task TempMuteUser([RequireHierarchy] UserRef userRef, TimeSpan time, [Remainder] string reason) { if (time.TotalMinutes < 1) { await ReplyAsync("Can't temp-mute for less than a minute"); return; } ModerationSettings settings = Context.Guild.LoadFromFile <ModerationSettings>(); if (!(Context.Message.Author as IGuildUser).HasAdmin()) { if (settings?.maxTempAction != null && time > settings.maxTempAction) { await ReplyAsync("You are not allowed to punish for that long"); return; } } if (settings == null || settings.mutedRole == 0 || Context.Guild.GetRole(settings.mutedRole) == null) { await ReplyAsync("Muted role is null or invalid"); return; } TempActionList actions = Context.Guild.LoadFromFile <TempActionList>(true); TempAct oldAct = actions.tempMutes.FirstOrDefault(tempMute => tempMute.User == userRef.ID); if (oldAct != null) { if (!(Context.Message.Author as IGuildUser).HasAdmin() && (oldAct.Length - (DateTime.UtcNow - oldAct.DateBanned)) >= time) { await ReplyAsync($"{Context.User.Mention} please contact your admin(s) in order to shorten length of a punishment"); return; } string text = $"{userRef.Name()} is already temp-muted for {oldAct.Length.LimitedHumanize()} ({(oldAct.Length - (DateTime.UtcNow - oldAct.DateBanned)).LimitedHumanize()} left), are you sure you want to change the length?"; var request = new ConfirmationBuilder() .WithContent(new PageBuilder().WithText(text)) .Build(); var result = await Interactivity.SendConfirmationAsync(request, Context.Channel, TimeSpan.FromMinutes(2)); if (result.Value) { actions.tempMutes.Remove(oldAct); actions.SaveToFile(); } else { await ReplyAsync("Command canceled"); return; } } await userRef.TempMute(time, reason, Context, settings, actions); Context.Message.DeleteOrRespond($"Temporarily muted {userRef.Mention()} for {time.LimitedHumanize(3)} because of {reason}", Context.Guild); }
public async Task ActSanityCheck() { List <TypedTempAct> tempActsToEnd = new List <TypedTempAct>(); RequestOptions requestOptions = RequestOptions.Default; requestOptions.RetryMode = RetryMode.AlwaysRetry; foreach (SocketGuild sockGuild in Context.Client.Guilds) { TempActionList actions = sockGuild.LoadFromFile <TempActionList>(false); if (actions != null) { if (actions.tempBans?.Count is null or 0) { foreach (TempAct tempBan in actions.tempBans) { if (DateTime.UtcNow >= tempBan.End) { tempActsToEnd.Add(new TypedTempAct(tempBan, TempActType.TempBan)); } } } ModerationSettings settings = sockGuild.LoadFromFile <ModerationSettings>(); if (settings is not null && sockGuild.GetRole(settings.mutedRole) != null && actions.tempMutes?.Count is not null or 0) { foreach (TempAct tempMute in actions.tempMutes) { if (DateTime.UtcNow >= tempMute.End) { //Normal mute end tempActsToEnd.Add(new TypedTempAct(tempMute, TempActType.TempMute)); } } } } } if (tempActsToEnd.Count == 0) { await ReplyAsync("No acts should've ended already"); return; } var embed = new EmbedBuilder(); embed.Title = $"{tempActsToEnd.Count} tempacts should've ended (longest one ended ago is {TimeSpan.FromMilliseconds(tempActsToEnd.Select(tempAct => DateTime.UtcNow.Subtract(tempAct.End).TotalMilliseconds).Max()).Humanize(2)}"; foreach (TypedTempAct tempAct in tempActsToEnd) { embed.AddField($"{tempAct.Type} started on {tempAct.DateBanned.ToShortTimeString()} {tempAct.DateBanned.ToShortDateString()} for {tempAct.Length.LimitedHumanize()}", $"Should've ended {DateTime.UtcNow.Subtract(tempAct.End).LimitedHumanize()}"); } await ReplyAsync(embed : embed.Build()); if (tempActsToEnd.Any(tempAct => DateTime.UtcNow.Subtract(tempAct.End).CompareTo(TimeSpan.Zero) < 0)) { await ReplyAsync("Note: some of the values seem broken"); } }
async Task CheckNewUser(SocketGuildUser user) { ModerationSettings settings = user.Guild?.LoadFromFile <ModerationSettings>(); TempActionList actions = user.Guild?.LoadFromFile <TempActionList>(); if (settings == null || user.Guild?.GetRole(settings.mutedRole) == null || (actions?.tempMutes?.IsNullOrEmpty() ?? true)) { return; } if (actions.tempMutes.Any(tempMute => tempMute.user == user.Id)) { _ = user.AddRoleAsync(user.Guild.GetRole(settings.mutedRole)); } }
private async Task CheckNewUser(SocketGuildUser user) { ModerationSettings settings = user.Guild?.LoadFromFile <ModerationSettings>(); TempActionList actions = user.Guild?.LoadFromFile <TempActionList>(); //Can be done better and cleaner if (settings == null || user.Guild?.GetRole(settings.mutedRole) == null || (actions?.tempMutes?.Count is null or 0)) { return; } if (actions.tempMutes.Any(tempMute => tempMute.User == user.Id)) { await user.AddRoleAsync(user.Guild.GetRole(settings.mutedRole)); } }
public async Task Ban([RequireHierarchy] UserRef userRef, [Remainder] string reason) { if (reason.Split(' ').First().ToTime() != null) { var query = "Are you sure you don't mean to use !tempban?"; var request = new ConfirmationBuilder() .WithContent(new PageBuilder().WithText(query)) .Build(); var result = await Interactivity.SendConfirmationAsync(request, Context.Channel, TimeSpan.FromMinutes(1)); if (result.Value) { await ReplyAsync("Command Canceled"); return; } } TempActionList actions = Context.Guild.LoadFromFile <TempActionList>(false); if (actions?.tempBans?.Any(tempBan => tempBan.User == userRef.ID) ?? false) { var query = "User is already tempbanned, are you sure you want to ban?"; var request = new ConfirmationBuilder() .WithContent(new PageBuilder().WithText(query)) .Build(); var result = await Interactivity.SendConfirmationAsync(request, Context.Channel, TimeSpan.FromMinutes(2)); if (result.Value) { await ReplyAsync("Command Canceled"); return; } actions.tempBans.Remove(actions.tempBans.First(tempban => tempban.User == userRef.ID)); } else if ((await Context.Guild.GetBansAsync()).Any(ban => ban.User.Id == userRef.ID)) { await ReplyAsync("User has already been banned permanently"); return; } userRef.User?.TryNotify($"You have been perm banned in the {Context.Guild.Name} discord for {reason}"); await Context.Guild.AddBanAsync(userRef.ID, reason : reason); DiscordLogging.LogTempAct(Context.Guild, Context.Message.Author, userRef, "Bann", reason, Context.Message.GetJumpUrl(), TimeSpan.Zero); Context.Message.DeleteOrRespond($"{userRef.Name(true)} has been banned for {reason}", Context.Guild); }
public async Task Statistics() { var embed = new EmbedBuilder(); embed.WithTitle("Statistics"); embed.AddField($"Part of", $"{Context.Client.Guilds.Count} discord guilds", true); ulong infractions24Hours = 0; ulong totalInfractons = 0; ulong members = 0; uint tempBannedPeople = 0; uint tempMutedPeople = 0; foreach (SocketGuild guild in Context.Client.Guilds) { members += (ulong)guild.MemberCount; var collection = guild.GetInfractionsCollection(false); if (collection != null) { using var cursor = collection.Find(new BsonDocument()).ToCursor(); foreach (var doc in cursor.ToList()) { foreach (Infraction infraction in BsonSerializer.Deserialize <UserInfractions>(doc).infractions) { if (DateTime.UtcNow - infraction.Time < TimeSpan.FromHours(24)) { infractions24Hours++; } totalInfractons++; } } } TempActionList tempActionList = guild.LoadFromFile <TempActionList>(false); tempBannedPeople += (uint)(tempActionList?.tempBans?.Count ?? 0); tempMutedPeople += (uint)(tempActionList?.tempMutes?.Count ?? 0); } embed.AddField("Totals", $"{members} users || {totalInfractons} total infractions", true); embed.AddField("In the last 24 hours", $"{infractions24Hours} infractions given", true); embed.AddField("Temp Actions", $"{tempMutedPeople} tempmuted, {tempBannedPeople} tempbanned", true); embed.AddField("Uptime", (DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime()).LimitedHumanize()); await ReplyAsync(embed : embed.Build()); }
public async Task Ban(ulong ID, [Remainder] string reason = "Unspecified") { TempActionList actions = Context.Guild.LoadFromFile <TempActionList>(false); if (actions?.tempBans?.Any(tempBan => tempBan.user == ID) ?? false) { actions.tempBans.Remove(actions.tempBans.First(tempban => tempban.user == ID)); } else if (Context.Guild.GetBansAsync().Result.Any(ban => ban.User.Id == ID)) { await ReplyAsync("User has already been banned permanently"); return; } Context.Client.GetUser(ID)?.TryNotify($"You have been banned in the {Context.Guild.Name} discord for {reason}"); await Context.Guild.AddBanAsync(ID); Context.Message.DeleteOrRespond($"User has been banned for {reason}", Context.Guild); }
public async Task TempMuteWarnUser([RequireHierarchy] UserRef userRef, TimeSpan time, [Remainder] string reason) { if (time.TotalMinutes < 1) { await ReplyAsync("Can't temp-mute for less than a minute"); return; } ModerationSettings settings = Context.Guild.LoadFromFile <ModerationSettings>(); if (!(Context.Message.Author as IGuildUser).HasAdmin()) { if (settings?.maxTempAction != null && time > settings.maxTempAction) { await ReplyAsync("You are not allowed to punish for that long"); return; } } if (settings == null || settings.mutedRole == 0 || Context.Guild.GetRole(settings.mutedRole) == null) { await ReplyAsync("Muted role is null or invalid"); return; } await userRef.Warn(1, reason, Context.Channel as ITextChannel, Context.Message.GetJumpUrl()); TempActionList actions = Context.Guild.LoadFromFile <TempActionList>(true); if (actions.tempMutes.Any(tempMute => tempMute.User == userRef.ID)) { await ReplyAsync($"{userRef.Name()} is already temp-muted, (the warn did go through)"); return; } await userRef.TempMute(time, reason, Context, settings, actions); Context.Message.DeleteOrRespond($"Temporarily muted {userRef.Mention()} for {time.LimitedHumanize(3)} because of {reason}", Context.Guild); }
public static async Task CheckTempActs(DiscordSocketClient client, bool debug = false, CancellationToken?ct = null) { RequestOptions requestOptions = RequestOptions.Default; requestOptions.RetryMode = RetryMode.AlwaysRetry; try { currentInfo.checkedGuilds = 0; foreach (SocketGuild sockGuild in client.Guilds) { ct?.ThrowIfCancellationRequested(); currentInfo.checkedMutes = 0; if (currentInfo.checkedGuilds > client.Guilds.Count) { await new LogMessage(LogSeverity.Error, "TempAct", $"Check went past all guilds (at #{currentInfo.checkedGuilds}) but has been stopped. This doesn't seem physically possible.").Log(); return; } RestGuild restGuild = await client.Rest.SuperGetRestGuild(sockGuild.Id); if (debug) { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write($"\nChecking {sockGuild.Name} discord "); } TempActionList actions = sockGuild.LoadFromFile <TempActionList>(false); bool needSave = false; currentInfo.checkedGuilds++; if (actions != null) { if (actions.tempBans?.Count is not null or 0) { currentInfo.editedBans = new List <TempAct>(actions.tempBans); foreach (TempAct tempBan in actions.tempBans) { try { RestBan ban = await sockGuild.GetBanAsync(tempBan.User, requestOptions); if (ban == null) { //If manual unban var user = await client.Rest.GetUserAsync(tempBan.User); currentInfo.editedBans.Remove(tempBan); user?.TryNotify($"As you might know, you have been manually unbanned in {sockGuild.Name} discord"); //_ = new LogMessage(LogSeverity.Warning, "TempAction", "Tempbanned person isn't banned").Log(); if (user == null) { DiscordLogging.LogManualEndTempAct(sockGuild, tempBan.User, "bann", tempBan.DateBanned); } else { DiscordLogging.LogManualEndTempAct(sockGuild, user, "bann", tempBan.DateBanned); } } else if (DateTime.UtcNow >= tempBan.DateBanned.Add(tempBan.Length)) { RestUser rUser = ban.User; await sockGuild.RemoveBanAsync(tempBan.User, requestOptions); currentInfo.editedBans.Remove(tempBan); DiscordLogging.LogEndTempAct(sockGuild, rUser, "bann", tempBan.Reason, tempBan.Length); } } catch (Exception e) { await new LogMessage(LogSeverity.Error, "TempAct", "Something went wrong unbanning someone, continuing", e).Log(); } } //if all tempbans DON'T equal all edited tempbans (basically if there was a change if (currentInfo.editedBans.Count != actions.tempBans.Count) { if (debug) { Console.Write($"{actions.tempBans.Count - currentInfo.editedBans.Count} tempbans are over, "); } needSave = true; actions.tempBans = currentInfo.editedBans; } else if (debug) { Console.Write($"tempbans checked, none over, "); } } else if (debug) { Console.Write($"no tempbans, "); } ModerationSettings settings = sockGuild.LoadFromFile <ModerationSettings>(); if (settings is not null && sockGuild.GetRole(settings.mutedRole) != null && actions.tempMutes?.Count is not null or 0) { var mutedRole = sockGuild.GetRole(settings.mutedRole); List <TempAct> editedMutes = new List <TempAct>(actions.tempMutes); foreach (TempAct tempMute in actions.tempMutes) { currentInfo.checkedMutes++; try { IGuildUser gUser = sockGuild.GetUser(tempMute.User) ?? await restGuild.SuperGetUser(tempMute.User); if (gUser != null && !gUser.RoleIds.Contains(settings.mutedRole)) { //User missing muted role, must have been manually unmuted _ = gUser.TryNotify($"As you might know, you have been manually unmuted in {sockGuild.Name} discord"); editedMutes.Remove(tempMute); DiscordLogging.LogManualEndTempAct(sockGuild, gUser, "mut", tempMute.DateBanned); _ = (!editedMutes.Contains(tempMute)).AssertAsync("Tempmute not removed?!"); } else if (DateTime.UtcNow >= tempMute.DateBanned.Add(tempMute.Length)) { //Normal mute end if (gUser != null) { await gUser.RemoveRoleAsync(mutedRole, requestOptions); } // if user not in guild || if user doesn't contain muted role (successfully removed? if (gUser == null || !gUser.RoleIds.Contains(settings.mutedRole)) { //Doesn't remove tempmute if unmuting fails IUser user = gUser; //Gets user to try to message user ??= await client.SuperGetUser(tempMute.User); if (user != null) { // if possible to message, message and log DiscordLogging.LogEndTempAct(sockGuild, user, "mut", tempMute.Reason, tempMute.Length); _ = user.Notify("auto untempmuted", tempMute.Reason, sockGuild, client.CurrentUser); } editedMutes.Remove(tempMute); } else if (gUser != null) { await new LogMessage(LogSeverity.Warning, "TempAct", "User should've had role removed").Log(); } } } catch (Exception e) { await new LogMessage(LogSeverity.Error, "TempAct", "Something went wrong unmuting someone, continuing", e).Log(); } } //NOTE: Assertions fail if NOT true _ = (currentInfo.checkedMutes == actions.tempMutes.Count).AssertAsync($"Checked incorrect number tempmutes ({currentInfo.checkedMutes}/{actions.tempMutes.Count}) in guild {sockGuild} owned by {sockGuild.Owner}"); if (editedMutes.Count != actions.tempMutes.Count) { if (debug) { Console.Write($"{actions.tempMutes.Count - editedMutes.Count}/{actions.tempMutes.Count} tempmutes are over"); } actions.tempMutes = editedMutes; needSave = true; } else if (debug) { Console.Write($"none of {actions.tempMutes.Count} tempmutes over"); } } else if (debug) { Console.Write("no tempmutes to check or no settings"); } if (needSave) { actions.SaveToFile(); } }
public static async Task TempActChecker(DiscordSocketClient client, bool debug = false) { try { int checkedGuilds = 0; foreach (SocketGuild guild in client.Guilds) { if (debug) { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write($"\nChecking {guild.Name} discord "); } TempActionList actions = guild.LoadFromFile <TempActionList>(false); bool needSave = false; checkedGuilds++; if (actions != null) { if (!actions.tempBans.IsNullOrEmpty()) { List <TempAct> editedBans = new List <TempAct>(actions.tempBans); foreach (TempAct tempBan in actions.tempBans) { try { if (!guild.GetBansAsync().Result.Any(ban => ban.User.Id == tempBan.user)) //Need to add an embed for when this happens that's distinct { _ = client.GetUser(tempBan.user)?.TryNotify($"As you might know, you have been manually unbanned in {guild.Name} discord"); //_ = new LogMessage(LogSeverity.Warning, "TempAction", "Tempbanned person isn't banned").Log(); editedBans.Remove(tempBan); } else if (DateTime.Now >= tempBan.dateBanned.Add(tempBan.length)) { RestUser rUser = guild.GetBansAsync().Result.First(ban => ban.User.Id == tempBan.user).User; await guild.RemoveBanAsync(tempBan.user); editedBans.Remove(tempBan); Logging.LogEndTempAct(guild, rUser, "bann", tempBan.reason, tempBan.length); } } catch (Exception e) { _ = new LogMessage(LogSeverity.Error, "TempAct", "Something went wrong unbanning someone, continuing", e).Log(); } } if (editedBans != actions.tempBans) { if (debug) { Console.Write($"{actions.tempBans.Count - editedBans.Count} tempbans are over, "); } needSave = true; actions.tempBans = editedBans; } else if (debug) { Console.Write($"tempbans checked, none over, "); } } else if (debug) { Console.Write($"no tempbans, "); } ModerationSettings settings = guild.LoadFromFile <ModerationSettings>(); if (settings != null && guild.GetRole(settings.mutedRole) != null && !actions.tempMutes.IsNullOrEmpty()) { List <TempAct> editedMutes = new List <TempAct>(actions.tempMutes); uint checkedMutes = 0; foreach (TempAct tempMute in actions.tempMutes) { checkedMutes++; try { SocketUser user = guild.GetUser(tempMute.user); if (user != null && !(user as IGuildUser).RoleIds.Contains(settings.mutedRole)) { _ = user.TryNotify($"As you might know, you have been manually unmuted in {guild.Name} discord"); editedMutes.Remove(tempMute); } else if (DateTime.Now >= tempMute.dateBanned.Add(tempMute.length)) { if (user != null) { await guild.GetUser(tempMute.user).RemoveRoleAsync(guild.GetRole(settings.mutedRole)); } if (!(user as IGuildUser)?.RoleIds?.NotEmpty() ?? true || !(user as IGuildUser).RoleIds.Contains(settings.mutedRole)) //Doesn't remove tempmute if unmuting fails { user ??= client.GetUser(tempMute.user); if (user != null) { Logging.LogEndTempAct(guild, user, "mut", tempMute.reason, tempMute.length); _ = user.Notify($"untemp-muted", tempMute.reason, guild); } editedMutes.Remove(tempMute); } } } catch (Exception e) { _ = new LogMessage(LogSeverity.Error, "TempAct", "Something went wrong unmuting someone, continuing", e).Log(); } } _ = (checkedMutes == actions.tempMutes.Count || checkedMutes == uint.MaxValue).AssertAsync("Didn't check all tempmutes"); if (editedMutes != actions.tempMutes) { if (debug) { Console.Write($"{actions.tempMutes.Count - editedMutes.Count}/{actions.tempMutes.Count} tempmutes are over"); } actions.tempMutes = editedMutes; needSave = true; } else if (debug) { Console.Write($"no tempmute changes"); } } else if (debug) { Console.Write("no tempmutes to check or no settings"); } if (needSave) { actions.SaveToFile(guild); } } } if (debug) { Console.Write("\n"); } _ = (checkedGuilds > 0).AssertWarnAsync("Checked 0 guilds for tempbans?"); } catch (Exception e) { _ = new LogMessage(LogSeverity.Error, "TempAct", "Something went wrong unbanning someone", e).Log(); } }