diff --git a/MinecraftClient/ChatBots/AutoFishing.cs b/MinecraftClient/ChatBots/AutoFishing.cs index d6015d5f..0762f1d8 100644 --- a/MinecraftClient/ChatBots/AutoFishing.cs +++ b/MinecraftClient/ChatBots/AutoFishing.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using MinecraftClient.Inventory; using MinecraftClient.Mapping; using Tomlet.Attributes; @@ -142,6 +143,8 @@ namespace MinecraftClient.ChatBots private Entity? fishingBobber; private Location LastPos = Location.Zero; private DateTime CaughtTime = DateTime.Now; + private int fishItemCounter = 10; + private Entity fish = new(-1, EntityType.Item, Location.Zero); private int counter = 0; private readonly object stateLock = new(); @@ -243,6 +246,7 @@ namespace MinecraftClient.ChatBots isFishing = false; state = FishingState.Stopping; } + fishItemCounter = 10; } private void UseFishRod() @@ -255,6 +259,8 @@ namespace MinecraftClient.ChatBots public override void Update() { + if (fishItemCounter < 10) + ++fishItemCounter; lock (stateLock) { switch (state) @@ -341,11 +347,20 @@ namespace MinecraftClient.ChatBots public override void OnEntitySpawn(Entity entity) { - if (entity.Type == EntityType.FishingBobber && entity.ObjectData == GetPlayerEntityID()) + if (fishItemCounter < 10 && entity.Type == EntityType.Item && Math.Abs(entity.Location.Y - LastPos.Y) < 2.0 && + Math.Abs(entity.Location.X - LastPos.X) < 0.1 && Math.Abs(entity.Location.Z - LastPos.Z) < 0.1) + { + 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))); + fish = entity; + } + else if (entity.Type == EntityType.FishingBobber && entity.ObjectData == GetPlayerEntityID()) { if (Config.Log_Fish_Bobber) LogToConsole(string.Format("FishingBobber spawn at {0}, distance = {1:0.00}", entity.Location, GetCurrentLocation().Distance(entity.Location))); + fishItemCounter = 10; + LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.throw")); lock (stateLock) { @@ -387,7 +402,8 @@ namespace MinecraftClient.ChatBots 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)) { Location Pos = entity.Location; double Dx = LastPos.X - Pos.X; @@ -413,6 +429,15 @@ namespace MinecraftClient.ChatBots } } + public override void OnEntityMetadata(Entity entity, Dictionary metadata) + { + if (fishItemCounter < 10 && entity.ID == fish.ID && metadata.TryGetValue(8, out object? item)) + { + LogToConsole(Translations.Get("bot.autoFish.got", ((Item)item!).ToFullString())); + fishItemCounter = 10; + } + } + public override void AfterGameJoined() { StartFishing(); @@ -453,10 +478,11 @@ namespace MinecraftClient.ChatBots lock (stateLock) { - UseFishRod(); - counter = 0; state = FishingState.StartMove; + + fishItemCounter = 0; + UseFishRod(); } } diff --git a/MinecraftClient/Inventory/Item.cs b/MinecraftClient/Inventory/Item.cs index 37e72017..a3bac10a 100644 --- a/MinecraftClient/Inventory/Item.cs +++ b/MinecraftClient/Inventory/Item.cs @@ -3,6 +3,10 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; +using System.Text.RegularExpressions; +using System.Web; +using Microsoft.VisualBasic; +using MinecraftClient.Protocol; namespace MinecraftClient.Inventory { @@ -113,11 +117,48 @@ namespace MinecraftClient.Inventory } } + private string GetTranslatedType(ItemType itemType) + { + string type = itemType.ToString(); + string type_renamed = string.Concat(type.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); + string? res1 = ChatParser.TranslateString("item.minecraft." + type_renamed); + if (!string.IsNullOrEmpty(res1)) + return res1; + string? res2 = ChatParser.TranslateString("block.minecraft." + type_renamed); + if (!string.IsNullOrEmpty(res2)) + return res2; + return type; + } + + public string ToFullString() + { + StringBuilder sb = new(); + sb.Append(ToString()); + + try + { + if (NBT != null && (NBT.TryGetValue("Enchantments", out object? enchantments) || NBT.TryGetValue("StoredEnchantments", out enchantments))) + { + foreach (Dictionary enchantment in (object[])enchantments) + { + short level = (short)enchantment["lvl"]; + string id = ((string)enchantment["id"]).Replace(':', '.'); + sb.AppendFormat(" | {0} {1}", + ChatParser.TranslateString("enchantment." + id) ?? id, + ChatParser.TranslateString("enchantment.level." + level) ?? level.ToString()); + } + } + } + catch (Exception) { } + + return sb.ToString(); + } + public override string ToString() { StringBuilder sb = new(); - sb.AppendFormat("x{0,-2} {1}", Count, Type.ToString()); + sb.AppendFormat("x{0,-2} {1}", Count, GetTranslatedType(Type)); string? displayName = DisplayName; if (!String.IsNullOrEmpty(displayName)) diff --git a/MinecraftClient/Protocol/Message/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs index 367f948a..62728c59 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -286,6 +286,14 @@ namespace MinecraftClient.Protocol } } + public static string? TranslateString(string rulename) + { + if (TranslationRules.TryGetValue(rulename, out string? result)) + return result; + else + return null; + } + /// /// Format text using a specific formatting rule. /// Example : * %s %s + ["ORelio", "is doing something"] = * ORelio is doing something diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index 63a7bb82..bdcbb118 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -589,8 +589,9 @@ bot.autoDrop.no_inventory=Cannot find inventory {0}! bot.autoFish.no_inv_handle=Inventory handling is not enabled. Cannot check rod durability and switch rods. bot.autoFish.start=Fishing will start in {0:0.0} second(s). bot.autoFish.throw=Casting successfully. -bot.autoFish.caught=Caught a fish! (Count: {0}) -bot.autoFish.caught_at=Caught a fish at ({0:0.0},{1:0.0},{2:0.0})! (Count: {3}) +bot.autoFish.caught=Retract the fishing rod. (Count: {0}) +bot.autoFish.caught_at=Retract the fishing rod at ({0:0.0},{1:0.0},{2:0.0})! (Count: {3}) +bot.autoFish.got=Fishing got {0} bot.autoFish.no_rod=Current fishing rod is not available. Maybe broken or low durability? bot.autoFish.despawn=Fish floating despawn, will re-cast. bot.autoFish.fishing_timeout=Fishing timeout, will soon re-cast. diff --git a/MinecraftClient/Resources/lang/zh-Hans.ini b/MinecraftClient/Resources/lang/zh-Hans.ini index 76f8c972..7b7dca5c 100644 Binary files a/MinecraftClient/Resources/lang/zh-Hans.ini and b/MinecraftClient/Resources/lang/zh-Hans.ini differ diff --git a/MinecraftClient/Resources/lang/zh-Hant.ini b/MinecraftClient/Resources/lang/zh-Hant.ini index b015b011..2dafa578 100644 Binary files a/MinecraftClient/Resources/lang/zh-Hant.ini and b/MinecraftClient/Resources/lang/zh-Hant.ini differ