setting up all the commands
This commit is contained in:
parent
8ad2dee67c
commit
4aa4731480
|
@ -13,5 +13,10 @@
|
|||
}
|
||||
|
||||
public string Address { get; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Discord.WebSocket;
|
||||
using Discord;
|
||||
using BiblioTech.TokenCommands;
|
||||
|
||||
namespace BiblioTech
|
||||
{
|
||||
|
@ -33,19 +34,33 @@ namespace BiblioTech
|
|||
}
|
||||
|
||||
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 CommandOption(string name, string description, ApplicationCommandOptionType type)
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace BiblioTech
|
|||
|
||||
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;
|
||||
|
|
|
@ -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()
|
||||
: base(name: "ethaddress",
|
||||
description: "Ethereum address starting with '0x'.",
|
||||
type: Discord.ApplicationCommandOptionType.String)
|
||||
type: Discord.ApplicationCommandOptionType.String,
|
||||
isRequired: true)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using CodexContractsPlugin;
|
||||
using CodexPlugin;
|
||||
using Core;
|
||||
using Discord.WebSocket;
|
||||
using GethPlugin;
|
||||
|
@ -8,29 +7,36 @@ namespace BiblioTech.TokenCommands
|
|||
{
|
||||
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)
|
||||
{
|
||||
this.userAssociateCommand = userAssociateCommand;
|
||||
}
|
||||
|
||||
// connect users to eth address!
|
||||
|
||||
public override string Name => "balance";
|
||||
public override string StartingMessage => "Fetching balance...";
|
||||
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)
|
||||
{
|
||||
var addr = await ethOption.Parse(command);
|
||||
if (addr == null) return;
|
||||
var userId = GetUserId(optionalUser, command);
|
||||
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 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 Ether defaultEthToSend = 10.Eth();
|
||||
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)
|
||||
: base(monitor, ci)
|
||||
|
@ -19,12 +21,13 @@ namespace BiblioTech.TokenCommands
|
|||
|
||||
public override string Name => "mint";
|
||||
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 CommandOption[] Options => new[] { ethOption };
|
||||
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)
|
||||
{
|
||||
var addr = await ethOption.Parse(command);
|
||||
var userId = GetUserId(optionalUser, command);
|
||||
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||
if (addr == null) return;
|
||||
|
||||
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)
|
||||
{
|
||||
var user = GetOrCreate(discordId);
|
||||
|
|
Loading…
Reference in New Issue