Implement command completion suggestions.

This commit is contained in:
BruceChen 2022-12-06 15:50:17 +08:00
parent 5d2589b10f
commit 84cf749344
115 changed files with 4684 additions and 2695 deletions

View file

@ -0,0 +1,25 @@
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class AccountNickArgumentType : ArgumentType<string>
{
public override string Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadString();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
var accountList = Settings.Config.Main.Advanced.AccountList;
foreach (var account in accountList)
builder.Suggest(account.Key);
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,25 @@
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class AutoCraftRecipeNameArgumentType : ArgumentType<string>
{
public override string Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadString();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
var recipeList = Settings.Config.ChatBot.AutoCraft.Recipes;
foreach (var recipe in recipeList)
builder.Suggest(recipe.Name);
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,29 @@
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class BotNameArgumentType : ArgumentType<string>
{
public override string Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadString();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
McClient? client = CmdResult.client;
if (client != null)
{
var botList = client.GetLoadedChatBots();
foreach (var bot in botList)
builder.Suggest(bot.GetType().Name);
}
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,31 @@
using System;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Exceptions;
using Brigadier.NET.Suggestion;
using MinecraftClient.Mapping;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class EntityTypeArgumentType : ArgumentType<EntityType>
{
public override EntityType Parse(IStringReader reader)
{
reader.SkipWhitespace();
string entity = reader.ReadString();
if (Enum.TryParse(entity, true, out EntityType entityType))
return entityType;
else
throw CommandSyntaxException.BuiltInExceptions.LiteralIncorrect().CreateWithContext(reader, entity);
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
foreach (var result in Enum.GetNames(typeof(EntityType)))
builder.Suggest(result);
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,31 @@
using System;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Exceptions;
using Brigadier.NET.Suggestion;
using static MinecraftClient.ChatBots.Farmer;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class FarmerCropTypeArgumentType : ArgumentType<CropType>
{
public override CropType Parse(IStringReader reader)
{
reader.SkipWhitespace();
string inputStr = reader.ReadString();
if (Enum.TryParse(inputStr, true, out CropType cropType))
return cropType;
else
throw CommandSyntaxException.BuiltInExceptions.LiteralIncorrect().CreateWithContext(reader, inputStr);
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
foreach (var result in Enum.GetNames(typeof(CropType)))
builder.Suggest(result);
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,41 @@
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Exceptions;
using Brigadier.NET.Suggestion;
using MinecraftClient.Inventory;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class InventoryActionArgumentType : ArgumentType<WindowActionType>
{
private WindowActionType[] SupportActions = new WindowActionType[]
{
WindowActionType.LeftClick,
WindowActionType.RightClick,
WindowActionType.MiddleClick,
WindowActionType.ShiftClick,
};
public override WindowActionType Parse(IStringReader reader)
{
reader.SkipWhitespace();
string inputStr = reader.ReadString();
foreach (var action in SupportActions)
{
string actionStr = action.ToString();
if (string.Compare(inputStr, actionStr, true) == 0)
return action;
}
throw CommandSyntaxException.BuiltInExceptions.LiteralIncorrect().CreateWithContext(reader, inputStr);
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
foreach (var action in SupportActions)
builder.Suggest(action.ToString());
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class InventoryIdArgumentType : ArgumentType<int>
{
public override int Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadInt();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
McClient? client = CmdResult.client;
if (client != null)
{
var invList = client.GetInventories();
foreach (var inv in invList)
{
string invName = inv.Key.ToString();
if (invName.StartsWith(builder.RemainingLowerCase, StringComparison.InvariantCultureIgnoreCase))
builder.Suggest(invName);
}
}
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,31 @@
using System;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Exceptions;
using Brigadier.NET.Suggestion;
using MinecraftClient.Inventory;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class ItemTypeArgumentType : ArgumentType<ItemType>
{
public override ItemType Parse(IStringReader reader)
{
reader.SkipWhitespace();
string entity = reader.ReadString();
if (Enum.TryParse(entity, true, out ItemType itemType))
return itemType;
else
throw CommandSyntaxException.BuiltInExceptions.LiteralIncorrect().CreateWithContext(reader, entity);
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
foreach (var result in Enum.GetNames(typeof(ItemType)))
builder.Suggest(result);
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,99 @@
using System;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
using MinecraftClient.Mapping;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class LocationArgumentType : ArgumentType<Location>
{
public override Location Parse(IStringReader reader)
{
int[] status = new int[3];
double[] coords = new double[3];
for (int i = 0; i < 3; ++i)
{
reader.SkipWhitespace();
if (reader.Peek() == '~' || reader.Peek() == '')
{
status[i] = 1;
reader.Next();
if (reader.CanRead())
{
char next = reader.Peek();
if (char.IsDigit(next) || next == '.' || next == '-')
coords[i] = reader.ReadDouble();
else if (next == '+')
{
reader.Next();
coords[i] = reader.ReadDouble();
}
else coords[i] = 0;
}
else coords[i] = 0;
}
else
{
status[i] = 0;
coords[i] = reader.ReadDouble();
}
}
return new Location(coords[0], coords[1], coords[2], (byte)(status[0] | status[1] << 1 | status[2] << 2));
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
McClient? client = CmdResult.client;
string[] args = builder.Remaining.Split(' ', StringSplitOptions.TrimEntries);
if (args.Length == 0 || (args.Length == 1 && string.IsNullOrWhiteSpace(args[0])))
{
if (client != null)
{
Location current = client.GetCurrentLocation();
builder.Suggest(string.Format("{0:0.00}", current.X));
builder.Suggest(string.Format("{0:0.00} {1:0.00}", current.X, current.Y));
builder.Suggest(string.Format("{0:0.00} {1:0.00} {2:0.00}", current.X, current.Y, current.Z));
}
else
{
builder.Suggest("~");
builder.Suggest("~ ~");
builder.Suggest("~ ~ ~");
}
}
else if (args.Length == 1 || (args.Length == 2 && string.IsNullOrWhiteSpace(args[1])))
{
string add = args.Length == 1 ? " " : string.Empty;
if (client != null)
{
Location current = client.GetCurrentLocation();
builder.Suggest(string.Format("{0}{2}{1:0.00}", builder.Remaining, current.Y, add));
builder.Suggest(string.Format("{0}{3}{1:0.00} {2:0.00}", builder.Remaining, current.Y, current.Z, add));
}
else
{
builder.Suggest(builder.Remaining + add + "~");
builder.Suggest(builder.Remaining + add + "~ ~");
}
}
else if (args.Length == 2 || (args.Length == 3 && string.IsNullOrWhiteSpace(args[2])))
{
string add = args.Length == 2 ? " " : string.Empty;
if (client != null)
{
Location current = client.GetCurrentLocation();
builder.Suggest(string.Format("{0}{2}{1:0.00}", builder.Remaining, current.Z, add));
}
else
{
builder.Suggest(builder.Remaining + add + "~");
}
}
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
using MinecraftClient.ChatBots;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class MapBotMapIdArgumentType : ArgumentType<int>
{
public override int Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadInt();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
McClient? client = CmdResult.client;
if (client != null)
{
var bot = (Map?)client.GetLoadedChatBots().Find(bot => bot.GetType().Name == "Map");
if (bot != null)
{
var mapList = bot.cachedMaps;
foreach (var map in mapList)
{
string mapName = map.Key.ToString();
if (mapName.StartsWith(builder.RemainingLowerCase, StringComparison.InvariantCultureIgnoreCase))
builder.Suggest(mapName);
}
}
}
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,36 @@
using System.Linq;
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
using MinecraftClient.Mapping;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class PlayerNameArgumentType : ArgumentType<string>
{
public override string Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadString();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
McClient? client = CmdResult.client;
if (client != null)
{
var entityList = client.GetEntities().Values.ToList();
foreach (var entity in entityList)
{
if (entity.Type != EntityType.Player || string.IsNullOrWhiteSpace(entity.Name))
continue;
builder.Suggest(entity.Name);
}
builder.Suggest(client.GetUsername());
}
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,25 @@
using System.Threading.Tasks;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
using Brigadier.NET.Context;
using Brigadier.NET.Suggestion;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class ServerNickArgumentType : ArgumentType<string>
{
public override string Parse(IStringReader reader)
{
reader.SkipWhitespace();
return reader.ReadString();
}
public override Task<Suggestions> ListSuggestions<TSource>(CommandContext<TSource> context, SuggestionsBuilder builder)
{
var serverList = Settings.Config.Main.Advanced.ServerList;
foreach (var server in serverList)
builder.Suggest(server.Key);
return builder.BuildFuture();
}
}
}

View file

@ -0,0 +1,18 @@
using System;
using Brigadier.NET;
using Brigadier.NET.ArgumentTypes;
namespace MinecraftClient.CommandHandler.ArgumentType
{
public class TupleArgumentType : ArgumentType<Tuple<int, int>>
{
public override Tuple<int, int> Parse(IStringReader reader)
{
reader.SkipWhitespace();
int int1 = reader.ReadInt();
reader.SkipWhitespace();
int int2 = reader.ReadInt();
return new(int1, int2);
}
}
}