diff --git a/Tools/BiblioTech/BaseCodexCommand.cs b/Tools/BiblioTech/BaseCodexCommand.cs new file mode 100644 index 0000000..737e0ec --- /dev/null +++ b/Tools/BiblioTech/BaseCodexCommand.cs @@ -0,0 +1,27 @@ +using BiblioTech.Options; +using CodexPlugin; +using Core; + +namespace BiblioTech +{ + public abstract class BaseCodexCommand : BaseDeploymentCommand + { + private readonly CoreInterface ci; + + public BaseCodexCommand(CoreInterface ci) + { + this.ci = ci; + } + + protected override async Task ExecuteDeploymentCommand(CommandContext context, CodexDeployment codexDeployment) + { + var codexContainers = codexDeployment.CodexInstances.Select(c => c.Container).ToArray(); + + var group = ci.WrapCodexContainers(codexContainers); + + await Execute(context, group); + } + + protected abstract Task Execute(CommandContext context, ICodexNodeGroup codexGroup); + } +} diff --git a/Tools/BiblioTech/BaseDeploymentCommand.cs b/Tools/BiblioTech/BaseDeploymentCommand.cs new file mode 100644 index 0000000..100c39f --- /dev/null +++ b/Tools/BiblioTech/BaseDeploymentCommand.cs @@ -0,0 +1,36 @@ +using BiblioTech.Options; +using CodexPlugin; + +namespace BiblioTech +{ + public abstract class BaseDeploymentCommand : BaseCommand + { + protected override async Task Invoke(CommandContext context) + { + var proceed = await OnInvoke(context); + if (!proceed) return; + + var deployments = Program.DeploymentFilesMonitor.GetDeployments(); + if (deployments.Length == 0) + { + await context.Followup("No deployments are currently available."); + return; + } + if (deployments.Length > 1) + { + await context.Followup("Multiple deployments are online. I don't know which one to pick!"); + return; + } + + var codexDeployment = deployments.Single(); + await ExecuteDeploymentCommand(context, codexDeployment); + } + + protected abstract Task ExecuteDeploymentCommand(CommandContext context, CodexDeployment codexDeployment); + + protected virtual Task OnInvoke(CommandContext context) + { + return Task.FromResult(true); + } + } +} diff --git a/Tools/BiblioTech/BaseNetCommand.cs b/Tools/BiblioTech/BaseGethCommand.cs similarity index 50% rename from Tools/BiblioTech/BaseNetCommand.cs rename to Tools/BiblioTech/BaseGethCommand.cs index 4995cb8..37841b1 100644 --- a/Tools/BiblioTech/BaseNetCommand.cs +++ b/Tools/BiblioTech/BaseGethCommand.cs @@ -1,34 +1,22 @@ using BiblioTech.Options; using CodexContractsPlugin; +using CodexPlugin; using Core; using GethPlugin; namespace BiblioTech { - public abstract class BaseNetCommand : BaseCommand + public abstract class BaseGethCommand : BaseDeploymentCommand { private readonly CoreInterface ci; - public BaseNetCommand(CoreInterface ci) + public BaseGethCommand(CoreInterface ci) { this.ci = ci; } - protected override async Task Invoke(CommandContext context) + protected override async Task ExecuteDeploymentCommand(CommandContext context, CodexDeployment codexDeployment) { - var deployments = Program.DeploymentFilesMonitor.GetDeployments(); - if (deployments.Length == 0) - { - await context.Followup("No deployments are currently available."); - return; - } - if (deployments.Length > 1) - { - await context.Followup("Multiple deployments are online. I don't know which one to pick!"); - return; - } - - var codexDeployment = deployments.Single(); var gethDeployment = codexDeployment.GethDeployment; var contractsDeployment = codexDeployment.CodexContractsDeployment; diff --git a/Tools/BiblioTech/Commands/GetBalanceCommand.cs b/Tools/BiblioTech/Commands/GetBalanceCommand.cs index e0703d6..05337ab 100644 --- a/Tools/BiblioTech/Commands/GetBalanceCommand.cs +++ b/Tools/BiblioTech/Commands/GetBalanceCommand.cs @@ -5,7 +5,7 @@ using GethPlugin; namespace BiblioTech.Commands { - public class GetBalanceCommand : BaseNetCommand + public class GetBalanceCommand : BaseGethCommand { private readonly UserAssociateCommand userAssociateCommand; private readonly UserOption optionalUser = new UserOption( @@ -19,7 +19,7 @@ namespace BiblioTech.Commands } public override string Name => "balance"; - public override string StartingMessage => "Fetching balance..."; + public override string StartingMessage => RandomBusyMessage.Get(); public override string Description => "Shows Eth and TestToken balance of an eth address."; public override CommandOption[] Options => new[] { optionalUser }; diff --git a/Tools/BiblioTech/Commands/MintCommand.cs b/Tools/BiblioTech/Commands/MintCommand.cs index b6dde9d..ed87a1e 100644 --- a/Tools/BiblioTech/Commands/MintCommand.cs +++ b/Tools/BiblioTech/Commands/MintCommand.cs @@ -5,7 +5,7 @@ using GethPlugin; namespace BiblioTech.Commands { - public class MintCommand : BaseNetCommand + public class MintCommand : BaseGethCommand { private readonly Ether defaultEthToSend = 10.Eth(); private readonly TestToken defaultTestTokensToMint = 1024.TestTokens(); @@ -21,7 +21,7 @@ namespace BiblioTech.Commands } public override string Name => "mint"; - public override string StartingMessage => "Minting some tokens..."; + public override string StartingMessage => RandomBusyMessage.Get(); 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 }; diff --git a/Tools/BiblioTech/Commands/SprCommand.cs b/Tools/BiblioTech/Commands/SprCommand.cs new file mode 100644 index 0000000..6d52b3d --- /dev/null +++ b/Tools/BiblioTech/Commands/SprCommand.cs @@ -0,0 +1,61 @@ +using BiblioTech.Options; +using CodexPlugin; +using Core; + +namespace BiblioTech.Commands +{ + public class SprCommand : BaseCodexCommand + { + private readonly Random random = new Random(); + private readonly List sprCache = new List(); + private DateTime lastUpdate = DateTime.MinValue; + + public SprCommand(CoreInterface ci) : base(ci) + { + } + + public override string Name => "boot"; + public override string StartingMessage => RandomBusyMessage.Get(); + public override string Description => "Gets an SPR. (Signed peer record, used for bootstrapping.)"; + + protected override async Task OnInvoke(CommandContext context) + { + if (ShouldUpdate()) + { + return true; + } + + await ReplyWithRandomSpr(context); + return false; + } + + protected override async Task Execute(CommandContext context, ICodexNodeGroup codexGroup) + { + lastUpdate = DateTime.UtcNow; + sprCache.Clear(); + + var infos = codexGroup.Select(c => c.GetDebugInfo()).ToArray(); + sprCache.AddRange(infos.Select(i => i.spr)); + + await ReplyWithRandomSpr(context); + } + + private async Task ReplyWithRandomSpr(CommandContext context) + { + if (!sprCache.Any()) + { + await context.Followup("I'm sorry, no SPRs are available... :c"); + return; + } + + var i = random.Next(0, sprCache.Count); + var spr = sprCache[i]; + await context.Followup($"Your SPR: '{spr}'"); + } + + private bool ShouldUpdate() + { + return (DateTime.UtcNow - lastUpdate) > TimeSpan.FromMinutes(10); + } + } +} diff --git a/Tools/BiblioTech/Commands/UserAssociateCommand.cs b/Tools/BiblioTech/Commands/UserAssociateCommand.cs index a6160ec..2ede721 100644 --- a/Tools/BiblioTech/Commands/UserAssociateCommand.cs +++ b/Tools/BiblioTech/Commands/UserAssociateCommand.cs @@ -10,7 +10,7 @@ namespace BiblioTech.Commands isRequired: false); public override string Name => "set"; - public override string StartingMessage => "hold on..."; + public override string StartingMessage => RandomBusyMessage.Get(); public override string Description => "Associates a Discord user with an Ethereum address."; public override CommandOption[] Options => new CommandOption[] { ethOption, optionalUser }; diff --git a/Tools/BiblioTech/DeploymentsFilesMonitor.cs b/Tools/BiblioTech/DeploymentsFilesMonitor.cs index c02ed11..c06139f 100644 --- a/Tools/BiblioTech/DeploymentsFilesMonitor.cs +++ b/Tools/BiblioTech/DeploymentsFilesMonitor.cs @@ -6,14 +6,16 @@ namespace BiblioTech { public class DeploymentsFilesMonitor { - private DateTime lastUpdate = DateTime.MinValue; - private CodexDeployment[] deployments = Array.Empty(); + private readonly List deployments = new List(); + + public DeploymentsFilesMonitor() + { + LoadDeployments(); + } public CodexDeployment[] GetDeployments() { - if (ShouldUpdate()) UpdateDeployments(); - - return deployments; + return deployments.ToArray(); } public async Task DownloadDeployment(IAttachment file) @@ -30,7 +32,7 @@ namespace BiblioTech { var targetFile = Path.Combine(Program.Config.EndpointsPath, Guid.NewGuid().ToString().ToLowerInvariant() + ".json"); File.WriteAllText(targetFile, str); - deployments = Array.Empty(); + deployments.Add(deploy); return true; } } @@ -44,22 +46,21 @@ namespace BiblioTech if (!Directory.Exists(path)) return false; var files = Directory.GetFiles(path); - foreach ( var file in files) + foreach (var file in files) { var deploy = ProcessFile(file); if (deploy != null && deploy.Metadata.Name == deploymentName) { File.Delete(file); - deployments = Array.Empty(); + deployments.Remove(deploy); return true; } } return false; } - private void UpdateDeployments() + private void LoadDeployments() { - lastUpdate = DateTime.UtcNow; var path = Program.Config.EndpointsPath; if (!Directory.Exists(path)) { @@ -69,7 +70,7 @@ namespace BiblioTech } var files = Directory.GetFiles(path); - deployments = files.Select(ProcessFile).Where(d => d != null).Cast().ToArray(); + deployments.AddRange(files.Select(ProcessFile).Where(d => d != null).Cast()); } private CodexDeployment? ProcessFile(string filename) @@ -84,10 +85,5 @@ namespace BiblioTech return null; } } - - private bool ShouldUpdate() - { - return !deployments.Any() || (DateTime.UtcNow - lastUpdate) > TimeSpan.FromMinutes(10); - } } } diff --git a/Tools/BiblioTech/Program.cs b/Tools/BiblioTech/Program.cs index e4c5733..290cad2 100644 --- a/Tools/BiblioTech/Program.cs +++ b/Tools/BiblioTech/Program.cs @@ -50,6 +50,7 @@ namespace BiblioTech var handler = new CommandHandler(client, new GetBalanceCommand(ci, associateCommand), new MintCommand(ci, associateCommand), + new SprCommand(ci), associateCommand, new AdminCommand(ci) ); diff --git a/Tools/BiblioTech/RandomBusyMessage.cs b/Tools/BiblioTech/RandomBusyMessage.cs new file mode 100644 index 0000000..5582767 --- /dev/null +++ b/Tools/BiblioTech/RandomBusyMessage.cs @@ -0,0 +1,25 @@ +namespace BiblioTech +{ + public static class RandomBusyMessage + { + private static readonly Random random = new Random(); + private static readonly string[] messages = new[] + { + "Working on it...", + "Doing that...", + "Hang on...", + "Making it so...", + "Reversing the polarity...", + "Factoring the polynomial...", + "Analyzing the wavelengths...", + "Charging the flux-capacitor...", + "Jumping to hyperspace...", + "Computing the ultimate answer..." + }; + + public static string Get() + { + return messages[random.Next(messages.Length)]; + } + } +}