adds Whois command
This commit is contained in:
parent
bd9fc3a3cf
commit
69296577f8
@ -1,5 +1,6 @@
|
|||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using BiblioTech.Options;
|
using BiblioTech.Options;
|
||||||
|
using Discord;
|
||||||
|
|
||||||
namespace BiblioTech
|
namespace BiblioTech
|
||||||
{
|
{
|
||||||
@ -45,11 +46,11 @@ namespace BiblioTech
|
|||||||
return Program.AdminChecker.IsAdminChannel(command.Channel);
|
return Program.AdminChecker.IsAdminChannel(command.Channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ulong GetUserId(UserOption userOption, CommandContext context)
|
protected IUser GetUserFromCommand(UserOption userOption, CommandContext context)
|
||||||
{
|
{
|
||||||
var targetUser = userOption.GetOptionUserId(context);
|
var targetUser = userOption.GetUser(context);
|
||||||
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser.Value;
|
if (IsSenderAdmin(context.Command) && targetUser != null) return targetUser;
|
||||||
return context.Command.User.Id;
|
return context.Command.User;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,16 @@ namespace BiblioTech
|
|||||||
{
|
{
|
||||||
public abstract class BaseNetCommand : BaseCommand
|
public abstract class BaseNetCommand : BaseCommand
|
||||||
{
|
{
|
||||||
private readonly DeploymentsFilesMonitor monitor;
|
|
||||||
private readonly CoreInterface ci;
|
private readonly CoreInterface ci;
|
||||||
|
|
||||||
public BaseNetCommand(DeploymentsFilesMonitor monitor, CoreInterface ci)
|
public BaseNetCommand(CoreInterface ci)
|
||||||
{
|
{
|
||||||
this.monitor = monitor;
|
|
||||||
this.ci = ci;
|
this.ci = ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task Invoke(CommandContext context)
|
protected override async Task Invoke(CommandContext context)
|
||||||
{
|
{
|
||||||
var deployments = monitor.GetDeployments();
|
var deployments = Program.DeploymentFilesMonitor.GetDeployments();
|
||||||
if (deployments.Length == 0)
|
if (deployments.Length == 0)
|
||||||
{
|
{
|
||||||
await context.Followup("No deployments are currently available.");
|
await context.Followup("No deployments are currently available.");
|
||||||
|
@ -5,32 +5,25 @@ namespace BiblioTech.Commands
|
|||||||
{
|
{
|
||||||
public class AdminCommand : BaseCommand
|
public class AdminCommand : BaseCommand
|
||||||
{
|
{
|
||||||
private readonly ClearUserAssociationCommand clearCommand;
|
private readonly ClearUserAssociationCommand clearCommand = new ClearUserAssociationCommand();
|
||||||
private readonly ReportCommand reportCommand;
|
private readonly ReportCommand reportCommand = new ReportCommand();
|
||||||
private readonly DeployListCommand deployListCommand;
|
private readonly DeployListCommand deployListCommand = new DeployListCommand();
|
||||||
private readonly DeployUploadCommand deployUploadCommand;
|
private readonly DeployUploadCommand deployUploadCommand = new DeployUploadCommand();
|
||||||
private readonly DeployRemoveCommand deployRemoveCommand;
|
private readonly DeployRemoveCommand deployRemoveCommand = new DeployRemoveCommand();
|
||||||
|
private readonly WhoIsCommand whoIsCommand = new WhoIsCommand();
|
||||||
|
|
||||||
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.";
|
||||||
|
|
||||||
public AdminCommand(DeploymentsFilesMonitor monitor)
|
|
||||||
{
|
|
||||||
clearCommand = new ClearUserAssociationCommand();
|
|
||||||
reportCommand = new ReportCommand();
|
|
||||||
deployListCommand = new DeployListCommand(monitor);
|
|
||||||
deployUploadCommand = new DeployUploadCommand(monitor);
|
|
||||||
deployRemoveCommand = new DeployRemoveCommand(monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override CommandOption[] Options => new CommandOption[]
|
public override CommandOption[] Options => new CommandOption[]
|
||||||
{
|
{
|
||||||
clearCommand,
|
clearCommand,
|
||||||
reportCommand,
|
reportCommand,
|
||||||
deployListCommand,
|
deployListCommand,
|
||||||
deployUploadCommand,
|
deployUploadCommand,
|
||||||
deployRemoveCommand
|
deployRemoveCommand,
|
||||||
|
whoIsCommand,
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override async Task Invoke(CommandContext context)
|
protected override async Task Invoke(CommandContext context)
|
||||||
@ -52,36 +45,37 @@ namespace BiblioTech.Commands
|
|||||||
await deployListCommand.CommandHandler(context);
|
await deployListCommand.CommandHandler(context);
|
||||||
await deployUploadCommand.CommandHandler(context);
|
await deployUploadCommand.CommandHandler(context);
|
||||||
await deployRemoveCommand.CommandHandler(context);
|
await deployRemoveCommand.CommandHandler(context);
|
||||||
|
await whoIsCommand.CommandHandler(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClearUserAssociationCommand : SubCommandOption
|
public class ClearUserAssociationCommand : SubCommandOption
|
||||||
{
|
{
|
||||||
private readonly UserOption user = new UserOption("User to clear Eth address for.", true);
|
private readonly UserOption userOption = new UserOption("User to clear Eth address for.", true);
|
||||||
|
|
||||||
public ClearUserAssociationCommand()
|
public ClearUserAssociationCommand()
|
||||||
: base("clear", "Admin only. Clears current Eth address for a user, allowing them to set a new one.")
|
: base("clear", "Admin only. Clears current Eth address for a user, allowing them to set a new one.")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override CommandOption[] Options => new[] { user };
|
public override CommandOption[] Options => new[] { userOption };
|
||||||
|
|
||||||
protected override async Task onSubCommand(CommandContext context)
|
protected override async Task onSubCommand(CommandContext context)
|
||||||
{
|
{
|
||||||
var userId = user.GetOptionUserId(context);
|
var user = userOption.GetUser(context);
|
||||||
if (userId == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
await context.AdminFollowup("Failed to get user ID");
|
await context.AdminFollowup("Failed to get user ID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.UserRepo.ClearUserAssociatedAddress(userId.Value);
|
Program.UserRepo.ClearUserAssociatedAddress(user);
|
||||||
await context.AdminFollowup("Done.");
|
await context.AdminFollowup("Done.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ReportCommand : SubCommandOption
|
public class ReportCommand : SubCommandOption
|
||||||
{
|
{
|
||||||
private readonly UserOption user = new UserOption(
|
private readonly UserOption userOption = new UserOption(
|
||||||
description: "User to report history for.",
|
description: "User to report history for.",
|
||||||
isRequired: true);
|
isRequired: true);
|
||||||
|
|
||||||
@ -90,35 +84,32 @@ namespace BiblioTech.Commands
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override CommandOption[] Options => new[] { user };
|
public override CommandOption[] Options => new[] { userOption };
|
||||||
|
|
||||||
protected override async Task onSubCommand(CommandContext context)
|
protected override async Task onSubCommand(CommandContext context)
|
||||||
{
|
{
|
||||||
var userId = user.GetOptionUserId(context);
|
var user = userOption.GetUser(context);
|
||||||
if (userId == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
await context.AdminFollowup("Failed to get user ID");
|
await context.AdminFollowup("Failed to get user ID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var report = Program.UserRepo.GetInteractionReport(userId.Value);
|
var report = Program.UserRepo.GetInteractionReport(user);
|
||||||
await context.AdminFollowup(string.Join(Environment.NewLine, report));
|
await context.AdminFollowup(string.Join(Environment.NewLine, report));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeployListCommand : SubCommandOption
|
public class DeployListCommand : SubCommandOption
|
||||||
{
|
{
|
||||||
private readonly DeploymentsFilesMonitor monitor;
|
public DeployListCommand()
|
||||||
|
|
||||||
public DeployListCommand(DeploymentsFilesMonitor monitor)
|
|
||||||
: base("list", "Lists current deployments.")
|
: base("list", "Lists current deployments.")
|
||||||
{
|
{
|
||||||
this.monitor = monitor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task onSubCommand(CommandContext context)
|
protected override async Task onSubCommand(CommandContext context)
|
||||||
{
|
{
|
||||||
var deployments = monitor.GetDeployments();
|
var deployments = Program.DeploymentFilesMonitor.GetDeployments();
|
||||||
|
|
||||||
if (!deployments.Any())
|
if (!deployments.Any())
|
||||||
{
|
{
|
||||||
@ -138,16 +129,14 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
public class DeployUploadCommand : SubCommandOption
|
public class DeployUploadCommand : SubCommandOption
|
||||||
{
|
{
|
||||||
private readonly DeploymentsFilesMonitor monitor;
|
|
||||||
private readonly FileAttachementOption fileOption = new FileAttachementOption(
|
private readonly FileAttachementOption fileOption = new FileAttachementOption(
|
||||||
name: "json",
|
name: "json",
|
||||||
description: "Codex-deployment json to add.",
|
description: "Codex-deployment json to add.",
|
||||||
isRequired: true);
|
isRequired: true);
|
||||||
|
|
||||||
public DeployUploadCommand(DeploymentsFilesMonitor monitor)
|
public DeployUploadCommand()
|
||||||
: base("add", "Upload a new deployment JSON file.")
|
: base("add", "Upload a new deployment JSON file.")
|
||||||
{
|
{
|
||||||
this.monitor = monitor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override CommandOption[] Options => new[] { fileOption };
|
public override CommandOption[] Options => new[] { fileOption };
|
||||||
@ -157,7 +146,7 @@ namespace BiblioTech.Commands
|
|||||||
var file = await fileOption.Parse(context);
|
var file = await fileOption.Parse(context);
|
||||||
if (file == null) return;
|
if (file == null) return;
|
||||||
|
|
||||||
var result = await monitor.DownloadDeployment(file);
|
var result = await Program.DeploymentFilesMonitor.DownloadDeployment(file);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
await context.AdminFollowup("Success!");
|
await context.AdminFollowup("Success!");
|
||||||
@ -171,16 +160,14 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
public class DeployRemoveCommand : SubCommandOption
|
public class DeployRemoveCommand : SubCommandOption
|
||||||
{
|
{
|
||||||
private readonly DeploymentsFilesMonitor monitor;
|
|
||||||
private readonly StringOption stringOption = new StringOption(
|
private readonly StringOption stringOption = new StringOption(
|
||||||
name: "name",
|
name: "name",
|
||||||
description: "Name of deployment to remove.",
|
description: "Name of deployment to remove.",
|
||||||
isRequired: true);
|
isRequired: true);
|
||||||
|
|
||||||
public DeployRemoveCommand(DeploymentsFilesMonitor monitor)
|
public DeployRemoveCommand()
|
||||||
: base("remove", "Removes a deployment file.")
|
: base("remove", "Removes a deployment file.")
|
||||||
{
|
{
|
||||||
this.monitor = monitor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override CommandOption[] Options => new[] { stringOption };
|
public override CommandOption[] Options => new[] { stringOption };
|
||||||
@ -190,7 +177,7 @@ namespace BiblioTech.Commands
|
|||||||
var str = await stringOption.Parse(context);
|
var str = await stringOption.Parse(context);
|
||||||
if (string.IsNullOrEmpty(str)) return;
|
if (string.IsNullOrEmpty(str)) return;
|
||||||
|
|
||||||
var result = monitor.DeleteDeployment(str);
|
var result = Program.DeploymentFilesMonitor.DeleteDeployment(str);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
await context.AdminFollowup("Success!");
|
await context.AdminFollowup("Success!");
|
||||||
@ -201,5 +188,38 @@ namespace BiblioTech.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class WhoIsCommand : SubCommandOption
|
||||||
|
{
|
||||||
|
private readonly UserOption userOption = new UserOption("User", isRequired: false);
|
||||||
|
private readonly EthAddressOption ethAddressOption = new EthAddressOption(isRequired: false);
|
||||||
|
|
||||||
|
public WhoIsCommand()
|
||||||
|
: base(name: "whois",
|
||||||
|
description: "Fetches info about a user or ethAddress in the testnet.")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CommandOption[] Options => new CommandOption[]
|
||||||
|
{
|
||||||
|
userOption,
|
||||||
|
ethAddressOption
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override async Task onSubCommand(CommandContext context)
|
||||||
|
{
|
||||||
|
var user = userOption.GetUser(context);
|
||||||
|
var ethAddr = await ethAddressOption.Parse(context);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
await context.AdminFollowup(Program.UserRepo.GetUserReport(user));
|
||||||
|
}
|
||||||
|
if (ethAddr != null)
|
||||||
|
{
|
||||||
|
await context.AdminFollowup(Program.UserRepo.GetUserReport(ethAddr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ namespace BiblioTech.Commands
|
|||||||
description: "If set, get balance for another user. (Optional, admin-only)",
|
description: "If set, get balance for another user. (Optional, admin-only)",
|
||||||
isRequired: false);
|
isRequired: false);
|
||||||
|
|
||||||
public GetBalanceCommand(DeploymentsFilesMonitor monitor, CoreInterface ci, UserAssociateCommand userAssociateCommand)
|
public GetBalanceCommand(CoreInterface ci, UserAssociateCommand userAssociateCommand)
|
||||||
: base(monitor, ci)
|
: base(ci)
|
||||||
{
|
{
|
||||||
this.userAssociateCommand = userAssociateCommand;
|
this.userAssociateCommand = userAssociateCommand;
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
protected override async Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts)
|
protected override async Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts)
|
||||||
{
|
{
|
||||||
var userId = GetUserId(optionalUser, context);
|
var userId = GetUserFromCommand(optionalUser, context);
|
||||||
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||||
if (addr == null)
|
if (addr == null)
|
||||||
{
|
{
|
||||||
|
@ -14,8 +14,8 @@ namespace BiblioTech.Commands
|
|||||||
isRequired: false);
|
isRequired: false);
|
||||||
private readonly UserAssociateCommand userAssociateCommand;
|
private readonly UserAssociateCommand userAssociateCommand;
|
||||||
|
|
||||||
public MintCommand(DeploymentsFilesMonitor monitor, CoreInterface ci, UserAssociateCommand userAssociateCommand)
|
public MintCommand(CoreInterface ci, UserAssociateCommand userAssociateCommand)
|
||||||
: base(monitor, ci)
|
: base(ci)
|
||||||
{
|
{
|
||||||
this.userAssociateCommand = userAssociateCommand;
|
this.userAssociateCommand = userAssociateCommand;
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
protected override async Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts)
|
protected override async Task Execute(CommandContext context, IGethNode gethNode, ICodexContracts contracts)
|
||||||
{
|
{
|
||||||
var userId = GetUserId(optionalUser, context);
|
var userId = GetUserFromCommand(optionalUser, context);
|
||||||
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
var addr = Program.UserRepo.GetCurrentAddressForUser(userId);
|
||||||
if (addr == null)
|
if (addr == null)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@ namespace BiblioTech.Commands
|
|||||||
{
|
{
|
||||||
public class UserAssociateCommand : BaseCommand
|
public class UserAssociateCommand : BaseCommand
|
||||||
{
|
{
|
||||||
private readonly EthAddressOption ethOption = new EthAddressOption();
|
private readonly EthAddressOption ethOption = new EthAddressOption(isRequired: false);
|
||||||
private readonly UserOption optionalUser = new UserOption(
|
private readonly UserOption optionalUser = new UserOption(
|
||||||
description: "If set, associates Ethereum address for another user. (Optional, admin-only)",
|
description: "If set, associates Ethereum address for another user. (Optional, admin-only)",
|
||||||
isRequired: false);
|
isRequired: false);
|
||||||
@ -16,11 +16,11 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
protected override async Task Invoke(CommandContext context)
|
protected override async Task Invoke(CommandContext context)
|
||||||
{
|
{
|
||||||
var userId = GetUserId(optionalUser, context);
|
var user = GetUserFromCommand(optionalUser, context);
|
||||||
var data = await ethOption.Parse(context);
|
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(user);
|
||||||
if (currentAddress != null && !IsSenderAdmin(context.Command))
|
if (currentAddress != null && !IsSenderAdmin(context.Command))
|
||||||
{
|
{
|
||||||
await context.Followup($"You've already set your Ethereum address to {currentAddress}.");
|
await context.Followup($"You've already set your Ethereum address to {currentAddress}.");
|
||||||
@ -29,7 +29,7 @@ namespace BiblioTech.Commands
|
|||||||
|
|
||||||
// private commands
|
// private commands
|
||||||
|
|
||||||
var result = Program.UserRepo.AssociateUserWithAddress(userId, data);
|
var result = Program.UserRepo.AssociateUserWithAddress(user, data);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
await context.Followup("Done! Thank you for joining the test net!");
|
await context.Followup("Done! Thank you for joining the test net!");
|
||||||
|
@ -5,11 +5,11 @@ namespace BiblioTech.Options
|
|||||||
{
|
{
|
||||||
public class EthAddressOption : CommandOption
|
public class EthAddressOption : CommandOption
|
||||||
{
|
{
|
||||||
public EthAddressOption()
|
public EthAddressOption(bool isRequired)
|
||||||
: 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)
|
isRequired)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,11 @@ namespace BiblioTech.Options
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong? GetOptionUserId(CommandContext context)
|
public IUser? GetUser(CommandContext context)
|
||||||
{
|
{
|
||||||
var userOptionData = context.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;
|
return userOptionData.Value as IUser;
|
||||||
if (user == null) return null;
|
|
||||||
return user.Id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,16 +45,14 @@ namespace BiblioTech
|
|||||||
retryDelay: TimeSpan.FromSeconds(10),
|
retryDelay: TimeSpan.FromSeconds(10),
|
||||||
kubernetesNamespace: "not-applicable"), "datafiles");
|
kubernetesNamespace: "not-applicable"), "datafiles");
|
||||||
|
|
||||||
var monitor = new DeploymentsFilesMonitor();
|
|
||||||
|
|
||||||
var ci = entryPoint.CreateInterface();
|
var ci = entryPoint.CreateInterface();
|
||||||
|
|
||||||
var associateCommand = new UserAssociateCommand();
|
var associateCommand = new UserAssociateCommand();
|
||||||
var handler = new CommandHandler(client,
|
var handler = new CommandHandler(client,
|
||||||
new GetBalanceCommand(monitor, ci, associateCommand),
|
new GetBalanceCommand(ci, associateCommand),
|
||||||
new MintCommand(monitor, ci, associateCommand),
|
new MintCommand(ci, associateCommand),
|
||||||
associateCommand,
|
associateCommand,
|
||||||
new AdminCommand(monitor)
|
new AdminCommand()
|
||||||
);
|
);
|
||||||
|
|
||||||
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using CodexContractsPlugin;
|
using CodexContractsPlugin;
|
||||||
|
using Discord;
|
||||||
using GethPlugin;
|
using GethPlugin;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Utils;
|
||||||
|
|
||||||
namespace BiblioTech
|
namespace BiblioTech
|
||||||
{
|
{
|
||||||
@ -8,70 +10,62 @@ namespace BiblioTech
|
|||||||
{
|
{
|
||||||
private readonly object repoLock = new object();
|
private readonly object repoLock = new object();
|
||||||
|
|
||||||
public bool AssociateUserWithAddress(ulong discordId, EthAddress address)
|
public bool AssociateUserWithAddress(IUser user, EthAddress address)
|
||||||
{
|
{
|
||||||
lock (repoLock)
|
lock (repoLock)
|
||||||
{
|
{
|
||||||
return SetUserAddress(discordId, address);
|
return SetUserAddress(user, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearUserAssociatedAddress(ulong discordId)
|
public void ClearUserAssociatedAddress(IUser user)
|
||||||
{
|
{
|
||||||
lock (repoLock)
|
lock (repoLock)
|
||||||
{
|
{
|
||||||
SetUserAddress(discordId, null);
|
SetUserAddress(user, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddMintEventForUser(ulong discordId, EthAddress usedAddress, Ether eth, TestToken tokens)
|
public void AddMintEventForUser(IUser user, EthAddress usedAddress, Ether eth, TestToken tokens)
|
||||||
{
|
{
|
||||||
lock (repoLock)
|
lock (repoLock)
|
||||||
{
|
{
|
||||||
var user = GetOrCreate(discordId);
|
var userData = GetOrCreate(user);
|
||||||
user.MintEvents.Add(new UserMintEvent(DateTime.UtcNow, usedAddress, eth, tokens));
|
userData.MintEvents.Add(new UserMintEvent(DateTime.UtcNow, usedAddress, eth, tokens));
|
||||||
SaveUser(user);
|
SaveUserData(userData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public EthAddress? GetCurrentAddressForUser(ulong discordId)
|
public EthAddress? GetCurrentAddressForUser(IUser user)
|
||||||
{
|
{
|
||||||
lock (repoLock)
|
lock (repoLock)
|
||||||
{
|
{
|
||||||
return GetOrCreate(discordId).CurrentAddress;
|
return GetOrCreate(user).CurrentAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetInteractionReport(ulong discordId)
|
public string[] GetInteractionReport(IUser user)
|
||||||
{
|
{
|
||||||
var result = new List<string>();
|
var result = new List<string>();
|
||||||
|
|
||||||
lock (repoLock)
|
lock (repoLock)
|
||||||
{
|
{
|
||||||
var filename = GetFilename(discordId);
|
var userData = GetUserData(user);
|
||||||
if (!File.Exists(filename))
|
if (userData == null)
|
||||||
{
|
{
|
||||||
result.Add("User has not joined the test net.");
|
result.Add("User has not joined the test net.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var user = JsonConvert.DeserializeObject<User>(File.ReadAllText(filename));
|
result.Add("User joined on " + userData.CreatedUtc.ToString("o"));
|
||||||
if (user == null)
|
result.Add("Current address: " + userData.CurrentAddress);
|
||||||
|
foreach (var ae in userData.AssociateEvents)
|
||||||
{
|
{
|
||||||
result.Add("Failed to load user records.");
|
result.Add($"{ae.Utc.ToString("o")} - Address set to: {ae.NewAddress}");
|
||||||
}
|
}
|
||||||
else
|
foreach (var me in userData.MintEvents)
|
||||||
{
|
{
|
||||||
result.Add("User joined on " + user.CreatedUtc.ToString("o"));
|
result.Add($"{me.Utc.ToString("o")} - Minted {me.EthReceived} and {me.TestTokensMinted} to {me.UsedAddress}.");
|
||||||
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}.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,40 +73,64 @@ namespace BiblioTech
|
|||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SetUserAddress(ulong discordId, EthAddress? address)
|
public string GetUserReport(IUser user)
|
||||||
{
|
{
|
||||||
if (IsAddressUsed(address))
|
var userData = GetUserData(user);
|
||||||
|
if (userData == null) return "User has not joined the test net.";
|
||||||
|
return userData.CreateOverview();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetUserReport(EthAddress ethAddress)
|
||||||
|
{
|
||||||
|
var userData = GetUserDataForAddress(ethAddress);
|
||||||
|
if (userData == null) return "No user is using this eth address.";
|
||||||
|
return userData.CreateOverview();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SetUserAddress(IUser user, EthAddress? address)
|
||||||
|
{
|
||||||
|
if (GetUserDataForAddress(address) != null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = GetOrCreate(discordId);
|
var userData = GetOrCreate(user);
|
||||||
user.CurrentAddress = address;
|
userData.CurrentAddress = address;
|
||||||
user.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address));
|
userData.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address));
|
||||||
SaveUser(user);
|
SaveUserData(userData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private User GetOrCreate(ulong discordId)
|
private UserData? GetUserData(IUser user)
|
||||||
{
|
{
|
||||||
var filename = GetFilename(discordId);
|
var filename = GetFilename(user);
|
||||||
if (!File.Exists(filename))
|
if (!File.Exists(filename))
|
||||||
{
|
{
|
||||||
return CreateAndSaveNewUser(discordId);
|
return null;
|
||||||
}
|
}
|
||||||
return JsonConvert.DeserializeObject<User>(File.ReadAllText(filename))!;
|
return JsonConvert.DeserializeObject<UserData>(File.ReadAllText(filename))!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private User CreateAndSaveNewUser(ulong discordId)
|
private UserData GetOrCreate(IUser user)
|
||||||
{
|
{
|
||||||
var newUser = new User(discordId, DateTime.UtcNow, null, new List<UserAssociateAddressEvent>(), new List<UserMintEvent>());
|
var userData = GetUserData(user);
|
||||||
SaveUser(newUser);
|
if (userData == null)
|
||||||
|
{
|
||||||
|
return CreateAndSaveNewUserData(user);
|
||||||
|
}
|
||||||
|
return userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserData CreateAndSaveNewUserData(IUser user)
|
||||||
|
{
|
||||||
|
var newUser = new UserData(user.Id, user.GlobalName, DateTime.UtcNow, null, new List<UserAssociateAddressEvent>(), new List<UserMintEvent>());
|
||||||
|
SaveUserData(newUser);
|
||||||
return newUser;
|
return newUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsAddressUsed(EthAddress? address)
|
private UserData? GetUserDataForAddress(EthAddress? address)
|
||||||
{
|
{
|
||||||
if (address == null) return false;
|
if (address == null) return null;
|
||||||
|
|
||||||
// If this becomes a performance problem, switch to in-memory cached list.
|
// If this becomes a performance problem, switch to in-memory cached list.
|
||||||
var files = Directory.GetFiles(Program.Config.UserDataPath);
|
var files = Directory.GetFiles(Program.Config.UserDataPath);
|
||||||
@ -120,24 +138,34 @@ namespace BiblioTech
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var user = JsonConvert.DeserializeObject<User>(File.ReadAllText(file))!;
|
var user = JsonConvert.DeserializeObject<UserData>(File.ReadAllText(file))!;
|
||||||
if (user.CurrentAddress != null &&
|
if (user.CurrentAddress != null &&
|
||||||
user.CurrentAddress.Address == address.Address)
|
user.CurrentAddress.Address == address.Address)
|
||||||
{
|
{
|
||||||
return true;
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveUser(User user)
|
private void SaveUserData(UserData userData)
|
||||||
{
|
{
|
||||||
var filename = GetFilename(user.DiscordId);
|
var filename = GetFilename(userData);
|
||||||
if (File.Exists(filename)) File.Delete(filename);
|
if (File.Exists(filename)) File.Delete(filename);
|
||||||
File.WriteAllText(filename, JsonConvert.SerializeObject(user));
|
File.WriteAllText(filename, JsonConvert.SerializeObject(userData));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFilename(IUser user)
|
||||||
|
{
|
||||||
|
return GetFilename(user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFilename(UserData userData)
|
||||||
|
{
|
||||||
|
return GetFilename(userData.DiscordId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetFilename(ulong discordId)
|
private static string GetFilename(ulong discordId)
|
||||||
@ -146,11 +174,12 @@ namespace BiblioTech
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class User
|
public class UserData
|
||||||
{
|
{
|
||||||
public User(ulong discordId, DateTime createdUtc, EthAddress? currentAddress, List<UserAssociateAddressEvent> associateEvents, List<UserMintEvent> mintEvents)
|
public UserData(ulong discordId, string name, DateTime createdUtc, EthAddress? currentAddress, List<UserAssociateAddressEvent> associateEvents, List<UserMintEvent> mintEvents)
|
||||||
{
|
{
|
||||||
DiscordId = discordId;
|
DiscordId = discordId;
|
||||||
|
Name = name;
|
||||||
CreatedUtc = createdUtc;
|
CreatedUtc = createdUtc;
|
||||||
CurrentAddress = currentAddress;
|
CurrentAddress = currentAddress;
|
||||||
AssociateEvents = associateEvents;
|
AssociateEvents = associateEvents;
|
||||||
@ -158,10 +187,21 @@ namespace BiblioTech
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ulong DiscordId { get; }
|
public ulong DiscordId { get; }
|
||||||
|
public string Name { get; }
|
||||||
public DateTime CreatedUtc { get; }
|
public DateTime CreatedUtc { get; }
|
||||||
public EthAddress? CurrentAddress { get; set; }
|
public EthAddress? CurrentAddress { get; set; }
|
||||||
public List<UserAssociateAddressEvent> AssociateEvents { get; }
|
public List<UserAssociateAddressEvent> AssociateEvents { get; }
|
||||||
public List<UserMintEvent> MintEvents { get; }
|
public List<UserMintEvent> MintEvents { get; }
|
||||||
|
|
||||||
|
public string CreateOverview()
|
||||||
|
{
|
||||||
|
var nl = Environment.NewLine;
|
||||||
|
return
|
||||||
|
$"name: '{Name}' - id:{DiscordId}{nl}" +
|
||||||
|
$"joined: {CreatedUtc.ToString("o")}{nl}" +
|
||||||
|
$"current address: {CurrentAddress}{nl}" +
|
||||||
|
$"{AssociateEvents.Count + MintEvents.Count} total bot events.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserAssociateAddressEvent
|
public class UserAssociateAddressEvent
|
||||||
|
Loading…
x
Reference in New Issue
Block a user