diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/InternalAccessor.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/InternalAccessor.java
index a612f41e..94588f9d 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/InternalAccessor.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/InternalAccessor.java
@@ -5,10 +5,10 @@
import com.lishid.openinv.internal.ISpecialEnderChest;
import com.lishid.openinv.internal.ISpecialInventory;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
-import com.lishid.openinv.internal.v1_21_R1.inventory.AnySilentContainer;
-import com.lishid.openinv.internal.v1_21_R1.inventory.OpenEnderChest;
-import com.lishid.openinv.internal.v1_21_R1.inventory.OpenInventory;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.AnySilentContainer;
+import com.lishid.openinv.internal.v1_21_R1.container.OpenEnderChest;
+import com.lishid.openinv.internal.v1_21_R1.container.OpenInventory;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import com.lishid.openinv.internal.v1_21_R1.player.PlayerManager;
import com.lishid.openinv.util.lang.LanguageManager;
import net.minecraft.world.Container;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/AnySilentContainer.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/AnySilentContainer.java
similarity index 99%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/AnySilentContainer.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/AnySilentContainer.java
index a7c0211c..05fb013a 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/AnySilentContainer.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/AnySilentContainer.java
@@ -14,7 +14,7 @@
* along with this program. If not, see .
*/
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
import com.lishid.openinv.internal.IAnySilentContainer;
import com.lishid.openinv.internal.v1_21_R1.player.PlayerManager;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenContainerMenu.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenContainerMenu.java
similarity index 98%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenContainerMenu.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenContainerMenu.java
index 3b4b0e0d..347cce48 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenContainerMenu.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenContainerMenu.java
@@ -1,7 +1,7 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
import com.google.common.base.Suppliers;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.SlotPlaceholder;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.SlotPlaceholder;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minecraft.world.inventory.AbstractContainerMenu;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenEnderChest.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenEnderChest.java
similarity index 98%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenEnderChest.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenEnderChest.java
index 55ca749c..6959e8f4 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenEnderChest.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenEnderChest.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
import com.lishid.openinv.internal.ISpecialEnderChest;
import com.lishid.openinv.internal.v1_21_R1.player.PlayerManager;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenEnderChestMenu.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenEnderChestMenu.java
similarity index 96%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenEnderChestMenu.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenEnderChestMenu.java
index dd333d5d..7bfb4b3a 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenEnderChestMenu.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenEnderChestMenu.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.SlotViewOnly;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.SlotViewOnly;
import com.lishid.openinv.util.Permissions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenInventory.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenInventory.java
similarity index 94%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenInventory.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenInventory.java
index 3f6c907f..bec7a8a5 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenInventory.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenInventory.java
@@ -1,17 +1,17 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
import com.lishid.openinv.internal.v1_21_R1.player.PlayerManager;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.Content;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentCrafting;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentCraftingResult;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentCursor;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentDrop;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentEquipment;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentList;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentOffHand;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentViewOnly;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.SlotViewOnly;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.Content;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentCrafting;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentCraftingResult;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentCursor;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentDrop;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentEquipment;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentList;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentOffHand;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentViewOnly;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.SlotViewOnly;
import net.minecraft.ChatFormatting;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenInventoryMenu.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenInventoryMenu.java
similarity index 97%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenInventoryMenu.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenInventoryMenu.java
index 7b0a8e13..e9a1ff11 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenInventoryMenu.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenInventoryMenu.java
@@ -1,8 +1,8 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentDrop;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.ContentEquipment;
-import com.lishid.openinv.internal.v1_21_R1.inventory.slot.SlotViewOnly;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentDrop;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentEquipment;
+import com.lishid.openinv.internal.v1_21_R1.container.slot.SlotViewOnly;
import com.lishid.openinv.util.Permissions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EquipmentSlot;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenPlayerInventory.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenPlayerInventory.java
similarity index 99%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenPlayerInventory.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenPlayerInventory.java
index 3a11ab19..5295a625 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/OpenPlayerInventory.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/OpenPlayerInventory.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
import com.google.common.base.Preconditions;
import net.minecraft.core.NonNullList;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/Placeholders.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/Placeholders.java
similarity index 99%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/Placeholders.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/Placeholders.java
index 16fc3269..c5f35d2d 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/Placeholders.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/Placeholders.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory;
+package com.lishid.openinv.internal.v1_21_R1.container;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/Content.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/Content.java
similarity index 96%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/Content.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/Content.java
index eed38f34..d63536f0 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/Content.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/Content.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCrafting.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCrafting.java
similarity index 96%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCrafting.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCrafting.java
index 5edd1ef0..3f2bdb98 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCrafting.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCrafting.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.ContainerHelper;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCraftingResult.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCraftingResult.java
similarity index 91%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCraftingResult.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCraftingResult.java
index 4a26a543..54fb0cdc 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCraftingResult.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCraftingResult.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.InventoryMenu;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCursor.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCursor.java
similarity index 96%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCursor.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCursor.java
index 19694fda..5401daca 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentCursor.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentCursor.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentDrop.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentDrop.java
similarity index 93%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentDrop.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentDrop.java
index 45594a06..9a083b33 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentDrop.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentDrop.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.Slot;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentEquipment.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentEquipment.java
similarity index 94%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentEquipment.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentEquipment.java
index 2ba44873..662d4d67 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentEquipment.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentEquipment.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.entity.EquipmentSlot;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentList.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentList.java
similarity index 95%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentList.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentList.java
index 980c0b12..48e14ced 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentList.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentList.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentOffHand.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentOffHand.java
similarity index 95%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentOffHand.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentOffHand.java
index f8872900..7b319041 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentOffHand.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentOffHand.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentViewOnly.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentViewOnly.java
similarity index 95%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentViewOnly.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentViewOnly.java
index b7dc9a1a..5dec5b32 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/ContentViewOnly.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/ContentViewOnly.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/SlotPlaceholder.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/SlotPlaceholder.java
similarity index 89%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/SlotPlaceholder.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/SlotPlaceholder.java
index 315b2b5c..c7a53a3a 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/SlotPlaceholder.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/SlotPlaceholder.java
@@ -1,4 +1,4 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.Slot;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/SlotViewOnly.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/SlotViewOnly.java
similarity index 95%
rename from internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/SlotViewOnly.java
rename to internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/SlotViewOnly.java
index 5fa9edd5..93975d51 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/inventory/slot/SlotViewOnly.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/container/slot/SlotViewOnly.java
@@ -1,6 +1,6 @@
-package com.lishid.openinv.internal.v1_21_R1.inventory.slot;
+package com.lishid.openinv.internal.v1_21_R1.container.slot;
-import com.lishid.openinv.internal.v1_21_R1.inventory.Placeholders;
+import com.lishid.openinv.internal.v1_21_R1.container.Placeholders;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.Slot;
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/OpenPlayer.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/OpenPlayer.java
index cae26fef..c90d4e1e 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/OpenPlayer.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/OpenPlayer.java
@@ -21,157 +21,157 @@
public class OpenPlayer extends CraftPlayer {
- /**
- * List of tags to always reset when saving.
- *
- * @see net.minecraft.world.entity.Entity#saveWithoutId(CompoundTag)
- * @see net.minecraft.server.level.ServerPlayer#addAdditionalSaveData(CompoundTag)
- * @see net.minecraft.world.entity.player.Player#addAdditionalSaveData(CompoundTag)
- * @see net.minecraft.world.entity.LivingEntity#addAdditionalSaveData(CompoundTag)
- */
- private static final Set RESET_TAGS = Set.of(
- // Entity#saveWithoutId(CompoundTag)
- "CustomName",
- "CustomNameVisible",
- "Silent",
- "NoGravity",
- "Glowing",
- "TicksFrozen",
- "HasVisualFire",
- "Tags",
- "Passengers",
- // ServerPlayer#addAdditionalSaveData(CompoundTag)
- // Intentional omissions to prevent mount loss: Attach, Entity, and RootVehicle
- "warden_spawn_tracker",
- "enteredNetherPosition",
- "SpawnX",
- "SpawnY",
- "SpawnZ",
- "SpawnForced",
- "SpawnAngle",
- "SpawnDimension",
- "raid_omen_position",
- // Player#addAdditionalSaveData(CompoundTag)
- "ShoulderEntityLeft",
- "ShoulderEntityRight",
- "LastDeathLocation",
- "current_explosion_impact_pos",
- // LivingEntity#addAdditionalSaveData(CompoundTag)
- "active_effects",
- "SleepingX",
- "SleepingY",
- "SleepingZ",
- "Brain"
- );
-
- private final PlayerManager manager;
-
- OpenPlayer(CraftServer server, ServerPlayer entity, PlayerManager manager) {
- super(server, entity);
- this.manager = manager;
+ /**
+ * List of tags to always reset when saving.
+ *
+ * @see net.minecraft.world.entity.Entity#saveWithoutId(CompoundTag)
+ * @see net.minecraft.server.level.ServerPlayer#addAdditionalSaveData(CompoundTag)
+ * @see net.minecraft.world.entity.player.Player#addAdditionalSaveData(CompoundTag)
+ * @see net.minecraft.world.entity.LivingEntity#addAdditionalSaveData(CompoundTag)
+ */
+ private static final Set RESET_TAGS = Set.of(
+ // Entity#saveWithoutId(CompoundTag)
+ "CustomName",
+ "CustomNameVisible",
+ "Silent",
+ "NoGravity",
+ "Glowing",
+ "TicksFrozen",
+ "HasVisualFire",
+ "Tags",
+ "Passengers",
+ // ServerPlayer#addAdditionalSaveData(CompoundTag)
+ // Intentional omissions to prevent mount loss: Attach, Entity, and RootVehicle
+ "warden_spawn_tracker",
+ "enteredNetherPosition",
+ "SpawnX",
+ "SpawnY",
+ "SpawnZ",
+ "SpawnForced",
+ "SpawnAngle",
+ "SpawnDimension",
+ "raid_omen_position",
+ // Player#addAdditionalSaveData(CompoundTag)
+ "ShoulderEntityLeft",
+ "ShoulderEntityRight",
+ "LastDeathLocation",
+ "current_explosion_impact_pos",
+ // LivingEntity#addAdditionalSaveData(CompoundTag)
+ "active_effects",
+ "SleepingX",
+ "SleepingY",
+ "SleepingZ",
+ "Brain"
+ );
+
+ private final PlayerManager manager;
+
+ OpenPlayer(CraftServer server, ServerPlayer entity, PlayerManager manager) {
+ super(server, entity);
+ this.manager = manager;
+ }
+
+ @Override
+ public void loadData() {
+ manager.loadData(getHandle());
+ }
+
+ @Override
+ public void saveData() {
+ if (OpenEvents.saveCancelled(this)) {
+ return;
}
- @Override
- public void loadData() {
- manager.loadData(getHandle());
+ ServerPlayer player = this.getHandle();
+ // See net.minecraft.world.level.storage.PlayerDataStorage#save(EntityHuman)
+ try {
+ PlayerDataStorage worldNBTStorage = player.server.getPlayerList().playerIo;
+
+ CompoundTag oldData = isOnline() ? null : worldNBTStorage.load(player.getName().getString(), player.getStringUUID()).orElse(null);
+ CompoundTag playerData = getWritableTag(oldData);
+ playerData = player.saveWithoutId(playerData);
+ setExtraData(playerData);
+
+ if (oldData != null) {
+ // Revert certain special data values when offline.
+ revertSpecialValues(playerData, oldData);
+ }
+
+ Path playerDataDir = worldNBTStorage.getPlayerDir().toPath();
+ Path tempFile = Files.createTempFile(playerDataDir, player.getStringUUID() + "-", ".dat");
+ NbtIo.writeCompressed(playerData, tempFile);
+ Path dataFile = playerDataDir.resolve(player.getStringUUID() + ".dat");
+ Path backupFile = playerDataDir.resolve(player.getStringUUID() + ".dat_old");
+ Util.safeReplaceFile(dataFile, tempFile, backupFile);
+ } catch (Exception e) {
+ LogUtils.getLogger().warn("Failed to save player data for {}: {}", player.getScoreboardName(), e);
}
+ }
- @Override
- public void saveData() {
- if (OpenEvents.saveCancelled(this)) {
- return;
- }
-
- ServerPlayer player = this.getHandle();
- // See net.minecraft.world.level.storage.PlayerDataStorage#save(EntityHuman)
- try {
- PlayerDataStorage worldNBTStorage = player.server.getPlayerList().playerIo;
-
- CompoundTag oldData = isOnline() ? null : worldNBTStorage.load(player.getName().getString(), player.getStringUUID()).orElse(null);
- CompoundTag playerData = getWritableTag(oldData);
- playerData = player.saveWithoutId(playerData);
- setExtraData(playerData);
-
- if (oldData != null) {
- // Revert certain special data values when offline.
- revertSpecialValues(playerData, oldData);
- }
-
- Path playerDataDir = worldNBTStorage.getPlayerDir().toPath();
- Path tempFile = Files.createTempFile(playerDataDir, player.getStringUUID() + "-", ".dat");
- NbtIo.writeCompressed(playerData, tempFile);
- Path dataFile = playerDataDir.resolve(player.getStringUUID() + ".dat");
- Path backupFile = playerDataDir.resolve(player.getStringUUID() + ".dat_old");
- Util.safeReplaceFile(dataFile, tempFile, backupFile);
- } catch (Exception e) {
- LogUtils.getLogger().warn("Failed to save player data for {}: {}", player.getScoreboardName(), e);
- }
+ @Contract("null -> new")
+ private @NotNull CompoundTag getWritableTag(@Nullable CompoundTag oldData) {
+ if (oldData == null) {
+ return new CompoundTag();
}
- @Contract("null -> new")
- private @NotNull CompoundTag getWritableTag(@Nullable CompoundTag oldData) {
- if (oldData == null) {
- return new CompoundTag();
- }
-
- // Copy old data. This is a deep clone, so operating on it should be safe.
- oldData = oldData.copy();
-
- // Remove vanilla/server data that is not written every time.
- oldData.getAllKeys()
- .removeIf(key -> RESET_TAGS.contains(key) || key.startsWith("Bukkit"));
-
- return oldData;
+ // Copy old data. This is a deep clone, so operating on it should be safe.
+ oldData = oldData.copy();
+
+ // Remove vanilla/server data that is not written every time.
+ oldData.getAllKeys()
+ .removeIf(key -> RESET_TAGS.contains(key) || key.startsWith("Bukkit"));
+
+ return oldData;
+ }
+
+ private void revertSpecialValues(@NotNull CompoundTag newData, @NotNull CompoundTag oldData) {
+ // Revert automatic updates to play timestamps.
+ copyValue(oldData, newData, "bukkit", "lastPlayed", NumericTag.class);
+ copyValue(oldData, newData, "Paper", "LastSeen", NumericTag.class);
+ copyValue(oldData, newData, "Paper", "LastLogin", NumericTag.class);
+ }
+
+ private void copyValue(
+ @NotNull CompoundTag source,
+ @NotNull CompoundTag target,
+ @NotNull String container,
+ @NotNull String key,
+ @SuppressWarnings("SameParameterValue") @NotNull Class tagType) {
+ CompoundTag oldContainer = getTag(source, container, CompoundTag.class);
+ CompoundTag newContainer = getTag(target, container, CompoundTag.class);
+
+ // New container being null means the server implementation doesn't store this data.
+ if (newContainer == null) {
+ return;
}
- private void revertSpecialValues(@NotNull CompoundTag newData, @NotNull CompoundTag oldData) {
- // Revert automatic updates to play timestamps.
- copyValue(oldData, newData, "bukkit", "lastPlayed", NumericTag.class);
- copyValue(oldData, newData, "Paper", "LastSeen", NumericTag.class);
- copyValue(oldData, newData, "Paper", "LastLogin", NumericTag.class);
- }
+ // If old tag exists, copy it to new location, removing otherwise.
+ setTag(newContainer, key, getTag(oldContainer, key, tagType));
+ }
- private void copyValue(
- @NotNull CompoundTag source,
- @NotNull CompoundTag target,
- @NotNull String container,
- @NotNull String key,
- @NotNull Class tagType) {
- CompoundTag oldContainer = getTag(source, container, CompoundTag.class);
- CompoundTag newContainer = getTag(target, container, CompoundTag.class);
-
- // New container being null means the server implementation doesn't store this data.
- if (newContainer == null) {
- return;
- }
-
- // If old tag exists, copy it to new location, removing otherwise.
- setTag(newContainer, key, getTag(oldContainer, key, tagType));
+ private @Nullable T getTag(
+ @Nullable CompoundTag container,
+ @NotNull String key,
+ @NotNull Class dataType) {
+ if (container == null) {
+ return null;
}
-
- private @Nullable T getTag(
- @Nullable CompoundTag container,
- @NotNull String key,
- @NotNull Class dataType) {
- if (container == null) {
- return null;
- }
- Tag value = container.get(key);
- if (value == null || !dataType.isAssignableFrom(value.getClass())) {
- return null;
- }
- return dataType.cast(value);
+ Tag value = container.get(key);
+ if (value == null || !dataType.isAssignableFrom(value.getClass())) {
+ return null;
}
-
- private void setTag(
- @NotNull CompoundTag container,
- @NotNull String key,
- @Nullable T data) {
- if (data == null) {
- container.remove(key);
- } else {
- container.put(key, data);
- }
+ return dataType.cast(value);
+ }
+
+ private void setTag(
+ @NotNull CompoundTag container,
+ @NotNull String key,
+ @Nullable T data) {
+ if (data == null) {
+ container.remove(key);
+ } else {
+ container.put(key, data);
}
+ }
}
diff --git a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/PlayerManager.java b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/PlayerManager.java
index 6fd0d9ec..350270bc 100644
--- a/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/PlayerManager.java
+++ b/internal/v1_21_R1/src/main/java/com/lishid/openinv/internal/v1_21_R1/player/PlayerManager.java
@@ -1,8 +1,8 @@
package com.lishid.openinv.internal.v1_21_R1.player;
import com.lishid.openinv.internal.ISpecialInventory;
-import com.lishid.openinv.internal.v1_21_R1.inventory.OpenEnderChest;
-import com.lishid.openinv.internal.v1_21_R1.inventory.OpenInventory;
+import com.lishid.openinv.internal.v1_21_R1.container.OpenEnderChest;
+import com.lishid.openinv.internal.v1_21_R1.container.OpenInventory;
import com.mojang.authlib.GameProfile;
import com.mojang.serialization.Dynamic;
import net.minecraft.nbt.CompoundTag;
@@ -38,235 +38,235 @@
public class PlayerManager implements com.lishid.openinv.internal.PlayerManager {
- private static boolean paper;
+ private static boolean paper;
static {
- try {
- Class.forName("io.papermc.paper.configuration.Configuration");
- paper = true;
- } catch (ClassNotFoundException ignored) {
- paper = false;
- }
+ try {
+ Class.forName("io.papermc.paper.configuration.Configuration");
+ paper = true;
+ } catch (ClassNotFoundException ignored) {
+ paper = false;
}
-
- private final @NotNull Logger logger;
- private @Nullable Field bukkitEntity;
-
- public PlayerManager(@NotNull Logger logger) {
- this.logger = logger;
- try {
- bukkitEntity = Entity.class.getDeclaredField("bukkitEntity");
- } catch (NoSuchFieldException e) {
- logger.warning("Unable to obtain field to inject custom save process - certain player data may be lost when saving!");
- logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
- bukkitEntity = null;
- }
+ }
+
+ private final @NotNull Logger logger;
+ private @Nullable Field bukkitEntity;
+
+ public PlayerManager(@NotNull Logger logger) {
+ this.logger = logger;
+ try {
+ bukkitEntity = Entity.class.getDeclaredField("bukkitEntity");
+ } catch (NoSuchFieldException e) {
+ logger.warning("Unable to obtain field to inject custom save process - certain player data may be lost when saving!");
+ logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
+ bukkitEntity = null;
}
+ }
- public static @NotNull ServerPlayer getHandle(final Player player) {
- if (player instanceof CraftPlayer) {
- return ((CraftPlayer) player).getHandle();
- }
-
- Server server = player.getServer();
- ServerPlayer nmsPlayer = null;
+ public static @NotNull ServerPlayer getHandle(final Player player) {
+ if (player instanceof CraftPlayer) {
+ return ((CraftPlayer) player).getHandle();
+ }
- if (server instanceof CraftServer) {
- nmsPlayer = ((CraftServer) server).getHandle().getPlayer(player.getUniqueId());
- }
+ Server server = player.getServer();
+ ServerPlayer nmsPlayer = null;
- if (nmsPlayer == null) {
- // Could use reflection to examine fields, but it's honestly not worth the bother.
- throw new RuntimeException("Unable to fetch EntityPlayer from Player implementation " + player.getClass().getName());
- }
+ if (server instanceof CraftServer) {
+ nmsPlayer = ((CraftServer) server).getHandle().getPlayer(player.getUniqueId());
+ }
- return nmsPlayer;
+ if (nmsPlayer == null) {
+ // Could use reflection to examine fields, but it's honestly not worth the bother.
+ throw new RuntimeException("Unable to fetch EntityPlayer from Player implementation " + player.getClass().getName());
}
- @Override
- public @Nullable Player loadPlayer(@NotNull final OfflinePlayer offline) {
- // Ensure player has data
- if (!offline.hasPlayedBefore()) {
- return null;
- }
+ return nmsPlayer;
+ }
- MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
- ServerLevel worldServer = server.getLevel(Level.OVERWORLD);
+ @Override
+ public @Nullable Player loadPlayer(@NotNull final OfflinePlayer offline) {
+ // Ensure player has data
+ if (!offline.hasPlayedBefore()) {
+ return null;
+ }
- if (worldServer == null) {
- return null;
- }
+ MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
+ ServerLevel worldServer = server.getLevel(Level.OVERWORLD);
- // Create a new ServerPlayer.
- ServerPlayer entity = createNewPlayer(server, worldServer, offline);
+ if (worldServer == null) {
+ return null;
+ }
- // Stop listening for advancement progression - if this is not cleaned up, loading causes a memory leak.
- entity.getAdvancements().stopListening();
+ // Create a new ServerPlayer.
+ ServerPlayer entity = createNewPlayer(server, worldServer, offline);
- // Try to load the player's data.
- if (loadData(entity)) {
- // If data is loaded successfully, return the Bukkit entity.
- return entity.getBukkitEntity();
- }
+ // Stop listening for advancement progression - if this is not cleaned up, loading causes a memory leak.
+ entity.getAdvancements().stopListening();
- return null;
+ // Try to load the player's data.
+ if (loadData(entity)) {
+ // If data is loaded successfully, return the Bukkit entity.
+ return entity.getBukkitEntity();
}
- private @NotNull ServerPlayer createNewPlayer(
- @NotNull MinecraftServer server,
- @NotNull ServerLevel worldServer,
- @NotNull final OfflinePlayer offline) {
- // See net.minecraft.server.players.PlayerList#canPlayerLogin(ServerLoginPacketListenerImpl, GameProfile)
- // See net.minecraft.server.network.ServerLoginPacketListenerImpl#handleHello(ServerboundHelloPacket)
- GameProfile profile = new GameProfile(offline.getUniqueId(),
- offline.getName() != null ? offline.getName() : offline.getUniqueId().toString());
-
- ClientInformation dummyInfo = new ClientInformation(
- "en_us",
- 1, // Reduce distance just in case.
- ChatVisiblity.HIDDEN, // Don't accept chat.
- false,
- ServerPlayer.DEFAULT_MODEL_CUSTOMIZATION,
- ServerPlayer.DEFAULT_MAIN_HAND,
- true,
- false // Don't list in player list (not that this player is in the list anyway).
- );
-
- ServerPlayer entity = new ServerPlayer(server, worldServer, profile, dummyInfo);
-
- try {
- injectPlayer(entity);
- } catch (IllegalAccessException e) {
- logger.log(
- java.util.logging.Level.WARNING,
- e,
- () -> "Unable to inject ServerPlayer, certain player data may be lost when saving!");
- }
-
- return entity;
+ return null;
+ }
+
+ private @NotNull ServerPlayer createNewPlayer(
+ @NotNull MinecraftServer server,
+ @NotNull ServerLevel worldServer,
+ @NotNull final OfflinePlayer offline) {
+ // See net.minecraft.server.players.PlayerList#canPlayerLogin(ServerLoginPacketListenerImpl, GameProfile)
+ // See net.minecraft.server.network.ServerLoginPacketListenerImpl#handleHello(ServerboundHelloPacket)
+ GameProfile profile = new GameProfile(offline.getUniqueId(),
+ offline.getName() != null ? offline.getName() : offline.getUniqueId().toString());
+
+ ClientInformation dummyInfo = new ClientInformation(
+ "en_us",
+ 1, // Reduce distance just in case.
+ ChatVisiblity.HIDDEN, // Don't accept chat.
+ false,
+ ServerPlayer.DEFAULT_MODEL_CUSTOMIZATION,
+ ServerPlayer.DEFAULT_MAIN_HAND,
+ true,
+ false // Don't list in player list (not that this player is in the list anyway).
+ );
+
+ ServerPlayer entity = new ServerPlayer(server, worldServer, profile, dummyInfo);
+
+ try {
+ injectPlayer(entity);
+ } catch (IllegalAccessException e) {
+ logger.log(
+ java.util.logging.Level.WARNING,
+ e,
+ () -> "Unable to inject ServerPlayer, certain player data may be lost when saving!");
}
- boolean loadData(@NotNull ServerPlayer player) {
- // See CraftPlayer#loadData
- CompoundTag loadedData = player.server.getPlayerList().playerIo.load(player).orElse(null);
+ return entity;
+ }
+
+ boolean loadData(@NotNull ServerPlayer player) {
+ // See CraftPlayer#loadData
+ CompoundTag loadedData = player.server.getPlayerList().playerIo.load(player).orElse(null);
+
+ if (loadedData == null) {
+ // Exceptions with loading are logged by Mojang.
+ return false;
+ }
- if (loadedData == null) {
- // Exceptions with loading are logged by Mojang.
- return false;
- }
+ // Read basic data into the player.
+ player.load(loadedData);
+ // Also read "extra" data.
+ player.readAdditionalSaveData(loadedData);
+ // Game type settings are also loaded separately.
+ player.loadGameTypes(loadedData);
- // Read basic data into the player.
- player.load(loadedData);
- // Also read "extra" data.
- player.readAdditionalSaveData(loadedData);
- // Game type settings are also loaded separately.
- player.loadGameTypes(loadedData);
+ if (paper) {
+ // Paper: world is not loaded by ServerPlayer#load(CompoundTag).
+ parseWorld(player, loadedData);
+ }
- if (paper) {
- // Paper: world is not loaded by ServerPlayer#load(CompoundTag).
- parseWorld(player, loadedData);
- }
+ return true;
+ }
+
+ private void parseWorld(@NotNull ServerPlayer player, @NotNull CompoundTag loadedData) {
+ // See PlayerList#placeNewPlayer
+ World bukkitWorld;
+ if (loadedData.contains("WorldUUIDMost") && loadedData.contains("WorldUUIDLeast")) {
+ // Modern Bukkit world.
+ bukkitWorld = Bukkit.getServer().getWorld(new UUID(loadedData.getLong("WorldUUIDMost"), loadedData.getLong("WorldUUIDLeast")));
+ } else if (loadedData.contains("world", net.minecraft.nbt.Tag.TAG_STRING)) {
+ // Legacy Bukkit world.
+ bukkitWorld = Bukkit.getServer().getWorld(loadedData.getString("world"));
+ } else {
+ // Vanilla player data.
+ DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, loadedData.get("Dimension")))
+ .resultOrPartial(logger::warning)
+ .map(player.server::getLevel)
+ // If ServerLevel exists, set, otherwise move to spawn.
+ .ifPresentOrElse(player::setServerLevel, () -> player.spawnIn(null));
+ return;
+ }
+ if (bukkitWorld == null) {
+ player.spawnIn(null);
+ return;
+ }
+ player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
+ }
- return true;
+ private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
+ if (bukkitEntity == null) {
+ return;
}
- private void parseWorld(@NotNull ServerPlayer player, @NotNull CompoundTag loadedData) {
- // See PlayerList#placeNewPlayer
- World bukkitWorld;
- if (loadedData.contains("WorldUUIDMost") && loadedData.contains("WorldUUIDLeast")) {
- // Modern Bukkit world.
- bukkitWorld = Bukkit.getServer().getWorld(new UUID(loadedData.getLong("WorldUUIDMost"), loadedData.getLong("WorldUUIDLeast")));
- } else if (loadedData.contains("world", net.minecraft.nbt.Tag.TAG_STRING)) {
- // Legacy Bukkit world.
- bukkitWorld = Bukkit.getServer().getWorld(loadedData.getString("world"));
- } else {
- // Vanilla player data.
- DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, loadedData.get("Dimension")))
- .resultOrPartial(logger::warning)
- .map(player.server::getLevel)
- // If ServerLevel exists, set, otherwise move to spawn.
- .ifPresentOrElse(player::setServerLevel, () -> player.spawnIn(null));
- return;
- }
- if (bukkitWorld == null) {
- player.spawnIn(null);
- return;
- }
- player.setServerLevel(((CraftWorld) bukkitWorld).getHandle());
+ bukkitEntity.setAccessible(true);
+
+ bukkitEntity.set(player, new OpenPlayer(player.server.server, player, this));
+ }
+
+ @Override
+ public @NotNull Player inject(@NotNull Player player) {
+ try {
+ ServerPlayer nmsPlayer = getHandle(player);
+ if (nmsPlayer.getBukkitEntity() instanceof OpenPlayer openPlayer) {
+ return openPlayer;
+ }
+ injectPlayer(nmsPlayer);
+ return nmsPlayer.getBukkitEntity();
+ } catch (IllegalAccessException e) {
+ logger.log(
+ java.util.logging.Level.WARNING,
+ e,
+ () -> "Unable to inject ServerPlayer, certain player data may be lost when saving!");
+ return player;
}
+ }
- private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
- if (bukkitEntity == null) {
- return;
- }
+ @Override
+ public @Nullable InventoryView openInventory(@NotNull Player bukkitPlayer, @NotNull ISpecialInventory inventory) {
+ ServerPlayer player = getHandle(bukkitPlayer);
- bukkitEntity.setAccessible(true);
+ if (player.connection == null) {
+ return null;
+ }
- bukkitEntity.set(player, new OpenPlayer(player.server.server, player, this));
+ MenuProvider provider;
+ Component title;
+ if (inventory instanceof OpenInventory playerInv) {
+ provider = playerInv;
+ title = playerInv.getTitle(player);
+ } else if (inventory instanceof OpenEnderChest enderChest) {
+ provider = enderChest;
+ title = enderChest.getDisplayName();
+ } else {
+ return null;
}
- @Override
- public @NotNull Player inject(@NotNull Player player) {
- try {
- ServerPlayer nmsPlayer = getHandle(player);
- if (nmsPlayer.getBukkitEntity() instanceof OpenPlayer openPlayer) {
- return openPlayer;
- }
- injectPlayer(nmsPlayer);
- return nmsPlayer.getBukkitEntity();
- } catch (IllegalAccessException e) {
- logger.log(
- java.util.logging.Level.WARNING,
- e,
- () -> "Unable to inject ServerPlayer, certain player data may be lost when saving!");
- return player;
- }
+ // See net.minecraft.server.level.ServerPlayer#openMenu(MenuProvider)
+ AbstractContainerMenu menu = provider.createMenu(player.nextContainerCounter(), player.getInventory(), player);
+
+ // Should never happen, player is a ServerPlayer with an active connection.
+ if (menu == null) {
+ return null;
}
- @Override
- public @Nullable InventoryView openInventory(@NotNull Player bukkitPlayer, @NotNull ISpecialInventory inventory) {
- ServerPlayer player = getHandle(bukkitPlayer);
-
- if (player.connection == null) {
- return null;
- }
-
- MenuProvider provider;
- Component title;
- if (inventory instanceof OpenInventory playerInv) {
- provider = playerInv;
- title = playerInv.getTitle(player);
- } else if (inventory instanceof OpenEnderChest enderChest) {
- provider = enderChest;
- title = enderChest.getDisplayName();
- } else {
- return null;
- }
-
- // See net.minecraft.server.level.ServerPlayer#openMenu(MenuProvider)
- AbstractContainerMenu menu = provider.createMenu(player.nextContainerCounter(), player.getInventory(), player);
-
- // Should never happen, player is a ServerPlayer with an active connection.
- if (menu == null) {
- return null;
- }
-
- // Set up title (the whole reason we're not just using Player#openInventory(Inventory)).
- // Title can only be set once for a menu, and is set during the open process.
- menu.setTitle(title);
-
- menu = CraftEventFactory.callInventoryOpenEvent(player, menu, false);
-
- // Menu is null if event is cancelled.
- if (menu == null) {
- return null;
- }
-
- player.containerMenu = menu;
- player.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), menu.getTitle()));
- player.initMenu(menu);
-
- return menu.getBukkitView();
+ // Set up title (the whole reason we're not just using Player#openInventory(Inventory)).
+ // Title can only be set once for a menu, and is set during the open process.
+ menu.setTitle(title);
+
+ menu = CraftEventFactory.callInventoryOpenEvent(player, menu, false);
+
+ // Menu is null if event is cancelled.
+ if (menu == null) {
+ return null;
}
+ player.containerMenu = menu;
+ player.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), menu.getTitle()));
+ player.initMenu(menu);
+
+ return menu.getBukkitView();
+ }
+
}