diff --git a/lang/en.yml b/lang/en.yml
index 03a4415..0be57b5 100644
--- a/lang/en.yml
+++ b/lang/en.yml
@@ -209,4 +209,4 @@ VALID_DONATION_KEY: "Valid donation key."
VERSION_INCOMPATIBLE: "{0} {1} is not supported."
VERSION_NOTICE: "Version {0} is now available."
VERSION_REQUIRED: "{0} {1} or higher is required."
-WORLD_NOT_FOUND: "World \"{0}\" not found."
+WORLD_NOT_FOUND: "World \"{0}\" not found."
\ No newline at end of file
diff --git a/lang/ru.yml b/lang/ru.yml
index a82438b..bee1016 100644
--- a/lang/ru.yml
+++ b/lang/ru.yml
@@ -139,7 +139,7 @@ PATCH_SKIP_UPDATE: "{Пропущена таблица|Пропущен инде
PATCH_STARTED: "Выполняется обновление {0}. Пожалуйста, подождите..."
PATCH_SUCCESS: "Успешно обновлен до {0}."
PATCH_UPGRADING: "Выполняется обновление базы данных. Пожалуйста, подождите..."
-PLEASE_SELECT: "Пожалуйста выберете: «{0}» или «{1}»."
+PLEASE_SELECT: "Пожалуйста выберите: «{0}» или «{1}»."
PREVIEW_CANCELLED: "Предварительный просмотр отменен."
PREVIEW_CANCELLING: "Отмена предварительного просмотра..."
PREVIEW_IN_GAME: "Предварительный просмотр откатов доступен только в игре."
diff --git a/pom.xml b/pom.xml
index ffaf6ec..8ad0cbe 100755
--- a/pom.xml
+++ b/pom.xml
@@ -113,6 +113,31 @@
${skipTests}
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.6.1
+
+
+ validate
+ enforce
+
+
+
+
+ central
+ enginehub-repo
+ spigot-repo
+ paper-repo
+ codemc-repo
+ jitpack.io
+
+
+
+
+
+
+
diff --git a/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java b/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java
index f498ef3..23f9207 100644
--- a/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java
+++ b/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java
@@ -1,7 +1,10 @@
package net.coreprotect.bukkit;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.bukkit.Color;
import org.bukkit.DyeColor;
@@ -20,6 +23,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.block.SignChangeEvent;
+import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
@@ -85,6 +89,7 @@ public class BukkitAdapter implements BukkitInterface {
}
// -------------------- Basic data conversion methods --------------------
+ public static Set EMPTY_SET = new HashSet<>(Arrays.asList());
@Override
public String parseLegacyName(String name) {
@@ -350,4 +355,19 @@ public class BukkitAdapter implements BukkitInterface {
public Object getRegistryValue(String key, Object tClass) {
return null;
}
+
+ @Override
+ public boolean isCrafter(InventoryType type) {
+ return false;
+ }
+
+ @Override
+ public boolean isCopperChest(Material material) {
+ return false;
+ }
+
+ @Override
+ public Set copperChestMaterials() {
+ return EMPTY_SET;
+ }
}
diff --git a/src/main/java/net/coreprotect/bukkit/BukkitInterface.java b/src/main/java/net/coreprotect/bukkit/BukkitInterface.java
index a648b26..c66d7fc 100644
--- a/src/main/java/net/coreprotect/bukkit/BukkitInterface.java
+++ b/src/main/java/net/coreprotect/bukkit/BukkitInterface.java
@@ -2,6 +2,7 @@ package net.coreprotect.bukkit;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.bukkit.Material;
import org.bukkit.World;
@@ -14,6 +15,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.block.SignChangeEvent;
+import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
@@ -432,4 +434,11 @@ public interface BukkitInterface {
* @return The parsed name
*/
String parseLegacyName(String name);
+
+ boolean isCrafter(InventoryType type);
+
+ boolean isCopperChest(Material material);
+
+ Set copperChestMaterials();
+
}
diff --git a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_21.java b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_21.java
index 6cea78e..4d52be8 100644
--- a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_21.java
+++ b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_21.java
@@ -1,5 +1,7 @@
package net.coreprotect.bukkit;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -9,6 +11,7 @@ import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;
import org.bukkit.entity.EntityType;
+import org.bukkit.event.inventory.InventoryType;
import net.coreprotect.model.BlockGroup;
@@ -22,6 +25,8 @@ import net.coreprotect.model.BlockGroup;
*/
public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
+ public static Set COPPER_CHESTS = new HashSet<>(Arrays.asList());
+
/**
* Initializes the Bukkit_v1_21 adapter with 1.21-specific block groups and mappings.
* Sets up collections of blocks with similar behavior for efficient handling.
@@ -29,6 +34,9 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
public Bukkit_v1_21() {
initializeBlockGroups();
initializeTrapdoorBlocks();
+ BlockGroup.INTERACT_BLOCKS.addAll(copperChestMaterials());
+ BlockGroup.CONTAINERS.addAll(copperChestMaterials());
+ BlockGroup.UPDATE_STATE.addAll(copperChestMaterials());
}
/**
@@ -154,4 +162,40 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
wolf.setVariant(variant);
}
+
+ @Override
+ public boolean isCrafter(InventoryType type) {
+ return type == InventoryType.CRAFTER;
+ }
+
+ @Override
+ public boolean isCopperChest(Material material) {
+ if (COPPER_CHESTS.contains(material) && material != Material.CHEST) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public Set copperChestMaterials() {
+ if (COPPER_CHESTS.isEmpty()) {
+ Material copperChest = Material.getMaterial("COPPER_CHEST");
+ if (copperChest == null) {
+ COPPER_CHESTS.add(Material.CHEST);
+ }
+ else {
+ COPPER_CHESTS.add(Material.getMaterial("COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("EXPOSED_COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("WEATHERED_COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("OXIDIZED_COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("WAXED_COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("WAXED_EXPOSED_COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("WAXED_WEATHERED_COPPER_CHEST"));
+ COPPER_CHESTS.add(Material.getMaterial("WAXED_OXIDIZED_COPPER_CHEST"));
+ }
+ }
+
+ return COPPER_CHESTS;
+ }
}
diff --git a/src/main/java/net/coreprotect/command/StatusCommand.java b/src/main/java/net/coreprotect/command/StatusCommand.java
index 040061f..f035f77 100755
--- a/src/main/java/net/coreprotect/command/StatusCommand.java
+++ b/src/main/java/net/coreprotect/command/StatusCommand.java
@@ -39,9 +39,13 @@ public class StatusCommand {
String versionCheck = "";
if (Config.getGlobal().CHECK_UPDATES) {
String latestVersion = NetworkHandler.latestVersion();
+ String latestEdgeVersion = NetworkHandler.latestEdgeVersion();
if (latestVersion != null) {
versionCheck = " (" + Phrase.build(Phrase.LATEST_VERSION, "v" + latestVersion) + ")";
}
+ else if (latestEdgeVersion != null && !VersionUtils.isCommunityEdition()) {
+ versionCheck = " (" + Phrase.build(Phrase.LATEST_VERSION, "v" + latestEdgeVersion) + ")";
+ }
}
Chat.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + "CoreProtect" + (VersionUtils.isCommunityEdition() ? " " + ConfigHandler.COMMUNITY_EDITION : "") + Color.WHITE + " -----");
diff --git a/src/main/java/net/coreprotect/config/ConfigHandler.java b/src/main/java/net/coreprotect/config/ConfigHandler.java
index 6effac7..bf59112 100644
--- a/src/main/java/net/coreprotect/config/ConfigHandler.java
+++ b/src/main/java/net/coreprotect/config/ConfigHandler.java
@@ -40,6 +40,11 @@ import net.coreprotect.utility.VersionUtils;
import oshi.hardware.CentralProcessor;
public class ConfigHandler extends Queue {
+
+ public enum CacheType {
+ MATERIALS, BLOCKDATA, ART, ENTITIES, WORLDS
+ }
+
public static int SERVER_VERSION = 0;
public static final int EDITION_VERSION = 2;
public static final String EDITION_BRANCH = VersionUtils.getBranch();
@@ -47,7 +52,8 @@ public class ConfigHandler extends Queue {
public static final String COMMUNITY_EDITION = "Community Edition";
public static final String JAVA_VERSION = "11.0";
public static final String MINECRAFT_VERSION = "1.16";
- public static final String LATEST_VERSION = "1.21.8";
+ public static final String PATCH_VERSION = "23.0";
+ public static final String LATEST_VERSION = "1.21.10";
public static String path = "plugins/CoreProtect/";
public static String sqlite = "database.db";
public static String host = "127.0.0.1";
@@ -268,7 +274,7 @@ public class ConfigHandler extends Queue {
Database.createDatabaseTables(ConfigHandler.prefix, false, null, Config.getGlobal().MYSQL, false);
}
- public static void loadTypes(Statement statement) {
+ public static void loadMaterials(Statement statement) {
try {
String query = "SELECT id,material FROM " + ConfigHandler.prefix + "material_map";
ResultSet rs = statement.executeQuery(query);
@@ -286,9 +292,16 @@ public class ConfigHandler extends Queue {
}
}
rs.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
- query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
- rs = statement.executeQuery(query);
+ public static void loadBlockdata(Statement statement) {
+ try {
+ String query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
+ ResultSet rs = statement.executeQuery(query);
ConfigHandler.blockdata.clear();
ConfigHandler.blockdataReversed.clear();
blockdataId = 0;
@@ -303,9 +316,16 @@ public class ConfigHandler extends Queue {
}
}
rs.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
- query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
- rs = statement.executeQuery(query);
+ public static void loadArt(Statement statement) {
+ try {
+ String query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
+ ResultSet rs = statement.executeQuery(query);
ConfigHandler.art.clear();
ConfigHandler.artReversed.clear();
artId = 0;
@@ -320,9 +340,16 @@ public class ConfigHandler extends Queue {
}
}
rs.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
- query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
- rs = statement.executeQuery(query);
+ public static void loadEntities(Statement statement) {
+ try {
+ String query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
+ ResultSet rs = statement.executeQuery(query);
ConfigHandler.entities.clear();
ConfigHandler.entitiesReversed.clear();
entityId = 0;
@@ -343,6 +370,67 @@ public class ConfigHandler extends Queue {
}
}
+ public static void loadTypes(Statement statement) {
+ loadMaterials(statement);
+ loadBlockdata(statement);
+ loadArt(statement);
+ loadEntities(statement);
+ }
+
+ /**
+ * Unified method to reload cache from database when DATABASE_LOCK is false (multi-server setup)
+ *
+ * @param type
+ * The type of cache to reload
+ * @param name
+ * The name to look up after reload
+ * @return The ID if found after reload, or -1 if not found
+ */
+ public static int reloadAndGetId(CacheType type, String name) {
+ // Only reload if DATABASE_LOCK is false (multi-server setup)
+ if (Config.getGlobal().DATABASE_LOCK) {
+ return -1;
+ }
+
+ try (Connection connection = Database.getConnection(true)) {
+ if (connection != null) {
+ Statement statement = connection.createStatement();
+
+ // Reload appropriate cache based on type
+ switch (type) {
+ case MATERIALS:
+ loadMaterials(statement);
+ statement.close();
+ return materials.getOrDefault(name, -1);
+ case BLOCKDATA:
+ loadBlockdata(statement);
+ statement.close();
+ return blockdata.getOrDefault(name, -1);
+ case ART:
+ loadArt(statement);
+ statement.close();
+ return art.getOrDefault(name, -1);
+ case ENTITIES:
+ loadEntities(statement);
+ statement.close();
+ return entities.getOrDefault(name, -1);
+ case WORLDS:
+ loadWorlds(statement);
+ statement.close();
+ return worlds.getOrDefault(name, -1);
+ default:
+ statement.close();
+ return -1;
+ }
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return -1;
+ }
+
public static void loadWorlds(Statement statement) {
try {
String query = "SELECT id,world FROM " + ConfigHandler.prefix + "world";
diff --git a/src/main/java/net/coreprotect/database/rollback/RollbackProcessor.java b/src/main/java/net/coreprotect/database/rollback/RollbackProcessor.java
index d566fa4..21788c8 100644
--- a/src/main/java/net/coreprotect/database/rollback/RollbackProcessor.java
+++ b/src/main/java/net/coreprotect/database/rollback/RollbackProcessor.java
@@ -209,7 +209,7 @@ public class RollbackProcessor {
BlockData checkData = rowType == Material.AIR ? blockData : rawBlockData;
if (checkData != null) {
if (checkData.getAsString().equals(pendingChangeData.getAsString()) || checkData instanceof org.bukkit.block.data.MultipleFacing || checkData instanceof org.bukkit.block.data.type.Stairs || checkData instanceof org.bukkit.block.data.type.RedstoneWire) {
- if (rowType != Material.CHEST && rowType != Material.TRAPPED_CHEST) { // always update double chests
+ if (rowType != Material.CHEST && rowType != Material.TRAPPED_CHEST && !BukkitAdapter.ADAPTER.isCopperChest(rowType)) { // always update double chests
changeBlock = false;
}
}
diff --git a/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java b/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java
index cbb372c..5db038e 100644
--- a/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java
+++ b/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java
@@ -10,12 +10,14 @@ import java.util.concurrent.atomic.AtomicLong;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
+import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
@@ -27,6 +29,7 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
+import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
@@ -342,9 +345,58 @@ public final class InventoryChangeListener extends Queue implements Listener {
return true;
}
+ private boolean checkCrafterSlotChange(InventoryClickEvent event) {
+ // Check if the clicked inventory is a crafter
+ if (!BukkitAdapter.ADAPTER.isCrafter(event.getInventory().getType())) {
+ return false;
+ }
+
+ // Check that the Action is NOTHING
+ if (event.getAction() != InventoryAction.NOTHING) {
+ return false;
+ }
+
+ // Check if the clicked slot is one of the crafter slots
+ if (event.getRawSlot() < 0 || event.getRawSlot() > 8) {
+ return false;
+ }
+
+ // Check that the click type is not a middle click
+ if (!(event.getClick() == ClickType.LEFT || event.getClick() == ClickType.RIGHT)) {
+ return false;
+ }
+
+ // Gather other necessary information
+ Player player = (Player) event.getWhoClicked();
+ Inventory inventory = event.getInventory();
+
+ Location location = null;
+ try {
+ location = inventory.getLocation();
+ }
+ catch (Exception e) {
+ return false;
+ }
+
+ if (location == null) {
+ return false;
+ }
+
+ Block block = location.getBlock();
+ BlockState blockState = block.getState();
+
+ Queue.queueBlockPlace(player.getName(), blockState, block.getType(), blockState, block.getType(), -1, 0, blockState.getBlockData().getAsString());
+ return true;
+ }
+
@EventHandler(priority = EventPriority.LOWEST)
protected void onInventoryClick(InventoryClickEvent event) {
InventoryAction inventoryAction = event.getAction();
+
+ if (checkCrafterSlotChange(event)) {
+ return;
+ }
+
if (inventoryAction == InventoryAction.NOTHING) {
return;
}
diff --git a/src/main/java/net/coreprotect/listener/player/PlayerInteractListener.java b/src/main/java/net/coreprotect/listener/player/PlayerInteractListener.java
index 35c997f..680aa61 100755
--- a/src/main/java/net/coreprotect/listener/player/PlayerInteractListener.java
+++ b/src/main/java/net/coreprotect/listener/player/PlayerInteractListener.java
@@ -145,7 +145,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
}
else if (isContainerBlock && Config.getConfig(world).ITEM_TRANSACTIONS) {
Location location = null;
- if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST)) {
+ if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST) || BukkitAdapter.ADAPTER.isCopperChest(type)) {
Chest chest = (Chest) clickedBlock.getState();
InventoryHolder inventoryHolder = chest.getInventory().getHolder();
diff --git a/src/main/java/net/coreprotect/services/VersionCheckService.java b/src/main/java/net/coreprotect/services/VersionCheckService.java
index dba40c8..68aeb64 100644
--- a/src/main/java/net/coreprotect/services/VersionCheckService.java
+++ b/src/main/java/net/coreprotect/services/VersionCheckService.java
@@ -44,6 +44,13 @@ public class VersionCheckService {
return false;
}
+ // Patch version validation
+ if (VersionUtils.newVersion(ConfigHandler.PATCH_VERSION, VersionUtils.getPluginVersion()) && !VersionUtils.isBranch("dev")) {
+ Chat.console(Phrase.build(Phrase.VERSION_INCOMPATIBLE, "CoreProtect", "v" + VersionUtils.getPluginVersion()));
+ Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_2));
+ return false;
+ }
+
// Branch validation
if (ConfigHandler.EDITION_BRANCH.length() == 0) {
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_1));
diff --git a/src/main/java/net/coreprotect/utility/BlockUtils.java b/src/main/java/net/coreprotect/utility/BlockUtils.java
index b8eb786..b0bd680 100644
--- a/src/main/java/net/coreprotect/utility/BlockUtils.java
+++ b/src/main/java/net/coreprotect/utility/BlockUtils.java
@@ -207,7 +207,8 @@ public class BlockUtils {
try {
if (blockState instanceof BlockInventoryHolder) {
if (singleBlock) {
- List chests = java.util.Arrays.asList(Material.CHEST, Material.TRAPPED_CHEST);
+ List chests = new java.util.ArrayList<>(java.util.Arrays.asList(Material.CHEST, Material.TRAPPED_CHEST));
+ chests.addAll(BukkitAdapter.ADAPTER.copperChestMaterials());
Material type = blockState.getType();
if (chests.contains(type)) {
inventory = ((org.bukkit.block.Chest) blockState).getBlockInventory();
diff --git a/src/main/java/net/coreprotect/utility/EntityUtils.java b/src/main/java/net/coreprotect/utility/EntityUtils.java
index 342e75f..7e1ab37 100644
--- a/src/main/java/net/coreprotect/utility/EntityUtils.java
+++ b/src/main/java/net/coreprotect/utility/EntityUtils.java
@@ -33,6 +33,12 @@ public class EntityUtils extends Queue {
id = ConfigHandler.entities.get(name);
}
else if (internal) {
+ // Check if another server has already added this entity (multi-server setup)
+ id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.ENTITIES, name);
+ if (id != -1) {
+ return id;
+ }
+
int entityID = ConfigHandler.entityId + 1;
ConfigHandler.entities.put(name, entityID);
ConfigHandler.entitiesReversed.put(entityID, name);
diff --git a/src/main/java/net/coreprotect/utility/MaterialUtils.java b/src/main/java/net/coreprotect/utility/MaterialUtils.java
index f0f568e..25129cd 100644
--- a/src/main/java/net/coreprotect/utility/MaterialUtils.java
+++ b/src/main/java/net/coreprotect/utility/MaterialUtils.java
@@ -35,6 +35,12 @@ public class MaterialUtils extends Queue {
id = ConfigHandler.materials.get(name);
}
else if (internal) {
+ // Check if another server has already added this material (multi-server setup)
+ id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.MATERIALS, name);
+ if (id != -1) {
+ return id;
+ }
+
int mid = ConfigHandler.materialId + 1;
ConfigHandler.materials.put(name, mid);
ConfigHandler.materialsReversed.put(mid, name);
@@ -54,6 +60,12 @@ public class MaterialUtils extends Queue {
id = ConfigHandler.blockdata.get(data);
}
else if (internal) {
+ // Check if another server has already added this blockdata (multi-server setup)
+ id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.BLOCKDATA, data);
+ if (id != -1) {
+ return id;
+ }
+
int bid = ConfigHandler.blockdataId + 1;
ConfigHandler.blockdata.put(data, bid);
ConfigHandler.blockdataReversed.put(bid, data);
@@ -135,6 +147,12 @@ public class MaterialUtils extends Queue {
id = ConfigHandler.art.get(name);
}
else if (internal) {
+ // Check if another server has already added this art (multi-server setup)
+ id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.ART, name);
+ if (id != -1) {
+ return id;
+ }
+
int artID = ConfigHandler.artId + 1;
ConfigHandler.art.put(name, artID);
ConfigHandler.artReversed.put(artID, name);
diff --git a/src/main/java/net/coreprotect/utility/WorldUtils.java b/src/main/java/net/coreprotect/utility/WorldUtils.java
index 4af911e..a63b5ab 100644
--- a/src/main/java/net/coreprotect/utility/WorldUtils.java
+++ b/src/main/java/net/coreprotect/utility/WorldUtils.java
@@ -16,6 +16,12 @@ public class WorldUtils extends Queue {
int id = -1;
try {
if (ConfigHandler.worlds.get(name) == null) {
+ // Check if another server has already added this world (multi-server setup)
+ id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.WORLDS, name);
+ if (id != -1) {
+ return id;
+ }
+
int wid = ConfigHandler.worldId + 1;
ConfigHandler.worlds.put(name, wid);
ConfigHandler.worldsReversed.put(wid, name);
@@ -84,7 +90,7 @@ public class WorldUtils extends Queue {
return id;
}
-
+
public static String getWidIndex(String queryTable) {
String index = "";
boolean isMySQL = net.coreprotect.config.Config.getGlobal().MYSQL;
@@ -121,4 +127,4 @@ public class WorldUtils extends Queue {
return index;
}
-}
\ No newline at end of file
+}