server:
Fixed cli help texts Added administrator options for critical methods Added result state for client and server specific errors Redirect root to help text Fixed fingerprint error, fingerprint must be case sensitive Re-Added online messages Added typing trigger for discord bot messages client: fixed chunkString for empty results preemtive wrap error objects for server messages both: added raw lua RS Bridge command entry
This commit is contained in:
@ -2,17 +2,21 @@
|
||||
using MinecraftDiscordBot.Commands;
|
||||
using MinecraftDiscordBot.Models;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace MinecraftDiscordBot.Services;
|
||||
|
||||
public class RefinedStorageService : CommandRouter {
|
||||
private readonly ITaskWaitSource _taskSource;
|
||||
private readonly IUserRoleManager _roleManager;
|
||||
public override string HelpTextPrefix => "!rs ";
|
||||
public RefinedStorageService(ITaskWaitSource taskSource) : base() => _taskSource = taskSource;
|
||||
public RefinedStorageService(ITaskWaitSource taskSource, IUserRoleManager roleManager) : base() {
|
||||
_taskSource = taskSource;
|
||||
_roleManager = roleManager;
|
||||
}
|
||||
|
||||
public override Task<ResponseType> FallbackHandler(SocketUserMessage message, string method, string[] parameters, CancellationToken ct)
|
||||
=> throw new ReplyException($"The RS system has no command '{method}'!");
|
||||
public override Task<ResponseType> RootAnswer(SocketUserMessage message, CancellationToken ct)
|
||||
=> Task.FromResult(ResponseType.AsString("The RS system is online!"));
|
||||
|
||||
private async Task<T> Method<T>(string methodName, Func<string, T> parser, CancellationToken ct, Dictionary<string, object>? parameters = null) {
|
||||
var waiter = _taskSource.GetWaiter(parser, ct);
|
||||
@ -27,6 +31,7 @@ public class RefinedStorageService : CommandRouter {
|
||||
private const string CmdListFluids = "listfluids";
|
||||
private const string CmdCraftItem = "craft";
|
||||
private const string CmdGetItem = "getitem";
|
||||
private const string CmdCommand = "command";
|
||||
|
||||
public async Task<int> GetEnergyUsageAsync(CancellationToken ct) => await Method(CmdEnergyUsage, int.Parse, ct);
|
||||
public async Task<int> GetEnergyStorageAsync(CancellationToken ct) => await Method(CmdEnergyStorage, int.Parse, ct);
|
||||
@ -35,10 +40,16 @@ public class RefinedStorageService : CommandRouter {
|
||||
public async Task<Item> GetItemData(string itemid, CancellationToken ct) => await Method(CmdGetItem, RootCommandService.Deserialize<Item>(), ct, new() {
|
||||
["name"] = itemid
|
||||
});
|
||||
public async Task<Item> GetItemData(Md5Hash fingerprint, CancellationToken ct) => await Method(CmdGetItem, RootCommandService.Deserialize<Item>(), ct, new() {
|
||||
["fingerprint"] = fingerprint.ToString()
|
||||
});
|
||||
public async Task<bool> CraftItem(string itemid, int amount, CancellationToken ct) => await Method(CmdCraftItem, RootCommandService.Deserialize<bool>(), ct, new() {
|
||||
["name"] = itemid,
|
||||
["count"] = amount
|
||||
});
|
||||
public async Task<LuaPackedArray> RawCommand(string command, CancellationToken ct) => await Method(CmdCommand, LuaPackedArray.Deserialize, ct, new() {
|
||||
["command"] = command
|
||||
});
|
||||
|
||||
private Task<IEnumerable<Item>> FilterItems(SocketUserMessage message, IEnumerable<string> filters, CancellationToken ct)
|
||||
=> FilterItems(message, filters.Select(ItemFilter.Parse), ct);
|
||||
@ -89,19 +100,12 @@ public class RefinedStorageService : CommandRouter {
|
||||
}
|
||||
[CommandHandler(CmdGetItem, HelpText = "Get information about a specific item.")]
|
||||
public async Task<ResponseType> HandleGetItemData(SocketUserMessage message, string[] parameters, CancellationToken ct) {
|
||||
var amount = 1;
|
||||
string itemid;
|
||||
if (parameters.Length is 1 or 2) {
|
||||
itemid = parameters[0];
|
||||
if (parameters.Length is 2)
|
||||
if (int.TryParse(parameters[1], out var value)) amount = value;
|
||||
else return ResponseType.AsString($"I expected an amount to craft, not '{parameters[1]}'!");
|
||||
} else return parameters.Length is < 1
|
||||
? ResponseType.AsString("You have to give me at least an item name!")
|
||||
: parameters.Length is > 2
|
||||
? ResponseType.AsString("Yo, those are way too many arguments! I want only item name and maybe an amount!")
|
||||
: throw new InvalidOperationException($"Forgot to match parameter length {parameters.Length}!");
|
||||
var item = await GetItemData(itemid, ct);
|
||||
if (parameters.Length is not 1) throw new ReplyException($"I only want one name or fingerprint to search for, you gave me {parameters.Length} arguments!");
|
||||
itemid = parameters[0];
|
||||
var item = await (Md5Hash.TryParse(itemid, out var fingerprint)
|
||||
? GetItemData(fingerprint, ct)
|
||||
: GetItemData(itemid, ct));
|
||||
var sb = new StringBuilder();
|
||||
sb.Append($"We currently have {item.Amount:n0} {item.CleanDisplayName}!");
|
||||
if (item.Tags is not null and var tags) {
|
||||
@ -111,6 +115,7 @@ public class RefinedStorageService : CommandRouter {
|
||||
sb.Append($"\nRefer to this item with fingerprint {item.Fingerprint}");
|
||||
return ResponseType.AsString(sb.ToString());
|
||||
}
|
||||
|
||||
[CommandHandler(CmdItemName, HelpText = "Filter items by name.")]
|
||||
public async Task<ResponseType> HandleItemName(SocketUserMessage message, string[] parameters, CancellationToken ct) {
|
||||
if (parameters.Length < 2) return ResponseType.AsString($"Usage: {CmdItemName} filters...");
|
||||
@ -134,6 +139,14 @@ public class RefinedStorageService : CommandRouter {
|
||||
return ResponseType.AsString(sb.ToString());
|
||||
}
|
||||
|
||||
[CommandHandler(CmdCommand, HelpText = "Runs a raw command on the RS system.")]
|
||||
public async Task<ResponseType> HandleRawCommand(SocketUserMessage message, string[] parameters, CancellationToken ct) {
|
||||
_roleManager.RequireAdministrator(message.Author.Id, "You are not authorized to run raw commands on this instance!");
|
||||
var command = string.Join(' ', parameters);
|
||||
var response = await RawCommand(command, ct);
|
||||
return ResponseType.AsString(response.ToString());
|
||||
}
|
||||
|
||||
[CommandHandler(CmdListItems, HelpText = "Gets a list of items that are currently stored in the RS system.")]
|
||||
public async Task<ResponseType> HandleItemListing(SocketUserMessage message, string[] parameters, CancellationToken ct) {
|
||||
var sb = new StringBuilder();
|
||||
|
@ -12,10 +12,10 @@ public delegate Task HandleCommandDelegate(SocketUserMessage message, string[] p
|
||||
public class RootCommandService : CommandRouter, ITaskWaitSource {
|
||||
protected readonly IWebSocketConnection _socket;
|
||||
public override string HelpTextPrefix => "!";
|
||||
public RootCommandService(IWebSocketConnection socket) : base() {
|
||||
public RootCommandService(IWebSocketConnection socket, IUserRoleManager roleManager) : base() {
|
||||
socket.OnMessage = OnMessage;
|
||||
_socket = socket;
|
||||
_rs = new RefinedStorageService(this);
|
||||
_rs = new RefinedStorageService(this, roleManager);
|
||||
}
|
||||
|
||||
private void OnMessage(string message) {
|
||||
@ -25,7 +25,7 @@ public class RootCommandService : CommandRouter, ITaskWaitSource {
|
||||
Program.LogWarningAsync("Socket", $"Invalid wait id '{msg.AnswerId}'!");
|
||||
return;
|
||||
}
|
||||
if (!msg.Success) waiter.SetUnsuccessful();
|
||||
waiter.SetResultState(msg.State);
|
||||
waiter.AddChunk(msg.Chunk, msg.Total, msg.Result);
|
||||
if (waiter.Finished || waiter.IsCancellationRequested)
|
||||
lock (_syncRoot)
|
||||
@ -65,8 +65,6 @@ public class RootCommandService : CommandRouter, ITaskWaitSource {
|
||||
|
||||
public static Func<string, T> Deserialize<T>() => msg
|
||||
=> JsonConvert.DeserializeObject<T>(msg) ?? throw new InvalidProgramException("Empty response!");
|
||||
public override Task<ResponseType> RootAnswer(SocketUserMessage message, CancellationToken ct)
|
||||
=> Task.FromResult(ResponseType.AsString("The Minecraft server is connected!"));
|
||||
public override Task<ResponseType> FallbackHandler(SocketUserMessage message, string method, string[] parameters, CancellationToken ct)
|
||||
=> throw new ReplyException($"What the fuck do you mean by '{method}'?");
|
||||
}
|
||||
|
Reference in New Issue
Block a user