diff --git a/.gitignore b/.gitignore
index 27d5dde..df446fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# User-specific stuff
.idea/
+.vscode/
*.iml
*.ipr
@@ -8,10 +9,10 @@
# IntelliJ
out/
-# Compiled class file
+# Compiled class files
*.class
-# Log file
+# Log files
*.log
# BlueJ files
@@ -25,12 +26,10 @@ out/
*.tar.gz
*.rar
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+# Virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
-*~
-
-# temporary files which can be created if a process still has a handle open of a deleted file
+# Temporary files which can be created if a process still has a handle open on a deleted file
.fuse_hidden*
# KDE directory preferences
@@ -42,7 +41,7 @@ hs_err_pid*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
-# General
+# General system files
.DS_Store
.AppleDouble
.LSOverride
@@ -75,10 +74,10 @@ Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
-# Dump file
+# Dump files
*.stackdump
-# Folder config file
+# Folder config files
[Dd]esktop.ini
# Recycle Bin used on file shares
@@ -94,8 +93,10 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
+# Maven target directory
target/
+# Maven build files and backup files
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
diff --git a/Code/pom.xml b/Code/pom.xml
index 9c3d5cf..cd1d8df 100644
--- a/Code/pom.xml
+++ b/Code/pom.xml
@@ -6,7 +6,7 @@
com.github.happyuky7
SepareWorldItems
- 1.2.22
+ 1.2.23-DEV
jar
SepareWorldItems
@@ -27,6 +27,14 @@
sonatype
https://oss.sonatype.org/content/groups/public/
+
+ essentials-releases
+ https://repo.essentialsx.net/releases/
+
+
+ paper-repo
+ https://papermc.io/repo/repository/maven-public/
+
@@ -42,6 +50,12 @@
json
20240303
+
+ net.essentialsx
+ EssentialsX
+ 2.20.1
+ provided
+
@@ -92,4 +106,31 @@
+
+
+
+
+
+ org.checkerframework
+ checker-qual
+ 3.33.0
+
+
+ org.spigotmc
+ spigot-api
+ 1.21-R0.1-SNAPSHOT
+
+
+ com.google.errorprone
+ error_prone_annotations
+ 2.18.0
+
+
+ org.yaml
+ snakeyaml
+ 2.2
+
+
+
+
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/SepareWorldItems.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/SepareWorldItems.java
index d57b0e9..e811468 100644
--- a/Code/src/main/java/com/github/happyuky7/separeworlditems/SepareWorldItems.java
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/SepareWorldItems.java
@@ -9,7 +9,8 @@
import com.github.happyuky7.separeworlditems.commands.SepareWorldItemsCMD;
import com.github.happyuky7.separeworlditems.filemanagers.FileManager;
-import com.github.happyuky7.separeworlditems.listeners.WorldChangeEvent;
+import com.github.happyuky7.separeworlditems.listeners.Integration.EssentialsX.HomeEvent;
+import com.github.happyuky7.separeworlditems.listeners.base.WorldChangeEvent;
import com.github.happyuky7.separeworlditems.utils.ConvertTime;
import com.github.happyuky7.separeworlditems.utils.DownloadTranslations;
import com.github.happyuky7.separeworlditems.utils.BackupManager;
@@ -179,7 +180,7 @@ private void logPluginShutdownDetails() {
* does not match the required version.
*/
private void verifyConfigVersion() {
- if (!getConfig().getString("config-version").equalsIgnoreCase("1.2.22")) {
+ if (!getConfig().getString("config-version").equalsIgnoreCase("1.2.23-DEV")) {
Bukkit.getConsoleSender()
.sendMessage(MessageColors.getMsgColor("&3&m------------------------------------"));
Bukkit.getConsoleSender().sendMessage(MessageColors.getMsgColor("&f [Error]: &cConfig Version ERROR."));
@@ -204,6 +205,7 @@ public void registerCommands() {
public void registerEvents() {
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new WorldChangeEvent(this), this);
+ pm.registerEvents(new HomeEvent(this), this);
}
/**
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/ExperienceLoader.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/ExperienceLoader.java
new file mode 100644
index 0000000..4ba35a0
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/ExperienceLoader.java
@@ -0,0 +1,21 @@
+package com.github.happyuky7.separeworlditems.data.loaders;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+
+/**
+ * Utility class for loading player experience data from a configuration file.
+ */
+public class ExperienceLoader {
+
+ /**
+ * Loads the player's experience and level from the configuration file.
+ *
+ * @param player The player whose experience and level are being loaded.
+ * @param config The configuration file where the data is loaded from.
+ */
+ public static void load(Player player, FileConfiguration config) {
+ player.setExp((float) config.getDouble("exp", 0.0F));
+ player.setLevel(config.getInt("exp-level", 0));
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/InventoryLoader.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/InventoryLoader.java
new file mode 100644
index 0000000..b3a2d13
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/InventoryLoader.java
@@ -0,0 +1,31 @@
+package com.github.happyuky7.separeworlditems.data.loaders;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+
+/**
+ * Utility class for loading player inventory data from a configuration file.
+ */
+public class InventoryLoader {
+
+ /**
+ * Loads the player's inventory, ender chest, and armor contents from the
+ * configuration file.
+ *
+ * @param player The player whose inventory is being loaded.
+ * @param config The configuration file where the data is loaded from.
+ */
+ public static void load(Player player, FileConfiguration config) {
+ if (config.contains("inventory")) {
+ for (String key : config.getConfigurationSection("inventory").getKeys(false)) {
+ player.getInventory().setItem(Integer.parseInt(key), config.getItemStack("inventory." + key));
+ }
+ }
+
+ if (config.getBoolean("Options.ender-chest", true) && config.contains("ender_chest")) {
+ for (String key : config.getConfigurationSection("ender_chest").getKeys(false)) {
+ player.getEnderChest().setItem(Integer.parseInt(key), config.getItemStack("ender_chest." + key));
+ }
+ }
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/PlayerDataLoader.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/PlayerDataLoader.java
new file mode 100644
index 0000000..9ab77ad
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/loaders/PlayerDataLoader.java
@@ -0,0 +1,60 @@
+package com.github.happyuky7.separeworlditems.data.loaders;
+
+import org.bukkit.GameMode;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+/**
+ * Utility class for loading player data such as attributes, potion effects, and
+ * off-hand items from a configuration file.
+ */
+public class PlayerDataLoader {
+
+ /**
+ * Loads the player's attributes such as gamemode, flying state, health, hunger,
+ * and experience from the configuration file.
+ *
+ * @param player The player whose attributes are being loaded.
+ * @param config The configuration file where the data is loaded from.
+ */
+ public static void loadAttributes(Player player, FileConfiguration config) {
+ player.setGameMode(GameMode.valueOf(config.getString("gamemode", "SURVIVAL")));
+ player.setFlying(config.getBoolean("flying", false));
+ player.setHealth(config.getDouble("health", 20.0D));
+ player.setFoodLevel(config.getInt("hunger", 20));
+ ExperienceLoader.load(player, config);
+ }
+
+ /**
+ * Loads the player's active potion effects from the configuration file.
+ *
+ * @param player The player whose potion effects are being loaded.
+ * @param config The configuration file where the data is loaded from.
+ */
+ public static void loadPotionEffects(Player player, FileConfiguration config) {
+ if (config.contains("potion_effect")) {
+ for (String key : config.getConfigurationSection("potion_effect").getKeys(false)) {
+ @SuppressWarnings("deprecation")
+ PotionEffect effect = new PotionEffect(
+ PotionEffectType.getByName(config.getString("potion_effect." + key + ".type")),
+ config.getInt("potion_effect." + key + ".duration"),
+ config.getInt("potion_effect." + key + ".level"));
+ player.addPotionEffect(effect);
+ }
+ }
+ }
+
+ /**
+ * Loads the player's off-hand item from the configuration file.
+ *
+ * @param player The player whose off-hand item is being loaded.
+ * @param config The configuration file where the data is loaded from.
+ */
+ public static void loadOffHandItem(Player player, FileConfiguration config) {
+ if (config.contains("off_hand_item")) {
+ player.getInventory().setItemInOffHand(config.getItemStack("off_hand_item"));
+ }
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/models/PlayerData.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/models/PlayerData.java
new file mode 100644
index 0000000..75b8bde
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/models/PlayerData.java
@@ -0,0 +1,319 @@
+package com.github.happyuky7.separeworlditems.data.models;
+
+import org.bukkit.GameMode;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+
+import java.util.List;
+
+/**
+ * This class holds all the relevant data for a player.
+ */
+public class PlayerData {
+
+ private GameMode gameMode;
+ private boolean isFlying;
+ private double health;
+ private int hunger;
+ private float experience;
+ private int expLevel;
+ private List potionEffects;
+ private ItemStack[] inventory;
+ private ItemStack[] enderChest;
+ private ItemStack helmet;
+ private ItemStack chestplate;
+ private ItemStack leggings;
+ private ItemStack boots;
+ private ItemStack offHandItem;
+
+ /**
+ * Constructor to initialize all fields.
+ *
+ * @param gameMode The player's game mode.
+ * @param isFlying Whether the player is flying.
+ * @param health The player's health.
+ * @param hunger The player's hunger level.
+ * @param experience The player's experience.
+ * @param expLevel The player's experience level.
+ * @param potionEffects The player's active potion effects.
+ * @param inventory The player's inventory contents.
+ * @param enderChest The player's ender chest contents.
+ * @param helmet The player's helmet item.
+ * @param chestplate The player's chestplate item.
+ * @param leggings The player's leggings item.
+ * @param boots The player's boots item.
+ * @param offHandItem The player's off-hand item.
+ */
+ public PlayerData(GameMode gameMode, boolean isFlying, double health, int hunger, float experience, int expLevel,
+ List potionEffects, ItemStack[] inventory, ItemStack[] enderChest,
+ ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots, ItemStack offHandItem) {
+ this.gameMode = gameMode;
+ this.isFlying = isFlying;
+ this.health = health;
+ this.hunger = hunger;
+ this.experience = experience;
+ this.expLevel = expLevel;
+ this.potionEffects = potionEffects;
+ this.inventory = inventory;
+ this.enderChest = enderChest;
+ this.helmet = helmet;
+ this.chestplate = chestplate;
+ this.leggings = leggings;
+ this.boots = boots;
+ this.offHandItem = offHandItem;
+ }
+
+ // Getters and Setters
+
+ /**
+ * Gets the player's game mode.
+ *
+ * @return The player's game mode.
+ */
+ public GameMode getGameMode() {
+ return gameMode;
+ }
+
+ /**
+ * Sets the player's game mode.
+ *
+ * @param gameMode The player's new game mode.
+ */
+ public void setGameMode(GameMode gameMode) {
+ this.gameMode = gameMode;
+ }
+
+ /**
+ * Checks if the player is flying.
+ *
+ * @return True if the player is flying, otherwise false.
+ */
+ public boolean isFlying() {
+ return isFlying;
+ }
+
+ /**
+ * Sets the player's flying state.
+ *
+ * @param flying The player's new flying state.
+ */
+ public void setFlying(boolean flying) {
+ isFlying = flying;
+ }
+
+ /**
+ * Gets the player's health.
+ *
+ * @return The player's health.
+ */
+ public double getHealth() {
+ return health;
+ }
+
+ /**
+ * Sets the player's health.
+ *
+ * @param health The player's new health.
+ */
+ public void setHealth(double health) {
+ this.health = health;
+ }
+
+ /**
+ * Gets the player's hunger level.
+ *
+ * @return The player's hunger level.
+ */
+ public int getHunger() {
+ return hunger;
+ }
+
+ /**
+ * Sets the player's hunger level.
+ *
+ * @param hunger The player's new hunger level.
+ */
+ public void setHunger(int hunger) {
+ this.hunger = hunger;
+ }
+
+ /**
+ * Gets the player's experience.
+ *
+ * @return The player's experience.
+ */
+ public float getExperience() {
+ return experience;
+ }
+
+ /**
+ * Sets the player's experience.
+ *
+ * @param experience The player's new experience.
+ */
+ public void setExperience(float experience) {
+ this.experience = experience;
+ }
+
+ /**
+ * Gets the player's experience level.
+ *
+ * @return The player's experience level.
+ */
+ public int getExpLevel() {
+ return expLevel;
+ }
+
+ /**
+ * Sets the player's experience level.
+ *
+ * @param expLevel The player's new experience level.
+ */
+ public void setExpLevel(int expLevel) {
+ this.expLevel = expLevel;
+ }
+
+ /**
+ * Gets the player's active potion effects.
+ *
+ * @return A list of the player's active potion effects.
+ */
+ public List getPotionEffects() {
+ return potionEffects;
+ }
+
+ /**
+ * Sets the player's active potion effects.
+ *
+ * @param potionEffects The player's new active potion effects.
+ */
+ public void setPotionEffects(List potionEffects) {
+ this.potionEffects = potionEffects;
+ }
+
+ /**
+ * Gets the player's inventory contents.
+ *
+ * @return The player's inventory contents.
+ */
+ public ItemStack[] getInventory() {
+ return inventory;
+ }
+
+ /**
+ * Sets the player's inventory contents.
+ *
+ * @param inventory The player's new inventory contents.
+ */
+ public void setInventory(ItemStack[] inventory) {
+ this.inventory = inventory;
+ }
+
+ /**
+ * Gets the player's ender chest contents.
+ *
+ * @return The player's ender chest contents.
+ */
+ public ItemStack[] getEnderChest() {
+ return enderChest;
+ }
+
+ /**
+ * Sets the player's ender chest contents.
+ *
+ * @param enderChest The player's new ender chest contents.
+ */
+ public void setEnderChest(ItemStack[] enderChest) {
+ this.enderChest = enderChest;
+ }
+
+ /**
+ * Gets the player's helmet item.
+ *
+ * @return The player's helmet item.
+ */
+ public ItemStack getHelmet() {
+ return helmet;
+ }
+
+ /**
+ * Sets the player's helmet item.
+ *
+ * @param helmet The player's new helmet item.
+ */
+ public void setHelmet(ItemStack helmet) {
+ this.helmet = helmet;
+ }
+
+ /**
+ * Gets the player's chestplate item.
+ *
+ * @return The player's chestplate item.
+ */
+ public ItemStack getChestplate() {
+ return chestplate;
+ }
+
+ /**
+ * Sets the player's chestplate item.
+ *
+ * @param chestplate The player's new chestplate item.
+ */
+ public void setChestplate(ItemStack chestplate) {
+ this.chestplate = chestplate;
+ }
+
+ /**
+ * Gets the player's leggings item.
+ *
+ * @return The player's leggings item.
+ */
+ public ItemStack getLeggings() {
+ return leggings;
+ }
+
+ /**
+ * Sets the player's leggings item.
+ *
+ * @param leggings The player's new leggings item.
+ */
+ public void setLeggings(ItemStack leggings) {
+ this.leggings = leggings;
+ }
+
+ /**
+ * Gets the player's boots item.
+ *
+ * @return The player's boots item.
+ */
+ public ItemStack getBoots() {
+ return boots;
+ }
+
+ /**
+ * Sets the player's boots item.
+ *
+ * @param boots The player's new boots item.
+ */
+ public void setBoots(ItemStack boots) {
+ this.boots = boots;
+ }
+
+ /**
+ * Gets the player's off-hand item.
+ *
+ * @return The player's off-hand item.
+ */
+ public ItemStack getOffHandItem() {
+ return offHandItem;
+ }
+
+ /**
+ * Sets the player's off-hand item.
+ *
+ * @param offHandItem The player's new off-hand item.
+ */
+ public void setOffHandItem(ItemStack offHandItem) {
+ this.offHandItem = offHandItem;
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/ExperienceSaver.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/ExperienceSaver.java
new file mode 100644
index 0000000..83cf0d0
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/ExperienceSaver.java
@@ -0,0 +1,21 @@
+package com.github.happyuky7.separeworlditems.data.savers;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+
+/**
+ * Utility class for saving player experience data to a configuration file.
+ */
+public class ExperienceSaver {
+
+ /**
+ * Saves the player's experience and level to the configuration file.
+ *
+ * @param player The player whose experience and level are being saved.
+ * @param config The configuration file where the data is saved.
+ */
+ public static void save(Player player, FileConfiguration config) {
+ config.set("exp", player.getExp());
+ config.set("exp-level", player.getLevel());
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/InventorySaver.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/InventorySaver.java
new file mode 100644
index 0000000..9c33547
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/InventorySaver.java
@@ -0,0 +1,40 @@
+package com.github.happyuky7.separeworlditems.data.savers;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+/**
+ * Utility class for saving player inventory data to a configuration file.
+ */
+public class InventorySaver {
+
+ /**
+ * Saves the player's inventory, ender chest, and armor contents to the
+ * configuration file.
+ *
+ * @param player The player whose inventory is being saved.
+ * @param config The configuration file where the data is saved.
+ */
+ public static void save(Player player, FileConfiguration config) {
+ // Save inventory contents
+ int index = 0;
+ for (ItemStack item : player.getInventory().getContents()) {
+ config.set("inventory." + index++, item);
+ }
+
+ // Save ender chest contents if enabled
+ if (config.getBoolean("Options.ender-chest", true)) {
+ index = 0;
+ for (ItemStack item : player.getEnderChest().getContents()) {
+ config.set("ender_chest." + index++, item);
+ }
+ }
+
+ // Save armor contents
+ config.set("armor_contents.helmet", player.getInventory().getHelmet());
+ config.set("armor_contents.chestplate", player.getInventory().getChestplate());
+ config.set("armor_contents.leggings", player.getInventory().getLeggings());
+ config.set("armor_contents.boots", player.getInventory().getBoots());
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/PlayerDataSaver.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/PlayerDataSaver.java
new file mode 100644
index 0000000..05d050c
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/data/savers/PlayerDataSaver.java
@@ -0,0 +1,66 @@
+package com.github.happyuky7.separeworlditems.data.savers;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+
+/**
+ * Utility class for saving player data such as attributes, potion effects, and
+ * off-hand items to a configuration file.
+ */
+public class PlayerDataSaver {
+
+ /**
+ * Saves the player's attributes such as gamemode, flying state, health, hunger,
+ * and experience to the configuration file.
+ *
+ * @param player The player whose attributes are being saved.
+ * @param config The configuration file where the data is saved.
+ */
+ public static void saveAttributes(Player player, FileConfiguration config) {
+ // Save gamemode
+ if (config.getBoolean("Options.gamemode", true)) {
+ config.set("gamemode", player.getGameMode().toString());
+ }
+
+ // Save flying state
+ if (config.getBoolean("Options.flying", true)) {
+ config.set("flying", player.isFlying());
+ }
+
+ // Save health and hunger
+ config.set("health", config.getBoolean("Options.health-options.health-default-save", true)
+ ? player.getHealth()
+ : 20.0D);
+ config.set("hunger", player.getFoodLevel());
+
+ ExperienceSaver.save(player, config);
+ }
+
+ /**
+ * Saves the player's active potion effects to the configuration file.
+ *
+ * @param player The player whose potion effects are being saved.
+ * @param config The configuration file where the data is saved.
+ */
+ @SuppressWarnings("deprecation")
+ public static void savePotionEffects(Player player, FileConfiguration config) {
+ int index = 0;
+ for (PotionEffect effect : player.getActivePotionEffects()) {
+ config.set("potion_effect." + index + ".type", effect.getType().getName());
+ config.set("potion_effect." + index + ".level", effect.getAmplifier());
+ config.set("potion_effect." + index + ".duration", effect.getDuration());
+ index++;
+ }
+ }
+
+ /**
+ * Saves the player's off-hand item to the configuration file.
+ *
+ * @param player The player whose off-hand item is being saved.
+ * @param config The configuration file where the data is saved.
+ */
+ public static void saveOffHandItem(Player player, FileConfiguration config) {
+ config.set("off_hand_item", player.getInventory().getItemInOffHand());
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/Integration/EssentialsX/HomeEvent.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/Integration/EssentialsX/HomeEvent.java
new file mode 100644
index 0000000..9ff7cd0
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/Integration/EssentialsX/HomeEvent.java
@@ -0,0 +1,193 @@
+package com.github.happyuky7.separeworlditems.listeners.Integration.EssentialsX;
+
+import com.github.happyuky7.separeworlditems.SepareWorldItems;
+import com.github.happyuky7.separeworlditems.data.loaders.InventoryLoader;
+import com.github.happyuky7.separeworlditems.data.loaders.PlayerDataLoader;
+import com.github.happyuky7.separeworlditems.data.savers.InventorySaver;
+import com.github.happyuky7.separeworlditems.data.savers.PlayerDataSaver;
+import com.github.happyuky7.separeworlditems.filemanagers.FileManager2;
+import com.github.happyuky7.separeworlditems.utils.TeleportationManager;
+
+import net.ess3.api.events.UserTeleportHomeEvent;
+
+import org.bukkit.GameMode;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+import java.io.File;
+
+/**
+ * Event listener that handles player teleport events specifically related to
+ * home teleports.
+ * Integrates with the EssentialsX plugin to manage player data during
+ * teleportation.
+ */
+public class HomeEvent implements Listener {
+
+ private final SepareWorldItems plugin;
+
+ /**
+ * Constructor for initializing the HomeEvent listener with the main plugin
+ * instance.
+ *
+ * @param plugin The main plugin instance.
+ */
+ public HomeEvent(SepareWorldItems plugin) {
+ this.plugin = plugin;
+ }
+
+ /**
+ * Handles the user teleportation event when a player teleports to their home.
+ * It ensures that player data is saved and reloaded appropriately for the
+ * target world.
+ *
+ * @param event The event triggered when a player teleports to their home.
+ */
+ @EventHandler
+ public void onUserTeleportHome(UserTeleportHomeEvent event) {
+ @SuppressWarnings("deprecation")
+ Player player = event.getUser().getBase().getPlayer();
+
+ // Skip handling if the player is already in a teleportation process
+ if (TeleportationManager.isTeleporting(player.getUniqueId())) {
+ return; // Player is already teleporting, skip further handling
+ }
+
+ String fromWorld = player.getWorld().getName(); // Current world
+ String toWorld = event.getHomeLocation().getWorld().getName(); // Target world (home)
+
+ // Check if both the source and destination worlds are configured in the plugin
+ FileConfiguration config = plugin.getConfig();
+ if (config.contains("worlds." + fromWorld) && config.contains("worlds." + toWorld)) {
+ String fromGroup = config.getString("worlds." + fromWorld);
+ String toGroup = config.getString("worlds." + toWorld);
+
+ // Mark the player as teleporting if the worlds differ
+ if (!fromWorld.equals(toWorld)) {
+ TeleportationManager.setTeleporting(player.getUniqueId(), true);
+ }
+
+ // Save player data for the source world
+ savePlayerData(player, fromGroup);
+
+ // Load or reload player data based on the group of the target world
+ if (!fromGroup.equals(toGroup)) {
+ loadPlayerData(player, toGroup);
+ } else {
+ reloadAllPlayerData(player, fromGroup);
+ }
+ }
+ }
+
+ /**
+ * Saves the player's current data (inventory, attributes, potion effects, etc.)
+ * to a group-specific configuration file before teleportation.
+ *
+ * @param player The player whose data is being saved.
+ * @param groupName The group name associated with the player's current world.
+ */
+ private void savePlayerData(Player player, String groupName) {
+ File file = new File(plugin.getDataFolder() + File.separator + "groups"
+ + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
+ FileConfiguration config = FileManager2.getYaml(file);
+
+ // Save various player data into the configuration file
+ InventorySaver.save(player, config);
+ PlayerDataSaver.saveAttributes(player, config);
+ PlayerDataSaver.savePotionEffects(player, config);
+ PlayerDataSaver.saveOffHandItem(player, config);
+
+ // Save the updated configuration to disk
+ FileManager2.saveConfiguration(file, config);
+
+ // Clear the player's state in preparation for the teleportation
+ clearPlayerState(player);
+ }
+
+ /**
+ * Loads the player's data from a group-specific configuration file after
+ * teleportation.
+ *
+ * @param player The player whose data is being loaded.
+ * @param groupName The group name associated with the target world.
+ */
+ private void loadPlayerData(Player player, String groupName) {
+ File file = new File(plugin.getDataFolder() + File.separator + "groups"
+ + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
+ FileConfiguration config = FileManager2.getYaml(file);
+
+ // Load player data (inventory, attributes, potion effects, etc.)
+ InventoryLoader.load(player, config);
+ PlayerDataLoader.loadAttributes(player, config);
+ PlayerDataLoader.loadPotionEffects(player, config);
+ PlayerDataLoader.loadOffHandItem(player, config);
+ }
+
+ /**
+ * Clears the player's state by resetting inventory, ender chest, game mode,
+ * health,
+ * food level, experience, and other attributes to ensure a clean state when the
+ * player transitions between worlds.
+ *
+ * @param player The player whose state is being cleared.
+ */
+ private void clearPlayerState(Player player) {
+ // Clear the player's inventory and ender chest
+ player.getInventory().clear();
+ player.getEnderChest().clear();
+
+ // Reset the player's state to a default, clean state
+ player.setFlying(false);
+ player.setGameMode(GameMode.SURVIVAL);
+ player.setHealth(20.0D); // Full health
+ player.setFoodLevel(20); // Full hunger
+ player.setExp(0.0F); // No experience
+ player.setLevel(0); // No levels
+ }
+
+ /**
+ * Reloads all of the player's data (inventory, attributes, potion effects,
+ * etc.)
+ * from a group-specific configuration file.
+ *
+ * @param player The player whose data is being reloaded.
+ * @param groupName The group name associated with the player's world.
+ */
+ private void reloadAllPlayerData(Player player, String groupName) {
+ File file = new File(plugin.getDataFolder() + File.separator + "groups"
+ + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
+ FileConfiguration config = FileManager2.getYaml(file);
+
+ // Reload the player's data (inventory, attributes, potion effects, off-hand,
+ // etc.)
+ InventoryLoader.load(player, config);
+ PlayerDataLoader.loadAttributes(player, config);
+ PlayerDataLoader.loadPotionEffects(player, config);
+ PlayerDataLoader.loadOffHandItem(player, config);
+
+ // Reload the player's experience and level if necessary
+ reloadExperienceAndLevel(player, config);
+ }
+
+ /**
+ * Reloads the player's experience and level from a group-specific configuration
+ * file to ensure they match the state from the previous world or group.
+ *
+ * @param player The player whose experience and level are being reloaded.
+ * @param config The configuration file containing the player's data.
+ */
+ private void reloadExperienceAndLevel(Player player, FileConfiguration config) {
+ // Check if experience and level data are present in the configuration
+ if (config.contains("exp") && config.contains("exp-level")) {
+ // Retrieve and set the player's experience and level
+ float experience = (float) config.getDouble("exp", 0.0F);
+ int level = config.getInt("exp-level", 0);
+
+ // Set the player's experience and level from the loaded data
+ player.setExp(experience);
+ player.setLevel(level);
+ }
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/WorldChangeEvent.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/WorldChangeEvent.java
deleted file mode 100644
index 8934f76..0000000
--- a/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/WorldChangeEvent.java
+++ /dev/null
@@ -1,287 +0,0 @@
-package com.github.happyuky7.separeworlditems.listeners;
-
-/*
- * Code by: Happyuky7
- * GitHub: https://github.com/Happyuky7
- * License: Custom
- * Link: https://github.com/Happyuky7/SEPARE-WORLD-ITEMS
- */
-
-import com.github.happyuky7.separeworlditems.SepareWorldItems;
-import com.github.happyuky7.separeworlditems.filemanagers.FileManager2;
-import com.github.happyuky7.separeworlditems.utils.MessageColors;
-import org.bukkit.GameMode;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerChangedWorldEvent;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
-
-import java.io.File;
-
-/**
- * Event listener for handling player world change events and managing player
- * data
- * specific to different worlds.
- */
-public class WorldChangeEvent implements Listener {
-
- private final SepareWorldItems plugin;
-
- /**
- * Constructor for WorldChangeEvent.
- *
- * @param plugin The main plugin instance.
- */
- public WorldChangeEvent(SepareWorldItems plugin) {
- this.plugin = plugin;
- }
-
- /**
- * Event handler for PlayerChangedWorldEvent. Manages inventory and player state
- * when a player changes worlds.
- *
- * @param event The PlayerChangedWorldEvent.
- */
- @EventHandler
- public void onWorldChange(PlayerChangedWorldEvent event) {
- Player player = event.getPlayer();
-
- // Handle bypass option
- if (plugin.playerlist1.contains(player.getUniqueId())) {
- if (plugin.getConfig().getBoolean("Options.bypass-world-options.use_bypass", true)) {
- player.sendMessage(
- MessageColors.getMsgColor(plugin.getLangs().getString("general.bypass.bypass-warning-alert")));
- return;
- }
- plugin.playerlist1.remove(player.getUniqueId());
- }
-
- // Get source and target world names
- String fromWorld = event.getFrom().getName();
- String toWorld = player.getWorld().getName();
-
- FileConfiguration config = plugin.getConfig();
-
- if (config.contains("worlds." + fromWorld) && config.contains("worlds." + toWorld)) {
- String fromGroup = config.getString("worlds." + fromWorld);
- String toGroup = config.getString("worlds." + toWorld);
-
- if (!fromGroup.equals(toGroup)) {
- savePlayerData(player, fromGroup);
- loadPlayerData(player, toGroup);
- }
- }
- }
-
- /**
- * Saves the player's current data to a group-specific configuration file.
- *
- * @param player the player whose data is being saved
- * @param groupName the group name associated with the player's current world
- */
- private void savePlayerData(Player player, String groupName) {
- File file = new File(plugin.getDataFolder() + File.separator + "groups"
- + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
- FileConfiguration config = FileManager2.getYaml(file);
-
- saveInventory(player, config);
- savePlayerAttributes(player, config);
- savePotionEffects(player, config);
- saveOffHandItem(player, config);
-
- FileManager2.saveConfiguration(file, config);
-
- clearPlayerState(player);
- }
-
- /**
- * Loads the player's data from a group-specific configuration file.
- *
- * @param player the player whose data is being loaded
- * @param groupName the group name associated with the player's target world
- */
- private void loadPlayerData(Player player, String groupName) {
- File file = new File(plugin.getDataFolder() + File.separator + "groups"
- + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
- FileConfiguration config = FileManager2.getYaml(file);
-
- loadInventory(player, config);
- loadPlayerAttributes(player, config);
- loadPotionEffects(player, config);
- loadOffHandItem(player, config);
- }
-
- /**
- * Saves the player's inventory, ender chest, and armor contents to the
- * configuration file.
- *
- * @param player The player whose inventory is being saved.
- * @param config The configuration file where the data is saved.
- */
- private void saveInventory(Player player, FileConfiguration config) {
- // Save inventory contents
- int index = 0;
- for (ItemStack item : player.getInventory().getContents()) {
- config.set("inventory." + index++, item);
- }
-
- // Save ender chest contents if enabled
- if (plugin.getConfig().getBoolean("Options.ender-chest", true)) {
- index = 0;
- for (ItemStack item : player.getEnderChest().getContents()) {
- config.set("ender_chest." + index++, item);
- }
- }
-
- // Save armor contents
- config.set("armor_contents.helmet", player.getInventory().getHelmet());
- config.set("armor_contents.chestplate", player.getInventory().getChestplate());
- config.set("armor_contents.leggings", player.getInventory().getLeggings());
- config.set("armor_contents.boots", player.getInventory().getBoots());
- }
-
- /**
- * Saves the player's attributes such as gamemode, flying state, health, hunger,
- * and experience.
- *
- * @param player The player whose attributes are being saved.
- * @param config The configuration file where the data is saved.
- */
- private void savePlayerAttributes(Player player, FileConfiguration config) {
- // Save gamemode
- if (plugin.getConfig().getBoolean("Options.gamemode", true)) {
- config.set("gamemode", player.getGameMode().toString());
- }
-
- // Save flying state
- if (plugin.getConfig().getBoolean("Options.flying", true)) {
- config.set("flying", player.isFlying());
- }
-
- // Save health and hunger
- config.set("health", plugin.getConfig().getBoolean("Options.health-options.health-default-save", true)
- ? player.getHealth()
- : 20.0D);
- config.set("hunger", player.getFoodLevel());
-
- // Save experience
- config.set("exp", player.getExp());
- config.set("exp-level", player.getLevel());
- }
-
- /**
- * Saves the player's active potion effects to the configuration file.
- *
- * @param player The player whose potion effects are being saved.
- * @param config The configuration file where the data is saved.
- */
- @SuppressWarnings("deprecation")
- private void savePotionEffects(Player player, FileConfiguration config) {
- int index = 0;
- for (PotionEffect effect : player.getActivePotionEffects()) {
- config.set("potion_effect." + index + ".type", effect.getType().getName());
- config.set("potion_effect." + index + ".level", effect.getAmplifier());
- config.set("potion_effect." + index + ".duration", effect.getDuration());
- index++;
- }
- }
-
- /**
- * Saves the player's off-hand item to the configuration file.
- *
- * @param player The player whose off-hand item is being saved.
- * @param config The configuration file where the data is saved.
- */
- private void saveOffHandItem(Player player, FileConfiguration config) {
- config.set("off_hand_item", player.getInventory().getItemInOffHand());
- }
-
- /**
- * Loads the player's off-hand item from the configuration file.
- *
- * @param player The player whose off-hand item is being loaded.
- * @param config The configuration file where the data is loaded from.
- */
- private void loadOffHandItem(Player player, FileConfiguration config) {
- if (config.contains("off_hand_item")) {
- player.getInventory().setItemInOffHand(config.getItemStack("off_hand_item"));
- }
- }
-
- /**
- * Clears the player's state by resetting their inventory, ender chest, flying
- * state, gamemode, health, hunger, experience, and level.
- *
- * @param player The player whose state is being cleared.
- */
- private void clearPlayerState(Player player) {
- player.getInventory().clear();
- player.getEnderChest().clear();
- player.setFlying(false);
- player.setGameMode(GameMode.SURVIVAL);
- player.setHealth(20.0D);
- player.setFoodLevel(20);
- player.setExp(0.0F);
- player.setLevel(0);
- }
-
- /**
- * Loads the player's inventory, ender chest, and armor contents from the
- * configuration file.
- *
- * @param player The player whose inventory is being loaded.
- * @param config The configuration file where the data is loaded from.
- */
- private void loadInventory(Player player, FileConfiguration config) {
- if (config.contains("inventory")) {
- for (String key : config.getConfigurationSection("inventory").getKeys(false)) {
- player.getInventory().setItem(Integer.parseInt(key), config.getItemStack("inventory." + key));
- }
- }
-
- if (plugin.getConfig().getBoolean("Options.ender-chest", true) && config.contains("ender_chest")) {
- for (String key : config.getConfigurationSection("ender_chest").getKeys(false)) {
- player.getEnderChest().setItem(Integer.parseInt(key), config.getItemStack("ender_chest." + key));
- }
- }
- }
-
- /**
- * Loads the player's attributes such as gamemode, flying state, health, hunger,
- * and experience from the configuration file.
- *
- * @param player The player whose attributes are being loaded.
- * @param config The configuration file where the data is loaded from.
- */
- private void loadPlayerAttributes(Player player, FileConfiguration config) {
- player.setGameMode(GameMode.valueOf(config.getString("gamemode", "SURVIVAL")));
- player.setFlying(config.getBoolean("flying", false));
- player.setHealth(config.getDouble("health", 20.0D));
- player.setFoodLevel(config.getInt("hunger", 20));
- player.setExp((float) config.getDouble("exp", 0.0F));
- player.setLevel(config.getInt("exp-level", 0));
- }
-
- /**
- * Loads the player's active potion effects from the configuration file.
- *
- * @param player The player whose potion effects are being loaded.
- * @param config The configuration file where the data is loaded from.
- */
- private void loadPotionEffects(Player player, FileConfiguration config) {
- if (config.contains("potion_effect")) {
- for (String key : config.getConfigurationSection("potion_effect").getKeys(false)) {
- @SuppressWarnings("deprecation")
- PotionEffect effect = new PotionEffect(
- PotionEffectType.getByName(config.getString("potion_effect." + key + ".type")),
- config.getInt("potion_effect." + key + ".duration"),
- config.getInt("potion_effect." + key + ".level"));
- player.addPotionEffect(effect);
- }
- }
- }
-}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/base/WorldChangeEvent.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/base/WorldChangeEvent.java
new file mode 100644
index 0000000..3a65278
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/listeners/base/WorldChangeEvent.java
@@ -0,0 +1,192 @@
+package com.github.happyuky7.separeworlditems.listeners.base;
+
+import com.github.happyuky7.separeworlditems.SepareWorldItems;
+import com.github.happyuky7.separeworlditems.data.loaders.InventoryLoader;
+import com.github.happyuky7.separeworlditems.data.loaders.PlayerDataLoader;
+import com.github.happyuky7.separeworlditems.data.savers.InventorySaver;
+import com.github.happyuky7.separeworlditems.data.savers.PlayerDataSaver;
+import com.github.happyuky7.separeworlditems.filemanagers.FileManager2;
+import com.github.happyuky7.separeworlditems.utils.TeleportationManager;
+
+import org.bukkit.GameMode;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerChangedWorldEvent;
+
+import java.io.File;
+
+/**
+ * Event listener for handling player world change events.
+ * Manages player data and inventory based on the world the player changes to.
+ * Supports saving and loading data between different world groups.
+ */
+public class WorldChangeEvent implements Listener {
+
+ private final SepareWorldItems plugin;
+
+ /**
+ * Constructs a new WorldChangeEvent listener.
+ *
+ * @param plugin The main plugin instance.
+ */
+ public WorldChangeEvent(SepareWorldItems plugin) {
+ this.plugin = plugin;
+ }
+
+ /**
+ * Handles the PlayerChangedWorldEvent. This method is triggered whenever a
+ * player
+ * changes worlds. It manages the player's data, such as inventory, attributes,
+ * and other world-specific states.
+ *
+ * @param event The PlayerChangedWorldEvent that triggered this handler.
+ */
+ @EventHandler
+ public void onWorldChange(PlayerChangedWorldEvent event) {
+ Player player = event.getPlayer();
+
+ // Prevent further handling if the player is in the teleportation process
+ // trigger by EssentialsX.
+ if (TeleportationManager.isTeleporting(player.getUniqueId())) {
+ TeleportationManager.setTeleporting(player.getUniqueId(), false); // Reset the teleportation flag
+ return; // Skip further processing
+ }
+
+ // Retrieve the world names the player is transitioning between
+ String fromWorld = event.getFrom().getName(); // Previous world
+ String toWorld = player.getWorld().getName(); // Target world
+
+ FileConfiguration config = plugin.getConfig();
+
+ // Check if the worlds are configured in the plugin's settings
+ if (config.contains("worlds." + fromWorld) && config.contains("worlds." + toWorld)) {
+ // Retrieve the world groups the player is switching between
+ String fromGroup = config.getString("worlds." + fromWorld);
+ String toGroup = config.getString("worlds." + toWorld);
+
+ // Save the player's data from the previous world before switching
+ savePlayerData(player, fromGroup);
+
+ // If worlds belong to different groups, load data for the new world
+ if (!fromGroup.equals(toGroup)) {
+ loadPlayerData(player, toGroup);
+ } else {
+ // If worlds belong to the same group, reload the player's data without changes
+ reloadAllPlayerData(player, fromGroup);
+ }
+ }
+ }
+
+ /**
+ * Saves the player's data (inventory, attributes, potion effects, etc.) to a
+ * group-specific configuration file based on the player's current world group.
+ *
+ * @param player The player whose data is being saved.
+ * @param groupName The group name associated with the player's current world.
+ */
+ private void savePlayerData(Player player, String groupName) {
+ File file = new File(plugin.getDataFolder() + File.separator + "groups"
+ + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
+ FileConfiguration config = FileManager2.getYaml(file);
+
+ // Save various player data (inventory, attributes, potion effects, etc.)
+ InventorySaver.save(player, config);
+ PlayerDataSaver.saveAttributes(player, config);
+ PlayerDataSaver.savePotionEffects(player, config);
+ PlayerDataSaver.saveOffHandItem(player, config);
+
+ // Persist the changes in the configuration file
+ FileManager2.saveConfiguration(file, config);
+
+ // Clear the player's state to prevent unwanted data persistence (e.g.,
+ // inventory)
+ clearPlayerState(player);
+ }
+
+ /**
+ * Loads the player's data (inventory, attributes, potion effects, etc.) from a
+ * group-specific configuration file based on the player's target world group.
+ *
+ * @param player The player whose data is being loaded.
+ * @param groupName The group name associated with the player's target world.
+ */
+ private void loadPlayerData(Player player, String groupName) {
+ File file = new File(plugin.getDataFolder() + File.separator + "groups"
+ + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
+ FileConfiguration config = FileManager2.getYaml(file);
+
+ // Load player data (inventory, attributes, potion effects, etc.)
+ InventoryLoader.load(player, config);
+ PlayerDataLoader.loadAttributes(player, config);
+ PlayerDataLoader.loadPotionEffects(player, config);
+ PlayerDataLoader.loadOffHandItem(player, config);
+ }
+
+ /**
+ * Clears the player's state by resetting inventory, ender chest, game mode,
+ * health,
+ * food level, experience, and other attributes to ensure a clean state when the
+ * player transitions between worlds.
+ *
+ * @param player The player whose state is being cleared.
+ */
+ private void clearPlayerState(Player player) {
+ // Clear the player's inventory and ender chest
+ player.getInventory().clear();
+ player.getEnderChest().clear();
+
+ // Reset the player's state to a default, clean state
+ player.setFlying(false);
+ player.setGameMode(GameMode.SURVIVAL);
+ player.setHealth(20.0D); // Full health
+ player.setFoodLevel(20); // Full hunger
+ player.setExp(0.0F); // No experience
+ player.setLevel(0); // No levels
+ }
+
+ /**
+ * Reloads all of the player's data (inventory, attributes, potion effects,
+ * etc.)
+ * from a group-specific configuration file.
+ *
+ * @param player The player whose data is being reloaded.
+ * @param groupName The group name associated with the player's world.
+ */
+ private void reloadAllPlayerData(Player player, String groupName) {
+ File file = new File(plugin.getDataFolder() + File.separator + "groups"
+ + File.separator + groupName + File.separator + player.getName() + "-" + player.getUniqueId() + ".yml");
+ FileConfiguration config = FileManager2.getYaml(file);
+
+ // Reload the player's data (inventory, attributes, potion effects, off-hand,
+ // etc.)
+ InventoryLoader.load(player, config);
+ PlayerDataLoader.loadAttributes(player, config);
+ PlayerDataLoader.loadPotionEffects(player, config);
+ PlayerDataLoader.loadOffHandItem(player, config);
+
+ // Reload the player's experience and level if necessary
+ reloadExperienceAndLevel(player, config);
+ }
+
+ /**
+ * Reloads the player's experience and level from a group-specific configuration
+ * file to ensure they match the state from the previous world or group.
+ *
+ * @param player The player whose experience and level are being reloaded.
+ * @param config The configuration file containing the player's data.
+ */
+ private void reloadExperienceAndLevel(Player player, FileConfiguration config) {
+ // Check if experience and level data are present in the configuration
+ if (config.contains("exp") && config.contains("exp-level")) {
+ // Retrieve and set the player's experience and level
+ float experience = (float) config.getDouble("exp", 0.0F);
+ int level = config.getInt("exp-level", 0);
+
+ // Set the player's experience and level from the loaded data
+ player.setExp(experience);
+ player.setLevel(level);
+ }
+ }
+}
diff --git a/Code/src/main/java/com/github/happyuky7/separeworlditems/utils/TeleportationManager.java b/Code/src/main/java/com/github/happyuky7/separeworlditems/utils/TeleportationManager.java
new file mode 100644
index 0000000..69f0241
--- /dev/null
+++ b/Code/src/main/java/com/github/happyuky7/separeworlditems/utils/TeleportationManager.java
@@ -0,0 +1,74 @@
+package com.github.happyuky7.separeworlditems.utils;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Utility class that manages the state of players during teleportation events.
+ * It keeps track of players who are in the process of teleporting, preventing
+ * conflicts and ensuring smooth teleportation operations, such as saving and loading
+ * player data across different worlds.
+ *
+ * This class is crucial in scenarios where teleportation events are triggered,
+ * and the system must ensure that a player does not get caught in multiple teleportation
+ * events simultaneously. For example, when a player teleports between worlds, their data
+ * must be saved before teleporting and reloaded afterward. The {@code TeleportationManager}
+ * prevents the data from being overwritten or handled multiple times while the player is already teleporting.
+ *
+ */
+public class TeleportationManager {
+ // Set to store UUIDs of players who are currently teleporting
+ private static final Set teleportingPlayers = new HashSet<>();
+
+ /**
+ * Marks a player as being in the process of teleporting or not.
+ *
+ * This method is called before teleportation begins to mark the player as
+ * being in a teleporting state. It ensures that any actions that require
+ * the player to be out of teleportation (e.g., saving/loading player data)
+ * will not interfere with the teleportation process.
+ *
+ *
+ * Example usage:
+ *
+ * {@code TeleportationManager.setTeleporting(playerUUID, true); // Mark as teleporting}
+ * {@code TeleportationManager.setTeleporting(playerUUID, false); // Mark as not teleporting}
+ *
+ *
+ *
+ * @param playerUUID The unique identifier of the player.
+ * @param isTeleporting A boolean indicating whether the player is teleporting.
+ */
+ public static void setTeleporting(UUID playerUUID, boolean isTeleporting) {
+ if (isTeleporting) {
+ teleportingPlayers.add(playerUUID); // Add the player to the teleporting set
+ } else {
+ teleportingPlayers.remove(playerUUID); // Remove the player from the teleporting set
+ }
+ }
+
+ /**
+ * Checks whether a player is currently in the process of teleporting.
+ *
+ * This method is used to verify if a player is already teleporting, preventing
+ * multiple teleportation processes from being triggered at once. This is particularly
+ * important when there are multiple triggers for teleportation, such as home teleport
+ * or world change.
+ *
+ *
+ * Example usage:
+ *
+ * {@code if (TeleportationManager.isTeleporting(playerUUID)) { }
+ * // Skip processing since the player is already teleporting
+ * }
+ *
+ *
+ *
+ * @param playerUUID The unique identifier of the player.
+ * @return {@code true} if the player is currently teleporting, {@code false} otherwise.
+ */
+ public static boolean isTeleporting(UUID playerUUID) {
+ return teleportingPlayers.contains(playerUUID); // Return true if player is in teleporting set
+ }
+}
diff --git a/Code/src/main/resources/config.yml b/Code/src/main/resources/config.yml
index 27aad49..7929846 100644
--- a/Code/src/main/resources/config.yml
+++ b/Code/src/main/resources/config.yml
@@ -1,12 +1,12 @@
#
# SepareWorldItems
-# Version: 1.2.22
+# Version: 1.2.23-DEV
# Tutorial: https://github.com/Happyuky7/SEPARE-WORLD-ITEMS/wiki
# Discord OR Support: https://discord.gg/3EebYUyeUX
#
-# Config Version: 1.2.22
-config-version: 1.2.22
+# Config Version: 1.2.23-DEV
+config-version: 1.2.23-DEV
experimental:
lang: en_US
diff --git a/Code/src/main/resources/langs.yml b/Code/src/main/resources/langs.yml
index 83038c9..0f3629d 100644
--- a/Code/src/main/resources/langs.yml
+++ b/Code/src/main/resources/langs.yml
@@ -1,5 +1,5 @@
# Config Langs
-# Config = 1.2.22
+# Config = 1.2.23-DEV
# Prefix Value: %prefix%
# Lang: EN
# Here you can find the list of languages to which the plugin is already translated:
diff --git a/Code/src/main/resources/langs/en_US.yml b/Code/src/main/resources/langs/en_US.yml
index 564ccac..5412ac2 100644
--- a/Code/src/main/resources/langs/en_US.yml
+++ b/Code/src/main/resources/langs/en_US.yml
@@ -1,5 +1,5 @@
# Config Langs
-# Config = 1.2.22
+# Config = 1.2.23-DEV
# Prefix Value: %prefix%
# Lang: EN
# Here you can find the list of languages to which the plugin is already translated: