|
@@ -0,0 +1,134 @@
|
|
|
+package de.linus122.playerworlds;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.function.Consumer;
|
|
|
+import net.minecraft.core.Position;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
+import org.bukkit.Bukkit;
|
|
|
+import org.bukkit.Location;
|
|
|
+import org.bukkit.Material;
|
|
|
+import org.bukkit.World;
|
|
|
+import org.bukkit.WorldCreator;
|
|
|
+import org.bukkit.World.Environment;
|
|
|
+import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
|
|
+import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity;
|
|
|
+import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
|
|
|
+import org.bukkit.event.Cancellable;
|
|
|
+import org.bukkit.event.EventHandler;
|
|
|
+import org.bukkit.event.Listener;
|
|
|
+import org.bukkit.event.entity.EntityPortalEvent;
|
|
|
+import org.bukkit.event.player.PlayerRespawnEvent;
|
|
|
+import org.bukkit.event.player.PlayerTeleportEvent;
|
|
|
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
|
|
+
|
|
|
+public class Listeners implements Listener {
|
|
|
+ private final Main main;
|
|
|
+
|
|
|
+ private final String SUFFIX_NETHER = "_nether";
|
|
|
+ private final String SUFFIX_END = "_the_end";
|
|
|
+
|
|
|
+ public Listeners(Main main) {
|
|
|
+ this.main = main;
|
|
|
+ }
|
|
|
+
|
|
|
+ @EventHandler
|
|
|
+ public void onEntityTeleport(EntityPortalEvent event) {
|
|
|
+ this.main.debug("EntityPortalEvent %s %s -> %s".formatted(event.getEntityType(), event.getFrom().getWorld().getName(), event.getTo().getWorld().getName()));
|
|
|
+
|
|
|
+ if (!event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
|
|
+ if (event.getFrom().getWorld().getEnvironment().equals(Environment.NETHER) ^ event.getTo().getWorld().getEnvironment().equals(Environment.NETHER)) {
|
|
|
+ this.onTeleport(event.getFrom(), event.getTo(), TeleportCause.NETHER_PORTAL, world -> {
|
|
|
+ CraftEntity craftEntity = (CraftEntity)event.getEntity();
|
|
|
+ craftEntity.getHandle().teleportTo(((CraftWorld) world).getHandle(), (Position) null);
|
|
|
+ this.main.debug("Entity teleported %s %s -> %s".formatted(event.getEntityType(), event.getFrom().getWorld().getName(), world.getName()));
|
|
|
+ }, event);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (event.getFrom().getWorld().getEnvironment().equals(Environment.THE_END) ^ event.getTo().getWorld().getEnvironment().equals(Environment.THE_END)) {
|
|
|
+ this.onTeleport(event.getFrom(), event.getTo(), TeleportCause.END_PORTAL, world -> {
|
|
|
+ CraftEntity craftEntity = (CraftEntity)event.getEntity();
|
|
|
+ craftEntity.getHandle().teleportTo(((CraftWorld) world).getHandle(), (Position) null);
|
|
|
+ this.main.debug("Entity teleported %s %s -> %s".formatted(event.getEntityType(), event.getFrom().getWorld().getName(), world.getName()));
|
|
|
+ }, event);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @EventHandler
|
|
|
+ public void onRespawn(PlayerRespawnEvent event) {
|
|
|
+ if (event.getPlayer().getLocation().getBlock().getType().equals(Material.END_PORTAL) && event.getPlayer().getLocation().getWorld().getEnvironment() == Environment.THE_END) {
|
|
|
+ String newName = event.getPlayer().getWorld().getName().replaceFirst("_the_end", "");
|
|
|
+ World world = Bukkit.getWorld(newName);
|
|
|
+ Location respawnLocation = world.getSpawnLocation();
|
|
|
+ if (event.getPlayer().getBedSpawnLocation() != null) {
|
|
|
+ respawnLocation = event.getPlayer().getBedSpawnLocation();
|
|
|
+ }
|
|
|
+
|
|
|
+ event.setRespawnLocation(respawnLocation);
|
|
|
+ this.main.debug("Respawn from end %s %s -> %s".formatted(event.getPlayer().getName(), event.getPlayer().getLocation().getWorld().getName(), respawnLocation));
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @EventHandler
|
|
|
+ public void onTeleport(PlayerTeleportEvent event) {
|
|
|
+ this.main.debug("PlayerTeleportEvent %s %s -> %s".formatted(event.getPlayer().getName(), event.getFrom().getWorld().getName(), event.getTo().getWorld().getName()));
|
|
|
+
|
|
|
+ this.onTeleport(event.getFrom(), event.getTo(), event.getCause(), world -> {
|
|
|
+ CraftPlayer craftPlayer = (CraftPlayer) event.getPlayer();
|
|
|
+ craftPlayer.getHandle().changeDimension(((CraftWorld)world).getHandle(), event.getCause());
|
|
|
+ this.main.debug("Player teleported %s -> %s".formatted(event.getFrom().getWorld().getName(), world.getName()));
|
|
|
+ }, event);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void onTeleport(Location from, Location to, TeleportCause cause, Consumer<World> action, Cancellable event) {
|
|
|
+ Environment fromEnv = from.getWorld().getEnvironment();
|
|
|
+ Environment toEnv = to.getWorld().getEnvironment();
|
|
|
+ if (to.getWorld().getName().startsWith("world")) {
|
|
|
+ if (cause.equals(TeleportCause.NETHER_PORTAL) || cause.equals(TeleportCause.END_PORTAL) || cause.equals(TeleportCause.END_GATEWAY)) {
|
|
|
+ String newWorldname = null;
|
|
|
+ if (fromEnv.equals(Environment.NORMAL) && toEnv.equals(Environment.NETHER)) {
|
|
|
+ newWorldname = from.getWorld().getName() + SUFFIX_NETHER;
|
|
|
+ } else if (fromEnv.equals(Environment.NETHER) && toEnv.equals(Environment.NORMAL)) {
|
|
|
+ newWorldname = from.getWorld().getName().replaceFirst(SUFFIX_NETHER, "");
|
|
|
+ } else if (fromEnv.equals(Environment.NORMAL) && toEnv.equals(Environment.THE_END)) {
|
|
|
+ newWorldname = from.getWorld().getName() + SUFFIX_END;
|
|
|
+ } else if (fromEnv.equals(Environment.THE_END) && toEnv.equals(Environment.NORMAL)) {
|
|
|
+ newWorldname = from.getWorld().getName().replaceFirst(SUFFIX_END, "");
|
|
|
+ }
|
|
|
+
|
|
|
+ World toNew = Bukkit.getWorld(newWorldname);
|
|
|
+ if (toNew == null && !toEnv.equals(Environment.NORMAL)) {
|
|
|
+ try {
|
|
|
+ this.copyNewWorld(newWorldname, toEnv);
|
|
|
+ } catch (IOException exception) {
|
|
|
+ exception.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ WorldCreator wc = new WorldCreator(newWorldname);
|
|
|
+ wc.environment(toEnv);
|
|
|
+ wc.createWorld();
|
|
|
+ toNew = Bukkit.getWorld(newWorldname);
|
|
|
+ }
|
|
|
+
|
|
|
+ event.setCancelled(true);
|
|
|
+ action.accept(toNew);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void copyNewWorld(String worldName, Environment env) throws IOException {
|
|
|
+ File newWorldFolder = new File(worldName);
|
|
|
+ if (!newWorldFolder.exists()) {
|
|
|
+ String originalWorldFolderName = this.main.getConfig().getString(env.toString().toLowerCase());
|
|
|
+ this.main.getLogger().info(originalWorldFolderName);
|
|
|
+
|
|
|
+ File sourceWorldFolder = new File(this.main.getDataFolder(), originalWorldFolderName);
|
|
|
+ FileUtils.copyDirectory(sourceWorldFolder, newWorldFolder);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|