From 65dec596872fe32c836d417fcf1e1ef14ee2cef0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:14:25 +0000 Subject: [PATCH 1/3] Initial plan From 1a86655dfbab6ebe90cea41fd8abb9b12bbbc0d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:44:23 +0000 Subject: [PATCH 2/3] feat: add autodig tool switching Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/e83f9c2a-a85c-4763-821b-c5b4a0db75a6 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/ChatBots/AutoDig.cs | 112 +++++++++++++++++- .../Translations/Translations.Designer.cs | 18 +++ .../Resources/Translations/Translations.resx | 6 + docs/guide/chat-bots.md | 40 +++++++ 4 files changed, 173 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/ChatBots/AutoDig.cs b/MinecraftClient/ChatBots/AutoDig.cs index 67d0b199..4af2d90d 100644 --- a/MinecraftClient/ChatBots/AutoDig.cs +++ b/MinecraftClient/ChatBots/AutoDig.cs @@ -5,7 +5,9 @@ using System.Threading; using Brigadier.NET.Builder; using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler.Patch; +using MinecraftClient.Inventory; using MinecraftClient.Mapping; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; using MinecraftClient.Scripting; using Tomlet.Attributes; @@ -25,15 +27,12 @@ namespace MinecraftClient.ChatBots public bool Enabled = false; - [NonSerialized] [TomlInlineComment("$ChatBot.AutoDig.Auto_Tool_Switch$")] public bool Auto_Tool_Switch = false; - [NonSerialized] [TomlInlineComment("$ChatBot.AutoDig.Durability_Limit$")] public int Durability_Limit = 2; - [NonSerialized] [TomlInlineComment("$ChatBot.AutoDig.Drop_Low_Durability_Tools$")] public bool Drop_Low_Durability_Tools = false; @@ -65,6 +64,8 @@ namespace MinecraftClient.ChatBots public void OnSettingUpdate() { + Durability_Limit = Math.Max(0, Durability_Limit); + if (Auto_Start_Delay >= 0) Auto_Start_Delay = Math.Max(0.1, Auto_Start_Delay); @@ -225,6 +226,102 @@ namespace MinecraftClient.ChatBots } } + private static int GetLegacyMaxDamage(ItemType itemType) + { + return itemType switch + { + ItemType.WoodenPickaxe or ItemType.WoodenAxe or ItemType.WoodenShovel or ItemType.WoodenSword or ItemType.WoodenHoe => 59, + ItemType.StonePickaxe or ItemType.StoneAxe or ItemType.StoneShovel or ItemType.StoneSword or ItemType.StoneHoe => 131, + ItemType.IronPickaxe or ItemType.IronAxe or ItemType.IronShovel or ItemType.IronSword or ItemType.IronHoe => 250, + ItemType.GoldenPickaxe or ItemType.GoldenAxe or ItemType.GoldenShovel or ItemType.GoldenSword or ItemType.GoldenHoe => 32, + ItemType.DiamondPickaxe or ItemType.DiamondAxe or ItemType.DiamondShovel or ItemType.DiamondSword or ItemType.DiamondHoe => 1561, + ItemType.NetheritePickaxe or ItemType.NetheriteAxe or ItemType.NetheriteShovel or ItemType.NetheriteSword or ItemType.NetheriteHoe => 2031, + ItemType.Shears => 238, + _ => 0 + }; + } + + private static int GetMaxDamage(Item item) + { + if (item.Components is not null) + { + var maxDamageComponent = item.Components.OfType().FirstOrDefault(); + if (maxDamageComponent is not null) + return maxDamageComponent.MaxDamage; + } + + return GetLegacyMaxDamage(item.Type); + } + + private static int GetRemainingDurability(Item item) + { + int maxDamage = GetMaxDamage(item); + return maxDamage > 0 ? maxDamage - item.Damage : int.MaxValue; + } + + private bool HasEnoughDurability(Item item) + { + return Config.Durability_Limit <= 0 || GetRemainingDurability(item) >= Config.Durability_Limit; + } + + private bool IsBelowDurabilityLimit(Item? item) + { + return item is not null && Config.Durability_Limit > 0 && GetRemainingDurability(item) < Config.Durability_Limit; + } + + private static bool IsRecommendedTool(Item? item, ItemType[] recommendedTools) + { + return item is not null && recommendedTools.Contains(item.Type); + } + + private bool SwapToolIntoHand(int sourceSlot, int handSlot) + { + return WindowAction(0, sourceSlot, WindowActionType.LeftClick) + && WindowAction(0, handSlot, WindowActionType.LeftClick) + && WindowAction(0, sourceSlot, WindowActionType.LeftClick); + } + + private bool EnsureSuitableTool(Material blockType) + { + if (!inventoryEnabled || !Config.Auto_Tool_Switch) + return true; + + ItemType[] recommendedTools = Material2Tool.GetCorrectToolForBlock(blockType); + if (recommendedTools.Length == 0) + return true; + + Container container = GetPlayerInventory(); + int handSlot = 36 + GetCurrentSlot(); + container.Items.TryGetValue(handSlot, out Item? currentTool); + + if (IsRecommendedTool(currentTool, recommendedTools) && currentTool is not null && HasEnoughDurability(currentTool)) + return true; + + foreach (ItemType recommendedTool in recommendedTools) + { + foreach ((int slot, Item item) in container.Items) + { + if (slot == handSlot || item.Type != recommendedTool || !HasEnoughDurability(item)) + continue; + + if (!SwapToolIntoHand(slot, handSlot)) + return false; + + LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_switch, slot, item.GetTypeString())); + + if (Config.Drop_Low_Durability_Tools && IsBelowDurabilityLimit(currentTool) && + WindowAction(0, slot, WindowActionType.DropItemStack)) + { + LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_drop_low_durability, currentTool!.GetTypeString(), slot)); + } + + return true; + } + } + + return !IsBelowDurabilityLimit(currentTool); + } + public override void Update() { lock (stateLock) @@ -293,6 +390,9 @@ namespace MinecraftClient.ChatBots if (Config.Mode == Configs.ModeType.lookat || (Config.Mode == Configs.ModeType.both && Config._Locations.Contains(blockLoc))) { + if (!EnsureSuitableTool(block.Type)) + return false; + if (DigBlock(blockLoc, Direction.Down, lookAtBlock: false)) { currentDig = blockLoc; @@ -354,6 +454,9 @@ namespace MinecraftClient.ChatBots if (minDistance <= 6.0) { + if (!EnsureSuitableTool(targetBlock.Type)) + return false; + if (DigBlock(target, Direction.Down, lookAtBlock: true)) { currentDig = target; @@ -388,6 +491,9 @@ namespace MinecraftClient.ChatBots ((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) || (Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type)))) { + if (!EnsureSuitableTool(block.Type)) + return false; + if (DigBlock(blockLoc, Direction.Down, lookAtBlock: true)) { currentDig = blockLoc; diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 96e143d3..8259988c 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -437,6 +437,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Dropped low durability {0} from slot {1}.. + /// + internal static string bot_autodig_drop_low_durability { + get { + return ResourceManager.GetString("bot.autodig.drop_low_durability", resourceCulture); + } + } + /// /// Looks up a localized string similar to The block currently pointed to is not in the allowed list.. /// @@ -473,6 +482,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Switch to {1} from slot {0}.. + /// + internal static string bot_autodig_switch { + get { + return ResourceManager.GetString("bot.autodig.switch", resourceCulture); + } + } + /// /// Looks up a localized string similar to Added item {0}. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index f25a6165..31e29fc8 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -243,6 +243,9 @@ Inventory handling is not enabled. Unable to switch tools automatically. + + Dropped low durability {0} from slot {1}. + Automatic digging has started. @@ -252,6 +255,9 @@ Auto-digging has been stopped. + + Switch to {1} from slot {0}. + Added item {0} diff --git a/docs/guide/chat-bots.md b/docs/guide/chat-bots.md index e8b6c711..3c725a7a 100644 --- a/docs/guide/chat-bots.md +++ b/docs/guide/chat-bots.md @@ -748,6 +748,46 @@ redirectFrom: - **Default:** `3.0` + #### `Auto_Tool_Switch` + + - **Description:** + + Automatically switch to a more suitable tool from your inventory before digging. + + When `Durability_Limit` is above zero, tools below that durability threshold are skipped. + + - **Available values:** `true` and `false` + + - **Type:** `boolean` + + - **Default:** `false` + + #### `Durability_Limit` + + - **Description:** + + Will not use tools with less durability than this. + + Set to `0` to disable this durability check. + + - **Type:** `integer` + + - **Default:** `2` + + #### `Drop_Low_Durability_Tools` + + - **Description:** + + Drop the replaced tool if its remaining durability is below `Durability_Limit`. + + This setting is only useful when `Auto_Tool_Switch` is enabled. + + - **Available values:** `true` and `false` + + - **Type:** `boolean` + + - **Default:** `false` + #### `Dig_Timeout` - **Description:** From 737a94475ad1613f73d031ac777f2dcaa8911b6f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:50:43 +0000 Subject: [PATCH 3/3] fix: clarify autodig switch log formatting Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/e83f9c2a-a85c-4763-821b-c5b4a0db75a6 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/ChatBots/AutoDig.cs | 4 ++-- .../Resources/Translations/Translations.Designer.cs | 2 +- MinecraftClient/Resources/Translations/Translations.resx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MinecraftClient/ChatBots/AutoDig.cs b/MinecraftClient/ChatBots/AutoDig.cs index 4af2d90d..148335d5 100644 --- a/MinecraftClient/ChatBots/AutoDig.cs +++ b/MinecraftClient/ChatBots/AutoDig.cs @@ -294,7 +294,7 @@ namespace MinecraftClient.ChatBots int handSlot = 36 + GetCurrentSlot(); container.Items.TryGetValue(handSlot, out Item? currentTool); - if (IsRecommendedTool(currentTool, recommendedTools) && currentTool is not null && HasEnoughDurability(currentTool)) + if (currentTool is not null && IsRecommendedTool(currentTool, recommendedTools) && HasEnoughDurability(currentTool)) return true; foreach (ItemType recommendedTool in recommendedTools) @@ -307,7 +307,7 @@ namespace MinecraftClient.ChatBots if (!SwapToolIntoHand(slot, handSlot)) return false; - LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_switch, slot, item.GetTypeString())); + LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_switch, item.GetTypeString(), slot)); if (Config.Drop_Low_Durability_Tools && IsBelowDurabilityLimit(currentTool) && WindowAction(0, slot, WindowActionType.DropItemStack)) diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 8259988c..02447274 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -483,7 +483,7 @@ namespace MinecraftClient { } /// - /// Looks up a localized string similar to Switch to {1} from slot {0}.. + /// Looks up a localized string similar to Switch to {0} from slot {1}.. /// internal static string bot_autodig_switch { get { diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 31e29fc8..c9c53ae6 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -256,7 +256,7 @@ Auto-digging has been stopped. - Switch to {1} from slot {0}. + Switch to {0} from slot {1}. Added item {0}