feat: User Count Channel

This commit is contained in:
Mira 2025-05-07 19:49:03 +02:00
parent 1c3aa23a76
commit 50c60bf0da
Signed by untrusted user who does not match committer: Xorog
GPG key ID: 983798ED9C3E7C36
5 changed files with 170 additions and 1 deletions

View file

@ -26,6 +26,8 @@ internal sealed class JoinCommand : BaseCommand
var pad = TranslationUtil.CalculatePadding(ctx.DbUser,
CommandKey.Autoban,
CommandKey.JoinLogChannel,
CommandKey.UserCountChannel,
CommandKey.UserCountChannelFormat,
CommandKey.Role,
CommandKey.ReApplyRoles,
CommandKey.ReApplyNickname,
@ -35,6 +37,7 @@ internal sealed class JoinCommand : BaseCommand
return $"{"🌐".UnicodeToEmoji()} `{CommandKey.Autoban.Get(ctx.DbUser).PadRight(pad)}`: {ctx.DbGuild.Join.AutoBanGlobalBans.ToEmote(ctx.Bot)}\n" +
$"{"👋".UnicodeToEmoji()} `{CommandKey.JoinLogChannel.Get(ctx.DbUser).PadRight(pad)}`: {(ctx.DbGuild.Join.JoinlogChannelId != 0 ? $"<#{ctx.DbGuild.Join.JoinlogChannelId}>" : false.ToEmote(ctx.Bot))}\n" +
$"{"🔢".UnicodeToEmoji()} `{CommandKey.UserCountChannel.Get(ctx.DbUser).PadRight(pad)}`: {(ctx.DbGuild.Join.UserCountChannelId != 0 ? $"<#{ctx.DbGuild.Join.UserCountChannelId}> (`{(ctx.DbGuild.Join.UserCountChannelFormat is not null ? ctx.DbGuild.Join.UserCountChannelFormat : "Users: %s")}`)" : false.ToEmote(ctx.Bot))}\n" +
$"{"👤".UnicodeToEmoji()} `{CommandKey.Role.Get(ctx.DbUser).PadRight(pad)}`: {(ctx.DbGuild.Join.AutoAssignRoleId != 0 ? $"<@&{ctx.DbGuild.Join.AutoAssignRoleId}>" : false.ToEmote(ctx.Bot))}\n" +
$"{"👥".UnicodeToEmoji()} `{CommandKey.ReApplyRoles.Get(ctx.DbUser).PadRight(pad)}`: {ctx.DbGuild.Join.ReApplyRoles.ToEmote(ctx.Bot)}\n" +
$"{"💬".UnicodeToEmoji()} `{CommandKey.ReApplyNickname.Get(ctx.DbUser).PadRight(pad)}`: {ctx.DbGuild.Join.ReApplyNickname.ToEmote(ctx.Bot)}\n\n" +
@ -57,6 +60,8 @@ internal sealed class JoinCommand : BaseCommand
var ToggleGlobalban = new DiscordButtonComponent((ctx.DbGuild.Join.AutoBanGlobalBans ? ButtonStyle.Danger : ButtonStyle.Success), Guid.NewGuid().ToString(), this.GetString(CommandKey.ToggleGlobalBansButton), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("🌐")));
var ChangeJoinlogChannel = new DiscordButtonComponent(ButtonStyle.Primary, Guid.NewGuid().ToString(), this.GetString(CommandKey.ChangeJoinlogChannelButton), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("👋")));
var ChangeUserCountChannel = new DiscordButtonComponent(ButtonStyle.Primary, Guid.NewGuid().ToString(), this.GetString(CommandKey.ChangeUserCountChannel), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("🔢")));
var ChangeUserCountFormat = new DiscordButtonComponent(ButtonStyle.Primary, Guid.NewGuid().ToString(), this.GetString(CommandKey.ChangeUserCountChannelFormat), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("🔢")));
var ChangeRoleOnJoin = new DiscordButtonComponent(ButtonStyle.Primary, Guid.NewGuid().ToString(), this.GetString(CommandKey.ChangeRoleButton), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("👤")));
var ToggleReApplyRoles = new DiscordButtonComponent((ctx.DbGuild.Join.ReApplyRoles ? ButtonStyle.Danger : ButtonStyle.Success), Guid.NewGuid().ToString(), this.GetString(CommandKey.ToggleReApplyRole), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("👥")));
var ToggleReApplyName = new DiscordButtonComponent((ctx.DbGuild.Join.ReApplyNickname ? ButtonStyle.Danger : ButtonStyle.Success), Guid.NewGuid().ToString(), this.GetString(CommandKey.ToggleReApplyNickname), false, new DiscordComponentEmoji(DiscordEmoji.FromUnicode("💬")));
@ -76,6 +81,8 @@ internal sealed class JoinCommand : BaseCommand
{
ChangeJoinlogChannel,
ChangeRoleOnJoin,
ChangeUserCountChannel,
ChangeUserCountFormat,
})
.AddComponents(new List<DiscordComponent>
{
@ -93,7 +100,8 @@ internal sealed class JoinCommand : BaseCommand
return;
}
_ = e.Result.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate);
if (e.GetCustomId() != ChangeUserCountFormat.CustomId)
_ = e.Result.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate);
if (e.GetCustomId() == ToggleGlobalban.CustomId)
{
@ -156,6 +164,81 @@ internal sealed class JoinCommand : BaseCommand
await this.ExecuteCommand(ctx, arguments);
return;
}
else if (e.GetCustomId() == ChangeUserCountChannel.CustomId)
{
var ChannelResult = await this.PromptChannelSelection(ChannelType.Text, new ChannelPromptConfiguration
{
CreateChannelOption = new()
{
Name = "tmp-usercount",
ChannelType = ChannelType.Text
},
DisableOption = this.GetString(CommandKey.DisableUserCountChannel)
});
if (ChannelResult.TimedOut)
{
this.ModifyToTimedOut(true);
return;
}
else if (ChannelResult.Cancelled)
{
await this.ExecuteCommand(ctx, arguments);
return;
}
else if (ChannelResult.Failed)
{
if (ChannelResult.Exception.GetType() == typeof(NullReferenceException))
{
_ = await this.RespondOrEdit(new DiscordEmbedBuilder().AsError(ctx).WithDescription(this.GetString(this.t.Commands.Common.Errors.NoChannels)));
await Task.Delay(3000);
await this.ExecuteCommand(ctx, arguments);
return;
}
throw ChannelResult.Exception;
}
ctx.DbGuild.Join.UserCountChannelId = ChannelResult.Result is null ? 0 : ChannelResult.Result.Id;
await this.ExecuteCommand(ctx, arguments);
return;
}
else if (e.GetCustomId() == ChangeUserCountFormat.CustomId)
{
var modelResult = await this.PromptModalWithRetry(e.Result.Interaction,
new DiscordInteractionModalBuilder(this.GetString(CommandKey.ChangeUserCountChannelFormat))
.AddTextComponent(new DiscordTextComponent(TextComponentStyle.Small, "new_format", this.GetString(CommandKey.ChangeUserCountChannelFormatModal), null, 2, 16)),
false);
if (modelResult.TimedOut)
{
this.ModifyToTimedOut(true);
return;
}
else if (modelResult.Cancelled)
{
await this.ExecuteCommand(ctx, arguments);
return;
}
else if (modelResult.Failed)
{
if (modelResult.Exception.GetType() == typeof(NullReferenceException))
{
_ = await this.RespondOrEdit(new DiscordEmbedBuilder().AsError(ctx).WithDescription(this.GetString(this.t.Commands.Common.Errors.NoChannels)));
await Task.Delay(3000);
await this.ExecuteCommand(ctx, arguments);
return;
}
throw modelResult.Exception;
}
ctx.DbGuild.Join.UserCountChannelFormat = modelResult.Result.Interaction.GetModalValueByCustomId("new_format");
await this.ExecuteCommand(ctx, arguments);
return;
}
else if (e.GetCustomId() == ChangeRoleOnJoin.CustomId)
{
var RoleResult = await this.PromptRoleSelection(new RolePromptConfiguration { CreateRoleOption = this.GetString(CommandKey.AutoAssignRoleName), DisableOption = this.GetString(CommandKey.DisableRoleOnJoin) });

View file

@ -24,6 +24,27 @@ public sealed class JoinSettings(Bot bot, Guild parent) : RequiresParent<Guild>(
get => this.Bot.DatabaseClient.GetValue<ulong>("guilds", "serverid", this.Parent.Id, "joinlog_channel_id", this.Bot.DatabaseClient.mainDatabaseConnection);
set => _ = this.Bot.DatabaseClient.SetValue("guilds", "serverid", this.Parent.Id, "joinlog_channel_id", value, this.Bot.DatabaseClient.mainDatabaseConnection);
}
[ColumnName("usercount_channel_last_edit"), ColumnType(ColumnTypes.BigInt), Default("0")]
public DateTime UserCountChannelLastEdit
{
get => this.Bot.DatabaseClient.GetValue<DateTime>("guilds", "serverid", this.Parent.Id, "usercount_channel_last_edit", this.Bot.DatabaseClient.mainDatabaseConnection);
set => _ = this.Bot.DatabaseClient.SetValue("guilds", "serverid", this.Parent.Id, "usercount_channel_last_edit", value, this.Bot.DatabaseClient.mainDatabaseConnection);
}
[ColumnName("usercount_channel_id"), ColumnType(ColumnTypes.BigInt), Default("0")]
public ulong UserCountChannelId
{
get => this.Bot.DatabaseClient.GetValue<ulong>("guilds", "serverid", this.Parent.Id, "usercount_channel_id", this.Bot.DatabaseClient.mainDatabaseConnection);
set => _ = this.Bot.DatabaseClient.SetValue("guilds", "serverid", this.Parent.Id, "usercount_channel_id", value, this.Bot.DatabaseClient.mainDatabaseConnection);
}
[ColumnName("usercount_channel_format"), ColumnType(ColumnTypes.Text), Nullable]
public string? UserCountChannelFormat
{
get => this.Bot.DatabaseClient.GetValue<string?>("guilds", "serverid", this.Parent.Id, "usercount_channel_format", this.Bot.DatabaseClient.mainDatabaseConnection);
set => _ = this.Bot.DatabaseClient.SetValue("guilds", "serverid", this.Parent.Id, "usercount_channel_format", value, this.Bot.DatabaseClient.mainDatabaseConnection);
}
[ColumnName("autoban_global_ban"), ColumnType(ColumnTypes.TinyInt), Default("0")]
public bool AutoBanGlobalBans

View file

@ -380,11 +380,15 @@ public class Translations : ITranslations
public SingleTranslationKey CantUseRole;
public SingleTranslationKey DisableRoleOnJoin;
public SingleTranslationKey AutoAssignRoleName;
public SingleTranslationKey DisableUserCountChannel;
public SingleTranslationKey DisableJoinlog;
public SingleTranslationKey JoinLogChannelName;
public SingleTranslationKey ToggleReApplyNickname;
public SingleTranslationKey ToggleReApplyRole;
public SingleTranslationKey ChangeRoleButton;
public SingleTranslationKey ChangeUserCountChannelFormatModal;
public SingleTranslationKey ChangeUserCountChannelFormat;
public SingleTranslationKey ChangeUserCountChannel;
public SingleTranslationKey ChangeJoinlogChannelButton;
public SingleTranslationKey ToggleGlobalBansButton;
public SingleTranslationKey TimeNotice;
@ -392,6 +396,8 @@ public class Translations : ITranslations
public SingleTranslationKey ReApplyNickname;
public SingleTranslationKey ReApplyRoles;
public SingleTranslationKey Role;
public SingleTranslationKey UserCountChannelFormat;
public SingleTranslationKey UserCountChannel;
public SingleTranslationKey JoinLogChannel;
public SingleTranslationKey Autoban;
public SingleTranslationKey Title;

View file

@ -54,6 +54,7 @@ internal sealed class JoinEvents(Bot bot) : RequiresTranslation(bot)
}
}
await this.RunUserCountUpdater(e.Guild);
await this.Bot.Guilds[e.Guild.Id].Members[e.Member.Id].PerformAutoKickChecks(e.Guild, e.Member);
}
@ -81,5 +82,39 @@ internal sealed class JoinEvents(Bot bot) : RequiresTranslation(bot)
});
}
}
await this.RunUserCountUpdater(e.Guild);
}
private async Task RunUserCountUpdater(DiscordGuild Guild)
{
if (this.Bot.Guilds[Guild.Id].Join.UserCountChannelId != 0)
{
if (Guild.Channels.ContainsKey(this.Bot.Guilds[Guild.Id].Join.UserCountChannelId))
{
foreach (var b in ScheduledTaskExtensions.GetScheduledTasks())
{
if (b.CustomData is not ScheduledTaskIdentifier scheduledTaskIdentifier)
continue;
if (scheduledTaskIdentifier.Snowflake == Guild.Id && scheduledTaskIdentifier.Type == "usercount")
b.Delete();
}
_ = new Func<Task>(async () =>
{
_ = Guild.GetChannel(this.Bot.Guilds[Guild.Id].Join.UserCountChannelId).ModifyAsync(x =>
{
x.Name = (this.Bot.Guilds[Guild.Id].Join.UserCountChannelFormat is null ? "Count: %s" : this.Bot.Guilds[Guild.Id].Join.UserCountChannelFormat)
.Replace("%s", Guild.MemberCount);
})
.ContinueWith(x =>
{
this.Bot.Guilds[Guild.Id].Join.UserCountChannelLastEdit = DateTime.UtcNow;
});
}).CreateScheduledTask(this.Bot.Guilds[Guild.Id].Join.UserCountChannelLastEdit.AddMinutes(5),
new ScheduledTaskIdentifier(Guild.Id, "", "usercount"));
}
}
}
}

View file

@ -3780,6 +3780,14 @@
"en": "Joinlog Channel",
"de": "Beitrittsprotokoll-Kanal"
},
"UserCountChannel": {
"en": "User Count Channel",
"de": "Benutzeranzahl-Kanal"
},
"UserCountChannelFormat": {
"en": "User Count Format",
"de": "Benutzeranzahl-Format"
},
"Role": {
"en": "Role On Join",
"de": "Rolle beim Beitritt"
@ -3808,6 +3816,18 @@
"en": "Change Joinlog Channel",
"de": "Beitrittsprotokoll-Kanal ändern"
},
"ChangeUserCountChannel": {
"en": "Change User Count Channel",
"de": "Benutzeranzahl-Kanal ändern"
},
"ChangeUserCountChannelFormat": {
"en": "Change User Count Format",
"de": "Benutzeranzahl-Format ändern"
},
"ChangeUserCountChannelFormatModal": {
"en": "User Count Format | %s as placeholder",
"de": "Benutzeranzahl-Format | %s für Platzhalter"
},
"ChangeRoleButton": {
"en": "Change Role assigned on join",
"de": "Beim Beitritt zugewiesene Rolle ändern"
@ -3828,6 +3848,10 @@
"en": "Disable Joinlog",
"de": "Beitrittsprotokoll deaktivieren"
},
"DisableUserCountChannel": {
"en": "Disable User Count Channel",
"de": "Benutzeranzahl-Kanal deaktivieren"
},
"AutoAssignRoleName": {
"en": "Automatically Assigned Role",
"de": "Automatisch zugewiesene Rolle"