Skip to content

Commit

Permalink
Merge branch 'main' into floatingmilkshake/dsp-command-migration
Browse files Browse the repository at this point in the history
  • Loading branch information
FloatingMilkshake committed Dec 28, 2024
2 parents e8dc35c + 169be11 commit 41f820f
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 50 deletions.
29 changes: 16 additions & 13 deletions Commands/BanCmds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,18 @@ public async Task BanInfoSlashCommand(
[HomeServer, RequireHomeserverPerm(ServerPermLevel.Moderator)]
public async Task MassBanCmd(TextCommandContext ctx, [RemainingText] string input)
{
List<string> usersString = input.Replace("\n", " ").Replace("\r", "").Split(' ').ToList();
List<ulong> users = usersString.Select(x => Convert.ToUInt64(x)).ToList();
List<string> inputString = input.Replace("\n", " ").Replace("\r", "").Split(' ').ToList();
List<ulong> users = new();
string reason = "";
foreach (var word in inputString)
{
if (ulong.TryParse(word, out var id))
users.Add(id);
else
reason += $"{word} ";
}
reason = reason.Trim();

if (users.Count == 1 || users.Count == 0)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} Not accepting a massban with a single user. Please use `!ban`.");
Expand All @@ -173,7 +183,10 @@ public async Task MassBanCmd(TextCommandContext ctx, [RemainingText] string inpu

foreach (ulong user in users)
{
taskList.Add(BanSilently(ctx.Guild, user));
if (string.IsNullOrWhiteSpace(reason))
taskList.Add(BanSilently(ctx.Guild, user));
else
taskList.Add(BanSilently(ctx.Guild, user, $"Mass ban: {reason}"));
}

var tasks = await Task.WhenAll(taskList);
Expand Down Expand Up @@ -272,11 +285,6 @@ public async Task BanCmd(TextCommandContext ctx,
return;
}
}
reason = reason.Replace("`", "\\`").Replace("*", "\\*");
if (banDuration == default)
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} {targetMember.Mention} has been banned: **{reason}**");
else
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} {targetMember.Mention} has been banned for **{TimeHelpers.TimeToPrettyFormat(banDuration, false)}**: **{reason}**");
}

/// I CANNOT find a way to do this as alias so I made it a separate copy of the command.
Expand Down Expand Up @@ -357,11 +365,6 @@ public async Task BankeepCmd(TextCommandContext ctx,
return;
}
}
reason = reason.Replace("`", "\\`").Replace("*", "\\*");
if (banDuration == default)
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} {targetMember.Mention} has been banned: **{reason}**");
else
await ctx.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} {targetMember.Mention} has been banned for **{TimeHelpers.TimeToPrettyFormat(banDuration, false)}**: **{reason}**");
}
}
}
4 changes: 2 additions & 2 deletions Commands/DebugCmds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,14 @@ public async Task Refresh(TextCommandContext ctx)
var msg = await ctx.GetResponseAsync();
bool bans = await Tasks.PunishmentTasks.CheckBansAsync();
bool mutes = await Tasks.PunishmentTasks.CheckMutesAsync();
bool warns = await Tasks.PunishmentTasks.CheckAutomaticWarningsAsync();
bool punishmentMessages = await Tasks.PunishmentTasks.CleanUpPunishmentMessagesAsync();
bool reminders = await Tasks.ReminderTasks.CheckRemindersAsync();
bool raidmode = await Tasks.RaidmodeTasks.CheckRaidmodeAsync(ctx.Guild.Id);
bool unlocks = await Tasks.LockdownTasks.CheckUnlocksAsync();
bool channelUpdateEvents = await Tasks.EventTasks.HandlePendingChannelUpdateEventsAsync();
bool channelDeleteEvents = await Tasks.EventTasks.HandlePendingChannelDeleteEventsAsync();

await msg.ModifyAsync($"Unban check result: `{bans}`\nUnmute check result: `{mutes}`\nAutomatic warning message check result: `{warns}`\nReminders check result: `{reminders}`\nRaidmode check result: `{raidmode}`\nUnlocks check result: `{unlocks}`\nPending Channel Update events check result: `{channelUpdateEvents}`\nPending Channel Delete events check result: `{channelDeleteEvents}`");
await msg.ModifyAsync($"Unban check result: `{bans}`\nUnmute check result: `{mutes}`\nPunishment message cleanup check result: `{punishmentMessages}`\nReminders check result: `{reminders}`\nRaidmode check result: `{raidmode}`\nUnlocks check result: `{unlocks}`\nPending Channel Update events check result: `{channelUpdateEvents}`\nPending Channel Delete events check result: `{channelDeleteEvents}`");
}

[Command("sh")]
Expand Down
16 changes: 13 additions & 3 deletions Commands/KickCmds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,18 @@ public class KickCmds
public async Task MassKickCmd(TextCommandContext ctx, [RemainingText] string input)
{

List<string> usersString = input.Replace("\n", " ").Replace("\r", "").Split(' ').ToList();
List<ulong> users = usersString.Select(x => Convert.ToUInt64(x)).ToList();
List<string> inputString = input.Replace("\n", " ").Replace("\r", "").Split(' ').ToList();
List<ulong> users = new();
string reason = "";
foreach (var word in inputString)
{
if (ulong.TryParse(word, out var id))
users.Add(id);
else
reason += $"{word} ";
}
reason = reason.Trim();

if (users.Count == 1 || users.Count == 0)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} Not accepting a masskick with a single user. Please use `!ban`.");
Expand All @@ -79,7 +89,7 @@ public async Task MassKickCmd(TextCommandContext ctx, [RemainingText] string inp
if (member is not null)
{

taskList.Add(SafeKickAndLogAsync(member, "Mass kick", ctx.Member));
taskList.Add(SafeKickAndLogAsync(member, $"Mass kick{(string.IsNullOrWhiteSpace(reason) ? "" : $": {reason}")}", ctx.Member));
}
}
catch
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN dotnet restore

# Copy source code and build
COPY . ./
RUN dotnet build -c Release -o out
RUN dotnet publish Cliptok.csproj -c Release --property:PublishDir=$PWD/out

# We already have this image pulled, its actually quicker to reuse it
FROM mcr.microsoft.com/dotnet/sdk:9.0.100 AS git-collector
Expand Down
57 changes: 43 additions & 14 deletions Helpers/BanHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,16 @@ public static async Task<bool> BanFromServerAsync(ulong targetUserId, string rea
expireTime = null;
}

MemberPunishment newBan = new()
(DiscordMessage? dmMessage, DiscordMessage? chatMessage) output = new();

reason = reason.Replace("`", "\\`").Replace("*", "\\*");
if (channel is not null)
{
MemberId = targetUserId,
ModId = moderatorId,
ServerId = guild.Id,
ExpireTime = expireTime,
ActionTime = actionTime,
Reason = reason
};

await Program.db.HashSetAsync("bans", targetUserId, JsonConvert.SerializeObject(newBan));
if (banDuration == default)
output.chatMessage = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} <@{targetUserId}> has been banned: **{reason}**");
else
output.chatMessage = await channel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} <@{targetUserId}> has been banned for **{TimeHelpers.TimeToPrettyFormat(banDuration, false)}**: **{reason}**");
}

try
{
Expand All @@ -38,24 +37,54 @@ public static async Task<bool> BanFromServerAsync(ulong targetUserId, string rea
if (appealable)
{
if (compromisedAccount)
await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}**!\nReason: **{reason}**\nYou can appeal the ban here: <{Program.cfgjson.AppealLink}>\nBefore appealing, please follow these steps to protect your account:\n1. Reset your Discord account password. Even if you use MFA, this will reset all session tokens.\n2. Review active sessions and authorised app connections.\n3. Ensure your PC is free of malware.\n4. [Enable MFA](https://support.discord.com/hc/en-us/articles/219576828-Setting-up-Multi-Factor-Authentication) if not already.");
output.dmMessage = await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}**!\nReason: **{reason}**\nYou can appeal the ban here: <{Program.cfgjson.AppealLink}>\nBefore appealing, please follow these steps to protect your account:\n1. Reset your Discord account password. Even if you use MFA, this will reset all session tokens.\n2. Review active sessions and authorised app connections.\n3. Ensure your PC is free of malware.\n4. [Enable MFA](https://support.discord.com/hc/en-us/articles/219576828-Setting-up-Multi-Factor-Authentication) if not already.");
else
await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}**!\nReason: **{reason}**\nYou can appeal the ban here: <{Program.cfgjson.AppealLink}>");
output.dmMessage = await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}**!\nReason: **{reason}**\nYou can appeal the ban here: <{Program.cfgjson.AppealLink}>");
}
else
{
await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been permanently banned from **{guild.Name}**!\nReason: **{reason}**");
output.dmMessage = await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been permanently banned from **{guild.Name}**!\nReason: **{reason}**");
}
}
else
{
await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}** for {TimeHelpers.TimeToPrettyFormat(banDuration, false)}!\nReason: **{reason}**\nBan expires: <t:{TimeHelpers.ToUnixTimestamp(expireTime)}:R>");
output.dmMessage = await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}** for {TimeHelpers.TimeToPrettyFormat(banDuration, false)}!\nReason: **{reason}**\nBan expires: <t:{TimeHelpers.ToUnixTimestamp(expireTime)}:R>");
}
}
catch
{
// A DM failing to send isn't important.
}

MemberPunishment newBan = new()
{
MemberId = targetUserId,
ModId = moderatorId,
ServerId = guild.Id,
ExpireTime = expireTime,
ActionTime = actionTime,
Reason = reason
};

if (output.chatMessage is not null)
newBan.ContextMessageReference = new()
{
MessageId = output.chatMessage.Id,
ChannelId = output.chatMessage.ChannelId
};

if (output.dmMessage is not null)
newBan!.DmMessageReference = new()
{
MessageId = output.dmMessage.Id,
ChannelId = output.dmMessage.ChannelId
};

await Program.db.HashSetAsync("bans", targetUserId, JsonConvert.SerializeObject(newBan));

// If ban is for a compromised account, add to list so the context message can be more-easily deleted later
if (compromisedAccount)
Program.db.HashSet("compromisedAccountBans", targetUserId, JsonConvert.SerializeObject(newBan));

try
{
Expand Down
2 changes: 1 addition & 1 deletion Helpers/WarningHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ public static async Task<DiscordMessage> SendPublicWarningMessageAndDeleteInfrin
// Return the sent warning message for logging.

var targetChannel = infringingMessage.Channel;
if (infringingMessage.Channel.Type == DiscordChannelType.GuildForum)
if (infringingMessage.Channel.Type == DiscordChannelType.GuildForum || infringingMessage.Channel.Parent.Type == DiscordChannelType.GuildForum)
{
if (Program.cfgjson.ForumChannelAutoWarnFallbackChannel == 0)
Program.discord.Logger.LogWarning("A warning in forum channel {channelId} was attempted, but may fail due to the fallback channel not being set. Please set 'forumChannelAutoWarnFallbackChannel' in config.json to avoid this.", targetChannel.Id);
Expand Down
3 changes: 3 additions & 0 deletions Lists/scams.txt
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,6 @@ serious about earning over $50K weekly in the digital market
% of your profits once you start seeing earnings
get started by asking (How)
coach_davidrobert
qCIKIQ
5,000+ OnlyFans Models
Teen, SnapChat & Other Packs
2 changes: 1 addition & 1 deletion Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ static async Task Main(string[] _)
[
Tasks.PunishmentTasks.CheckMutesAsync(),
Tasks.PunishmentTasks.CheckBansAsync(),
Tasks.PunishmentTasks.CheckAutomaticWarningsAsync(),
Tasks.PunishmentTasks.CleanUpPunishmentMessagesAsync(),
Tasks.ReminderTasks.CheckRemindersAsync(),
Tasks.RaidmodeTasks.CheckRaidmodeAsync(cfgjson.ServerID),
Tasks.LockdownTasks.CheckUnlocksAsync(),
Expand Down
3 changes: 3 additions & 0 deletions Structs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ public class ConfigJson

[JsonProperty("autoWarnMsgAutoDeleteDays")]
public int AutoWarnMsgAutoDeleteDays { get; private set; }

[JsonProperty("compromisedAccountBanMsgAutoDeleteDays")]
public int CompromisedAccountBanMsgAutoDeleteDays { get; private set; }

[JsonProperty("logLevel")]
public Level LogLevel { get; private set; } = Level.Information;
Expand Down
68 changes: 53 additions & 15 deletions Tasks/PunishmentTasks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,30 @@ public static async Task<bool> CheckMutesAsync()
}
}

public static async Task<bool> CheckAutomaticWarningsAsync()
// Cleans up public messages for automatic warnings & bans for compromised accounts
public static async Task<bool> CleanUpPunishmentMessagesAsync()
{
if (Program.cfgjson.AutoWarnMsgAutoDeleteDays == 0)
if (Program.cfgjson.AutoWarnMsgAutoDeleteDays == 0 && Program.cfgjson.CompromisedAccountBanMsgAutoDeleteDays == 0)
return false;

Dictionary<string, UserWarning> warnList = Program.db.HashGetAll("automaticWarnings").ToDictionary(
x => x.Name.ToString(),
x => JsonConvert.DeserializeObject<UserWarning>(x.Value)
);

if (warnList is null | warnList.Keys.Count == 0)
return false;
else

// The success value will be changed later if any of the message deletes are successful.
bool success = false;

if (Program.cfgjson.AutoWarnMsgAutoDeleteDays > 0)
{
// The success value will be changed later if any of the message deletes are successful.
bool success = false;
Dictionary<string, UserWarning> warnList = Program.db.HashGetAll("automaticWarnings").ToDictionary(
x => x.Name.ToString(),
x => JsonConvert.DeserializeObject<UserWarning>(x.Value)
);

foreach (KeyValuePair<string, UserWarning> entry in warnList)
{
UserWarning warn = entry.Value;
#if DEBUG
if (DateTime.Now > warn.WarnTimestamp.AddSeconds(Program.cfgjson.AutoWarnMsgAutoDeleteDays))
#else
if (DateTime.Now > warn.WarnTimestamp.AddDays(Program.cfgjson.AutoWarnMsgAutoDeleteDays))
#endif
{
try
{
Expand All @@ -94,9 +98,43 @@ public static async Task<bool> CheckAutomaticWarningsAsync()
}
}
}
Program.discord.Logger.LogDebug(Program.CliptokEventID, "Checked automatic warnings at {time} with result: {result}", DateTime.Now, success);
return success;
}

if (Program.cfgjson.CompromisedAccountBanMsgAutoDeleteDays > 0)
{
Dictionary<string, MemberPunishment> banList = Program.db.HashGetAll("compromisedAccountBans").ToDictionary(
x => x.Name.ToString(),
x => JsonConvert.DeserializeObject<MemberPunishment>(x.Value)
);

foreach (KeyValuePair<string, MemberPunishment> entry in banList)
{
MemberPunishment ban = entry.Value;
#if DEBUG
if (DateTime.Now > ban.ActionTime.Value.AddSeconds(Program.cfgjson.CompromisedAccountBanMsgAutoDeleteDays))
#else
if (DateTime.Now > ban.ActionTime.Value.AddDays(Program.cfgjson.CompromisedAccountBanMsgAutoDeleteDays))
#endif
{
try
{
var contextMessage = await DiscordHelpers.GetMessageFromReferenceAsync(ban.ContextMessageReference);
await contextMessage.DeleteAsync();
Program.db.HashDelete("compromisedAccountBans", ban.MemberId);
success = true;
}
catch (NullReferenceException)
{
// it's fine. trust me. we'll live.
Program.db.HashDelete("compromisedAccountBans", ban.MemberId);
continue;
}
}
}
}

Program.discord.Logger.LogDebug(Program.CliptokEventID, "Checked for auto-warn and compromised account ban messages at {time} with result: {result}", DateTime.Now, success);
return success;
}
}

Expand Down
1 change: 1 addition & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@
"tqsMutedRole": 752821045408563230,
"tqsMuteDurationHours": 2,
"autoWarnMsgAutoDeleteDays": 3,
"compromisedAccountBanMsgAutoDeleteDays": 3,
"logLevel": "Debug",
"lokiURL": "http://100.79.19.82:3100",
"lokiServiceName": "cliptok",
Expand Down

0 comments on commit 41f820f

Please sign in to comment.