cleanup of admin commands
This commit is contained in:
parent
5aff8c6f6d
commit
a0461a446e
@ -1,6 +1,5 @@
|
|||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using Discord;
|
using BiblioTech.Options;
|
||||||
using BiblioTech.Commands;
|
|
||||||
|
|
||||||
namespace BiblioTech
|
namespace BiblioTech
|
||||||
{
|
{
|
||||||
@ -24,7 +23,7 @@ namespace BiblioTech
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await command.RespondAsync(StartingMessage);
|
await command.RespondAsync(StartingMessage);
|
||||||
await Invoke(command);
|
await Invoke(new CommandContext(command, command.Data.Options));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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)
|
protected bool IsSenderAdmin(SocketSlashCommand command)
|
||||||
{
|
{
|
||||||
return Program.AdminChecker.IsUserAdmin(command.User.Id);
|
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);
|
var targetUser = userOption.GetOptionUserId(context);
|
||||||
if (IsSenderAdmin(command) && targetUser != null) return targetUser.Value;
|
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser.Value;
|
||||||
return command.User.Id;
|
return context.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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using CodexContractsPlugin;
|
using BiblioTech.Options;
|
||||||
|
using CodexContractsPlugin;
|
||||||
using Core;
|
using Core;
|
||||||
using Discord.WebSocket;
|
|
||||||
using GethPlugin;
|
using GethPlugin;
|
||||||
|
|
||||||
namespace BiblioTech
|
namespace BiblioTech
|
||||||
@ -16,17 +16,17 @@ namespace BiblioTech
|
|||||||
this.ci = ci;
|
this.ci = ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task Invoke(SocketSlashCommand command)
|
protected override async Task Invoke(CommandContext context)
|
||||||
{
|
{
|
||||||
var deployments = monitor.GetDeployments();
|
var deployments = monitor.GetDeployments();
|
||||||
if (deployments.Length == 0)
|
if (deployments.Length == 0)
|
||||||
{
|
{
|
||||||
await command.FollowupAsync("No deployments are currently available.");
|
await context.Command.FollowupAsync("No deployments are currently available.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (deployments.Length > 1)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,9 +37,9 @@ namespace BiblioTech
|
|||||||
var gethNode = ci.WrapGethDeployment(gethDeployment);
|
var gethNode = ci.WrapGethDeployment(gethDeployment);
|
||||||
var contracts = ci.WrapCodexContractsDeployment(contractsDeployment);
|
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 BiblioTech.Options;
|
||||||
using Discord.WebSocket;
|
using CodexPlugin;
|
||||||
|
|
||||||
namespace BiblioTech.Commands
|
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
|
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 Name => "admin";
|
||||||
public override string StartingMessage => "...";
|
public override string StartingMessage => "...";
|
||||||
public override string Description => "Admins only.";
|
public override string Description => "Admins only.";
|
||||||
|
|
||||||
private readonly SubCommandOption aaa = new SubCommandOption("aaa", "does AAA", new EthAddressOption());
|
public AdminCommand(DeploymentsFilesMonitor monitor)
|
||||||
private readonly SubCommandOption bbb = new SubCommandOption("bbb", "does BBB", new UserOption("a user", true));
|
{
|
||||||
|
clearCommand = new ClearUserAssociationCommand();
|
||||||
|
reportCommand = new ReportCommand();
|
||||||
|
deployListCommand = new DeployListCommand(monitor);
|
||||||
|
deployUploadCommand = new DeployUploadCommand(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
public override CommandOption[] Options => new CommandOption[]
|
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 Core;
|
||||||
using Discord.WebSocket;
|
|
||||||
using GethPlugin;
|
using GethPlugin;
|
||||||
|
|
||||||
namespace BiblioTech.Commands
|
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 string Description => "Shows Eth and TestToken balance of an eth address.";
|
||||||
public override CommandOption[] Options => new[] { optionalUser };
|
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);
|
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||||
if (addr == null)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eth = gethNode.GetEthBalance(addr);
|
var eth = gethNode.GetEthBalance(addr);
|
||||||
var testTokens = contracts.GetTestTokenBalance(gethNode, 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 Core;
|
||||||
using Discord.WebSocket;
|
|
||||||
using GethPlugin;
|
using GethPlugin;
|
||||||
|
|
||||||
namespace BiblioTech.Commands
|
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 string Description => "Mint some TestTokens and send some Eth to the user if their balance is low.";
|
||||||
public override CommandOption[] Options => new[] { optionalUser };
|
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);
|
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||||
if (addr == null)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
Program.UserRepo.AddMintEventForUser(userId, addr, sentEth, mintedTokens);
|
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)
|
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
|
namespace BiblioTech.Commands
|
||||||
{
|
{
|
||||||
@ -14,21 +14,21 @@ namespace BiblioTech.Commands
|
|||||||
public override string Description => "Associates a Discord user with an Ethereum address.";
|
public override string Description => "Associates a Discord user with an Ethereum address.";
|
||||||
public override CommandOption[] Options => new CommandOption[] { ethOption, optionalUser };
|
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 userId = GetUserId(optionalUser, context);
|
||||||
var data = await ethOption.Parse(command);
|
var data = await ethOption.Parse(context);
|
||||||
if (data == null) return;
|
if (data == null) return;
|
||||||
|
|
||||||
var currentAddress = Program.UserRepo.GetCurrentAddressForUser(userId);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.UserRepo.AssociateUserWithAddress(userId, data);
|
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!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
Tools/BiblioTech/Options/CommandContext.cs
Normal file
16
Tools/BiblioTech/Options/CommandContext.cs
Normal file
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
29
Tools/BiblioTech/Options/CommandOption.cs
Normal file
29
Tools/BiblioTech/Options/CommandOption.cs
Normal file
@ -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;
|
using Nethereum.Util;
|
||||||
|
|
||||||
namespace BiblioTech.Commands
|
namespace BiblioTech.Options
|
||||||
{
|
{
|
||||||
public class EthAddressOption : CommandOption
|
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)
|
if (ethOptionData == null)
|
||||||
{
|
{
|
||||||
await command.FollowupAsync("EthAddress option not received.");
|
await context.Command.FollowupAsync("EthAddress option not received.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var ethAddressStr = ethOptionData.Value as string;
|
var ethAddressStr = ethOptionData.Value as string;
|
||||||
if (string.IsNullOrEmpty(ethAddressStr))
|
if (string.IsNullOrEmpty(ethAddressStr))
|
||||||
{
|
{
|
||||||
await command.FollowupAsync("EthAddress is null or empty.");
|
await context.Command.FollowupAsync("EthAddress is null or empty.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ namespace BiblioTech.Commands
|
|||||||
!AddressUtil.Current.IsValidEthereumAddressHexFormat(ethAddressStr) ||
|
!AddressUtil.Current.IsValidEthereumAddressHexFormat(ethAddressStr) ||
|
||||||
!AddressUtil.Current.IsChecksumAddress(ethAddressStr))
|
!AddressUtil.Current.IsChecksumAddress(ethAddressStr))
|
||||||
{
|
{
|
||||||
await command.FollowupAsync("EthAddress is not valid.");
|
await context.Command.FollowupAsync("EthAddress is not valid.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
30
Tools/BiblioTech/Options/FileAttachementOption.cs
Normal file
30
Tools/BiblioTech/Options/FileAttachementOption.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
Tools/BiblioTech/Options/SubCommandOption.cs
Normal file
40
Tools/BiblioTech/Options/SubCommandOption.cs
Normal file
@ -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;
|
||||||
using Discord.WebSocket;
|
|
||||||
|
|
||||||
namespace BiblioTech.Commands
|
namespace BiblioTech.Options
|
||||||
{
|
{
|
||||||
public class UserOption : CommandOption
|
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;
|
if (userOptionData == null) return null;
|
||||||
var user = userOptionData.Value as IUser;
|
var user = userOptionData.Value as IUser;
|
||||||
if (user == null) return null;
|
if (user == null) return null;
|
@ -51,13 +51,10 @@ namespace BiblioTech
|
|||||||
|
|
||||||
var associateCommand = new UserAssociateCommand();
|
var associateCommand = new UserAssociateCommand();
|
||||||
var handler = new CommandHandler(client,
|
var handler = new CommandHandler(client,
|
||||||
//new ClearUserAssociationCommand(),
|
|
||||||
new GetBalanceCommand(monitor, ci, associateCommand),
|
new GetBalanceCommand(monitor, ci, associateCommand),
|
||||||
new MintCommand(monitor, ci, associateCommand),
|
new MintCommand(monitor, ci, associateCommand),
|
||||||
//new ReportHistoryCommand(),
|
|
||||||
associateCommand,
|
associateCommand,
|
||||||
//new DeploymentsCommand(monitor),
|
new AdminCommand(monitor)
|
||||||
new AdminCommand()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user