mirror of
https://github.com/tribufu/ServerManagers
synced 2026-05-06 15:17:34 +00:00
Discord Bot Scaffolding
This commit is contained in:
parent
ceb3ab73c4
commit
c4bf4906ea
24 changed files with 1119 additions and 5 deletions
151
src/ServerManager.Discord/Modules/HelpModule.cs
Normal file
151
src/ServerManager.Discord/Modules/HelpModule.cs
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServerManagerTool.Discord.Modules
|
||||
{
|
||||
[Name("Help")]
|
||||
public sealed class HelpModule : ModuleBase<SocketCommandContext>
|
||||
{
|
||||
private const int MAX_VALUE_LENGTH = 1024;
|
||||
|
||||
private readonly CommandService _service;
|
||||
private readonly IConfigurationRoot _config;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public HelpModule(CommandService service, IConfigurationRoot config, IServiceProvider services)
|
||||
{
|
||||
_service = service;
|
||||
_config = config;
|
||||
_services = services;
|
||||
}
|
||||
|
||||
[Command("help")]
|
||||
[Summary("Provides a list of available commands")]
|
||||
public async Task HelpAsync()
|
||||
{
|
||||
var prefix = _config["DiscordSettings:Prefix"];
|
||||
|
||||
var builder = new EmbedBuilder()
|
||||
{
|
||||
Color = new Color(114, 137, 218),
|
||||
Description = "These are the commands you can use"
|
||||
};
|
||||
|
||||
foreach (var module in _service.Modules)
|
||||
{
|
||||
var moduleName = module.Name;
|
||||
|
||||
// create the list of accessible commands
|
||||
var commands = new List<string>(module.Commands.Count);
|
||||
|
||||
foreach (var cmd in module.Commands)
|
||||
{
|
||||
var result = await cmd.CheckPreconditionsAsync(Context, _services);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
commands.Add($"{prefix}{cmd.Aliases.First()}");
|
||||
}
|
||||
|
||||
// remove all duplicate commands
|
||||
commands = commands.Distinct().ToList();
|
||||
|
||||
var commandString = string.Empty;
|
||||
|
||||
foreach (var command in commands)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var commandToAdd = $"{command}\n";
|
||||
|
||||
if (commandString.Length + commandToAdd.Length > MAX_VALUE_LENGTH)
|
||||
{
|
||||
// force the output, string would be too long
|
||||
builder.AddField(x =>
|
||||
{
|
||||
x.Name = moduleName;
|
||||
x.Value = $"{commandString}\n";
|
||||
x.IsInline = false;
|
||||
});
|
||||
|
||||
// reset the module name and command string
|
||||
moduleName = $"{module.Name} cont.";
|
||||
commandString = string.Empty;
|
||||
}
|
||||
|
||||
commandString += commandToAdd;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(commandString))
|
||||
{
|
||||
builder.AddField(x =>
|
||||
{
|
||||
x.Name = moduleName;
|
||||
x.Value = $"{commandString}\n";
|
||||
x.IsInline = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await ReplyAsync(string.Empty, false, builder.Build());
|
||||
}
|
||||
|
||||
[Command("help")]
|
||||
[Summary("Searches a list of available commands")]
|
||||
public async Task HelpAsync(string command)
|
||||
{
|
||||
var searchResults = _service.Search(Context, command);
|
||||
|
||||
if (!searchResults.IsSuccess)
|
||||
{
|
||||
await ReplyAsync($"Sorry, couldn't find a command like **{command}**.");
|
||||
return;
|
||||
}
|
||||
|
||||
var prefix = _config["DiscordSettings:Prefix"];
|
||||
|
||||
var builder = new EmbedBuilder()
|
||||
{
|
||||
Color = new Color(114, 137, 218),
|
||||
Description = $"Here are some commands like **{command}**"
|
||||
};
|
||||
|
||||
foreach (var match in searchResults.Commands)
|
||||
{
|
||||
var cmd = match.Command;
|
||||
|
||||
var result = await cmd.CheckPreconditionsAsync(Context, _services);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var usage = $"{prefix}{cmd.Aliases.First()}";
|
||||
if (cmd.Parameters.Count > 0)
|
||||
{
|
||||
usage += $" {string.Join(" ", cmd.Parameters.Select(p => p.Name))}";
|
||||
}
|
||||
usage += $"\n";
|
||||
|
||||
builder.AddField(x =>
|
||||
{
|
||||
x.Name = string.Join(", ", cmd.Aliases);
|
||||
x.Value = $"Summary: {cmd.Summary}\nUsage: {usage}";
|
||||
x.IsInline = false;
|
||||
});
|
||||
}
|
||||
|
||||
await ReplyAsync(string.Empty, false, builder.Build());
|
||||
}
|
||||
}
|
||||
}
|
||||
207
src/ServerManager.Discord/Modules/ServerCommandModule.cs
Normal file
207
src/ServerManager.Discord/Modules/ServerCommandModule.cs
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
using Discord.Addons.Interactive;
|
||||
using Discord.Commands;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using ServerManagerTool.Discord.Enums;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServerManagerTool.Discord.Modules
|
||||
{
|
||||
[Name("Server Commands")]
|
||||
public sealed class ServerCommandModule : InteractiveBase
|
||||
{
|
||||
private readonly CommandService _service;
|
||||
private readonly IConfigurationRoot _config;
|
||||
|
||||
public ServerCommandModule(CommandService service, IConfigurationRoot config)
|
||||
{
|
||||
_service = service;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
[Command("backup", RunMode = RunMode.Async)]
|
||||
[Summary("Perform a backup of the server")]
|
||||
[Remarks("backup")]
|
||||
public async Task BackupServerAsync()
|
||||
{
|
||||
await BackupServerAsync(null);
|
||||
}
|
||||
|
||||
[Command("backup", RunMode = RunMode.Async)]
|
||||
[Summary("Perform a backup of the server")]
|
||||
[Remarks("backup profileId")]
|
||||
public async Task BackupServerAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.BackupServer, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("shutdown", RunMode = RunMode.Async)]
|
||||
[Summary("Shuts down the server properly")]
|
||||
[Remarks("shutdown")]
|
||||
public async Task ShutdownServerAsync()
|
||||
{
|
||||
await ShutdownServerAsync(null);
|
||||
}
|
||||
|
||||
[Command("shutdown", RunMode = RunMode.Async)]
|
||||
[Summary("Shuts down the server properly")]
|
||||
[Remarks("shutdown profileId")]
|
||||
public async Task ShutdownServerAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.ShutdownServer, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("start", RunMode = RunMode.Async)]
|
||||
[Summary("Starts the server")]
|
||||
[Remarks("start")]
|
||||
public async Task StartServerAsync()
|
||||
{
|
||||
await StartServerAsync(null);
|
||||
}
|
||||
|
||||
[Command("start", RunMode = RunMode.Async)]
|
||||
[Summary("Starts the server")]
|
||||
[Remarks("start profileId")]
|
||||
public async Task StartServerAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.StartServer, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("stop", RunMode = RunMode.Async)]
|
||||
[Summary("Forcibly stops the server")]
|
||||
[Remarks("stop")]
|
||||
public async Task StopServerAsync()
|
||||
{
|
||||
await StopServerAsync(null);
|
||||
}
|
||||
|
||||
[Command("stop", RunMode = RunMode.Async)]
|
||||
[Summary("Forcibly stops the server")]
|
||||
[Remarks("stop profileId")]
|
||||
public async Task StopServerAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.StopServer, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("update", RunMode = RunMode.Async)]
|
||||
[Summary("Updates the server")]
|
||||
[Remarks("update")]
|
||||
public async Task UpdateServerAsync()
|
||||
{
|
||||
await UpdateServerAsync(null);
|
||||
}
|
||||
|
||||
[Command("update", RunMode = RunMode.Async)]
|
||||
[Summary("Updates the server")]
|
||||
[Remarks("update profileId")]
|
||||
public async Task UpdateServerAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.UpdateServer, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
125
src/ServerManager.Discord/Modules/ServerQueryModule.cs
Normal file
125
src/ServerManager.Discord/Modules/ServerQueryModule.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
using Discord.Addons.Interactive;
|
||||
using Discord.Commands;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using ServerManagerTool.Discord.Enums;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServerManagerTool.Discord.Modules
|
||||
{
|
||||
[Name("Server Query")]
|
||||
public sealed class ServerQueryModule : InteractiveBase
|
||||
{
|
||||
private readonly CommandService _service;
|
||||
private readonly IConfigurationRoot _config;
|
||||
|
||||
public ServerQueryModule(CommandService service, IConfigurationRoot config)
|
||||
{
|
||||
_service = service;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
[Command("info", RunMode = RunMode.Async)]
|
||||
[Summary("Poll server for information")]
|
||||
[Remarks("info")]
|
||||
public async Task ServerInfoAsync()
|
||||
{
|
||||
await ServerInfoAsync(null);
|
||||
}
|
||||
|
||||
[Command("info", RunMode = RunMode.Async)]
|
||||
[Summary("Poll server for information")]
|
||||
[Remarks("info profileId")]
|
||||
public async Task ServerInfoAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.ServerInfo, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("list", RunMode = RunMode.Async)]
|
||||
[Summary("List of all servers associated with this channel")]
|
||||
[Remarks("list")]
|
||||
public async Task ServerListAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.ServerList, channelId, null);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
[Command("status", RunMode = RunMode.Async)]
|
||||
[Summary("Poll server for status")]
|
||||
[Remarks("status")]
|
||||
public async Task ServerStatusAsync()
|
||||
{
|
||||
await ServerStatusAsync(null);
|
||||
}
|
||||
|
||||
[Command("status", RunMode = RunMode.Async)]
|
||||
[Summary("Poll server for status")]
|
||||
[Remarks("status profileId")]
|
||||
public async Task ServerStatusAsync(string profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||
|
||||
var response = DiscordBot.HandleCommandCallback?.Invoke(CommandType.ServerStatus, channelId, profileId);
|
||||
if (response is null || response.Count == 0)
|
||||
{
|
||||
await ReplyAsync("No servers associated with this channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var output in response)
|
||||
{
|
||||
await ReplyAsync(output);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue