Update AutoFishing

This commit is contained in:
BruceChen 2022-10-17 20:06:06 +08:00 committed by GitHub
commit 836a1b5801
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 229 additions and 151 deletions

View file

@ -247,7 +247,7 @@ namespace MinecraftClient.ChatBots
{ {
currentDig = blockLoc; currentDig = blockLoc;
if (Config.Log_Block_Dig) if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.Type)); LogToConsole(Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.GetTypeString()));
return true; return true;
} }
else else
@ -308,7 +308,7 @@ namespace MinecraftClient.ChatBots
{ {
currentDig = target; currentDig = target;
if (Config.Log_Block_Dig) if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.dig", target.X, target.Y, target.Z, targetBlock.Type)); LogToConsole(Translations.Get("cmd.dig.dig", target.X, target.Y, target.Z, targetBlock.GetTypeString()));
return true; return true;
} }
else else
@ -342,7 +342,7 @@ namespace MinecraftClient.ChatBots
{ {
currentDig = blockLoc; currentDig = blockLoc;
if (Config.Log_Block_Dig) if (Config.Log_Block_Dig)
LogToConsole(Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.Type)); LogToConsole(Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.GetTypeString()));
return true; return true;
} }
else else

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using MinecraftClient.Inventory; using MinecraftClient.Inventory;
using MinecraftClient.Mapping; using MinecraftClient.Mapping;
using Tomlet.Attributes; using Tomlet.Attributes;
@ -142,6 +143,8 @@ namespace MinecraftClient.ChatBots
private Entity? fishingBobber; private Entity? fishingBobber;
private Location LastPos = Location.Zero; private Location LastPos = Location.Zero;
private DateTime CaughtTime = DateTime.Now; private DateTime CaughtTime = DateTime.Now;
private int fishItemCounter = 10;
private Entity fishItem = new(-1, EntityType.Item, Location.Zero);
private int counter = 0; private int counter = 0;
private readonly object stateLock = new(); private readonly object stateLock = new();
@ -173,6 +176,43 @@ namespace MinecraftClient.ChatBots
inventoryEnabled = GetInventoryEnabled(); inventoryEnabled = GetInventoryEnabled();
if (!inventoryEnabled) if (!inventoryEnabled)
LogToConsoleTranslated("bot.autoFish.no_inv_handle"); LogToConsoleTranslated("bot.autoFish.no_inv_handle");
RegisterChatBotCommand("fish", Translations.Get("bot.autoFish.cmd"), GetHelp(), CommandHandler);
}
public string CommandHandler(string cmd, string[] args)
{
if (args.Length > 0)
{
switch (args[0])
{
case "start":
isFishing = false;
lock (stateLock)
{
isFishing = false;
counter = 0;
state = FishingState.StartMove;
}
return Translations.Get("bot.autoFish.start");
case "stop":
isFishing = false;
lock (stateLock)
{
isFishing = false;
if (state == FishingState.WaitingFishToBite)
UseFishRod();
state = FishingState.Stopping;
}
StopFishing();
return Translations.Get("bot.autoFish.stop");
case "help":
return GetCommandHelp(args.Length >= 2 ? args[1] : "");
default:
return GetHelp();
}
}
else return GetHelp();
} }
private void StartFishing() private void StartFishing()
@ -181,9 +221,10 @@ namespace MinecraftClient.ChatBots
if (Config.Auto_Start) if (Config.Auto_Start)
{ {
double delay = Config.Fishing_Delay; double delay = Config.Fishing_Delay;
LogToConsole(Translations.Get("bot.autoFish.start", delay)); LogToConsole(Translations.Get("bot.autoFish.start_at", delay));
lock (stateLock) lock (stateLock)
{ {
isFishing = false;
counter = Settings.DoubleToTick(delay); counter = Settings.DoubleToTick(delay);
state = FishingState.StartMove; state = FishingState.StartMove;
} }
@ -202,8 +243,10 @@ namespace MinecraftClient.ChatBots
isFishing = false; isFishing = false;
lock (stateLock) lock (stateLock)
{ {
isFishing = false;
state = FishingState.Stopping; state = FishingState.Stopping;
} }
fishItemCounter = 10;
} }
private void UseFishRod() private void UseFishRod()
@ -216,6 +259,8 @@ namespace MinecraftClient.ChatBots
public override void Update() public override void Update()
{ {
if (fishItemCounter < 10)
++fishItemCounter;
lock (stateLock) lock (stateLock)
{ {
switch (state) switch (state)
@ -302,11 +347,20 @@ namespace MinecraftClient.ChatBots
public override void OnEntitySpawn(Entity entity) 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)));
fishItem = entity;
}
else if (entity.Type == EntityType.FishingBobber && entity.ObjectData == GetPlayerEntityID())
{ {
if (Config.Log_Fish_Bobber) if (Config.Log_Fish_Bobber)
LogToConsole(string.Format("FishingBobber spawn at {0}, distance = {1:0.00}", entity.Location, GetCurrentLocation().Distance(entity.Location))); 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")); LogToConsole(GetTimestamp() + ": " + Translations.Get("bot.autoFish.throw"));
lock (stateLock) lock (stateLock)
{ {
@ -348,7 +402,8 @@ 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))
{ {
Location Pos = entity.Location; Location Pos = entity.Location;
double Dx = LastPos.X - Pos.X; double Dx = LastPos.X - Pos.X;
@ -374,6 +429,15 @@ namespace MinecraftClient.ChatBots
} }
} }
public override void OnEntityMetadata(Entity entity, Dictionary<int, object?> metadata)
{
if (fishItemCounter < 10 && entity.ID == fishItem.ID && metadata.TryGetValue(8, out object? item))
{
LogToConsole(Translations.Get("bot.autoFish.got", ((Item)item!).ToFullString()));
fishItemCounter = 10;
}
}
public override void AfterGameJoined() public override void AfterGameJoined()
{ {
StartFishing(); StartFishing();
@ -414,10 +478,11 @@ namespace MinecraftClient.ChatBots
lock (stateLock) lock (stateLock)
{ {
UseFishRod();
counter = 0; counter = 0;
state = FishingState.StartMove; state = FishingState.StartMove;
fishItemCounter = 0;
UseFishRod();
} }
} }
@ -512,5 +577,23 @@ namespace MinecraftClient.ChatBots
return false; return false;
} }
} }
private static string GetHelp()
{
return Translations.Get("bot.autoFish.available_cmd", "start, stop, help");
}
private string GetCommandHelp(string cmd)
{
return cmd.ToLower() switch
{
#pragma warning disable format // @formatter:off
"start" => Translations.Get("bot.autoFish.help.start"),
"stop" => Translations.Get("bot.autoFish.help.stop"),
"help" => Translations.Get("bot.autoFish.help.help"),
_ => GetHelp(),
#pragma warning restore format // @formatter:on
};
}
} }
} }

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Xml.Linq;
using Tomlet.Attributes; using Tomlet.Attributes;
using static MinecraftClient.ChatBots.ScriptScheduler.Configs; using static MinecraftClient.ChatBots.ScriptScheduler.Configs;

View file

@ -10,7 +10,7 @@ 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 "cmd.blockinfo.desc"; } } public override string CmdDesc { get { return "cmd.blockinfo.desc"; } }
public override string Run(McClient handler, string command, Dictionary<string, object> localVars) public override string Run(McClient handler, string command, Dictionary<string, object>? localVars)
{ {
string[] args = GetArgs(command); string[] args = GetArgs(command);
@ -24,7 +24,7 @@ namespace MinecraftClient.Commands
Block block = handler.GetWorld().GetBlock(targetBlockLocation); Block block = handler.GetWorld().GetBlock(targetBlockLocation);
handler.Log.Info(Translations.TryGet("cmd.blockinfo.BlockType") + ": " + block.Type); handler.Log.Info(Translations.TryGet("cmd.blockinfo.BlockType") + ": " + block.GetTypeString());
if (reportSurrounding) if (reportSurrounding)
{ {
@ -38,14 +38,14 @@ namespace MinecraftClient.Commands
Block blockZPositive = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y, targetBlockLocation.Z + 1)); Block blockZPositive = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y, targetBlockLocation.Z + 1));
Block blockZNegative = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y, targetBlockLocation.Z - 1)); Block blockZNegative = handler.GetWorld().GetBlock(new Location(targetBlockLocation.X, targetBlockLocation.Y, targetBlockLocation.Z - 1));
sb.AppendLine("[X " + Translations.TryGet("cmd.blockinfo.Positive") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockXPositive.Type); sb.AppendLine("[X " + Translations.TryGet("cmd.blockinfo.Positive") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockXPositive.GetTypeString());
sb.AppendLine("[X " + Translations.TryGet("cmd.blockinfo.Negative") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockXNegative.Type); sb.AppendLine("[X " + Translations.TryGet("cmd.blockinfo.Negative") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockXNegative.GetTypeString());
sb.AppendLine(" "); sb.AppendLine(" ");
sb.AppendLine("[Y " + Translations.TryGet("cmd.blockinfo.Positive") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockYPositive.Type); sb.AppendLine("[Y " + Translations.TryGet("cmd.blockinfo.Positive") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockYPositive.GetTypeString());
sb.AppendLine("[Y " + Translations.TryGet("cmd.blockinfo.Negative") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockYNegative.Type); sb.AppendLine("[Y " + Translations.TryGet("cmd.blockinfo.Negative") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockYNegative.GetTypeString());
sb.AppendLine(" "); sb.AppendLine(" ");
sb.AppendLine("[Z " + Translations.TryGet("cmd.blockinfo.Positive") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockZPositive.Type); sb.AppendLine("[Z " + Translations.TryGet("cmd.blockinfo.Positive") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockZPositive.GetTypeString());
sb.AppendLine("[Z " + Translations.TryGet("cmd.blockinfo.Negative") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockZNegative.Type); sb.AppendLine("[Z " + Translations.TryGet("cmd.blockinfo.Negative") + "] " + Translations.TryGet("cmd.blockinfo.BlockType") + ": " + blockZNegative.GetTypeString());
handler.Log.Info(sb.ToString()); handler.Log.Info(sb.ToString());
} }

View file

@ -24,7 +24,7 @@ namespace MinecraftClient.Commands
else if (block.Type == Material.Air) else if (block.Type == Material.Air)
return Translations.Get("cmd.dig.no_block"); return Translations.Get("cmd.dig.no_block");
else if (handler.DigBlock(blockLoc, lookAtBlock: false)) else if (handler.DigBlock(blockLoc, lookAtBlock: false))
return Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.Type); return Translations.Get("cmd.dig.dig", blockLoc.X, blockLoc.Y, blockLoc.Z, block.GetTypeString());
else else
return Translations.Get("cmd.dig.fail"); return Translations.Get("cmd.dig.fail");
} }
@ -42,7 +42,7 @@ namespace MinecraftClient.Commands
else if (handler.DigBlock(blockToBreak)) else if (handler.DigBlock(blockToBreak))
{ {
blockToBreak = blockToBreak.ToCenter(); blockToBreak = blockToBreak.ToCenter();
return Translations.Get("cmd.dig.dig", blockToBreak.X, blockToBreak.Y, blockToBreak.Z, block.Type); return Translations.Get("cmd.dig.dig", blockToBreak.X, blockToBreak.Y, blockToBreak.Z, block.GetTypeString());
} }
else else
return Translations.Get("cmd.dig.fail"); return Translations.Get("cmd.dig.fail");

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Text;
using MinecraftClient.Inventory; using MinecraftClient.Inventory;
using MinecraftClient.Mapping; using MinecraftClient.Mapping;
@ -56,43 +57,44 @@ namespace MinecraftClient.Commands
color = "§e"; // Yellow color = "§e"; // Yellow
string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity.Location.X, 2), Math.Round(entity.Location.Y, 2), Math.Round(entity.Location.Z, 2)); string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity.Location.X, 2), Math.Round(entity.Location.Y, 2), Math.Round(entity.Location.Z, 2));
string done = Translations.Replace("([cmd.entityCmd.entity]): {0}\n [MCC] Type: {1}", id, type); StringBuilder done = new();
done.Append(Translations.Replace("([cmd.entityCmd.entity]): {0}\n [MCC] Type: {1}", id, entity.GetTypeString()));
if (!String.IsNullOrEmpty(nickname)) if (!String.IsNullOrEmpty(nickname))
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.nickname]): {0}", nickname); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.nickname]): {0}", nickname));
else if (!String.IsNullOrEmpty(customname)) else if (!String.IsNullOrEmpty(customname))
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.customname]): {0}§8", customname.Replace("&", "§")); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.customname]): {0}§8", customname.Replace("&", "§")));
if (type == EntityType.Player) if (type == EntityType.Player)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.latency]): {0}", latency); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.latency]): {0}", latency));
else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket) else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket)
{ {
string? displayName = item.DisplayName; string? displayName = item.DisplayName;
if (String.IsNullOrEmpty(displayName)) if (String.IsNullOrEmpty(displayName))
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1}", item.Type, item.Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1}", item.GetTypeString(), item.Count));
else else
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1} - {2}§8", item.Type, item.Count, displayName); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1} - {2}§8", item.GetTypeString(), item.Count, displayName));
} }
if (entity.Equipment.Count >= 1 && entity.Equipment != null) if (entity.Equipment.Count >= 1 && entity.Equipment != null)
{ {
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.equipment]):"); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.equipment]):"));
if (entity.Equipment.ContainsKey(0) && entity.Equipment[0] != null) if (entity.Equipment.ContainsKey(0) && entity.Equipment[0] != null)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.mainhand]): {0} x{1}", entity.Equipment[0].Type, entity.Equipment[0].Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.mainhand]): {0} x{1}", entity.Equipment[0].GetTypeString(), entity.Equipment[0].Count));
if (entity.Equipment.ContainsKey(1) && entity.Equipment[1] != null) if (entity.Equipment.ContainsKey(1) && entity.Equipment[1] != null)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.offhand]): {0} x{1}", entity.Equipment[1].Type, entity.Equipment[1].Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.offhand]): {0} x{1}", entity.Equipment[1].GetTypeString(), entity.Equipment[1].Count));
if (entity.Equipment.ContainsKey(5) && entity.Equipment[5] != null) if (entity.Equipment.ContainsKey(5) && entity.Equipment[5] != null)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.helmet]): {0} x{1}", entity.Equipment[5].Type, entity.Equipment[5].Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.helmet]): {0} x{1}", entity.Equipment[5].GetTypeString(), entity.Equipment[5].Count));
if (entity.Equipment.ContainsKey(4) && entity.Equipment[4] != null) if (entity.Equipment.ContainsKey(4) && entity.Equipment[4] != null)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.chestplate]): {0} x{1}", entity.Equipment[4].Type, entity.Equipment[4].Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.chestplate]): {0} x{1}", entity.Equipment[4].GetTypeString(), entity.Equipment[4].Count));
if (entity.Equipment.ContainsKey(3) && entity.Equipment[3] != null) if (entity.Equipment.ContainsKey(3) && entity.Equipment[3] != null)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.leggings]): {0} x{1}", entity.Equipment[3].Type, entity.Equipment[3].Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.leggings]): {0} x{1}", entity.Equipment[3].GetTypeString(), entity.Equipment[3].Count));
if (entity.Equipment.ContainsKey(2) && entity.Equipment[2] != null) if (entity.Equipment.ContainsKey(2) && entity.Equipment[2] != null)
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.boots]): {0} x{1}", entity.Equipment[2].Type, entity.Equipment[2].Count); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.boots]): {0} x{1}", entity.Equipment[2].GetTypeString(), entity.Equipment[2].Count));
} }
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.pose]): {0}", pose); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.pose]): {0}", pose));
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.health]): {0}", color + health + "§8"); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.health]): {0}", color + health + "§8"));
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.distance]): {0}", distance); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.distance]): {0}", distance));
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.location]): {0}", location); done.Append(Translations.Replace("\n [MCC] ([cmd.entityCmd.location]): {0}", location));
return done; return done.ToString();
} }
} }
else return Translations.Get("cmd.entityCmd.not_found"); else return Translations.Get("cmd.entityCmd.not_found");
@ -132,10 +134,8 @@ namespace MinecraftClient.Commands
else else
{ {
Dictionary<int, Entity> entities = handler.GetEntities(); Dictionary<int, Entity> entities = handler.GetEntities();
List<string> response = new() StringBuilder response = new();
{ response.AppendLine(Translations.Get("cmd.entityCmd.entities"));
Translations.Get("cmd.entityCmd.entities")
};
foreach (var entity2 in entities) foreach (var entity2 in entities)
{ {
int id = entity2.Key; int id = entity2.Key;
@ -149,16 +149,16 @@ namespace MinecraftClient.Commands
string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity2.Value.Location.X, 2), Math.Round(entity2.Value.Location.Y, 2), Math.Round(entity2.Value.Location.Z, 2)); string location = String.Format("X:{0}, Y:{1}, Z:{2}", Math.Round(entity2.Value.Location.X, 2), Math.Round(entity2.Value.Location.Y, 2), Math.Round(entity2.Value.Location.Z, 2));
if (type == EntityType.Item || type == EntityType.ItemFrame || type == EntityType.EyeOfEnder || type == EntityType.Egg || type == EntityType.EnderPearl || type == EntityType.Potion || type == EntityType.Fireball || type == EntityType.FireworkRocket) if (type == EntityType.Item || type == EntityType.ItemFrame || type == EntityType.EyeOfEnder || type == EntityType.Egg || type == EntityType.EnderPearl || type == EntityType.Potion || type == EntityType.Fireball || type == EntityType.FireworkRocket)
response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.item]): {2}, ([cmd.entityCmd.location]): {3}", id, type, item.Type, location)); response.AppendLine(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.item]): {2}, ([cmd.entityCmd.location]): {3}", id, entity2.Value.GetTypeString(), item.GetTypeString(), location));
else if (type == EntityType.Player && !String.IsNullOrEmpty(nickname)) else if (type == EntityType.Player && !String.IsNullOrEmpty(nickname))
response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.nickname]): §8{2}§8, ([cmd.entityCmd.latency]): {3}, ([cmd.entityCmd.health]): {4}, ([cmd.entityCmd.pose]): {5}, ([cmd.entityCmd.location]): {6}", id, type, nickname, latency, health, pose, location)); response.AppendLine(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.nickname]): §8{2}§8, ([cmd.entityCmd.latency]): {3}, ([cmd.entityCmd.health]): {4}, ([cmd.entityCmd.pose]): {5}, ([cmd.entityCmd.location]): {6}", id, entity2.Value.GetTypeString(), nickname, latency, health, pose, location));
else if (type == EntityType.Player && !String.IsNullOrEmpty(customname)) else if (type == EntityType.Player && !String.IsNullOrEmpty(customname))
response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.customname]): §8{2}§8, ([cmd.entityCmd.latency]): {3}, ([cmd.entityCmd.health]): {4}, ([cmd.entityCmd.pose]): {5}, ([cmd.entityCmd.location]): {6}", id, type, customname.Replace("&", "§"), latency, health, pose, location)); response.AppendLine(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.customname]): §8{2}§8, ([cmd.entityCmd.latency]): {3}, ([cmd.entityCmd.health]): {4}, ([cmd.entityCmd.pose]): {5}, ([cmd.entityCmd.location]): {6}", id, entity2.Value.GetTypeString(), customname.Replace("&", "§"), latency, health, pose, location));
else else
response.Add(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.health]): {2}, ([cmd.entityCmd.location]): {3}", id, type, health, location)); response.AppendLine(Translations.Replace(" #{0}: ([cmd.entityCmd.type]): {1}, ([cmd.entityCmd.health]): {2}, ([cmd.entityCmd.location]): {3}", id, entity2.Value.GetTypeString(), health, location));
} }
response.Add(GetCmdDescTranslated()); response.Append(GetCmdDescTranslated());
return String.Join("\n", response); return response.ToString();
} }
} }
else return Translations.Get("extra.entity_required"); else return Translations.Get("extra.entity_required");

View file

@ -148,7 +148,7 @@ namespace MinecraftClient.Commands
response.AppendLine(String.Format("{0} (#{1}):", inventories[invId].Title, invId)); response.AppendLine(String.Format("{0} (#{1}):", inventories[invId].Title, invId));
foreach (Item item in itemsList) foreach (Item item in itemsList)
response.AppendLine(String.Format("\t- {0}", item.ToString())); response.AppendLine(String.Format("\t- {0}", item.ToFullString()));
response.AppendLine(" "); response.AppendLine(" ");
} }
@ -195,7 +195,7 @@ namespace MinecraftClient.Commands
string hotbarString = isHotbar ? (hotbar + 1).ToString() : " "; string hotbarString = isHotbar ? (hotbar + 1).ToString() : " ";
if ((hotbar + 1) == selectedHotbar) if ((hotbar + 1) == selectedHotbar)
hotbarString = ">" + hotbarString; hotbarString = ">" + hotbarString;
response.AppendLine(String.Format("{0,2} | #{1,-2}: {2}", hotbarString, itemId, item.ToString())); response.AppendLine(String.Format("{0,2} | #{1,-2}: {2}", hotbarString, itemId, item.ToFullString()));
} }
if (inventoryId == 0) if (inventoryId == 0)

View file

@ -0,0 +1,12 @@
using System.Linq;
namespace MinecraftClient
{
public static class ExtensionMethods
{
public static string ToUnderscoreCase(this string str)
{
return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
}
}
}

View file

@ -136,50 +136,6 @@ namespace MinecraftClient.Inventory
{ 37, Enchantment.Mending }, { 37, Enchantment.Mending },
{ 38, Enchantment.VanishingCurse } { 38, Enchantment.VanishingCurse }
}; };
private static Dictionary<Enchantment, string> enchantmentNames = new Dictionary<Enchantment, string>()
{
//type
{ Enchantment.Protection, "Enchantment.Protection" },
{ Enchantment.FireProtection, "Enchantment.FireProtection" },
{ Enchantment.FeatherFalling, "Enchantment.FeatherFalling" },
{ Enchantment.BlastProtection, "Enchantment.BlastProtection" },
{ Enchantment.ProjectileProtection, "Enchantment.ProjectileProtection" },
{ Enchantment.Respiration, "Enchantment.Respiration" },
{ Enchantment.AquaAffinity, "Enchantment.AquaAffinity" },
{ Enchantment.Thorns, "Enchantment.Thorns" },
{ Enchantment.DepthStrieder, "Enchantment.DepthStrieder" },
{ Enchantment.FrostWalker, "Enchantment.FrostWalker" },
{ Enchantment.BindingCurse, "Enchantment.BindingCurse" },
{ Enchantment.SoulSpeed, "Enchantment.SoulSpeed" },
{ Enchantment.SwiftSneak, "Enchantment.SwiftSneak" },
{ Enchantment.Sharpness, "Enchantment.Sharpness" },
{ Enchantment.Smite, "Enchantment.Smite" },
{ Enchantment.BaneOfArthropods, "Enchantment.BaneOfArthropods" },
{ Enchantment.Knockback, "Enchantment.Knockback" },
{ Enchantment.FireAspect, "Enchantment.FireAspect" },
{ Enchantment.Looting, "Enchantment.Looting" },
{ Enchantment.Sweeping, "Enchantment.Sweeping" },
{ Enchantment.Efficency, "Enchantment.Efficency" },
{ Enchantment.SilkTouch, "Enchantment.SilkTouch" },
{ Enchantment.Unbreaking, "Enchantment.Unbreaking" },
{ Enchantment.Fortune, "Enchantment.Fortune" },
{ Enchantment.Power, "Enchantment.Power" },
{ Enchantment.Punch, "Enchantment.Punch" },
{ Enchantment.Flame, "Enchantment.Flame" },
{ Enchantment.Infinity, "Enchantment.Infinity" },
{ Enchantment.LuckOfTheSea, "Enchantment.LuckOfTheSea" },
{ Enchantment.Lure, "Enchantment.Lure" },
{ Enchantment.Loyality, "Enchantment.Loyality" },
{ Enchantment.Impaling, "Enchantment.Impaling" },
{ Enchantment.Riptide, "Enchantment.Riptide" },
{ Enchantment.Channeling, "Enchantment.Channeling" },
{ Enchantment.Multishot, "Enchantment.Multishot" },
{ Enchantment.QuickCharge, "Enchantment.QuickCharge" },
{ Enchantment.Piercing, "Enchantment.Piercing" },
{ Enchantment.Mending, "Enchantment.Mending" },
{ Enchantment.VanishingCurse, "Enchantment.VanishingCurse" }
};
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
public static Enchantment GetEnchantmentById(int protocolVersion, short id) public static Enchantment GetEnchantmentById(int protocolVersion, short id)
@ -202,10 +158,11 @@ namespace MinecraftClient.Inventory
public static string GetEnchantmentName(Enchantment enchantment) public static string GetEnchantmentName(Enchantment enchantment)
{ {
if (!enchantmentNames.ContainsKey(enchantment)) string? trans = Protocol.ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase());
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
return Translations.TryGet(enchantmentNames[enchantment]); return trans;
} }
public static string ConvertLevelToRomanNumbers(int num) public static string ConvertLevelToRomanNumbers(int num)

View file

@ -113,11 +113,48 @@ namespace MinecraftClient.Inventory
} }
} }
public string GetTypeString()
{
string type = Type.ToString();
string type_renamed = type.ToUnderscoreCase();
string? res1 = Protocol.ChatParser.TranslateString("item.minecraft." + type_renamed);
if (!string.IsNullOrEmpty(res1))
return res1;
string? res2 = Protocol.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<string, object> enchantment in (object[])enchantments)
{
short level = (short)enchantment["lvl"];
string id = ((string)enchantment["id"]).Replace(':', '.');
sb.AppendFormat(" | {0} {1}",
Protocol.ChatParser.TranslateString("enchantment." + id) ?? id,
Protocol.ChatParser.TranslateString("enchantment.level." + level) ?? level.ToString());
}
}
}
catch (Exception) { }
return sb.ToString();
}
public override string ToString() public override string ToString()
{ {
StringBuilder sb = new(); StringBuilder sb = new();
sb.AppendFormat("x{0,-2} {1}", Count, Type.ToString()); sb.AppendFormat("x{0,-2} {1}", Count, GetTypeString());
string? displayName = DisplayName; string? displayName = DisplayName;
if (!String.IsNullOrEmpty(displayName)) if (!String.IsNullOrEmpty(displayName))

View file

@ -112,6 +112,13 @@ namespace MinecraftClient.Mapping
blockIdAndMeta = typeAndMeta; blockIdAndMeta = typeAndMeta;
} }
public string GetTypeString()
{
string typeStr = Type.ToString();
string? trans = Protocol.ChatParser.TranslateString("block.minecraft." + typeStr.ToUnderscoreCase());
return string.IsNullOrEmpty(trans) ? typeStr : trans;
}
/// <summary> /// <summary>
/// String representation of the block /// String representation of the block
/// </summary> /// </summary>

View file

@ -154,5 +154,12 @@ namespace MinecraftClient.Mapping
Yaw = yaw * (1 / 256) * 360; // to angle in 360 degree Yaw = yaw * (1 / 256) * 360; // to angle in 360 degree
Pitch = pitch * (1 / 256) * 360; Pitch = pitch * (1 / 256) * 360;
} }
public string GetTypeString()
{
string typeStr = Type.ToString();
string? trans = Protocol.ChatParser.TranslateString("entity.minecraft." + typeStr.ToUnderscoreCase());
return string.IsNullOrEmpty(trans) ? typeStr : trans;
}
} }
} }

View file

@ -64,7 +64,7 @@ namespace MinecraftClient.Mapping
/// <summary> /// <summary>
/// Parse location from the string. /// Parse location from the string.
/// return NULL if the parsing fails. /// throw FormatException if the parsing fails.
/// </summary> /// </summary>
/// <param name="x">The string representation of the X-axis coordinate.</param> /// <param name="x">The string representation of the X-axis coordinate.</param>
/// <param name="y">The string representation of the Y-axis coordinate.</param> /// <param name="y">The string representation of the Y-axis coordinate.</param>
@ -99,7 +99,7 @@ namespace MinecraftClient.Mapping
/// <summary> /// <summary>
/// Parse location from the string (relative coordinate representation is supported). /// Parse location from the string (relative coordinate representation is supported).
/// return NULL if the parsing fails. /// throw FormatException if the parsing fails.
/// </summary> /// </summary>
/// <param name="current">Relative position base point.</param> /// <param name="current">Relative position base point.</param>
/// <param name="x">The string representation of the X-axis coordinate.</param> /// <param name="x">The string representation of the X-axis coordinate.</param>

View file

@ -197,7 +197,7 @@ namespace MinecraftClient
if (Settings.CheckUpdate(Config.Head.CurrentVersion, Config.Head.LatestVersion)) if (Settings.CheckUpdate(Config.Head.CurrentVersion, Config.Head.LatestVersion))
{ {
needPromptUpdate = false; needPromptUpdate = false;
ConsoleIO.WriteLineFormatted(Translations.TryGet("mcc.has_update", Settings.GithubLatestReleaseUrl)); ConsoleIO.WriteLineFormatted(Translations.TryGet("mcc.has_update", Settings.GithubReleaseUrl));
} }
//Other command-line arguments //Other command-line arguments
@ -328,7 +328,7 @@ namespace MinecraftClient
string latestVersion = string.Format("GitHub build {0}, built on {1}-{2}-{3}", run, year, month, day); string latestVersion = string.Format("GitHub build {0}, built on {1}-{2}-{3}", run, year, month, day);
if (needPromptUpdate) if (needPromptUpdate)
if (Settings.CheckUpdate(Config.Head.CurrentVersion, Config.Head.LatestVersion)) if (Settings.CheckUpdate(Config.Head.CurrentVersion, Config.Head.LatestVersion))
ConsoleIO.WriteLineFormatted(Translations.TryGet("mcc.has_update", Settings.GithubLatestReleaseUrl)); ConsoleIO.WriteLineFormatted(Translations.TryGet("mcc.has_update", Settings.GithubReleaseUrl));
if (latestVersion != Config.Head.LatestVersion) if (latestVersion != Config.Head.LatestVersion)
{ {
Config.Head.LatestVersion = latestVersion; Config.Head.LatestVersion = latestVersion;

View file

@ -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;
}
/// <summary> /// <summary>
/// Format text using a specific formatting rule. /// Format text using a specific formatting rule.
/// Example : * %s %s + ["ORelio", "is doing something"] = * ORelio is doing something /// Example : * %s %s + ["ORelio", "is doing something"] = * ORelio is doing something

View file

@ -159,46 +159,6 @@ Enchantment.middle_slot=Middle slot
Enchantment.bottom_slot=Bottom slot Enchantment.bottom_slot=Bottom slot
Enchantment.levels=Levels Enchantment.levels=Levels
Enchantment.Protection=Protection
Enchantment.FireProtection=Fire Protection
Enchantment.FeatherFalling=Feather Falling
Enchantment.BlastProtection=Blast Protection
Enchantment.ProjectileProtection=Projectile Protection
Enchantment.Respiration=Respiration
Enchantment.AquaAffinity=Aqua Affinity
Enchantment.Thorns=Thorns
Enchantment.DepthStrieder=Depth Strieder
Enchantment.FrostWalker=Frost Walker
Enchantment.BindingCurse=Curse of Binding
Enchantment.SoulSpeed=Soul Speed
Enchantment.SwiftSneak=Swift Sneak
Enchantment.Sharpness=Sharpness
Enchantment.Smite=Smite
Enchantment.BaneOfArthropods=Bane of Arthropods
Enchantment.Knockback=Knockback
Enchantment.FireAspect=Fire Aspect
Enchantment.Looting=Looting
Enchantment.Sweeping=Sweeping
Enchantment.Efficency=Efficency
Enchantment.SilkTouch=Silk Touch
Enchantment.Unbreaking=Unbreaking
Enchantment.Fortune=Fortune
Enchantment.Power=Power
Enchantment.Punch=Punch
Enchantment.Flame=Flame
Enchantment.Infinity=Infinity
Enchantment.LuckOfTheSea=Luck of the Sea
Enchantment.Lure=Lure
Enchantment.Loyality=Loyality
Enchantment.Impaling=Impaling
Enchantment.Riptide=Riptide
Enchantment.Channeling=Channeling
Enchantment.Multishot=Multishot
Enchantment.QuickCharge=Quick Charge
Enchantment.Piercing=Piercing
Enchantment.Mending=Mending
Enchantment.VanishingCurse=Curse of Vanishing
[forge] [forge]
# Messages from Forge handler # Messages from Forge handler
forge.version=§8Forge protocol version : {0} forge.version=§8Forge protocol version : {0}
@ -587,16 +547,24 @@ bot.autoDrop.no_inventory=Cannot find inventory {0}!
# AutoFish # AutoFish
bot.autoFish.no_inv_handle=Inventory handling is not enabled. Cannot check rod durability and switch rods. 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.start_at=Fishing will start in {0:0.0} second(s).
bot.autoFish.throw=Casting successfully. bot.autoFish.throw=Casting successfully.
bot.autoFish.caught=Caught a fish! (Count: {0}) bot.autoFish.caught=Retract the fishing rod. (Count: {0})
bot.autoFish.caught_at=Caught a fish at ({0:0.0},{1:0.0},{2:0.0})! (Count: {3}) 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.no_rod=Current fishing rod is not available. Maybe broken or low durability?
bot.autoFish.despawn=Fish floating despawn, will re-cast. bot.autoFish.despawn=Fish floating despawn, will re-cast.
bot.autoFish.fishing_timeout=Fishing timeout, will soon re-cast. bot.autoFish.fishing_timeout=Fishing timeout, will soon re-cast.
bot.autoFish.cast_timeout=Casting timeout and will soon retry. (Timeout increased to {0:0.0} sec). bot.autoFish.cast_timeout=Casting timeout and will soon retry. (Timeout increased to {0:0.0} sec).
bot.autoFish.update_lookat=Update yaw = {0:0.00}, pitch = {1:0.00}. bot.autoFish.update_lookat=Update yaw = {0:0.00}, pitch = {1:0.00}.
bot.autoFish.switch=Switch to the rod in slot {0}, durability {1}/64. bot.autoFish.switch=Switch to the rod in slot {0}, durability {1}/64.
bot.autoFish.cmd=Auto-Fishing ChatBot command
bot.autoFish.available_cmd=Available commands: {0}. Use /fish help <cmd name> for more information.
bot.autoFish.start=Start auto-fishing.
bot.autoFish.stop=Stop auto-fishing.
bot.autoFish.help.start=Start auto-fishing.
bot.autoFish.help.stop=Stop auto-fishing.
bot.autoFish.help.help=Get the command description. Usage: /fish help <command name>
# AutoRelog # AutoRelog
bot.autoRelog.launch=Launching with {0} reconnection attempts bot.autoRelog.launch=Launching with {0} reconnection attempts
@ -900,7 +868,7 @@ config.ChatBot.AutoDrop.Mode="include", "exclude" or "everything". Include: drop
config.ChatBot.AutoEat=Automatically eat food when your Hunger value is low\n# You need to enable Inventory Handling to use this bot config.ChatBot.AutoEat=Automatically eat food when your Hunger value is low\n# You need to enable Inventory Handling to use this bot
# ChatBot.AutoFishing # ChatBot.AutoFishing
config.ChatBot.AutoFishing=Automatically catch fish using a fishing rod\n# Guide: https://mccteam.github.io/guide/chat-bots.html#auto-fishing\n# /!\ Make sure server rules allow automated farming before using this bot config.ChatBot.AutoFishing=Automatically catch fish using a fishing rod\n# Guide: https://mccteam.github.io/guide/chat-bots.html#auto-fishing\n# You can use "/fish" to control the bot manually.\n# /!\ Make sure server rules allow automated farming before using this bot
config.ChatBot.AutoFishing.Antidespawn=Keep it as false if you have not changed it before. config.ChatBot.AutoFishing.Antidespawn=Keep it as false if you have not changed it before.
config.ChatBot.AutoFishing.Mainhand=Use the mainhand or the offhand to hold the rod. config.ChatBot.AutoFishing.Mainhand=Use the mainhand or the offhand to hold the rod.
config.ChatBot.AutoFishing.Auto_Start=Whether to start fishing automatically after entering a world. config.ChatBot.AutoFishing.Auto_Start=Whether to start fishing automatically after entering a world.

View file

@ -52,13 +52,13 @@ If you'd like to contribute to Minecraft Console Client, great, just fork the re
Check out: [How to update or add translations for MCC](https://mccteam.github.io/guide/contibuting.html#translations). Check out: [How to update or add translations for MCC](https://mccteam.github.io/guide/contibuting.html#translations).
MCC now supports the following languages (Alphabetical order) : MCC now supports the following languages (Alphabetical order) :
* `de.ini` (49.19% translated) : Deutsch - German * `de.ini` (51.34% translated) : Deutsch - German
* `en.ini` : English - English * `en.ini` : English - English
* `fr.ini` (49.19% translated) : Français (France) - French * `fr.ini` (51.34% translated) : Français (France) - French
* `ru.ini` (48.38% translated) : Русский (Russkiy) - Russian * `ru.ini` (50.49% translated) : Русский (Russkiy) - Russian
* `vi.ini` (48.38% translated) : Tiếng Việt (Việt Nam) - Vietnamese * `vi.ini` (50.49% translated) : Tiếng Việt (Việt Nam) - Vietnamese
* `zh-Hans.ini` (90.43% translated) : 简体中文 - Chinese Simplified * `zh-Hans.ini` (95.50% translated) : 简体中文 - Chinese Simplified
* `zh-Hant.ini` (90.43% translated) : 繁體中文 - Chinese Traditional * `zh-Hant.ini` (95.50% translated) : 繁體中文 - Chinese Traditional
## Building from the source 🏗️ ## Building from the source 🏗️