setting up all the commands
This commit is contained in:
parent
8ad2dee67c
commit
4aa4731480
|
@ -13,5 +13,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Address { get; }
|
public string Address { get; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Address;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using Discord;
|
using Discord;
|
||||||
|
using BiblioTech.TokenCommands;
|
||||||
|
|
||||||
namespace BiblioTech
|
namespace BiblioTech
|
||||||
{
|
{
|
||||||
|
@ -33,19 +34,33 @@ namespace BiblioTech
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Task Invoke(SocketSlashCommand command);
|
protected abstract Task Invoke(SocketSlashCommand command);
|
||||||
|
|
||||||
|
protected bool IsSenderAdmin(SocketSlashCommand command)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ulong GetUserId(UserOption userOption, SocketSlashCommand command)
|
||||||
|
{
|
||||||
|
var targetUser = userOption.GetOptionUserId(command);
|
||||||
|
if (IsSenderAdmin(command) && targetUser != null) return targetUser.Value;
|
||||||
|
return command.User.Id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CommandOption
|
public class CommandOption
|
||||||
{
|
{
|
||||||
public CommandOption(string name, string description, ApplicationCommandOptionType type)
|
public CommandOption(string name, string description, ApplicationCommandOptionType type, bool isRequired)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Description = description;
|
Description = description;
|
||||||
Type = type;
|
Type = type;
|
||||||
|
IsRequired = isRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
public ApplicationCommandOptionType Type { get; }
|
public ApplicationCommandOptionType Type { get; }
|
||||||
|
public bool IsRequired { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace BiblioTech
|
||||||
|
|
||||||
foreach (var option in c.Options)
|
foreach (var option in c.Options)
|
||||||
{
|
{
|
||||||
builder.AddOption(option.Name, option.Type, option.Description, isRequired: true);
|
builder.AddOption(option.Name, option.Type, option.Description, isRequired: option.IsRequired);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace BiblioTech.TokenCommands
|
||||||
|
{
|
||||||
|
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.";
|
||||||
|
|
||||||
|
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."); ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,8 @@ namespace BiblioTech.TokenCommands
|
||||||
public EthAddressOption()
|
public EthAddressOption()
|
||||||
: base(name: "ethaddress",
|
: base(name: "ethaddress",
|
||||||
description: "Ethereum address starting with '0x'.",
|
description: "Ethereum address starting with '0x'.",
|
||||||
type: Discord.ApplicationCommandOptionType.String)
|
type: Discord.ApplicationCommandOptionType.String,
|
||||||
|
isRequired: true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using CodexContractsPlugin;
|
using CodexContractsPlugin;
|
||||||
using CodexPlugin;
|
|
||||||
using Core;
|
using Core;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using GethPlugin;
|
using GethPlugin;
|
||||||
|
@ -8,29 +7,36 @@ namespace BiblioTech.TokenCommands
|
||||||
{
|
{
|
||||||
public class GetBalanceCommand : BaseNetCommand
|
public class GetBalanceCommand : BaseNetCommand
|
||||||
{
|
{
|
||||||
private readonly EthAddressOption ethOption = new EthAddressOption();
|
private readonly UserAssociateCommand userAssociateCommand;
|
||||||
|
private readonly UserOption optionalUser = new UserOption(
|
||||||
|
description: "If set, get balance for another user. (Optional, admin-only)",
|
||||||
|
isRequired: false);
|
||||||
|
|
||||||
public GetBalanceCommand(DeploymentsFilesMonitor monitor, CoreInterface ci)
|
public GetBalanceCommand(DeploymentsFilesMonitor monitor, CoreInterface ci, UserAssociateCommand userAssociateCommand)
|
||||||
: base(monitor, ci)
|
: base(monitor, ci)
|
||||||
{
|
{
|
||||||
|
this.userAssociateCommand = userAssociateCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect users to eth address!
|
|
||||||
|
|
||||||
public override string Name => "balance";
|
public override string Name => "balance";
|
||||||
public override string StartingMessage => "Fetching balance...";
|
public override string StartingMessage => "Fetching balance...";
|
||||||
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[] { ethOption };
|
public override CommandOption[] Options => new[] { optionalUser };
|
||||||
|
|
||||||
protected override async Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts)
|
protected override async Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts)
|
||||||
{
|
{
|
||||||
var addr = await ethOption.Parse(command);
|
var userId = GetUserId(optionalUser, command);
|
||||||
if (addr == null) return;
|
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.");
|
||||||
|
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.RespondAsync($"Address '{addr.Address}' has {eth} and {testTokens}.");
|
await command.FollowupAsync($"{command.User.Username} has {eth} and {testTokens}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ namespace BiblioTech.TokenCommands
|
||||||
private readonly string nl = Environment.NewLine;
|
private readonly string nl = Environment.NewLine;
|
||||||
private readonly Ether defaultEthToSend = 10.Eth();
|
private readonly Ether defaultEthToSend = 10.Eth();
|
||||||
private readonly TestToken defaultTestTokensToMint = 1024.TestTokens();
|
private readonly TestToken defaultTestTokensToMint = 1024.TestTokens();
|
||||||
private readonly EthAddressOption ethOption = new EthAddressOption();
|
private readonly UserOption optionalUser = new UserOption(
|
||||||
|
description: "If set, mint tokens for this user. (Optional, admin-only)",
|
||||||
|
isRequired: true);
|
||||||
|
|
||||||
public MintCommand(DeploymentsFilesMonitor monitor, CoreInterface ci)
|
public MintCommand(DeploymentsFilesMonitor monitor, CoreInterface ci)
|
||||||
: base(monitor, ci)
|
: base(monitor, ci)
|
||||||
|
@ -19,12 +21,13 @@ namespace BiblioTech.TokenCommands
|
||||||
|
|
||||||
public override string Name => "mint";
|
public override string Name => "mint";
|
||||||
public override string StartingMessage => "Minting some tokens...";
|
public override string StartingMessage => "Minting some tokens...";
|
||||||
public override string Description => "Mint some TestTokens and send some Eth to the address if its 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[] { ethOption };
|
public override CommandOption[] Options => new[] { optionalUser };
|
||||||
|
|
||||||
protected override async Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts)
|
protected override async Task Execute(SocketSlashCommand command, IGethNode gethNode, ICodexContracts contracts)
|
||||||
{
|
{
|
||||||
var addr = await ethOption.Parse(command);
|
var userId = GetUserId(optionalUser, command);
|
||||||
|
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||||
if (addr == null) return;
|
if (addr == null) return;
|
||||||
|
|
||||||
var report =
|
var report =
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace BiblioTech.TokenCommands
|
||||||
|
{
|
||||||
|
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.";
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace BiblioTech.TokenCommands
|
||||||
|
{
|
||||||
|
public class ShowIdCommand : BaseCommand
|
||||||
|
{
|
||||||
|
public override string Name => "my-id";
|
||||||
|
public override string StartingMessage => "...";
|
||||||
|
public override string Description => "Shows you your Discord ID. (Useful for admins)";
|
||||||
|
|
||||||
|
protected override async Task Invoke(SocketSlashCommand command)
|
||||||
|
{
|
||||||
|
await command.FollowupAsync("Your ID: " + command.User.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace BiblioTech.TokenCommands
|
||||||
|
{
|
||||||
|
public class UserAssociateCommand : BaseCommand
|
||||||
|
{
|
||||||
|
private readonly EthAddressOption ethOption = new EthAddressOption();
|
||||||
|
|
||||||
|
public override string Name => "set";
|
||||||
|
public override string StartingMessage => "hold on...";
|
||||||
|
public override string Description => "Associates a Discord user with an Ethereum address in the TestNet. " +
|
||||||
|
"Warning: You can set your Ethereum address only once! Double-check before hitting enter.";
|
||||||
|
|
||||||
|
public override CommandOption[] Options => new[] { ethOption };
|
||||||
|
|
||||||
|
protected override async Task Invoke(SocketSlashCommand command)
|
||||||
|
{
|
||||||
|
var userId = command.User.Id;
|
||||||
|
var data = await ethOption.Parse(command);
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
|
var currentAddress = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||||
|
if (currentAddress != null)
|
||||||
|
{
|
||||||
|
await 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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Discord;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace BiblioTech.TokenCommands
|
||||||
|
{
|
||||||
|
public class UserOption : CommandOption
|
||||||
|
{
|
||||||
|
public UserOption(string description, bool isRequired)
|
||||||
|
: base("user", description, ApplicationCommandOptionType.User, isRequired)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong? GetOptionUserId(SocketSlashCommand command)
|
||||||
|
{
|
||||||
|
var userOptionData = command.Data.Options.SingleOrDefault(o => o.Name == Name);
|
||||||
|
if (userOptionData == null) return null;
|
||||||
|
var user = userOptionData.Value as IUser;
|
||||||
|
if (user == null) return null;
|
||||||
|
return user.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,43 @@ namespace BiblioTech
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string[] GetInteractionReport(ulong discordId)
|
||||||
|
{
|
||||||
|
var result = new List<string>();
|
||||||
|
|
||||||
|
lock (repoLock)
|
||||||
|
{
|
||||||
|
var filename = GetFilename(discordId);
|
||||||
|
if (!File.Exists(filename))
|
||||||
|
{
|
||||||
|
result.Add("User has not joined the test net.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var user = JsonConvert.DeserializeObject<User>(File.ReadAllText(filename));
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
result.Add("Failed to load user records.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Add("User joined on " + user.CreatedUtc.ToString("o"));
|
||||||
|
result.Add("Current address: " + user.CurrentAddress);
|
||||||
|
foreach (var ae in user.AssociateEvents)
|
||||||
|
{
|
||||||
|
result.Add($"{ae.Utc.ToString("o")} - Address set to: {ae.NewAddress}");
|
||||||
|
}
|
||||||
|
foreach (var me in user.MintEvents)
|
||||||
|
{
|
||||||
|
result.Add($"{me.Utc.ToString("o")} - Minted {me.EthReceived} and {me.TestTokensMinted} to {me.UsedAddress}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
private void SetUserAddress(ulong discordId, EthAddress? address)
|
private void SetUserAddress(ulong discordId, EthAddress? address)
|
||||||
{
|
{
|
||||||
var user = GetOrCreate(discordId);
|
var user = GetOrCreate(discordId);
|
||||||
|
|
Loading…
Reference in New Issue