Fixed plugin reloading
This commit is contained in:
@@ -23,5 +23,5 @@ public interface IPluginLoader
|
||||
/// <summary>
|
||||
/// Unload all plugins from the plugin manager.
|
||||
/// </summary>
|
||||
public void UnloadAllPlugins();
|
||||
public Task UnloadAllPlugins();
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using DiscordBotCore.Logging;
|
||||
using DiscordBotCore.PluginCore.Helpers.Execution.DbEvent;
|
||||
using DiscordBotCore.PluginCore.Interfaces;
|
||||
using DiscordBotCore.PluginManagement.Loading.Exceptions;
|
||||
using DiscordBotCore.Utilities.Responses;
|
||||
|
||||
namespace DiscordBotCore.PluginManagement.Loading;
|
||||
|
||||
@@ -24,8 +25,7 @@ public class PluginLoader : IPluginLoader
|
||||
private readonly List<IDbCommand> _Commands = new List<IDbCommand>();
|
||||
private readonly List<IDbEvent> _Events = new List<IDbEvent>();
|
||||
private readonly List<IDbSlashCommand> _SlashCommands = new List<IDbSlashCommand>();
|
||||
|
||||
private bool _IsFirstLoad = true;
|
||||
private readonly List<SocketApplicationCommand> _ApplicationCommands = new List<SocketApplicationCommand>();
|
||||
|
||||
public PluginLoader(IPluginManager pluginManager, ILogger logger, IConfiguration configuration)
|
||||
{
|
||||
@@ -57,11 +57,16 @@ public class PluginLoader : IPluginLoader
|
||||
|
||||
public async Task LoadPlugins()
|
||||
{
|
||||
UnloadAllPlugins();
|
||||
if (PluginLoaderContext is not null)
|
||||
{
|
||||
_Logger.Log("The plugins are already loaded", this, LogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_Events.Clear();
|
||||
_Commands.Clear();
|
||||
_SlashCommands.Clear();
|
||||
_ApplicationCommands.Clear();
|
||||
|
||||
await LoadPluginFiles();
|
||||
|
||||
@@ -88,37 +93,45 @@ public class PluginLoader : IPluginLoader
|
||||
_Logger.Log("Loaded plugins", this);
|
||||
}
|
||||
|
||||
public void UnloadAllPlugins()
|
||||
public async Task UnloadAllPlugins()
|
||||
{
|
||||
if (_IsFirstLoad)
|
||||
{
|
||||
// Allow unloading only after the first load
|
||||
_IsFirstLoad = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PluginLoaderContext is null)
|
||||
{
|
||||
_Logger.Log("The plugins are not loaded. Please load the plugins before unloading them.", this, LogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
await UnloadSlashCommands();
|
||||
|
||||
PluginLoaderContext.Unload();
|
||||
PluginLoaderContext = null;
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
PluginLoaderContext = null;
|
||||
|
||||
}
|
||||
|
||||
private async Task UnloadSlashCommands()
|
||||
{
|
||||
if (_DiscordClient is null)
|
||||
{
|
||||
_Logger.Log("The client is not set. Please set the client before unloading slash commands.", this, LogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (SocketApplicationCommand command in _ApplicationCommands)
|
||||
{
|
||||
await command.DeleteAsync();
|
||||
}
|
||||
|
||||
_ApplicationCommands.Clear();
|
||||
_Logger.Log("Unloaded all slash commands", this);
|
||||
}
|
||||
|
||||
private async Task LoadPluginFiles()
|
||||
{
|
||||
if (PluginLoaderContext is not null)
|
||||
{
|
||||
_Logger.Log("The plugins are already loaded", this, LogType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var installedPlugins = await _PluginManager.GetInstalledPlugins();
|
||||
|
||||
if (installedPlugins.Count == 0)
|
||||
@@ -314,34 +327,45 @@ public class PluginLoader : IPluginLoader
|
||||
builder.WithContextTypes(InteractionContextType.Guild);
|
||||
|
||||
List<ulong> serverIds = _Configuration.GetList("ServerIds", new List<ulong>());
|
||||
|
||||
foreach(ulong guildId in serverIds)
|
||||
{
|
||||
bool result = await EnableSlashCommandPerGuild(guildId, builder);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
_Logger.Log($"Failed to enable slash command {dbSlashCommand.Name} for guild {guildId}", this, LogType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
await _DiscordClient.CreateGlobalApplicationCommandAsync(builder.Build());
|
||||
|
||||
if (serverIds.Any())
|
||||
{
|
||||
foreach(ulong guildId in serverIds)
|
||||
{
|
||||
IResponse<SocketApplicationCommand> result = await EnableSlashCommandPerGuild(guildId, builder);
|
||||
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
_Logger.Log($"Failed to enable slash command {dbSlashCommand.Name} for guild {guildId}", this, LogType.Error);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result.Data is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_ApplicationCommands.Add(result.Data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var command = await _DiscordClient.CreateGlobalApplicationCommandAsync(builder.Build());
|
||||
_ApplicationCommands.Add(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> EnableSlashCommandPerGuild(ulong guildId, SlashCommandBuilder builder)
|
||||
private async Task<IResponse<SocketApplicationCommand>> EnableSlashCommandPerGuild(ulong guildId, SlashCommandBuilder builder)
|
||||
{
|
||||
SocketGuild? guild = _DiscordClient?.GetGuild(guildId);
|
||||
if (guild is null)
|
||||
{
|
||||
_Logger.Log("Failed to get guild with ID " + guildId, this, LogType.Error);
|
||||
return false;
|
||||
return Response<SocketApplicationCommand>.Failure("Failed to get guild with ID " + guildId);
|
||||
}
|
||||
|
||||
await guild.CreateApplicationCommandAsync(builder.Build());
|
||||
|
||||
return true;
|
||||
var command = await guild.CreateApplicationCommandAsync(builder.Build());
|
||||
return Response<SocketApplicationCommand>.Success(command);
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@ public class DiscordBotApplication : IDiscordBotApplication
|
||||
return;
|
||||
}
|
||||
|
||||
await _PluginLoader.UnloadAllPlugins();
|
||||
|
||||
await Client.LogoutAsync();
|
||||
await Client.StopAsync();
|
||||
|
||||
@@ -54,6 +56,7 @@ public class DiscordBotApplication : IDiscordBotApplication
|
||||
|
||||
await Client.DisposeAsync();
|
||||
|
||||
|
||||
IsReady = false;
|
||||
|
||||
}
|
||||
@@ -73,7 +76,7 @@ public class DiscordBotApplication : IDiscordBotApplication
|
||||
};
|
||||
|
||||
DiscordSocketClient client = new DiscordSocketClient(config);
|
||||
Client = client;
|
||||
|
||||
|
||||
_Service = new CommandService();
|
||||
|
||||
@@ -82,8 +85,8 @@ public class DiscordBotApplication : IDiscordBotApplication
|
||||
client.Ready += Ready;
|
||||
client.Disconnected += Client_Disconnected;
|
||||
|
||||
Client = client;
|
||||
await client.LoginAsync(TokenType.Bot, _Configuration.Get<string>("token"));
|
||||
|
||||
await client.StartAsync();
|
||||
|
||||
_CommandServiceHandler = new CommandHandler(_Logger, _PluginLoader, _Configuration, _Service);
|
||||
|
||||
@@ -13,8 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{EA4F
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LevelingSystem", "Plugins\LevelingSystem\LevelingSystem.csproj", "{FCE9743F-7EB4-4639-A080-FCDDFCC7D689}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicPlayer", "Plugins\MusicPlayer\MusicPlayer.csproj", "{F3C61A47-F758-4145-B496-E3ECCF979D89}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppCompatibilityModule", "Modules\CppCompatibilityModule\CppCompatibilityModule.csproj", "{C67908F9-4A55-4DD8-B993-C26C648226F1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotCore.PluginCore", "DiscordBotCore.PluginCore\DiscordBotCore.PluginCore.csproj", "{B5725C86-2633-4C7A-A6A4-49AAA2767E54}"
|
||||
@@ -77,18 +75,6 @@ Global
|
||||
{FCE9743F-7EB4-4639-A080-FCDDFCC7D689}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{FCE9743F-7EB4-4639-A080-FCDDFCC7D689}.Release|x64.ActiveCfg = Release|x64
|
||||
{FCE9743F-7EB4-4639-A080-FCDDFCC7D689}.Release|x64.Build.0 = Release|x64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Debug|x64.Build.0 = Debug|x64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Release|x64.ActiveCfg = Release|x64
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89}.Release|x64.Build.0 = Release|x64
|
||||
{C67908F9-4A55-4DD8-B993-C26C648226F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C67908F9-4A55-4DD8-B993-C26C648226F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C67908F9-4A55-4DD8-B993-C26C648226F1}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
@@ -251,7 +237,6 @@ Global
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{FCE9743F-7EB4-4639-A080-FCDDFCC7D689} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
||||
{F3C61A47-F758-4145-B496-E3ECCF979D89} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
||||
{C67908F9-4A55-4DD8-B993-C26C648226F1} = {EA4FA308-7B2C-458E-8485-8747D745DD59}
|
||||
{9A4B98C1-00AC-481C-BE55-A70C0B9D3BE7} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
||||
{94238D37-60C6-4E40-80EC-4B4D242F5914} = {8F27B3EA-F292-40DF-B9B3-4B0E6BEA4E70}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
private async Task DeletePluginButtonClick(InstalledPlugin plugin)
|
||||
{
|
||||
PluginLoader.UnloadAllPlugins();
|
||||
await PluginLoader.UnloadAllPlugins();
|
||||
|
||||
Logger.Log($"Deleting plugin {plugin.Name}", this);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
Save <i class="bi bi-check-lg"></i>
|
||||
Save
|
||||
</button>
|
||||
</EditForm>
|
||||
</CenteredCard>
|
||||
|
||||
Reference in New Issue
Block a user