diff --git a/Minecraft.Server.FourKit/.editorconfig b/Minecraft.Server.FourKit/.editorconfig
new file mode 100644
index 00000000..d7a83b70
--- /dev/null
+++ b/Minecraft.Server.FourKit/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# IDE1006: Naming Styles
+dotnet_diagnostic.IDE1006.severity = suggestion
diff --git a/Minecraft.Server.FourKit/Enchantments/AquaAffinityEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/AquaAffinityEnchantment.cs
new file mode 100644
index 00000000..970ea0df
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/AquaAffinityEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class AquaAffinityEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.CHAINMAIL_HELMET, Material.GOLD_HELMET, Material.IRON_HELMET, Material.DIAMOND_HELMET,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR_HEAD;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.WATER_WORKER;
+
+ public override int getMaxLevel() => 1;
+
+ public override string getName() => "aquaaffinity";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/BaneOfArthopodsEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/BaneOfArthopodsEnchantment.cs
new file mode 100644
index 00000000..1d5654e3
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/BaneOfArthopodsEnchantment.cs
@@ -0,0 +1,31 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+//name could be changed
+public class BaneOfArthropodsEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.DAMAGE_ALL,
+ EnchantmentType.DAMAGE_UNDEAD,
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.WEAPON;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.DAMAGE_ARTHOPODS;
+
+ public override int getMaxLevel() => 5;
+
+ public override string getName() => "arthopods"; //could be changed
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/BlastProtectionEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/BlastProtectionEnchantment.cs
new file mode 100644
index 00000000..3034302b
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/BlastProtectionEnchantment.cs
@@ -0,0 +1,34 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class BlastProtectionEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
+ Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
+ Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS,
+ Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
+ Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.PROTECTION_ENVIRONMENTAL,
+ EnchantmentType.PROTECTION_FIRE,
+ EnchantmentType.PROTECTION_PROJECTILE,
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.PROTECTION_EXPLOSIVE;
+
+ public override int getMaxLevel() => 4;
+
+ public override string getName() => "blastprotection";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/EfficiencyEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/EfficiencyEnchantment.cs
new file mode 100644
index 00000000..5428ae87
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/EfficiencyEnchantment.cs
@@ -0,0 +1,32 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class EfficiencyEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLD_PICKAXE, Material.DIAMOND_PICKAXE,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ Material.WOOD_SPADE, Material.STONE_SPADE, Material.IRON_SPADE, Material.GOLD_SPADE, Material.DIAMOND_SPADE,
+ Material.WOOD_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.GOLD_HOE, Material.DIAMOND_HOE,
+
+ Material.SHEARS
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.TOOL;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.DIG_SPEAD;
+
+ public override int getMaxLevel() => 5;
+
+ public override string getName() => "efficiency";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/Enchantment.cs b/Minecraft.Server.FourKit/Enchantments/Enchantment.cs
new file mode 100644
index 00000000..e3daa549
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/Enchantment.cs
@@ -0,0 +1,274 @@
+namespace Minecraft.Server.FourKit.Enchantments;
+
+using Minecraft.Server.FourKit.Inventory;
+
+///
+/// Represents the applicable target for a Enchantment
+///
+public enum EnchantmentTarget
+{
+ ///
+ /// Allows the Enchantment to be placed on all items
+ ///
+ ALL,
+ ///
+ /// Allows the Enchantment to be placed on armor
+ ///
+ ARMOR,
+ ///
+ /// Allows the Enchantment to be placed on feet slot armor
+ ///
+ ARMOR_FEET,
+ ///
+ /// Allows the Enchantment to be placed on head slot armor
+ ///
+ ARMOR_HEAD,
+ ///
+ /// Allows the Enchantment to be placed on leg slot armor
+ ///
+ ARMOR_LEGS,
+ ///
+ /// Allows the Enchantment to be placed on torso slot armor
+ ///
+ ARMOR_TORSO,
+ ///
+ /// Allows the Enchantment to be placed on bows.
+ ///
+ BOW,
+ ///
+ /// Allows the Enchantment to be placed on tools (spades, pickaxe, hoes, axes)
+ ///
+ TOOL,
+ ///
+ /// Allows the Enchantment to be placed on weapons (swords)
+ ///
+ WEAPON,
+}
+
+//these numbers match the same ones that the enchants register as, Enchantment.cpp - 41
+
+///
+/// The various type of enchantments that may be added to armour or weapons
+///
+public enum EnchantmentType
+{
+ ///
+ /// Provides extra damage when shooting arrows from bows
+ ///
+ ARROW_DAMAGE = 48,
+ ///
+ /// Sets entities on fire when hit by arrows shot from a bow
+ ///
+ ARROW_FIRE = 50,
+ ///
+ /// Provides infinite arrows when shooting a bow
+ ///
+ ARROW_INFINITE = 51,
+ ///
+ /// Provides a knockback when an entity is hit by an arrow from a bow
+ ///
+ ARROW_KNOCKBACK = 49,
+ ///
+ /// Increases damage against all targets
+ ///
+ DAMAGE_ALL = 16,
+ ///
+ /// Increases damage against arthropod targets
+ ///
+ DAMAGE_ARTHOPODS = 18,
+ ///
+ /// Increases damage against undead targets
+ ///
+ DAMAGE_UNDEAD = 17,
+ ///
+ /// Increases the rate at which you mine/dig
+ ///
+ DIG_SPEAD = 32,
+ ///
+ /// Decreases the rate at which a tool looses durability
+ ///
+ DURABILITY = 34,
+ ///
+ /// When attacking a target, has a chance to set them on fire
+ ///
+ FIRE_ASPECT = 20,
+ ///
+ /// All damage to other targets will knock them back when hit
+ ///
+ KNOCKBACK = 19,
+ ///
+ /// Provides a chance of gaining extra loot when destroying blocks
+ ///
+ LOOT_BONUS_BLOCKS = 35,
+ ///
+ /// Provides a chance of gaining extra loot when killing monsters
+ ///
+ LOOT_BONUS_MOBS = 21,
+ ///
+ /// Decreases the rate of air loss whilst underwater
+ ///
+ OXYGEN = 5,
+ ///
+ /// Provides protection against environmental damage
+ ///
+ PROTECTION_ENVIRONMENTAL = 0,
+ ///
+ /// Provides protection against explosive damage
+ ///
+ PROTECTION_EXPLOSIVE = 3,
+ ///
+ /// Provides protection against fall damage
+ ///
+ PROTECTION_FALL = 2,
+ ///
+ /// Provides protection against fire damage
+ ///
+ PROTECTION_FIRE = 1,
+ ///
+ /// Provides protection against projectile damage
+ ///
+ PROTECTION_PROJECTILE = 4,
+ ///
+ /// Allows blocks to drop themselves instead of fragments (for example, stone instead of cobblestone)
+ ///
+ SILK_TOUCH = 33,
+ ///
+ /// Damages the attacker
+ ///
+ THORNS = 7,
+ ///
+ /// Increases the speed at which a player may mine underwater
+ ///
+ WATER_WORKER = 6
+}
+
+public abstract class Enchantment
+{
+ public static Enchantment PowerEnchantment => _registry[EnchantmentType.ARROW_DAMAGE];
+ public static Enchantment FlameEnchantment => _registry[EnchantmentType.ARROW_FIRE];
+ public static Enchantment InfinityEnchantment => _registry[EnchantmentType.ARROW_INFINITE];
+ public static Enchantment PunchEnchantment => _registry[EnchantmentType.ARROW_KNOCKBACK];
+ public static Enchantment SharpnessEnchantment => _registry[EnchantmentType.DAMAGE_ALL];
+ public static Enchantment BaneOfArthropodsEnchantment => _registry[EnchantmentType.DAMAGE_ARTHOPODS];
+ public static Enchantment SmiteEnchantment => _registry[EnchantmentType.DAMAGE_UNDEAD];
+ public static Enchantment EfficiencyEnchantment => _registry[EnchantmentType.DIG_SPEAD];
+ public static Enchantment UnbreakingEnchantment => _registry[EnchantmentType.DURABILITY];
+ public static Enchantment FireAspectEnchantment => _registry[EnchantmentType.FIRE_ASPECT];
+ public static Enchantment KnockbackEnchantment => _registry[EnchantmentType.KNOCKBACK];
+ public static Enchantment FortuneEnchantment => _registry[EnchantmentType.LOOT_BONUS_BLOCKS];
+ public static Enchantment LootingEnchantment => _registry[EnchantmentType.LOOT_BONUS_MOBS];
+ public static Enchantment RespirationEnchantment => _registry[EnchantmentType.OXYGEN];
+ public static Enchantment ProtectionEnchantment => _registry[EnchantmentType.PROTECTION_ENVIRONMENTAL];
+ public static Enchantment BlastProtectionEnchantment => _registry[EnchantmentType.PROTECTION_EXPLOSIVE];
+ public static Enchantment FeatherFallingEnchantment => _registry[EnchantmentType.PROTECTION_FALL];
+ public static Enchantment FireProtectionEnchantment => _registry[EnchantmentType.PROTECTION_FIRE];
+ public static Enchantment ProjectileProtectionEnchantment => _registry[EnchantmentType.PROTECTION_PROJECTILE];
+ public static Enchantment SilkTouchEnchantment => _registry[EnchantmentType.SILK_TOUCH];
+ public static Enchantment ThornsEnchantment => _registry[EnchantmentType.THORNS];
+ public static Enchantment AquaAffinityEnchantment => _registry[EnchantmentType.WATER_WORKER];
+
+
+ private static Dictionary _registry = new Dictionary()
+ {
+ { EnchantmentType.ARROW_DAMAGE, new PowerEnchantment() },
+ { EnchantmentType.ARROW_FIRE, new FlameEnchantment() },
+ { EnchantmentType.ARROW_INFINITE, new InfinityEnchantment() },
+ { EnchantmentType.ARROW_KNOCKBACK, new PunchEnchantment() },
+ { EnchantmentType.DAMAGE_ALL, new SharpnessEnchantment() },
+ { EnchantmentType.DAMAGE_ARTHOPODS, new BaneOfArthropodsEnchantment() },
+ { EnchantmentType.DAMAGE_UNDEAD, new SmiteEnchantment() },
+ { EnchantmentType.DIG_SPEAD, new EfficiencyEnchantment() },
+ { EnchantmentType.DURABILITY, new UnbreakingEnchantment() },
+ { EnchantmentType.FIRE_ASPECT, new FireAspectEnchantment() },
+ { EnchantmentType.KNOCKBACK, new KnockbackEnchantment() },
+ { EnchantmentType.LOOT_BONUS_BLOCKS, new FortuneEnchantment() },
+ { EnchantmentType.LOOT_BONUS_MOBS, new LootingEnchantment() },
+ { EnchantmentType.OXYGEN, new RespirationEnchantment() },
+ { EnchantmentType.PROTECTION_ENVIRONMENTAL, new ProtectionEnchantment() },
+ { EnchantmentType.PROTECTION_EXPLOSIVE, new BlastProtectionEnchantment() },
+ { EnchantmentType.PROTECTION_FALL, new FeatherFallingEnchantment() },
+ { EnchantmentType.PROTECTION_FIRE, new FireProtectionEnchantment() },
+ { EnchantmentType.PROTECTION_PROJECTILE, new ProjectileProtectionEnchantment() },
+ { EnchantmentType.SILK_TOUCH, new SilkTouchEnchantment() },
+ { EnchantmentType.THORNS, new ThornsEnchantment() },
+ { EnchantmentType.WATER_WORKER, new AquaAffinityEnchantment() },
+ };
+
+ ///
+ /// Checks if this Enchantment may be applied to the given . This does not check if it conflicts with any enchantments already applied to the item.
+ ///
+ /// Item to test
+ /// True if the enchantment may be applied, otherwise False
+ public abstract bool canEnchantItem(ItemStack item);
+
+ ///
+ /// Check if this enchantment conflicts with another enchantment.
+ ///
+ /// The enchantment to check against
+ /// True if there is a conflict.
+ public abstract bool conflictsWith(Enchantment other);
+ //public abstract Enchantment getById(int id); //deprecated by bukkit
+
+ ///
+ /// Gets the Enchantment at the specified name
+ ///
+ /// Name to fetch.
+ /// Resulting Enchantment, or null if not found
+ public static Enchantment? getByName(string name)
+ {
+ foreach (KeyValuePair enchantmentPair in _registry)
+ {
+ if (enchantmentPair.Value.getName().Equals(name)) return enchantmentPair.Value;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the Enchantment at the specified type
+ ///
+ /// Type to fetch.
+ /// Resulting Enchantment, or null if not found
+ public static Enchantment getByType(EnchantmentType type)
+ {
+ return _registry[type]; //we should always have the enchant based on the type
+ }
+
+ //public abstract int getId(); //deprecated by bukkit
+
+ ///
+ /// Gets the type of that may fit this Enchantment.
+ ///
+ /// Gets the type of that may fit this Enchantment.
+ public abstract EnchantmentTarget getItemTarget();
+
+ ///
+ /// Returns the .
+ ///
+ /// Gets the enchantment type.
+ public abstract EnchantmentType getEnchantType();
+
+ ///
+ /// Gets the maximum level that this Enchantment may become.
+ ///
+ /// Maximum level of the Enchantment
+ public abstract int getMaxLevel();
+
+
+ ///
+ /// Gets the unique name of this enchantment
+ ///
+ /// Unique name
+ public abstract string getName();
+
+ ///
+ /// Gets the level that this Enchantment should start at
+ ///
+ /// Starting level of the Enchantment
+ public abstract int getStartLevel();
+
+ //public static bool isAcceptingRegistrations(); //we dont have enchant registrations
+ //public static void registerEnchantment(Enchantment enchantment); //we dont have enchant registrations
+ //public static void stopAcceptingRegistrations(); //we dont have enchant registrations
+
+}
\ No newline at end of file
diff --git a/Minecraft.Server.FourKit/Enchantments/FeatherFallingEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/FeatherFallingEnchantment.cs
new file mode 100644
index 00000000..f27e56d2
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/FeatherFallingEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class FeatherFallingEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_BOOTS, Material.LEATHER_BOOTS, Material.CHAINMAIL_BOOTS, Material.GOLD_BOOTS, Material.IRON_BOOTS, Material.DIAMOND_BOOTS,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR_FEET;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.PROTECTION_FALL;
+
+ public override int getMaxLevel() => 4;
+
+ public override string getName() => "featherfalling";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/FireAspectEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/FireAspectEnchantment.cs
new file mode 100644
index 00000000..c7a8b5c5
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/FireAspectEnchantment.cs
@@ -0,0 +1,27 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class FireAspectEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.WEAPON;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.FIRE_ASPECT;
+
+ public override int getMaxLevel() => 2;
+
+ public override string getName() => "fireaspect";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/FireProtectionEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/FireProtectionEnchantment.cs
new file mode 100644
index 00000000..09f2c8ea
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/FireProtectionEnchantment.cs
@@ -0,0 +1,34 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class FireProtectionEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
+ Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
+ Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS,
+ Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
+ Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.PROTECTION_ENVIRONMENTAL,
+ EnchantmentType.PROTECTION_EXPLOSIVE,
+ EnchantmentType.PROTECTION_PROJECTILE,
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.PROTECTION_FIRE;
+
+ public override int getMaxLevel() => 4;
+
+ public override string getName() => "fireprotection";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/FlameEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/FlameEnchantment.cs
new file mode 100644
index 00000000..4166170b
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/FlameEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class FlameEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.BOW
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.BOW;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.ARROW_FIRE;
+
+ public override int getMaxLevel() => 1;
+
+ public override string getName() => "flame";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/FortuneEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/FortuneEnchantment.cs
new file mode 100644
index 00000000..d3477b27
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/FortuneEnchantment.cs
@@ -0,0 +1,31 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class FortuneEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLD_PICKAXE, Material.DIAMOND_PICKAXE,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ Material.WOOD_SPADE, Material.STONE_SPADE, Material.IRON_SPADE, Material.GOLD_SPADE, Material.DIAMOND_SPADE,
+ Material.WOOD_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.GOLD_HOE, Material.DIAMOND_HOE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.SILK_TOUCH
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.TOOL;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.LOOT_BONUS_BLOCKS;
+
+ public override int getMaxLevel() => 3;
+
+ public override string getName() => "fortune";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/InfinityEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/InfinityEnchantment.cs
new file mode 100644
index 00000000..f1c697b7
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/InfinityEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class InfinityEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.BOW
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.BOW;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.ARROW_INFINITE;
+
+ public override int getMaxLevel() => 1;
+
+ public override string getName() => "infinity";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/KnockbackEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/KnockbackEnchantment.cs
new file mode 100644
index 00000000..5a508a42
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/KnockbackEnchantment.cs
@@ -0,0 +1,27 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class KnockbackEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.WEAPON;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.KNOCKBACK;
+
+ public override int getMaxLevel() => 2;
+
+ public override string getName() => "knockback";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/LootingEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/LootingEnchantment.cs
new file mode 100644
index 00000000..710b6518
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/LootingEnchantment.cs
@@ -0,0 +1,27 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class LootingEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLD_PICKAXE, Material.DIAMOND_PICKAXE,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.WEAPON;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.LOOT_BONUS_MOBS;
+
+ public override int getMaxLevel() => 3;
+
+ public override string getName() => "looting";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/PowerEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/PowerEnchantment.cs
new file mode 100644
index 00000000..f5e93e5a
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/PowerEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class PowerEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.BOW
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.BOW;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.ARROW_DAMAGE;
+
+ public override int getMaxLevel() => 5;
+
+ public override string getName() => "power";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/ProjectileProtectionEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/ProjectileProtectionEnchantment.cs
new file mode 100644
index 00000000..31706216
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/ProjectileProtectionEnchantment.cs
@@ -0,0 +1,34 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class ProjectileProtectionEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
+ Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
+ Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS,
+ Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
+ Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.PROTECTION_ENVIRONMENTAL,
+ EnchantmentType.PROTECTION_EXPLOSIVE,
+ EnchantmentType.PROTECTION_FIRE,
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.PROTECTION_PROJECTILE;
+
+ public override int getMaxLevel() => 4;
+
+ public override string getName() => "projectileprotection";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/ProtectionEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/ProtectionEnchantment.cs
new file mode 100644
index 00000000..70fe5d85
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/ProtectionEnchantment.cs
@@ -0,0 +1,34 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class ProtectionEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
+ Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
+ Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS,
+ Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
+ Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.PROTECTION_EXPLOSIVE,
+ EnchantmentType.PROTECTION_FIRE,
+ EnchantmentType.PROTECTION_PROJECTILE,
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.PROTECTION_ENVIRONMENTAL;
+
+ public override int getMaxLevel() => 4;
+
+ public override string getName() => "protection";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/PunchEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/PunchEnchantment.cs
new file mode 100644
index 00000000..3fb5b3e0
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/PunchEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class PunchEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.BOW
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.BOW;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.ARROW_KNOCKBACK;
+
+ public override int getMaxLevel() => 2;
+
+ public override string getName() => "punch";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/RespirationEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/RespirationEnchantment.cs
new file mode 100644
index 00000000..8d599077
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/RespirationEnchantment.cs
@@ -0,0 +1,26 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class RespirationEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.CHAINMAIL_HELMET, Material.GOLD_HELMET, Material.IRON_HELMET, Material.DIAMOND_HELMET,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR_HEAD;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.OXYGEN;
+
+ public override int getMaxLevel() => 3;
+
+ public override string getName() => "respiration";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/SharpnessEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/SharpnessEnchantment.cs
new file mode 100644
index 00000000..00421a7b
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/SharpnessEnchantment.cs
@@ -0,0 +1,30 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class SharpnessEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.DAMAGE_ARTHOPODS,
+ EnchantmentType.DAMAGE_UNDEAD
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.WEAPON;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.DAMAGE_ALL;
+
+ public override int getMaxLevel() => 5;
+
+ public override string getName() => "sharpness";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/SilkTouchEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/SilkTouchEnchantment.cs
new file mode 100644
index 00000000..01c2bbce
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/SilkTouchEnchantment.cs
@@ -0,0 +1,33 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class SilkTouchEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLD_PICKAXE, Material.DIAMOND_PICKAXE,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ Material.WOOD_SPADE, Material.STONE_SPADE, Material.IRON_SPADE, Material.GOLD_SPADE, Material.DIAMOND_SPADE,
+ Material.WOOD_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.GOLD_HOE, Material.DIAMOND_HOE,
+
+ Material.SHEARS
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.LOOT_BONUS_BLOCKS
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.TOOL;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.SILK_TOUCH;
+
+ public override int getMaxLevel() => 1;
+
+ public override string getName() => "silktouch";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/SmiteEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/SmiteEnchantment.cs
new file mode 100644
index 00000000..6bc95082
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/SmiteEnchantment.cs
@@ -0,0 +1,30 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class SmiteEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = {
+ EnchantmentType.DAMAGE_ALL,
+ EnchantmentType.DAMAGE_ARTHOPODS
+ };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.WEAPON;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.DAMAGE_UNDEAD;
+
+ public override int getMaxLevel() => 5;
+
+ public override string getName() => "smite";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/ThornsEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/ThornsEnchantment.cs
new file mode 100644
index 00000000..fc6ea8e2
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/ThornsEnchantment.cs
@@ -0,0 +1,30 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class ThornsEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
+ Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
+ Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS,
+ Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
+ Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ARMOR;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.THORNS;
+
+ public override int getMaxLevel() => 3;
+
+ public override string getName() => "thorns";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Enchantments/UnbreakingEnchantment.cs b/Minecraft.Server.FourKit/Enchantments/UnbreakingEnchantment.cs
new file mode 100644
index 00000000..a83039ab
--- /dev/null
+++ b/Minecraft.Server.FourKit/Enchantments/UnbreakingEnchantment.cs
@@ -0,0 +1,39 @@
+using Minecraft.Server.FourKit.Inventory;
+
+namespace Minecraft.Server.FourKit.Enchantments;
+
+public class UnbreakingEnchantment : Enchantment
+{
+ static readonly Material[] supportedItems = {
+ Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD,
+ Material.WOOD_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLD_PICKAXE, Material.DIAMOND_PICKAXE,
+ Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE,
+ Material.WOOD_SPADE, Material.STONE_SPADE, Material.IRON_SPADE, Material.GOLD_SPADE, Material.DIAMOND_SPADE,
+ Material.WOOD_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.GOLD_HOE, Material.DIAMOND_HOE,
+
+ Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
+ Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
+ Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS,
+ Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
+ Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
+
+ Material.FISHING_ROD, Material.BOW,
+ Material.SHEARS, Material.FLINT_AND_STEEL, Material.CARROT_STICK
+ };
+
+ static readonly EnchantmentType[] conflictedEnchants = { };
+
+ public override bool canEnchantItem(ItemStack item) => supportedItems.Contains(item.getType());
+
+ public override bool conflictsWith(Enchantment other) => conflictedEnchants.Contains(other.getEnchantType());
+
+ public override EnchantmentTarget getItemTarget() => EnchantmentTarget.ALL;
+
+ public override EnchantmentType getEnchantType() => EnchantmentType.DURABILITY;
+
+ public override int getMaxLevel() => 3;
+
+ public override string getName() => "unbreaking";
+
+ public override int getStartLevel() => 1;
+}
diff --git a/Minecraft.Server.FourKit/Inventory/ItemStack.cs b/Minecraft.Server.FourKit/Inventory/ItemStack.cs
index e5c9a5b5..5af48d3f 100644
--- a/Minecraft.Server.FourKit/Inventory/ItemStack.cs
+++ b/Minecraft.Server.FourKit/Inventory/ItemStack.cs
@@ -126,6 +126,7 @@ public class ItemStack
public bool setItemMeta(ItemMeta? itemMeta)
{
_meta = itemMeta?.clone();
+ SyncToOwner();
return true;
}
diff --git a/Minecraft.Server.FourKit/Inventory/Meta/ItemMeta.cs b/Minecraft.Server.FourKit/Inventory/Meta/ItemMeta.cs
index 5da46c5a..60ba224c 100644
--- a/Minecraft.Server.FourKit/Inventory/Meta/ItemMeta.cs
+++ b/Minecraft.Server.FourKit/Inventory/Meta/ItemMeta.cs
@@ -1,11 +1,14 @@
namespace Minecraft.Server.FourKit.Inventory.Meta;
+using Minecraft.Server.FourKit.Enchantments;
+
///
/// Represents the metadata of an , including display name and lore.
///
public class ItemMeta
{
private string? _displayName;
+ private Dictionary? _enchants;
private List? _lore;
///
@@ -49,16 +52,123 @@ public class ItemMeta
_lore = lore != null ? new List(lore) : null;
}
+ ///
+ /// Adds the specified enchantment to this item meta.
+ ///
+ /// Enchantment to add
+ /// Level for the enchantment
+ /// Indicates the enchantment should be applied, ignoring the level limit
+ /// true if the item meta changed as a result of this call, false otherwise
+ public bool addEnchant(EnchantmentType enchantment, int level, bool ignoreLevelRestriction)
+ {
+ if (_enchants == null)
+ _enchants = new Dictionary();
+
+ if (!ignoreLevelRestriction)
+ {
+ Enchantment enchant = Enchantment.getByType(enchantment);
+
+ if (enchant.getMaxLevel() < level) return false;
+ }
+
+ try
+ {
+ _enchants.Add(enchantment, level);
+ return true;
+ } catch { }
+
+ return false;
+ }
+
+ ///
+ /// Removes the specified enchantment from this item meta.
+ ///
+ /// Enchantment to remove
+ /// true if the item meta changed as a result of this call, false otherwise
+ public bool removeEnchant(EnchantmentType enchantment)
+ {
+ if (!hasEnchant(enchantment)) return false;
+
+ return _enchants.Remove(enchantment);
+ }
+
+ ///
+ /// Returns a copy of the enchantments in this ItemMeta. Returns an empty map if none.
+ ///
+ /// An immutable copy of the enchantments
+ public Dictionary getEnchants() => _enchants != null ? new Dictionary(_enchants) { } : new Dictionary();
+
+ ///
+ /// Checks for the level of the specified enchantment.
+ ///
+ /// Enchantment to check
+ /// The level that the specified enchantment has, or 0 if none
+ public int getEnchantLevel(EnchantmentType enchantment)
+ {
+ if (!hasEnchant(enchantment)) return 0;
+
+ return _enchants[enchantment]; //this cant be invalid, we check above
+ }
+
+ ///
+ /// Checks if the specified enchantment conflicts with any enchantments in this ItemMeta.
+ ///
+ /// Enchantment to test
+ /// true if the enchantment conflicts, false otherwise
+ public bool hasConflictingEnchant(EnchantmentType enchantment)
+ {
+ Enchantment enchantmentClass = Enchantment.getByType(enchantment);
+ if (enchantmentClass == null) return false; //this should never happen
+
+ foreach (KeyValuePair ench in _enchants)
+ {
+ Enchantment enchClass = Enchantment.getByType(ench.Key);
+
+ if (enchClass == null) continue; //this should never happen
+
+ if (enchClass.conflictsWith(enchantmentClass))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Checks for existence of the specified enchantment.
+ ///
+ /// Enchantment to check
+ /// true if this enchantment exists for this meta
+ public bool hasEnchant(EnchantmentType enchantment) => hasEnchants() && _enchants.ContainsKey(enchantment);
+
+ ///
+ /// Checks for the existence of any enchantments.
+ ///
+ /// true if an enchantment exists on this meta
+ public bool hasEnchants() => _enchants != null && _enchants.Count > 0;
+
+ ///
+ /// Sets the enchantments for this item meta.
+ ///
+ /// The enchantments to set.
+ public void setEnchants(Dictionary? enchants)
+ {
+ enchants = enchants != null ? new Dictionary(enchants) : null;
+ }
+
+
public ItemMeta clone()
{
var copy = new ItemMeta();
copy._displayName = _displayName;
+ copy._enchants = _enchants != null ? new Dictionary(_enchants) : null;
copy._lore = _lore != null ? new List(_lore) : null;
return copy;
}
internal bool isEmpty()
{
- return _displayName == null && (_lore == null || _lore.Count == 0);
+ return _displayName == null && (_lore == null || _lore.Count == 0) && (_enchants == null || _enchants.Count == 0);
}
}
diff --git a/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs b/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs
index 6a165d30..bc33a9ea 100644
--- a/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs
+++ b/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs
@@ -1,7 +1,9 @@
namespace Minecraft.Server.FourKit.Inventory;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
+using Minecraft.Server.FourKit.Enchantments;
using Minecraft.Server.FourKit.Entity;
using Minecraft.Server.FourKit.Inventory.Meta;
@@ -154,7 +156,10 @@ public class PlayerInventory : Inventory
/// Gets the item the player is currently holding.
///
/// The held ItemStack.
- public ItemStack? getItemInHand() => getItem(_heldItemSlot);
+ public ItemStack? getItemInHand() {
+ EnsureSynced();
+ return getItem(_heldItemSlot);
+ }
///
/// Sets the item in the player's hand.
@@ -278,7 +283,33 @@ public class PlayerInventory : Inventory
}
}
- if (displayName == null && (lore == null || lore.Count == 0))
+ int enchantCount = 0;
+ if (offset + 4 <= bytesWritten)
+ {
+ enchantCount = BitConverter.ToInt32(buf, offset);
+ offset += 4;
+ }
+
+ Dictionary? enchants = null;
+ if (enchantCount > 0)
+ {
+ enchants = new Dictionary(enchantCount);
+ for (int i = 0; i < enchantCount; i++)
+ {
+ if (offset + (4 + 4) > bytesWritten)
+ break;
+
+ int type = BitConverter.ToInt32(buf, offset);
+ offset += 4;
+
+ int level = BitConverter.ToInt32(buf, offset);
+ offset += 4;
+
+ enchants.Add((EnchantmentType)type, level);
+ }
+ }
+
+ if (displayName == null && (lore == null || lore.Count == 0) && (enchants == null || enchants.Count == 0))
return null;
var meta = new ItemMeta();
@@ -286,6 +317,8 @@ public class PlayerInventory : Inventory
meta.setDisplayName(displayName);
if (lore != null && lore.Count > 0)
meta.setLore(lore);
+ if (enchants != null && enchants.Count > 0)
+ meta.setEnchants(enchants);
return meta;
}
@@ -330,6 +363,27 @@ public class PlayerInventory : Inventory
bw.Write(0);
}
+ if (meta.hasEnchants())
+ {
+
+ Debug.WriteLine("Writting Enchants");
+ var enchants = meta.getEnchants();
+ bw.Write(enchants.Count);
+ foreach (var enchant in enchants)
+ {
+ Debug.WriteLine("Wrote A Enchant");
+
+ bw.Write((int)enchant.Key);
+ bw.Write(enchant.Value);
+ }
+ }
+ else
+ {
+ Debug.WriteLine("Had No Enchants");
+
+ bw.Write(0);
+ }
+
bw.Flush();
byte[] data = ms.ToArray();
var gh = GCHandle.Alloc(data, GCHandleType.Pinned);
diff --git a/Minecraft.Server/FourKitNatives.cpp b/Minecraft.Server/FourKitNatives.cpp
index 00c072da..dc6c843c 100644
--- a/Minecraft.Server/FourKitNatives.cpp
+++ b/Minecraft.Server/FourKitNatives.cpp
@@ -41,6 +41,7 @@
#include "Access\Access.h"
#include "Common\NetworkUtils.h"
#include "ServerLogManager.h"
+#include "../Minecraft.World/ItemInstance.cpp"
namespace
{
@@ -751,10 +752,12 @@ void __cdecl NativeOpenVirtualContainer(int entityId, int nativeType, const char
player->openContainer(container);
}
-
+//didnt update this for enchants
// [nameLen:int32][nameUTF8:bytes][loreCount:int32][lore0Len:int32][lore0UTF8:bytes]
int __cdecl NativeGetItemMeta(int entityId, int slot, char *outBuf, int bufSize)
{
+ printf("NativeGetItemMeta::entry\n");
+
auto player = FindPlayer(entityId);
if (!player || !player->inventory)
return 0;
@@ -775,6 +778,8 @@ int __cdecl NativeGetItemMeta(int entityId, int slot, char *outBuf, int bufSize)
bool hasName = display->contains(L"Name");
bool hasLore = display->contains(L"Lore");
+ bool hasEnchantments = item->isEnchanted();
+
if (!hasName && !hasLore)
return 0;
@@ -827,6 +832,34 @@ int __cdecl NativeGetItemMeta(int entityId, int slot, char *outBuf, int bufSize)
offset += 4;
}
+ if (hasEnchantments) {
+ ListTag* list = item->getEnchantmentTags();
+ if (list != nullptr) {
+ int listSize = list->size();
+
+ if ((offset + 4 + (listSize * (4 + 4))) > bufSize) return 0;
+
+ memcpy(outBuf + offset, &listSize, 4);
+ offset += 4;
+ for (int i = 0; i < listSize; i++) {
+ int type = list->get(i)->getShort((wchar_t*)ItemInstance::TAG_ENCH_ID);
+ int level = list->get(i)->getShort((wchar_t*)ItemInstance::TAG_ENCH_LEVEL);
+
+ memcpy(outBuf + offset, &type, 4);
+ offset += 4;
+
+ memcpy(outBuf + offset, &level, 4);
+ offset += 4;
+ }
+ }
+ }
+ else {
+ int zero = 0;
+ if (offset + 4 > bufSize) return 0;
+ memcpy(outBuf + offset, &zero, 4);
+ offset += 4;
+ }
+
return offset;
}
@@ -861,6 +894,11 @@ void __cdecl NativeSetItemMeta(int entityId, int slot, const char *inBuf, int bu
item->setTag(nullptr);
}
}
+
+ if (tag && tag->contains(L"ench"))
+ {
+ tag->remove(L"ench");
+ }
}
return;
}
@@ -925,6 +963,47 @@ void __cdecl NativeSetItemMeta(int entityId, int slot, const char *inBuf, int bu
tag->getCompound(L"display")->remove(L"Lore");
}
}
+
+ if (offset + 4 > bufSize) return;
+ int enchantCount = 0;
+ memcpy(&enchantCount, inBuf + offset, 4);
+ offset += 4;
+
+ if (enchantCount > 0)
+ {
+ if (!item->hasTag()) item->setTag(new CompoundTag());
+ CompoundTag* tag = item->getTag();
+ if (!tag->contains(L"ench")) tag->put(L"ench", new ListTag(L"ench"));
+ ListTag* enchantments = static_cast *>(tag->get(L"ench"));
+
+ for (int i = 0; i < enchantCount; i++) {
+ if (offset + (4 + 4) > bufSize) break;
+
+ int type = 0;
+ memcpy(&type, inBuf + offset, 4);
+ offset += 4;
+
+ int level = 0;
+ memcpy(&level, inBuf + offset, 4);
+ offset += 4;
+
+ CompoundTag* ench = new CompoundTag();
+ ench->putShort((wchar_t*)ItemInstance::TAG_ENCH_ID, static_cast(type));
+ ench->putShort((wchar_t*)ItemInstance::TAG_ENCH_LEVEL, static_cast(level));
+ enchantments->add(ench);
+ }
+ }
+ else
+ {
+ if (item->hasTag())
+ {
+ CompoundTag* tag = item->getTag();
+ if (tag && tag->contains(L"ench"))
+ {
+ tag->remove(L"ench");
+ }
+ }
+ }
}
void __cdecl NativeSetHeldItemSlot(int entityId, int slot)