diff --git a/ChestsPlusPlus_1_16_R3/pom.xml b/ChestsPlusPlus_1_16_R3/pom.xml
new file mode 100644
index 0000000..9779359
--- /dev/null
+++ b/ChestsPlusPlus_1_16_R3/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+
+ ChestsPlusPlus-Parent
+ com.jamesdpeters.minecraft.chests
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ jar
+ ChestsPlusPlus_1_16_R3
+ 1.0-SNAPSHOT
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+
+
+
+ com.jamesdpeters.minecraft.chests
+ ChestsPlusPlus-API
+ 1.0-SNAPSHOT
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.16.4-R0.1-SNAPSHOT
+ provided
+
+
+ com.jamesdpeters.minecraft.chests
+ ChestsPlusPlus_1_16
+ 1.0-SNAPSHOT
+ compile
+
+
+
+ org.bukkit
+ craftbukkit
+ 1.16.4-R0.1-SNAPSHOT
+ provided
+
+
+
+
+
\ No newline at end of file
diff --git a/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/Crafting.java b/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/Crafting.java
new file mode 100644
index 0000000..4b2e215
--- /dev/null
+++ b/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/Crafting.java
@@ -0,0 +1,86 @@
+package com.jamesdpeters.minecraft.chests.v1_16_R3;
+
+import com.jamesdpeters.minecraft.chests.CraftingProvider;
+import net.minecraft.server.v1_16_R3.Container;
+import net.minecraft.server.v1_16_R3.EntityHuman;
+import net.minecraft.server.v1_16_R3.IRecipe;
+import net.minecraft.server.v1_16_R3.InventoryCrafting;
+import net.minecraft.server.v1_16_R3.RecipeCrafting;
+import net.minecraft.server.v1_16_R3.Recipes;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
+import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
+import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
+import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.Recipe;
+
+import java.util.List;
+import java.util.Optional;
+
+public class Crafting implements CraftingProvider {
+
+ @Override
+ public ItemStack craft(World world, List items) {
+ Container container = new Container(null, -1) {
+ @Override
+ public InventoryView getBukkitView() {
+ return null;
+ }
+
+ @Override
+ public boolean canUse(EntityHuman entityHuman) {
+ return false;
+ }
+ };
+
+ InventoryCrafting crafting = new InventoryCrafting(container, 3, 3);
+
+ for (int i = 0; i < items.size(); i++) {
+ crafting.setItem(i, CraftItemStack.asNMSCopy(items.get(i)));
+ }
+
+ CraftServer server = (CraftServer) Bukkit.getServer();
+ CraftWorld craftWorld = (CraftWorld) world;
+ Optional optional = server.getServer().getCraftingManager().craft(Recipes.CRAFTING, crafting, craftWorld.getHandle());
+
+ net.minecraft.server.v1_16_R3.ItemStack itemstack = net.minecraft.server.v1_16_R3.ItemStack.b;
+
+ if (optional.isPresent()) {
+ RecipeCrafting recipeCrafting = optional.get();
+ itemstack = recipeCrafting.a(crafting);
+ }
+
+ return CraftItemStack.asBukkitCopy(itemstack);
+ }
+
+ @Override
+ public Recipe getRecipe(World world, List items) {
+ Container container = new Container(null, -1) {
+ @Override
+ public InventoryView getBukkitView() {
+ return null;
+ }
+
+ @Override
+ public boolean canUse(EntityHuman entityHuman) {
+ return false;
+ }
+ };
+
+ InventoryCrafting crafting = new InventoryCrafting(container, 3, 3);
+
+ for (int i = 0; i < items.size(); i++) {
+ if(i >= 9) break; // ItemList cant contain more than 9 items.
+ crafting.setItem(i, CraftItemStack.asNMSCopy(items.get(i)));
+ }
+
+ CraftServer server = (CraftServer) Bukkit.getServer();
+ CraftWorld craftWorld = (CraftWorld) world;
+ Optional optional = server.getServer().getCraftingManager().craft(Recipes.CRAFTING, crafting, craftWorld.getHandle());
+
+ return optional.map(IRecipe::toBukkitRecipe).orElse(null);
+
+ }
+}
diff --git a/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/MaterialChecker_1_16_R3.java b/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/MaterialChecker_1_16_R3.java
new file mode 100644
index 0000000..7380227
--- /dev/null
+++ b/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/MaterialChecker_1_16_R3.java
@@ -0,0 +1,35 @@
+package com.jamesdpeters.minecraft.chests.v1_16_R3;
+
+import com.jamesdpeters.minecraft.chests.MaterialChecker;
+import com.jamesdpeters.minecraft.chests.v1_16_R1.MaterialChecker_1_16;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.List;
+
+/**
+ * Only a protocol change from 1.16.2 to 1.16.3 so no new materials were added.
+ */
+public class MaterialChecker_1_16_R3 extends MaterialChecker {
+
+ private MaterialChecker_1_16 version1_16;
+
+ public MaterialChecker_1_16_R3(){
+ version1_16 = new MaterialChecker_1_16();
+ }
+
+ @Override
+ public List graphically2DList() {
+ return version1_16.graphically2DList();
+ }
+
+ @Override
+ public List ignoredMaterials() {
+ return version1_16.ignoredMaterials();
+ }
+
+ @Override
+ public boolean isTool(ItemStack itemStack) {
+ return version1_16.isTool(itemStack);
+ }
+}
diff --git a/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/NMSProviderImpl.java b/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/NMSProviderImpl.java
new file mode 100644
index 0000000..aa74e77
--- /dev/null
+++ b/ChestsPlusPlus_1_16_R3/src/main/java/com/jamesdpeters/minecraft/chests/v1_16_R3/NMSProviderImpl.java
@@ -0,0 +1,51 @@
+package com.jamesdpeters.minecraft.chests.v1_16_R3;
+
+import com.jamesdpeters.minecraft.chests.ChestOpener;
+import com.jamesdpeters.minecraft.chests.CraftingProvider;
+import com.jamesdpeters.minecraft.chests.MaterialChecker;
+import com.jamesdpeters.minecraft.chests.NMSProvider;
+import org.bukkit.block.Lidded;
+import org.bukkit.entity.ItemFrame;
+
+public class NMSProviderImpl implements NMSProvider {
+
+ @Override
+ public ChestOpener getChestOpener() {
+ return (inventory, container, tileEntityOpener) -> {
+ if(hasLiddedAPI()){
+ if(container instanceof Lidded){
+ if(inventory.getViewers().size() > 0){
+ ((Lidded) container).open();
+ } else {
+ ((Lidded) container).close();
+ }
+ }
+ }
+ return null;
+ };
+ }
+
+ @Override
+ public MaterialChecker getMaterialChecker() {
+ return new MaterialChecker_1_16_R3();
+ }
+
+ @Override
+ public CraftingProvider getCraftingProvider() {
+ return new Crafting();
+ }
+
+ @Override
+ public void setItemFrameVisible(ItemFrame itemFrame, boolean visible) {
+ itemFrame.setVisible(visible);
+ }
+
+ private boolean hasLiddedAPI(){
+ try {
+ Class.forName("org.bukkit.block.Lidded");
+ return true;
+ } catch (ClassNotFoundException e){
+ return false;
+ }
+ }
+}
diff --git a/ChestsPlusPlus_Main/pom.xml b/ChestsPlusPlus_Main/pom.xml
index 07f4d8b..4f52079 100644
--- a/ChestsPlusPlus_Main/pom.xml
+++ b/ChestsPlusPlus_Main/pom.xml
@@ -92,6 +92,14 @@
1.7
+
+ com.jamesdpeters.minecraft.chests
+ ChestsPlusPlus_1_16_R3
+ 1.0-SNAPSHOT
+ jar
+ compile
+
+
com.jamesdpeters.minecraft.chests
ChestsPlusPlus_1_16_R2
diff --git a/pom.xml b/pom.xml
index c139d81..9294ce4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,6 +16,7 @@
ChestsPlusPlusAPI
+ ChestsPlusPlus_1_16_R3
ChestsPlusPlus_1_16_R2
ChestsPlusPlus_1_16
ChestsPlusPlus_1_15