mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
merge brigadier-dev into milutinke:1.19.3
This commit is contained in:
commit
ba0d9ba3fc
139 changed files with 12057 additions and 3183 deletions
2
.github/workflows/build-and-release.yml
vendored
2
.github/workflows/build-and-release.yml
vendored
|
|
@ -8,7 +8,7 @@ on:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PROJECT: "MinecraftClient"
|
PROJECT: "MinecraftClient"
|
||||||
target-version: "net6.0"
|
target-version: "net7.0"
|
||||||
compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None"
|
compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ Global
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
RESX_SortFileContentOnSave = True
|
|
||||||
SolutionGuid = {6DED60F4-9CF4-4DB3-8966-582B2EBE8487}
|
|
||||||
RESX_ShowErrorsInErrorList = False
|
RESX_ShowErrorsInErrorList = False
|
||||||
|
SolutionGuid = {6DED60F4-9CF4-4DB3-8966-582B2EBE8487}
|
||||||
|
RESX_SortFileContentOnSave = False
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,13 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
using static MinecraftClient.ChatBots.AutoCraft.Configs;
|
using static MinecraftClient.ChatBots.AutoCraft.Configs;
|
||||||
|
|
||||||
|
|
@ -11,6 +16,8 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class AutoCraft : ChatBot
|
public class AutoCraft : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "autocraft";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -40,7 +47,7 @@ namespace MinecraftClient.ChatBots
|
||||||
Name: "Recipe-Name-2",
|
Name: "Recipe-Name-2",
|
||||||
Type: CraftTypeConfig.table,
|
Type: CraftTypeConfig.table,
|
||||||
Result: ItemType.StoneBricks,
|
Result: ItemType.StoneBricks,
|
||||||
Slots: new ItemType[9] {
|
Slots: new ItemType[9] {
|
||||||
ItemType.Stone, ItemType.Stone, ItemType.Null,
|
ItemType.Stone, ItemType.Stone, ItemType.Null,
|
||||||
ItemType.Stone, ItemType.Stone, ItemType.Null,
|
ItemType.Stone, ItemType.Stone, ItemType.Null,
|
||||||
ItemType.Null, ItemType.Null, ItemType.Null,
|
ItemType.Null, ItemType.Null, ItemType.Null,
|
||||||
|
|
@ -117,7 +124,7 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
public ItemType Result = ItemType.Air;
|
public ItemType Result = ItemType.Air;
|
||||||
|
|
||||||
public ItemType[] Slots = new ItemType[9] {
|
public ItemType[] Slots = new ItemType[9] {
|
||||||
ItemType.Null, ItemType.Null, ItemType.Null,
|
ItemType.Null, ItemType.Null, ItemType.Null,
|
||||||
ItemType.Null, ItemType.Null, ItemType.Null,
|
ItemType.Null, ItemType.Null, ItemType.Null,
|
||||||
ItemType.Null, ItemType.Null, ItemType.Null,
|
ItemType.Null, ItemType.Null, ItemType.Null,
|
||||||
|
|
@ -288,81 +295,94 @@ namespace MinecraftClient.ChatBots
|
||||||
UnloadBot();
|
UnloadBot();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RegisterChatBotCommand("autocraft", Translations.bot_autoCraft_cmd, GetHelp(), CommandHandler);
|
|
||||||
RegisterChatBotCommand("ac", Translations.bot_autoCraft_alias, GetHelp(), CommandHandler);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "list")))
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "start")))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "stop")))
|
||||||
|
.Then(l => l.Literal("help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "help")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OnCommandList(r.Source)))
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Then(l => l.Argument("RecipeName", MccArguments.AutoCraftRecipeName())
|
||||||
|
.Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "RecipeName")))))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandStop(r.Source)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CommandHandler(string cmd, string[] args)
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
if (args.Length > 0)
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
{
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
switch (args[0])
|
|
||||||
{
|
|
||||||
case "list":
|
|
||||||
StringBuilder nameList = new();
|
|
||||||
foreach (RecipeConfig recipe in Config.Recipes)
|
|
||||||
nameList.Append(recipe.Name).Append(", ");
|
|
||||||
return string.Format(Translations.bot_autoCraft_cmd_list, Config.Recipes.Length, nameList.ToString());
|
|
||||||
case "start":
|
|
||||||
if (args.Length >= 2)
|
|
||||||
{
|
|
||||||
string name = args[1];
|
|
||||||
|
|
||||||
bool hasRecipe = false;
|
|
||||||
RecipeConfig? recipe = null;
|
|
||||||
foreach (RecipeConfig recipeConfig in Config.Recipes)
|
|
||||||
{
|
|
||||||
if (recipeConfig.Name == name)
|
|
||||||
{
|
|
||||||
hasRecipe = true;
|
|
||||||
recipe = recipeConfig;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasRecipe)
|
|
||||||
{
|
|
||||||
ResetVar();
|
|
||||||
PrepareCrafting(recipe!);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Translations.bot_autoCraft_recipe_not_exist;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Translations.bot_autoCraft_no_recipe_name;
|
|
||||||
case "stop":
|
|
||||||
StopCrafting();
|
|
||||||
return Translations.bot_autoCraft_stop;
|
|
||||||
case "help":
|
|
||||||
return GetCommandHelp(args.Length >= 2 ? args[1] : "");
|
|
||||||
default:
|
|
||||||
return GetHelp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return GetHelp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetHelp()
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
{
|
{
|
||||||
return string.Format(Translations.bot_autoCraft_available_cmd, "load, list, reload, resetcfg, start, stop, help");
|
return r.SetAndReturn(cmd switch
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCommandHelp(string cmd)
|
|
||||||
{
|
|
||||||
return cmd.ToLower() switch
|
|
||||||
{
|
{
|
||||||
#pragma warning disable format // @formatter:off
|
#pragma warning disable format // @formatter:off
|
||||||
"load" => Translations.bot_autoCraft_help_load,
|
|
||||||
"list" => Translations.bot_autoCraft_help_list,
|
"list" => Translations.bot_autoCraft_help_list,
|
||||||
"reload" => Translations.bot_autoCraft_help_reload,
|
|
||||||
"resetcfg" => Translations.bot_autoCraft_help_resetcfg,
|
|
||||||
"start" => Translations.bot_autoCraft_help_start,
|
"start" => Translations.bot_autoCraft_help_start,
|
||||||
"stop" => Translations.bot_autoCraft_help_stop,
|
"stop" => Translations.bot_autoCraft_help_stop,
|
||||||
"help" => Translations.bot_autoCraft_help_help,
|
"help" => Translations.bot_autoCraft_help_help,
|
||||||
_ => GetHelp(),
|
_ => string.Format(Translations.bot_autoCraft_available_cmd, "load, list, reload, resetcfg, start, stop, help")
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
#pragma warning restore format // @formatter:on
|
#pragma warning restore format // @formatter:on
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandList(CmdResult r)
|
||||||
|
{
|
||||||
|
StringBuilder nameList = new();
|
||||||
|
foreach (RecipeConfig recipe in Config.Recipes)
|
||||||
|
nameList.Append(recipe.Name).Append(", ");
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_autoCraft_cmd_list, Config.Recipes.Length, nameList.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandStart(CmdResult r, string name)
|
||||||
|
{
|
||||||
|
bool hasRecipe = false;
|
||||||
|
RecipeConfig? recipe = null;
|
||||||
|
foreach (RecipeConfig recipeConfig in Config.Recipes)
|
||||||
|
{
|
||||||
|
if (recipeConfig.Name == name)
|
||||||
|
{
|
||||||
|
hasRecipe = true;
|
||||||
|
recipe = recipeConfig;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRecipe)
|
||||||
|
{
|
||||||
|
ResetVar();
|
||||||
|
PrepareCrafting(recipe!);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_autoCraft_recipe_not_exist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandStop(CmdResult r)
|
||||||
|
{
|
||||||
|
StopCrafting();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoCraft_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Core part of auto-crafting
|
#region Core part of auto-crafting
|
||||||
|
|
@ -442,7 +462,7 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
ItemType ResultItem = recipeConfig.Result;
|
ItemType ResultItem = recipeConfig.Result;
|
||||||
|
|
||||||
ContainerType CraftingAreaType =
|
ContainerType CraftingAreaType =
|
||||||
(recipeConfig.Type == CraftTypeConfig.player) ? ContainerType.PlayerInventory : ContainerType.Crafting;
|
(recipeConfig.Type == CraftTypeConfig.player) ? ContainerType.PlayerInventory : ContainerType.Crafting;
|
||||||
|
|
||||||
PrepareCrafting(new Recipe(materials, ResultItem, CraftingAreaType));
|
PrepareCrafting(new Recipe(materials, ResultItem, CraftingAreaType));
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class AutoDig : ChatBot
|
public class AutoDig : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "autodig";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -60,7 +66,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
if (Auto_Start_Delay >= 0)
|
if (Auto_Start_Delay >= 0)
|
||||||
Auto_Start_Delay = Math.Max(0.1, Auto_Start_Delay);
|
Auto_Start_Delay = Math.Max(0.1, Auto_Start_Delay);
|
||||||
|
|
||||||
if (Dig_Timeout >= 0)
|
if (Dig_Timeout >= 0)
|
||||||
Dig_Timeout = Math.Max(0.1, Dig_Timeout);
|
Dig_Timeout = Math.Max(0.1, Dig_Timeout);
|
||||||
|
|
||||||
|
|
@ -117,32 +123,68 @@ namespace MinecraftClient.ChatBots
|
||||||
if (!inventoryEnabled && Config.Auto_Tool_Switch)
|
if (!inventoryEnabled && Config.Auto_Tool_Switch)
|
||||||
LogToConsole(Translations.bot_autodig_no_inv_handle);
|
LogToConsole(Translations.bot_autodig_no_inv_handle);
|
||||||
|
|
||||||
RegisterChatBotCommand("digbot", Translations.bot_autodig_cmd, GetHelp(), CommandHandler);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "start")))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "stop")))
|
||||||
|
.Then(l => l.Literal("help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "help")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var cmd = McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Executes(r => OnCommandStart(r.Source)))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandStop(r.Source)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal("digbot")
|
||||||
|
.Redirect(cmd)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CommandHandler(string cmd, string[] args)
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
if (args.Length > 0)
|
McClient.dispatcher.Unregister("digbot");
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
switch (args[0])
|
#pragma warning disable format // @formatter:off
|
||||||
{
|
"start" => Translations.bot_autodig_help_start,
|
||||||
case "start":
|
"stop" => Translations.bot_autodig_help_stop,
|
||||||
lock (stateLock)
|
"help" => Translations.bot_autodig_help_help,
|
||||||
{
|
_ => string.Format(Translations.bot_autodig_available_cmd, "start, stop, help")
|
||||||
counter = 0;
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
state = State.WaitingStart;
|
#pragma warning restore format // @formatter:on
|
||||||
}
|
});
|
||||||
return Translations.bot_autodig_start;
|
}
|
||||||
case "stop":
|
|
||||||
StopDigging();
|
private int OnCommandStart(CmdResult r)
|
||||||
return Translations.bot_autodig_stop;
|
{
|
||||||
case "help":
|
lock (stateLock)
|
||||||
return GetCommandHelp(args.Length >= 2 ? args[1] : "");
|
{
|
||||||
default:
|
counter = 0;
|
||||||
return GetHelp();
|
state = State.WaitingStart;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else return GetHelp();
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autodig_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandStop(CmdResult r)
|
||||||
|
{
|
||||||
|
StopDigging();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autodig_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartDigging()
|
private void StartDigging()
|
||||||
|
|
@ -240,7 +282,7 @@ namespace MinecraftClient.ChatBots
|
||||||
else if ((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) ||
|
else if ((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) ||
|
||||||
(Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type)))
|
(Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type)))
|
||||||
{
|
{
|
||||||
if (Config.Mode == Configs.ModeType.lookat ||
|
if (Config.Mode == Configs.ModeType.lookat ||
|
||||||
(Config.Mode == Configs.ModeType.both && Config._Locations.Contains(blockLoc)))
|
(Config.Mode == Configs.ModeType.both && Config._Locations.Contains(blockLoc)))
|
||||||
{
|
{
|
||||||
if (DigBlock(blockLoc, lookAtBlock: false))
|
if (DigBlock(blockLoc, lookAtBlock: false))
|
||||||
|
|
@ -288,8 +330,8 @@ namespace MinecraftClient.ChatBots
|
||||||
foreach (Location location in Config._Locations)
|
foreach (Location location in Config._Locations)
|
||||||
{
|
{
|
||||||
Block block = GetWorld().GetBlock(location);
|
Block block = GetWorld().GetBlock(location);
|
||||||
if (block.Type != Material.Air &&
|
if (block.Type != Material.Air &&
|
||||||
((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) ||
|
((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) ||
|
||||||
(Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type))))
|
(Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type))))
|
||||||
{
|
{
|
||||||
double distance = current.Distance(location);
|
double distance = current.Distance(location);
|
||||||
|
|
@ -401,23 +443,5 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
return base.OnDisconnect(reason, message);
|
return base.OnDisconnect(reason, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetHelp()
|
|
||||||
{
|
|
||||||
return string.Format(Translations.bot_autodig_available_cmd, "start, stop, help");
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCommandHelp(string cmd)
|
|
||||||
{
|
|
||||||
return cmd.ToLower() switch
|
|
||||||
{
|
|
||||||
#pragma warning disable format // @formatter:off
|
|
||||||
"start" => Translations.bot_autodig_help_start,
|
|
||||||
"stop" => Translations.bot_autodig_help_stop,
|
|
||||||
"help" => Translations.bot_autodig_help_help,
|
|
||||||
_ => GetHelp(),
|
|
||||||
#pragma warning restore format // @formatter:on
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
using static MinecraftClient.ChatBots.AutoDrop.Configs;
|
using static MinecraftClient.ChatBots.AutoDrop.Configs;
|
||||||
|
|
||||||
|
|
@ -9,6 +13,8 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class AutoDrop : ChatBot
|
public class AutoDrop : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "autodrop";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -38,110 +44,6 @@ namespace MinecraftClient.ChatBots
|
||||||
private readonly int updateDebounceValue = 2;
|
private readonly int updateDebounceValue = 2;
|
||||||
private int inventoryUpdated = -1;
|
private int inventoryUpdated = -1;
|
||||||
|
|
||||||
public string CommandHandler(string cmd, string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
switch (args[0].ToLower())
|
|
||||||
{
|
|
||||||
case "on":
|
|
||||||
Config.Enabled = true;
|
|
||||||
inventoryUpdated = 0;
|
|
||||||
OnUpdateFinish();
|
|
||||||
return Translations.bot_autoDrop_on;
|
|
||||||
case "off":
|
|
||||||
Config.Enabled = false;
|
|
||||||
return Translations.bot_autoDrop_off;
|
|
||||||
case "add":
|
|
||||||
if (args.Length >= 2)
|
|
||||||
{
|
|
||||||
if (Enum.TryParse(args[1], true, out ItemType item))
|
|
||||||
{
|
|
||||||
Config.Items.Add(item);
|
|
||||||
return string.Format(Translations.bot_autoDrop_added, item.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return string.Format(Translations.bot_autoDrop_incorrect_name, args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Translations.cmd_inventory_help_usage + ": add <item name>";
|
|
||||||
}
|
|
||||||
case "remove":
|
|
||||||
if (args.Length >= 2)
|
|
||||||
{
|
|
||||||
if (Enum.TryParse(args[1], true, out ItemType item))
|
|
||||||
{
|
|
||||||
if (Config.Items.Contains(item))
|
|
||||||
{
|
|
||||||
Config.Items.Remove(item);
|
|
||||||
return string.Format(Translations.bot_autoDrop_removed, item.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Translations.bot_autoDrop_not_in_list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return string.Format(Translations.bot_autoDrop_incorrect_name, args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Translations.cmd_inventory_help_usage + ": remove <item name>";
|
|
||||||
}
|
|
||||||
case "list":
|
|
||||||
if (Config.Items.Count > 0)
|
|
||||||
{
|
|
||||||
return string.Format(Translations.bot_autoDrop_list, Config.Items.Count, string.Join("\n", Config.Items));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Translations.bot_autoDrop_no_item;
|
|
||||||
}
|
|
||||||
case "mode":
|
|
||||||
if (args.Length >= 2)
|
|
||||||
{
|
|
||||||
switch (args[1].ToLower())
|
|
||||||
{
|
|
||||||
case "include":
|
|
||||||
Config.Mode = DropMode.include;
|
|
||||||
break;
|
|
||||||
case "exclude":
|
|
||||||
Config.Mode = DropMode.exclude;
|
|
||||||
break;
|
|
||||||
case "everything":
|
|
||||||
Config.Mode = DropMode.everything;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return Translations.bot_autoDrop_unknown_mode; // Unknwon mode. Available modes: Include, Exclude, Everything
|
|
||||||
}
|
|
||||||
inventoryUpdated = 0;
|
|
||||||
OnUpdateFinish();
|
|
||||||
return string.Format(Translations.bot_autoDrop_switched, Config.Mode.ToString()); // Switched to {0} mode.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Translations.bot_autoDrop_unknown_mode;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return GetHelp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetHelp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetHelp()
|
|
||||||
{
|
|
||||||
return string.Format(Translations.general_available_cmd, "on, off, add, remove, list, mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
if (!GetInventoryEnabled())
|
if (!GetInventoryEnabled())
|
||||||
|
|
@ -151,8 +53,114 @@ namespace MinecraftClient.ChatBots
|
||||||
UnloadBot();
|
UnloadBot();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RegisterChatBotCommand("autodrop", Translations.bot_autoDrop_cmd, GetHelp(), CommandHandler);
|
|
||||||
RegisterChatBotCommand("ad", Translations.bot_autoDrop_alias, GetHelp(), CommandHandler);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("add")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "add")))
|
||||||
|
.Then(l => l.Literal("remove")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "remove")))
|
||||||
|
.Then(l => l.Literal("mode")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "mode")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("on")
|
||||||
|
.Executes(r => OnCommandEnable(r.Source, true)))
|
||||||
|
.Then(l => l.Literal("off")
|
||||||
|
.Executes(r => OnCommandEnable(r.Source, false)))
|
||||||
|
.Then(l => l.Literal("add")
|
||||||
|
.Then(l => l.Argument("ItemType", MccArguments.ItemType())
|
||||||
|
.Executes(r => OnCommandAdd(r.Source, MccArguments.GetItemType(r, "ItemType")))))
|
||||||
|
.Then(l => l.Literal("remove")
|
||||||
|
.Then(l => l.Argument("ItemType", MccArguments.ItemType())
|
||||||
|
.Executes(r => OnCommandRemove(r.Source, MccArguments.GetItemType(r, "ItemType")))))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OnCommandList(r.Source)))
|
||||||
|
.Then(l => l.Literal("mode")
|
||||||
|
.Then(l => l.Literal("include")
|
||||||
|
.Executes(r => OnCommandMode(r.Source, DropMode.include)))
|
||||||
|
.Then(l => l.Literal("exclude")
|
||||||
|
.Executes(r => OnCommandMode(r.Source, DropMode.exclude)))
|
||||||
|
.Then(l => l.Literal("everything")
|
||||||
|
.Executes(r => OnCommandMode(r.Source, DropMode.everything))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUnload()
|
||||||
|
{
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
"add" => Translations.cmd_inventory_help_usage + ": add <item name>",
|
||||||
|
"remove" => Translations.cmd_inventory_help_usage + ": remove <item name>",
|
||||||
|
"mode" => Translations.bot_autoDrop_unknown_mode,
|
||||||
|
_ => string.Format(Translations.general_available_cmd, "on, off, add, remove, list, mode")
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandEnable(CmdResult r, bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
Config.Enabled = true;
|
||||||
|
inventoryUpdated = 0;
|
||||||
|
OnUpdateFinish();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoDrop_on);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Config.Enabled = false;
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoDrop_off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandAdd(CmdResult r, ItemType item)
|
||||||
|
{
|
||||||
|
Config.Items.Add(item);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_autoDrop_added, item.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandRemove(CmdResult r, ItemType item)
|
||||||
|
{
|
||||||
|
if (Config.Items.Contains(item))
|
||||||
|
{
|
||||||
|
Config.Items.Remove(item);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_autoDrop_removed, item.ToString()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_autoDrop_not_in_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandList(CmdResult r)
|
||||||
|
{
|
||||||
|
if (Config.Items.Count > 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_autoDrop_list, Config.Items.Count, string.Join("\n", Config.Items)));
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_autoDrop_no_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandMode(CmdResult r, DropMode mode)
|
||||||
|
{
|
||||||
|
Config.Mode = mode;
|
||||||
|
inventoryUpdated = 0;
|
||||||
|
OnUpdateFinish();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_autoDrop_switched, Config.Mode.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,12 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
using static MinecraftClient.ChatBots.AutoFishing.Configs;
|
using static MinecraftClient.ChatBots.AutoFishing.Configs;
|
||||||
|
|
||||||
|
|
@ -15,6 +19,8 @@ namespace MinecraftClient.ChatBots
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AutoFishing : ChatBot
|
public class AutoFishing : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "autofishing";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -176,80 +182,113 @@ namespace MinecraftClient.ChatBots
|
||||||
LogToConsole(Translations.extra_entity_required);
|
LogToConsole(Translations.extra_entity_required);
|
||||||
state = FishingState.WaitJoinGame;
|
state = FishingState.WaitJoinGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
inventoryEnabled = GetInventoryEnabled();
|
inventoryEnabled = GetInventoryEnabled();
|
||||||
if (!inventoryEnabled)
|
if (!inventoryEnabled)
|
||||||
LogToConsole(Translations.bot_autoFish_no_inv_handle);
|
LogToConsole(Translations.bot_autoFish_no_inv_handle);
|
||||||
|
|
||||||
RegisterChatBotCommand("fish", Translations.bot_autoFish_cmd, GetHelp(), CommandHandler);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "start")))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "stop")))
|
||||||
|
.Then(l => l.Literal("status")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "status")))
|
||||||
|
.Then(l => l.Literal("help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, "help")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Executes(r => OnCommandStart(r.Source)))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandStop(r.Source)))
|
||||||
|
.Then(l => l.Literal("status")
|
||||||
|
.Executes(r => OnCommandStatus(r.Source))
|
||||||
|
.Then(l => l.Literal("clear")
|
||||||
|
.Executes(r => OnCommandStatusClear(r.Source))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CommandHandler(string cmd, string[] args)
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
if (args.Length >= 1)
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
switch (args[0])
|
#pragma warning disable format // @formatter:off
|
||||||
{
|
"start" => Translations.bot_autoFish_help_start,
|
||||||
case "start":
|
"stop" => Translations.bot_autoFish_help_stop,
|
||||||
isFishing = false;
|
"status" => Translations.bot_autoFish_help_status,
|
||||||
lock (stateLock)
|
"help" => Translations.bot_autoFish_help_help,
|
||||||
{
|
_ => string.Format(Translations.bot_autoFish_available_cmd, "start, stop, status, help")
|
||||||
isFishing = false;
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
counter = 0;
|
#pragma warning restore format // @formatter:on
|
||||||
state = FishingState.StartMove;
|
});
|
||||||
}
|
}
|
||||||
return Translations.bot_autoFish_start;
|
|
||||||
case "stop":
|
|
||||||
isFishing = false;
|
|
||||||
lock (stateLock)
|
|
||||||
{
|
|
||||||
isFishing = false;
|
|
||||||
if (state == FishingState.WaitingFishToBite)
|
|
||||||
UseFishRod();
|
|
||||||
state = FishingState.Stopping;
|
|
||||||
}
|
|
||||||
StopFishing();
|
|
||||||
return Translations.bot_autoFish_stop;
|
|
||||||
case "status":
|
|
||||||
if (args.Length >= 2)
|
|
||||||
{
|
|
||||||
if (args[1] == "clear")
|
|
||||||
{
|
|
||||||
fishItemCnt = new();
|
|
||||||
return Translations.bot_autoFish_status_clear;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetCommandHelp("status");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fishItemCnt.Count == 0)
|
|
||||||
return Translations.bot_autoFish_status_info;
|
|
||||||
|
|
||||||
List<KeyValuePair<ItemType, uint>> orderedList = fishItemCnt.OrderBy(x => x.Value).ToList();
|
private int OnCommandStart(CmdResult r)
|
||||||
int maxLen = orderedList[^1].Value.ToString().Length;
|
{
|
||||||
StringBuilder sb = new();
|
isFishing = false;
|
||||||
sb.Append(Translations.bot_autoFish_status_info);
|
lock (stateLock)
|
||||||
foreach ((ItemType type, uint cnt) in orderedList)
|
{
|
||||||
{
|
isFishing = false;
|
||||||
sb.Append(Environment.NewLine);
|
counter = 0;
|
||||||
|
state = FishingState.StartMove;
|
||||||
string cntStr = cnt.ToString();
|
|
||||||
sb.Append(' ', maxLen - cntStr.Length).Append(cntStr);
|
|
||||||
sb.Append(" x ");
|
|
||||||
sb.Append(Item.GetTypeString(type));
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
case "help":
|
|
||||||
return GetCommandHelp(args.Length >= 2 ? args[1] : "");
|
|
||||||
default:
|
|
||||||
return GetHelp();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoFish_start);
|
||||||
return GetHelp();
|
}
|
||||||
|
|
||||||
|
private int OnCommandStop(CmdResult r)
|
||||||
|
{
|
||||||
|
isFishing = false;
|
||||||
|
lock (stateLock)
|
||||||
|
{
|
||||||
|
isFishing = false;
|
||||||
|
if (state == FishingState.WaitingFishToBite)
|
||||||
|
UseFishRod();
|
||||||
|
state = FishingState.Stopping;
|
||||||
|
}
|
||||||
|
StopFishing();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoFish_stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandStatus(CmdResult r)
|
||||||
|
{
|
||||||
|
if (fishItemCnt.Count == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoFish_status_info);
|
||||||
|
|
||||||
|
List<KeyValuePair<ItemType, uint>> orderedList = fishItemCnt.OrderBy(x => x.Value).ToList();
|
||||||
|
int maxLen = orderedList[^1].Value.ToString().Length;
|
||||||
|
StringBuilder sb = new();
|
||||||
|
sb.Append(Translations.bot_autoFish_status_info);
|
||||||
|
foreach ((ItemType type, uint cnt) in orderedList)
|
||||||
|
{
|
||||||
|
sb.Append(Environment.NewLine);
|
||||||
|
|
||||||
|
string cntStr = cnt.ToString();
|
||||||
|
sb.Append(' ', maxLen - cntStr.Length).Append(cntStr);
|
||||||
|
sb.Append(" x ");
|
||||||
|
sb.Append(Item.GetTypeString(type));
|
||||||
|
}
|
||||||
|
LogToConsole(sb.ToString());
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandStatusClear(CmdResult r)
|
||||||
|
{
|
||||||
|
fishItemCnt = new();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_autoFish_status_clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartFishing()
|
private void StartFishing()
|
||||||
|
|
@ -386,7 +425,7 @@ namespace MinecraftClient.ChatBots
|
||||||
public override void OnEntitySpawn(Entity entity)
|
public override void OnEntitySpawn(Entity entity)
|
||||||
{
|
{
|
||||||
if (fishItemCounter < 15 && entity.Type == EntityType.Item && Math.Abs(entity.Location.Y - LastPos.Y) < 2.2 &&
|
if (fishItemCounter < 15 && entity.Type == EntityType.Item && Math.Abs(entity.Location.Y - LastPos.Y) < 2.2 &&
|
||||||
Math.Abs(entity.Location.X - LastPos.X) < 0.12 && Math.Abs(entity.Location.Z - LastPos.Z) < 0.12)
|
Math.Abs(entity.Location.X - LastPos.X) < 0.12 && Math.Abs(entity.Location.Z - LastPos.Z) < 0.12)
|
||||||
{
|
{
|
||||||
if (Config.Log_Fish_Bobber)
|
if (Config.Log_Fish_Bobber)
|
||||||
LogToConsole(string.Format("Item ({0}) spawn at {1}, distance = {2:0.00}", entity.ID, entity.Location, entity.Location.Distance(LastPos)));
|
LogToConsole(string.Format("Item ({0}) spawn at {1}, distance = {2:0.00}", entity.ID, entity.Location, entity.Location.Distance(LastPos)));
|
||||||
|
|
@ -440,7 +479,7 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
public override void OnEntityMove(Entity entity)
|
public override void OnEntityMove(Entity entity)
|
||||||
{
|
{
|
||||||
if (isFishing && entity != null && fishingBobber!.ID == entity.ID &&
|
if (isFishing && entity != null && fishingBobber!.ID == entity.ID &&
|
||||||
(state == FishingState.WaitingFishToBite || state == FishingState.WaitingFishingBobber))
|
(state == FishingState.WaitingFishToBite || state == FishingState.WaitingFishingBobber))
|
||||||
{
|
{
|
||||||
Location Pos = entity.Location;
|
Location Pos = entity.Location;
|
||||||
|
|
@ -620,24 +659,5 @@ namespace MinecraftClient.ChatBots
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetHelp()
|
|
||||||
{
|
|
||||||
return string.Format(Translations.bot_autoFish_available_cmd, "start, stop, status, help");
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCommandHelp(string cmd)
|
|
||||||
{
|
|
||||||
return cmd.ToLower() switch
|
|
||||||
{
|
|
||||||
#pragma warning disable format // @formatter:off
|
|
||||||
"start" => Translations.bot_autoFish_help_start,
|
|
||||||
"stop" => Translations.bot_autoFish_help_stop,
|
|
||||||
"status" => Translations.bot_autoFish_help_status,
|
|
||||||
"help" => Translations.bot_autoFish_help_help,
|
|
||||||
_ => GetHelp(),
|
|
||||||
#pragma warning restore format // @formatter:on
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
@ -43,7 +44,7 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
if (Delay.min > Delay.max)
|
if (Delay.min > Delay.max)
|
||||||
(Delay.min, Delay.max) = (Delay.max, Delay.min);
|
(Delay.min, Delay.max) = (Delay.max, Delay.min);
|
||||||
|
|
||||||
if (Retries == -1)
|
if (Retries == -1)
|
||||||
Retries = int.MaxValue;
|
Retries = int.MaxValue;
|
||||||
|
|
||||||
|
|
@ -83,6 +84,11 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
_Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _Initialize()
|
||||||
{
|
{
|
||||||
McClient.ReconnectionAttemptsLeft = Config.Retries;
|
McClient.ReconnectionAttemptsLeft = Config.Retries;
|
||||||
if (Config.Ignore_Kick_Message)
|
if (Config.Ignore_Kick_Message)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
using static MinecraftClient.Settings;
|
using static MinecraftClient.Settings;
|
||||||
|
|
||||||
|
|
@ -304,12 +306,12 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
Dictionary<string, object> localVars = new();
|
Dictionary<string, object> localVars = new();
|
||||||
string? toPerform = rule.Match(sender, message, msgType, localVars);
|
string? toPerform = rule.Match(sender, message, msgType, localVars);
|
||||||
if (!String.IsNullOrEmpty(toPerform))
|
if (!string.IsNullOrEmpty(toPerform))
|
||||||
{
|
{
|
||||||
string? response = null;
|
CmdResult response = new();
|
||||||
LogToConsole(string.Format(Translations.bot_autoRespond_match_run, toPerform));
|
LogToConsole(string.Format(Translations.bot_autoRespond_match_run, toPerform));
|
||||||
PerformInternalCommand(toPerform, ref response, localVars);
|
PerformInternalCommand(toPerform, ref response, localVars);
|
||||||
if (!String.IsNullOrEmpty(response))
|
if (response.status != CmdResult.Status.Done || !string.IsNullOrWhiteSpace(response.result))
|
||||||
LogToConsole(response);
|
LogToConsole(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
@ -115,7 +117,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnInternalCommand(string commandName, string commandParams, string result)
|
public override void OnInternalCommand(string commandName, string commandParams, CmdResult result)
|
||||||
{
|
{
|
||||||
if (saveInternal)
|
if (saveInternal)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,22 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
using DSharpPlus;
|
using DSharpPlus;
|
||||||
using DSharpPlus.Entities;
|
using DSharpPlus.Entities;
|
||||||
using DSharpPlus.Exceptions;
|
using DSharpPlus.Exceptions;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class DiscordBridge : ChatBot
|
public class DiscordBridge : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "dscbridge";
|
||||||
|
|
||||||
private enum BridgeDirection
|
private enum BridgeDirection
|
||||||
{
|
{
|
||||||
Both = 0,
|
Both = 0,
|
||||||
|
|
@ -70,17 +76,74 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
RegisterChatBotCommand("dscbridge", "bot.DiscordBridge.desc", "dscbridge direction <both|mc|discord>", OnDscCommand);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("direction")
|
||||||
|
.Then(l => l.Literal("both")
|
||||||
|
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Both)))
|
||||||
|
.Then(l => l.Literal("mc")
|
||||||
|
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Minecraft)))
|
||||||
|
.Then(l => l.Literal("discord")
|
||||||
|
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Discord)))
|
||||||
|
)
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
|
|
||||||
Task.Run(async () => await MainAsync());
|
Task.Run(async () => await MainAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
~DiscordBridge()
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnUnload()
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => "dscbridge direction <both|mc|discord>"
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandDirection(CmdResult r, BridgeDirection direction)
|
||||||
|
{
|
||||||
|
string bridgeName;
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case BridgeDirection.Both:
|
||||||
|
bridgeName = Translations.bot_DiscordBridge_direction_both;
|
||||||
|
bridgeDirection = BridgeDirection.Both;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BridgeDirection.Minecraft:
|
||||||
|
bridgeName = Translations.bot_DiscordBridge_direction_minecraft;
|
||||||
|
bridgeDirection = BridgeDirection.Minecraft;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BridgeDirection.Discord:
|
||||||
|
bridgeName = Translations.bot_DiscordBridge_direction_discord;
|
||||||
|
bridgeDirection = BridgeDirection.Discord;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto case BridgeDirection.Both;
|
||||||
|
}
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_DiscordBridge_direction, bridgeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
~DiscordBridge()
|
||||||
{
|
{
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +163,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,47 +177,6 @@ namespace MinecraftClient.ChatBots
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string OnDscCommand(string cmd, string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length == 2)
|
|
||||||
{
|
|
||||||
if (args[0].ToLower().Equals("direction"))
|
|
||||||
{
|
|
||||||
string direction = args[1].ToLower().Trim();
|
|
||||||
|
|
||||||
string bridgeName;
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case "b":
|
|
||||||
case "both":
|
|
||||||
bridgeName = Translations.bot_DiscordBridge_direction_both;
|
|
||||||
bridgeDirection = BridgeDirection.Both;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "mc":
|
|
||||||
case "minecraft":
|
|
||||||
bridgeName = Translations.bot_DiscordBridge_direction_minecraft;
|
|
||||||
bridgeDirection = BridgeDirection.Minecraft;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "d":
|
|
||||||
case "dcs":
|
|
||||||
case "discord":
|
|
||||||
bridgeName = Translations.bot_DiscordBridge_direction_discord;
|
|
||||||
bridgeDirection = BridgeDirection.Discord;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return Translations.bot_DiscordBridge_invalid_direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Format(Translations.bot_DiscordBridge_direction, bridgeName);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return "dscbridge direction <both|mc|discord>";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetText(string text)
|
public override void GetText(string text)
|
||||||
{
|
{
|
||||||
if (!CanSendMessages())
|
if (!CanSendMessages())
|
||||||
|
|
@ -211,7 +233,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -227,7 +249,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -243,7 +265,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +291,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_DiscordBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -369,9 +391,8 @@ namespace MinecraftClient.ChatBots
|
||||||
message = message[1..];
|
message = message[1..];
|
||||||
await e.Message.CreateReactionAsync(DiscordEmoji.FromName(discordBotClient, ":gear:"));
|
await e.Message.CreateReactionAsync(DiscordEmoji.FromName(discordBotClient, ":gear:"));
|
||||||
|
|
||||||
string? result = "";
|
CmdResult result = new();
|
||||||
PerformInternalCommand(message, ref result);
|
PerformInternalCommand(message, ref result);
|
||||||
result = string.IsNullOrEmpty(result) ? "-" : result;
|
|
||||||
|
|
||||||
await e.Message.DeleteOwnReactionAsync(DiscordEmoji.FromName(discordBotClient, ":gear:"));
|
await e.Message.DeleteOwnReactionAsync(DiscordEmoji.FromName(discordBotClient, ":gear:"));
|
||||||
await e.Message.CreateReactionAsync(DiscordEmoji.FromName(discordBotClient, ":white_check_mark:"));
|
await e.Message.CreateReactionAsync(DiscordEmoji.FromName(discordBotClient, ":white_check_mark:"));
|
||||||
|
|
@ -399,12 +420,12 @@ namespace MinecraftClient.ChatBots
|
||||||
});
|
});
|
||||||
|
|
||||||
IsConnected = true;
|
IsConnected = true;
|
||||||
LogToConsole("§y§l§f" + Translations.bot_DiscordBridge_connected);
|
LogToConsole("§§2§l§f" + Translations.bot_DiscordBridge_connected);
|
||||||
await Task.Delay(-1);
|
await Task.Delay(-1);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_DiscordBridge_unknown_error);
|
LogToConsole("§§4§l§f" + Translations.bot_DiscordBridge_unknown_error);
|
||||||
LogToConsole(e);
|
LogToConsole(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,34 +3,22 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
using MinecraftClient.Protocol.Handlers;
|
using MinecraftClient.Protocol.Handlers;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
enum State
|
|
||||||
{
|
|
||||||
SearchingForCropsToBreak = 0,
|
|
||||||
SearchingForFarmlandToPlant,
|
|
||||||
PlantingCrops,
|
|
||||||
BonemealingCrops
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CropType
|
|
||||||
{
|
|
||||||
Beetroot,
|
|
||||||
Carrot,
|
|
||||||
Melon,
|
|
||||||
Netherwart,
|
|
||||||
Pumpkin,
|
|
||||||
Potato,
|
|
||||||
Wheat
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Farmer : ChatBot
|
public class Farmer : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "farmer";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -42,15 +30,34 @@ namespace MinecraftClient.ChatBots
|
||||||
public bool Enabled = false;
|
public bool Enabled = false;
|
||||||
|
|
||||||
[TomlInlineComment("$ChatBot.Farmer.Delay_Between_Tasks$")]
|
[TomlInlineComment("$ChatBot.Farmer.Delay_Between_Tasks$")]
|
||||||
public int Delay_Between_Tasks = 1;
|
public double Delay_Between_Tasks = 1.0;
|
||||||
|
|
||||||
public void OnSettingUpdate()
|
public void OnSettingUpdate()
|
||||||
{
|
{
|
||||||
if (Delay_Between_Tasks <= 0)
|
if (Delay_Between_Tasks < 1.0)
|
||||||
Delay_Between_Tasks = 1;
|
Delay_Between_Tasks = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum State
|
||||||
|
{
|
||||||
|
SearchingForCropsToBreak = 0,
|
||||||
|
SearchingForFarmlandToPlant,
|
||||||
|
PlantingCrops,
|
||||||
|
BonemealingCrops
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CropType
|
||||||
|
{
|
||||||
|
Beetroot,
|
||||||
|
Carrot,
|
||||||
|
Melon,
|
||||||
|
Netherwart,
|
||||||
|
Pumpkin,
|
||||||
|
Potato,
|
||||||
|
Wheat
|
||||||
|
}
|
||||||
|
|
||||||
private State state = State.SearchingForCropsToBreak;
|
private State state = State.SearchingForCropsToBreak;
|
||||||
private CropType cropType = CropType.Wheat;
|
private CropType cropType = CropType.Wheat;
|
||||||
private int farmingRadius = 30;
|
private int farmingRadius = 30;
|
||||||
|
|
@ -59,6 +66,8 @@ namespace MinecraftClient.ChatBots
|
||||||
private bool allowTeleport = false;
|
private bool allowTeleport = false;
|
||||||
private bool debugEnabled = false;
|
private bool debugEnabled = false;
|
||||||
|
|
||||||
|
public int Delay_Between_Tasks_Millisecond => (int)Math.Round(Config.Delay_Between_Tasks * 1000);
|
||||||
|
|
||||||
private const string commandDescription = "farmer <start <crop type> [radius:<radius = 30>] [unsafe:<true/false>] [teleport:<true/false>] [debug:<true/false>]|stop>";
|
private const string commandDescription = "farmer <start <crop type> [radius:<radius = 30>] [unsafe:<true/false>] [teleport:<true/false>] [debug:<true/false>]|stop>";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
|
|
@ -81,130 +90,153 @@ namespace MinecraftClient.ChatBots
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterChatBotCommand("farmer", "bot.farmer.desc", commandDescription, OnFarmCommand);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandStop(r.Source)))
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Then(l => l.Argument("CropType", MccArguments.FarmerCropType())
|
||||||
|
.Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"), null))
|
||||||
|
.Then(l => l.Argument("OtherArgs", Arguments.GreedyString())
|
||||||
|
.Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"), Arguments.GetString(r, "OtherArgs"))))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string OnFarmCommand(string cmd, string[] args)
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
if (args.Length > 0)
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
if (args[0].Equals("stop", StringComparison.OrdinalIgnoreCase))
|
#pragma warning disable format // @formatter:off
|
||||||
{
|
_ => Translations.bot_farmer_desc + ": " + commandDescription
|
||||||
if (!running)
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
return Translations.bot_farmer_already_stopped;
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
running = false;
|
private int OnCommandStop(CmdResult r)
|
||||||
return Translations.bot_farmer_stopping;
|
{
|
||||||
}
|
if (!running)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_farmer_already_stopped);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_farmer_stopping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args[0].Equals("start", StringComparison.OrdinalIgnoreCase))
|
private int OnCommandStart(CmdResult r, CropType whatToFarm, string? otherArgs)
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_farmer_already_running);
|
||||||
|
|
||||||
|
int radius = 30;
|
||||||
|
|
||||||
|
state = State.SearchingForFarmlandToPlant;
|
||||||
|
cropType = whatToFarm;
|
||||||
|
allowUnsafe = false;
|
||||||
|
allowTeleport = false;
|
||||||
|
debugEnabled = false;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(otherArgs))
|
||||||
|
{
|
||||||
|
string[] args = otherArgs.ToLower().Split(' ', StringSplitOptions.TrimEntries);
|
||||||
|
foreach (string currentArg in args)
|
||||||
{
|
{
|
||||||
if (args.Length >= 2)
|
if (!currentArg.Contains(':'))
|
||||||
{
|
{
|
||||||
if (running)
|
LogToConsole("§§6§1§0" + string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg));
|
||||||
return Translations.bot_farmer_already_running;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Enum.TryParse(args[1], true, out CropType whatToFarm))
|
string[] parts = currentArg.Split(":", StringSplitOptions.TrimEntries);
|
||||||
return Translations.bot_farmer_invalid_crop_type;
|
|
||||||
|
|
||||||
int radius = 30;
|
if (parts.Length != 2)
|
||||||
|
{
|
||||||
|
LogToConsole("§§6§1§0" + string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
state = State.SearchingForFarmlandToPlant;
|
switch (parts[0])
|
||||||
cropType = whatToFarm;
|
{
|
||||||
allowUnsafe = false;
|
case "r":
|
||||||
allowTeleport = false;
|
case "radius":
|
||||||
debugEnabled = false;
|
if (!int.TryParse(parts[1], NumberStyles.Any, CultureInfo.CurrentCulture, out radius))
|
||||||
|
LogToConsole("§§6§1§0" + Translations.bot_farmer_invalid_radius);
|
||||||
|
|
||||||
if (args.Length >= 3)
|
if (radius <= 0)
|
||||||
{
|
|
||||||
for (int i = 2; i < args.Length; i++)
|
|
||||||
{
|
{
|
||||||
string currentArg = args[i].Trim().ToLower();
|
LogToConsole("§§6§1§0" + Translations.bot_farmer_invalid_radius);
|
||||||
|
radius = 30;
|
||||||
if (!currentArg.Contains(':'))
|
|
||||||
{
|
|
||||||
LogToConsole("§x§1§0" + string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] parts = currentArg.Split(":", StringSplitOptions.TrimEntries);
|
|
||||||
|
|
||||||
if (parts.Length != 2)
|
|
||||||
{
|
|
||||||
LogToConsole("§x§1§0" + string.Format(Translations.bot_farmer_warining_invalid_parameter, currentArg));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (parts[0])
|
|
||||||
{
|
|
||||||
case "r":
|
|
||||||
case "radius":
|
|
||||||
if (!int.TryParse(parts[1], NumberStyles.Any, CultureInfo.CurrentCulture, out radius))
|
|
||||||
LogToConsole("§x§1§0" + Translations.bot_farmer_invalid_radius);
|
|
||||||
|
|
||||||
if (radius <= 0)
|
|
||||||
{
|
|
||||||
LogToConsole("§x§1§0" + Translations.bot_farmer_invalid_radius);
|
|
||||||
radius = 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "f":
|
|
||||||
case "unsafe":
|
|
||||||
if (allowUnsafe)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
|
||||||
{
|
|
||||||
LogToConsole("§x§1§0" + Translations.bot_farmer_warining_force_unsafe);
|
|
||||||
allowUnsafe = true;
|
|
||||||
}
|
|
||||||
else allowUnsafe = false;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "t":
|
|
||||||
case "teleport":
|
|
||||||
if (allowTeleport)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
|
||||||
{
|
|
||||||
LogToConsole("§w§1§f" + Translations.bot_farmer_warining_allow_teleport);
|
|
||||||
allowTeleport = true;
|
|
||||||
}
|
|
||||||
else allowTeleport = false;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "d":
|
|
||||||
case "debug":
|
|
||||||
if (debugEnabled)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
|
||||||
{
|
|
||||||
LogToConsole("Debug enabled!");
|
|
||||||
debugEnabled = true;
|
|
||||||
}
|
|
||||||
else debugEnabled = false;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
farmingRadius = radius;
|
break;
|
||||||
running = true;
|
|
||||||
new Thread(() => MainPorcess()).Start();
|
|
||||||
|
|
||||||
return "";
|
case "f":
|
||||||
|
case "unsafe":
|
||||||
|
if (allowUnsafe)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
||||||
|
{
|
||||||
|
LogToConsole("§§6§1§0" + Translations.bot_farmer_warining_force_unsafe);
|
||||||
|
allowUnsafe = true;
|
||||||
|
}
|
||||||
|
else allowUnsafe = false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "t":
|
||||||
|
case "teleport":
|
||||||
|
if (allowTeleport)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
||||||
|
{
|
||||||
|
LogToConsole("§§4§1§f" + Translations.bot_farmer_warining_allow_teleport);
|
||||||
|
allowTeleport = true;
|
||||||
|
}
|
||||||
|
else allowTeleport = false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "d":
|
||||||
|
case "debug":
|
||||||
|
if (debugEnabled)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (parts[1].Equals("true") || parts[1].Equals("1"))
|
||||||
|
{
|
||||||
|
LogToConsole("Debug enabled!");
|
||||||
|
debugEnabled = true;
|
||||||
|
}
|
||||||
|
else debugEnabled = false;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Translations.bot_farmer_desc + ": " + commandDescription;
|
farmingRadius = radius;
|
||||||
|
running = true;
|
||||||
|
new Thread(() => MainPorcess()).Start();
|
||||||
|
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterGameJoined()
|
public override void AfterGameJoined()
|
||||||
|
|
@ -220,9 +252,9 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
private void MainPorcess()
|
private void MainPorcess()
|
||||||
{
|
{
|
||||||
LogToConsole("§y§1§f" + Translations.bot_farmer_started);
|
LogToConsole("§§2§1§f" + Translations.bot_farmer_started);
|
||||||
LogToConsole("§y§1§f " + Translations.bot_farmer_crop_type + ": " + cropType);
|
LogToConsole("§§2§1§f " + Translations.bot_farmer_crop_type + ": " + cropType);
|
||||||
LogToConsole("§y§1§f " + Translations.bot_farmer_radius + ": " + farmingRadius);
|
LogToConsole("§§2§1§f " + Translations.bot_farmer_radius + ": " + farmingRadius);
|
||||||
|
|
||||||
while (running)
|
while (running)
|
||||||
{
|
{
|
||||||
|
|
@ -230,7 +262,7 @@ namespace MinecraftClient.ChatBots
|
||||||
if (AutoEat.Eating)
|
if (AutoEat.Eating)
|
||||||
{
|
{
|
||||||
LogDebug("Eating...");
|
LogDebug("Eating...");
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,7 +278,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebug("No seeds, trying to find some crops to break");
|
LogDebug("No seeds, trying to find some crops to break");
|
||||||
state = State.SearchingForCropsToBreak;
|
state = State.SearchingForCropsToBreak;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,7 +288,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebug("Could not find any farmland, trying to find some crops to break");
|
LogDebug("Could not find any farmland, trying to find some crops to break");
|
||||||
state = State.SearchingForCropsToBreak;
|
state = State.SearchingForCropsToBreak;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,7 +304,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebug("Ran out of seeds, looking for crops to break...");
|
LogDebug("Ran out of seeds, looking for crops to break...");
|
||||||
state = State.SearchingForCropsToBreak;
|
state = State.SearchingForCropsToBreak;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +353,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogToConsole("No crops to break, trying to bonemeal ungrown ones");
|
LogToConsole("No crops to break, trying to bonemeal ungrown ones");
|
||||||
state = State.BonemealingCrops;
|
state = State.BonemealingCrops;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,7 +399,7 @@ namespace MinecraftClient.ChatBots
|
||||||
if (cropType == CropType.Netherwart)
|
if (cropType == CropType.Netherwart)
|
||||||
{
|
{
|
||||||
state = State.SearchingForFarmlandToPlant;
|
state = State.SearchingForFarmlandToPlant;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,7 +408,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebug("No bonemeal, searching for some farmland to plant seeds on");
|
LogDebug("No bonemeal, searching for some farmland to plant seeds on");
|
||||||
state = State.SearchingForFarmlandToPlant;
|
state = State.SearchingForFarmlandToPlant;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,7 +418,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebug("No crops to bonemeal, searching for farmland to plant seeds on");
|
LogDebug("No crops to bonemeal, searching for farmland to plant seeds on");
|
||||||
state = State.SearchingForFarmlandToPlant;
|
state = State.SearchingForFarmlandToPlant;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -402,7 +434,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
LogDebug("Ran out of Bone Meal, looking for farmland to plant on...");
|
LogDebug("Ran out of Bone Meal, looking for farmland to plant on...");
|
||||||
state = State.SearchingForFarmlandToPlant;
|
state = State.SearchingForFarmlandToPlant;
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -438,8 +470,8 @@ namespace MinecraftClient.ChatBots
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogDebug("Waiting for " + Config.Delay_Between_Tasks + " seconds for next cycle.");
|
LogDebug(string.Format("Waiting for {0:0.00} seconds for next cycle.", Config.Delay_Between_Tasks));
|
||||||
Thread.Sleep(Config.Delay_Between_Tasks * 1000);
|
Thread.Sleep(Delay_Between_Tasks_Millisecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogToConsole(Translations.bot_farmer_stopped);
|
LogToConsole(Translations.bot_farmer_stopped);
|
||||||
|
|
@ -815,6 +847,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
return GetPlayerInventory().SearchItem(itemType).Length > 0;
|
return GetPlayerInventory().SearchItem(itemType).Length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogDebug(object text)
|
private void LogDebug(object text)
|
||||||
{
|
{
|
||||||
if (debugEnabled)
|
if (debugEnabled)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,19 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class FollowPlayer : ChatBot
|
public class FollowPlayer : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "follow";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -55,58 +62,86 @@ namespace MinecraftClient.ChatBots
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterChatBotCommand("follow", "cmd.follow.desc", "follow <player name|stop>", OnFollowCommand);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("start")
|
||||||
|
.Then(l => l.Argument("PlayerName", MccArguments.PlayerName())
|
||||||
|
.Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: true)))))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandStop(r.Source)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string OnFollowCommand(string cmd, string[] args)
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
if (args.Length > 0)
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
if (args[0].Equals("stop", StringComparison.OrdinalIgnoreCase))
|
#pragma warning disable format // @formatter:off
|
||||||
{
|
_ => Translations.cmd_follow_desc + ": " + Translations.cmd_follow_usage
|
||||||
if (_playerToFollow == null)
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
return Translations.cmd_follow_already_stopped;
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_playerToFollow = null;
|
private int OnCommandStart(CmdResult r, string name, bool takeRisk)
|
||||||
return Translations.cmd_follow_stopping;
|
{
|
||||||
}
|
if (!IsValidName(name))
|
||||||
else
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_invalid_name);
|
||||||
{
|
|
||||||
if (!IsValidName(args[0]))
|
|
||||||
return Translations.cmd_follow_invalid_name;
|
|
||||||
|
|
||||||
Entity? player = GetEntities().Values.ToList().Find(entity =>
|
Entity? player = GetEntities().Values.ToList().Find(entity =>
|
||||||
entity.Type == EntityType.Player && !string.IsNullOrEmpty(entity.Name) && entity.Name.Equals(args[0], StringComparison.OrdinalIgnoreCase));
|
entity.Type == EntityType.Player
|
||||||
|
&& !string.IsNullOrEmpty(entity.Name)
|
||||||
|
&& entity.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
if (player == null)
|
if (player == null)
|
||||||
return Translations.cmd_follow_invalid_player;
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_invalid_player);
|
||||||
|
|
||||||
if (!CanMoveThere(player.Location))
|
if (!CanMoveThere(player.Location))
|
||||||
return Translations.cmd_follow_cant_reach_player;
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_cant_reach_player);
|
||||||
|
|
||||||
if (_playerToFollow != null && _playerToFollow.Equals(args[0], StringComparison.OrdinalIgnoreCase))
|
if (_playerToFollow != null && _playerToFollow.Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||||
return string.Format(Translations.cmd_follow_already_following, _playerToFollow);
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_follow_already_following, _playerToFollow));
|
||||||
|
|
||||||
string result;
|
string result;
|
||||||
if (_playerToFollow != null)
|
if (_playerToFollow != null)
|
||||||
result = string.Format(Translations.cmd_follow_switched, player.Name!);
|
result = string.Format(Translations.cmd_follow_switched, player.Name!);
|
||||||
else
|
else
|
||||||
result = string.Format(Translations.cmd_follow_started, player.Name!);
|
result = string.Format(Translations.cmd_follow_started, player.Name!);
|
||||||
_playerToFollow = args[0].Trim().ToLower();
|
_playerToFollow = name.ToLower();
|
||||||
|
|
||||||
LogToConsole(Translations.cmd_follow_note);
|
if (takeRisk)
|
||||||
|
{
|
||||||
if (args.Length == 2 && args[1].Equals("-f", StringComparison.OrdinalIgnoreCase))
|
_unsafeEnabled = true;
|
||||||
{
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_note + '\n' + Translations.cmd_follow_unsafe_enabled);
|
||||||
_unsafeEnabled = true;
|
|
||||||
LogToConsole(Translations.cmd_follow_unsafe_enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_note);
|
||||||
|
}
|
||||||
|
|
||||||
return Translations.cmd_follow_desc + ": " + Translations.cmd_follow_usage;
|
private int OnCommandStop(CmdResult r)
|
||||||
|
{
|
||||||
|
if (_playerToFollow == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_follow_already_stopped);
|
||||||
|
|
||||||
|
_playerToFollow = null;
|
||||||
|
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_follow_stopping);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,11 @@ using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
@ -12,6 +17,8 @@ namespace MinecraftClient.ChatBots
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Mailer : ChatBot
|
public class Mailer : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "mailer";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -251,7 +258,101 @@ namespace MinecraftClient.ChatBots
|
||||||
mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.DatabaseFile)!, Path.GetFileName(Config.DatabaseFile), FileMonitorCallback);
|
mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.DatabaseFile)!, Path.GetFileName(Config.DatabaseFile), FileMonitorCallback);
|
||||||
ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.IgnoreListFile)!, Path.GetFileName(Config.IgnoreListFile), FileMonitorCallback);
|
ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.IgnoreListFile)!, Path.GetFileName(Config.IgnoreListFile), FileMonitorCallback);
|
||||||
|
|
||||||
RegisterChatBotCommand("mailer", Translations.bot_mailer_cmd, "mailer <getmails|addignored|getignored|removeignored>", ProcessInternalCommand);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty)))
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("getmails")
|
||||||
|
.Executes(r => OnCommandGetMails()))
|
||||||
|
.Then(l => l.Literal("getignored")
|
||||||
|
.Executes(r => OnCommandGetIgnored()))
|
||||||
|
.Then(l => l.Literal("addignored")
|
||||||
|
.Then(l => l.Argument("username", Arguments.String())
|
||||||
|
.Executes(r => OnCommandAddIgnored(Arguments.GetString(r, "username")))))
|
||||||
|
.Then(l => l.Literal("removeignored")
|
||||||
|
.Then(l => l.Argument("username", Arguments.String())
|
||||||
|
.Executes(r => OnCommandRemoveIgnored(Arguments.GetString(r, "username")))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUnload()
|
||||||
|
{
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => Translations.bot_mailer_cmd_help + ": /mailer <getmails|addignored|getignored|removeignored>"
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandGetMails()
|
||||||
|
{
|
||||||
|
LogToConsole(string.Format(Translations.bot_mailer_cmd_getmails, string.Join("\n", mailDatabase)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandGetIgnored()
|
||||||
|
{
|
||||||
|
LogToConsole(string.Format(Translations.bot_mailer_cmd_getignored, string.Join("\n", ignoreList)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandAddIgnored(string username)
|
||||||
|
{
|
||||||
|
if (IsValidName(username))
|
||||||
|
{
|
||||||
|
username = username.ToLower();
|
||||||
|
lock (readWriteLock)
|
||||||
|
{
|
||||||
|
if (!ignoreList.Contains(username))
|
||||||
|
{
|
||||||
|
ignoreList.Add(username);
|
||||||
|
ignoreList.SaveToFile(Config.IgnoreListFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogToConsole(string.Format(Translations.bot_mailer_cmd_ignore_added, username));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogToConsole(string.Format(Translations.bot_mailer_cmd_ignore_invalid, "addignored"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandRemoveIgnored(string username)
|
||||||
|
{
|
||||||
|
if (IsValidName(username))
|
||||||
|
{
|
||||||
|
username = username.ToLower();
|
||||||
|
lock (readWriteLock)
|
||||||
|
{
|
||||||
|
if (ignoreList.Contains(username))
|
||||||
|
{
|
||||||
|
ignoreList.Remove(username);
|
||||||
|
ignoreList.SaveToFile(Config.IgnoreListFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogToConsole(string.Format(Translations.bot_mailer_cmd_ignore_removed, username));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogToConsole(string.Format(Translations.bot_mailer_cmd_ignore_invalid, "removeignored"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -365,57 +466,5 @@ namespace MinecraftClient.ChatBots
|
||||||
ignoreList = IgnoreList.FromFile(Config.IgnoreListFile);
|
ignoreList = IgnoreList.FromFile(Config.IgnoreListFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interprets local commands.
|
|
||||||
/// </summary>
|
|
||||||
private string ProcessInternalCommand(string cmd, string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
string commandName = args[0].ToLower();
|
|
||||||
switch (commandName)
|
|
||||||
{
|
|
||||||
case "getmails": // Sorry, I (ReinforceZwei) replaced "=" to "-" because it would affect the parsing of translation file (key=value)
|
|
||||||
return string.Format(Translations.bot_mailer_cmd_getmails, string.Join("\n", mailDatabase));
|
|
||||||
|
|
||||||
case "getignored":
|
|
||||||
return string.Format(Translations.bot_mailer_cmd_getignored, string.Join("\n", ignoreList));
|
|
||||||
|
|
||||||
case "addignored":
|
|
||||||
case "removeignored":
|
|
||||||
if (args.Length > 1 && IsValidName(args[1]))
|
|
||||||
{
|
|
||||||
string username = args[1].ToLower();
|
|
||||||
if (commandName == "addignored")
|
|
||||||
{
|
|
||||||
lock (readWriteLock)
|
|
||||||
{
|
|
||||||
if (!ignoreList.Contains(username))
|
|
||||||
{
|
|
||||||
ignoreList.Add(username);
|
|
||||||
ignoreList.SaveToFile(Config.IgnoreListFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string.Format(Translations.bot_mailer_cmd_ignore_added, args[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lock (readWriteLock)
|
|
||||||
{
|
|
||||||
if (ignoreList.Contains(username))
|
|
||||||
{
|
|
||||||
ignoreList.Remove(username);
|
|
||||||
ignoreList.SaveToFile(Config.IgnoreListFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string.Format(Translations.bot_mailer_cmd_ignore_removed, args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return string.Format(Translations.bot_mailer_cmd_ignore_invalid, commandName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Translations.bot_mailer_cmd_help + ": /help mailer";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
using ImageMagick;
|
using ImageMagick;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class Map : ChatBot
|
public class Map : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "maps";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
public struct QueuedMap
|
public struct QueuedMap
|
||||||
|
|
@ -63,7 +69,7 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
private readonly string baseDirectory = @"Rendered_Maps";
|
private readonly string baseDirectory = @"Rendered_Maps";
|
||||||
|
|
||||||
private readonly Dictionary<int, McMap> cachedMaps = new();
|
internal readonly Dictionary<int, McMap> cachedMaps = new();
|
||||||
|
|
||||||
private readonly Queue<QueuedMap> discordQueue = new();
|
private readonly Queue<QueuedMap> discordQueue = new();
|
||||||
|
|
||||||
|
|
@ -74,14 +80,79 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
DeleteRenderedMaps();
|
DeleteRenderedMaps();
|
||||||
|
|
||||||
RegisterChatBotCommand("maps", "bot.map.cmd.desc", "maps list|render <id> or maps l|r <id>", OnMapCommand);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandList(r.Source))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OnCommandList(r.Source)))
|
||||||
|
.Then(l => l.Literal("render")
|
||||||
|
.Then(l => l.Argument("MapID", MccArguments.MapBotMapId())
|
||||||
|
.Executes(r => OnCommandRender(r.Source, Arguments.GetInteger(r, "MapID")))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnUnload()
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
DeleteRenderedMaps();
|
DeleteRenderedMaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => Translations.error_usage + ": /maps <list/render <id>>"
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandList(CmdResult r)
|
||||||
|
{
|
||||||
|
if (cachedMaps.Count == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_map_no_maps);
|
||||||
|
|
||||||
|
LogToConsole(Translations.bot_map_received);
|
||||||
|
|
||||||
|
foreach (var (key, value) in new SortedDictionary<int, McMap>(cachedMaps))
|
||||||
|
LogToConsole(string.Format(Translations.bot_map_list_item, key, value.LastUpdated));
|
||||||
|
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandRender(CmdResult r, int mapId)
|
||||||
|
{
|
||||||
|
if (!cachedMaps.ContainsKey(mapId))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.bot_map_cmd_not_found, mapId));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
McMap map = cachedMaps[mapId];
|
||||||
|
if (Config.Save_To_File)
|
||||||
|
SaveToFile(map);
|
||||||
|
|
||||||
|
if (Config.Render_In_Console)
|
||||||
|
RenderInConsole(map);
|
||||||
|
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LogDebugToConsole(e.StackTrace!);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.bot_map_failed_to_render, mapId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DeleteRenderedMaps()
|
private void DeleteRenderedMaps()
|
||||||
{
|
{
|
||||||
if (Config.Delete_All_On_Unload)
|
if (Config.Delete_All_On_Unload)
|
||||||
|
|
@ -94,56 +165,6 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string OnMapCommand(string command, string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length == 0 || (args.Length == 1 && (args[0].ToLower().Equals("list") || args[0].ToLower().Equals("l"))))
|
|
||||||
{
|
|
||||||
if (cachedMaps.Count == 0)
|
|
||||||
return Translations.bot_map_no_maps;
|
|
||||||
|
|
||||||
LogToConsole(Translations.bot_map_received);
|
|
||||||
|
|
||||||
foreach (var (key, value) in new SortedDictionary<int, McMap>(cachedMaps))
|
|
||||||
LogToConsole(string.Format(Translations.bot_map_list_item, key, value.LastUpdated));
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.Length > 1)
|
|
||||||
{
|
|
||||||
if (args[0].ToLower().Equals("render") || args[0].ToLower().Equals("r"))
|
|
||||||
{
|
|
||||||
if (args.Length < 2)
|
|
||||||
return "maps <list/render <id>> | maps <l/r <id>>";
|
|
||||||
|
|
||||||
if (int.TryParse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture, out int mapId))
|
|
||||||
{
|
|
||||||
if (!cachedMaps.ContainsKey(mapId))
|
|
||||||
return string.Format(Translations.bot_map_cmd_not_found, mapId);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
McMap map = cachedMaps[mapId];
|
|
||||||
if (Config.Save_To_File)
|
|
||||||
SaveToFile(map);
|
|
||||||
|
|
||||||
if (Config.Render_In_Console)
|
|
||||||
RenderInConsole(map);
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LogDebugToConsole(e.StackTrace!);
|
|
||||||
return string.Format(Translations.bot_map_failed_to_render, mapId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Translations.bot_map_cmd_invalid_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnMapData(int mapid, byte scale, bool trackingPosition, bool locked, List<MapIcon> icons, byte columnsUpdated, byte rowsUpdated, byte mapCoulmnX, byte mapRowZ, byte[]? colors)
|
public override void OnMapData(int mapid, byte scale, bool trackingPosition, bool locked, List<MapIcon> icons, byte columnsUpdated, byte rowsUpdated, byte mapCoulmnX, byte mapRowZ, byte[]? colors)
|
||||||
{
|
{
|
||||||
if (columnsUpdated == 0 && cachedMaps.ContainsKey(mapid))
|
if (columnsUpdated == 0 && cachedMaps.ContainsKey(mapid))
|
||||||
|
|
@ -320,7 +341,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderInConsole(McMap map)
|
private static void RenderInConsole(McMap map)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
|
|
||||||
|
|
@ -406,7 +427,7 @@ namespace MinecraftClient.ChatBots
|
||||||
public DateTime LastUpdated { get; set; }
|
public DateTime LastUpdated { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapColors
|
internal class MapColors
|
||||||
{
|
{
|
||||||
// When colors are updated in a new update, you can get them using the game code: net\minecraft\world\level\material\MaterialColor.java
|
// When colors are updated in a new update, you can get them using the game code: net\minecraft\world\level\material\MaterialColor.java
|
||||||
public static Dictionary<byte, byte[]> Colors = new()
|
public static Dictionary<byte, byte[]> Colors = new()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
@ -32,17 +34,9 @@ namespace MinecraftClient.ChatBots
|
||||||
string command = "", sender = "";
|
string command = "", sender = "";
|
||||||
if (IsPrivateMessage(text, ref command, ref sender) && Settings.Config.Main.Advanced.BotOwners.Contains(sender.ToLower().Trim()))
|
if (IsPrivateMessage(text, ref command, ref sender) && Settings.Config.Main.Advanced.BotOwners.Contains(sender.ToLower().Trim()))
|
||||||
{
|
{
|
||||||
string? response = "";
|
CmdResult response = new();
|
||||||
PerformInternalCommand(command, ref response);
|
PerformInternalCommand(command, ref response);
|
||||||
response = GetVerbatim(response);
|
SendPrivateMessage(sender, response.ToString());
|
||||||
foreach (char disallowedChar in McClient.GetDisallowedChatCharacters())
|
|
||||||
{
|
|
||||||
response = response.Replace(disallowedChar.ToString(), String.Empty);
|
|
||||||
}
|
|
||||||
if (response.Length > 0)
|
|
||||||
{
|
|
||||||
SendPrivateMessage(sender, response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Config.AutoTpaccept
|
else if (Config.AutoTpaccept
|
||||||
&& IsTeleportRequest(text, ref sender)
|
&& IsTeleportRequest(text, ref sender)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Protocol;
|
using MinecraftClient.Protocol;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
|
|
@ -10,6 +14,8 @@ namespace MinecraftClient.ChatBots
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ReplayCapture : ChatBot
|
public class ReplayCapture : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "replay";
|
||||||
|
|
||||||
public static Configs Config = new();
|
public static Configs Config = new();
|
||||||
|
|
||||||
[TomlDoNotInlineObject]
|
[TomlDoNotInlineObject]
|
||||||
|
|
@ -40,7 +46,74 @@ namespace MinecraftClient.ChatBots
|
||||||
replay.MetaData.serverName = GetServerHost() + GetServerPort();
|
replay.MetaData.serverName = GetServerHost() + GetServerPort();
|
||||||
backupCounter = Settings.DoubleToTick(Config.Backup_Interval);
|
backupCounter = Settings.DoubleToTick(Config.Backup_Interval);
|
||||||
|
|
||||||
RegisterChatBotCommand("replay", Translations.bot_replayCapture_cmd, "replay <save|stop>", Command);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("save")
|
||||||
|
.Executes(r => OnCommandSave(r.Source)))
|
||||||
|
.Then(l => l.Literal("stop")
|
||||||
|
.Executes(r => OnCommandStop(r.Source)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUnload()
|
||||||
|
{
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => string.Format(Translations.general_available_cmd, "save, stop")
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandSave(CmdResult r)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (replay!.RecordRunning)
|
||||||
|
{
|
||||||
|
replay.CreateBackupReplay(@"replay_recordings\" + replay.GetReplayDefaultName());
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_replayCapture_created);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_replayCapture_restart);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandStop(CmdResult r)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (replay!.RecordRunning)
|
||||||
|
{
|
||||||
|
replay.OnShutDown();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.bot_replayCapture_stopped);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.bot_replayCapture_restart);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, e.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnNetworkPacket(int packetID, List<byte> packetData, bool isLogin, bool isInbound)
|
public override void OnNetworkPacket(int packetID, List<byte> packetData, bool isLogin, bool isInbound)
|
||||||
|
|
@ -66,37 +139,5 @@ namespace MinecraftClient.ChatBots
|
||||||
replay!.OnShutDown();
|
replay!.OnShutDown();
|
||||||
return base.OnDisconnect(reason, message);
|
return base.OnDisconnect(reason, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Command(string cmd, string[] args)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (replay!.RecordRunning)
|
|
||||||
{
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
switch (args[0].ToLower())
|
|
||||||
{
|
|
||||||
case "save":
|
|
||||||
{
|
|
||||||
replay.CreateBackupReplay(@"replay_recordings\" + replay.GetReplayDefaultName());
|
|
||||||
return Translations.bot_replayCapture_created;
|
|
||||||
}
|
|
||||||
case "stop":
|
|
||||||
{
|
|
||||||
replay.OnShutDown();
|
|
||||||
return Translations.bot_replayCapture_stopped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string.Format(Translations.general_available_cmd, "save, stop");
|
|
||||||
}
|
|
||||||
else return Translations.bot_replayCapture_restart;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
return e.Message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
|
|
||||||
namespace MinecraftClient.ChatBots
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Tomlet.Attributes;
|
using Tomlet.Attributes;
|
||||||
using static MinecraftClient.ChatBots.ScriptScheduler.Configs;
|
using static MinecraftClient.ChatBots.ScriptScheduler.Configs;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
using Telegram.Bot.Exceptions;
|
using Telegram.Bot.Exceptions;
|
||||||
using Telegram.Bot.Polling;
|
using Telegram.Bot.Polling;
|
||||||
|
|
@ -16,6 +20,8 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
public class TelegramBridge : ChatBot
|
public class TelegramBridge : ChatBot
|
||||||
{
|
{
|
||||||
|
public const string CommandName = "tgbridge";
|
||||||
|
|
||||||
private enum BridgeDirection
|
private enum BridgeDirection
|
||||||
{
|
{
|
||||||
Both = 0,
|
Both = 0,
|
||||||
|
|
@ -70,17 +76,73 @@ namespace MinecraftClient.ChatBots
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
RegisterChatBotCommand("tgbridge", "bot.TelegramBridge.desc", "tgbridge direction <both|mc|telegram>", OnTgCommand);
|
McClient.dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CommandName)
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
McClient.dispatcher.Register(l => l.Literal(CommandName)
|
||||||
|
.Then(l => l.Literal("direction")
|
||||||
|
.Then(l => l.Literal("both")
|
||||||
|
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Both)))
|
||||||
|
.Then(l => l.Literal("mc")
|
||||||
|
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Minecraft)))
|
||||||
|
.Then(l => l.Literal("telegram")
|
||||||
|
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Telegram))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => OnCommandHelp(r.Source, string.Empty))
|
||||||
|
.Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
|
||||||
|
);
|
||||||
|
|
||||||
Task.Run(async () => await MainAsync());
|
Task.Run(async () => await MainAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
~TelegramBridge()
|
public override void OnUnload()
|
||||||
{
|
{
|
||||||
|
McClient.dispatcher.Unregister(CommandName);
|
||||||
|
McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnUnload()
|
private int OnCommandHelp(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => Translations.error_usage + ": /tgbridge direction <both|mc|telegram>"
|
||||||
|
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OnCommandDirection(CmdResult r, BridgeDirection direction)
|
||||||
|
{
|
||||||
|
string bridgeName;
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case BridgeDirection.Both:
|
||||||
|
bridgeName = Translations.bot_TelegramBridge_direction_both;
|
||||||
|
bridgeDirection = BridgeDirection.Both;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BridgeDirection.Minecraft:
|
||||||
|
bridgeName = Translations.bot_TelegramBridge_direction_minecraft;
|
||||||
|
bridgeDirection = BridgeDirection.Minecraft;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BridgeDirection.Telegram:
|
||||||
|
bridgeName = Translations.bot_TelegramBridge_direction_Telegram;
|
||||||
|
bridgeDirection = BridgeDirection.Telegram;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto case BridgeDirection.Both;
|
||||||
|
}
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_TelegramBridge_direction, bridgeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
~TelegramBridge()
|
||||||
{
|
{
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +159,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_TelegramBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_TelegramBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,47 +172,6 @@ namespace MinecraftClient.ChatBots
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string OnTgCommand(string cmd, string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length == 2)
|
|
||||||
{
|
|
||||||
if (args[0].ToLower().Equals("direction"))
|
|
||||||
{
|
|
||||||
string direction = args[1].ToLower().Trim();
|
|
||||||
|
|
||||||
string bridgeName;
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case "b":
|
|
||||||
case "both":
|
|
||||||
bridgeName = Translations.bot_TelegramBridge_direction_both;
|
|
||||||
bridgeDirection = BridgeDirection.Both;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "mc":
|
|
||||||
case "minecraft":
|
|
||||||
bridgeName = Translations.bot_TelegramBridge_direction_minecraft;
|
|
||||||
bridgeDirection = BridgeDirection.Minecraft;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "t":
|
|
||||||
case "tg":
|
|
||||||
case "telegram":
|
|
||||||
bridgeName = Translations.bot_TelegramBridge_direction_Telegram;
|
|
||||||
bridgeDirection = BridgeDirection.Telegram;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return Translations.bot_TelegramBridge_invalid_direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Format(Translations.bot_TelegramBridge_direction, bridgeName);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return "dscbridge direction <both|mc|discord>";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetText(string text)
|
public override void GetText(string text)
|
||||||
{
|
{
|
||||||
if (!CanSendMessages())
|
if (!CanSendMessages())
|
||||||
|
|
@ -188,7 +209,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_TelegramBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_TelegramBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +232,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole("§w§l§f" + Translations.bot_TelegramBridge_canceled_sending);
|
LogToConsole("§§4§l§f" + Translations.bot_TelegramBridge_canceled_sending);
|
||||||
LogDebugToConsole(e);
|
LogDebugToConsole(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -233,7 +254,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Config.ChannelId.Trim()))
|
if (string.IsNullOrEmpty(Config.ChannelId.Trim()))
|
||||||
LogToConsole("§w§l§f" + Translations.bot_TelegramBridge_missing_channel_id);
|
LogToConsole("§§4§l§f" + Translations.bot_TelegramBridge_missing_channel_id);
|
||||||
|
|
||||||
botClient = new TelegramBotClient(Config.Token.Trim());
|
botClient = new TelegramBotClient(Config.Token.Trim());
|
||||||
cancellationToken = new CancellationTokenSource();
|
cancellationToken = new CancellationTokenSource();
|
||||||
|
|
@ -252,12 +273,12 @@ namespace MinecraftClient.ChatBots
|
||||||
IsConnected = true;
|
IsConnected = true;
|
||||||
|
|
||||||
SendMessage($"✅ {Translations.bot_TelegramBridge_connected}");
|
SendMessage($"✅ {Translations.bot_TelegramBridge_connected}");
|
||||||
LogToConsole($"§y§l§f{Translations.bot_TelegramBridge_connected}");
|
LogToConsole($"§§2§l§f{Translations.bot_TelegramBridge_connected}");
|
||||||
|
|
||||||
if (Config.Authorized_Chat_Ids.Length == 0)
|
if (Config.Authorized_Chat_Ids.Length == 0)
|
||||||
{
|
{
|
||||||
SendMessage($"⚠️ *{Translations.bot_TelegramBridge_missing_authorized_channels}* ⚠️");
|
SendMessage($"⚠️ *{Translations.bot_TelegramBridge_missing_authorized_channels}* ⚠️");
|
||||||
LogToConsole($"§w§l§f{Translations.bot_TelegramBridge_missing_authorized_channels}");
|
LogToConsole($"§§4§l§f{Translations.bot_TelegramBridge_missing_authorized_channels}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,7 +286,7 @@ namespace MinecraftClient.ChatBots
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogToConsole($"§w§l§f{Translations.bot_TelegramBridge_unknown_error}");
|
LogToConsole($"§§4§l§f{Translations.bot_TelegramBridge_unknown_error}");
|
||||||
LogToConsole(e);
|
LogToConsole(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -324,9 +345,8 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
var command = text[1..];
|
var command = text[1..];
|
||||||
|
|
||||||
string? result = "";
|
CmdResult result = new();
|
||||||
PerformInternalCommand(command, ref result);
|
PerformInternalCommand(command, ref result);
|
||||||
result = string.IsNullOrEmpty(result) ? "-" : result;
|
|
||||||
|
|
||||||
await botClient.SendTextMessageAsync(
|
await botClient.SendTextMessageAsync(
|
||||||
chatId: chatId,
|
chatId: chatId,
|
||||||
|
|
@ -348,7 +368,7 @@ namespace MinecraftClient.ChatBots
|
||||||
_ => exception.ToString()
|
_ => exception.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
LogToConsole("§w§l§f" + ErrorMessage);
|
LogToConsole("§§4§l§f" + ErrorMessage);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
namespace MinecraftClient.ChatBots
|
using MinecraftClient.Scripting;
|
||||||
|
|
||||||
|
namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Example of message receiving.
|
/// Example of message receiving.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using static MinecraftClient.Settings.MainConfigHealper.MainConfig.AdvancedConfig;
|
using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig;
|
||||||
|
|
||||||
namespace MinecraftClient
|
namespace MinecraftClient
|
||||||
{
|
{
|
||||||
|
|
@ -75,14 +75,37 @@ namespace MinecraftClient
|
||||||
|
|
||||||
public static string GetColorEscapeCode(byte R, byte G, byte B, bool foreground)
|
public static string GetColorEscapeCode(byte R, byte G, byte B, bool foreground)
|
||||||
{
|
{
|
||||||
return GetColorEscapeCode(R, G, B, foreground, Settings.Config.Main.Advanced.TerminalColorDepth);
|
return GetColorEscapeCode(R, G, B, foreground, Settings.Config.Console.General.ConsoleColorMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetColorEscapeCode(byte R, byte G, byte B, bool foreground, TerminalColorDepthType colorDepth)
|
public static string GetColorEscapeCode(byte R, byte G, byte B, bool foreground, ConsoleColorModeType colorDepth)
|
||||||
{
|
{
|
||||||
switch (colorDepth)
|
switch (colorDepth)
|
||||||
{
|
{
|
||||||
case TerminalColorDepthType.bit_4:
|
case ConsoleColorModeType.disable:
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
case ConsoleColorModeType.legacy_4bit:
|
||||||
|
{
|
||||||
|
ColorRGBA color = new(R, G, B);
|
||||||
|
int best_idx = 0;
|
||||||
|
double min_distance = ColorMap4[0].Item1.Distance(color);
|
||||||
|
for (int i = 1; i < ColorMap4.Length; ++i)
|
||||||
|
{
|
||||||
|
double distance = ColorMap4[i].Item1.Distance(color);
|
||||||
|
if (distance < min_distance)
|
||||||
|
{
|
||||||
|
min_distance = distance;
|
||||||
|
best_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foreground)
|
||||||
|
return $"§{best_idx:X}";
|
||||||
|
else
|
||||||
|
return $"§§{best_idx:X}";
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConsoleColorModeType.vt100_4bit:
|
||||||
{
|
{
|
||||||
ColorRGBA color = new(R, G, B);
|
ColorRGBA color = new(R, G, B);
|
||||||
int best_idx = 0;
|
int best_idx = 0;
|
||||||
|
|
@ -99,7 +122,7 @@ namespace MinecraftClient
|
||||||
return string.Format("\u001b[{0}m", ColorMap4[best_idx].Item2 - (foreground ? 10 : 0));
|
return string.Format("\u001b[{0}m", ColorMap4[best_idx].Item2 - (foreground ? 10 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
case TerminalColorDepthType.bit_8:
|
case ConsoleColorModeType.vt100_8bit:
|
||||||
{
|
{
|
||||||
ColorRGBA color = new(R, G, B);
|
ColorRGBA color = new(R, G, B);
|
||||||
int R_idx = (int)(R <= 95 ? Math.Round(R / 95.0) : 1 + Math.Round((R - 95.0) / 40.0));
|
int R_idx = (int)(R <= 95 ? Math.Round(R / 95.0) : 1 + Math.Round((R - 95.0) / 40.0));
|
||||||
|
|
@ -126,7 +149,7 @@ namespace MinecraftClient
|
||||||
return string.Format("\u001B[{0};5;{1}m", (foreground ? 38 : 48), ColorMap8[best_idx].Item2);
|
return string.Format("\u001B[{0};5;{1}m", (foreground ? 38 : 48), ColorMap8[best_idx].Item2);
|
||||||
}
|
}
|
||||||
|
|
||||||
case TerminalColorDepthType.bit_24:
|
case ConsoleColorModeType.vt100_24bit:
|
||||||
return string.Format("\u001B[{0};2;{1};{2};{3}m", (foreground ? 38 : 48), R, G, B);
|
return string.Format("\u001B[{0};2;{1};{2};{3}m", (foreground ? 38 : 48), R, G, B);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
|
|
||||||
namespace MinecraftClient
|
namespace MinecraftClient
|
||||||
{
|
{
|
||||||
|
|
@ -28,8 +31,13 @@ namespace MinecraftClient
|
||||||
/// <returns>Translated command description</returns>
|
/// <returns>Translated command description</returns>
|
||||||
public string GetCmdDescTranslated()
|
public string GetCmdDescTranslated()
|
||||||
{
|
{
|
||||||
string s = (string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc)) ? "" : ": "; // If either one is empty, no colon :
|
char cmdChar = Settings.Config.Main.Advanced.InternalCmdChar.ToChar();
|
||||||
return CmdUsage + s + CmdDesc;
|
|
||||||
|
StringBuilder sb = new();
|
||||||
|
string s = (string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc)) ? string.Empty : ": "; // If either one is empty, no colon :
|
||||||
|
sb.Append("§e").Append(cmdChar).Append(CmdUsage).Append("§r").Append(s).AppendLine(CmdDesc);
|
||||||
|
sb.Append(McClient.dispatcher.GetAllUsageString(CmdName, false));
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -38,18 +46,9 @@ namespace MinecraftClient
|
||||||
public abstract string CmdUsage { get; }
|
public abstract string CmdUsage { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform the command
|
/// Register the command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The full command, eg: 'mycommand arg1 arg2'</param>
|
public abstract void RegisterCommand(CommandDispatcher<CmdResult> dispatcher);
|
||||||
/// <param name="localVars">Local variables passed along with the command (may be null)</param>
|
|
||||||
/// <returns>A confirmation/error message, or "" if no message</returns>
|
|
||||||
public abstract string Run(McClient handler, string command, Dictionary<string, object>? localVars);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return a list of aliases for this command.
|
|
||||||
/// Override this method if you wish to put aliases to the command
|
|
||||||
/// </summary>
|
|
||||||
public virtual IEnumerable<string> GetCMDAliases() { return Array.Empty<string>(); }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if at least one argument has been passed to the command
|
/// Check if at least one argument has been passed to the command
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.currentHandler;
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
var botList = client.GetLoadedChatBots();
|
||||||
|
foreach (var bot in botList)
|
||||||
|
builder.Suggest(bot.GetType().Name);
|
||||||
|
}
|
||||||
|
return builder.BuildFuture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
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 (EntityType result in Enum.GetValues<EntityType>())
|
||||||
|
{
|
||||||
|
string name = result.ToString();
|
||||||
|
string localName = Entity.GetTypeString(result);
|
||||||
|
bool same = true;
|
||||||
|
for (int i = 0, j = 0; i < name.Length; ++i, ++j)
|
||||||
|
{
|
||||||
|
while (j < localName.Length && localName[j] == ' ')
|
||||||
|
++j;
|
||||||
|
if (j >= localName.Length || name[i] != localName[j])
|
||||||
|
{
|
||||||
|
same = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (same)
|
||||||
|
builder.Suggest(name);
|
||||||
|
else
|
||||||
|
builder.Suggest(name, new SuggestionTooltip(localName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.BuildFuture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
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 HotbarSlotArgumentType : 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.currentHandler;
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
Inventory.Container? inventory = client.GetInventory(0);
|
||||||
|
if (inventory != null)
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= 9; ++i)
|
||||||
|
{
|
||||||
|
if (inventory.Items.TryGetValue(i - 1 + 36, out Inventory.Item? item))
|
||||||
|
{
|
||||||
|
string slotStr = i.ToString();
|
||||||
|
if (slotStr.StartsWith(builder.RemainingLowerCase, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
string itemDesc = item.Count == 1 ? item.GetTypeString() : string.Format("{0}x{1}", item.Count, item.GetTypeString());
|
||||||
|
builder.Suggest(slotStr, new SuggestionTooltip(itemDesc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.BuildFuture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
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.currentHandler;
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
var invList = client.GetInventories();
|
||||||
|
foreach (var inv in invList)
|
||||||
|
{
|
||||||
|
string invName = inv.Key.ToString();
|
||||||
|
if (invName.StartsWith(builder.RemainingLowerCase, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
string? invTitle = inv.Value.Title;
|
||||||
|
if (!string.IsNullOrWhiteSpace(invTitle))
|
||||||
|
builder.Suggest(invName, new SuggestionTooltip(invTitle));
|
||||||
|
else
|
||||||
|
builder.Suggest(invName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.BuildFuture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
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 InventorySlotArgumentType : 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.currentHandler;
|
||||||
|
if (client != null && context.Nodes.Count >= 2)
|
||||||
|
{
|
||||||
|
string invName = context.Nodes[1].Range.Get(builder.Input);
|
||||||
|
if (!int.TryParse(invName, out int invId))
|
||||||
|
invId = invName switch
|
||||||
|
{
|
||||||
|
"creativegive" => 0,
|
||||||
|
"creativedelete" => 0,
|
||||||
|
"player" => 0,
|
||||||
|
"container" => client.GetInventories().Keys.ToList().Max(),
|
||||||
|
_ => -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
Inventory.Container? inventory = client.GetInventory(invId);
|
||||||
|
if (inventory != null)
|
||||||
|
{
|
||||||
|
foreach ((int slot, Inventory.Item item) in inventory.Items)
|
||||||
|
{
|
||||||
|
if (item != null && item.Count > 0)
|
||||||
|
{
|
||||||
|
string slotStr = slot.ToString();
|
||||||
|
if (slotStr.StartsWith(builder.RemainingLowerCase, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
string itemDesc = item.Count == 1 ? item.GetTypeString() : string.Format("{0}x{1}", item.Count, item.GetTypeString());
|
||||||
|
builder.Suggest(slotStr, new SuggestionTooltip(itemDesc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.BuildFuture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
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 (ItemType result in Enum.GetValues<ItemType>())
|
||||||
|
{
|
||||||
|
if (result == ItemType.Unknown || result == ItemType.Null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string name = result.ToString();
|
||||||
|
string localName = Item.GetTypeString(result);
|
||||||
|
bool same = true;
|
||||||
|
for (int i = 0, j = 0; i < name.Length; ++i, ++j)
|
||||||
|
{
|
||||||
|
while (j < localName.Length && localName[j] == ' ')
|
||||||
|
++j;
|
||||||
|
if (j >= localName.Length || name[i] != localName[j])
|
||||||
|
{
|
||||||
|
same = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (same)
|
||||||
|
builder.Suggest(name);
|
||||||
|
else
|
||||||
|
builder.Suggest(name, new SuggestionTooltip(localName));
|
||||||
|
}
|
||||||
|
return builder.BuildFuture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.currentHandler;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.currentHandler;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.currentHandler;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
96
MinecraftClient/CommandHandler/CmdResult.cs
Normal file
96
MinecraftClient/CommandHandler/CmdResult.cs
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MinecraftClient.CommandHandler
|
||||||
|
{
|
||||||
|
public class CmdResult
|
||||||
|
{
|
||||||
|
public static readonly CmdResult Empty = new();
|
||||||
|
|
||||||
|
internal static McClient? currentHandler;
|
||||||
|
|
||||||
|
public enum Status
|
||||||
|
{
|
||||||
|
NotRun = int.MinValue,
|
||||||
|
FailChunkNotLoad = -4,
|
||||||
|
FailNeedEntity = -3,
|
||||||
|
FailNeedInventory = -2,
|
||||||
|
FailNeedTerrain = -1,
|
||||||
|
Fail = 0,
|
||||||
|
Done = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmdResult()
|
||||||
|
{
|
||||||
|
this.status = Status.NotRun;
|
||||||
|
this.result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status status;
|
||||||
|
|
||||||
|
public string? result;
|
||||||
|
|
||||||
|
public int SetAndReturn(Status status)
|
||||||
|
{
|
||||||
|
this.status = status;
|
||||||
|
this.result = status switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
Status.NotRun => null,
|
||||||
|
Status.FailChunkNotLoad => null,
|
||||||
|
Status.FailNeedEntity => Translations.extra_entity_required,
|
||||||
|
Status.FailNeedInventory => Translations.extra_inventory_required,
|
||||||
|
Status.FailNeedTerrain => Translations.extra_terrainandmovement_required,
|
||||||
|
Status.Fail => Translations.general_fail,
|
||||||
|
Status.Done => null,
|
||||||
|
_ => null,
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
};
|
||||||
|
return Convert.ToInt32(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetAndReturn(Status status, string? result)
|
||||||
|
{
|
||||||
|
this.status = status;
|
||||||
|
this.result = result;
|
||||||
|
return Convert.ToInt32(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetAndReturn(int code, string? result)
|
||||||
|
{
|
||||||
|
this.status = (Status)Enum.ToObject(typeof(Status), code);
|
||||||
|
if (!Enum.IsDefined(typeof(Status), status))
|
||||||
|
throw new InvalidOperationException($"{code} is not a legal return value.");
|
||||||
|
this.result = result;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetAndReturn(bool result)
|
||||||
|
{
|
||||||
|
this.status = result ? Status.Done : Status.Fail;
|
||||||
|
this.result = result ? Translations.general_done : Translations.general_fail;
|
||||||
|
return Convert.ToInt32(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetAndReturn(string? result)
|
||||||
|
{
|
||||||
|
this.status = Status.Done;
|
||||||
|
this.result = result;
|
||||||
|
return Convert.ToInt32(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetAndReturn(string? resultstr, bool result)
|
||||||
|
{
|
||||||
|
this.status = result ? Status.Done : Status.Fail;
|
||||||
|
this.result = resultstr;
|
||||||
|
return Convert.ToInt32(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (result != null)
|
||||||
|
return result;
|
||||||
|
else
|
||||||
|
return status.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
114
MinecraftClient/CommandHandler/MccArguments.cs
Normal file
114
MinecraftClient/CommandHandler/MccArguments.cs
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
using System;
|
||||||
|
using Brigadier.NET.Context;
|
||||||
|
using MinecraftClient.CommandHandler.ArgumentType;
|
||||||
|
|
||||||
|
namespace MinecraftClient.CommandHandler
|
||||||
|
{
|
||||||
|
public static class MccArguments
|
||||||
|
{
|
||||||
|
public static LocationArgumentType Location()
|
||||||
|
{
|
||||||
|
return new LocationArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mapping.Location GetLocation<TSource>(CommandContext<TSource> context, string name)
|
||||||
|
{
|
||||||
|
return context.GetArgument<Mapping.Location>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TupleArgumentType Tuple()
|
||||||
|
{
|
||||||
|
return new TupleArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tuple<int, int> GetTuple<TSource>(CommandContext<TSource> context, string name)
|
||||||
|
{
|
||||||
|
return context.GetArgument<Tuple<int, int>>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityTypeArgumentType EntityType()
|
||||||
|
{
|
||||||
|
return new EntityTypeArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mapping.EntityType GetEntityType<TSource>(CommandContext<TSource> context, string name)
|
||||||
|
{
|
||||||
|
return context.GetArgument<Mapping.EntityType>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemTypeArgumentType ItemType()
|
||||||
|
{
|
||||||
|
return new ItemTypeArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Inventory.ItemType GetItemType<TSource>(CommandContext<TSource> context, string name)
|
||||||
|
{
|
||||||
|
return context.GetArgument<Inventory.ItemType>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BotNameArgumentType BotName()
|
||||||
|
{
|
||||||
|
return new BotNameArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServerNickArgumentType ServerNick()
|
||||||
|
{
|
||||||
|
return new ServerNickArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AccountNickArgumentType AccountNick()
|
||||||
|
{
|
||||||
|
return new AccountNickArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InventoryIdArgumentType InventoryId()
|
||||||
|
{
|
||||||
|
return new InventoryIdArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InventoryActionArgumentType InventoryAction()
|
||||||
|
{
|
||||||
|
return new InventoryActionArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InventorySlotArgumentType InventorySlot()
|
||||||
|
{
|
||||||
|
return new InventorySlotArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Inventory.WindowActionType GetInventoryAction<TSource>(CommandContext<TSource> context, string name)
|
||||||
|
{
|
||||||
|
return context.GetArgument<Inventory.WindowActionType>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AutoCraftRecipeNameArgumentType AutoCraftRecipeName()
|
||||||
|
{
|
||||||
|
return new AutoCraftRecipeNameArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FarmerCropTypeArgumentType FarmerCropType()
|
||||||
|
{
|
||||||
|
return new FarmerCropTypeArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatBots.Farmer.CropType GetFarmerCropType<TSource>(CommandContext<TSource> context, string name)
|
||||||
|
{
|
||||||
|
return context.GetArgument<ChatBots.Farmer.CropType>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerNameArgumentType PlayerName()
|
||||||
|
{
|
||||||
|
return new PlayerNameArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MapBotMapIdArgumentType MapBotMapId()
|
||||||
|
{
|
||||||
|
return new MapBotMapIdArgumentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HotbarSlotArgumentType HotbarSlot()
|
||||||
|
{
|
||||||
|
return new HotbarSlotArgumentType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
|
||||||
|
namespace MinecraftClient.CommandHandler.Patch
|
||||||
|
{
|
||||||
|
public static class CommandDispatcherExtensions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method unregisteres a previously declared command
|
||||||
|
*
|
||||||
|
* @param The name of the command to remove
|
||||||
|
*/
|
||||||
|
public static void Unregister(this CommandDispatcher<CmdResult> commandDispatcher, string commandname)
|
||||||
|
{
|
||||||
|
commandDispatcher.GetRoot().RemoveChild(commandname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetAllUsageString(this CommandDispatcher<CmdResult> commandDispatcher, string commandName, bool restricted)
|
||||||
|
{
|
||||||
|
char cmdChar = Settings.Config.Main.Advanced.InternalCmdChar.ToChar();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] usages = commandDispatcher.GetAllUsage(commandDispatcher.GetRoot().GetChild(commandName), new(), restricted);
|
||||||
|
StringBuilder sb = new();
|
||||||
|
sb.AppendLine("All Usages:");
|
||||||
|
foreach (var usage in usages)
|
||||||
|
{
|
||||||
|
sb.Append(cmdChar).Append(commandName).Append(' ');
|
||||||
|
if (usage.Length > 0 && usage[0] == '_')
|
||||||
|
sb.AppendLine(usage.Replace("_help -> ", $"_help -> {cmdChar}help "));
|
||||||
|
else
|
||||||
|
sb.AppendLine(usage);
|
||||||
|
}
|
||||||
|
sb.Remove(sb.Length - 1, 1);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using Brigadier.NET.Tree;
|
||||||
|
|
||||||
|
namespace MinecraftClient.CommandHandler.Patch
|
||||||
|
{
|
||||||
|
public static class CommandNodeExtensions
|
||||||
|
{
|
||||||
|
public static void RemoveChild(this CommandNode<CmdResult> commandNode, string name)
|
||||||
|
{
|
||||||
|
var children = (IDictionary<string, CommandNode<CmdResult>>)
|
||||||
|
typeof(CommandNode<CmdResult>)
|
||||||
|
.GetField("_children", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)!
|
||||||
|
.GetValue(commandNode)!;
|
||||||
|
var literals = (IDictionary<string, LiteralCommandNode<CmdResult>>)
|
||||||
|
typeof(CommandNode<CmdResult>)
|
||||||
|
.GetField("_literals", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)!
|
||||||
|
.GetValue(commandNode)!;
|
||||||
|
var arguments = (IDictionary<string, ArgumentCommandNode<CmdResult>>)
|
||||||
|
typeof(CommandNode<CmdResult>)
|
||||||
|
.GetField("_arguments", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)!
|
||||||
|
.GetValue(commandNode)!;
|
||||||
|
|
||||||
|
children.Remove(name);
|
||||||
|
literals.Remove(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
MinecraftClient/CommandHandler/SuggestionTooltip.cs
Normal file
14
MinecraftClient/CommandHandler/SuggestionTooltip.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Brigadier.NET;
|
||||||
|
|
||||||
|
namespace MinecraftClient.CommandHandler
|
||||||
|
{
|
||||||
|
internal class SuggestionTooltip : IMessage
|
||||||
|
{
|
||||||
|
public SuggestionTooltip(string tooltip)
|
||||||
|
{
|
||||||
|
String = tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string String { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,34 +10,46 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "animation <mainhand|offhand>"; } }
|
public override string CmdUsage { get { return "animation <mainhand|offhand>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_animation_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_animation_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("mainhand")
|
||||||
|
.Executes(r => GetUsage(r.Source, "mainhand")))
|
||||||
|
.Then(l => l.Literal("offhand")
|
||||||
|
.Executes(r => GetUsage(r.Source, "offhand")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoAnimation(r.Source, mainhand: true))
|
||||||
|
.Then(l => l.Literal("mainhand")
|
||||||
|
.Executes(r => DoAnimation(r.Source, mainhand: true)))
|
||||||
|
.Then(l => l.Literal("offhand")
|
||||||
|
.Executes(r => DoAnimation(r.Source, mainhand: false)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
#pragma warning disable format // @formatter:off
|
||||||
if (args.Length > 0)
|
"mainhand" => GetCmdDescTranslated(),
|
||||||
{
|
"offhand" => GetCmdDescTranslated(),
|
||||||
if (args[0] == "mainhand" || args[0] == "0")
|
_ => GetCmdDescTranslated(),
|
||||||
{
|
#pragma warning restore format // @formatter:on
|
||||||
handler.DoAnimation(0);
|
});
|
||||||
return Translations.general_done;
|
}
|
||||||
}
|
|
||||||
else if (args[0] == "offhand" || args[0] == "1")
|
private static int DoAnimation(CmdResult r, bool mainhand)
|
||||||
{
|
{
|
||||||
handler.DoAnimation(1);
|
McClient handler = CmdResult.currentHandler!;
|
||||||
return Translations.general_done;
|
return r.SetAndReturn(handler.DoAnimation(mainhand ? 1 : 0));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -13,138 +16,166 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "bed leave|sleep <x> <y> <z>|sleep <radius>"; } }
|
public override string CmdUsage { get { return "bed leave|sleep <x> <y> <z>|sleep <radius>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_bed_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_bed_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("leave")
|
||||||
|
.Executes(r => GetUsage(r.Source, "leave")))
|
||||||
|
.Then(l => l.Literal("sleep")
|
||||||
|
.Executes(r => GetUsage(r.Source, "sleep")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (args.Length >= 1)
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Literal("leave")
|
||||||
|
.Executes(r => DoLeaveBed(r.Source)))
|
||||||
|
.Then(l => l.Literal("sleep")
|
||||||
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => DoSleepBedWithLocation(r.Source, MccArguments.GetLocation(r, "Location"))))
|
||||||
|
.Then(l => l.Argument("Radius", Arguments.Double())
|
||||||
|
.Executes(r => DoSleepBedWithRadius(r.Source, Arguments.GetDouble(r, "Radius")))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string subcommand = args[0].ToLower().Trim();
|
#pragma warning disable format // @formatter:off
|
||||||
|
"leave" => GetCmdDescTranslated(),
|
||||||
|
"sleep" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (subcommand.Equals("leave") || subcommand.Equals("l"))
|
private static int DoLeaveBed(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
return r.SetAndReturn(Translations.cmd_bed_leaving, handler.SendEntityAction(Protocol.EntityActionType.LeaveBed));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int DoSleepBedWithRadius(CmdResult r, double radius)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
handler.Log.Info(string.Format(Translations.cmd_bed_searching, radius));
|
||||||
|
|
||||||
|
Location current = handler.GetCurrentLocation();
|
||||||
|
Location bedLocation = current;
|
||||||
|
|
||||||
|
Material[] bedMaterialList = new Material[]
|
||||||
|
{
|
||||||
|
Material.BlackBed,
|
||||||
|
Material.BlueBed,
|
||||||
|
Material.BrownBed,
|
||||||
|
Material.CyanBed,
|
||||||
|
Material.GrayBed,
|
||||||
|
Material.GreenBed,
|
||||||
|
Material.LightBlueBed,
|
||||||
|
Material.LightGrayBed,
|
||||||
|
Material.LimeBed,
|
||||||
|
Material.MagentaBed,
|
||||||
|
Material.OrangeBed,
|
||||||
|
Material.PinkBed,
|
||||||
|
Material.PurpleBed,
|
||||||
|
Material.RedBed,
|
||||||
|
Material.WhiteBed,
|
||||||
|
Material.YellowBed
|
||||||
|
};
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
foreach (Material material in bedMaterialList)
|
||||||
|
{
|
||||||
|
List<Location> beds = handler.GetWorld().FindBlock(current, material, radius);
|
||||||
|
|
||||||
|
if (beds.Count > 0)
|
||||||
{
|
{
|
||||||
handler.SendEntityAction(Protocol.EntityActionType.LeaveBed);
|
found = true;
|
||||||
return Translations.cmd_bed_leaving;
|
bedLocation = beds.First();
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (subcommand.Equals("sleep") || subcommand.Equals("s"))
|
|
||||||
{
|
|
||||||
if (!handler.GetTerrainEnabled())
|
|
||||||
return Translations.error_terrain_not_enabled;
|
|
||||||
|
|
||||||
if (args.Length == 2)
|
|
||||||
{
|
|
||||||
if (!int.TryParse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture, out int radius))
|
|
||||||
return CmdUsage;
|
|
||||||
|
|
||||||
handler.GetLogger().Info(string.Format(Translations.cmd_bed_searching, radius));
|
|
||||||
|
|
||||||
Location current = handler.GetCurrentLocation();
|
|
||||||
Location bedLocation = current;
|
|
||||||
|
|
||||||
Material[] bedMaterialList = new Material[]{
|
|
||||||
Material.BlackBed,
|
|
||||||
Material.BlueBed,
|
|
||||||
Material.BrownBed,
|
|
||||||
Material.CyanBed,
|
|
||||||
Material.GrayBed,
|
|
||||||
Material.GreenBed,
|
|
||||||
Material.LightBlueBed,
|
|
||||||
Material.LightGrayBed,
|
|
||||||
Material.LimeBed,
|
|
||||||
Material.MagentaBed,
|
|
||||||
Material.OrangeBed,
|
|
||||||
Material.PinkBed,
|
|
||||||
Material.PurpleBed,
|
|
||||||
Material.RedBed,
|
|
||||||
Material.WhiteBed,
|
|
||||||
Material.YellowBed
|
|
||||||
};
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
foreach (Material material in bedMaterialList)
|
|
||||||
{
|
|
||||||
List<Location> beds = handler.GetWorld().FindBlock(current, material, radius);
|
|
||||||
|
|
||||||
if (beds.Count > 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
bedLocation = beds.First();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
return Translations.cmd_bed_bed_not_found;
|
|
||||||
|
|
||||||
handler.Log.Info(string.Format(Translations.cmd_bed_found_a_bed_at, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
|
||||||
|
|
||||||
if (!Movement.CheckChunkLoading(handler.GetWorld(), current, bedLocation))
|
|
||||||
return string.Format(Translations.cmd_move_chunk_not_loaded, bedLocation.X, bedLocation.Y, bedLocation.Z);
|
|
||||||
|
|
||||||
if (handler.MoveTo(bedLocation))
|
|
||||||
{
|
|
||||||
Task.Factory.StartNew(() =>
|
|
||||||
{
|
|
||||||
bool atTheLocation = false;
|
|
||||||
DateTime timeout = DateTime.Now.AddSeconds(60);
|
|
||||||
|
|
||||||
while (DateTime.Now < timeout)
|
|
||||||
{
|
|
||||||
if (handler.GetCurrentLocation() == bedLocation || handler.GetCurrentLocation().Distance(bedLocation) <= 2.0)
|
|
||||||
{
|
|
||||||
atTheLocation = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!atTheLocation)
|
|
||||||
{
|
|
||||||
handler.Log.Info(string.Format(Translations.cmd_bed_failed_to_reach_in_time, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.Log.Info(string.Format(Translations.cmd_bed_moving, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
|
||||||
|
|
||||||
bool res = handler.PlaceBlock(bedLocation, Direction.Down);
|
|
||||||
|
|
||||||
handler.Log.Info(string.Format(
|
|
||||||
Translations.cmd_bed_trying_to_use,
|
|
||||||
bedLocation.X,
|
|
||||||
bedLocation.Y,
|
|
||||||
bedLocation.Z,
|
|
||||||
res ? Translations.cmd_bed_in : Translations.cmd_bed_not_in
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Translations.cmd_bed_cant_reach_safely;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.Length >= 3)
|
|
||||||
{
|
|
||||||
Location block = Location.Parse(handler.GetCurrentLocation(), args[1], args[2], args[3]).ToFloor();
|
|
||||||
Location blockCenter = block.ToCenter();
|
|
||||||
|
|
||||||
if (!handler.GetWorld().GetBlock(block).Type.IsBed())
|
|
||||||
return string.Format(Translations.cmd_bed_not_a_bed, blockCenter.X, blockCenter.Y, blockCenter.Z);
|
|
||||||
|
|
||||||
bool res = handler.PlaceBlock(block, Direction.Down);
|
|
||||||
|
|
||||||
return string.Format(
|
|
||||||
Translations.cmd_bed_trying_to_use,
|
|
||||||
blockCenter.X,
|
|
||||||
blockCenter.Y,
|
|
||||||
blockCenter.Z,
|
|
||||||
res ? Translations.cmd_bed_in : Translations.cmd_bed_not_in
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CmdUsage;
|
if (!found)
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_bed_bed_not_found);
|
||||||
|
|
||||||
|
handler.Log.Info(string.Format(Translations.cmd_bed_found_a_bed_at, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
||||||
|
|
||||||
|
if (!Movement.CheckChunkLoading(handler.GetWorld(), current, bedLocation))
|
||||||
|
return r.SetAndReturn(Status.FailChunkNotLoad,
|
||||||
|
string.Format(Translations.cmd_move_chunk_not_loaded, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
||||||
|
|
||||||
|
if (handler.MoveTo(bedLocation))
|
||||||
|
{
|
||||||
|
Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
bool atTheLocation = false;
|
||||||
|
DateTime timeout = DateTime.Now.AddSeconds(60);
|
||||||
|
|
||||||
|
while (DateTime.Now < timeout)
|
||||||
|
{
|
||||||
|
if (handler.GetCurrentLocation() == bedLocation || handler.GetCurrentLocation().Distance(bedLocation) <= 2.0)
|
||||||
|
{
|
||||||
|
atTheLocation = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!atTheLocation)
|
||||||
|
{
|
||||||
|
handler.Log.Info(string.Format(Translations.cmd_bed_failed_to_reach_in_time, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Log.Info(string.Format(Translations.cmd_bed_moving, bedLocation.X, bedLocation.Y, bedLocation.Z));
|
||||||
|
|
||||||
|
bool res = handler.PlaceBlock(bedLocation, Direction.Down);
|
||||||
|
|
||||||
|
handler.Log.Info(string.Format(
|
||||||
|
Translations.cmd_bed_trying_to_use,
|
||||||
|
bedLocation.X,
|
||||||
|
bedLocation.Y,
|
||||||
|
bedLocation.Z,
|
||||||
|
res ? Translations.cmd_bed_in : Translations.cmd_bed_not_in
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_bed_cant_reach_safely);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int DoSleepBedWithLocation(CmdResult r, Location block)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
block.ToAbsolute(handler.GetCurrentLocation());
|
||||||
|
Location blockCenter = block.ToCenter();
|
||||||
|
|
||||||
|
if (!handler.GetWorld().GetBlock(block).Type.IsBed())
|
||||||
|
return r.SetAndReturn(Status.Fail,
|
||||||
|
string.Format(Translations.cmd_bed_not_a_bed, blockCenter.X, blockCenter.Y, blockCenter.Z));
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(
|
||||||
|
Translations.cmd_bed_trying_to_use,
|
||||||
|
blockCenter.X,
|
||||||
|
blockCenter.Y,
|
||||||
|
blockCenter.Z,
|
||||||
|
handler.PlaceBlock(block, Direction.Down) ? Translations.cmd_bed_in : Translations.cmd_bed_not_in
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Text;
|
||||||
using System.Text;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -10,36 +13,67 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "blockinfo <x> <y> <z> [-s]"; } }
|
public override string CmdUsage { get { return "blockinfo <x> <y> <z> [-s]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_blockinfo_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_blockinfo_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("-s")
|
||||||
|
.Executes(r => GetUsage(r.Source, "-s")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => LogBlockInfo(r.Source, null, false))
|
||||||
|
.Then(l => l.Literal("-s")
|
||||||
|
.Executes(r => LogBlockInfo(r.Source, null, true)))
|
||||||
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => LogBlockInfo(r.Source, MccArguments.GetLocation(r, "Location"), false))
|
||||||
|
.Then(l => l.Literal("-s")
|
||||||
|
.Executes(r => LogBlockInfo(r.Source, MccArguments.GetLocation(r, "Location"), true))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
"-s" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int LogBlockInfo(CmdResult r, Location? targetBlock, bool reportSurrounding)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
if (!handler.GetTerrainEnabled())
|
if (!handler.GetTerrainEnabled())
|
||||||
return Translations.error_terrain_not_enabled;
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
string[] args = GetArgs(command);
|
if (targetBlock.HasValue)
|
||||||
|
targetBlock.Value.ToAbsolute(handler.GetCurrentLocation());
|
||||||
|
else
|
||||||
|
targetBlock = handler.GetCurrentLocation();
|
||||||
|
|
||||||
if (args.Length < 3)
|
Block block = handler.GetWorld().GetBlock(targetBlock.Value);
|
||||||
return CmdUsage;
|
|
||||||
|
|
||||||
bool reportSurrounding = args.Length >= 4 && args[3].Equals("-s", System.StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
Location current = handler.GetCurrentLocation();
|
|
||||||
Location targetBlockLocation = Location.Parse(current, args[0], args[1], args[2]);
|
|
||||||
|
|
||||||
Block block = handler.GetWorld().GetBlock(targetBlockLocation);
|
|
||||||
|
|
||||||
handler.Log.Info($"{Translations.cmd_blockinfo_BlockType}: {block.GetTypeString()}");
|
handler.Log.Info($"{Translations.cmd_blockinfo_BlockType}: {block.GetTypeString()}");
|
||||||
|
|
||||||
if (reportSurrounding)
|
if (reportSurrounding)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.AppendLine($"{Translations.cmd_blockinfo_BlocksAround}:");
|
sb.AppendLine($"{Translations.cmd_blockinfo_BlocksAround}:");
|
||||||
|
|
||||||
Block blockXPositive = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X + 1, targetBlockLocation.Y, targetBlockLocation.Z));
|
double X = targetBlock.Value.X, Y = targetBlock.Value.Y, Z = targetBlock.Value.Z;
|
||||||
Block blockXNegative = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X - 1, targetBlockLocation.Y, targetBlockLocation.Z));
|
Block blockXPositive = handler.GetWorld().GetBlock(new Location(X + 1, Y, Z));
|
||||||
Block blockYPositive = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y + 1, targetBlockLocation.Z));
|
Block blockXNegative = handler.GetWorld().GetBlock(new Location(X - 1, Y, Z));
|
||||||
Block blockYNegative = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y - 1, targetBlockLocation.Z));
|
Block blockYPositive = handler.GetWorld().GetBlock(new Location(X, Y + 1, Z));
|
||||||
Block blockZPositive = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y, targetBlockLocation.Z + 1));
|
Block blockYNegative = handler.GetWorld().GetBlock(new Location(X, Y - 1, Z));
|
||||||
Block blockZNegative = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y, targetBlockLocation.Z - 1));
|
Block blockZPositive = handler.GetWorld().GetBlock(new Location(X, Y, Z + 1));
|
||||||
|
Block blockZNegative = handler.GetWorld().GetBlock(new Location(X, Y, Z - 1));
|
||||||
|
|
||||||
sb.AppendLine($"[X {Translations.cmd_blockinfo_Positive}] {Translations.cmd_blockinfo_BlockType}: {blockXPositive.GetTypeString()}");
|
sb.AppendLine($"[X {Translations.cmd_blockinfo_Positive}] {Translations.cmd_blockinfo_BlockType}: {blockXPositive.GetTypeString()}");
|
||||||
sb.AppendLine($"[X {Translations.cmd_blockinfo_Negative}] {Translations.cmd_blockinfo_BlockType}: {blockXNegative.GetTypeString()}");
|
sb.AppendLine($"[X {Translations.cmd_blockinfo_Negative}] {Translations.cmd_blockinfo_BlockType}: {blockXNegative.GetTypeString()}");
|
||||||
|
|
@ -56,9 +90,7 @@ namespace MinecraftClient.Commands
|
||||||
|
|
||||||
handler.Log.Info(sb.ToString());
|
handler.Log.Info(sb.ToString());
|
||||||
}
|
}
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -10,65 +13,85 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "bots [list|unload <bot name|all>]"; } }
|
public override string CmdUsage { get { return "bots [list|unload <bot name|all>]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_bots_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_bots_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => GetUsage(r.Source, "list")))
|
||||||
|
.Then(l => l.Literal("unload")
|
||||||
|
.Executes(r => GetUsage(r.Source, "unload")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoListBot(r.Source))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => DoListBot(r.Source)))
|
||||||
|
.Then(l => l.Literal("unload")
|
||||||
|
.Then(l => l.Argument("BotName", MccArguments.BotName())
|
||||||
|
.Executes(r => DoUnloadBot(r.Source, Arguments.GetString(r, "BotName")))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
#pragma warning disable format // @formatter:off
|
||||||
|
"list" => GetCmdDescTranslated(),
|
||||||
|
"unload" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (args.Length == 1)
|
private int DoListBot(CmdResult r)
|
||||||
{
|
{
|
||||||
if (args[0].Equals("list", StringComparison.OrdinalIgnoreCase))
|
McClient handler = CmdResult.currentHandler!;
|
||||||
{
|
int length = handler.GetLoadedChatBots().Count;
|
||||||
StringBuilder sb = new();
|
if (length == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_bots_noloaded);
|
||||||
|
|
||||||
int length = handler.GetLoadedChatBots().Count;
|
StringBuilder sb = new();
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
if (length == 0)
|
{
|
||||||
return Translations.cmd_bots_noloaded;
|
sb.Append(handler.GetLoadedChatBots()[i].GetType().Name);
|
||||||
|
if (i != length - 1)
|
||||||
for (int i = 0; i < length; i++)
|
sb.Append(" ,");
|
||||||
{
|
|
||||||
sb.Append(handler.GetLoadedChatBots()[i].GetType().Name);
|
|
||||||
|
|
||||||
if (i != length - 1)
|
|
||||||
sb.Append(" ,");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return Translations.cmd_bots_list + ": " + sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (args.Length == 2)
|
|
||||||
{
|
|
||||||
if (args[0].Equals("unload", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
string botName = args[1].Trim();
|
|
||||||
|
|
||||||
if (botName.ToLower().Equals("all", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (handler.GetLoadedChatBots().Count == 0)
|
|
||||||
return Translations.cmd_bots_noloaded;
|
|
||||||
|
|
||||||
handler.UnloadAllBots();
|
|
||||||
return Translations.cmd_bots_unloaded_all;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ChatBot? bot = handler.GetLoadedChatBots().Find(bot => bot.GetType().Name.ToLower() == botName.ToLower());
|
|
||||||
|
|
||||||
if (bot == null)
|
|
||||||
return string.Format(Translations.cmd_bots_notfound, botName);
|
|
||||||
|
|
||||||
handler.BotUnLoad(bot);
|
|
||||||
return string.Format(Translations.cmd_bots_unloaded, botName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetCmdDescTranslated();
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_bots_list + ": " + sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoUnloadBot(CmdResult r, string botName)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (botName.ToLower().Equals("all", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (handler.GetLoadedChatBots().Count == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_bots_noloaded);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handler.UnloadAllBots();
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_bots_unloaded_all);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChatBot? bot = handler.GetLoadedChatBots().Find(bot => bot.GetType().Name.ToLower() == botName.ToLower());
|
||||||
|
if (bot == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_bots_notfound, botName));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handler.BotUnLoad(bot);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_bots_unloaded, botName));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using Brigadier.NET;
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -9,35 +11,43 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "changeslot <1-9>"; } }
|
public override string CmdUsage { get { return "changeslot <1-9>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_changeSlot_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_changeSlot_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (!handler.GetInventoryEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
return Translations.extra_inventory_required;
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.HotbarSlot())
|
||||||
|
.Executes(r => DoChangeSlot(r.Source, Arguments.GetInteger(r, "Slot"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
short slot;
|
#pragma warning disable format // @formatter:off
|
||||||
try
|
_ => GetCmdDescTranslated(),
|
||||||
{
|
#pragma warning restore format // @formatter:on
|
||||||
slot = Convert.ToInt16(GetArg(command));
|
});
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
|
||||||
{
|
private int DoChangeSlot(CmdResult r, int slot)
|
||||||
return Translations.cmd_changeSlot_nan;
|
{
|
||||||
}
|
McClient handler = CmdResult.currentHandler!;
|
||||||
if (slot >= 1 && slot <= 9)
|
if (!handler.GetInventoryEnabled())
|
||||||
{
|
return r.SetAndReturn(Status.FailNeedInventory);
|
||||||
if (handler.ChangeSlot(slot -= 1))
|
|
||||||
{
|
if (handler.ChangeSlot((short)(slot - 1)))
|
||||||
return string.Format(Translations.cmd_changeSlot_changed, (slot += 1));
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_changeSlot_changed, slot));
|
||||||
}
|
else
|
||||||
else
|
return r.SetAndReturn(Status.Fail, Translations.cmd_changeSlot_fail);
|
||||||
{
|
|
||||||
return Translations.cmd_changeSlot_fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -12,248 +14,272 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "chunk status [chunkX chunkZ|locationX locationY locationZ]"; } }
|
public override string CmdUsage { get { return "chunk status [chunkX chunkZ|locationX locationY locationZ]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_chunk_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_chunk_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
{
|
.Then(l => l.Literal(CmdName)
|
||||||
string[] args = GetArgs(command);
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
if (args.Length > 0)
|
.Then(l => l.Literal("status")
|
||||||
{
|
.Executes(r => GetUsage(r.Source, "status")))
|
||||||
if (args[0] == "status")
|
.Then(l => l.Literal("_setloading")
|
||||||
{
|
.Executes(r => GetUsage(r.Source, "_setloading")))
|
||||||
World world = handler.GetWorld();
|
.Then(l => l.Literal("_setloaded")
|
||||||
Location current = handler.GetCurrentLocation();
|
.Executes(r => GetUsage(r.Source, "_setloaded")))
|
||||||
|
.Then(l => l.Literal("_delete")
|
||||||
|
.Executes(r => GetUsage(r.Source, "_delete")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
Tuple<int, int>? markedChunkPos = ParseChunkPos(args);
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
(int markChunkX, int markChunkZ) = markedChunkPos ?? (new(current.ChunkX, current.ChunkZ));
|
.Then(l => l.Literal("status")
|
||||||
|
.Executes(r => LogChunkStatus(r.Source))
|
||||||
StringBuilder sb = new();
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => LogChunkStatus(r.Source, pos: MccArguments.GetLocation(r, "Location"))))
|
||||||
sb.Append(World.GetChunkLoadingStatus(handler.GetWorld()));
|
.Then(l => l.Argument("Chunk", MccArguments.Tuple())
|
||||||
sb.Append('\n');
|
.Executes(r => LogChunkStatus(r.Source, markedChunkPos: MccArguments.GetTuple(r, "Chunk")))))
|
||||||
|
.Then(l => l.Literal("_setloading")
|
||||||
sb.AppendLine(string.Format(Translations.cmd_chunk_current, current, current.ChunkX, current.ChunkZ));
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
if (markedChunkPos != null)
|
.Executes(r => DebugSetLoading(r.Source, pos: MccArguments.GetLocation(r, "Location"))))
|
||||||
{
|
.Then(l => l.Argument("Chunk", MccArguments.Tuple())
|
||||||
sb.Append(Translations.cmd_chunk_marked);
|
.Executes(r => DebugSetLoading(r.Source, markedChunkPos: MccArguments.GetTuple(r, "Chunk")))))
|
||||||
if (args.Length == 1 + 3)
|
.Then(l => l.Literal("_setloaded")
|
||||||
sb.Append(String.Format("X:{0:0.00} Y:{1:0.00} Z:{2:0.00}, ",
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
double.Parse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture),
|
.Executes(r => DebugSetLoaded(r.Source, pos: MccArguments.GetLocation(r, "Location"))))
|
||||||
double.Parse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture),
|
.Then(l => l.Argument("Chunk", MccArguments.Tuple())
|
||||||
double.Parse(args[3], NumberStyles.Any, CultureInfo.CurrentCulture)));
|
.Executes(r => DebugSetLoaded(r.Source, markedChunkPos: MccArguments.GetTuple(r, "Chunk")))))
|
||||||
sb.AppendLine(string.Format(Translations.cmd_chunk_chunk_pos, markChunkX, markChunkZ));;
|
.Then(l => l.Literal("_delete")
|
||||||
}
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => DebugDelete(r.Source, pos: MccArguments.GetLocation(r, "Location"))))
|
||||||
int consoleHeight = Math.Max(Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25);
|
.Then(l => l.Argument("Chunk", MccArguments.Tuple())
|
||||||
if (consoleHeight % 2 == 0)
|
.Executes(r => DebugDelete(r.Source, markedChunkPos: MccArguments.GetTuple(r, "Chunk")))))
|
||||||
--consoleHeight;
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
int consoleWidth = Math.Max(Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17);
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
if (consoleWidth % 2 == 0)
|
);
|
||||||
--consoleWidth;
|
|
||||||
|
|
||||||
int startZ = current.ChunkZ - consoleHeight, endZ = current.ChunkZ + consoleHeight;
|
|
||||||
int startX = current.ChunkX - consoleWidth, endX = current.ChunkX + consoleWidth;
|
|
||||||
|
|
||||||
int leftMost = endX, rightMost = startX, topMost = endZ, bottomMost = startZ;
|
|
||||||
for (int z = startZ; z <= endZ; z++)
|
|
||||||
{
|
|
||||||
for (int x = startX; x <= endX; ++x)
|
|
||||||
{
|
|
||||||
if (world[x, z] != null)
|
|
||||||
{
|
|
||||||
leftMost = Math.Min(leftMost, x);
|
|
||||||
rightMost = Math.Max(rightMost, x);
|
|
||||||
topMost = Math.Min(topMost, z);
|
|
||||||
bottomMost = Math.Max(bottomMost, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include the player's location
|
|
||||||
topMost = Math.Min(topMost, current.ChunkZ);
|
|
||||||
bottomMost = Math.Max(bottomMost, current.ChunkZ);
|
|
||||||
leftMost = Math.Min(leftMost, current.ChunkX);
|
|
||||||
rightMost = Math.Max(rightMost, current.ChunkX);
|
|
||||||
|
|
||||||
// Empty one row and one column each
|
|
||||||
--leftMost; ++rightMost; --topMost; ++bottomMost;
|
|
||||||
|
|
||||||
// Resize according to limitations
|
|
||||||
if ((bottomMost - topMost + 1) > consoleHeight)
|
|
||||||
{
|
|
||||||
int delta = (bottomMost - topMost + 1) - consoleHeight;
|
|
||||||
if (bottomMost - (delta + 1) / 2 < current.ChunkZ + 1)
|
|
||||||
{
|
|
||||||
int bottomReduce = bottomMost - (current.ChunkZ + 1);
|
|
||||||
bottomMost -= bottomReduce;
|
|
||||||
topMost += delta - bottomReduce;
|
|
||||||
}
|
|
||||||
else if (topMost + delta / 2 > current.ChunkZ - 1)
|
|
||||||
{
|
|
||||||
int topAdd = topMost - (current.ChunkZ - 1);
|
|
||||||
topMost += topAdd;
|
|
||||||
bottomMost -= delta - topAdd;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
topMost += delta / 2;
|
|
||||||
bottomMost -= (delta + 1) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((rightMost - leftMost + 1) > consoleWidth)
|
|
||||||
{
|
|
||||||
int delta = (rightMost - leftMost + 1) - consoleWidth;
|
|
||||||
if (rightMost - (delta + 1) / 2 < current.ChunkX + 1)
|
|
||||||
{
|
|
||||||
int rightReduce = rightMost - (current.ChunkX + 1);
|
|
||||||
rightMost -= rightReduce;
|
|
||||||
leftMost += delta - rightReduce;
|
|
||||||
}
|
|
||||||
else if (leftMost + delta / 2 > current.ChunkX - 1)
|
|
||||||
{
|
|
||||||
int leftAdd = leftMost - (current.ChunkX - 1);
|
|
||||||
leftMost += leftAdd;
|
|
||||||
rightMost -= delta - leftAdd;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
leftMost += delta / 2;
|
|
||||||
rightMost -= (delta + 1) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to include the marker chunk
|
|
||||||
if (markedChunkPos != null &&
|
|
||||||
(((Math.Max(bottomMost, markChunkZ) - Math.Min(topMost, markChunkZ) + 1) > consoleHeight) ||
|
|
||||||
((Math.Max(rightMost, markChunkX) - Math.Min(leftMost, markChunkX) + 1) > consoleWidth)))
|
|
||||||
sb.AppendLine("§x§0" + Translations.cmd_chunk_outside);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
topMost = Math.Min(topMost, markChunkZ);
|
|
||||||
bottomMost = Math.Max(bottomMost, markChunkZ);
|
|
||||||
leftMost = Math.Min(leftMost, markChunkX);
|
|
||||||
rightMost = Math.Max(rightMost, markChunkX);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// \ud83d\udd33: 🔳, \ud83d\udfe8: 🟨, \ud83d\udfe9: 🟩, \u25A1: □, \u25A3: ▣, \u25A0: ■
|
|
||||||
string[] chunkStatusStr = Settings.Config.Main.Advanced.EnableEmoji ?
|
|
||||||
new string[] { "\ud83d\udd33", "\ud83d\udfe8", "\ud83d\udfe9" } : new string[] { "\u25A1", "\u25A3", "\u25A0" };
|
|
||||||
|
|
||||||
// Output
|
|
||||||
for (int z = topMost; z <= bottomMost; ++z)
|
|
||||||
{
|
|
||||||
for (int x = leftMost; x <= rightMost; ++x)
|
|
||||||
{
|
|
||||||
if (z == current.ChunkZ && x == current.ChunkX)
|
|
||||||
sb.Append("§z"); // Player Location: background gray
|
|
||||||
else if (z == markChunkZ && x == markChunkX)
|
|
||||||
sb.Append("§w"); // Marked chunk: background red
|
|
||||||
|
|
||||||
ChunkColumn? chunkColumn = world[x, z];
|
|
||||||
if (chunkColumn == null)
|
|
||||||
sb.Append(chunkStatusStr[0]);
|
|
||||||
else if (chunkColumn.FullyLoaded)
|
|
||||||
sb.Append(chunkStatusStr[2]);
|
|
||||||
else
|
|
||||||
sb.Append(chunkStatusStr[1]);
|
|
||||||
|
|
||||||
if ((z == current.ChunkZ && x == current.ChunkX) || (z == markChunkZ && x == markChunkX))
|
|
||||||
sb.Append("§r"); // Reset background color
|
|
||||||
}
|
|
||||||
sb.Append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine(string.Format(Translations.cmd_chunk_icon, "§z §r", "§w §r", chunkStatusStr[0], chunkStatusStr[1], chunkStatusStr[2]));
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
else if (args[0] == "setloading") // For debugging
|
|
||||||
{
|
|
||||||
Tuple<int, int>? chunkPos = ParseChunkPos(args);
|
|
||||||
if (chunkPos != null)
|
|
||||||
{
|
|
||||||
handler.Log.Info("§x§0" + Translations.cmd_chunk_for_debug);
|
|
||||||
World world = handler.GetWorld();
|
|
||||||
(int chunkX, int chunkZ) = chunkPos;
|
|
||||||
ChunkColumn? chunkColumn = world[chunkX, chunkZ];
|
|
||||||
if (chunkColumn != null)
|
|
||||||
chunkColumn.FullyLoaded = false;
|
|
||||||
return (chunkColumn == null) ? "Fail: chunk dosen't exist!" :
|
|
||||||
String.Format("Successfully marked chunk ({0}, {1}) as loading.", chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else if (args[0] == "setloaded") // For debugging
|
|
||||||
{
|
|
||||||
Tuple<int, int>? chunkPos = ParseChunkPos(args);
|
|
||||||
if (chunkPos != null)
|
|
||||||
{
|
|
||||||
handler.Log.Info("§x§0" + Translations.cmd_chunk_for_debug);
|
|
||||||
World world = handler.GetWorld();
|
|
||||||
(int chunkX, int chunkZ) = chunkPos;
|
|
||||||
ChunkColumn? chunkColumn = world[chunkX, chunkZ];
|
|
||||||
if (chunkColumn != null)
|
|
||||||
chunkColumn.FullyLoaded = true;
|
|
||||||
return (chunkColumn == null) ? "Fail: chunk dosen't exist!" :
|
|
||||||
String.Format("Successfully marked chunk ({0}, {1}) as loaded.", chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else if (args[0] == "delete") // For debugging
|
|
||||||
{
|
|
||||||
Tuple<int, int>? chunkPos = ParseChunkPos(args);
|
|
||||||
if (chunkPos != null)
|
|
||||||
{
|
|
||||||
handler.Log.Info("§x§0" + Translations.cmd_chunk_for_debug);
|
|
||||||
World world = handler.GetWorld();
|
|
||||||
(int chunkX, int chunkZ) = chunkPos;
|
|
||||||
world[chunkX, chunkZ] = null;
|
|
||||||
return String.Format("Successfully deleted chunk ({0}, {1}).", chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Tuple<int, int>? ParseChunkPos(string[] args)
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
{
|
{
|
||||||
try
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
int chunkX, chunkZ;
|
#pragma warning disable format // @formatter:off
|
||||||
if (args.Length == 1 + 3)
|
"status" => GetCmdDescTranslated(),
|
||||||
|
"_setloading" => GetCmdDescTranslated(),
|
||||||
|
"_setloaded" => GetCmdDescTranslated(),
|
||||||
|
"_delete" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int LogChunkStatus(CmdResult r, Location? pos = null, Tuple<int, int>? markedChunkPos = null)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
World world = handler.GetWorld();
|
||||||
|
Location current = handler.GetCurrentLocation();
|
||||||
|
if (pos.HasValue)
|
||||||
|
pos.Value.ToAbsolute(current);
|
||||||
|
|
||||||
|
(int markChunkX, int markChunkZ) = markedChunkPos ??
|
||||||
|
(pos.HasValue ? new(pos.Value.ChunkX, pos.Value.ChunkZ) : new(current.ChunkX, current.ChunkZ));
|
||||||
|
|
||||||
|
StringBuilder sb = new();
|
||||||
|
|
||||||
|
sb.Append(World.GetChunkLoadingStatus(handler.GetWorld()));
|
||||||
|
sb.Append('\n');
|
||||||
|
|
||||||
|
sb.AppendLine(string.Format(Translations.cmd_chunk_current, current, current.ChunkX, current.ChunkZ));
|
||||||
|
if (markedChunkPos != null)
|
||||||
|
{
|
||||||
|
sb.Append(Translations.cmd_chunk_marked);
|
||||||
|
if (pos.HasValue)
|
||||||
|
sb.Append(string.Format("X:{0:0.00} Y:{1:0.00} Z:{2:0.00}, ", pos.Value.X, pos.Value.Y, pos.Value.Z));
|
||||||
|
sb.AppendLine(string.Format(Translations.cmd_chunk_chunk_pos, markChunkX, markChunkZ)); ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int consoleHeight = Math.Max(Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25);
|
||||||
|
if (consoleHeight % 2 == 0)
|
||||||
|
--consoleHeight;
|
||||||
|
|
||||||
|
int consoleWidth = Math.Max(Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17);
|
||||||
|
if (consoleWidth % 2 == 0)
|
||||||
|
--consoleWidth;
|
||||||
|
|
||||||
|
int startZ = current.ChunkZ - consoleHeight, endZ = current.ChunkZ + consoleHeight;
|
||||||
|
int startX = current.ChunkX - consoleWidth, endX = current.ChunkX + consoleWidth;
|
||||||
|
|
||||||
|
int leftMost = endX, rightMost = startX, topMost = endZ, bottomMost = startZ;
|
||||||
|
for (int z = startZ; z <= endZ; z++)
|
||||||
|
{
|
||||||
|
for (int x = startX; x <= endX; ++x)
|
||||||
{
|
{
|
||||||
Location pos = new(
|
if (world[x, z] != null)
|
||||||
double.Parse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture),
|
{
|
||||||
double.Parse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture),
|
leftMost = Math.Min(leftMost, x);
|
||||||
double.Parse(args[3], NumberStyles.Any, CultureInfo.CurrentCulture)
|
rightMost = Math.Max(rightMost, x);
|
||||||
);
|
topMost = Math.Min(topMost, z);
|
||||||
chunkX = pos.ChunkX;
|
bottomMost = Math.Max(bottomMost, z);
|
||||||
chunkZ = pos.ChunkZ;
|
}
|
||||||
}
|
}
|
||||||
else if (args.Length == 1 + 2)
|
}
|
||||||
|
|
||||||
|
// Include the player's location
|
||||||
|
topMost = Math.Min(topMost, current.ChunkZ);
|
||||||
|
bottomMost = Math.Max(bottomMost, current.ChunkZ);
|
||||||
|
leftMost = Math.Min(leftMost, current.ChunkX);
|
||||||
|
rightMost = Math.Max(rightMost, current.ChunkX);
|
||||||
|
|
||||||
|
// Empty one row and one column each
|
||||||
|
--leftMost; ++rightMost; --topMost; ++bottomMost;
|
||||||
|
|
||||||
|
// Resize according to limitations
|
||||||
|
if ((bottomMost - topMost + 1) > consoleHeight)
|
||||||
|
{
|
||||||
|
int delta = (bottomMost - topMost + 1) - consoleHeight;
|
||||||
|
if (bottomMost - (delta + 1) / 2 < current.ChunkZ + 1)
|
||||||
{
|
{
|
||||||
chunkX = int.Parse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture);
|
int bottomReduce = bottomMost - (current.ChunkZ + 1);
|
||||||
chunkZ = int.Parse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture);
|
bottomMost -= bottomReduce;
|
||||||
|
topMost += delta - bottomReduce;
|
||||||
|
}
|
||||||
|
else if (topMost + delta / 2 > current.ChunkZ - 1)
|
||||||
|
{
|
||||||
|
int topAdd = topMost - (current.ChunkZ - 1);
|
||||||
|
topMost += topAdd;
|
||||||
|
bottomMost -= delta - topAdd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return null;
|
{
|
||||||
return new(chunkX, chunkZ);
|
topMost += delta / 2;
|
||||||
|
bottomMost -= (delta + 1) / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
if ((rightMost - leftMost + 1) > consoleWidth)
|
||||||
{
|
{
|
||||||
return null;
|
int delta = (rightMost - leftMost + 1) - consoleWidth;
|
||||||
|
if (rightMost - (delta + 1) / 2 < current.ChunkX + 1)
|
||||||
|
{
|
||||||
|
int rightReduce = rightMost - (current.ChunkX + 1);
|
||||||
|
rightMost -= rightReduce;
|
||||||
|
leftMost += delta - rightReduce;
|
||||||
|
}
|
||||||
|
else if (leftMost + delta / 2 > current.ChunkX - 1)
|
||||||
|
{
|
||||||
|
int leftAdd = leftMost - (current.ChunkX - 1);
|
||||||
|
leftMost += leftAdd;
|
||||||
|
rightMost -= delta - leftAdd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftMost += delta / 2;
|
||||||
|
rightMost -= (delta + 1) / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to include the marker chunk
|
||||||
|
if (markedChunkPos != null &&
|
||||||
|
(((Math.Max(bottomMost, markChunkZ) - Math.Min(topMost, markChunkZ) + 1) > consoleHeight) ||
|
||||||
|
((Math.Max(rightMost, markChunkX) - Math.Min(leftMost, markChunkX) + 1) > consoleWidth)))
|
||||||
|
sb.AppendLine(Translations.cmd_chunk_outside);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
topMost = Math.Min(topMost, markChunkZ);
|
||||||
|
bottomMost = Math.Max(bottomMost, markChunkZ);
|
||||||
|
leftMost = Math.Min(leftMost, markChunkX);
|
||||||
|
rightMost = Math.Max(rightMost, markChunkX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// \ud83d\udd33: 🔳, \ud83d\udfe8: 🟨, \ud83d\udfe9: 🟩, \u25A1: □, \u25A3: ▣, \u25A0: ■
|
||||||
|
string[] chunkStatusStr = Settings.Config.Main.Advanced.EnableEmoji ?
|
||||||
|
new string[] { "\ud83d\udd33", "\ud83d\udfe8", "\ud83d\udfe9" } : new string[] { "\u25A1", "\u25A3", "\u25A0" };
|
||||||
|
|
||||||
|
// Output
|
||||||
|
for (int z = topMost; z <= bottomMost; ++z)
|
||||||
|
{
|
||||||
|
for (int x = leftMost; x <= rightMost; ++x)
|
||||||
|
{
|
||||||
|
if (z == current.ChunkZ && x == current.ChunkX)
|
||||||
|
sb.Append("§§7"); // Player Location: background gray
|
||||||
|
else if (z == markChunkZ && x == markChunkX)
|
||||||
|
sb.Append("§§4"); // Marked chunk: background red
|
||||||
|
|
||||||
|
ChunkColumn? chunkColumn = world[x, z];
|
||||||
|
if (chunkColumn == null)
|
||||||
|
sb.Append(chunkStatusStr[0]);
|
||||||
|
else if (chunkColumn.FullyLoaded)
|
||||||
|
sb.Append(chunkStatusStr[2]);
|
||||||
|
else
|
||||||
|
sb.Append(chunkStatusStr[1]);
|
||||||
|
|
||||||
|
if ((z == current.ChunkZ && x == current.ChunkX) || (z == markChunkZ && x == markChunkX))
|
||||||
|
sb.Append("§§r"); // Reset background color
|
||||||
|
}
|
||||||
|
sb.Append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append(string.Format(Translations.cmd_chunk_icon, "§§7 §§r", "§§4 §§r", chunkStatusStr[0], chunkStatusStr[1], chunkStatusStr[2]));
|
||||||
|
handler.Log.Info(sb.ToString());
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int DebugSetLoading(CmdResult r, Location? pos = null, Tuple<int, int>? markedChunkPos = null)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
if (pos.HasValue)
|
||||||
|
pos.Value.ToAbsolute(handler.GetCurrentLocation());
|
||||||
|
handler.Log.Info(Translations.cmd_chunk_for_debug);
|
||||||
|
(int chunkX, int chunkZ) = markedChunkPos ?? new(pos!.Value.ChunkX, pos!.Value.ChunkZ);
|
||||||
|
ChunkColumn? chunkColumn = handler.GetWorld()[chunkX, chunkZ];
|
||||||
|
if (chunkColumn != null)
|
||||||
|
chunkColumn.FullyLoaded = false;
|
||||||
|
|
||||||
|
if (chunkColumn == null)
|
||||||
|
return r.SetAndReturn(Status.Fail, "Fail: chunk dosen't exist!");
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format("Successfully marked chunk ({0}, {1}) as loading.", chunkX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int DebugSetLoaded(CmdResult r, Location? pos = null, Tuple<int, int>? markedChunkPos = null)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
if (pos.HasValue)
|
||||||
|
pos.Value.ToAbsolute(handler.GetCurrentLocation());
|
||||||
|
handler.Log.Info(Translations.cmd_chunk_for_debug);
|
||||||
|
(int chunkX, int chunkZ) = markedChunkPos ?? new(pos!.Value.ChunkX, pos!.Value.ChunkZ);
|
||||||
|
ChunkColumn? chunkColumn = handler.GetWorld()[chunkX, chunkZ];
|
||||||
|
if (chunkColumn != null)
|
||||||
|
chunkColumn.FullyLoaded = false;
|
||||||
|
|
||||||
|
if (chunkColumn == null)
|
||||||
|
return r.SetAndReturn(Status.Fail, "Fail: chunk dosen't exist!");
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format("Successfully marked chunk ({0}, {1}) as loaded.", chunkX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int DebugDelete(CmdResult r, Location? pos = null, Tuple<int, int>? markedChunkPos = null)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
if (pos.HasValue)
|
||||||
|
pos.Value.ToAbsolute(handler.GetCurrentLocation());
|
||||||
|
handler.Log.Info(Translations.cmd_chunk_for_debug);
|
||||||
|
(int chunkX, int chunkZ) = markedChunkPos ?? new(pos!.Value.ChunkX, pos!.Value.ChunkZ);
|
||||||
|
handler.GetWorld()[chunkX, chunkZ] = null;
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format("Successfully deleted chunk ({0}, {1}).", chunkX, chunkZ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,27 +11,66 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "connect <server> [account]"; } }
|
public override string CmdUsage { get { return "connect <server> [account]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_connect_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_connect_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient? handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
{
|
.Then(l => l.Literal(CmdName)
|
||||||
string[] args = GetArgs(command);
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
if (args.Length > 1)
|
)
|
||||||
{
|
);
|
||||||
if (!Settings.Config.Main.Advanced.SetAccount(args[1]))
|
|
||||||
{
|
|
||||||
return string.Format(Translations.cmd_connect_unknown, args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.Config.Main.SetServerIP(new Settings.MainConfigHealper.MainConfig.ServerInfoConfig(args[0]), true))
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
{
|
.Then(l => l.Argument("ServerNick", MccArguments.ServerNick())
|
||||||
Program.Restart(keepAccountAndServerSettings: true);
|
.Executes(r => DoConnect(r.Source, Arguments.GetString(r, "ServerNick"), string.Empty))
|
||||||
return "";
|
.Then(l => l.Argument("AccountNick", MccArguments.AccountNick())
|
||||||
}
|
.Executes(r => DoConnect(r.Source, Arguments.GetString(r, "ServerNick"), Arguments.GetString(r, "AccountNick")))))
|
||||||
else return string.Format(Translations.cmd_connect_invalid_ip, args[0]);
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoConnect(CmdResult r, string server, string account)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(account) && !Settings.Config.Main.Advanced.SetAccount(account))
|
||||||
|
return r.SetAndReturn(Status.Fail, string.Format(Translations.cmd_connect_unknown, account));
|
||||||
|
|
||||||
|
if (Settings.Config.Main.SetServerIP(new Settings.MainConfigHealper.MainConfig.ServerInfoConfig(server), true))
|
||||||
|
{
|
||||||
|
Program.Restart(keepAccountAndServerSettings: true);
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(Status.Fail, string.Format(Translations.cmd_connect_invalid_ip, server));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string DoConnect(string command)
|
||||||
|
{
|
||||||
|
string[] args = GetArgs(command);
|
||||||
|
if (args.Length > 1 && !Settings.Config.Main.Advanced.SetAccount(args[1]))
|
||||||
|
return string.Format(Translations.cmd_connect_unknown, args[1]);
|
||||||
|
|
||||||
|
if (Settings.Config.Main.SetServerIP(new Settings.MainConfigHealper.MainConfig.ServerInfoConfig(args[0]), true))
|
||||||
|
{
|
||||||
|
Program.Restart(keepAccountAndServerSettings: true);
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return string.Format(Translations.cmd_connect_invalid_ip, args[0]);
|
||||||
}
|
}
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,16 +10,47 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "debug [on|off]"; } }
|
public override string CmdUsage { get { return "debug [on|off]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_debug_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_debug_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
Settings.Config.Logging.DebugMessages = (GetArg(command).ToLower() == "on");
|
.Then(l => l.Literal(CmdName)
|
||||||
else
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => SetDebugMode(r.Source, true))
|
||||||
|
.Then(l => l.Literal("on")
|
||||||
|
.Executes(r => SetDebugMode(r.Source, false, true)))
|
||||||
|
.Then(l => l.Literal("off")
|
||||||
|
.Executes(r => SetDebugMode(r.Source, false, false)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int SetDebugMode(CmdResult r, bool flip, bool mode = false)
|
||||||
|
{
|
||||||
|
if (flip)
|
||||||
Settings.Config.Logging.DebugMessages = !Settings.Config.Logging.DebugMessages;
|
Settings.Config.Logging.DebugMessages = !Settings.Config.Logging.DebugMessages;
|
||||||
if (Settings.Config.Logging.DebugMessages)
|
|
||||||
return Translations.cmd_debug_state_on;
|
|
||||||
else
|
else
|
||||||
return Translations.cmd_debug_state_off;
|
Settings.Config.Logging.DebugMessages = mode;
|
||||||
|
|
||||||
|
if (Settings.Config.Logging.DebugMessages)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_debug_state_on);
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_debug_state_off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -10,49 +13,71 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "dig <x> <y> <z>"; } }
|
public override string CmdUsage { get { return "dig <x> <y> <z>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_dig_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_dig_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (!handler.GetTerrainEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
return Translations.extra_terrainandmovement_required;
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
string[] args = GetArgs(command);
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
if (args.Length == 0)
|
.Executes(r => DigLookAt(r.Source))
|
||||||
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => DigAt(r.Source, MccArguments.GetLocation(r, "Location"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
(bool hasBlock, Location blockLoc, Block block) = RaycastHelper.RaycastBlock(handler, 4.5, false);
|
#pragma warning disable format // @formatter:off
|
||||||
if (!hasBlock)
|
_ => GetCmdDescTranslated(),
|
||||||
return Translations.cmd_dig_too_far;
|
#pragma warning restore format // @formatter:on
|
||||||
else if (block.Type == Material.Air)
|
});
|
||||||
return Translations.cmd_dig_no_block;
|
}
|
||||||
else if (handler.DigBlock(blockLoc, lookAtBlock: false))
|
|
||||||
return string.Format(Translations.cmd_dig_dig, blockLoc.X, blockLoc.Y, blockLoc.Z, block.GetTypeString());
|
private int DigAt(CmdResult r, Location blockToBreak)
|
||||||
else
|
{
|
||||||
return Translations.cmd_dig_fail;
|
McClient handler = CmdResult.currentHandler!;
|
||||||
}
|
if (!handler.GetTerrainEnabled())
|
||||||
else if (args.Length == 3)
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
Location current = handler.GetCurrentLocation();
|
||||||
|
blockToBreak = blockToBreak.ToAbsolute(current);
|
||||||
|
if (blockToBreak.DistanceSquared(current.EyesLocation()) > 25)
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_dig_too_far);
|
||||||
|
Block block = handler.GetWorld().GetBlock(blockToBreak);
|
||||||
|
if (block.Type == Material.Air)
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_dig_no_block);
|
||||||
|
else if (handler.DigBlock(blockToBreak))
|
||||||
{
|
{
|
||||||
try
|
blockToBreak = blockToBreak.ToCenter();
|
||||||
{
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_dig_dig, blockToBreak.X, blockToBreak.Y, blockToBreak.Z, block.GetTypeString()));
|
||||||
Location current = handler.GetCurrentLocation();
|
|
||||||
Location blockToBreak = Location.Parse(current.ToFloor(), args[0], args[1], args[2]);
|
|
||||||
if (blockToBreak.DistanceSquared(current.EyesLocation()) > 25)
|
|
||||||
return Translations.cmd_dig_too_far;
|
|
||||||
Block block = handler.GetWorld().GetBlock(blockToBreak);
|
|
||||||
if (block.Type == Material.Air)
|
|
||||||
return Translations.cmd_dig_no_block;
|
|
||||||
else if (handler.DigBlock(blockToBreak))
|
|
||||||
{
|
|
||||||
blockToBreak = blockToBreak.ToCenter();
|
|
||||||
return string.Format(Translations.cmd_dig_dig, blockToBreak.X, blockToBreak.Y, blockToBreak.Z, block.GetTypeString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Translations.cmd_dig_fail;
|
|
||||||
}
|
|
||||||
catch (FormatException) { return GetCmdDescTranslated(); }
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return r.SetAndReturn(Status.Fail, Translations.cmd_dig_fail);
|
||||||
return GetCmdDescTranslated();
|
}
|
||||||
}
|
|
||||||
|
private int DigLookAt(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
(bool hasBlock, Location blockLoc, Block block) = RaycastHelper.RaycastBlock(handler, 4.5, false);
|
||||||
|
if (!hasBlock)
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_dig_too_far);
|
||||||
|
else if (block.Type == Material.Air)
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_dig_no_block);
|
||||||
|
else if (handler.DigBlock(blockLoc, lookAtBlock: false))
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_dig_dig, blockLoc.X, blockLoc.Y, blockLoc.Z, block.GetTypeString()));
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_dig_fail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,66 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
class DropItem : Command
|
class DropItem : Command
|
||||||
{
|
{
|
||||||
public override string CmdName { get { return "dropitem"; } }
|
public override string CmdName { get { return "dropitem"; } }
|
||||||
public override string CmdUsage { get { return "/dropitem <itemtype>"; } }
|
public override string CmdUsage { get { return "dropitem <itemtype>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_dropItem_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_dropItem_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("ItemType", MccArguments.ItemType())
|
||||||
|
.Executes(r => DoDropItem(r.Source, MccArguments.GetItemType(r, "ItemType"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoDropItem(CmdResult r, ItemType itemType)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
if (!handler.GetInventoryEnabled())
|
if (!handler.GetInventoryEnabled())
|
||||||
{
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
return Translations.extra_inventory_required;
|
|
||||||
}
|
int inventoryId;
|
||||||
if (HasArg(command))
|
var inventories = handler.GetInventories();
|
||||||
{
|
List<int> availableIds = inventories.Keys.ToList();
|
||||||
string arg = GetArg(command);
|
availableIds.Remove(0); // remove player inventory ID from list
|
||||||
if (Enum.TryParse(arg, true, out ItemType itemType))
|
if (availableIds.Count == 1)
|
||||||
{
|
inventoryId = availableIds[0]; // one container, use it
|
||||||
int inventoryId;
|
|
||||||
var inventories = handler.GetInventories();
|
|
||||||
List<int> availableIds = inventories.Keys.ToList();
|
|
||||||
availableIds.Remove(0); // remove player inventory ID from list
|
|
||||||
if (availableIds.Count == 1)
|
|
||||||
inventoryId = availableIds[0]; // one container, use it
|
|
||||||
else
|
|
||||||
inventoryId = 0;
|
|
||||||
var p = inventories[inventoryId];
|
|
||||||
int[] targetItems = p.SearchItem(itemType);
|
|
||||||
foreach (int slot in targetItems)
|
|
||||||
{
|
|
||||||
handler.DoWindowAction(inventoryId, slot, WindowActionType.DropItemStack);
|
|
||||||
}
|
|
||||||
return string.Format(Translations.cmd_dropItem_dropped, itemType.ToString(), inventoryId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return string.Format(Translations.cmd_dropItem_unknown_item, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
inventoryId = 0;
|
||||||
return CmdUsage;
|
var p = inventories[inventoryId];
|
||||||
}
|
int[] targetItems = p.SearchItem(itemType);
|
||||||
|
foreach (int slot in targetItems)
|
||||||
|
handler.DoWindowAction(inventoryId, slot, WindowActionType.DropItemStack);
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_dropItem_dropped, Item.GetTypeString(itemType), inventoryId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using System.Linq;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
|
|
@ -10,76 +12,98 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "enchant <top|middle|bottom>"; } }
|
public override string CmdUsage { get { return "enchant <top|middle|bottom>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_enchant_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_enchant_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (!handler.GetInventoryEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
return Translations.error_inventoryhandling_not_enabled;
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("top")
|
||||||
|
.Executes(r => GetUsage(r.Source, "top")))
|
||||||
|
.Then(l => l.Literal("middle")
|
||||||
|
.Executes(r => GetUsage(r.Source, "middle")))
|
||||||
|
.Then(l => l.Literal("bottom")
|
||||||
|
.Executes(r => GetUsage(r.Source, "bottom")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Literal("top")
|
||||||
|
.Executes(r => DoEnchant(r.Source, slotId: 0)))
|
||||||
|
.Then(l => l.Literal("middle")
|
||||||
|
.Executes(r => DoEnchant(r.Source, slotId: 1)))
|
||||||
|
.Then(l => l.Literal("bottom")
|
||||||
|
.Executes(r => DoEnchant(r.Source, slotId: 2)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string slot = GetArg(command).ToLower().Trim();
|
#pragma warning disable format // @formatter:off
|
||||||
|
"top" => GetCmdDescTranslated(),
|
||||||
|
"middle" => GetCmdDescTranslated(),
|
||||||
|
"bottom" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
int slotId = slot switch
|
private int DoEnchant(CmdResult r, int slotId)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
Container? enchantingTable = null;
|
||||||
|
|
||||||
|
foreach (var (id, container) in handler.GetInventories())
|
||||||
|
{
|
||||||
|
if (container.Type == ContainerType.Enchantment)
|
||||||
{
|
{
|
||||||
"top" => 0,
|
enchantingTable = container;
|
||||||
"middle" => 1,
|
break;
|
||||||
"bottom" => 2,
|
|
||||||
_ => -1
|
|
||||||
};
|
|
||||||
|
|
||||||
if (slotId == -1)
|
|
||||||
return Translations.cmd_enchant_invalid_slot;
|
|
||||||
|
|
||||||
Container? enchantingTable = null;
|
|
||||||
|
|
||||||
foreach (var (id, container) in handler.GetInventories())
|
|
||||||
{
|
|
||||||
if (container.Type == ContainerType.Enchantment)
|
|
||||||
{
|
|
||||||
enchantingTable = container;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enchantingTable == null)
|
|
||||||
return Translations.cmd_enchant_enchanting_table_not_opened;
|
|
||||||
|
|
||||||
int[] emptySlots = enchantingTable.GetEmpytSlots();
|
|
||||||
|
|
||||||
if (emptySlots.Contains(0))
|
|
||||||
return Translations.cmd_enchant_enchanting_no_item;
|
|
||||||
|
|
||||||
if (emptySlots.Contains(1))
|
|
||||||
return Translations.cmd_enchant_enchanting_no_lapis;
|
|
||||||
|
|
||||||
Item lapisSlot = enchantingTable.Items[1];
|
|
||||||
|
|
||||||
if (lapisSlot.Type != ItemType.LapisLazuli)
|
|
||||||
return Translations.cmd_enchant_enchanting_no_lapis;
|
|
||||||
|
|
||||||
if (lapisSlot.Count < 3)
|
|
||||||
return Translations.cmd_enchant_enchanting_no_lapis;
|
|
||||||
|
|
||||||
EnchantmentData? enchantment = handler.GetLastEnchantments();
|
|
||||||
|
|
||||||
if (enchantment == null)
|
|
||||||
return Translations.cmd_enchant_no_enchantments;
|
|
||||||
|
|
||||||
short requiredLevel = slotId switch
|
|
||||||
{
|
|
||||||
0 => enchantment.TopEnchantmentLevelRequirement,
|
|
||||||
1 => enchantment.MiddleEnchantmentLevelRequirement,
|
|
||||||
2 => enchantment.BottomEnchantmentLevelRequirement,
|
|
||||||
_ => 9999
|
|
||||||
};
|
|
||||||
|
|
||||||
if (handler.GetLevel() < requiredLevel)
|
|
||||||
return string.Format(Translations.cmd_enchant_no_levels, handler.GetLevel(), requiredLevel);
|
|
||||||
|
|
||||||
return handler.ClickContainerButton(enchantingTable.ID, slotId) ? Translations.cmd_enchant_clicked : Translations.cmd_enchant_not_clicked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetCmdDescTranslated();
|
if (enchantingTable == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_enchant_enchanting_table_not_opened);
|
||||||
|
|
||||||
|
int[] emptySlots = enchantingTable.GetEmpytSlots();
|
||||||
|
|
||||||
|
if (emptySlots.Contains(0))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_enchant_enchanting_no_item);
|
||||||
|
|
||||||
|
if (emptySlots.Contains(1))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_enchant_enchanting_no_lapis);
|
||||||
|
|
||||||
|
Item lapisSlot = enchantingTable.Items[1];
|
||||||
|
|
||||||
|
if (lapisSlot.Type != ItemType.LapisLazuli || lapisSlot.Count < 3)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_enchant_enchanting_no_lapis);
|
||||||
|
|
||||||
|
EnchantmentData? enchantment = handler.GetLastEnchantments();
|
||||||
|
|
||||||
|
if (enchantment == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_enchant_no_enchantments);
|
||||||
|
|
||||||
|
short requiredLevel = slotId switch
|
||||||
|
{
|
||||||
|
0 => enchantment.TopEnchantmentLevelRequirement,
|
||||||
|
1 => enchantment.MiddleEnchantmentLevelRequirement,
|
||||||
|
2 => enchantment.BottomEnchantmentLevelRequirement,
|
||||||
|
_ => 9999
|
||||||
|
};
|
||||||
|
|
||||||
|
if (handler.GetLevel() < requiredLevel)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_enchant_no_levels, handler.GetLevel(), requiredLevel));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (handler.ClickContainerButton(enchantingTable.ID, slotId))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_enchant_clicked);
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_enchant_not_clicked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -14,6 +17,187 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "entity [near] <id|entitytype> <attack|use>"; } }
|
public override string CmdUsage { get { return "entity [near] <id|entitytype> <attack|use>"; } }
|
||||||
public override string CmdDesc { get { return string.Empty; } }
|
public override string CmdDesc { get { return string.Empty; } }
|
||||||
|
|
||||||
|
private enum ActionType { Attack, Use, List };
|
||||||
|
|
||||||
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("near")
|
||||||
|
.Executes(r => GetUsage(r.Source, "near")))
|
||||||
|
.Then(l => l.Literal("attack")
|
||||||
|
.Executes(r => GetUsage(r.Source, "attack")))
|
||||||
|
.Then(l => l.Literal("use")
|
||||||
|
.Executes(r => GetUsage(r.Source, "use")))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => GetUsage(r.Source, "list")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetFullEntityList(r.Source))
|
||||||
|
.Then(l => l.Literal("near")
|
||||||
|
.Executes(r => GetClosetEntityList(r.Source))
|
||||||
|
.Then(l => l.Argument("EntityID", Arguments.Integer())
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.List))
|
||||||
|
.Then(l => l.Literal("attack")
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.Attack)))
|
||||||
|
.Then(l => l.Literal("use")
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.Use)))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.List))))
|
||||||
|
.Then(l => l.Argument("EntityType", MccArguments.EntityType())
|
||||||
|
.Executes(r => OperateWithType(r.Source, true, MccArguments.GetEntityType(r, "EntityType"), ActionType.List))
|
||||||
|
.Then(l => l.Literal("attack")
|
||||||
|
.Executes(r => OperateWithType(r.Source, near: true, MccArguments.GetEntityType(r, "EntityType"), ActionType.Attack)))
|
||||||
|
.Then(l => l.Literal("use")
|
||||||
|
.Executes(r => OperateWithType(r.Source, near: true, MccArguments.GetEntityType(r, "EntityType"), ActionType.Use)))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OperateWithType(r.Source, near: true, MccArguments.GetEntityType(r, "EntityType"), ActionType.List)))))
|
||||||
|
.Then(l => l.Argument("EntityID", Arguments.Integer())
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.List))
|
||||||
|
.Then(l => l.Literal("attack")
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.Attack)))
|
||||||
|
.Then(l => l.Literal("use")
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.Use)))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OperateWithId(r.Source, Arguments.GetInteger(r, "EntityID"), ActionType.List))))
|
||||||
|
.Then(l => l.Argument("EntityType", MccArguments.EntityType())
|
||||||
|
.Executes(r => OperateWithType(r.Source, true, MccArguments.GetEntityType(r, "EntityType"), ActionType.List))
|
||||||
|
.Then(l => l.Literal("attack")
|
||||||
|
.Executes(r => OperateWithType(r.Source, near: false, MccArguments.GetEntityType(r, "EntityType"), ActionType.Attack)))
|
||||||
|
.Then(l => l.Literal("use")
|
||||||
|
.Executes(r => OperateWithType(r.Source, near: false, MccArguments.GetEntityType(r, "EntityType"), ActionType.Use)))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => OperateWithType(r.Source, near: false, MccArguments.GetEntityType(r, "EntityType"), ActionType.List))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
"near" => GetCmdDescTranslated(),
|
||||||
|
"attack" => GetCmdDescTranslated(),
|
||||||
|
"use" => GetCmdDescTranslated(),
|
||||||
|
"list" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetFullEntityList(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetEntityHandlingEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedEntity);
|
||||||
|
|
||||||
|
Dictionary<int, Entity> entities = handler.GetEntities();
|
||||||
|
StringBuilder response = new();
|
||||||
|
response.AppendLine(Translations.cmd_entityCmd_entities);
|
||||||
|
foreach (var entity2 in entities)
|
||||||
|
response.AppendLine(GetEntityInfoShort(entity2.Value));
|
||||||
|
response.Append(GetCmdDescTranslated());
|
||||||
|
handler.Log.Info(response.ToString());
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetClosetEntityList(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetEntityHandlingEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedEntity);
|
||||||
|
|
||||||
|
if (TryGetClosetEntity(handler.GetEntities(), handler.GetCurrentLocation(), null, out Entity? closest))
|
||||||
|
{
|
||||||
|
handler.Log.Info(GetEntityInfoDetailed(handler, closest));
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_entityCmd_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OperateWithId(CmdResult r, int entityID, ActionType action)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetEntityHandlingEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedEntity);
|
||||||
|
|
||||||
|
if (handler.GetEntities().TryGetValue(entityID, out Entity? entity))
|
||||||
|
{
|
||||||
|
handler.Log.Info(InteractionWithEntity(handler, entity, action));
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_entityCmd_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int OperateWithType(CmdResult r, bool near, EntityType entityType, ActionType action)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetEntityHandlingEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedEntity);
|
||||||
|
|
||||||
|
if (near)
|
||||||
|
{
|
||||||
|
if (TryGetClosetEntity(handler.GetEntities(), handler.GetCurrentLocation(), entityType, out Entity? closest))
|
||||||
|
{
|
||||||
|
handler.Log.Info(InteractionWithEntity(handler, closest, action));
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(Status.Fail, Translations.cmd_entityCmd_not_found);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (action == ActionType.Attack || action == ActionType.Use)
|
||||||
|
{
|
||||||
|
string actionst = Translations.cmd_entityCmd_attacked;
|
||||||
|
int actioncount = 0;
|
||||||
|
foreach (var entity2 in handler.GetEntities())
|
||||||
|
{
|
||||||
|
if (entity2.Value.Type == entityType)
|
||||||
|
{
|
||||||
|
if (action == ActionType.Attack)
|
||||||
|
{
|
||||||
|
handler.InteractEntity(entity2.Key, InteractType.Attack);
|
||||||
|
actionst = Translations.cmd_entityCmd_attacked;
|
||||||
|
}
|
||||||
|
else if (action == ActionType.Use)
|
||||||
|
{
|
||||||
|
handler.InteractEntity(entity2.Key, InteractType.Interact);
|
||||||
|
actionst = Translations.cmd_entityCmd_used;
|
||||||
|
}
|
||||||
|
actioncount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handler.Log.Info(actioncount + " " + actionst);
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringBuilder response = new();
|
||||||
|
response.AppendLine(Translations.cmd_entityCmd_entities);
|
||||||
|
foreach (var entity2 in handler.GetEntities())
|
||||||
|
{
|
||||||
|
if (entity2.Value.Type == entityType)
|
||||||
|
{
|
||||||
|
response.AppendLine(GetEntityInfoShort(entity2.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response.Append(GetCmdDescTranslated());
|
||||||
|
handler.Log.Info(response.ToString());
|
||||||
|
return r.SetAndReturn(Status.Done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetEntityInfoShort(Entity entity)
|
private static string GetEntityInfoShort(Entity entity)
|
||||||
{
|
{
|
||||||
int id = entity.ID;
|
int id = entity.ID;
|
||||||
|
|
@ -122,122 +306,21 @@ namespace MinecraftClient.Commands
|
||||||
return find;
|
return find;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string InteractionWithEntity(McClient handler, Entity entity, string action)
|
private static string InteractionWithEntity(McClient handler, Entity entity, ActionType action)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case "attack":
|
case ActionType.Attack:
|
||||||
handler.InteractEntity(entity.ID, InteractType.Attack);
|
handler.InteractEntity(entity.ID, InteractType.Attack);
|
||||||
return Translations.cmd_entityCmd_attacked;
|
return Translations.cmd_entityCmd_attacked;
|
||||||
case "use":
|
case ActionType.Use:
|
||||||
handler.InteractEntity(entity.ID, InteractType.Interact);
|
handler.InteractEntity(entity.ID, InteractType.Interact);
|
||||||
return Translations.cmd_entityCmd_used;
|
return Translations.cmd_entityCmd_used;
|
||||||
default:
|
case ActionType.List:
|
||||||
return GetEntityInfoDetailed(handler, entity);
|
return GetEntityInfoDetailed(handler, entity);
|
||||||
|
default:
|
||||||
|
goto case ActionType.List;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
|
||||||
{
|
|
||||||
if (handler.GetEntityHandlingEnabled())
|
|
||||||
{
|
|
||||||
string[] args = GetArgs(command);
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
if (int.TryParse(args[0], NumberStyles.Any, CultureInfo.CurrentCulture, out int entityID))
|
|
||||||
{
|
|
||||||
if (handler.GetEntities().TryGetValue(entityID, out Entity? entity))
|
|
||||||
return InteractionWithEntity(handler, entity, args.Length > 1 ? args[1].ToLower() : "list");
|
|
||||||
else
|
|
||||||
return Translations.cmd_entityCmd_not_found;
|
|
||||||
}
|
|
||||||
else if (Enum.TryParse(args[0], true, out EntityType interacttype))
|
|
||||||
{
|
|
||||||
string action = args.Length > 1
|
|
||||||
? args[1].ToLower()
|
|
||||||
: "list";
|
|
||||||
if (action == "attack" || action == "use")
|
|
||||||
{
|
|
||||||
string actionst = Translations.cmd_entityCmd_attacked;
|
|
||||||
int actioncount = 0;
|
|
||||||
foreach (var entity2 in handler.GetEntities())
|
|
||||||
{
|
|
||||||
if (entity2.Value.Type == interacttype)
|
|
||||||
{
|
|
||||||
if (action == "attack")
|
|
||||||
{
|
|
||||||
handler.InteractEntity(entity2.Key, InteractType.Attack);
|
|
||||||
actionst = Translations.cmd_entityCmd_attacked;
|
|
||||||
actioncount++;
|
|
||||||
}
|
|
||||||
else if (action == "use")
|
|
||||||
{
|
|
||||||
handler.InteractEntity(entity2.Key, InteractType.Interact);
|
|
||||||
actionst = Translations.cmd_entityCmd_used;
|
|
||||||
actioncount++;
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return actioncount + " " + actionst;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder response = new();
|
|
||||||
response.AppendLine(Translations.cmd_entityCmd_entities);
|
|
||||||
foreach (var entity2 in handler.GetEntities())
|
|
||||||
{
|
|
||||||
if (entity2.Value.Type == interacttype)
|
|
||||||
{
|
|
||||||
response.AppendLine(GetEntityInfoShort(entity2.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response.Append(GetCmdDescTranslated());
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
else if (args[0] == "near")
|
|
||||||
{
|
|
||||||
if (args.Length > 1)
|
|
||||||
{
|
|
||||||
if (Enum.TryParse(args[1], true, out EntityType entityType))
|
|
||||||
{
|
|
||||||
if (TryGetClosetEntity(handler.GetEntities(), handler.GetCurrentLocation(), entityType, out Entity? closest))
|
|
||||||
return InteractionWithEntity(handler, closest, args.Length > 2 ? args[2].ToLower() : "list");
|
|
||||||
else
|
|
||||||
return Translations.cmd_entityCmd_not_found;
|
|
||||||
}
|
|
||||||
else if (int.TryParse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture, out int entityID2))
|
|
||||||
{
|
|
||||||
if (handler.GetEntities().TryGetValue(entityID2, out Entity? entity))
|
|
||||||
return InteractionWithEntity(handler, entity, args.Length > 1 ? args[1].ToLower() : "list");
|
|
||||||
else
|
|
||||||
return Translations.cmd_entityCmd_not_found;
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (TryGetClosetEntity(handler.GetEntities(), handler.GetCurrentLocation(), null, out Entity? closest))
|
|
||||||
return GetEntityInfoDetailed(handler, closest);
|
|
||||||
else
|
|
||||||
return Translations.cmd_entityCmd_not_found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<int, Entity> entities = handler.GetEntities();
|
|
||||||
StringBuilder response = new();
|
|
||||||
response.AppendLine(Translations.cmd_entityCmd_entities);
|
|
||||||
foreach (var entity2 in entities)
|
|
||||||
{
|
|
||||||
response.AppendLine(GetEntityInfoShort(entity2.Value));
|
|
||||||
}
|
|
||||||
response.Append(GetCmdDescTranslated());
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return Translations.extra_entity_required;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,94 +1,95 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
using DynamicExpresso;
|
using DynamicExpresso;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
class ExecIf : Command
|
class ExecIf : Command
|
||||||
{
|
{
|
||||||
public override string CmdName { get { return "execif"; } }
|
public override string CmdName { get { return "execif"; } }
|
||||||
public override string CmdUsage { get { return "execif <condition/expression> ---> <command>"; } }
|
public override string CmdUsage { get { return "execif \"<condition/expression>\" \"<command>\""; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_execif_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_execif_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
{
|
.Then(l => l.Literal(CmdName)
|
||||||
string commandsString = GetArg(command);
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (!commandsString.Contains("--->"))
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
return GetCmdDescTranslated();
|
.Then(l => l.Argument("Condition", Arguments.String())
|
||||||
|
.Then(l => l.Argument("Command", Arguments.String())
|
||||||
string[] parts = commandsString.Split("--->", StringSplitOptions.TrimEntries)
|
.Executes(r => HandleCommand(r.Source, Arguments.GetString(r, "Condition"), Arguments.GetString(r, "Command")))))
|
||||||
.ToList()
|
);
|
||||||
.ConvertAll(command => command.Trim())
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
if (parts.Length == 0)
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
string expressionText = parts[0];
|
|
||||||
string resultCommand = parts[1];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var interpreter = new Interpreter();
|
|
||||||
interpreter.SetVariable("MCC", handler);
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, object> entry in Settings.Config.AppVar.GetVariables())
|
|
||||||
interpreter.SetVariable(entry.Key, entry.Value);
|
|
||||||
|
|
||||||
var result = interpreter.Eval<bool>(expressionText);
|
|
||||||
|
|
||||||
bool shouldExec = result;
|
|
||||||
|
|
||||||
/*if (result is bool)
|
|
||||||
shouldExec = (bool)result;
|
|
||||||
else if (result is string)
|
|
||||||
shouldExec = !string.IsNullOrEmpty((string)result) && ((string)result).Trim().Contains("true", StringComparison.OrdinalIgnoreCase);
|
|
||||||
else if (result is int)
|
|
||||||
shouldExec = (int)result > 0;
|
|
||||||
else if (result is double)
|
|
||||||
shouldExec = (double)result > 0;
|
|
||||||
else if (result is float)
|
|
||||||
shouldExec = (float)result > 0;
|
|
||||||
else if (result is Int16)
|
|
||||||
shouldExec = (Int16)result > 0;
|
|
||||||
else if (result is Int32)
|
|
||||||
shouldExec = (Int32)result > 0;
|
|
||||||
else if (result is Int64)
|
|
||||||
shouldExec = (Int64)result > 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
handler.Log.Debug("[Execif] Result Type: " + result.GetType().Name);
|
|
||||||
|
|
||||||
if (shouldExec)
|
|
||||||
{
|
|
||||||
string? output = "";
|
|
||||||
handler.PerformInternalCommand(resultCommand, ref output);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(output))
|
|
||||||
handler.Log.Debug(string.Format(Translations.cmd_execif_executed_no_output, expressionText, resultCommand));
|
|
||||||
else
|
|
||||||
handler.Log.Debug(string.Format(Translations.cmd_execif_executed, expressionText, resultCommand, output));
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
handler.Log.Error(string.Format(Translations.cmd_execif_error_occured, command));
|
|
||||||
handler.Log.Error(string.Format(Translations.cmd_execif_error, e.Message));
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int HandleCommand(CmdResult r, string expressionText, string resultCommand)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var interpreter = new Interpreter();
|
||||||
|
interpreter.SetVariable("MCC", handler);
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, object> entry in Settings.Config.AppVar.GetVariables())
|
||||||
|
interpreter.SetVariable(entry.Key, entry.Value);
|
||||||
|
|
||||||
|
var result = interpreter.Eval<bool>(expressionText);
|
||||||
|
|
||||||
|
bool shouldExec = result;
|
||||||
|
|
||||||
|
/*if (result is bool)
|
||||||
|
shouldExec = (bool)result;
|
||||||
|
else if (result is string)
|
||||||
|
shouldExec = !string.IsNullOrEmpty((string)result) && ((string)result).Trim().Contains("true", StringComparison.OrdinalIgnoreCase);
|
||||||
|
else if (result is int)
|
||||||
|
shouldExec = (int)result > 0;
|
||||||
|
else if (result is double)
|
||||||
|
shouldExec = (double)result > 0;
|
||||||
|
else if (result is float)
|
||||||
|
shouldExec = (float)result > 0;
|
||||||
|
else if (result is Int16)
|
||||||
|
shouldExec = (Int16)result > 0;
|
||||||
|
else if (result is Int32)
|
||||||
|
shouldExec = (Int32)result > 0;
|
||||||
|
else if (result is Int64)
|
||||||
|
shouldExec = (Int64)result > 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
handler.Log.Debug("[Execif] Result Type: " + result.GetType().Name);
|
||||||
|
|
||||||
|
if (shouldExec)
|
||||||
|
{
|
||||||
|
CmdResult output = new();
|
||||||
|
handler.PerformInternalCommand(resultCommand, ref output);
|
||||||
|
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_execif_executed, expressionText, resultCommand, output));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
handler.Log.Error(string.Format(Translations.cmd_execif_error, e.Message));
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_execif_error_occured, expressionText + " ---> " + resultCommand));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -10,38 +13,48 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "execmulti <command 1> -> <command2> -> <command 3> -> ..."; } }
|
public override string CmdUsage { get { return "execmulti <command 1> -> <command2> -> <command 3> -> ..."; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_execmulti_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_execmulti_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("Commands", Arguments.GreedyString())
|
||||||
|
.Executes(r => HandleCommand(r.Source, Arguments.GetString(r, "Commands"))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string commandsString = GetArg(command);
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (commandsString.Contains("execmulti", StringComparison.OrdinalIgnoreCase) || commandsString.Contains("execif", StringComparison.OrdinalIgnoreCase))
|
private int HandleCommand(CmdResult r, string commandsString)
|
||||||
return Translations.cmd_execmulti_prevent;
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (commandsString.Contains("execmulti", StringComparison.OrdinalIgnoreCase) || commandsString.Contains("execif", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_execmulti_prevent);
|
||||||
|
|
||||||
IEnumerable<string> commands = commandsString.Split("->", StringSplitOptions.TrimEntries)
|
IEnumerable<string> commands = commandsString.Split("->", StringSplitOptions.TrimEntries)
|
||||||
.ToList()
|
.ToList()
|
||||||
.FindAll(command => !string.IsNullOrEmpty(command));
|
.FindAll(command => !string.IsNullOrEmpty(command));
|
||||||
|
|
||||||
foreach (string cmd in commands)
|
foreach (string cmd in commands)
|
||||||
{
|
{
|
||||||
string? output = "";
|
CmdResult output = new();
|
||||||
handler.PerformInternalCommand(cmd, ref output);
|
handler.PerformInternalCommand(cmd, ref output);
|
||||||
|
handler.Log.Info(string.Format(Translations.cmd_execmulti_executed, cmd, string.Format(Translations.cmd_execmulti_result, output)));
|
||||||
string log = string.Format(
|
|
||||||
Translations.cmd_execmulti_executed, cmd,
|
|
||||||
string.IsNullOrEmpty(output) ? Translations.cmd_execmulti_no_result : string.Format(Translations.cmd_execmulti_result, output));
|
|
||||||
|
|
||||||
if (output != null && output.Contains("unknown command", StringComparison.OrdinalIgnoreCase))
|
|
||||||
handler.Log.Error(log);
|
|
||||||
else
|
|
||||||
handler.Log.Info(log);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetCmdDescTranslated();
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,15 +10,49 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "exit"; } }
|
public override string CmdUsage { get { return "exit"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_exit_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_exit_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient? handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
Program.Exit();
|
dispatcher.Register(l => l.Literal("help")
|
||||||
return "";
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var exit = dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoExit(r.Source, 0))
|
||||||
|
.Then(l => l.Argument("ExitCode", Arguments.Integer())
|
||||||
|
.Executes(r => DoExit(r.Source, Arguments.GetInteger(r, "ExitCode"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal("quit")
|
||||||
|
.Executes(r => DoExit(r.Source, 0))
|
||||||
|
.Redirect(exit)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetCMDAliases()
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
{
|
{
|
||||||
return new string[] { "quit" };
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoExit(CmdResult r, int code = 0)
|
||||||
|
{
|
||||||
|
Program.Exit(code);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string DoExit(string command)
|
||||||
|
{
|
||||||
|
Program.Exit();
|
||||||
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,9 +10,36 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "health"; } }
|
public override string CmdUsage { get { return "health"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_health_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_health_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
return string.Format(Translations.cmd_health_response, handler.GetHealth(), handler.GetSaturation(), handler.GetLevel(), handler.GetTotalExperience());
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => LogHealth(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LogHealth(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_health_response, handler.GetHealth(), handler.GetSaturation(), handler.GetLevel(), handler.GetTotalExperience()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
MinecraftClient/Commands/Help.cs
Normal file
34
MinecraftClient/Commands/Help.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Commands
|
||||||
|
{
|
||||||
|
internal class Help : Command
|
||||||
|
{
|
||||||
|
public override string CmdName => throw new NotImplementedException();
|
||||||
|
public override string CmdDesc => throw new NotImplementedException();
|
||||||
|
public override string CmdUsage => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
|
{
|
||||||
|
dispatcher.Register(l =>
|
||||||
|
l.Literal("help")
|
||||||
|
.Executes(r => LogHelp(r.Source, dispatcher))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LogHelp(CmdResult r, CommandDispatcher<CmdResult> dispatcher)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
var usage = dispatcher.GetSmartUsage(dispatcher.GetRoot(), CmdResult.Empty);
|
||||||
|
StringBuilder sb = new();
|
||||||
|
foreach (var item in usage)
|
||||||
|
sb.AppendLine(Settings.Config.Main.Advanced.InternalCmdChar.ToChar() + item.Value);
|
||||||
|
handler.Log.Info(string.Format(Translations.icmd_list, sb.ToString(), Settings.Config.Main.Advanced.InternalCmdChar.ToChar()));
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
|
|
@ -13,266 +15,384 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return GetBasicUsage(); } }
|
public override string CmdUsage { get { return GetBasicUsage(); } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_inventory_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_inventory_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (handler.GetInventoryEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => GetUsage(r.Source, "list")))
|
||||||
|
.Then(l => l.Literal("close")
|
||||||
|
.Executes(r => GetUsage(r.Source, "close")))
|
||||||
|
.Then(l => l.Literal("click")
|
||||||
|
.Executes(r => GetUsage(r.Source, "click")))
|
||||||
|
.Then(l => l.Literal("drop")
|
||||||
|
.Executes(r => GetUsage(r.Source, "drop")))
|
||||||
|
.Then(l => l.Literal("creativegive")
|
||||||
|
.Executes(r => GetUsage(r.Source, "creativegive")))
|
||||||
|
.Then(l => l.Literal("creativedelete")
|
||||||
|
.Executes(r => GetUsage(r.Source, "creativedelete")))
|
||||||
|
.Then(l => l.Literal("inventories")
|
||||||
|
.Executes(r => GetUsage(r.Source, "inventories")))
|
||||||
|
.Then(l => l.Literal("search")
|
||||||
|
.Executes(r => GetUsage(r.Source, "search")))
|
||||||
|
.Then(l => l.Literal("help")
|
||||||
|
.Executes(r => GetUsage(r.Source, "help")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => ListAllInventories(r.Source))
|
||||||
|
.Then(l => l.Literal("creativegive")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Then(l => l.Argument("ItemType", MccArguments.ItemType())
|
||||||
|
.Then(l => l.Argument("Count", Arguments.Integer(min: 1))
|
||||||
|
.Executes(r => DoCreativeGive(r.Source, Arguments.GetInteger(r, "Slot"), MccArguments.GetItemType(r, "ItemType"), Arguments.GetInteger(r, "Count")))))))
|
||||||
|
.Then(l => l.Literal("creativedelete")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoCreativeDelete(r.Source, Arguments.GetInteger(r, "Slot")))))
|
||||||
|
.Then(l => l.Literal("inventories")
|
||||||
|
.Executes(r => ListAvailableInventories(r.Source)))
|
||||||
|
.Then(l => l.Literal("search")
|
||||||
|
.Then(l => l.Argument("ItemType", MccArguments.ItemType())
|
||||||
|
.Executes(r => SearchItem(r.Source, MccArguments.GetItemType(r, "ItemType"), null))
|
||||||
|
.Then(l => l.Argument("Count", Arguments.Integer(0, 64))
|
||||||
|
.Executes(r => SearchItem(r.Source, MccArguments.GetItemType(r, "ItemType"), Arguments.GetInteger(r, "Count"))))))
|
||||||
|
.Then(l => l.Argument("InventoryId", MccArguments.InventoryId())
|
||||||
|
.Then(l => l.Literal("close")
|
||||||
|
.Executes(r => DoCloseAction(r.Source, Arguments.GetInteger(r, "InventoryId"))))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => DoListAction(r.Source, Arguments.GetInteger(r, "InventoryId"))))
|
||||||
|
.Then(l => l.Literal("click")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoClickAction(r.Source, Arguments.GetInteger(r, "InventoryId"), Arguments.GetInteger(r, "Slot"), WindowActionType.LeftClick))
|
||||||
|
.Then(l => l.Argument("Action", MccArguments.InventoryAction())
|
||||||
|
.Executes(r => DoClickAction(r.Source, Arguments.GetInteger(r, "InventoryId"), Arguments.GetInteger(r, "Slot"), MccArguments.GetInventoryAction(r, "Action"))))))
|
||||||
|
.Then(l => l.Literal("drop")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoDropAction(r.Source, Arguments.GetInteger(r, "InventoryId"), Arguments.GetInteger(r, "Slot"), WindowActionType.DropItem))
|
||||||
|
.Then(l => l.Literal("all")
|
||||||
|
.Executes(r => DoDropAction(r.Source, Arguments.GetInteger(r, "InventoryId"), Arguments.GetInteger(r, "Slot"), WindowActionType.DropItemStack))))))
|
||||||
|
.Then(l => l.Literal("player")
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => DoListAction(r.Source, inventoryId: 0)))
|
||||||
|
.Then(l => l.Literal("click")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoClickAction(r.Source, inventoryId: 0, Arguments.GetInteger(r, "Slot"), WindowActionType.LeftClick))
|
||||||
|
.Then(l => l.Argument("Action", MccArguments.InventoryAction())
|
||||||
|
.Executes(r => DoClickAction(r.Source, inventoryId: 0, Arguments.GetInteger(r, "Slot"), MccArguments.GetInventoryAction(r, "Action"))))))
|
||||||
|
.Then(l => l.Literal("drop")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoDropAction(r.Source, inventoryId: 0, Arguments.GetInteger(r, "Slot"), WindowActionType.DropItem))
|
||||||
|
.Then(l => l.Literal("all")
|
||||||
|
.Executes(r => DoDropAction(r.Source, inventoryId: 0, Arguments.GetInteger(r, "Slot"), WindowActionType.DropItemStack))))))
|
||||||
|
.Then(l => l.Literal("container")
|
||||||
|
.Then(l => l.Literal("close")
|
||||||
|
.Executes(r => DoCloseAction(r.Source, inventoryId: null)))
|
||||||
|
.Then(l => l.Literal("list")
|
||||||
|
.Executes(r => DoListAction(r.Source, inventoryId: null)))
|
||||||
|
.Then(l => l.Literal("click")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoClickAction(r.Source, inventoryId: null, Arguments.GetInteger(r, "Slot"), WindowActionType.LeftClick))
|
||||||
|
.Then(l => l.Argument("Action", MccArguments.InventoryAction())
|
||||||
|
.Executes(r => DoClickAction(r.Source, inventoryId: null, Arguments.GetInteger(r, "Slot"), MccArguments.GetInventoryAction(r, "Action"))))))
|
||||||
|
.Then(l => l.Literal("drop")
|
||||||
|
.Then(l => l.Argument("Slot", MccArguments.InventorySlot())
|
||||||
|
.Executes(r => DoDropAction(r.Source, inventoryId: null, Arguments.GetInteger(r, "Slot"), WindowActionType.DropItem))
|
||||||
|
.Then(l => l.Literal("all")
|
||||||
|
.Executes(r => DoDropAction(r.Source, inventoryId: null, Arguments.GetInteger(r, "Slot"), WindowActionType.DropItemStack))))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
string usageStr = ' ' + Translations.cmd_inventory_help_usage + ": ";
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
#pragma warning disable format // @formatter:off
|
||||||
if (args.Length >= 1)
|
"list" => Translations.cmd_inventory_help_list + usageStr + "/inventory <player|container|<id>> list",
|
||||||
{
|
"close" => Translations.cmd_inventory_help_close + usageStr + "/inventory <player|container|<id>> close",
|
||||||
int inventoryId;
|
"click" => Translations.cmd_inventory_help_click + usageStr + "/inventory <player|container|<id>> click <slot> [left|right|middle|shift]\nDefault is left click",
|
||||||
if (args[0].ToLower() == "creativegive")
|
"drop" => Translations.cmd_inventory_help_drop + usageStr + "/inventory <player|container|<id>> drop <slot> [all]\nAll means drop full stack",
|
||||||
{
|
"creativegive" => Translations.cmd_inventory_help_creativegive + usageStr + "/inventory creativegive <slot> <itemtype> <amount>",
|
||||||
if (args.Length >= 4)
|
"creativedelete" => Translations.cmd_inventory_help_creativedelete + usageStr + "/inventory creativedelete <slot>",
|
||||||
{
|
"inventories" => Translations.cmd_inventory_help_inventories + usageStr + "/inventory inventories",
|
||||||
if (!int.TryParse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture, out int slot))
|
"search" => Translations.cmd_inventory_help_search + usageStr + "/inventory search <item type> [count]",
|
||||||
return GetCmdDescTranslated();
|
"help" => GetCmdDescTranslated(),
|
||||||
|
"action" => Translations.cmd_inventory_help_unknown + GetAvailableActions(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (Enum.TryParse(args[2], true, out ItemType itemType))
|
private int GetMaximumInventoryId(McClient handler)
|
||||||
{
|
{
|
||||||
if (handler.GetGamemode() == 1)
|
List<int> availableIds = handler.GetInventories().Keys.ToList();
|
||||||
{
|
return availableIds.Max(); // use foreground container
|
||||||
if (!int.TryParse(args[3], NumberStyles.Any, CultureInfo.CurrentCulture, out int count))
|
}
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
if (handler.DoCreativeGive(slot, itemType, count, null))
|
private int ListAllInventories(CmdResult r)
|
||||||
return string.Format(Translations.cmd_inventory_creative_done, itemType, count, slot);
|
{
|
||||||
else
|
McClient handler = CmdResult.currentHandler!;
|
||||||
return Translations.cmd_inventory_creative_fail;
|
if (!handler.GetInventoryEnabled())
|
||||||
}
|
{
|
||||||
else
|
handler.Log.Info(Translations.extra_inventory_required);
|
||||||
return Translations.cmd_inventory_need_creative;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
StringBuilder response = new();
|
||||||
return GetCmdDescTranslated();
|
response.Append(Translations.cmd_inventory_inventories).Append(":\n");
|
||||||
}
|
foreach ((int invId, Container inv) in handler.GetInventories())
|
||||||
else
|
response.AppendLine(String.Format(" #{0}: {1}§8", invId, inv.Title));
|
||||||
return GetCmdDescTranslated();
|
response.Append(CmdUsage);
|
||||||
}
|
handler.Log.Info(response.ToString());
|
||||||
else if (args[0].ToLower() == "creativedelete")
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
{
|
}
|
||||||
if (args.Length >= 2)
|
|
||||||
{
|
|
||||||
if (!int.TryParse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture, out int slot))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
if (handler.GetGamemode() == 1)
|
private int DoCreativeGive(CmdResult r, int slot, ItemType itemType, int count)
|
||||||
{
|
{
|
||||||
if (handler.DoCreativeGive(slot, ItemType.Null, 0, null))
|
McClient handler = CmdResult.currentHandler!;
|
||||||
return string.Format(Translations.cmd_inventory_creative_delete, slot);
|
if (!handler.GetInventoryEnabled())
|
||||||
else
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
return Translations.cmd_inventory_creative_fail;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Translations.cmd_inventory_need_creative;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else if (args[0].ToLower().StartsWith("p"))
|
|
||||||
{
|
|
||||||
// player inventory is always ID 0
|
|
||||||
inventoryId = 0;
|
|
||||||
}
|
|
||||||
else if (args[0].ToLower().StartsWith("c"))
|
|
||||||
{
|
|
||||||
List<int> availableIds = handler.GetInventories().Keys.ToList();
|
|
||||||
availableIds.Remove(0); // remove player inventory ID from list
|
|
||||||
if (availableIds.Count > 0)
|
|
||||||
inventoryId = availableIds.Max(); // use foreground container
|
|
||||||
else
|
|
||||||
return Translations.cmd_inventory_container_not_found;
|
|
||||||
}
|
|
||||||
else if (args[0].ToLower().StartsWith("inventories") || args[0].ToLower().StartsWith("i"))
|
|
||||||
{
|
|
||||||
Dictionary<int, Container> inventories = handler.GetInventories();
|
|
||||||
List<int> availableIds = inventories.Keys.ToList();
|
|
||||||
StringBuilder response = new();
|
|
||||||
response.AppendLine(Translations.cmd_inventory_inventories_available);
|
|
||||||
|
|
||||||
foreach (int id in availableIds)
|
if (handler.GetGamemode() == 1)
|
||||||
response.AppendLine(String.Format(" #{0} - {1}§8", id, inventories[id].Title));
|
{
|
||||||
|
if (handler.DoCreativeGive(slot, itemType, count, null))
|
||||||
return response.ToString();
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_inventory_creative_done, itemType, count, slot));
|
||||||
}
|
|
||||||
else if (args[0].ToLower().StartsWith("search") || args[0].ToLower().StartsWith("s"))
|
|
||||||
{
|
|
||||||
if (args.Length < 2)
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
if (!Enum.TryParse(args[1], true, out ItemType parsedItemType))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
bool shouldUseItemCount = args.Length >= 3;
|
|
||||||
int itemCount = 0;
|
|
||||||
|
|
||||||
if (shouldUseItemCount && !int.TryParse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture, out itemCount))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
Dictionary<int, Container> inventories = handler.GetInventories();
|
|
||||||
Dictionary<int, List<Item>> foundItems = new();
|
|
||||||
|
|
||||||
List<Container> availableInventories = inventories.Values.ToList();
|
|
||||||
|
|
||||||
availableInventories.ForEach(inventory =>
|
|
||||||
{
|
|
||||||
inventory.Items.Values
|
|
||||||
.ToList()
|
|
||||||
.FindAll(item => item.Type == parsedItemType && (!shouldUseItemCount || item.Count == itemCount))
|
|
||||||
.ForEach(item =>
|
|
||||||
{
|
|
||||||
if (!foundItems.ContainsKey(inventory.ID))
|
|
||||||
{
|
|
||||||
foundItems.Add(inventory.ID, new List<Item>() { item });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Item> invItems = foundItems[inventory.ID];
|
|
||||||
invItems.Add(item);
|
|
||||||
foundItems.Remove(inventory.ID);
|
|
||||||
foundItems.Add(inventory.ID, invItems);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (foundItems.Count == 0)
|
|
||||||
return Translations.cmd_inventory_no_found_items;
|
|
||||||
|
|
||||||
StringBuilder response = new();
|
|
||||||
|
|
||||||
response.AppendLine(Translations.cmd_inventory_found_items + ":");
|
|
||||||
|
|
||||||
foreach ((int invId, List<Item> itemsList) in new SortedDictionary<int, List<Item>>(foundItems))
|
|
||||||
{
|
|
||||||
if (itemsList.Count > 0)
|
|
||||||
{
|
|
||||||
response.AppendLine(String.Format("{0} (#{1}):", inventories[invId].Title, invId));
|
|
||||||
|
|
||||||
foreach (Item item in itemsList)
|
|
||||||
response.AppendLine(String.Format("\t- {0}", item.ToFullString()));
|
|
||||||
|
|
||||||
response.AppendLine(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
else if (args[0].ToLower() == "help")
|
|
||||||
{
|
|
||||||
if (args.Length >= 2)
|
|
||||||
return GetSubCommandHelp(args[1]);
|
|
||||||
else
|
|
||||||
return GetHelp();
|
|
||||||
}
|
|
||||||
else if (!int.TryParse(args[0], NumberStyles.Any, CultureInfo.CurrentCulture, out inventoryId))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
Container? inventory = handler.GetInventory(inventoryId);
|
|
||||||
if (inventory == null)
|
|
||||||
return string.Format(Translations.cmd_inventory_not_exist, inventoryId);
|
|
||||||
|
|
||||||
string action = args.Length > 1 ? args[1].ToLower() : "list";
|
|
||||||
if (action == "close")
|
|
||||||
{
|
|
||||||
if (handler.CloseInventory(inventoryId))
|
|
||||||
return string.Format(Translations.cmd_inventory_close, inventoryId);
|
|
||||||
else
|
|
||||||
return string.Format(Translations.cmd_inventory_close_fail, inventoryId);
|
|
||||||
}
|
|
||||||
else if (action == "list")
|
|
||||||
{
|
|
||||||
StringBuilder response = new();
|
|
||||||
response.Append(Translations.cmd_inventory_inventory);
|
|
||||||
response.AppendLine(String.Format(" #{0} - {1}§8", inventoryId, inventory.Title));
|
|
||||||
|
|
||||||
string? asciiArt = inventory.Type.GetAsciiArt();
|
|
||||||
if (asciiArt != null && Settings.Config.Main.Advanced.ShowInventoryLayout)
|
|
||||||
response.AppendLine(asciiArt);
|
|
||||||
|
|
||||||
int selectedHotbar = handler.GetCurrentSlot() + 1;
|
|
||||||
foreach ((int itemId, Item item) in new SortedDictionary<int, Item>(inventory.Items))
|
|
||||||
{
|
|
||||||
bool isHotbar = inventory.IsHotbar(itemId, out int hotbar);
|
|
||||||
string hotbarString = isHotbar ? (hotbar + 1).ToString() : " ";
|
|
||||||
if ((hotbar + 1) == selectedHotbar)
|
|
||||||
hotbarString = ">" + hotbarString;
|
|
||||||
response.AppendLine(String.Format("{0,2} | #{1,-2}: {2}", hotbarString, itemId, item.ToFullString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inventoryId == 0)
|
|
||||||
response.AppendLine(string.Format(Translations.cmd_inventory_hotbar, (handler.GetCurrentSlot() + 1)));
|
|
||||||
|
|
||||||
response.Remove(response.Length - 1, 1); // Remove last '\n'
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
else if (action == "click" && args.Length >= 3)
|
|
||||||
{
|
|
||||||
if (!int.TryParse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture, out int slot))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
WindowActionType actionType = WindowActionType.LeftClick;
|
|
||||||
string keyName = Translations.cmd_inventory_left;
|
|
||||||
if (args.Length >= 4)
|
|
||||||
{
|
|
||||||
string b = args[3];
|
|
||||||
if (b.ToLower()[0] == 'r')
|
|
||||||
(actionType, keyName) = (WindowActionType.RightClick, Translations.cmd_inventory_right);
|
|
||||||
else if (b.ToLower()[0] == 'm')
|
|
||||||
(actionType, keyName) = (WindowActionType.MiddleClick, Translations.cmd_inventory_middle);
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.DoWindowAction(inventoryId, slot, actionType);
|
|
||||||
return string.Format(Translations.cmd_inventory_clicking, keyName, slot, inventoryId);
|
|
||||||
}
|
|
||||||
else if (action == "shiftclick" && args.Length >= 3)
|
|
||||||
{
|
|
||||||
if (!int.TryParse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture, out int slot))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
if (!handler.DoWindowAction(inventoryId, slot, WindowActionType.ShiftClick))
|
|
||||||
return Translations.cmd_inventory_shiftclick_fail;
|
|
||||||
|
|
||||||
return string.Format(Translations.cmd_inventory_shiftclick, slot, inventoryId);
|
|
||||||
}
|
|
||||||
else if (action == "drop" && args.Length >= 3)
|
|
||||||
{
|
|
||||||
if (!int.TryParse(args[2], NumberStyles.Any, CultureInfo.CurrentCulture, out int slot))
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
|
|
||||||
// check item exist
|
|
||||||
if (!inventory.Items.ContainsKey(slot))
|
|
||||||
return string.Format(Translations.cmd_inventory_no_item, slot);
|
|
||||||
|
|
||||||
WindowActionType actionType = WindowActionType.DropItem;
|
|
||||||
if (args.Length >= 4 && args[3].ToLower() == "all")
|
|
||||||
actionType = WindowActionType.DropItemStack;
|
|
||||||
|
|
||||||
if (handler.DoWindowAction(inventoryId, slot, actionType))
|
|
||||||
{
|
|
||||||
if (actionType == WindowActionType.DropItemStack)
|
|
||||||
return string.Format(Translations.cmd_inventory_drop_stack, slot);
|
|
||||||
else
|
|
||||||
return string.Format(Translations.cmd_inventory_drop, slot);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "Failed";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_creative_fail);
|
||||||
StringBuilder response = new();
|
|
||||||
response.Append(Translations.cmd_inventory_inventories).Append(":\n");
|
|
||||||
foreach ((int invId, Container inv) in handler.GetInventories())
|
|
||||||
response.AppendLine(String.Format(" #{0}: {1}§8", invId, inv.Title));
|
|
||||||
response.Append(CmdUsage);
|
|
||||||
return response.ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return Translations.extra_inventory_required;
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_need_creative);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int DoCreativeDelete(CmdResult r, int slot)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
if (handler.GetGamemode() == 1)
|
||||||
|
{
|
||||||
|
if (handler.DoCreativeGive(slot, ItemType.Null, 0, null))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_inventory_creative_delete, slot));
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_creative_fail);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_need_creative);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ListAvailableInventories(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
Dictionary<int, Container> inventories = handler.GetInventories();
|
||||||
|
List<int> availableIds = inventories.Keys.ToList();
|
||||||
|
StringBuilder response = new();
|
||||||
|
response.AppendLine(Translations.cmd_inventory_inventories_available);
|
||||||
|
|
||||||
|
foreach (int id in availableIds)
|
||||||
|
response.AppendLine(String.Format(" #{0} - {1}§8", id, inventories[id].Title));
|
||||||
|
|
||||||
|
handler.Log.Info(response.ToString());
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int SearchItem(CmdResult r, ItemType itemType, int? itemCount)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
Dictionary<int, Container> inventories = handler.GetInventories();
|
||||||
|
Dictionary<int, List<Item>> foundItems = new();
|
||||||
|
|
||||||
|
List<Container> availableInventories = inventories.Values.ToList();
|
||||||
|
|
||||||
|
availableInventories.ForEach(inventory =>
|
||||||
|
{
|
||||||
|
inventory.Items.Values
|
||||||
|
.ToList()
|
||||||
|
.FindAll(item => item.Type == itemType && (!itemCount.HasValue || item.Count == itemCount))
|
||||||
|
.ForEach(item =>
|
||||||
|
{
|
||||||
|
if (!foundItems.ContainsKey(inventory.ID))
|
||||||
|
{
|
||||||
|
foundItems.Add(inventory.ID, new List<Item>() { item });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Item> invItems = foundItems[inventory.ID];
|
||||||
|
invItems.Add(item);
|
||||||
|
foundItems.Remove(inventory.ID);
|
||||||
|
foundItems.Add(inventory.ID, invItems);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (foundItems.Count == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_no_found_items);
|
||||||
|
|
||||||
|
StringBuilder response = new();
|
||||||
|
|
||||||
|
response.AppendLine(Translations.cmd_inventory_found_items + ":");
|
||||||
|
|
||||||
|
foreach ((int invId, List<Item> itemsList) in new SortedDictionary<int, List<Item>>(foundItems))
|
||||||
|
{
|
||||||
|
if (itemsList.Count > 0)
|
||||||
|
{
|
||||||
|
response.AppendLine(String.Format("{0} (#{1}):", inventories[invId].Title, invId));
|
||||||
|
|
||||||
|
foreach (Item item in itemsList)
|
||||||
|
response.AppendLine(String.Format("\t- {0}", item.ToFullString()));
|
||||||
|
|
||||||
|
response.AppendLine(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Log.Info(response.ToString());
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoCloseAction(CmdResult r, int? inventoryId)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
if (!inventoryId.HasValue)
|
||||||
|
{
|
||||||
|
inventoryId = GetMaximumInventoryId(handler);
|
||||||
|
if (inventoryId == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_container_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container? inventory = handler.GetInventory(inventoryId.Value);
|
||||||
|
if (inventory == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_inventory_not_exist, inventoryId));
|
||||||
|
|
||||||
|
if (handler.CloseInventory(inventoryId.Value))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_inventory_close, inventoryId));
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_inventory_close_fail, inventoryId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoListAction(CmdResult r, int? inventoryId)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
if (!inventoryId.HasValue)
|
||||||
|
{
|
||||||
|
inventoryId = GetMaximumInventoryId(handler);
|
||||||
|
if (inventoryId == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_container_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container? inventory = handler.GetInventory(inventoryId.Value);
|
||||||
|
if (inventory == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_inventory_not_exist, inventoryId));
|
||||||
|
|
||||||
|
StringBuilder response = new();
|
||||||
|
response.Append(Translations.cmd_inventory_inventory);
|
||||||
|
response.AppendLine(String.Format(" #{0} - {1}§8", inventoryId, inventory.Title));
|
||||||
|
|
||||||
|
string? asciiArt = inventory.Type.GetAsciiArt();
|
||||||
|
if (asciiArt != null && Settings.Config.Main.Advanced.ShowInventoryLayout)
|
||||||
|
response.AppendLine(asciiArt);
|
||||||
|
|
||||||
|
int selectedHotbar = handler.GetCurrentSlot() + 1;
|
||||||
|
foreach ((int itemId, Item item) in new SortedDictionary<int, Item>(inventory.Items))
|
||||||
|
{
|
||||||
|
bool isHotbar = inventory.IsHotbar(itemId, out int hotbar);
|
||||||
|
string hotbarString = isHotbar ? (hotbar + 1).ToString() : " ";
|
||||||
|
if ((hotbar + 1) == selectedHotbar)
|
||||||
|
hotbarString = ">" + hotbarString;
|
||||||
|
response.AppendLine(String.Format("{0,2} | #{1,-2}: {2}", hotbarString, itemId, item.ToFullString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inventoryId == 0)
|
||||||
|
response.AppendLine(string.Format(Translations.cmd_inventory_hotbar, (handler.GetCurrentSlot() + 1)));
|
||||||
|
|
||||||
|
response.Remove(response.Length - 1, 1); // Remove last '\n'
|
||||||
|
handler.Log.Info(response.ToString());
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoClickAction(CmdResult r, int? inventoryId, int slot, WindowActionType actionType)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
if (!inventoryId.HasValue)
|
||||||
|
{
|
||||||
|
inventoryId = GetMaximumInventoryId(handler);
|
||||||
|
if (inventoryId == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_container_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container? inventory = handler.GetInventory(inventoryId.Value);
|
||||||
|
if (inventory == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_inventory_not_exist, inventoryId));
|
||||||
|
|
||||||
|
string keyName = actionType switch
|
||||||
|
{
|
||||||
|
WindowActionType.LeftClick => Translations.cmd_inventory_left,
|
||||||
|
WindowActionType.RightClick => Translations.cmd_inventory_right,
|
||||||
|
WindowActionType.MiddleClick => Translations.cmd_inventory_middle,
|
||||||
|
WindowActionType.ShiftClick => Translations.cmd_inventory_shiftclick,
|
||||||
|
_ => "unknown",
|
||||||
|
};
|
||||||
|
|
||||||
|
handler.Log.Info(string.Format(Translations.cmd_inventory_clicking, keyName, slot, inventoryId));
|
||||||
|
return r.SetAndReturn(handler.DoWindowAction(inventoryId.Value, slot, actionType));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoDropAction(CmdResult r, int? inventoryId, int slot, WindowActionType actionType)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(CmdResult.Status.FailNeedInventory);
|
||||||
|
|
||||||
|
if (!inventoryId.HasValue)
|
||||||
|
{
|
||||||
|
inventoryId = GetMaximumInventoryId(handler);
|
||||||
|
if (inventoryId == 0)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_inventory_container_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container? inventory = handler.GetInventory(inventoryId.Value);
|
||||||
|
if (inventory == null)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_inventory_not_exist, inventoryId));
|
||||||
|
|
||||||
|
// check item exist
|
||||||
|
if (!inventory.Items.ContainsKey(slot))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_inventory_no_item, slot));
|
||||||
|
|
||||||
|
if (handler.DoWindowAction(inventoryId.Value, slot, actionType))
|
||||||
|
{
|
||||||
|
if (actionType == WindowActionType.DropItemStack)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_inventory_drop_stack, slot));
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_inventory_drop, slot));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, "Drop Failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Methods for commands help
|
#region Methods for commands help
|
||||||
|
|
||||||
private static string GetAvailableActions()
|
private static string GetAvailableActions()
|
||||||
|
|
@ -285,31 +405,6 @@ namespace MinecraftClient.Commands
|
||||||
return Translations.cmd_inventory_help_basic + ": /inventory <player|container|<id>> <action>.";
|
return Translations.cmd_inventory_help_basic + ": /inventory <player|container|<id>> <action>.";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetHelp()
|
|
||||||
{
|
|
||||||
return string.Format(Translations.cmd_inventory_help_help, GetAvailableActions());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetSubCommandHelp(string cmd)
|
|
||||||
{
|
|
||||||
string usageStr = ' ' + Translations.cmd_inventory_help_usage + ": ";
|
|
||||||
return cmd switch
|
|
||||||
{
|
|
||||||
#pragma warning disable format // @formatter:off
|
|
||||||
"list" => Translations.cmd_inventory_help_list + usageStr + "/inventory <player|container|<id>> list",
|
|
||||||
"close" => Translations.cmd_inventory_help_close + usageStr + "/inventory <player|container|<id>> close",
|
|
||||||
"click" => Translations.cmd_inventory_help_click + usageStr + "/inventory <player|container|<id>> click <slot> [left|right|middle]\nDefault is left click",
|
|
||||||
"shiftclick" => Translations.cmd_inventory_help_shiftclick + usageStr + "/inventory <player|container|<id>> shiftclick <slot>",
|
|
||||||
"drop" => Translations.cmd_inventory_help_drop + usageStr + "/inventory <player|container|<id>> drop <slot> [all]\nAll means drop full stack",
|
|
||||||
"creativegive" => Translations.cmd_inventory_help_creativegive + usageStr + "/inventory creativegive <slot> <itemtype> <amount>",
|
|
||||||
"creativedelete" => Translations.cmd_inventory_help_creativedelete + usageStr + "/inventory creativedelete <slot>",
|
|
||||||
"inventories" => Translations.cmd_inventory_help_inventories + usageStr + "/inventory inventories",
|
|
||||||
"search" => Translations.cmd_inventory_help_search + usageStr + "/inventory search <item type> [count]",
|
|
||||||
"help" => GetHelp(),
|
|
||||||
_ => Translations.cmd_inventory_help_unknown + GetAvailableActions(),
|
|
||||||
#pragma warning restore format // @formatter:on
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -9,9 +11,36 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "list"; } }
|
public override string CmdUsage { get { return "list"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_list_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_list_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
return string.Format(Translations.cmd_list_players, String.Join(", ", handler.GetOnlinePlayers()));
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoListPlayers(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoListPlayers(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_list_players, String.Join(", ", handler.GetOnlinePlayers())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,14 +10,35 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "log <text>"; } }
|
public override string CmdUsage { get { return "log <text>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_log_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_log_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("String", Arguments.GreedyString())
|
||||||
|
.Executes(r => DoLog(r.Source, Arguments.GetString(r, "String"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
ConsoleIO.WriteLogLine(GetArg(command));
|
#pragma warning disable format // @formatter:off
|
||||||
return "";
|
_ => GetCmdDescTranslated(),
|
||||||
}
|
#pragma warning restore format // @formatter:on
|
||||||
else return GetCmdDescTranslated();
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoLog(CmdResult r, string command)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
using System.Globalization;
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -11,70 +13,107 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "look <x y z|yaw pitch|up|down|east|west|north|south>"; } }
|
public override string CmdUsage { get { return "look <x y z|yaw pitch|up|down|east|west|north|south>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_look_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_look_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (handler.GetTerrainEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("direction")
|
||||||
|
.Executes(r => GetUsage(r.Source, "direction")))
|
||||||
|
.Then(l => l.Literal("angle")
|
||||||
|
.Executes(r => GetUsage(r.Source, "angle")))
|
||||||
|
.Then(l => l.Literal("location")
|
||||||
|
.Executes(r => GetUsage(r.Source, "location")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => LogCurrentLooking(r.Source))
|
||||||
|
.Then(l => l.Literal("up")
|
||||||
|
.Executes(r => LookAtDirection(r.Source, Direction.Up)))
|
||||||
|
.Then(l => l.Literal("down")
|
||||||
|
.Executes(r => LookAtDirection(r.Source, Direction.Down)))
|
||||||
|
.Then(l => l.Literal("east")
|
||||||
|
.Executes(r => LookAtDirection(r.Source, Direction.East)))
|
||||||
|
.Then(l => l.Literal("west")
|
||||||
|
.Executes(r => LookAtDirection(r.Source, Direction.West)))
|
||||||
|
.Then(l => l.Literal("north")
|
||||||
|
.Executes(r => LookAtDirection(r.Source, Direction.North)))
|
||||||
|
.Then(l => l.Literal("south")
|
||||||
|
.Executes(r => LookAtDirection(r.Source, Direction.South)))
|
||||||
|
.Then(l => l.Argument("Yaw", Arguments.Float())
|
||||||
|
.Then(l => l.Argument("Pitch", Arguments.Float())
|
||||||
|
.Executes(r => LookAtAngle(r.Source, Arguments.GetFloat(r, "Yaw"), Arguments.GetFloat(r, "Pitch")))))
|
||||||
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => LookAtLocation(r.Source, MccArguments.GetLocation(r, "Location"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
#pragma warning disable format // @formatter:off
|
||||||
if (args.Length == 0)
|
"direction" => GetCmdDescTranslated(),
|
||||||
{
|
"angle" => GetCmdDescTranslated(),
|
||||||
const double maxDistance = 8.0;
|
"location" => GetCmdDescTranslated(),
|
||||||
(bool hasBlock, Location target, Block block) = RaycastHelper.RaycastBlock(handler, maxDistance, false);
|
_ => GetCmdDescTranslated(),
|
||||||
if (!hasBlock)
|
#pragma warning restore format // @formatter:on
|
||||||
return string.Format(Translations.cmd_look_noinspection, maxDistance);
|
});
|
||||||
else
|
}
|
||||||
{
|
|
||||||
Location current = handler.GetCurrentLocation(), target_center = target.ToCenter();
|
|
||||||
return string.Format(Translations.cmd_look_inspection, block.Type, target.X, target.Y, target.Z,
|
|
||||||
current.Distance(target_center), current.EyesLocation().Distance(target_center));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (args.Length == 1)
|
|
||||||
{
|
|
||||||
string dirStr = GetArg(command).Trim().ToLower();
|
|
||||||
Direction direction;
|
|
||||||
switch (dirStr)
|
|
||||||
{
|
|
||||||
case "up": direction = Direction.Up; break;
|
|
||||||
case "down": direction = Direction.Down; break;
|
|
||||||
case "east": direction = Direction.East; break;
|
|
||||||
case "west": direction = Direction.West; break;
|
|
||||||
case "north": direction = Direction.North; break;
|
|
||||||
case "south": direction = Direction.South; break;
|
|
||||||
default: return string.Format(Translations.cmd_look_unknown, dirStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.UpdateLocation(handler.GetCurrentLocation(), direction);
|
private int LogCurrentLooking(CmdResult r)
|
||||||
return "Looking " + dirStr;
|
{
|
||||||
}
|
McClient handler = CmdResult.currentHandler!;
|
||||||
else if (args.Length == 2)
|
if (!handler.GetTerrainEnabled())
|
||||||
{
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
try
|
|
||||||
{
|
|
||||||
float yaw = float.Parse(args[0], NumberStyles.Any, CultureInfo.CurrentCulture);
|
|
||||||
float pitch = float.Parse(args[1], NumberStyles.Any, CultureInfo.CurrentCulture);
|
|
||||||
|
|
||||||
handler.UpdateLocation(handler.GetCurrentLocation(), yaw, pitch);
|
const double maxDistance = 8.0;
|
||||||
return string.Format(Translations.cmd_look_at, yaw.ToString("0.00"), pitch.ToString("0.00"));
|
(bool hasBlock, Location target, Block block) = RaycastHelper.RaycastBlock(handler, maxDistance, false);
|
||||||
}
|
if (!hasBlock)
|
||||||
catch (FormatException) { return GetCmdDescTranslated(); }
|
{
|
||||||
}
|
return r.SetAndReturn(Status.Fail, string.Format(Translations.cmd_look_noinspection, maxDistance));
|
||||||
else if (args.Length == 3)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Location current = handler.GetCurrentLocation();
|
|
||||||
Location block = Location.Parse(current, args[0], args[1], args[2]);
|
|
||||||
handler.UpdateLocation(current, block);
|
|
||||||
|
|
||||||
return string.Format(Translations.cmd_look_block, block);
|
|
||||||
}
|
|
||||||
catch (FormatException) { return CmdUsage; }
|
|
||||||
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
else return Translations.extra_terrainandmovement_required;
|
else
|
||||||
|
{
|
||||||
|
Location current = handler.GetCurrentLocation(), target_center = target.ToCenter();
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_look_inspection, block.Type, target.X, target.Y, target.Z,
|
||||||
|
current.Distance(target_center), current.EyesLocation().Distance(target_center)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LookAtDirection(CmdResult r, Direction direction)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
handler.UpdateLocation(handler.GetCurrentLocation(), direction);
|
||||||
|
return r.SetAndReturn(Status.Done, "Looking " + direction.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LookAtAngle(CmdResult r, float yaw, float pitch)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
handler.UpdateLocation(handler.GetCurrentLocation(), yaw, pitch);
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_look_at, yaw.ToString("0.00"), pitch.ToString("0.00")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LookAtLocation(CmdResult r, Location location)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
Location current = handler.GetCurrentLocation();
|
||||||
|
handler.UpdateLocation(current, location);
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_look_block, location));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
using System.Linq;
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -11,107 +13,190 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "move <on|off|get|up|down|east|west|north|south|center|x y z|gravity [on|off]> [-f]"; } }
|
public override string CmdUsage { get { return "move <on|off|get|up|down|east|west|north|south|center|x y z|gravity [on|off]> [-f]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_move_desc + " \"-f\": " + Translations.cmd_move_desc_force; } }
|
public override string CmdDesc { get { return Translations.cmd_move_desc + " \"-f\": " + Translations.cmd_move_desc_force; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
List<string> args = GetArgs(command.ToLower()).ToList();
|
dispatcher.Register(l => l.Literal("help")
|
||||||
bool takeRisk = false;
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("enable")
|
||||||
|
.Executes(r => GetUsage(r.Source, "enable")))
|
||||||
|
.Then(l => l.Literal("gravity")
|
||||||
|
.Executes(r => GetUsage(r.Source, "gravity")))
|
||||||
|
.Then(l => l.Literal("direction")
|
||||||
|
.Executes(r => GetUsage(r.Source, "direction")))
|
||||||
|
.Then(l => l.Literal("center")
|
||||||
|
.Executes(r => GetUsage(r.Source, "center")))
|
||||||
|
.Then(l => l.Literal("get")
|
||||||
|
.Executes(r => GetUsage(r.Source, "get")))
|
||||||
|
.Then(l => l.Literal("location")
|
||||||
|
.Executes(r => GetUsage(r.Source, "location")))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => GetUsage(r.Source, "-f")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (args.Count < 1)
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Literal("on")
|
||||||
|
.Executes(r => SetMovementEnable(r.Source, enable: true)))
|
||||||
|
.Then(l => l.Literal("off")
|
||||||
|
.Executes(r => SetMovementEnable(r.Source, enable: false)))
|
||||||
|
.Then(l => l.Literal("gravity")
|
||||||
|
.Executes(r => SetGravityEnable(r.Source, enable: null))
|
||||||
|
.Then(l => l.Literal("on")
|
||||||
|
.Executes(r => SetGravityEnable(r.Source, enable: true)))
|
||||||
|
.Then(l => l.Literal("off")
|
||||||
|
.Executes(r => SetGravityEnable(r.Source, enable: false))))
|
||||||
|
.Then(l => l.Literal("up")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.Up, false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.Up, true))))
|
||||||
|
.Then(l => l.Literal("down")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.Down, false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.Down, true))))
|
||||||
|
.Then(l => l.Literal("east")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.East, false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.East, true))))
|
||||||
|
.Then(l => l.Literal("west")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.West, false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.West, true))))
|
||||||
|
.Then(l => l.Literal("north")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.North, false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.North, true))))
|
||||||
|
.Then(l => l.Literal("south")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.South, false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveOnDirection(r.Source, Direction.South, true))))
|
||||||
|
.Then(l => l.Literal("center")
|
||||||
|
.Executes(r => MoveToCenter(r.Source)))
|
||||||
|
.Then(l => l.Literal("get")
|
||||||
|
.Executes(r => GetCurrentLocation(r.Source)))
|
||||||
|
.Then(l => l.Argument("location", MccArguments.Location())
|
||||||
|
.Executes(r => MoveToLocation(r.Source, MccArguments.GetLocation(r, "location"), false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => MoveToLocation(r.Source, MccArguments.GetLocation(r, "location"), true))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string desc = GetCmdDescTranslated();
|
#pragma warning disable format // @formatter:off
|
||||||
|
"enable" => GetCmdDescTranslated(),
|
||||||
|
"gravity" => GetCmdDescTranslated(),
|
||||||
|
"direction" => GetCmdDescTranslated(),
|
||||||
|
"center" => GetCmdDescTranslated(),
|
||||||
|
"get" => GetCmdDescTranslated(),
|
||||||
|
"location" => GetCmdDescTranslated(),
|
||||||
|
"-f" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (handler.GetTerrainEnabled())
|
private int SetMovementEnable(CmdResult r, bool enable)
|
||||||
handler.Log.Info(World.GetChunkLoadingStatus(handler.GetWorld()));
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
return desc;
|
if (enable)
|
||||||
}
|
|
||||||
|
|
||||||
if (args.Contains("-f"))
|
|
||||||
{
|
|
||||||
takeRisk = true;
|
|
||||||
args.Remove("-f");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0] == "on")
|
|
||||||
{
|
{
|
||||||
handler.SetTerrainEnabled(true);
|
handler.SetTerrainEnabled(true);
|
||||||
return Translations.cmd_move_enable;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_move_enable);
|
||||||
}
|
}
|
||||||
else if (args[0] == "off")
|
else
|
||||||
{
|
{
|
||||||
handler.SetTerrainEnabled(false);
|
handler.SetTerrainEnabled(false);
|
||||||
return Translations.cmd_move_disable;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_move_disable);
|
||||||
}
|
}
|
||||||
else if (args[0] == "gravity")
|
}
|
||||||
|
|
||||||
|
private int SetGravityEnable(CmdResult r, bool? enable)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (enable.HasValue)
|
||||||
|
Settings.InternalConfig.GravityEnabled = enable.Value;
|
||||||
|
|
||||||
|
if (Settings.InternalConfig.GravityEnabled)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_move_gravity_enabled);
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_move_gravity_disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetCurrentLocation(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
return r.SetAndReturn(Status.Done, handler.GetCurrentLocation().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int MoveToCenter(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
Location current = handler.GetCurrentLocation();
|
||||||
|
Location currentCenter = new(Math.Floor(current.X) + 0.5, current.Y, Math.Floor(current.Z) + 0.5);
|
||||||
|
handler.MoveTo(currentCenter, allowDirectTeleport: true);
|
||||||
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_move_walk, currentCenter, current));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int MoveOnDirection(CmdResult r, Direction direction, bool takeRisk)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetTerrainEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
|
|
||||||
|
Location goal = Movement.Move(handler.GetCurrentLocation(), direction);
|
||||||
|
|
||||||
|
if (!Movement.CheckChunkLoading(handler.GetWorld(), handler.GetCurrentLocation(), goal))
|
||||||
|
return r.SetAndReturn(Status.FailChunkNotLoad, string.Format(Translations.cmd_move_chunk_not_loaded, goal.X, goal.Y, goal.Z));
|
||||||
|
|
||||||
|
if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction))
|
||||||
{
|
{
|
||||||
if (args.Count >= 2)
|
if (handler.MoveTo(goal, allowUnsafe: takeRisk))
|
||||||
Settings.InternalConfig.GravityEnabled = (args[1] == "on");
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_move_moving, direction.ToString()));
|
||||||
if (Settings.InternalConfig.GravityEnabled)
|
else
|
||||||
return Translations.cmd_move_gravity_enabled;
|
return r.SetAndReturn(Status.Fail, takeRisk ? Translations.cmd_move_dir_fail : Translations.cmd_move_suggestforce);
|
||||||
else return Translations.cmd_move_gravity_disabled;
|
|
||||||
}
|
}
|
||||||
else if (handler.GetTerrainEnabled())
|
else
|
||||||
{
|
{
|
||||||
if (args.Count == 1)
|
return r.SetAndReturn(Status.Fail, Translations.cmd_move_dir_fail);
|
||||||
{
|
}
|
||||||
Direction direction;
|
}
|
||||||
switch (args[0])
|
|
||||||
{
|
private int MoveToLocation(CmdResult r, Location goal, bool takeRisk)
|
||||||
case "up": direction = Direction.Up; break;
|
{
|
||||||
case "down": direction = Direction.Down; break;
|
McClient handler = CmdResult.currentHandler!;
|
||||||
case "east": direction = Direction.East; break;
|
if (!handler.GetTerrainEnabled())
|
||||||
case "west": direction = Direction.West; break;
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
case "north": direction = Direction.North; break;
|
|
||||||
case "south": direction = Direction.South; break;
|
Location current = handler.GetCurrentLocation(), currentCenter = current.ToCenter();
|
||||||
case "center":
|
goal.ToAbsolute(current);
|
||||||
Location current = handler.GetCurrentLocation();
|
|
||||||
Location currentCenter = new(Math.Floor(current.X) + 0.5, current.Y, Math.Floor(current.Z) + 0.5);
|
if (!Movement.CheckChunkLoading(handler.GetWorld(), current, goal))
|
||||||
handler.MoveTo(currentCenter, allowDirectTeleport: true);
|
return r.SetAndReturn(Status.FailChunkNotLoad, string.Format(Translations.cmd_move_chunk_not_loaded, goal.X, goal.Y, goal.Z));
|
||||||
return string.Format(Translations.cmd_move_walk, currentCenter, current);
|
|
||||||
case "get": return handler.GetCurrentLocation().ToString();
|
if (takeRisk || Movement.PlayerFitsHere(handler.GetWorld(), goal))
|
||||||
default: return string.Format(Translations.cmd_look_unknown, args[0]);
|
{
|
||||||
}
|
if (current.ToFloor() == goal.ToFloor())
|
||||||
|
handler.MoveTo(goal, allowDirectTeleport: true);
|
||||||
Location goal = Movement.Move(handler.GetCurrentLocation(), direction);
|
else if (!handler.MoveTo(goal, allowUnsafe: takeRisk))
|
||||||
|
return r.SetAndReturn(Status.Fail, takeRisk ? string.Format(Translations.cmd_move_fail, goal) : string.Format(Translations.cmd_move_suggestforce, goal));
|
||||||
if (!Movement.CheckChunkLoading(handler.GetWorld(), handler.GetCurrentLocation(), goal))
|
return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_move_walk, goal, current));
|
||||||
return string.Format(Translations.cmd_move_chunk_not_loaded, goal.X, goal.Y, goal.Z);
|
}
|
||||||
|
else
|
||||||
if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction))
|
{
|
||||||
{
|
return r.SetAndReturn(Status.Fail, string.Format(Translations.cmd_move_suggestforce, goal));
|
||||||
if (handler.MoveTo(goal, allowUnsafe: takeRisk))
|
|
||||||
return string.Format(Translations.cmd_move_moving, args[0]);
|
|
||||||
else
|
|
||||||
return takeRisk ? Translations.cmd_move_dir_fail : Translations.cmd_move_suggestforce;
|
|
||||||
}
|
|
||||||
else return Translations.cmd_move_dir_fail;
|
|
||||||
}
|
|
||||||
else if (args.Count == 3)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Location current = handler.GetCurrentLocation(), currentCenter = current.ToCenter();
|
|
||||||
Location goal = Location.Parse(current, args[0], args[1], args[2]);
|
|
||||||
|
|
||||||
if (!Movement.CheckChunkLoading(handler.GetWorld(), current, goal))
|
|
||||||
return string.Format(Translations.cmd_move_chunk_not_loaded, goal.X, goal.Y, goal.Z);
|
|
||||||
|
|
||||||
if (takeRisk || Movement.PlayerFitsHere(handler.GetWorld(), goal))
|
|
||||||
{
|
|
||||||
if (current.ToFloor() == goal.ToFloor())
|
|
||||||
handler.MoveTo(goal, allowDirectTeleport: true);
|
|
||||||
else if (!handler.MoveTo(goal, allowUnsafe: takeRisk))
|
|
||||||
return takeRisk ? string.Format(Translations.cmd_move_fail, goal) : string.Format(Translations.cmd_move_suggestforce, goal);
|
|
||||||
return string.Format(Translations.cmd_move_walk, goal, current);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return string.Format(Translations.cmd_move_suggestforce, goal);
|
|
||||||
}
|
|
||||||
catch (FormatException) { return GetCmdDescTranslated(); }
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
else return Translations.extra_terrainandmovement_required;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,18 +11,59 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "reco [account]"; } }
|
public override string CmdUsage { get { return "reco [account]"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_reco_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_reco_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient? handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoReconnect(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Argument("AccountNick", MccArguments.AccountNick())
|
||||||
|
.Executes(r => DoReconnect(r.Source, Arguments.GetString(r, "AccountNick"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoReconnect(CmdResult r, string account)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(account))
|
||||||
|
{
|
||||||
|
account = account.Trim();
|
||||||
|
if (!Settings.Config.Main.Advanced.SetAccount(account))
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_connect_unknown, account));
|
||||||
|
}
|
||||||
|
Program.Restart(keepAccountAndServerSettings: true);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string DoReconnect(string command)
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
string[] args = GetArgs(command);
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
if (!Settings.Config.Main.Advanced.SetAccount(args[0]))
|
string account = args[0].Trim();
|
||||||
|
if (!Settings.Config.Main.Advanced.SetAccount(account))
|
||||||
{
|
{
|
||||||
return string.Format(Translations.cmd_connect_unknown, args[0]);
|
return string.Format(Translations.cmd_connect_unknown, account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Program.Restart(keepAccountAndServerSettings: true);
|
Program.Restart(keepAccountAndServerSettings: true);
|
||||||
return "";
|
return String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,8 +10,35 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "reload"; } }
|
public override string CmdUsage { get { return "reload"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_reload_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_reload_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoReload(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoReload(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
handler.Log.Info(Translations.cmd_reload_started);
|
handler.Log.Info(Translations.cmd_reload_started);
|
||||||
handler.ReloadSettings();
|
handler.ReloadSettings();
|
||||||
handler.Log.Warn(Translations.cmd_reload_warning1);
|
handler.Log.Warn(Translations.cmd_reload_warning1);
|
||||||
|
|
@ -17,7 +46,7 @@ namespace MinecraftClient.Commands
|
||||||
handler.Log.Warn(Translations.cmd_reload_warning3);
|
handler.Log.Warn(Translations.cmd_reload_warning3);
|
||||||
handler.Log.Warn(Translations.cmd_reload_warning4);
|
handler.Log.Warn(Translations.cmd_reload_warning4);
|
||||||
|
|
||||||
return Translations.cmd_reload_finished;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_reload_finished);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,10 +10,37 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "respawn"; } }
|
public override string CmdUsage { get { return "respawn"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_respawn_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_respawn_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoRespawn(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoRespawn(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
handler.SendRespawnPacket();
|
handler.SendRespawnPacket();
|
||||||
return Translations.cmd_respawn_done;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_respawn_done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,14 +11,38 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "script <scriptname>"; } }
|
public override string CmdUsage { get { return "script <scriptname>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_script_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_script_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("Script", Arguments.GreedyString())
|
||||||
|
.Executes(r => DoExecuteScript(r.Source, Arguments.GetString(r, "Script"), null)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
handler.BotLoad(new ChatBots.Script(GetArg(command), null, localVars));
|
#pragma warning disable format // @formatter:off
|
||||||
return "";
|
_ => GetCmdDescTranslated(),
|
||||||
}
|
#pragma warning restore format // @formatter:on
|
||||||
else return GetCmdDescTranslated();
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoExecuteScript(CmdResult r, string command, Dictionary<string, object>? localVars)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
handler.BotLoad(new ChatBots.Script(command.Trim(), null, localVars));
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,14 +10,35 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "send <text>"; } }
|
public override string CmdUsage { get { return "send <text>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_send_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_send_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("any", Arguments.GreedyString())
|
||||||
|
.Executes(r => DoSendText(r.Source, Arguments.GetString(r, "any"))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
handler.SendText(GetArg(command));
|
#pragma warning disable format // @formatter:off
|
||||||
return "";
|
_ => GetCmdDescTranslated(),
|
||||||
}
|
#pragma warning restore format // @formatter:on
|
||||||
else return GetCmdDescTranslated();
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoSendText(CmdResult r, string command)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
handler.SendText(command);
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,23 +10,51 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "set varname=value"; } }
|
public override string CmdUsage { get { return "set varname=value"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_set_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_set_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("Expression", Arguments.GreedyString())
|
||||||
|
.Executes(r => DoSetVar(r.Source, Arguments.GetString(r, "Expression"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] temp = GetArg(command).Split('=');
|
#pragma warning disable format // @formatter:off
|
||||||
if (temp.Length > 1)
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoSetVar(CmdResult r, string command)
|
||||||
|
{
|
||||||
|
string[] temp = command.Trim().Split('=');
|
||||||
|
if (temp.Length > 1)
|
||||||
|
{
|
||||||
|
if (Settings.Config.AppVar.SetVar(temp[0], command[(temp[0].Length + 1)..]))
|
||||||
{
|
{
|
||||||
if (Settings.Config.AppVar.SetVar(temp[0], GetArg(command).Substring(temp[0].Length + 1)))
|
return r.SetAndReturn(CmdResult.Status.Done); //Success
|
||||||
return ""; //Success
|
|
||||||
else
|
|
||||||
return Translations.cmd_set_format;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return GetCmdDescTranslated();
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_set_format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return GetCmdDescTranslated();
|
{
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_set_format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -10,61 +13,61 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdDesc { get { return Translations.cmd_setrnd_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_setrnd_desc; } }
|
||||||
private static readonly Random rand = new();
|
private static readonly Random rand = new();
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Then(l => l.Literal("range")
|
||||||
|
.Executes(r => GetUsage(r.Source, "range")))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("VarName", Arguments.String())
|
||||||
|
.Then(l => l.Argument("Min", Arguments.Long())
|
||||||
|
.Then(l => l.Literal("to")
|
||||||
|
.Then(l => l.Argument("Max", Arguments.Long())
|
||||||
|
.Executes(r => DoSetRnd(r.Source, Arguments.GetString(r, "VarName"), Arguments.GetLong(r, "Min"), Arguments.GetLong(r, "Max"))))))
|
||||||
|
.Then(l => l.Argument("Expression", Arguments.GreedyString())
|
||||||
|
.Executes(r => DoSetRnd(r.Source, Arguments.GetString(r, "VarName"), Arguments.GetString(r, "Expression")))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] args = GetArg(command).Split(' ');
|
#pragma warning disable format // @formatter:off
|
||||||
|
"range" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (args.Length > 1)
|
private int DoSetRnd(CmdResult r, string var, string argString)
|
||||||
{
|
{
|
||||||
// detect "to" keyword in string
|
// process all arguments similar to regular terminals with quotes and escaping
|
||||||
if (args.Length == 2 && args[1].Contains("to"))
|
List<string> values = ParseCommandLine(argString);
|
||||||
{
|
|
||||||
int num1;
|
|
||||||
int num2;
|
|
||||||
|
|
||||||
// try to extract the two numbers from the string
|
// create a variable or set it to one of the values
|
||||||
try
|
if (values.Count > 0 && Settings.Config.AppVar.SetVar(var, values[rand.Next(0, values.Count)]))
|
||||||
{
|
return r.SetAndReturn(CmdResult.Status.Done, string.Format("Set %{0}% to {1}.", var, Settings.Config.AppVar.GetVar(var)));
|
||||||
num1 = Convert.ToInt32(args[1][..args[1].IndexOf('t')]);
|
else
|
||||||
num2 = Convert.ToInt32(args[1].Substring(args[1].IndexOf('o') + 1, args[1].Length - 1 - args[1].IndexOf('o')));
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_setrndstr_format);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return Translations.cmd_setrndnum_format;
|
|
||||||
}
|
|
||||||
|
|
||||||
// switch the values if they were entered in the wrong way
|
private int DoSetRnd(CmdResult r, string var, long min, long max)
|
||||||
if (num2 < num1)
|
{
|
||||||
(num2, num1) = (num1, num2);
|
// switch the values if they were entered in the wrong way
|
||||||
|
if (max < min)
|
||||||
|
(max, min) = (min, max);
|
||||||
|
|
||||||
// create a variable or set it to num1 <= varlue < num2
|
// create a variable or set it to num1 <= varlue < num2
|
||||||
if (Settings.Config.AppVar.SetVar(args[0], rand.Next(num1, num2)))
|
if (Settings.Config.AppVar.SetVar(var, rand.NextInt64(min, max)))
|
||||||
{
|
return r.SetAndReturn(CmdResult.Status.Fail, string.Format("Set %{0}% to {1}.", var, Settings.Config.AppVar.GetVar(var)));
|
||||||
return string.Format("Set %{0}% to {1}.", args[0], Settings.Config.AppVar.GetVar(args[0])); //Success
|
else
|
||||||
}
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_setrndstr_format);
|
||||||
else return Translations.cmd_setrndnum_format;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// extract all arguments of the command
|
|
||||||
string argString = command[(8 + command.Split(' ')[1].Length)..];
|
|
||||||
|
|
||||||
// process all arguments similar to regular terminals with quotes and escaping
|
|
||||||
List<string> values = ParseCommandLine(argString);
|
|
||||||
|
|
||||||
// create a variable or set it to one of the values
|
|
||||||
if (values.Count > 0 && Settings.Config.AppVar.SetVar(args[0], values[rand.Next(0, values.Count)]))
|
|
||||||
{
|
|
||||||
return string.Format("Set %{0}% to {1}.", args[0], Settings.Config.AppVar.GetVar(args[0])); //Success
|
|
||||||
}
|
|
||||||
else return Translations.cmd_setrndstr_format;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else return GetCmdDescTranslated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,64 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
public class Sneak : Command
|
public class Sneak : Command
|
||||||
{
|
{
|
||||||
private bool sneaking = false;
|
private bool sneaking = false;
|
||||||
public override string CmdName { get { return "Sneak"; } }
|
public override string CmdName { get { return "sneak"; } }
|
||||||
public override string CmdUsage { get { return "Sneak"; } }
|
public override string CmdUsage { get { return "sneak"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_sneak_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_sneak_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoSneak(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoSneak(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
if (sneaking)
|
if (sneaking)
|
||||||
{
|
{
|
||||||
var result = handler.SendEntityAction(Protocol.EntityActionType.StopSneaking);
|
var result = handler.SendEntityAction(Protocol.EntityActionType.StopSneaking);
|
||||||
if (result)
|
if (result)
|
||||||
sneaking = false;
|
sneaking = false;
|
||||||
return result ? Translations.cmd_sneak_off : Translations.general_fail;
|
if (result)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_sneak_off);
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var result = handler.SendEntityAction(Protocol.EntityActionType.StartSneaking);
|
var result = handler.SendEntityAction(Protocol.EntityActionType.StartSneaking);
|
||||||
if (result)
|
if (result)
|
||||||
sneaking = true;
|
sneaking = true;
|
||||||
return result ? Translations.cmd_sneak_on : Translations.general_fail;
|
if (result)
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_sneak_on);
|
||||||
|
else
|
||||||
|
return r.SetAndReturn(CmdResult.Status.Fail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -9,17 +11,44 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "tps"; } }
|
public override string CmdUsage { get { return "tps"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_tps_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_tps_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoLogTps(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoLogTps(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
var tps = Math.Round(handler.GetServerTPS(), 2);
|
var tps = Math.Round(handler.GetServerTPS(), 2);
|
||||||
string color;
|
string color;
|
||||||
if (tps < 10)
|
if (tps < 10)
|
||||||
color = "§c"; // Red
|
color = "§c"; // Red
|
||||||
else if (tps < 15)
|
else if (tps < 15)
|
||||||
color = "§e"; // Yellow
|
color = "§e"; // Yellow
|
||||||
else
|
else
|
||||||
color = "§a"; // Green
|
color = "§a"; // Green
|
||||||
return Translations.cmd_tps_current + ": " + color + tps;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_tps_current + ": " + color + tps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,45 +10,69 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "upgrade [-f|check|cancel|download]"; } }
|
public override string CmdUsage { get { return "upgrade [-f|check|cancel|download]"; } }
|
||||||
public override string CmdDesc { get { return string.Empty; } }
|
public override string CmdDesc { get { return string.Empty; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (HasArg(command))
|
dispatcher.Register(l => l.Literal("help")
|
||||||
{
|
.Then(l => l.Literal(CmdName)
|
||||||
string[] args = GetArgs(command);
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
return args[0] switch
|
.Then(l => l.Literal("cancel")
|
||||||
{
|
.Executes(r => GetUsage(r.Source, "cancel")))
|
||||||
"-f" => DownloadUpdate(force: true),
|
.Then(l => l.Literal("check")
|
||||||
"-force" => DownloadUpdate(force: true),
|
.Executes(r => GetUsage(r.Source, "check")))
|
||||||
"cancel" => CancelDownloadUpdate(),
|
.Then(l => l.Literal("download")
|
||||||
"check" => CheckUpdate(),
|
.Executes(r => GetUsage(r.Source, "download")))
|
||||||
"download" => DownloadUpdate(force: args.Length > 1 && (args[1] == "-f" || args[1] == "-force")),
|
)
|
||||||
_ => GetCmdDescTranslated(),
|
);
|
||||||
};
|
|
||||||
}
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
else
|
.Executes(r => DownloadUpdate(r.Source, force: false))
|
||||||
{
|
.Then(l => l.Literal("-f")
|
||||||
return DownloadUpdate(force: false);
|
.Executes(r => DownloadUpdate(r.Source, force: true)))
|
||||||
}
|
.Then(l => l.Literal("download")
|
||||||
|
.Executes(r => DownloadUpdate(r.Source, force: false))
|
||||||
|
.Then(l => l.Literal("-f")
|
||||||
|
.Executes(r => DownloadUpdate(r.Source, force: true))))
|
||||||
|
.Then(l => l.Literal("check")
|
||||||
|
.Executes(r => CheckUpdate(r.Source)))
|
||||||
|
.Then(l => l.Literal("cancel")
|
||||||
|
.Executes(r => CancelDownloadUpdate(r.Source)))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string DownloadUpdate(bool force)
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
|
{
|
||||||
|
#pragma warning disable format // @formatter:off
|
||||||
|
"cancel" => GetCmdDescTranslated(),
|
||||||
|
"check" => GetCmdDescTranslated(),
|
||||||
|
"download" => GetCmdDescTranslated(),
|
||||||
|
_ => GetCmdDescTranslated(),
|
||||||
|
#pragma warning restore format // @formatter:on
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int DownloadUpdate(CmdResult r, bool force)
|
||||||
{
|
{
|
||||||
if (UpgradeHelper.DownloadLatestBuild(force))
|
if (UpgradeHelper.DownloadLatestBuild(force))
|
||||||
return Translations.mcc_update_start;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.mcc_update_start);
|
||||||
else
|
else
|
||||||
return Translations.mcc_update_already_running;
|
return r.SetAndReturn(CmdResult.Status.Fail, Translations.mcc_update_already_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CancelDownloadUpdate()
|
private static int CancelDownloadUpdate(CmdResult r)
|
||||||
{
|
{
|
||||||
UpgradeHelper.CancelDownloadUpdate();
|
UpgradeHelper.CancelDownloadUpdate();
|
||||||
return Translations.mcc_update_cancel;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.mcc_update_cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CheckUpdate()
|
private static int CheckUpdate(CmdResult r)
|
||||||
{
|
{
|
||||||
UpgradeHelper.CheckUpdate(forceUpdate: true);
|
UpgradeHelper.CheckUpdate(forceUpdate: true);
|
||||||
return Translations.mcc_update_start;
|
return r.SetAndReturn(CmdResult.Status.Done, Translations.mcc_update_start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -8,14 +11,40 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "useitem"; } }
|
public override string CmdUsage { get { return "useitem"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_useitem_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_useitem_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (handler.GetInventoryEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
|
.Then(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Executes(r => DoUseItem(r.Source))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
handler.UseItemOnHand();
|
#pragma warning disable format // @formatter:off
|
||||||
return Translations.cmd_useitem_use;
|
_ => GetCmdDescTranslated(),
|
||||||
}
|
#pragma warning restore format // @formatter:on
|
||||||
else return Translations.extra_inventory_required;
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DoUseItem(CmdResult r)
|
||||||
|
{
|
||||||
|
McClient handler = CmdResult.currentHandler!;
|
||||||
|
if (!handler.GetInventoryEnabled())
|
||||||
|
return r.SetAndReturn(Status.FailNeedInventory);
|
||||||
|
|
||||||
|
handler.UseItemOnHand();
|
||||||
|
return r.SetAndReturn(Status.Done, Translations.cmd_useitem_use);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Builder;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
using static MinecraftClient.CommandHandler.CmdResult;
|
||||||
|
|
||||||
namespace MinecraftClient.Commands
|
namespace MinecraftClient.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -9,25 +12,44 @@ namespace MinecraftClient.Commands
|
||||||
public override string CmdUsage { get { return "useblock <x> <y> <z>"; } }
|
public override string CmdUsage { get { return "useblock <x> <y> <z>"; } }
|
||||||
public override string CmdDesc { get { return Translations.cmd_useblock_desc; } }
|
public override string CmdDesc { get { return Translations.cmd_useblock_desc; } }
|
||||||
|
|
||||||
public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
|
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
|
||||||
{
|
{
|
||||||
if (!handler.GetTerrainEnabled())
|
dispatcher.Register(l => l.Literal("help")
|
||||||
return Translations.extra_terrainandmovement_required;
|
.Then(l => l.Literal(CmdName)
|
||||||
else if (HasArg(command))
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatcher.Register(l => l.Literal(CmdName)
|
||||||
|
.Then(l => l.Argument("Location", MccArguments.Location())
|
||||||
|
.Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"))))
|
||||||
|
.Then(l => l.Literal("_help")
|
||||||
|
.Executes(r => GetUsage(r.Source, string.Empty))
|
||||||
|
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetUsage(CmdResult r, string? cmd)
|
||||||
|
{
|
||||||
|
return r.SetAndReturn(cmd switch
|
||||||
{
|
{
|
||||||
string[] args = GetArgs(command);
|
#pragma warning disable format // @formatter:off
|
||||||
if (args.Length >= 3)
|
_ => GetCmdDescTranslated(),
|
||||||
{
|
#pragma warning restore format // @formatter:on
|
||||||
Location block = Location.Parse(handler.GetCurrentLocation().ToFloor(), args[0], args[1], args[2]).ToFloor();
|
});
|
||||||
Location blockCenter = block.ToCenter();
|
}
|
||||||
bool res = handler.PlaceBlock(block, Direction.Down);
|
|
||||||
return string.Format(Translations.cmd_useblock_use, blockCenter.X, blockCenter.Y, blockCenter.Z, res ? "succeeded" : "failed");
|
private int UseBlockAtLocation(CmdResult r, Location block)
|
||||||
}
|
{
|
||||||
else
|
McClient handler = CmdResult.currentHandler!;
|
||||||
return GetCmdDescTranslated();
|
if (!handler.GetTerrainEnabled())
|
||||||
}
|
return r.SetAndReturn(Status.FailNeedTerrain);
|
||||||
else
|
|
||||||
return GetCmdDescTranslated();
|
Location current = handler.GetCurrentLocation();
|
||||||
|
block = block.ToAbsolute(current).ToFloor();
|
||||||
|
Location blockCenter = block.ToCenter();
|
||||||
|
bool res = handler.PlaceBlock(block, Direction.Down);
|
||||||
|
return r.SetAndReturn(string.Format(Translations.cmd_useblock_use, blockCenter.X, blockCenter.Y, blockCenter.Z, res ? "succeeded" : "failed"), res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using FuzzySharp;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
|
using static MinecraftClient.Settings;
|
||||||
|
|
||||||
namespace MinecraftClient
|
namespace MinecraftClient
|
||||||
{
|
{
|
||||||
|
|
@ -175,15 +183,162 @@ namespace MinecraftClient
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static void AutocompleteHandler(object? sender, ConsoleKey e)
|
internal static bool AutoCompleteDone = false;
|
||||||
|
internal static string[] AutoCompleteResult = Array.Empty<string>();
|
||||||
|
|
||||||
|
private static HashSet<string> Commands = new();
|
||||||
|
private static string[] CommandsFromAutoComplete = Array.Empty<string>();
|
||||||
|
private static string[] CommandsFromDeclareCommands = Array.Empty<string>();
|
||||||
|
|
||||||
|
private static Task _latestTask = Task.CompletedTask;
|
||||||
|
private static CancellationTokenSource? _cancellationTokenSource;
|
||||||
|
|
||||||
|
private static void MccAutocompleteHandler(ConsoleInteractive.ConsoleReader.Buffer buffer)
|
||||||
{
|
{
|
||||||
if (e != ConsoleKey.Tab) return;
|
string fullCommand = buffer.Text;
|
||||||
|
if (string.IsNullOrEmpty(fullCommand))
|
||||||
if (autocomplete_engine == null)
|
{
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.ClearSuggestions();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var buffer = ConsoleInteractive.ConsoleReader.GetBufferContent();
|
var InternalCmdChar = Config.Main.Advanced.InternalCmdChar;
|
||||||
autocomplete_engine.AutoComplete(buffer.Text[..buffer.CursorPosition]);
|
if (InternalCmdChar == MainConfigHealper.MainConfig.AdvancedConfig.InternalCmdCharType.none || fullCommand[0] == InternalCmdChar.ToChar())
|
||||||
|
{
|
||||||
|
int offset = InternalCmdChar == MainConfigHealper.MainConfig.AdvancedConfig.InternalCmdCharType.none ? 0 : 1;
|
||||||
|
if (buffer.CursorPosition - offset < 0)
|
||||||
|
{
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.ClearSuggestions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_cancellationTokenSource?.Cancel();
|
||||||
|
using var cts = new CancellationTokenSource();
|
||||||
|
_cancellationTokenSource = cts;
|
||||||
|
var previousTask = _latestTask;
|
||||||
|
var newTask = new Task(async () =>
|
||||||
|
{
|
||||||
|
string command = fullCommand[offset..];
|
||||||
|
if (command.Length == 0)
|
||||||
|
{
|
||||||
|
List<ConsoleInteractive.ConsoleSuggestion.Suggestion> sugList = new();
|
||||||
|
|
||||||
|
sugList.Add(new("/"));
|
||||||
|
|
||||||
|
var childs = McClient.dispatcher.GetRoot().Children;
|
||||||
|
if (childs != null)
|
||||||
|
foreach (var child in childs)
|
||||||
|
sugList.Add(new(child.Name));
|
||||||
|
|
||||||
|
foreach (var cmd in Commands)
|
||||||
|
sugList.Add(new(cmd));
|
||||||
|
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.UpdateSuggestions(sugList.ToArray(), new(offset, offset));
|
||||||
|
}
|
||||||
|
else if (command.Length > 0 && command[0] == '/' && !command.Contains(' '))
|
||||||
|
{
|
||||||
|
var sorted = Process.ExtractSorted(command[1..], Commands);
|
||||||
|
var sugList = new ConsoleInteractive.ConsoleSuggestion.Suggestion[sorted.Count()];
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
foreach (var sug in sorted)
|
||||||
|
sugList[index++] = new(sug.Value);
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.UpdateSuggestions(sugList, new(offset, offset + command.Length));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommandDispatcher<CmdResult>? dispatcher = McClient.dispatcher;
|
||||||
|
if (dispatcher == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ParseResults<CmdResult> parse = dispatcher.Parse(command, CmdResult.Empty);
|
||||||
|
|
||||||
|
Brigadier.NET.Suggestion.Suggestions suggestions = await dispatcher.GetCompletionSuggestions(parse, buffer.CursorPosition - offset);
|
||||||
|
|
||||||
|
int sugLen = suggestions.List.Count;
|
||||||
|
if (sugLen == 0)
|
||||||
|
{
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.ClearSuggestions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, string?> dictionary = new();
|
||||||
|
foreach (var sug in suggestions.List)
|
||||||
|
dictionary.Add(sug.Text, sug.Tooltip?.String);
|
||||||
|
|
||||||
|
var sugList = new ConsoleInteractive.ConsoleSuggestion.Suggestion[sugLen];
|
||||||
|
if (cts.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tuple<int, int> range = new(suggestions.Range.Start + offset, suggestions.Range.End + offset);
|
||||||
|
var sorted = Process.ExtractSorted(fullCommand[range.Item1..range.Item2], dictionary.Keys);
|
||||||
|
if (cts.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
foreach (var sug in sorted)
|
||||||
|
sugList[index++] = new(sug.Value, dictionary[sug.Value] ?? string.Empty);
|
||||||
|
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.UpdateSuggestions(sugList, range);
|
||||||
|
}
|
||||||
|
}, cts.Token);
|
||||||
|
_latestTask = newTask;
|
||||||
|
try { newTask.Start(); } catch { }
|
||||||
|
if (_cancellationTokenSource == cts) _cancellationTokenSource = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.ClearSuggestions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AutocompleteHandler(object? sender, ConsoleInteractive.ConsoleReader.Buffer buffer)
|
||||||
|
{
|
||||||
|
if (Settings.Config.Console.CommandSuggestion.Enable)
|
||||||
|
MccAutocompleteHandler(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CancelAutocomplete()
|
||||||
|
{
|
||||||
|
_cancellationTokenSource?.Cancel();
|
||||||
|
_latestTask = Task.CompletedTask;
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.ClearSuggestions();
|
||||||
|
|
||||||
|
AutoCompleteDone = false;
|
||||||
|
AutoCompleteResult = Array.Empty<string>();
|
||||||
|
CommandsFromAutoComplete = Array.Empty<string>();
|
||||||
|
CommandsFromDeclareCommands = Array.Empty<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MergeCommands()
|
||||||
|
{
|
||||||
|
Commands.Clear();
|
||||||
|
foreach (string cmd in CommandsFromAutoComplete)
|
||||||
|
Commands.Add('/' + cmd);
|
||||||
|
foreach (string cmd in CommandsFromDeclareCommands)
|
||||||
|
Commands.Add('/' + cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnAutoCompleteDone(int transactionId, string[] result)
|
||||||
|
{
|
||||||
|
AutoCompleteResult = result;
|
||||||
|
if (transactionId == 0)
|
||||||
|
{
|
||||||
|
CommandsFromAutoComplete = result;
|
||||||
|
MergeCommands();
|
||||||
|
}
|
||||||
|
AutoCompleteDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnDeclareMinecraftCommand(string[] rootCommands)
|
||||||
|
{
|
||||||
|
CommandsFromDeclareCommands = rootCommands;
|
||||||
|
MergeCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitCommandList(CommandDispatcher<CmdResult> dispatcher)
|
||||||
|
{
|
||||||
|
autocomplete_engine!.AutoComplete("/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,6 +353,6 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="BehindCursor">Text behind the cursor, e.g. "my input comm"</param>
|
/// <param name="BehindCursor">Text behind the cursor, e.g. "my input comm"</param>
|
||||||
/// <returns>List of auto-complete words, e.g. ["command", "comment"]</returns>
|
/// <returns>List of auto-complete words, e.g. ["command", "comment"]</returns>
|
||||||
IEnumerable<string> AutoComplete(string BehindCursor);
|
int AutoComplete(string BehindCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace MinecraftClient.Crypto
|
||||||
{
|
{
|
||||||
public class AesCfb8Stream : Stream
|
public class AesCfb8Stream : Stream
|
||||||
{
|
{
|
||||||
public static readonly int blockSize = 16;
|
public const int blockSize = 16;
|
||||||
|
|
||||||
private readonly Aes? Aes = null;
|
private readonly Aes? Aes = null;
|
||||||
private readonly FastAes? FastAes = null;
|
private readonly FastAes? FastAes = null;
|
||||||
|
|
@ -109,7 +109,7 @@ namespace MinecraftClient.Crypto
|
||||||
if (inStreamEnded)
|
if (inStreamEnded)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Span<byte> blockOutput = FastAes != null ? stackalloc byte[blockSize] : null;
|
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||||
|
|
||||||
byte[] inputBuf = new byte[blockSize + required];
|
byte[] inputBuf = new byte[blockSize + required];
|
||||||
Array.Copy(ReadStreamIV, inputBuf, blockSize);
|
Array.Copy(ReadStreamIV, inputBuf, blockSize);
|
||||||
|
|
@ -135,18 +135,12 @@ namespace MinecraftClient.Crypto
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OrderablePartitioner<Tuple<int, int>> rangePartitioner = curRead <= 256 ?
|
for (int idx = readed; idx < processEnd; idx++)
|
||||||
Partitioner.Create(readed, processEnd, 32) : Partitioner.Create(readed, processEnd);
|
|
||||||
Parallel.ForEach(rangePartitioner, (range, loopState) =>
|
|
||||||
{
|
{
|
||||||
Span<byte> blockOutput = stackalloc byte[blockSize];
|
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||||
for (int idx = range.Item1; idx < range.Item2; idx++)
|
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
||||||
{
|
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||||
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
}
|
||||||
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
|
||||||
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MinecraftClient.Protocol.Handlers;
|
using MinecraftClient.Protocol.Handlers;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
namespace MinecraftClient.Inventory
|
namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
|
|
@ -158,7 +159,7 @@ namespace MinecraftClient.Inventory
|
||||||
|
|
||||||
public static string GetEnchantmentName(Enchantment enchantment)
|
public static string GetEnchantmentName(Enchantment enchantment)
|
||||||
{
|
{
|
||||||
string? trans = Protocol.ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase());
|
string? trans = ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase());
|
||||||
if (string.IsNullOrEmpty(trans))
|
if (string.IsNullOrEmpty(trans))
|
||||||
return "Unknown Enchantment with ID: " + ((short)enchantment) + " (Probably not named in the code yet)";
|
return "Unknown Enchantment with ID: " + ((short)enchantment) + " (Probably not named in the code yet)";
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
namespace MinecraftClient.Inventory
|
namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
|
|
@ -64,7 +65,7 @@ namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
string? displayName = displayProperties["Name"] as string;
|
string? displayName = displayProperties["Name"] as string;
|
||||||
if (!String.IsNullOrEmpty(displayName))
|
if (!String.IsNullOrEmpty(displayName))
|
||||||
return MinecraftClient.Protocol.ChatParser.ParseText(displayProperties["Name"].ToString() ?? string.Empty);
|
return ChatParser.ParseText(displayProperties["Name"].ToString() ?? string.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -85,7 +86,7 @@ namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
object[] displayName = (object[])displayProperties["Lore"];
|
object[] displayName = (object[])displayProperties["Lore"];
|
||||||
lores.AddRange(from string st in displayName
|
lores.AddRange(from string st in displayName
|
||||||
let str = MinecraftClient.Protocol.ChatParser.ParseText(st.ToString())
|
let str = ChatParser.ParseText(st.ToString())
|
||||||
select str);
|
select str);
|
||||||
return lores.ToArray();
|
return lores.ToArray();
|
||||||
}
|
}
|
||||||
|
|
@ -117,10 +118,10 @@ namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
string type_str = type.ToString();
|
string type_str = type.ToString();
|
||||||
string type_renamed = type_str.ToUnderscoreCase();
|
string type_renamed = type_str.ToUnderscoreCase();
|
||||||
string? res1 = Protocol.ChatParser.TranslateString("item.minecraft." + type_renamed);
|
string? res1 = ChatParser.TranslateString("item.minecraft." + type_renamed);
|
||||||
if (!string.IsNullOrEmpty(res1))
|
if (!string.IsNullOrEmpty(res1))
|
||||||
return res1;
|
return res1;
|
||||||
string? res2 = Protocol.ChatParser.TranslateString("block.minecraft." + type_renamed);
|
string? res2 = ChatParser.TranslateString("block.minecraft." + type_renamed);
|
||||||
if (!string.IsNullOrEmpty(res2))
|
if (!string.IsNullOrEmpty(res2))
|
||||||
return res2;
|
return res2;
|
||||||
return type_str;
|
return type_str;
|
||||||
|
|
@ -145,8 +146,8 @@ namespace MinecraftClient.Inventory
|
||||||
short level = (short)enchantment["lvl"];
|
short level = (short)enchantment["lvl"];
|
||||||
string id = ((string)enchantment["id"]).Replace(':', '.');
|
string id = ((string)enchantment["id"]).Replace(':', '.');
|
||||||
sb.AppendFormat(" | {0} {1}",
|
sb.AppendFormat(" | {0} {1}",
|
||||||
Protocol.ChatParser.TranslateString("enchantment." + id) ?? id,
|
ChatParser.TranslateString("enchantment." + id) ?? id,
|
||||||
Protocol.ChatParser.TranslateString("enchantment.level." + level) ?? level.ToString());
|
ChatParser.TranslateString("enchantment.level." + level) ?? level.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
|
|
||||||
namespace MinecraftClient.Inventory
|
namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace MinecraftClient.Mapping
|
namespace MinecraftClient.Inventory
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Properties of a villager
|
/// Properties of a villager
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ namespace MinecraftClient
|
||||||
&& IsHex(toparse[cursorpos + 5]))
|
&& IsHex(toparse[cursorpos + 5]))
|
||||||
{
|
{
|
||||||
//"abc\u0123abc" => "0123" => 0123 => Unicode char n°0123 => Add char to string
|
//"abc\u0123abc" => "0123" => 0123 => Unicode char n°0123 => Add char to string
|
||||||
data.StringValue += char.ConvertFromUtf32(int.Parse(toparse.Substring(cursorpos + 2, 4),
|
data.StringValue += char.ConvertFromUtf32(int.Parse(toparse.Substring(cursorpos + 2, 4),
|
||||||
System.Globalization.NumberStyles.HexNumber));
|
System.Globalization.NumberStyles.HexNumber));
|
||||||
cursorpos += 6; continue;
|
cursorpos += 6; continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
|
|
||||||
namespace MinecraftClient.Logger
|
namespace MinecraftClient.Logger
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using MinecraftClient.Mapping.BlockPalettes;
|
using MinecraftClient.Mapping.BlockPalettes;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
namespace MinecraftClient.Mapping
|
namespace MinecraftClient.Mapping
|
||||||
{
|
{
|
||||||
|
|
@ -115,7 +116,7 @@ namespace MinecraftClient.Mapping
|
||||||
public string GetTypeString()
|
public string GetTypeString()
|
||||||
{
|
{
|
||||||
string typeStr = Type.ToString();
|
string typeStr = Type.ToString();
|
||||||
string? trans = Protocol.ChatParser.TranslateString("block.minecraft." + typeStr.ToUnderscoreCase());
|
string? trans = ChatParser.TranslateString("block.minecraft." + typeStr.ToUnderscoreCase());
|
||||||
return string.IsNullOrEmpty(trans) ? typeStr : trans;
|
return string.IsNullOrEmpty(trans) ? typeStr : trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,9 @@ namespace MinecraftClient.Mapping
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var monsterSpawnLightLevelObj = nbt["monster_spawn_light_level"];
|
var monsterSpawnLightLevelObj = nbt["monster_spawn_light_level"];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
monsterSpawnMinLightLevel = monsterSpawnMaxLightLevel = Convert.ToInt32(monsterSpawnLightLevelObj);
|
monsterSpawnMinLightLevel = monsterSpawnMaxLightLevel = Convert.ToInt32(monsterSpawnLightLevelObj);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
|
using MinecraftClient.Protocol.Message;
|
||||||
|
|
||||||
namespace MinecraftClient.Mapping
|
namespace MinecraftClient.Mapping
|
||||||
{
|
{
|
||||||
|
|
@ -155,11 +156,16 @@ namespace MinecraftClient.Mapping
|
||||||
Pitch = pitch * (1F / 256) * 360;
|
Pitch = pitch * (1F / 256) * 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetTypeString(EntityType type)
|
||||||
|
{
|
||||||
|
string typeStr = type.ToString();
|
||||||
|
string? trans = ChatParser.TranslateString("entity.minecraft." + typeStr.ToUnderscoreCase());
|
||||||
|
return string.IsNullOrEmpty(trans) ? typeStr : trans;
|
||||||
|
}
|
||||||
|
|
||||||
public string GetTypeString()
|
public string GetTypeString()
|
||||||
{
|
{
|
||||||
string typeStr = Type.ToString();
|
return GetTypeString(Type);
|
||||||
string? trans = Protocol.ChatParser.TranslateString("entity.minecraft." + typeStr.ToUnderscoreCase());
|
|
||||||
return string.IsNullOrEmpty(trans) ? typeStr : trans;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,15 @@ namespace MinecraftClient.Mapping
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double Z;
|
public double Z;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies whether the coordinates are absolute or relative.
|
||||||
|
/// true for relative coordinates, false for absolute coordinates.
|
||||||
|
/// X-axis: ((Status & (1 << 0)) > 0)
|
||||||
|
/// Y-axis: ((Status & (1 << 1)) > 0)
|
||||||
|
/// Z-axis: ((Status & (1 << 2)) > 0)
|
||||||
|
/// </summary>
|
||||||
|
public byte Status;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new location
|
/// Create a new location
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -34,6 +43,18 @@ namespace MinecraftClient.Mapping
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
Z = z;
|
Z = z;
|
||||||
|
Status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new location
|
||||||
|
/// </summary>
|
||||||
|
public Location(double x, double y, double z, byte status)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
Status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -44,6 +65,7 @@ namespace MinecraftClient.Mapping
|
||||||
X = loc.X;
|
X = loc.X;
|
||||||
Y = loc.Y;
|
Y = loc.Y;
|
||||||
Z = loc.Z;
|
Z = loc.Z;
|
||||||
|
Status = loc.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -60,6 +82,19 @@ namespace MinecraftClient.Mapping
|
||||||
X = chunkX * Chunk.SizeX + blockX;
|
X = chunkX * Chunk.SizeX + blockX;
|
||||||
Y = blockY;
|
Y = blockY;
|
||||||
Z = chunkZ * Chunk.SizeZ + blockZ;
|
Z = chunkZ * Chunk.SizeZ + blockZ;
|
||||||
|
Status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location ToAbsolute(Location based)
|
||||||
|
{
|
||||||
|
if ((Status & (1 << 0)) > 0)
|
||||||
|
X += based.X;
|
||||||
|
if ((Status & (1 << 1)) > 0)
|
||||||
|
Y += based.Y;
|
||||||
|
if ((Status & (1 << 2)) > 0)
|
||||||
|
Z += based.Z;
|
||||||
|
Status = 0;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ namespace MinecraftClient.Mapping
|
||||||
{
|
{
|
||||||
if (start == end)
|
if (start == end)
|
||||||
return new(false, Location.Zero, Block.Air);
|
return new(false, Location.Zero, Block.Air);
|
||||||
|
|
||||||
double start_x = MathHelper.Lerp(-1.0E-7, start.X, end.X);
|
double start_x = MathHelper.Lerp(-1.0E-7, start.X, end.X);
|
||||||
double start_y = MathHelper.Lerp(-1.0E-7, start.Y, end.Y);
|
double start_y = MathHelper.Lerp(-1.0E-7, start.Y, end.Y);
|
||||||
double start_z = MathHelper.Lerp(-1.0E-7, start.Z, end.Z);
|
double start_z = MathHelper.Lerp(-1.0E-7, start.Z, end.Z);
|
||||||
|
|
@ -87,7 +87,7 @@ namespace MinecraftClient.Mapping
|
||||||
res_location.Z += dz_sign;
|
res_location.Z += dz_sign;
|
||||||
z_frac += z_step;
|
z_frac += z_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
block = CheckRaycastResult(world, res_location, includeFluids);
|
block = CheckRaycastResult(world, res_location, includeFluids);
|
||||||
if (block.Type != Material.Air)
|
if (block.Type != Material.Air)
|
||||||
return new(true, res_location, block);
|
return new(true, res_location, block);
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ namespace MinecraftClient.Mapping
|
||||||
/// <param name="block">Block type</param>
|
/// <param name="block">Block type</param>
|
||||||
/// <param name="radius">Search radius - larger is slower: O^3 complexity</param>
|
/// <param name="radius">Search radius - larger is slower: O^3 complexity</param>
|
||||||
/// <returns>Block matching the specified block type</returns>
|
/// <returns>Block matching the specified block type</returns>
|
||||||
public List<Location> FindBlock(Location from, Material block, int radius)
|
public List<Location> FindBlock(Location from, Material block, double radius)
|
||||||
{
|
{
|
||||||
return FindBlock(from, block, radius, radius, radius);
|
return FindBlock(from, block, radius, radius, radius);
|
||||||
}
|
}
|
||||||
|
|
@ -167,7 +167,7 @@ namespace MinecraftClient.Mapping
|
||||||
/// <param name="radiusy">Search radius on the Y axis</param>
|
/// <param name="radiusy">Search radius on the Y axis</param>
|
||||||
/// <param name="radiusz">Search radius on the Z axis</param>
|
/// <param name="radiusz">Search radius on the Z axis</param>
|
||||||
/// <returns>Block matching the specified block type</returns>
|
/// <returns>Block matching the specified block type</returns>
|
||||||
public List<Location> FindBlock(Location from, Material block, int radiusx, int radiusy, int radiusz)
|
public List<Location> FindBlock(Location from, Material block, double radiusx, double radiusy, double radiusz)
|
||||||
{
|
{
|
||||||
Location minPoint = new Location(from.X - radiusx, from.Y - radiusy, from.Z - radiusz);
|
Location minPoint = new Location(from.X - radiusx, from.Y - radiusy, from.Z - radiusz);
|
||||||
Location maxPoint = new Location(from.X + radiusx, from.Y + radiusy, from.Z + radiusz);
|
Location maxPoint = new Location(from.X + radiusx, from.Y + radiusy, from.Z + radiusz);
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,22 @@ using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Brigadier.NET;
|
||||||
|
using Brigadier.NET.Exceptions;
|
||||||
using MinecraftClient.ChatBots;
|
using MinecraftClient.ChatBots;
|
||||||
|
using MinecraftClient.CommandHandler;
|
||||||
|
using MinecraftClient.CommandHandler.Patch;
|
||||||
using MinecraftClient.Inventory;
|
using MinecraftClient.Inventory;
|
||||||
using MinecraftClient.Logger;
|
using MinecraftClient.Logger;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
using MinecraftClient.Protocol;
|
using MinecraftClient.Protocol;
|
||||||
using MinecraftClient.Protocol.Handlers;
|
using MinecraftClient.Protocol.Handlers;
|
||||||
using MinecraftClient.Protocol.Handlers.Forge;
|
using MinecraftClient.Protocol.Handlers.Forge;
|
||||||
using MinecraftClient.Protocol.Keys;
|
|
||||||
using MinecraftClient.Protocol.Message;
|
using MinecraftClient.Protocol.Message;
|
||||||
|
using MinecraftClient.Protocol.ProfileKey;
|
||||||
using MinecraftClient.Protocol.Session;
|
using MinecraftClient.Protocol.Session;
|
||||||
using MinecraftClient.Proxy;
|
using MinecraftClient.Proxy;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using static MinecraftClient.Settings;
|
using static MinecraftClient.Settings;
|
||||||
|
|
||||||
namespace MinecraftClient
|
namespace MinecraftClient
|
||||||
|
|
@ -26,8 +31,7 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
public static int ReconnectionAttemptsLeft = 0;
|
public static int ReconnectionAttemptsLeft = 0;
|
||||||
|
|
||||||
private static readonly List<string> cmd_names = new();
|
public static CommandDispatcher<CmdResult> dispatcher = new();
|
||||||
private static readonly Dictionary<string, Command> cmds = new();
|
|
||||||
private readonly Dictionary<Guid, PlayerInfo> onlinePlayers = new();
|
private readonly Dictionary<Guid, PlayerInfo> onlinePlayers = new();
|
||||||
|
|
||||||
private static bool commandsLoaded = false;
|
private static bool commandsLoaded = false;
|
||||||
|
|
@ -148,6 +152,7 @@ namespace MinecraftClient
|
||||||
/// <param name="forgeInfo">ForgeInfo item stating that Forge is enabled</param>
|
/// <param name="forgeInfo">ForgeInfo item stating that Forge is enabled</param>
|
||||||
public McClient(SessionToken session, PlayerKeyPair? playerKeyPair, string server_ip, ushort port, int protocolversion, ForgeInfo? forgeInfo)
|
public McClient(SessionToken session, PlayerKeyPair? playerKeyPair, string server_ip, ushort port, int protocolversion, ForgeInfo? forgeInfo)
|
||||||
{
|
{
|
||||||
|
CmdResult.currentHandler = this;
|
||||||
terrainAndMovementsEnabled = Config.Main.Advanced.TerrainAndMovements;
|
terrainAndMovementsEnabled = Config.Main.Advanced.TerrainAndMovements;
|
||||||
inventoryHandlingEnabled = Config.Main.Advanced.InventoryHandling;
|
inventoryHandlingEnabled = Config.Main.Advanced.InventoryHandling;
|
||||||
entityHandlingEnabled = Config.Main.Advanced.EntityHandling;
|
entityHandlingEnabled = Config.Main.Advanced.EntityHandling;
|
||||||
|
|
@ -200,9 +205,9 @@ namespace MinecraftClient
|
||||||
Log.Info(string.Format(Translations.mcc_joined, Config.Main.Advanced.InternalCmdChar.ToLogString()));
|
Log.Info(string.Format(Translations.mcc_joined, Config.Main.Advanced.InternalCmdChar.ToLogString()));
|
||||||
|
|
||||||
cmdprompt = new CancellationTokenSource();
|
cmdprompt = new CancellationTokenSource();
|
||||||
ConsoleInteractive.ConsoleReader.BeginReadThread(cmdprompt);
|
ConsoleInteractive.ConsoleReader.BeginReadThread();
|
||||||
ConsoleInteractive.ConsoleReader.MessageReceived += ConsoleReaderOnMessageReceived;
|
ConsoleInteractive.ConsoleReader.MessageReceived += ConsoleReaderOnMessageReceived;
|
||||||
ConsoleInteractive.ConsoleReader.OnKeyInput += ConsoleIO.AutocompleteHandler;
|
ConsoleInteractive.ConsoleReader.OnInputChange += ConsoleIO.AutocompleteHandler;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -226,7 +231,7 @@ namespace MinecraftClient
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Retry:
|
Retry:
|
||||||
if (timeoutdetector != null)
|
if (timeoutdetector != null)
|
||||||
{
|
{
|
||||||
timeoutdetector.Item2.Cancel();
|
timeoutdetector.Item2.Cancel();
|
||||||
|
|
@ -243,7 +248,7 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
ConsoleInteractive.ConsoleReader.StopReadThread();
|
ConsoleInteractive.ConsoleReader.StopReadThread();
|
||||||
ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived;
|
ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived;
|
||||||
ConsoleInteractive.ConsoleReader.OnKeyInput -= ConsoleIO.AutocompleteHandler;
|
ConsoleInteractive.ConsoleReader.OnInputChange -= ConsoleIO.AutocompleteHandler;
|
||||||
Program.HandleFailure();
|
Program.HandleFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -455,6 +460,8 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OnConnectionLost(ChatBot.DisconnectReason reason, string message)
|
public void OnConnectionLost(ChatBot.DisconnectReason reason, string message)
|
||||||
{
|
{
|
||||||
|
ConsoleIO.CancelAutocomplete();
|
||||||
|
|
||||||
handler.Dispose();
|
handler.Dispose();
|
||||||
|
|
||||||
world.Clear();
|
world.Clear();
|
||||||
|
|
@ -513,7 +520,7 @@ namespace MinecraftClient
|
||||||
{
|
{
|
||||||
ConsoleInteractive.ConsoleReader.StopReadThread();
|
ConsoleInteractive.ConsoleReader.StopReadThread();
|
||||||
ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived;
|
ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived;
|
||||||
ConsoleInteractive.ConsoleReader.OnKeyInput -= ConsoleIO.AutocompleteHandler;
|
ConsoleInteractive.ConsoleReader.OnInputChange -= ConsoleIO.AutocompleteHandler;
|
||||||
Program.HandleFailure();
|
Program.HandleFailure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -552,7 +559,9 @@ namespace MinecraftClient
|
||||||
switch (command[0].ToLower())
|
switch (command[0].ToLower())
|
||||||
{
|
{
|
||||||
case "autocomplete":
|
case "autocomplete":
|
||||||
if (command.Length > 1) { ConsoleIO.WriteLine((char)0x00 + "autocomplete" + (char)0x00 + handler.AutoComplete(command[1])); }
|
int id = handler.AutoComplete(command[1]);
|
||||||
|
while (!ConsoleIO.AutoCompleteDone) { Thread.Sleep(100); }
|
||||||
|
if (command.Length > 1) { ConsoleIO.WriteLine((char)0x00 + "autocomplete" + (char)0x00 + ConsoleIO.AutoCompleteResult); }
|
||||||
else ConsoleIO.WriteLine((char)0x00 + "autocomplete" + (char)0x00);
|
else ConsoleIO.WriteLine((char)0x00 + "autocomplete" + (char)0x00);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -560,68 +569,44 @@ namespace MinecraftClient
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text = text.Trim();
|
text = text.Trim();
|
||||||
if (text.Length > 0)
|
|
||||||
|
if (text.Length > 1
|
||||||
|
&& Config.Main.Advanced.InternalCmdChar == MainConfigHealper.MainConfig.AdvancedConfig.InternalCmdCharType.none
|
||||||
|
&& text[0] == '/')
|
||||||
{
|
{
|
||||||
if (Config.Main.Advanced.InternalCmdChar.ToChar() == ' ' || text[0] == Config.Main.Advanced.InternalCmdChar.ToChar())
|
SendText(text);
|
||||||
|
}
|
||||||
|
else if (text.Length > 2
|
||||||
|
&& Config.Main.Advanced.InternalCmdChar != MainConfigHealper.MainConfig.AdvancedConfig.InternalCmdCharType.none
|
||||||
|
&& text[0] == Config.Main.Advanced.InternalCmdChar.ToChar()
|
||||||
|
&& text[1] == '/')
|
||||||
|
{
|
||||||
|
SendText(text[1..]);
|
||||||
|
}
|
||||||
|
else if (text.Length > 0)
|
||||||
|
{
|
||||||
|
if (Config.Main.Advanced.InternalCmdChar == MainConfigHealper.MainConfig.AdvancedConfig.InternalCmdCharType.none
|
||||||
|
|| text[0] == Config.Main.Advanced.InternalCmdChar.ToChar())
|
||||||
{
|
{
|
||||||
string? response_msg = "";
|
CmdResult result = new();
|
||||||
string command = Config.Main.Advanced.InternalCmdChar.ToChar() == ' ' ? text : text[1..];
|
string command = Config.Main.Advanced.InternalCmdChar.ToChar() == ' ' ? text : text[1..];
|
||||||
if (!PerformInternalCommand(Config.AppVar.ExpandVars(command), ref response_msg, Settings.Config.AppVar.GetVariables()) && Config.Main.Advanced.InternalCmdChar.ToChar() == '/')
|
if (!PerformInternalCommand(Config.AppVar.ExpandVars(command), ref result, Settings.Config.AppVar.GetVariables()) && Config.Main.Advanced.InternalCmdChar.ToChar() == '/')
|
||||||
{
|
{
|
||||||
SendText(text);
|
SendText(text);
|
||||||
}
|
}
|
||||||
else if (!String.IsNullOrEmpty(response_msg))
|
else if (result.status != CmdResult.Status.NotRun && (result.status != CmdResult.Status.Done || !string.IsNullOrWhiteSpace(result.result)))
|
||||||
{
|
{
|
||||||
Log.Info(response_msg);
|
Log.Info(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else SendText(text);
|
else
|
||||||
|
{
|
||||||
|
SendText(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register a custom console command
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cmdName">Name of the command</param>
|
|
||||||
/// <param name="cmdDesc">Description/usage of the command</param>
|
|
||||||
/// <param name="callback">Method for handling the command</param>
|
|
||||||
/// <returns>True if successfully registered</returns>
|
|
||||||
public bool RegisterCommand(string cmdName, string cmdDesc, string cmdUsage, ChatBot.CommandRunner callback)
|
|
||||||
{
|
|
||||||
if (cmds.ContainsKey(cmdName.ToLower()))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Command cmd = new ChatBot.ChatBotCommand(cmdName, cmdDesc, cmdUsage, callback);
|
|
||||||
cmds.Add(cmdName.ToLower(), cmd);
|
|
||||||
cmd_names.Add(cmdName.ToLower());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unregister a console command
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// There is no check for the command is registered by above method or is embedded command.
|
|
||||||
/// Which mean this can unload any command
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="cmdName">The name of command to be unregistered</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool UnregisterCommand(string cmdName)
|
|
||||||
{
|
|
||||||
if (cmds.ContainsKey(cmdName.ToLower()))
|
|
||||||
{
|
|
||||||
cmds.Remove(cmdName.ToLower());
|
|
||||||
cmd_names.Remove(cmdName.ToLower());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -629,37 +614,29 @@ namespace MinecraftClient
|
||||||
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
||||||
/// <param name="localVars">Local variables passed along with the command</param>
|
/// <param name="localVars">Local variables passed along with the command</param>
|
||||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||||
public bool PerformInternalCommand(string command, ref string? response_msg, Dictionary<string, object>? localVars = null)
|
public bool PerformInternalCommand(string command, ref CmdResult result, Dictionary<string, object>? localVars = null)
|
||||||
{
|
{
|
||||||
/* Process the provided command */
|
/* Process the provided command */
|
||||||
|
ParseResults<CmdResult> parse;
|
||||||
string command_name = command.Split(' ')[0].ToLower();
|
try
|
||||||
if (command_name == "help")
|
|
||||||
{
|
{
|
||||||
if (Command.HasArg(command))
|
parse = dispatcher.Parse(command, result);
|
||||||
{
|
|
||||||
string help_cmdname = Command.GetArgs(command)[0].ToLower();
|
|
||||||
if (help_cmdname == "help")
|
|
||||||
{
|
|
||||||
response_msg = Translations.icmd_help;
|
|
||||||
}
|
|
||||||
else if (cmds.ContainsKey(help_cmdname))
|
|
||||||
{
|
|
||||||
response_msg = cmds[help_cmdname].GetCmdDescTranslated();
|
|
||||||
}
|
|
||||||
else response_msg = string.Format(Translations.icmd_unknown, command_name);
|
|
||||||
}
|
|
||||||
else response_msg = string.Format(Translations.icmd_list, String.Join(", ", cmd_names.ToArray()), Config.Main.Advanced.InternalCmdChar.ToChar());
|
|
||||||
}
|
}
|
||||||
else if (cmds.ContainsKey(command_name))
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
response_msg = cmds[command_name].Run(this, command, localVars);
|
Log.Debug("Parse fail: " + e.GetFullMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dispatcher.Execute(parse);
|
||||||
|
|
||||||
foreach (ChatBot bot in bots.ToArray())
|
foreach (ChatBot bot in bots.ToArray())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bot.OnInternalCommand(command_name, string.Join(" ", Command.GetArgs(command)), response_msg);
|
bot.OnInternalCommand(command, string.Join(" ", Command.GetArgs(command)), result);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -670,14 +647,22 @@ namespace MinecraftClient
|
||||||
else throw; //ThreadAbortException should not be caught
|
else throw; //ThreadAbortException should not be caught
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response_msg = string.Format(Translations.icmd_unknown, command_name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
catch (CommandSyntaxException e)
|
||||||
|
{
|
||||||
|
if (parse.Context.Nodes.Count == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Info("§e" + e.Message ?? e.StackTrace ?? "Incorrect argument.");
|
||||||
|
Log.Info(dispatcher.GetAllUsageString(parse.Context.Nodes[0].Node.Name, false));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadCommands()
|
public void LoadCommands()
|
||||||
|
|
@ -694,10 +679,7 @@ namespace MinecraftClient
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Command cmd = (Command)Activator.CreateInstance(type)!;
|
Command cmd = (Command)Activator.CreateInstance(type)!;
|
||||||
cmds[Settings.ToLowerIfNeed(cmd.CmdName)] = cmd;
|
cmd.RegisterCommand(dispatcher);
|
||||||
cmd_names.Add(Settings.ToLowerIfNeed(cmd.CmdName));
|
|
||||||
foreach (string alias in cmd.GetCMDAliases())
|
|
||||||
cmds[Settings.ToLowerIfNeed(alias)] = cmd;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -849,7 +831,8 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
b.OnUnload();
|
b.OnUnload();
|
||||||
bots.RemoveAll(item => object.ReferenceEquals(item, b));
|
|
||||||
|
bots.RemoveAll(item => ReferenceEquals(item, b));
|
||||||
|
|
||||||
// ToList is needed to avoid an InvalidOperationException from modfiying the list while it's being iterated upon.
|
// ToList is needed to avoid an InvalidOperationException from modfiying the list while it's being iterated upon.
|
||||||
var botRegistrations = registeredBotPluginChannels.Where(entry => entry.Value.Contains(b)).ToList();
|
var botRegistrations = registeredBotPluginChannels.Where(entry => entry.Value.Contains(b)).ToList();
|
||||||
|
|
@ -1069,9 +1052,10 @@ namespace MinecraftClient
|
||||||
if (InvokeRequired)
|
if (InvokeRequired)
|
||||||
return InvokeOnMainThread(() => GetInventory(inventoryID));
|
return InvokeOnMainThread(() => GetInventory(inventoryID));
|
||||||
|
|
||||||
if (inventories.ContainsKey(inventoryID))
|
if (inventories.TryGetValue(inventoryID, out Container? inv))
|
||||||
return inventories[inventoryID];
|
return inv;
|
||||||
return null;
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -2427,6 +2411,8 @@ namespace MinecraftClient
|
||||||
ClearInventories();
|
ClearInventories();
|
||||||
|
|
||||||
DispatchBotEvent(bot => bot.AfterGameJoined());
|
DispatchBotEvent(bot => bot.AfterGameJoined());
|
||||||
|
|
||||||
|
ConsoleIO.InitCommandList(dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -3449,6 +3435,16 @@ namespace MinecraftClient
|
||||||
DispatchBotEvent(bot => bot.OnBlockChange(location, block));
|
DispatchBotEvent(bot => bot.OnBlockChange(location, block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when "AutoComplete" completes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transactionId">The number of this result.</param>
|
||||||
|
/// <param name="result">All commands.</param>
|
||||||
|
public void OnAutoCompleteDone(int transactionId, string[] result)
|
||||||
|
{
|
||||||
|
ConsoleIO.OnAutoCompleteDone(transactionId, result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send a click container button packet to the server.
|
/// Send a click container button packet to the server.
|
||||||
/// Used for Enchanting table, Lectern, stone cutter and loom
|
/// Used for Enchanting table, Lectern, stone cutter and loom
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
|
|
@ -27,21 +27,23 @@
|
||||||
<Content Include="Resources\AppIcon.ico" />
|
<Content Include="Resources\AppIcon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DnsClient" Version="1.6.1" />
|
<PackageReference Include="Brigadier.NET" Version="1.2.13" />
|
||||||
|
<PackageReference Include="DnsClient" Version="1.7.0" />
|
||||||
<PackageReference Include="DotNetZip" Version="1.16.0" />
|
<PackageReference Include="DotNetZip" Version="1.16.0" />
|
||||||
<PackageReference Include="DSharpPlus" Version="4.2.0" />
|
<PackageReference Include="DSharpPlus" Version="4.2.0" />
|
||||||
<PackageReference Include="DynamicExpresso.Core" Version="2.13.0" />
|
<PackageReference Include="DynamicExpresso.Core" Version="2.13.0" />
|
||||||
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="12.2.0" />
|
<PackageReference Include="FuzzySharp" Version="2.0.2" />
|
||||||
|
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="12.2.1" />
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
|
||||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
|
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" />
|
|
||||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||||
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Windows.Compatibility" Version="7.0.0" />
|
||||||
<PackageReference Include="Samboy063.Tomlet" Version="5.0.1" />
|
<PackageReference Include="Samboy063.Tomlet" Version="5.0.1" />
|
||||||
<PackageReference Include="SingleFileExtractor.Core" Version="1.0.1" />
|
<PackageReference Include="SingleFileExtractor.Core" Version="1.0.1" />
|
||||||
<PackageReference Include="starksoft.aspen" Version="1.1.8">
|
<PackageReference Include="starksoft.aspen" Version="1.1.8">
|
||||||
<NoWarn>NU1701</NoWarn>
|
<NoWarn>NU1701</NoWarn>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
|
||||||
<PackageReference Include="Telegram.Bot" Version="18.0.0" />
|
<PackageReference Include="Telegram.Bot" Version="18.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -83,6 +85,11 @@
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DependentUpon>ConfigComments.resx</DependentUpon>
|
<DependentUpon>ConfigComments.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Update="Resources\MinecraftAssets.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>MinecraftAssets.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Update="Resources\Translations\Translations.Designer.cs">
|
<Compile Update="Resources\Translations\Translations.Designer.cs">
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
@ -100,6 +107,11 @@
|
||||||
<LastGenOutput>ConfigComments.Designer.cs</LastGenOutput>
|
<LastGenOutput>ConfigComments.Designer.cs</LastGenOutput>
|
||||||
<CustomToolNamespace>MinecraftClient</CustomToolNamespace>
|
<CustomToolNamespace>MinecraftClient</CustomToolNamespace>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="Resources\MinecraftAssets.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>MinecraftAssets.Designer.cs</LastGenOutput>
|
||||||
|
<CustomToolNamespace>MinecraftClient</CustomToolNamespace>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Update="Resources\Translations\Translations.resx">
|
<EmbeddedResource Update="Resources\Translations\Translations.resx">
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Translations.Designer.cs</LastGenOutput>
|
<LastGenOutput>Translations.Designer.cs</LastGenOutput>
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,13 @@ using MinecraftClient.Mapping.BlockPalettes;
|
||||||
using MinecraftClient.Mapping.EntityPalettes;
|
using MinecraftClient.Mapping.EntityPalettes;
|
||||||
using MinecraftClient.Protocol;
|
using MinecraftClient.Protocol;
|
||||||
using MinecraftClient.Protocol.Handlers.Forge;
|
using MinecraftClient.Protocol.Handlers.Forge;
|
||||||
using MinecraftClient.Protocol.Keys;
|
using MinecraftClient.Protocol.ProfileKey;
|
||||||
using MinecraftClient.Protocol.Session;
|
using MinecraftClient.Protocol.Session;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using MinecraftClient.WinAPI;
|
using MinecraftClient.WinAPI;
|
||||||
using Tomlet;
|
using Tomlet;
|
||||||
using static MinecraftClient.Settings;
|
using static MinecraftClient.Settings;
|
||||||
|
using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig;
|
||||||
using static MinecraftClient.Settings.MainConfigHealper.MainConfig.AdvancedConfig;
|
using static MinecraftClient.Settings.MainConfigHealper.MainConfig.AdvancedConfig;
|
||||||
using static MinecraftClient.Settings.MainConfigHealper.MainConfig.GeneralConfig;
|
using static MinecraftClient.Settings.MainConfigHealper.MainConfig.GeneralConfig;
|
||||||
|
|
||||||
|
|
@ -97,9 +99,7 @@ namespace MinecraftClient
|
||||||
|
|
||||||
//Build information to facilitate processing of bug reports
|
//Build information to facilitate processing of bug reports
|
||||||
if (BuildInfo != null)
|
if (BuildInfo != null)
|
||||||
{
|
|
||||||
ConsoleIO.WriteLineFormatted("§8" + BuildInfo);
|
ConsoleIO.WriteLineFormatted("§8" + BuildInfo);
|
||||||
}
|
|
||||||
|
|
||||||
//Debug input ?
|
//Debug input ?
|
||||||
if (args.Length == 1 && args[0] == "--keyboard-debug")
|
if (args.Length == 1 && args[0] == "--keyboard-debug")
|
||||||
|
|
@ -287,7 +287,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.Main.Advanced.ConsoleTitle != "")
|
if (OperatingSystem.IsWindows() && !string.IsNullOrWhiteSpace(Config.Main.Advanced.ConsoleTitle))
|
||||||
{
|
{
|
||||||
InternalConfig.Username = "New Window";
|
InternalConfig.Username = "New Window";
|
||||||
Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle);
|
Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle);
|
||||||
|
|
@ -318,28 +318,28 @@ namespace MinecraftClient
|
||||||
Random random = new();
|
Random random = new();
|
||||||
{ // Test 8 bit color
|
{ // Test 8 bit color
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.Append("[0123456789]: (8bit)[");
|
sb.Append("[0123456789]: (vt100 8bit)[");
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
sb.Append(ColorHelper.GetColorEscapeCode((byte)random.Next(255),
|
sb.Append(ColorHelper.GetColorEscapeCode((byte)random.Next(255),
|
||||||
(byte)random.Next(255),
|
(byte)random.Next(255),
|
||||||
(byte)random.Next(255),
|
(byte)random.Next(255),
|
||||||
true,
|
true,
|
||||||
TerminalColorDepthType.bit_8)).Append(i);
|
ConsoleColorModeType.vt100_8bit)).Append(i);
|
||||||
}
|
}
|
||||||
sb.Append(ColorHelper.GetResetEscapeCode()).Append(']');
|
sb.Append(ColorHelper.GetResetEscapeCode()).Append(']');
|
||||||
ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb.ToString()));
|
ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb.ToString()));
|
||||||
}
|
}
|
||||||
{ // Test 24 bit color
|
{ // Test 24 bit color
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.Append("[0123456789]: (24bit)[");
|
sb.Append("[0123456789]: (vt100 24bit)[");
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
sb.Append(ColorHelper.GetColorEscapeCode((byte)random.Next(255),
|
sb.Append(ColorHelper.GetColorEscapeCode((byte)random.Next(255),
|
||||||
(byte)random.Next(255),
|
(byte)random.Next(255),
|
||||||
(byte)random.Next(255),
|
(byte)random.Next(255),
|
||||||
true,
|
true,
|
||||||
TerminalColorDepthType.bit_24)).Append(i);
|
ConsoleColorModeType.vt100_24bit)).Append(i);
|
||||||
}
|
}
|
||||||
sb.Append(ColorHelper.GetResetEscapeCode()).Append(']');
|
sb.Append(ColorHelper.GetResetEscapeCode()).Append(']');
|
||||||
ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb.ToString()));
|
ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb.ToString()));
|
||||||
|
|
@ -463,7 +463,7 @@ namespace MinecraftClient
|
||||||
InternalConfig.Username = session.PlayerName;
|
InternalConfig.Username = session.PlayerName;
|
||||||
bool isRealms = false;
|
bool isRealms = false;
|
||||||
|
|
||||||
if (Config.Main.Advanced.ConsoleTitle != "")
|
if (OperatingSystem.IsWindows() && !string.IsNullOrWhiteSpace(Config.Main.Advanced.ConsoleTitle))
|
||||||
Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle);
|
Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle);
|
||||||
|
|
||||||
if (Config.Main.Advanced.PlayerHeadAsIcon && OperatingSystem.IsWindows())
|
if (Config.Main.Advanced.PlayerHeadAsIcon && OperatingSystem.IsWindows())
|
||||||
|
|
@ -543,7 +543,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
//Retrieve server info if version is not manually set OR if need to retrieve Forge information
|
//Retrieve server info if version is not manually set OR if need to retrieve Forge information
|
||||||
if (!isRealms && (protocolversion == 0 || (Config.Main.Advanced.EnableForge == ForgeConfigType.auto) ||
|
if (!isRealms && (protocolversion == 0 || (Config.Main.Advanced.EnableForge == ForgeConfigType.auto) ||
|
||||||
((Config.Main.Advanced.EnableForge == ForgeConfigType.force) && !ProtocolHandler.ProtocolMayForceForge(protocolversion))))
|
((Config.Main.Advanced.EnableForge == ForgeConfigType.force) && !ProtocolHandler.ProtocolMayForceForge(protocolversion))))
|
||||||
{
|
{
|
||||||
if (protocolversion != 0)
|
if (protocolversion != 0)
|
||||||
|
|
@ -557,9 +557,9 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.Main.General.AccountType == LoginType.microsoft
|
if (Config.Main.General.AccountType == LoginType.microsoft
|
||||||
&& (InternalConfig.Account.Password != "-" || Config.Main.General.Method == LoginMethod.browser)
|
&& (InternalConfig.Account.Password != "-" || Config.Main.General.Method == LoginMethod.browser)
|
||||||
&& Config.Signature.LoginWithSecureProfile
|
&& Config.Signature.LoginWithSecureProfile
|
||||||
&& protocolversion >= 759 /* 1.19 and above */)
|
&& protocolversion >= 759 /* 1.19 and above */)
|
||||||
{
|
{
|
||||||
// Load cached profile key from disk if necessary
|
// Load cached profile key from disk if necessary
|
||||||
|
|
@ -614,7 +614,7 @@ namespace MinecraftClient
|
||||||
client = new McClient(session, playerKeyPair, InternalConfig.ServerIP, InternalConfig.ServerPort, protocolversion, forgeInfo);
|
client = new McClient(session, playerKeyPair, InternalConfig.ServerIP, InternalConfig.ServerPort, protocolversion, forgeInfo);
|
||||||
|
|
||||||
//Update console title
|
//Update console title
|
||||||
if (Config.Main.Advanced.ConsoleTitle != "")
|
if (OperatingSystem.IsWindows() && !string.IsNullOrWhiteSpace(Config.Main.Advanced.ConsoleTitle))
|
||||||
Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle);
|
Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle);
|
||||||
}
|
}
|
||||||
catch (NotSupportedException)
|
catch (NotSupportedException)
|
||||||
|
|
@ -657,7 +657,7 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ReloadSettings(bool keepAccountAndServerSettings = false)
|
public static void ReloadSettings(bool keepAccountAndServerSettings = false)
|
||||||
{
|
{
|
||||||
if(Settings.LoadFromFile(settingsIniPath, keepAccountAndServerSettings).Item1)
|
if (Settings.LoadFromFile(settingsIniPath, keepAccountAndServerSettings).Item1)
|
||||||
ConsoleIO.WriteLine(string.Format(Translations.config_load, settingsIniPath));
|
ConsoleIO.WriteLine(string.Format(Translations.config_load, settingsIniPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,6 +694,7 @@ namespace MinecraftClient
|
||||||
public static void DoExit(int exitcode = 0)
|
public static void DoExit(int exitcode = 0)
|
||||||
{
|
{
|
||||||
WriteBackSettings(true);
|
WriteBackSettings(true);
|
||||||
|
ConsoleInteractive.ConsoleSuggestion.ClearSuggestions();
|
||||||
ConsoleIO.WriteLineFormatted("§a" + string.Format(Translations.config_saving, settingsIniPath));
|
ConsoleIO.WriteLineFormatted("§a" + string.Format(Translations.config_saving, settingsIniPath));
|
||||||
|
|
||||||
if (client != null) { client.Disconnect(); ConsoleIO.Reset(); }
|
if (client != null) { client.Disconnect(); ConsoleIO.Reset(); }
|
||||||
|
|
@ -781,7 +782,7 @@ namespace MinecraftClient
|
||||||
|
|
||||||
if (command.StartsWith("reco"))
|
if (command.StartsWith("reco"))
|
||||||
{
|
{
|
||||||
message = new Commands.Reco().Run(null, Config.AppVar.ExpandVars(command), null);
|
message = Commands.Reco.DoReconnect(Config.AppVar.ExpandVars(command));
|
||||||
if (message == "")
|
if (message == "")
|
||||||
{
|
{
|
||||||
exitThread = true;
|
exitThread = true;
|
||||||
|
|
@ -790,7 +791,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
else if (command.StartsWith("connect"))
|
else if (command.StartsWith("connect"))
|
||||||
{
|
{
|
||||||
message = new Commands.Connect().Run(null, Config.AppVar.ExpandVars(command), null);
|
message = Commands.Connect.DoConnect(Config.AppVar.ExpandVars(command));
|
||||||
if (message == "")
|
if (message == "")
|
||||||
{
|
{
|
||||||
exitThread = true;
|
exitThread = true;
|
||||||
|
|
@ -799,7 +800,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
else if (command.StartsWith("exit") || command.StartsWith("quit"))
|
else if (command.StartsWith("exit") || command.StartsWith("quit"))
|
||||||
{
|
{
|
||||||
message = new Commands.Exit().Run(null, Config.AppVar.ExpandVars(command), null);
|
message = Commands.Exit.DoExit(Config.AppVar.ExpandVars(command));
|
||||||
}
|
}
|
||||||
else if (command.StartsWith("help"))
|
else if (command.StartsWith("help"))
|
||||||
{
|
{
|
||||||
|
|
@ -818,7 +819,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ = new Commands.Exit().Run(null, Config.AppVar.ExpandVars(command), null);
|
Commands.Exit.DoExit(Config.AppVar.ExpandVars(command));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,22 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c
|
||||||
|
|
||||||
Nodes[i] = new(flags, childs, redirectNode, name, paser, suggestionsType);
|
Nodes[i] = new(flags, childs, redirectNode, name, paser, suggestionsType);
|
||||||
}
|
}
|
||||||
RootIdx = dataTypes.ReadNextVarInt(packetData);
|
RootIdx = dataTypes.ReadNextVarInt(packetData);
|
||||||
|
|
||||||
|
ConsoleIO.OnDeclareMinecraftCommand(ExtractRootCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] ExtractRootCommand()
|
||||||
|
{
|
||||||
|
List<string> commands = new();
|
||||||
|
CommandNode root = Nodes[RootIdx];
|
||||||
|
foreach (var child in root.Clildren)
|
||||||
|
{
|
||||||
|
string? childName = Nodes[child].Name;
|
||||||
|
if (childName != null)
|
||||||
|
commands.Add(childName);
|
||||||
|
}
|
||||||
|
return commands.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Tuple<string, string>> CollectSignArguments(string command)
|
public static List<Tuple<string, string>> CollectSignArguments(string command)
|
||||||
|
|
@ -113,7 +128,7 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c
|
||||||
public string? Name;
|
public string? Name;
|
||||||
public Paser? Paser;
|
public Paser? Paser;
|
||||||
public string? SuggestionsType;
|
public string? SuggestionsType;
|
||||||
|
|
||||||
|
|
||||||
public CommandNode(byte Flags,
|
public CommandNode(byte Flags,
|
||||||
int[] Clildren,
|
int[] Clildren,
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue