cleanup of admin commands
This commit is contained in:
parent
5aff8c6f6d
commit
a0461a446e
|
@ -1,6 +1,5 @@
|
|||
using Discord.WebSocket;
|
||||
using Discord;
|
||||
using BiblioTech.Commands;
|
||||
using BiblioTech.Options;
|
||||
|
||||
namespace BiblioTech
|
||||
{
|
||||
|
@ -24,7 +23,7 @@ namespace BiblioTech
|
|||
try
|
||||
{
|
||||
await command.RespondAsync(StartingMessage);
|
||||
await Invoke(command);
|
||||
await Invoke(new CommandContext(command, command.Data.Options));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -33,43 +32,18 @@ namespace BiblioTech
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract Task Invoke(SocketSlashCommand command);
|
||||
protected abstract Task Invoke(CommandContext context);
|
||||
|
||||
protected bool IsSenderAdmin(SocketSlashCommand command)
|
||||
{
|
||||
return Program.AdminChecker.IsUserAdmin(command.User.Id);
|
||||
}
|
||||
|
||||
protected ulong GetUserId(UserOption userOption, SocketSlashCommand command)
|
||||
protected ulong GetUserId(UserOption userOption, CommandContext context)
|
||||
{
|
||||
var targetUser = userOption.GetOptionUserId(command);
|
||||
if (IsSenderAdmin(command) && targetUser != null) return targetUser.Value;
|
||||
return command.User.Id;
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandOption
|
||||
{
|
||||
public CommandOption(string name, string description, ApplicationCommandOptionType type, bool isRequired)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
Type = type;
|
||||
IsRequired = isRequired;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public ApplicationCommandOptionType Type { get; }
|
||||
public bool IsRequired { get; }
|
||||
|
||||
public virtual SlashCommandOptionBuilder Build()
|
||||
{
|
||||
return new SlashCommandOptionBuilder()
|
||||
.WithName(Name)
|
||||
.WithDescription(Description)
|
||||
.WithType(Type)
|
||||
.WithRequired(IsRequired);
|
||||
var targetUser = userOption.GetOptionUserId(context);
|
||||
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser.Value;
|
||||
return context.Command.User.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using CodexContractsPlugin;
|
||||
using BiblioTech.Options;
|
||||
using CodexContractsPlugin;
|
||||
using Core;
|
||||
using Discord.WebSocket;
|
||||
using GethPlugin;
|
||||
|
||||
namespace BiblioTech
|
||||
|
@ -16,17 +16,17 @@ namespace BiblioTech
|
|||
this.ci = ci;
|
||||
}
|
||||
|
||||
protected override async Task Invoke(SocketSlashCommand command)
|
||||
protected override async Task Invoke(CommandContext context)
|
||||
{
|
||||
var deployments = monitor.GetDeployments();
|
||||
if (deployments.Length == 0)
|
||||
{
|
||||
await command.FollowupAsync("No deployments are currently available.");
|
||||
await context.Command.FollowupAsync("No deployments are currently available.");
|
||||
return;
|
||||
}
|
||||
if (deployments.Length > 1)
|
||||
{
|
||||
await command.FollowupAsync("Multiple deployments are online. I don't know which one to pick!");
|
||||
await context.Command.FollowupAsync("Multiple deployments are online. I don't know which one to pick!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,9 @@ namespace BiblioTech
|
|||
var gethNode = ci.WrapGethDeployment(gethDeployment);
|
||||
var contracts = ci.WrapCodexContractsDeployment(contractsDeployment);
|
||||
|
||||
await Execute(command, gethNode, contracts);
|
||||
await Execute(context, gethNode, contracts);
|
||||
}
|
||||
|
||||
protected abstract Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts);
|
||||
protected abstract Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +1,156 @@
|
|||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using BiblioTech.Options;
|
||||
using CodexPlugin;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
{
|
||||
public class SubCommandOption : CommandOption
|
||||
{
|
||||
private readonly CommandOption[] options;
|
||||
|
||||
public SubCommandOption(string name, string description, params CommandOption[] options)
|
||||
: base(name, description, type: ApplicationCommandOptionType.SubCommand, isRequired: false)
|
||||
{
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public override SlashCommandOptionBuilder Build()
|
||||
{
|
||||
var builder = base.Build();
|
||||
foreach (var option in options)
|
||||
{
|
||||
builder.AddOption(option.Build());
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public class AdminCommand : BaseCommand
|
||||
{
|
||||
private readonly ClearUserAssociationCommand clearCommand;
|
||||
private readonly ReportCommand reportCommand;
|
||||
private readonly DeployListCommand deployListCommand;
|
||||
private readonly DeployUploadCommand deployUploadCommand;
|
||||
|
||||
public override string Name => "admin";
|
||||
public override string StartingMessage => "...";
|
||||
public override string Description => "Admins only.";
|
||||
|
||||
private readonly SubCommandOption aaa = new SubCommandOption("aaa", "does AAA", new EthAddressOption());
|
||||
private readonly SubCommandOption bbb = new SubCommandOption("bbb", "does BBB", new UserOption("a user", true));
|
||||
public AdminCommand(DeploymentsFilesMonitor monitor)
|
||||
{
|
||||
clearCommand = new ClearUserAssociationCommand();
|
||||
reportCommand = new ReportCommand();
|
||||
deployListCommand = new DeployListCommand(monitor);
|
||||
deployUploadCommand = new DeployUploadCommand(monitor);
|
||||
}
|
||||
|
||||
public override CommandOption[] Options => new CommandOption[]
|
||||
{
|
||||
aaa, bbb
|
||||
clearCommand,
|
||||
reportCommand,
|
||||
deployListCommand,
|
||||
deployUploadCommand,
|
||||
};
|
||||
|
||||
protected override Task Invoke(SocketSlashCommand command)
|
||||
protected override async Task Invoke(CommandContext context)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
if (!IsSenderAdmin(context.Command))
|
||||
{
|
||||
await context.Command.FollowupAsync("You're not an admin.");
|
||||
return;
|
||||
}
|
||||
|
||||
await clearCommand.CommandHandler(context);
|
||||
await reportCommand.CommandHandler(context);
|
||||
await deployListCommand.CommandHandler(context);
|
||||
await deployUploadCommand.CommandHandler(context);
|
||||
}
|
||||
|
||||
public class ClearUserAssociationCommand : SubCommandOption
|
||||
{
|
||||
private readonly UserOption user = new UserOption("User to clear Eth address for.", true);
|
||||
|
||||
public ClearUserAssociationCommand()
|
||||
: base("clear", "Admin only. Clears current Eth address for a user, allowing them to set a new one.")
|
||||
{
|
||||
}
|
||||
|
||||
public override CommandOption[] Options => new[] { user };
|
||||
|
||||
protected override async Task onSubCommand(CommandContext context)
|
||||
{
|
||||
var userId = user.GetOptionUserId(context);
|
||||
if (userId == null)
|
||||
{
|
||||
await context.Command.FollowupAsync("Failed to get user ID");
|
||||
return;
|
||||
}
|
||||
|
||||
Program.UserRepo.ClearUserAssociatedAddress(userId.Value);
|
||||
await context.Command.FollowupAsync("Done.");
|
||||
}
|
||||
}
|
||||
|
||||
public class ReportCommand : SubCommandOption
|
||||
{
|
||||
private readonly UserOption user = new UserOption(
|
||||
description: "User to report history for.",
|
||||
isRequired: true);
|
||||
|
||||
public ReportCommand()
|
||||
: base("report", "Admin only. Reports bot-interaction history for a user.")
|
||||
{
|
||||
}
|
||||
|
||||
public override CommandOption[] Options => new[] { user };
|
||||
|
||||
protected override async Task onSubCommand(CommandContext context)
|
||||
{
|
||||
var userId = user.GetOptionUserId(context);
|
||||
if (userId == null)
|
||||
{
|
||||
await context.Command.FollowupAsync("Failed to get user ID");
|
||||
return;
|
||||
}
|
||||
|
||||
var report = Program.UserRepo.GetInteractionReport(userId.Value);
|
||||
await context.Command.FollowupAsync(string.Join(Environment.NewLine, report));
|
||||
}
|
||||
}
|
||||
|
||||
public class DeployListCommand : SubCommandOption
|
||||
{
|
||||
private readonly DeploymentsFilesMonitor monitor;
|
||||
|
||||
public DeployListCommand(DeploymentsFilesMonitor monitor)
|
||||
: base("list", "Lists current deployments.")
|
||||
{
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
protected override async Task onSubCommand(CommandContext context)
|
||||
{
|
||||
var deployments = monitor.GetDeployments();
|
||||
|
||||
if (!deployments.Any())
|
||||
{
|
||||
await context.Command.FollowupAsync("No deployments available.");
|
||||
return;
|
||||
}
|
||||
|
||||
await context.Command.FollowupAsync($"Deployments: {string.Join(", ", deployments.Select(FormatDeployment))}");
|
||||
}
|
||||
|
||||
private string FormatDeployment(CodexDeployment deployment)
|
||||
{
|
||||
var m = deployment.Metadata;
|
||||
return $"{m.Name} ({m.StartUtc.ToString("o")})";
|
||||
}
|
||||
}
|
||||
|
||||
public class DeployUploadCommand : SubCommandOption
|
||||
{
|
||||
private readonly DeploymentsFilesMonitor monitor;
|
||||
private readonly FileAttachementOption fileOption = new FileAttachementOption(
|
||||
name: "json",
|
||||
description: "Codex-deployment json to add.",
|
||||
isRequired: true);
|
||||
|
||||
public DeployUploadCommand(DeploymentsFilesMonitor monitor)
|
||||
: base("add", "Upload a new deployment JSON file.")
|
||||
{
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public override CommandOption[] Options => new[] { fileOption };
|
||||
|
||||
protected override async Task onSubCommand(CommandContext context)
|
||||
{
|
||||
var file = await fileOption.Parse(context);
|
||||
if (file == null) return;
|
||||
|
||||
await context.Command.FollowupAsync("Received: " + file.Size);
|
||||
|
||||
// todo pass to monitor, add to folder.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
using Discord.WebSocket;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
{
|
||||
public class ClearUserAssociationCommand : BaseCommand
|
||||
{
|
||||
private readonly UserOption user = new UserOption(
|
||||
description: "User to clear Eth address for.",
|
||||
isRequired: true);
|
||||
|
||||
public override string Name => "clear";
|
||||
public override string StartingMessage => "Hold on...";
|
||||
public override string Description => "Admin only. Clears current Eth address for a user, allowing them to set a new one.";
|
||||
public override CommandOption[] Options => new[] { user };
|
||||
|
||||
protected override async Task Invoke(SocketSlashCommand command)
|
||||
{
|
||||
if (!IsSenderAdmin(command))
|
||||
{
|
||||
await command.FollowupAsync("You're not an admin.");
|
||||
return;
|
||||
}
|
||||
|
||||
var userId = user.GetOptionUserId(command);
|
||||
if (userId == null)
|
||||
{
|
||||
await command.FollowupAsync("Failed to get user ID");
|
||||
return;
|
||||
}
|
||||
|
||||
Program.UserRepo.ClearUserAssociatedAddress(userId.Value);
|
||||
await command.FollowupAsync("Done."); ;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
using CodexPlugin;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
{
|
||||
public class DeploymentsCommand : BaseCommand
|
||||
{
|
||||
private readonly DeploymentsFilesMonitor monitor;
|
||||
|
||||
public DeploymentsCommand(DeploymentsFilesMonitor monitor)
|
||||
{
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public override string Name => "deployments";
|
||||
public override string StartingMessage => "Fetching deployments information...";
|
||||
public override string Description => "Lists active TestNet deployments";
|
||||
|
||||
protected override async Task Invoke(SocketSlashCommand command)
|
||||
{
|
||||
var deployments = monitor.GetDeployments();
|
||||
|
||||
if (!deployments.Any())
|
||||
{
|
||||
await command.FollowupAsync("No deployments available.");
|
||||
return;
|
||||
}
|
||||
|
||||
await command.FollowupAsync($"Deployments: {string.Join(", ", deployments.Select(FormatDeployment))}");
|
||||
}
|
||||
|
||||
private string FormatDeployment(CodexDeployment deployment)
|
||||
{
|
||||
var m = deployment.Metadata;
|
||||
return $"{m.Name} ({m.StartUtc.ToString("o")})";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using CodexContractsPlugin;
|
||||
using BiblioTech.Options;
|
||||
using CodexContractsPlugin;
|
||||
using Core;
|
||||
using Discord.WebSocket;
|
||||
using GethPlugin;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
|
@ -23,20 +23,20 @@ namespace BiblioTech.Commands
|
|||
public override string Description => "Shows Eth and TestToken balance of an eth address.";
|
||||
public override CommandOption[] Options => new[] { optionalUser };
|
||||
|
||||
protected override async Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts)
|
||||
protected override async Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts)
|
||||
{
|
||||
var userId = GetUserId(optionalUser, command);
|
||||
var userId = GetUserId(optionalUser, context);
|
||||
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||
if (addr == null)
|
||||
{
|
||||
await command.FollowupAsync($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
||||
await context.Command.FollowupAsync($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
||||
return;
|
||||
}
|
||||
|
||||
var eth = gethNode.GetEthBalance(addr);
|
||||
var testTokens = contracts.GetTestTokenBalance(gethNode, addr);
|
||||
|
||||
await command.FollowupAsync($"{command.User.Username} has {eth} and {testTokens}.");
|
||||
await context.Command.FollowupAsync($"{context.Command.User.Username} has {eth} and {testTokens}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using CodexContractsPlugin;
|
||||
using BiblioTech.Options;
|
||||
using CodexContractsPlugin;
|
||||
using Core;
|
||||
using Discord.WebSocket;
|
||||
using GethPlugin;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
|
@ -25,13 +25,13 @@ namespace BiblioTech.Commands
|
|||
public override string Description => "Mint some TestTokens and send some Eth to the user if their balance is low.";
|
||||
public override CommandOption[] Options => new[] { optionalUser };
|
||||
|
||||
protected override async Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts)
|
||||
protected override async Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts)
|
||||
{
|
||||
var userId = GetUserId(optionalUser, command);
|
||||
var userId = GetUserId(optionalUser, context);
|
||||
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||
if (addr == null)
|
||||
{
|
||||
await command.FollowupAsync($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
||||
await context.Command.FollowupAsync($"No address has been set for this user. Please use '/{userAssociateCommand.Name}' to set it first.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace BiblioTech.Commands
|
|||
|
||||
Program.UserRepo.AddMintEventForUser(userId, addr, sentEth, mintedTokens);
|
||||
|
||||
await command.FollowupAsync(string.Join(Environment.NewLine, report));
|
||||
await context.Command.FollowupAsync(string.Join(Environment.NewLine, report));
|
||||
}
|
||||
|
||||
private TestToken ProcessTokens(IGethNode gethNode, ICodexContracts contracts, EthAddress addr, List<string> report)
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
using Discord.WebSocket;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
{
|
||||
public class ReportHistoryCommand : BaseCommand
|
||||
{
|
||||
private readonly UserOption user = new UserOption(
|
||||
description: "User to report history for.",
|
||||
isRequired: true);
|
||||
|
||||
public override string Name => "report";
|
||||
public override string StartingMessage => "Getting that data...";
|
||||
public override string Description => "Admin only. Reports bot-interaction history for a user.";
|
||||
public override CommandOption[] Options => new[] { user };
|
||||
|
||||
protected override async Task Invoke(SocketSlashCommand command)
|
||||
{
|
||||
if (!IsSenderAdmin(command))
|
||||
{
|
||||
await command.FollowupAsync("You're not an admin.");
|
||||
return;
|
||||
}
|
||||
|
||||
var userId = user.GetOptionUserId(command);
|
||||
if (userId == null)
|
||||
{
|
||||
await command.FollowupAsync("Failed to get user ID");
|
||||
return;
|
||||
}
|
||||
|
||||
var report = Program.UserRepo.GetInteractionReport(userId.Value);
|
||||
await command.FollowupAsync(string.Join(Environment.NewLine, report));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using Discord.WebSocket;
|
||||
using BiblioTech.Options;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
{
|
||||
|
@ -14,21 +14,21 @@ namespace BiblioTech.Commands
|
|||
public override string Description => "Associates a Discord user with an Ethereum address.";
|
||||
public override CommandOption[] Options => new CommandOption[] { ethOption, optionalUser };
|
||||
|
||||
protected override async Task Invoke(SocketSlashCommand command)
|
||||
protected override async Task Invoke(CommandContext context)
|
||||
{
|
||||
var userId = GetUserId(optionalUser, command);
|
||||
var data = await ethOption.Parse(command);
|
||||
var userId = GetUserId(optionalUser, context);
|
||||
var data = await ethOption.Parse(context);
|
||||
if (data == null) return;
|
||||
|
||||
var currentAddress = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||
if (currentAddress != null && !IsSenderAdmin(command))
|
||||
if (currentAddress != null && !IsSenderAdmin(context.Command))
|
||||
{
|
||||
await command.FollowupAsync($"You've already set your Ethereum address to {currentAddress}.");
|
||||
await context.Command.FollowupAsync($"You've already set your Ethereum address to {currentAddress}.");
|
||||
return;
|
||||
}
|
||||
|
||||
Program.UserRepo.AssociateUserWithAddress(userId, data);
|
||||
await command.FollowupAsync("Done! Thank you for joining the test net!");
|
||||
await context.Command.FollowupAsync("Done! Thank you for joining the test net!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
using Discord.WebSocket;
|
||||
|
||||
namespace BiblioTech.Options
|
||||
{
|
||||
public class CommandContext
|
||||
{
|
||||
public CommandContext(SocketSlashCommand command, IReadOnlyCollection<SocketSlashCommandDataOption> options)
|
||||
{
|
||||
Command = command;
|
||||
Options = options;
|
||||
}
|
||||
|
||||
public SocketSlashCommand Command { get; }
|
||||
public IReadOnlyCollection<SocketSlashCommandDataOption> Options { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using Discord;
|
||||
|
||||
namespace BiblioTech.Options
|
||||
{
|
||||
public abstract class CommandOption
|
||||
{
|
||||
public CommandOption(string name, string description, ApplicationCommandOptionType type, bool isRequired)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
Type = type;
|
||||
IsRequired = isRequired;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public ApplicationCommandOptionType Type { get; }
|
||||
public bool IsRequired { get; }
|
||||
|
||||
public virtual SlashCommandOptionBuilder Build()
|
||||
{
|
||||
return new SlashCommandOptionBuilder()
|
||||
.WithName(Name)
|
||||
.WithDescription(Description)
|
||||
.WithType(Type)
|
||||
.WithRequired(IsRequired);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
using Discord.WebSocket;
|
||||
using GethPlugin;
|
||||
using GethPlugin;
|
||||
using Nethereum.Util;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
namespace BiblioTech.Options
|
||||
{
|
||||
public class EthAddressOption : CommandOption
|
||||
{
|
||||
|
@ -14,18 +13,18 @@ namespace BiblioTech.Commands
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<EthAddress?> Parse(SocketSlashCommand command)
|
||||
public async Task<EthAddress?> Parse(CommandContext context)
|
||||
{
|
||||
var ethOptionData = command.Data.Options.SingleOrDefault(o => o.Name == Name);
|
||||
var ethOptionData = context.Options.SingleOrDefault(o => o.Name == Name);
|
||||
if (ethOptionData == null)
|
||||
{
|
||||
await command.FollowupAsync("EthAddress option not received.");
|
||||
await context.Command.FollowupAsync("EthAddress option not received.");
|
||||
return null;
|
||||
}
|
||||
var ethAddressStr = ethOptionData.Value as string;
|
||||
if (string.IsNullOrEmpty(ethAddressStr))
|
||||
{
|
||||
await command.FollowupAsync("EthAddress is null or empty.");
|
||||
await context.Command.FollowupAsync("EthAddress is null or empty.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -33,7 +32,7 @@ namespace BiblioTech.Commands
|
|||
!AddressUtil.Current.IsValidEthereumAddressHexFormat(ethAddressStr) ||
|
||||
!AddressUtil.Current.IsChecksumAddress(ethAddressStr))
|
||||
{
|
||||
await command.FollowupAsync("EthAddress is not valid.");
|
||||
await context.Command.FollowupAsync("EthAddress is not valid.");
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using Discord;
|
||||
|
||||
namespace BiblioTech.Options
|
||||
{
|
||||
public class FileAttachementOption : CommandOption
|
||||
{
|
||||
public FileAttachementOption(string name, string description, bool isRequired)
|
||||
: base(name, description, type: ApplicationCommandOptionType.Attachment, isRequired)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<IAttachment?> Parse(CommandContext context)
|
||||
{
|
||||
var fileOptionData = context.Options.SingleOrDefault(o => o.Name == Name);
|
||||
if (fileOptionData == null)
|
||||
{
|
||||
await context.Command.FollowupAsync("Attachement option not received.");
|
||||
return null;
|
||||
}
|
||||
var attachement = fileOptionData.Value as IAttachment;
|
||||
if (attachement == null)
|
||||
{
|
||||
await context.Command.FollowupAsync("Attachement is null or empty.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return attachement;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using Discord;
|
||||
|
||||
namespace BiblioTech.Options
|
||||
{
|
||||
public abstract class SubCommandOption : CommandOption
|
||||
{
|
||||
public SubCommandOption(string name, string description)
|
||||
: base(name, description, type: ApplicationCommandOptionType.SubCommand, isRequired: false)
|
||||
{
|
||||
}
|
||||
|
||||
public override SlashCommandOptionBuilder Build()
|
||||
{
|
||||
var builder = base.Build();
|
||||
foreach (var option in Options)
|
||||
{
|
||||
builder.AddOption(option.Build());
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public async Task CommandHandler(CommandContext context)
|
||||
{
|
||||
var mine = context.Options.SingleOrDefault(o => o.Name == Name);
|
||||
if (mine == null) return;
|
||||
|
||||
await onSubCommand(new CommandContext(context.Command, mine.Options));
|
||||
}
|
||||
|
||||
public virtual CommandOption[] Options
|
||||
{
|
||||
get
|
||||
{
|
||||
return Array.Empty<CommandOption>();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Task onSubCommand(CommandContext context);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace BiblioTech.Commands
|
||||
namespace BiblioTech.Options
|
||||
{
|
||||
public class UserOption : CommandOption
|
||||
{
|
||||
|
@ -10,9 +9,9 @@ namespace BiblioTech.Commands
|
|||
{
|
||||
}
|
||||
|
||||
public ulong? GetOptionUserId(SocketSlashCommand command)
|
||||
public ulong? GetOptionUserId(CommandContext context)
|
||||
{
|
||||
var userOptionData = command.Data.Options.SingleOrDefault(o => o.Name == Name);
|
||||
var userOptionData = context.Options.SingleOrDefault(o => o.Name == Name);
|
||||
if (userOptionData == null) return null;
|
||||
var user = userOptionData.Value as IUser;
|
||||
if (user == null) return null;
|
|
@ -51,13 +51,10 @@ namespace BiblioTech
|
|||
|
||||
var associateCommand = new UserAssociateCommand();
|
||||
var handler = new CommandHandler(client,
|
||||
//new ClearUserAssociationCommand(),
|
||||
new GetBalanceCommand(monitor, ci, associateCommand),
|
||||
new MintCommand(monitor, ci, associateCommand),
|
||||
//new ReportHistoryCommand(),
|
||||
associateCommand,
|
||||
//new DeploymentsCommand(monitor),
|
||||
new AdminCommand()
|
||||
new AdminCommand(monitor)
|
||||
);
|
||||
|
||||
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
||||
|
|
Loading…
Reference in New Issue