Added Enchanting Table ASCII Art.

Added ChatBot method for enchantments.
Changed the how the list of enchantments looks, now looks cleaner + has Roman numbers.
Added safe guards to the echant command.
This commit is contained in:
Milutinke 2022-10-14 15:33:33 +02:00
parent 4dc1b420f5
commit c47add39a4
9 changed files with 277 additions and 88 deletions

View file

@ -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();

View file

@ -8,7 +8,8 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace MinecraftClient {
namespace MinecraftClient
{
using System;
@ -22,23 +23,28 @@ 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()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[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;
}
@ -51,11 +57,14 @@ namespace MinecraftClient {
/// resource lookups using this strongly typed resource class.
/// </summary>
[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;
}
}
@ -75,8 +84,10 @@ namespace MinecraftClient {
///║║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║10 ║11 ║12 ║13 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_BrewingStand {
get {
internal static string ContainerType_BrewingStand
{
get
{
return ResourceManager.GetString("ContainerType_BrewingStand", resourceCulture);
}
}
@ -96,11 +107,20 @@ namespace MinecraftClient {
///║║10 ║11 ║12 ║13 ║14 ║15 ║16 ║17 ║18 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]&quot;;.
/// </summary>
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);
}
}
/// <summary>
/// Looks up a localized string similar to ╔═════════════════════════════════════╗
@ -117,8 +137,10 @@ namespace MinecraftClient {
///║╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗║
///║║ 3 ║ 4 ║ 5 ║ 6 ║ 7 [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_Furnace {
get {
internal static string ContainerType_Furnace
{
get
{
return ResourceManager.GetString("ContainerType_Furnace", resourceCulture);
}
}
@ -138,8 +160,10 @@ namespace MinecraftClient {
///║║ 9 ║10 ║11 ║12 ║13 ║14 ║15 ║16 ║17 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_Generic_3x3 {
get {
internal static string ContainerType_Generic_3x3
{
get
{
return ResourceManager.GetString("ContainerType_Generic_3x3", resourceCulture);
}
}
@ -159,8 +183,10 @@ namespace MinecraftClient {
///║║27 ║28 ║29 ║30 ║31 ║32 ║33 ║34 ║35 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_Generic_9x3 {
get {
internal static string ContainerType_Generic_9x3
{
get
{
return ResourceManager.GetString("ContainerType_Generic_9x3", resourceCulture);
}
}
@ -180,8 +206,10 @@ namespace MinecraftClient {
///║║36 ║37 ║38 ║39 ║40 ║41 ║42 ║43 ║44 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_Generic_9x6 {
get {
internal static string ContainerType_Generic_9x6
{
get
{
return ResourceManager.GetString("ContainerType_Generic_9x6", resourceCulture);
}
}
@ -201,8 +229,10 @@ namespace MinecraftClient {
///║ ╚══╝ ╚══╝ ║
///║ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_Grindstone {
get {
internal static string ContainerType_Grindstone
{
get
{
return ResourceManager.GetString("ContainerType_Grindstone", resourceCulture);
}
}
@ -222,8 +252,10 @@ namespace MinecraftClient {
///║║23 ║24 ║25 ║26 ║27 ║28 ║29 ║30 ║31 ║║
///║╚═══╩═══╩═══╩═══╩══ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_Hopper {
get {
internal static string ContainerType_Hopper
{
get
{
return ResourceManager.GetString("ContainerType_Hopper", resourceCulture);
}
}
@ -243,8 +275,10 @@ namespace MinecraftClient {
///║║ 9 ║10 ║11 ║12 ║13 ║14 ║15 ║16 ║17 ║║
///║╠═══╬═══╬═══╬═══╬══ [rest of string was truncated]&quot;;.
/// </summary>
internal static string ContainerType_PlayerInventory {
get {
internal static string ContainerType_PlayerInventory
{
get
{
return ResourceManager.GetString("ContainerType_PlayerInventory", resourceCulture);
}
}
@ -265,8 +299,10 @@ namespace MinecraftClient {
///mcc.session_invalid=§8Gespeicherte Session ungültig oder abgelaufen.
///mcc.session_valid=§8Gespeicherte Ses [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_de {
get {
internal static string Translation_de
{
get
{
return ResourceManager.GetString("Translation_de", resourceCulture);
}
}
@ -285,8 +321,10 @@ namespace MinecraftClient {
///mcc.password_hidden=Password(invisible): {0}
///mcc.off [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_en {
get {
internal static string Translation_en
{
get
{
return ResourceManager.GetString("Translation_en", resourceCulture);
}
}
@ -307,8 +345,10 @@ namespace MinecraftClient {
///mcc.session_invalid=§8Le cache de la session est invalide ou a expiré.
///mcc.session_va [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_fr {
get {
internal static string Translation_fr
{
get
{
return ResourceManager.GetString("Translation_fr", resourceCulture);
}
}
@ -329,8 +369,10 @@ namespace MinecraftClient {
///mcc.session_invalid=§8Кэшированная сессия недействительна или истекла.
///mcc.session_valid=§8Кэшированная се [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_ru {
get {
internal static string Translation_ru
{
get
{
return ResourceManager.GetString("Translation_ru", resourceCulture);
}
}
@ -352,8 +394,10 @@ namespace MinecraftClient {
///mcc.session_valid=§8Phiên vẫn còn hợp lệ cho {0}.
///mcc.profile_ke [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_vi {
get {
internal static string Translation_vi
{
get
{
return ResourceManager.GetString("Translation_vi", resourceCulture);
}
}
@ -376,8 +420,10 @@ namespace MinecraftClient {
///mcc.profile_key_invalid=§8缓存的聊天签名密钥需要刷新。
///mcc.profile_key_valid=§8{0 [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_zh_Hans {
get {
internal static string Translation_zh_Hans
{
get
{
return ResourceManager.GetString("Translation_zh_Hans", resourceCulture);
}
}
@ -400,8 +446,10 @@ namespace MinecraftClient {
///mcc.profile_key_invalid=§8快取的聊天簽名金鑰需要重新整理。
///mcc.profile_key_valid [rest of string was truncated]&quot;;.
/// </summary>
internal static string Translation_zh_Hant {
get {
internal static string Translation_zh_Hant
{
get
{
return ResourceManager.GetString("Translation_zh_Hant", resourceCulture);
}
}

View file

@ -124,6 +124,9 @@
<data name="ContainerType_Crafting" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\containers\ContainerType.Crafting.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="ContainerType_EnchantingTable" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\containers\ContainerType.EnchantingTable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="ContainerType_Furnace" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\containers\ContainerType.Furnace.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>

View file

@ -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,

View file

@ -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<short, Enchantment> enchantmentMappings114 = new Dictionary<short, Enchantment>()
{
@ -92,7 +95,7 @@ namespace MinecraftClient.Inventory
private static Dictionary<Enchantment, string> enchantmentNames = new Dictionary<Enchantment, string>()
{
//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<string, int> romanNumbers = new Dictionary<string, int>
{
{"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;
}
}
}

View file

@ -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));
}
}
}

View file

@ -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 ║
╚═════════════════════════════════════╝

View file

@ -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

View file

@ -368,6 +368,32 @@ namespace MinecraftClient
/// <param name="propertyValue">Property Value</param>
public virtual void OnInventoryProperties(byte inventoryID, short propertyId, short propertyValue) { }
/// <summary>
/// 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
/// </summary>
/// <param name="topEnchantment">Enchantment in the top most slot</param>
/// <param name="middleEnchantment">Enchantment in the middle slot</param>
/// <param name="bottomEnchantment">Enchantment in the bottom slot</param>
/// <param name="topEnchantmentLevel">Enchantment level for the enchantment in the top most slot</param>
/// <param name="middleEnchantmentLevel">Enchantment level for the enchantment in the middle slot</param>
/// <param name="bottomEnchantmentLevel">Enchantment level for the enchantment in the bottom slot</param>
/// <param name="topEnchantmentLevelRequirement">Levels required by player for the enchantment in the top most slot</param>
/// <param name="middleEnchantmentLevelRequirement">Levels required by player for the enchantment in the middle slot</param>
/// <param name="bottomEnchantmentLevelRequirement">Levels required by player for the enchantment in the bottom slot</param>
public virtual void OnEnchantments(
Enchantment topEnchantment,
Enchantment middleEnchantment,
Enchantment bottomEnchantment,
short topEnchantmentLevel,
short middleEnchantmentLevel,
short bottomEnchantmentLevel,
short topEnchantmentLevelRequirement,
short middleEnchantmentLevelRequirement,
short bottomEnchantmentLevelRequirement)
{ }
/// <summary>
/// Called when a player joined the game
/// </summary>