diff --git a/DiscordLab.Bot/Client.cs b/DiscordLab.Bot/Client.cs
index fca8fe8..eb21b2b 100644
--- a/DiscordLab.Bot/Client.cs
+++ b/DiscordLab.Bot/Client.cs
@@ -1,5 +1,4 @@
// ReSharper disable MemberCanBePrivate.Global
-
namespace DiscordLab.Bot;
using System.Net;
@@ -16,7 +15,6 @@ namespace DiscordLab.Bot;
using DiscordLab.Bot.API.Features;
using LabApi.Features.Console;
using NorthwoodLib.Pools;
-
///
/// The Discord bot client.
///
@@ -26,39 +24,25 @@ public static class Client
/// Gets the websocket client for the Discord bot.
///
public static DiscordSocketClient SocketClient { get; private set; } = null!;
-
- ///
+ ///
/// Gets a value indicating whether the client is in the ready state.
///
public static bool IsClientReady { get; private set; }
-
///
/// Gets a list of saved text channels listed by their ID.
///
public static Dictionary SavedTextChannels { get; private set; } = new();
-
///
/// Gets the default guild for the plugin.
///
public static SocketGuild? DefaultGuild { get; private set; }
private static Config Config => Plugin.Instance.Config;
+
- ///
- /// Gets a cached guild from a ID.
- ///
- /// The guild ID.
- /// If the ID is 0, then the default guild (if it exists), if else then it will return the found guild, or null.
public static SocketGuild? GetGuild(ulong id)
- {
- return id == 0 ? DefaultGuild : SocketClient.GetGuild(id);
- }
+ => id == 0 ? DefaultGuild : SocketClient.GetGuild(id);
- ///
- /// Gets or adds a channel via its ID. Uses cache.
- ///
- /// The ID of the channel.
- /// The channel, if found.
public static SocketTextChannel? GetOrAddChannel(ulong id)
{
if (id == 0)
@@ -67,8 +51,7 @@ public static class Client
if (SavedTextChannels.TryGetValue(id, out SocketTextChannel ret))
return ret;
- SocketChannel channel = SocketClient.GetChannel(id);
- if (channel is not SocketTextChannel text)
+ if (SocketClient.GetChannel(id) is not SocketTextChannel text)
return null;
SavedTextChannels.Add(id, text);
@@ -76,27 +59,18 @@ public static class Client
}
#nullable disable
- ///
- /// Tries to get or add a channel via its ID. Uses cache.
- ///
- /// The ID of the channel.
- /// The channel, if found.
- /// Whether the channel was found.
public static bool TryGetOrAddChannel(ulong id, out SocketTextChannel channel)
{
channel = GetOrAddChannel(id);
-
return channel != null;
}
#nullable restore
- ///
- /// Starts the bot.
- ///
[CallOnLoad]
internal static void Start()
{
DebugLog("Starting the Client");
+
DiscordSocketConfig config = new()
{
GatewayIntents = GatewayIntents.All,
@@ -113,42 +87,41 @@ internal static void Start()
config.WebSocketProvider = DefaultWebSocketProvider.Create(proxy);
}
- DebugLog("Done the initial setup...");
-
try
{
SocketClient = new(config);
- DebugLog("Client has been created...");
-
SocketClient.Log += OnLog;
SocketClient.Ready += OnReady;
SocketClient.SlashCommandExecuted += SlashCommandHandler;
SocketClient.AutocompleteExecuted += AutocompleteHandler;
+
+ // ===============================
+ // Privileged intent listeners
+ // ===============================
+ SocketClient.PresenceUpdated += OnPresenceUpdated;
+
+ SocketClient.GuildScheduledEventCreated += _ => Task.CompletedTask;
+ SocketClient.GuildScheduledEventUpdated += (_, _) => Task.CompletedTask;
+ SocketClient.GuildScheduledEventDeleted += _ => Task.CompletedTask;
+
+ SocketClient.InviteCreated += _ => Task.CompletedTask;
+ SocketClient.InviteDeleted += _ => Task.CompletedTask;
}
catch (TargetInvocationException ex) when (ex.InnerException is TypeLoadException)
{
StringBuilder builder = StringBuilderPool.Shared.Rent();
builder.AppendLine("You may have setup DiscordLab incorrectly, or used another Discord bot in the past.");
- builder.AppendLine(
- "Please ensure you have no conflicting dependencies. This can either be triggered by duplication of the Discord dependencies, or Newtonsoft.Json.");
- builder.AppendLine(
- "Some plugins might implement either of the 2 listed dependencies above, so if you have no duplications at all, you will manually need to remove plugins to see the culprit.");
- builder.AppendLine(
- "If you find a plugin that doesn't work with DiscordLab, please join our Discord and report it there with a link to the repository. We can not fix private plugins.");
+ builder.AppendLine("Please ensure you have no conflicting dependencies (Discord or Newtonsoft.Json).");
+ builder.AppendLine("If you find a conflicting plugin, report it with a repository link.");
builder.AppendLine("Discord link: https://discord.gg/XBzuGbsNZK");
Logger.Error(StringBuilderPool.Shared.ToStringReturn(builder));
throw;
}
- DebugLog("Client events subscribed...");
-
Task.RunAndLog(StartClient);
}
- ///
- /// Disables the bot.
- ///
[CallOnUnload]
internal static void Disable()
{
@@ -158,6 +131,8 @@ internal static void Disable()
SocketClient.Ready -= OnReady;
SocketClient.SlashCommandExecuted -= SlashCommandHandler;
SocketClient.AutocompleteExecuted -= AutocompleteHandler;
+ SocketClient.PresenceUpdated -= OnPresenceUpdated;
+
Task.RunAndLog(async () =>
{
await SocketClient.LogoutAsync();
@@ -178,29 +153,30 @@ private static Task OnLog(LogMessage msg)
switch (msg.Exception)
{
case WebSocketException { InnerException: WebSocketClosedException { CloseCode: 4014 } }:
- Logger.Error("DiscordLab requires that you have all Privileged Gateway Intents enabled, you can do this in the \"Bot\" panel of your application. Restart your server when this is complete.");
+ Logger.Error("Privileged Gateway Intents are not enabled in the Discord Developer Portal.");
return Task.CompletedTask;
+
case WebSocketException or GatewayReconnectException when !Config.Debug:
return Task.CompletedTask;
- default:
- switch (msg.Severity)
- {
- case LogSeverity.Error or LogSeverity.Critical:
- Logger.Error(msg);
- break;
- case LogSeverity.Warning:
- Logger.Warn(msg);
- break;
- case LogSeverity.Debug:
- DebugLog(msg);
- break;
- default:
- Logger.Info(msg);
- break;
- }
+ }
- return Task.CompletedTask;
+ switch (msg.Severity)
+ {
+ case LogSeverity.Error or LogSeverity.Critical:
+ Logger.Error(msg);
+ break;
+ case LogSeverity.Warning:
+ Logger.Warn(msg);
+ break;
+ case LogSeverity.Debug:
+ DebugLog(msg);
+ break;
+ default:
+ Logger.Info(msg);
+ break;
}
+
+ return Task.CompletedTask;
}
private static Task OnReady()
@@ -211,30 +187,20 @@ private static Task OnReady()
CallOnReadyAttribute.Ready();
if (Config.Debug)
- {
DebugLog(string.Join("\n", SocketClient.Guilds.Select(GenerateGuildChannelsMessage)));
- }
return Task.CompletedTask;
}
- private static string GenerateGuildChannelsMessage(SocketGuild guild) =>
- $"Guild {guild.Name} ({guild.Id}) channels: {string.Join("\n", guild.Channels.Where(channel => channel is SocketTextChannel).Select(GenerateChannelMessage))}";
-
- private static string GenerateChannelMessage(SocketGuildChannel channel) => $"{channel.Name} ({channel.Id})";
-
private static Task SlashCommandHandler(SocketSlashCommand command)
{
- DebugLog($"{command.Data.Name} requested a response, finding the command...");
SlashCommand? cmd = SlashCommand.Commands.FirstOrDefault(c => c.Data.Name == command.Data.Name);
-
cmd?.Run(command);
return Task.CompletedTask;
}
private static Task AutocompleteHandler(SocketAutocompleteInteraction autocomplete)
{
- DebugLog($"{autocomplete.Data.CommandName} requested a response, finding the command...");
AutocompleteCommand? command =
SlashCommand.Commands.FirstOrDefault(c =>
c is AutocompleteCommand cmd && cmd.Data.Name == autocomplete.Data.CommandName) as AutocompleteCommand;
@@ -243,8 +209,18 @@ private static Task AutocompleteHandler(SocketAutocompleteInteraction autocomple
return Task.CompletedTask;
}
- private static void DebugLog(object message)
+ private static Task OnPresenceUpdated(
+ SocketUser user,
+ SocketPresence before,
+ SocketPresence after)
{
- Logger.Debug(message, Config.Debug);
+ return Task.CompletedTask;
}
-}
\ No newline at end of file
+
+ private static string GenerateGuildChannelsMessage(SocketGuild guild) =>
+ $"Guild {guild.Name} ({guild.Id}) channels:\n" +
+ string.Join("\n", guild.Channels.OfType().Select(c => $"{c.Name} ({c.Id})"));
+
+ private static void DebugLog(object message)
+ => Logger.Debug(message, Config.Debug);
+}