Skip to content

Commit

Permalink
feat(Bot): lab command
Browse files Browse the repository at this point in the history
  • Loading branch information
JayXTQ committed Dec 10, 2024
1 parent a2522ff commit 8a3b884
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 2 deletions.
17 changes: 15 additions & 2 deletions DiscordLab.Bot/API/Modules/UpdateStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public static class UpdateStatus
private static readonly HttpClient Client = new ();

private static readonly string Path = Paths.Plugins;

public static List<API.Features.UpdateStatus> Statuses { get; private set; }

/// <summary>
/// This will write a plugin to the Plugins folder.
Expand All @@ -46,6 +48,16 @@ private static void WritePlugin(byte[] bytes, string name)
string pluginPath = System.IO.Path.Combine(Path, name + ".dll");
File.WriteAllBytes(pluginPath, bytes);
}

/// <summary>
/// This will download a plugin using <see cref="HttpClient"/>
/// </summary>
/// <param name="status">The <see cref="API.Features.UpdateStatus"/></param>
public static async Task DownloadPlugin(API.Features.UpdateStatus status)
{
byte[] pluginData = await Client.GetByteArrayAsync(status.Url);
WritePlugin(pluginData, status.ModuleName);
}

/// <summary>
/// This will check the GitHub API for the latest version of the modules and plugins.
Expand Down Expand Up @@ -81,6 +93,8 @@ public static async Task GetStatus()
}
}
}

Statuses = statuses;

List<IPlugin<IConfig>> plugins = Loader.Plugins.Where(x => x.Name.StartsWith("DiscordLab.")).ToList();
plugins.Add(Loader.Plugins.First(x => x.Name == Plugin.Instance.Name));
Expand All @@ -98,8 +112,7 @@ public static async Task GetStatus()
if (Plugin.Instance.Config.AutoUpdate)
{
pluginsToUpdate.Add(status.ModuleName);
byte[] pluginData = await Client.GetByteArrayAsync(status.Url);
WritePlugin(pluginData, status.ModuleName);
await DownloadPlugin(status);
}
else
{
Expand Down
74 changes: 74 additions & 0 deletions DiscordLab.Bot/Commands/Discord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Discord;
using Discord.WebSocket;
using DiscordLab.Bot.API.Interfaces;
using DiscordLab.Bot.API.Modules;

namespace DiscordLab.Bot.Commands
{
public class Discord : ISlashCommand
{
public SlashCommandBuilder Data { get; } = new()
{
Name = "discordlab",
Description = "DiscordLab related commands",
DefaultMemberPermissions = GuildPermission.Administrator,
Options = new()
{
new()
{
Type = ApplicationCommandOptionType.SubCommand,
Name = "list",
Description = "List all available DiscordLab modules",
},
new()
{
Type = ApplicationCommandOptionType.SubCommand,
Name = "install",
Description = "Install a DiscordLab module",
Options = new ()
{
new ()
{
Type = ApplicationCommandOptionType.String,
Name = "module",
Description = "The module to install",
IsRequired = true,
IsAutocomplete = true
}
}
}
}
};

public ulong GuildId { get; set; } = Plugin.Instance.Config.GuildId;

public async Task Run(SocketSlashCommand command)
{
string subcommand = command.Data.Options.First().Name;
if (subcommand == "list")
{
string modules = string.Join("\n", UpdateStatus.Statuses.Where(s => s.ModuleName != "DiscordLab.Bot").Select(s => s.ModuleName));
await command.RespondAsync("List of available DiscordLab modules:\n\n" + modules, ephemeral:true);
}
else if (subcommand == "install")
{
string module = command.Data.Options.First().Options.First().Value.ToString();
if(string.IsNullOrWhiteSpace(module))
{
await command.RespondAsync("Please provide a module name.", ephemeral: true);
return;
}
API.Features.UpdateStatus status = UpdateStatus.Statuses.FirstOrDefault(s => s.ModuleName == module);
if (status == null)
{
await command.RespondAsync("Module not found.", ephemeral: true);
return;
}

await UpdateStatus.DownloadPlugin(status);
ServerStatic.StopNextRound = ServerStatic.NextRoundAction.Restart;
await command.RespondAsync("Downloaded module. Server will restart next round.", ephemeral:true);
}
}
}
}
53 changes: 53 additions & 0 deletions DiscordLab.Bot/Commands/LocalAdmin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using CommandSystem;
using DiscordLab.Bot.API.Modules;
using PluginAPI.Core;

namespace DiscordLab.Bot.Commands
{
[CommandHandler(typeof(GameConsoleCommandHandler))]
public class LocalAdmin : ICommand
{
public string Command { get; } = "discordlab";

public string[] Aliases { get; } = new [] { "dl", "lab" };

public string Description { get; } = "Do things directly with DiscordLab.";

public bool Execute(
ArraySegment<string> arguments,
ICommandSender sender,
out string response
)
{
switch (arguments.FirstOrDefault())
{
case "list":
string modules = string.Join("\n", UpdateStatus.Statuses.Where(s => s.ModuleName != "DiscordLab.Bot").Select(s => s.ModuleName));
response =
$"Available modules:\n{modules}";
return true;
case "install":
string module = arguments.ElementAtOrDefault(1);
if(string.IsNullOrWhiteSpace(module))
{
response = "Please provide a module name.";
return false;
}
API.Features.UpdateStatus status = UpdateStatus.Statuses.FirstOrDefault(s => s.ModuleName == module);
if (status == null)
{
response = "Module not found.";
return false;
}

Task.Run(async () => await UpdateStatus.DownloadPlugin(status));
ServerStatic.StopNextRound = ServerStatic.NextRoundAction.Restart;
response = "Downloaded module. Server will restart next round.";
return true;
default:
response = "Invalid subcommand. Available subcommands: list, install";
return false;
}
}
}
}
17 changes: 17 additions & 0 deletions DiscordLab.Bot/Handlers/DiscordBot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void Init()
Client.Log += DiscLog;
Client.Ready += Ready;
Client.SlashCommandExecuted += SlashCommandHandler;
Client.AutocompleteExecuted += AutoCompleteHandler;
Task.Run(StartClient);
}

Expand Down Expand Up @@ -84,5 +85,21 @@ private async Task SlashCommandHandler(SocketSlashCommand command)
if (cmd == null) return;
await cmd.Run(command);
}

private async Task AutoCompleteHandler(SocketAutocompleteInteraction autocomplete)
{
List<ISlashCommand> commands = SlashCommandLoader.Commands;
ISlashCommand cmd = commands.FirstOrDefault(c => c.Data.Name == autocomplete.Data.CommandName);
if (cmd == null) return;
if (cmd.Data.Name == "discordlab")
{
await autocomplete.RespondAsync(result: UpdateStatus.Statuses
.Where(s => s.ModuleName != "DiscordLab.Bot").Select(s => new AutocompleteResult
{
Name = s.ModuleName,
Value = s.ModuleName
}));
}
}
}
}

0 comments on commit 8a3b884

Please sign in to comment.