mirror of
https://github.com/RPCS3/discord-bot.git
synced 2026-01-31 01:25:22 +01:00
Adjust names of commands
Check permissions before changing nickname Display table instead of raw text in list command Add periodic check if forced nicknames are still valid. Add GuildId in order to not list forced nicknames added on different guild.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CompatBot.Commands.Attributes;
|
||||
using CompatBot.Database;
|
||||
using CompatBot.Utils;
|
||||
using DSharpPlus;
|
||||
using DSharpPlus.CommandsNext;
|
||||
using DSharpPlus.CommandsNext.Attributes;
|
||||
using DSharpPlus.Entities;
|
||||
@@ -11,59 +12,85 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CompatBot.Commands
|
||||
{
|
||||
[Group("forced-nicknames"), RequiresWhitelistedRole]
|
||||
[Group("rename"), RequiresBotModRole]
|
||||
[Description("Manage users who has forced nickname.")]
|
||||
internal sealed class ForcedNicknames : BaseCommandModuleCustom
|
||||
{
|
||||
[Command("add")]
|
||||
[GroupCommand]
|
||||
[Description("Enforces specific nickname for particular user.")]
|
||||
public async Task Add(CommandContext ctx,
|
||||
[Description("Discord user to add to forced nickname list.")] DiscordMember discordMember,
|
||||
[Description("Nickname which should be displayed.")] string expectedNickname)
|
||||
{
|
||||
using (var context = new BotDb())
|
||||
try
|
||||
{
|
||||
if (!(await context.ForcedNicknames.SingleOrDefaultAsync(x => x.UserId == discordMember.Id).ConfigureAwait(false) is null))
|
||||
using (var context = new BotDb())
|
||||
{
|
||||
await ctx.ReactWithAsync(Config.Reactions.Failure, $"{discordMember.Mention} is already on blacklist.").ConfigureAwait(false);
|
||||
return;
|
||||
var forcedNickname = context.ForcedNicknames.SingleOrDefault(x => x.UserId == discordMember.Id && x.GuildId == discordMember.Guild.Id);
|
||||
if (forcedNickname is {})
|
||||
{
|
||||
await ChangeNickname(discordMember, expectedNickname, forcedNickname, context,ctx);
|
||||
|
||||
await ctx.ReactWithAsync(Config.Reactions.Success).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
context.ForcedNicknames.Add(
|
||||
new ForcedNickname {UserId = discordMember.Id, GuildId = discordMember.Guild.Id, Nickname = expectedNickname}
|
||||
);
|
||||
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await discordMember.ModifyAsync(x => x.Nickname = expectedNickname).ConfigureAwait(false);
|
||||
|
||||
await ctx.ReactWithAsync(Config.Reactions.Success).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
context.ForcedNicknames.Add(
|
||||
new ForcedNickname {UserId = discordMember.Id, Nickname = expectedNickname}
|
||||
);
|
||||
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await discordMember.ModifyAsync(x => x.Nickname = expectedNickname).ConfigureAwait(false);
|
||||
|
||||
await ctx.ReactWithAsync(Config.Reactions.Success,
|
||||
$"{discordMember.Mention} was successfully added to blacklist!\n" +
|
||||
$"Try using `{ctx.Prefix}help` to see new commands available to you"
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await ctx.ReactWithAsync(Config.Reactions.Failure).ConfigureAwait(false);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[Command("remove")]
|
||||
private static async Task ChangeNickname(DiscordMember discordMember, string expectedNickname,
|
||||
ForcedNickname forcedNickname, BotDb context, CommandContext ctx)
|
||||
{
|
||||
if (forcedNickname.Nickname == expectedNickname)
|
||||
return;
|
||||
|
||||
forcedNickname.Nickname = expectedNickname;
|
||||
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await discordMember.ModifyAsync(x => x.Nickname = expectedNickname).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[Command("clear")]
|
||||
[Aliases("remove")]
|
||||
[Description("Removes nickname restriction from particular user.")]
|
||||
public async Task Remove(CommandContext ctx,
|
||||
[Description("Discord user to remove from forced nickname list.")] DiscordMember discordMember)
|
||||
{
|
||||
using (var context = new BotDb())
|
||||
try
|
||||
{
|
||||
var forcedNickname = await context.ForcedNicknames.SingleOrDefaultAsync(x => x.UserId == discordMember.Id).ConfigureAwait(false);
|
||||
if (forcedNickname is null)
|
||||
using (var context = new BotDb())
|
||||
{
|
||||
await ctx.ReactWithAsync(Config.Reactions.Failure, $"{discordMember.Mention} is not on blacklist.").ConfigureAwait(false);
|
||||
return;
|
||||
var forcedNickname = context.ForcedNicknames.SingleOrDefault(x => x.UserId == discordMember.Id && x.GuildId == discordMember.Guild.Id);
|
||||
if (forcedNickname is null)
|
||||
{
|
||||
await ctx.ReactWithAsync(Config.Reactions.Failure, $"{discordMember.Mention} is not on blacklist.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
context.ForcedNicknames.Remove(forcedNickname);
|
||||
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await ctx.ReactWithAsync(Config.Reactions.Success).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
context.ForcedNicknames.Remove(forcedNickname);
|
||||
await context.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await ctx.ReactWithAsync(Config.Reactions.Success,
|
||||
$"{discordMember.Mention} was successfully removed from blacklist!\n" +
|
||||
$"Try using `{ctx.Prefix}help` to see new commands available to you"
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await ctx.ReactWithAsync(Config.Reactions.Failure).ConfigureAwait(false);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,16 +100,21 @@ namespace CompatBot.Commands
|
||||
{
|
||||
using (var context = new BotDb())
|
||||
{
|
||||
var forcedNicknames = await context.ForcedNicknames.AsNoTracking().ToListAsync().ConfigureAwait(false);
|
||||
var forcedNicknames = await context.ForcedNicknames.AsNoTracking().Where(x=>x.GuildId == ctx.Guild.Id).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
var displayString = forcedNicknames.Select(x =>
|
||||
$"User: {ctx.Client.GetMember(x.UserId).Username}, forced nickname: {x.Nickname}")
|
||||
.Aggregate(new StringBuilder(), (agg, x) => agg.AppendJoin("\n", x),x=>x.ToString());
|
||||
var table = new AsciiTable(
|
||||
new AsciiColumn("ID", !ctx.Channel.IsPrivate),
|
||||
new AsciiColumn("Username", maxWidth: 15),
|
||||
new AsciiColumn("Forced nickname")
|
||||
);
|
||||
|
||||
if (string.IsNullOrEmpty(displayString))
|
||||
displayString = "Not found any forced nicknames.";
|
||||
foreach (var forcedNickname in forcedNicknames)
|
||||
{
|
||||
var username = await ctx.GetUserNameAsync(forcedNickname.UserId).ConfigureAwait(false);
|
||||
table.Add(forcedNickname.UserId.ToString(), username, forcedNickname.Nickname);
|
||||
}
|
||||
|
||||
await ctx.RespondAsync(displayString).ConfigureAwait(false);
|
||||
await ctx.RespondAsync(table.ToString()).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace CompatBot
|
||||
public static int BuildNumberDifferenceForOutdatedBuilds => config.GetValue(nameof(BuildNumberDifferenceForOutdatedBuilds), 10);
|
||||
public static int MinimumPiracyTriggerLength => config.GetValue(nameof(MinimumPiracyTriggerLength), 4);
|
||||
public static int MaxSyscallResultLines => config.GetValue(nameof(MaxSyscallResultLines), 13);
|
||||
|
||||
public static int ForcedNicknamesRecheckTimeInSeconds => config.GetValue(nameof(ForcedNicknamesRecheckTimeInSeconds), 3 * 60 * 60);
|
||||
public static string Token => config.GetValue(nameof(Token), "");
|
||||
public static string LogPath => config.GetValue(nameof(LogPath), "./logs/"); // paths are relative to the working directory
|
||||
public static string IrdCachePath => config.GetValue(nameof(IrdCachePath), "./ird/");
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace CompatBot.Database
|
||||
modelBuilder.Entity<Stats>().HasIndex(s => new { s.Category, s.Key }).IsUnique().HasName("stats_category_key");
|
||||
modelBuilder.Entity<Kot>().HasIndex(k => k.UserId).IsUnique().HasName("kot_user_id");
|
||||
modelBuilder.Entity<Doggo>().HasIndex(d => d.UserId).IsUnique().HasName("doggo_user_id");
|
||||
modelBuilder.Entity<ForcedNickname>().HasIndex(d => d.UserId).IsUnique().HasName("forced_nickname_user_id");
|
||||
modelBuilder.Entity<ForcedNickname>().HasIndex(d => new { d.UserId, d.GuildId }).IsUnique().HasName("forced_nickname_user_id_guild_id");
|
||||
|
||||
//configure default policy of Id being the primary key
|
||||
modelBuilder.ConfigureDefaultPkConvention();
|
||||
@@ -178,8 +178,8 @@ namespace CompatBot.Database
|
||||
internal class ForcedNickname
|
||||
{
|
||||
public int Id { get; set; }
|
||||
[Required]
|
||||
public ulong UserId { set; get; }
|
||||
public ulong GuildId { set; get; }
|
||||
[Required]
|
||||
public string Nickname { get; set; }
|
||||
}
|
||||
|
||||
@@ -141,27 +141,29 @@ namespace CompatBot.Database.Migrations
|
||||
});
|
||||
|
||||
modelBuilder.Entity("CompatBot.Database.ForcedNickname", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnName("id");
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.IsRequired()
|
||||
.HasColumnName("nickname");
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnName("guild_id");
|
||||
|
||||
b.Property<ulong>("UserId")
|
||||
.HasColumnName("user_id");
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnName("nickname");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("id");
|
||||
b.Property<ulong>("UserId")
|
||||
.HasColumnName("user_id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique()
|
||||
.HasName("blacklisted_user_user_id");
|
||||
b.HasKey("Id")
|
||||
.HasName("id");
|
||||
|
||||
b.ToTable("forced_nicknames");
|
||||
});
|
||||
b.HasIndex("UserId", "GuildId")
|
||||
.IsUnique()
|
||||
.HasName("forced_nickname_user_id_guild_id");
|
||||
|
||||
b.ToTable("forced_nicknames");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("CompatBot.Database.Kot", b =>
|
||||
{
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace CompatBot.Database.Migrations
|
||||
id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
user_id = table.Column<ulong>(nullable: false),
|
||||
nickname = table.Column<string>(nullable: false)
|
||||
guild_id = table.Column<ulong>(nullable: false),
|
||||
nickname = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
@@ -21,9 +22,9 @@ namespace CompatBot.Database.Migrations
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "blacklisted_user_user_id",
|
||||
name: "forced_nickname_user_id_guild_id",
|
||||
table: "forced_nicknames",
|
||||
column: "user_id",
|
||||
columns: new[] { "user_id", "guild_id" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,27 +139,29 @@ namespace CompatBot.Database.Migrations
|
||||
});
|
||||
|
||||
modelBuilder.Entity("CompatBot.Database.ForcedNickname", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnName("id");
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.IsRequired()
|
||||
.HasColumnName("nickname");
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnName("guild_id");
|
||||
|
||||
b.Property<ulong>("UserId")
|
||||
.HasColumnName("user_id");
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnName("nickname");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("id");
|
||||
b.Property<ulong>("UserId")
|
||||
.HasColumnName("user_id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique()
|
||||
.HasName("blacklisted_user_user_id");
|
||||
b.HasKey("Id")
|
||||
.HasName("id");
|
||||
|
||||
b.ToTable("forced_nicknames");
|
||||
});
|
||||
b.HasIndex("UserId", "GuildId")
|
||||
.IsUnique()
|
||||
.HasName("forced_nickname_user_id_guild_id");
|
||||
|
||||
b.ToTable("forced_nicknames");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("CompatBot.Database.Kot", b =>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CompatBot.Database;
|
||||
using CompatBot.Utils;
|
||||
@@ -11,29 +13,26 @@ namespace CompatBot.EventHandlers
|
||||
{
|
||||
public static class UsernameValidationMonitor
|
||||
{
|
||||
public static async Task OnUserUpdated(UserUpdateEventArgs args)
|
||||
{
|
||||
await UpdateDisplayName(args.Client, () => args.Client.GetMember(args.UserAfter)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task OnMemberUpdated(GuildMemberUpdateEventArgs args)
|
||||
{
|
||||
await UpdateDisplayName(args.Client, () => args.Member).ConfigureAwait(false);
|
||||
}
|
||||
await UpdateDisplayName(args.Guild.CurrentMember, args.Member).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task OnMemberAdded(GuildMemberAddEventArgs args)
|
||||
{
|
||||
await UpdateDisplayName(args.Client, () => args.Member).ConfigureAwait(false);
|
||||
await UpdateDisplayName(args.Guild.CurrentMember, args.Member).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task UpdateDisplayName(DiscordClient client, Func<DiscordMember> getGuildMember)
|
||||
private static async Task UpdateDisplayName(DiscordMember bot, DiscordMember guildMember)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (guildMember.IsWhitelisted())
|
||||
return;
|
||||
|
||||
using (var context = new BotDb())
|
||||
{
|
||||
var guildMember = getGuildMember();
|
||||
var forcedNickname = await context.ForcedNicknames.FirstOrDefaultAsync(x => x.UserId == guildMember.Id).ConfigureAwait(false);
|
||||
var forcedNickname = await context.ForcedNicknames.FirstOrDefaultAsync(x => x.UserId == guildMember.Id && x.GuildId == guildMember.Guild.Id).ConfigureAwait(false);
|
||||
if (forcedNickname is null)
|
||||
return;
|
||||
|
||||
@@ -41,13 +40,6 @@ namespace CompatBot.EventHandlers
|
||||
return;
|
||||
|
||||
await guildMember.ModifyAsync(x => x.Nickname = forcedNickname.Nickname).ConfigureAwait(false);
|
||||
|
||||
await client.ReportAsync(
|
||||
"User nickname was changed.",
|
||||
$"",
|
||||
null,
|
||||
ReportSeverity.Low
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -55,5 +47,52 @@ namespace CompatBot.EventHandlers
|
||||
Config.Log.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly IList<DiscordGuild> AvailableGuilds = new List<DiscordGuild>();
|
||||
|
||||
public static void SetupGuilds(IEnumerable<DiscordGuild>guilds)
|
||||
{
|
||||
foreach (var discordGuild in guilds)
|
||||
{
|
||||
AvailableGuilds.Add(discordGuild);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task MonitorAsync()
|
||||
{
|
||||
while (!Config.Cts.IsCancellationRequested)
|
||||
{
|
||||
if (!AvailableGuilds.Any())
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(3), Config.Cts.Token).ConfigureAwait(false);
|
||||
continue;
|
||||
}
|
||||
foreach (var guild in AvailableGuilds)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var context = new BotDb())
|
||||
{
|
||||
var forcedNicknames = await context.ForcedNicknames.Where(x=>x.GuildId == guild.Id).ToDictionaryAsync(x => x.UserId).ConfigureAwait(false);
|
||||
var membersToUpdate = guild.Members.Where(x => forcedNicknames.ContainsKey(x.Key))
|
||||
.Select(x => (discordMember: x.Value, forcedNickname: forcedNicknames[x.Key]))
|
||||
.Where(x => x.discordMember.DisplayName != x.forcedNickname.Nickname)
|
||||
.ToList();
|
||||
|
||||
foreach (var (discordMember, forcedNickname) in membersToUpdate)
|
||||
{
|
||||
await discordMember.ModifyAsync(x => x.Nickname = forcedNickname.Nickname).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Config.Log.Error(e);
|
||||
}
|
||||
}
|
||||
await Task.Delay(TimeSpan.FromSeconds(Config.ForcedNicknamesRecheckTimeInSeconds), Config.Cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,6 +190,11 @@ namespace CompatBot
|
||||
}
|
||||
Config.Log.Info($"All moderation backlogs checked in {gaArgs.Guild.Name}.");
|
||||
};
|
||||
client.GuildDownloadCompleted += async gdcArgs =>
|
||||
{
|
||||
UsernameValidationMonitor.SetupGuilds(gdcArgs.Guilds.Select(x => x.Value).ToList());
|
||||
await Task.CompletedTask;
|
||||
};
|
||||
client.GuildUnavailable += guArgs =>
|
||||
{
|
||||
Config.Log.Warn($"{guArgs.Guild.Name} is unavailable");
|
||||
@@ -310,13 +315,14 @@ namespace CompatBot
|
||||
Config.Log.Debug("Args: " + string.Join(" ", pArgs));
|
||||
}
|
||||
|
||||
Config.Log.Debug("Running RPCS3 update check thread");
|
||||
backgroundTasks = Task.WhenAll(
|
||||
backgroundTasks,
|
||||
NewBuildsMonitor.MonitorAsync(client),
|
||||
Watchdog.Watch(client),
|
||||
InviteWhitelistProvider.CleanupAsync(client)
|
||||
);
|
||||
Config.Log.Debug("Running RPCS3 update check thread");
|
||||
backgroundTasks = Task.WhenAll(
|
||||
backgroundTasks,
|
||||
NewBuildsMonitor.MonitorAsync(client),
|
||||
Watchdog.Watch(client),
|
||||
InviteWhitelistProvider.CleanupAsync(client),
|
||||
UsernameValidationMonitor.MonitorAsync()
|
||||
);
|
||||
|
||||
while (!Config.Cts.IsCancellationRequested)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user