diff --git a/MinecraftClient/Commands/Enchant.cs b/MinecraftClient/Commands/Enchant.cs
index 1830b147..db7a9f18 100644
--- a/MinecraftClient/Commands/Enchant.cs
+++ b/MinecraftClient/Commands/Enchant.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
using MinecraftClient.Inventory;
namespace MinecraftClient.Commands
@@ -27,21 +28,37 @@ namespace MinecraftClient.Commands
if (slotId == -1)
return Translations.TryGet("cmd.enchant.invalid_slot");
- int containerId = -1;
+ Container? enchantingTable = null;
foreach (var (id, container) in handler.GetInventories())
{
if (container.Type == ContainerType.Enchantment)
{
- containerId = id;
+ enchantingTable = container;
break;
}
}
- if (containerId == -1)
+ if (enchantingTable == null)
return Translations.TryGet("cmd.enchant.enchanting_table_not_opened");
- return handler.ClickContainerButton(containerId, slotId) ? Translations.TryGet("cmd.enchant.clicked") : Translations.TryGet("cmd.enchant.not_clicked");
+ int[] emptySlots = enchantingTable.GetEmpytSlots();
+
+ if (emptySlots.Contains(0))
+ return Translations.TryGet("cmd.enchant.enchanting_no_item");
+
+ if (emptySlots.Contains(1))
+ return Translations.TryGet("cmd.enchant.enchanting_no_lapis");
+
+ Item lapisSlot = enchantingTable.Items[1];
+
+ if (lapisSlot.Type != ItemType.LapisLazuli)
+ return Translations.TryGet("cmd.enchant.enchanting_no_lapis");
+
+ if (lapisSlot.Count < 3)
+ return Translations.TryGet("cmd.enchant.enchanting_no_lapis");
+
+ return handler.ClickContainerButton(enchantingTable.ID, slotId) ? Translations.TryGet("cmd.enchant.clicked") : Translations.TryGet("cmd.enchant.not_clicked");
}
return GetCmdDescTranslated();
diff --git a/MinecraftClient/DefaultConfigResource.Designer.cs b/MinecraftClient/DefaultConfigResource.Designer.cs
index cb31f5aa..f7ec6226 100644
--- a/MinecraftClient/DefaultConfigResource.Designer.cs
+++ b/MinecraftClient/DefaultConfigResource.Designer.cs
@@ -8,10 +8,11 @@
//
//------------------------------------------------------------------------------
-namespace MinecraftClient {
+namespace MinecraftClient
+{
using System;
-
-
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -22,44 +23,52 @@ namespace MinecraftClient {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DefaultConfigResource {
-
+ internal class DefaultConfigResource
+ {
+
private static global::System.Resources.ResourceManager resourceMan;
-
+
private static global::System.Globalization.CultureInfo resourceCulture;
-
+
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal DefaultConfigResource() {
+ internal DefaultConfigResource()
+ {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if (object.ReferenceEquals(resourceMan, null))
+ {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MinecraftClient.DefaultConfigResource", typeof(DefaultConfigResource).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
return resourceCulture;
}
- set {
+ set
+ {
resourceCulture = value;
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Brewing Stand ║
@@ -75,12 +84,14 @@ namespace MinecraftClient {
///║║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║10 ║11 ║12 ║13 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]";.
///
- internal static string ContainerType_BrewingStand {
- get {
+ internal static string ContainerType_BrewingStand
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_BrewingStand", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Crafting ║
@@ -96,12 +107,21 @@ namespace MinecraftClient {
///║║10 ║11 ║12 ║13 ║14 ║15 ║16 ║17 ║18 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]";.
///
- internal static string ContainerType_Crafting {
- get {
+ internal static string ContainerType_Crafting
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Crafting", resourceCulture);
}
}
-
+ internal static string ContainerType_EnchantingTable
+ {
+ get
+ {
+ return ResourceManager.GetString("ContainerType_EnchantingTable", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Container ║
@@ -117,12 +137,14 @@ namespace MinecraftClient {
///║╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗║
///║║ 3 ║ 4 ║ 5 ║ 6 ║ 7 [rest of string was truncated]";.
///
- internal static string ContainerType_Furnace {
- get {
+ internal static string ContainerType_Furnace
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Furnace", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Container ║
@@ -138,12 +160,14 @@ namespace MinecraftClient {
///║║ 9 ║10 ║11 ║12 ║13 ║14 ║15 ║16 ║17 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]";.
///
- internal static string ContainerType_Generic_3x3 {
- get {
+ internal static string ContainerType_Generic_3x3
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Generic_3x3", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Container ║
@@ -159,12 +183,14 @@ namespace MinecraftClient {
///║║27 ║28 ║29 ║30 ║31 ║32 ║33 ║34 ║35 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]";.
///
- internal static string ContainerType_Generic_9x3 {
- get {
+ internal static string ContainerType_Generic_9x3
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Generic_9x3", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Container ║
@@ -180,12 +206,14 @@ namespace MinecraftClient {
///║║36 ║37 ║38 ║39 ║40 ║41 ║42 ║43 ║44 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]";.
///
- internal static string ContainerType_Generic_9x6 {
- get {
+ internal static string ContainerType_Generic_9x6
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Generic_9x6", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Repair & Disenchant ║
@@ -201,12 +229,14 @@ namespace MinecraftClient {
///║ ╚══╝ ╚══╝ ║
///║ [rest of string was truncated]";.
///
- internal static string ContainerType_Grindstone {
- get {
+ internal static string ContainerType_Grindstone
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Grindstone", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║ Container ║
@@ -222,12 +252,14 @@ namespace MinecraftClient {
///║║23 ║24 ║25 ║26 ║27 ║28 ║29 ║30 ║31 ║║
///║╚═══╩═══╩═══╩═══╩══ [rest of string was truncated]";.
///
- internal static string ContainerType_Hopper {
- get {
+ internal static string ContainerType_Hopper
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_Hopper", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
///║╔═══╦═══════════╗ ║
@@ -243,12 +275,14 @@ namespace MinecraftClient {
///║║ 9 ║10 ║11 ║12 ║13 ║14 ║15 ║16 ║17 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]";.
///
- internal static string ContainerType_PlayerInventory {
- get {
+ internal static string ContainerType_PlayerInventory
+ {
+ get
+ {
return ResourceManager.GetString("ContainerType_PlayerInventory", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -265,12 +299,14 @@ namespace MinecraftClient {
///mcc.session_invalid=§8Gespeicherte Session ungültig oder abgelaufen.
///mcc.session_valid=§8Gespeicherte Ses [rest of string was truncated]";.
///
- internal static string Translation_de {
- get {
+ internal static string Translation_de
+ {
+ get
+ {
return ResourceManager.GetString("Translation_de", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -285,12 +321,14 @@ namespace MinecraftClient {
///mcc.password_hidden=Password(invisible): {0}
///mcc.off [rest of string was truncated]";.
///
- internal static string Translation_en {
- get {
+ internal static string Translation_en
+ {
+ get
+ {
return ResourceManager.GetString("Translation_en", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -307,12 +345,14 @@ namespace MinecraftClient {
///mcc.session_invalid=§8Le cache de la session est invalide ou a expiré.
///mcc.session_va [rest of string was truncated]";.
///
- internal static string Translation_fr {
- get {
+ internal static string Translation_fr
+ {
+ get
+ {
return ResourceManager.GetString("Translation_fr", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -329,12 +369,14 @@ namespace MinecraftClient {
///mcc.session_invalid=§8Кэшированная сессия недействительна или истекла.
///mcc.session_valid=§8Кэшированная се [rest of string was truncated]";.
///
- internal static string Translation_ru {
- get {
+ internal static string Translation_ru
+ {
+ get
+ {
return ResourceManager.GetString("Translation_ru", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -352,12 +394,14 @@ namespace MinecraftClient {
///mcc.session_valid=§8Phiên vẫn còn hợp lệ cho {0}.
///mcc.profile_ke [rest of string was truncated]";.
///
- internal static string Translation_vi {
- get {
+ internal static string Translation_vi
+ {
+ get
+ {
return ResourceManager.GetString("Translation_vi", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -376,12 +420,14 @@ namespace MinecraftClient {
///mcc.profile_key_invalid=§8缓存的聊天签名密钥需要刷新。
///mcc.profile_key_valid=§8{0 [rest of string was truncated]";.
///
- internal static string Translation_zh_Hans {
- get {
+ internal static string Translation_zh_Hans
+ {
+ get
+ {
return ResourceManager.GetString("Translation_zh_Hans", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to [mcc]
///# Messages from MCC itself
@@ -400,8 +446,10 @@ namespace MinecraftClient {
///mcc.profile_key_invalid=§8快取的聊天簽名金鑰需要重新整理。
///mcc.profile_key_valid [rest of string was truncated]";.
///
- internal static string Translation_zh_Hant {
- get {
+ internal static string Translation_zh_Hant
+ {
+ get
+ {
return ResourceManager.GetString("Translation_zh_Hant", resourceCulture);
}
}
diff --git a/MinecraftClient/DefaultConfigResource.resx b/MinecraftClient/DefaultConfigResource.resx
index 8bc4ea56..e6b21245 100644
--- a/MinecraftClient/DefaultConfigResource.resx
+++ b/MinecraftClient/DefaultConfigResource.resx
@@ -124,6 +124,9 @@
Resources\containers\ContainerType.Crafting.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
+
+ Resources\containers\ContainerType.EnchantingTable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
+
Resources\containers\ContainerType.Furnace.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
diff --git a/MinecraftClient/Inventory/ContainerTypeExtensions.cs b/MinecraftClient/Inventory/ContainerTypeExtensions.cs
index 166693e9..41c2217c 100644
--- a/MinecraftClient/Inventory/ContainerTypeExtensions.cs
+++ b/MinecraftClient/Inventory/ContainerTypeExtensions.cs
@@ -56,7 +56,7 @@
ContainerType.BlastFurnace => DefaultConfigResource.ContainerType_Furnace,
ContainerType.Furnace => DefaultConfigResource.ContainerType_Furnace,
ContainerType.Smoker => DefaultConfigResource.ContainerType_Furnace,
- ContainerType.Enchantment => null,
+ ContainerType.Enchantment => DefaultConfigResource.ContainerType_EnchantingTable,
ContainerType.BrewingStand => DefaultConfigResource.ContainerType_BrewingStand,
ContainerType.Merchant => null,
ContainerType.Beacon => null,
diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs
index 4f18e72a..791cdf37 100644
--- a/MinecraftClient/Inventory/EnchantmentMapping.cs
+++ b/MinecraftClient/Inventory/EnchantmentMapping.cs
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
+using System.Linq;
+using MinecraftClient.Commands;
using MinecraftClient.Protocol.Handlers;
namespace MinecraftClient.Inventory
{
public class EnchantmentMapping
{
+ #pragma warning disable format // @formatter:off
// 1.14 - 1.15.2
private static Dictionary enchantmentMappings114 = new Dictionary()
{
@@ -92,7 +95,7 @@ namespace MinecraftClient.Inventory
private static Dictionary enchantmentNames = new Dictionary()
{
//type
- { Enchantment.Protection, "Enchantment.Protection" } ,
+ { Enchantment.Protection, "Enchantment.Protection" },
{ Enchantment.FireProtection, "Enchantment.FireProtection" },
{ Enchantment.FeatherFalling, "Enchantment.FeatherFalling" },
{ Enchantment.BlastProtection, "Enchantment.BlastProtection" },
@@ -131,6 +134,7 @@ namespace MinecraftClient.Inventory
{ Enchantment.Mending, "Enchantment.Mending" },
{ Enchantment.VanishingCurse, "Enchantment.VanishingCurse" }
};
+#pragma warning restore format // @formatter:on
public static Enchantment GetEnchantmentById(int protocolVersion, short id)
{
@@ -151,9 +155,38 @@ namespace MinecraftClient.Inventory
public static string GetEnchantmentName(Enchantment enchantment)
{
if (!enchantmentNames.ContainsKey(enchantment))
- return "Unknown Enchantment with ID: " + ((int)enchantment) + " (Probably not named in the code yet)";
+ return "Unknown Enchantment with ID: " + ((short)enchantment) + " (Probably not named in the code yet)";
return Translations.TryGet(enchantmentNames[enchantment]);
}
+
+ public static string ConvertLevelToRomanNumbers(int num)
+ {
+ string result = string.Empty;
+ Dictionary romanNumbers = new Dictionary
+ {
+ {"M", 1000 },
+ {"CM", 900},
+ {"D", 500},
+ {"CD", 400},
+ {"C", 100},
+ {"XC", 90},
+ {"L", 50},
+ {"XL", 40},
+ {"X", 10},
+ {"IX", 9},
+ {"V", 5},
+ {"IV", 4},
+ {"I", 1}
+ };
+
+ foreach (var pair in romanNumbers)
+ {
+ result += string.Join(string.Empty, Enumerable.Repeat(pair.Key, num / pair.Value));
+ num %= pair.Value;
+ }
+
+ return result;
+ }
}
}
diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs
index 61060ecb..6667660e 100644
--- a/MinecraftClient/McClient.cs
+++ b/MinecraftClient/McClient.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
+using System.Transactions;
using MinecraftClient.ChatBots;
using MinecraftClient.Inventory;
using MinecraftClient.Logger;
@@ -2665,45 +2666,76 @@ namespace MinecraftClient
Container inventory = inventories[inventoryID];
- //Log.Info("Got a property " + propertyId + " with value: " + propertyValue);
-
if (inventory.Properties.ContainsKey(propertyId))
inventory.Properties.Remove(propertyId);
inventory.Properties.Add(propertyId, propertyValue);
+ Log.Info("Got a property " + propertyId + " with value: " + propertyValue);
+
DispatchBotEvent(bot => bot.OnInventoryProperties(inventoryID, propertyId, propertyValue));
if (inventory.Type == ContainerType.Enchantment)
{
// We got the last property for enchantment
- if ((int)propertyId == (int)EnchantmentPropertyInfo.BottomEnchantmentLevel && propertyValue != -1)
+ if (propertyId == 9 && propertyValue != -1)
{
- short topEnchantmentLevelRequirement = inventory.Properties[(int)EnchantmentPropertyInfo.TopEnchantmentLevelRequirement];
- short middleEnchantmentLevelRequirement = inventory.Properties[(int)EnchantmentPropertyInfo.MiddleEnchantmentLevelRequirement];
- short bottomEnchantmentLevelRequirement = inventory.Properties[(int)EnchantmentPropertyInfo.BottomEnchantmentLevelRequirement];
-
- short enchantmentSeed = inventory.Properties[(int)EnchantmentPropertyInfo.EnchantmentSeed];
+ short topEnchantmentLevelRequirement = inventory.Properties[0];
+ short middleEnchantmentLevelRequirement = inventory.Properties[1];
+ short bottomEnchantmentLevelRequirement = inventory.Properties[2];
Enchantment topEnchantment = EnchantmentMapping.GetEnchantmentById(
GetProtocolVersion(),
- inventory.Properties[(int)EnchantmentPropertyInfo.TopEnchantmentId]);
+ inventory.Properties[4]);
Enchantment middleEnchantment = EnchantmentMapping.GetEnchantmentById(
GetProtocolVersion(),
- inventory.Properties[(int)EnchantmentPropertyInfo.MiddleEnchantmentId]);
+ inventory.Properties[5]);
Enchantment bottomEnchantment = EnchantmentMapping.GetEnchantmentById(
GetProtocolVersion(),
- inventory.Properties[(int)EnchantmentPropertyInfo.BottomEnchantmentId]);
+ inventory.Properties[6]);
- short topEnchantmentLevel = inventory.Properties[(int)EnchantmentPropertyInfo.TopEnchantmentId];
- short middleEnchantmentLevel = inventory.Properties[(int)EnchantmentPropertyInfo.MiddleEnchantmentId];
- short bottomEnchantmentLevel = inventory.Properties[(int)EnchantmentPropertyInfo.BottomEnchantmentId];
+ short topEnchantmentLevel = inventory.Properties[7];
+ short middleEnchantmentLevel = inventory.Properties[8];
+ short bottomEnchantmentLevel = inventory.Properties[9];
- Log.Info(EnchantmentMapping.GetEnchantmentName(topEnchantment) + " " + topEnchantmentLevel + " > " + topEnchantmentLevelRequirement + " Levels");
- Log.Info(EnchantmentMapping.GetEnchantmentName(middleEnchantment) + " " + middleEnchantmentLevel + " > " + middleEnchantmentLevelRequirement + " Levels");
- Log.Info(EnchantmentMapping.GetEnchantmentName(bottomEnchantment) + " " + bottomEnchantmentLevel + " > " + bottomEnchantmentLevelRequirement + " Levels");
+ StringBuilder sb = new();
+
+ sb.AppendLine(Translations.TryGet("Enchantment.enchantments_available") + ":");
+
+ sb.AppendLine(Translations.TryGet("Enchantment.tops_slot") + ":\t"
+ + EnchantmentMapping.GetEnchantmentName(topEnchantment) + " "
+ + EnchantmentMapping.ConvertLevelToRomanNumbers(topEnchantmentLevel) + " ("
+ + topEnchantmentLevelRequirement + " " + Translations.TryGet("Enchantment.levels") + ")");
+
+ sb.AppendLine(Translations.TryGet("Enchantment.middle_slot") + ":\t"
+ + EnchantmentMapping.GetEnchantmentName(middleEnchantment) + " "
+ + EnchantmentMapping.ConvertLevelToRomanNumbers(middleEnchantmentLevel) + " ("
+ + middleEnchantmentLevelRequirement + " " + Translations.TryGet("Enchantment.levels") + ")");
+
+ sb.AppendLine(Translations.TryGet("Enchantment.bottom_slot") + ":\t"
+ + EnchantmentMapping.GetEnchantmentName(bottomEnchantment) + " "
+ + EnchantmentMapping.ConvertLevelToRomanNumbers(bottomEnchantmentLevel) + " ("
+ + bottomEnchantmentLevelRequirement + " " + Translations.TryGet("Enchantment.levels") + ")");
+
+ Log.Info(sb.ToString());
+
+ DispatchBotEvent(bot => bot.OnEnchantments(
+ // Enchantments
+ topEnchantment,
+ middleEnchantment,
+ bottomEnchantment,
+
+ // Enchantment levels
+ topEnchantmentLevel,
+ middleEnchantmentLevel,
+ bottomEnchantmentLevel,
+
+ // Required levels for enchanting
+ topEnchantmentLevelRequirement,
+ middleEnchantmentLevelRequirement,
+ bottomEnchantmentLevelRequirement));
}
}
}
diff --git a/MinecraftClient/Resources/containers/ContainerType.EnchantingTable.txt b/MinecraftClient/Resources/containers/ContainerType.EnchantingTable.txt
new file mode 100644
index 00000000..1ec0dd57
--- /dev/null
+++ b/MinecraftClient/Resources/containers/ContainerType.EnchantingTable.txt
@@ -0,0 +1,22 @@
+╔═════════════════════════════════════╗
+║ Enchant ║
+║ ╔════════════════════╗ ║
+║ ║ Top ║ ║
+║ ╔═══╦═══╗ ╠════════════════════╣ ║
+║ ║ 0 ║ 1 ║ ║ Middle ║ ║
+║ ╚═══╩═══╝ ╠════════════════════╣ ║
+║ ║ Bottom ║ ║
+║ ╚════════════════════╝ ║
+║ Inventory ║
+║╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗║
+║║ 2 ║ 3 ║ 4 ║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║10 ║║
+║╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣║
+║║11 ║12 ║13 ║14 ║15 ║16 ║17 ║18 ║19 ║║
+║╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣║
+║║20 ║21 ║22 ║23 ║24 ║25 ║26 ║27 ║28 ║║
+║╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝║
+║╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗║
+║║29 ║30 ║31 ║32 ║33 ║34 ║35 ║36 ║37 ║║
+║╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝║
+║ 1 2 3 4 5 6 7 8 9 ║
+╚═════════════════════════════════════╝
\ No newline at end of file
diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini
index 223919e8..a3e4a6ab 100644
--- a/MinecraftClient/Resources/lang/en.ini
+++ b/MinecraftClient/Resources/lang/en.ini
@@ -153,6 +153,12 @@ extra.entity_disabled=§cEntities are currently not handled for that MC version.
extra.entity_required=Please enable EntityHandling in the config file first.
# Enchantments
+Enchantment.enchantments_available=Enchantments available
+Enchantment.tops_slot=Top slot
+Enchantment.middle_slot=Middle slot
+Enchantment.bottom_slot=Bottom slot
+Enchantment.levels=Levels
+
Enchantment.Protection=Protection
Enchantment.FireProtection=Fire Protection
Enchantment.FeatherFalling=Feather Falling
@@ -308,6 +314,8 @@ cmd.enchant.invalid_slot=Invalid slot provided (Available: top, middle, bottom)!
cmd.enchant.enchanting_table_not_opened=You must open a an enchanting table in order to use this option!
cmd.enchant.clicked=Sent a click to the server, if you have enough levels and if you have placed the items in the correct slots it should enchant!
cmd.enchant.not_clicked=Could not click!
+cmd.enchant.enchanting_no_item=You must put an item inside the enchanting table in slot 0!
+cmd.enchant.enchanting_no_lapis=You must put at least 3 lapis lazuli inside the enchanting table in slot 1!
# Entitycmd
cmd.entityCmd.attacked=Entity attacked
diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs
index 45e976f1..6404f133 100644
--- a/MinecraftClient/Scripting/ChatBot.cs
+++ b/MinecraftClient/Scripting/ChatBot.cs
@@ -368,6 +368,32 @@ namespace MinecraftClient
/// Property Value
public virtual void OnInventoryProperties(byte inventoryID, short propertyId, short propertyValue) { }
+ ///
+ /// When received enchantments from the server this method is called
+ /// Enchantment levels are the levels of enchantment (eg. I, II, III, IV, V) (eg. Smite IV, Power III, Knockback II ..)
+ /// Enchantment level requirements are the levels that player needs to have in order to enchant the item
+ ///
+ /// Enchantment in the top most slot
+ /// Enchantment in the middle slot
+ /// Enchantment in the bottom slot
+ /// Enchantment level for the enchantment in the top most slot
+ /// Enchantment level for the enchantment in the middle slot
+ /// Enchantment level for the enchantment in the bottom slot
+ /// Levels required by player for the enchantment in the top most slot
+ /// Levels required by player for the enchantment in the middle slot
+ /// Levels required by player for the enchantment in the bottom slot
+ public virtual void OnEnchantments(
+ Enchantment topEnchantment,
+ Enchantment middleEnchantment,
+ Enchantment bottomEnchantment,
+ short topEnchantmentLevel,
+ short middleEnchantmentLevel,
+ short bottomEnchantmentLevel,
+ short topEnchantmentLevelRequirement,
+ short middleEnchantmentLevelRequirement,
+ short bottomEnchantmentLevelRequirement)
+ { }
+
///
/// Called when a player joined the game
///