From 431f002521f9becfb1c09ccef49e93f004f9f711 Mon Sep 17 00:00:00 2001
From: Martin <Martin.Olischlaeger@icloud.com>
Date: Thu, 27 Apr 2023 21:37:05 +0200
Subject: [PATCH] various fixes, better worldhandling

---
 .../eu/mhsl/craftattack/worldmuseum/Main.java | 18 +++---
 .../craftattack/worldmuseum/NewPlayer.java    | 56 +++++++++++++++++++
 .../{util => items}/CompassManager.java       |  3 +-
 .../listener/InventoryClickListener.java      | 16 ++++--
 ...sUseListener.java => ItemUseListener.java} | 10 +++-
 .../listener/MovementListener.java            | 14 +++++
 .../worldmuseum/util/ChangeWorld.java         | 31 +++++-----
 .../worldmuseum/util/ChunkLoadUtil.java       | 24 ++++++++
 8 files changed, 138 insertions(+), 34 deletions(-)
 create mode 100644 src/main/java/eu/mhsl/craftattack/worldmuseum/NewPlayer.java
 rename src/main/java/eu/mhsl/craftattack/worldmuseum/{util => items}/CompassManager.java (95%)
 rename src/main/java/eu/mhsl/craftattack/worldmuseum/listener/{CompassUseListener.java => ItemUseListener.java} (60%)
 create mode 100644 src/main/java/eu/mhsl/craftattack/worldmuseum/listener/MovementListener.java
 create mode 100644 src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChunkLoadUtil.java

diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/Main.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/Main.java
index 855489e..9e17391 100755
--- a/src/main/java/eu/mhsl/craftattack/worldmuseum/Main.java
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/Main.java
@@ -8,17 +8,16 @@ import eu.mhsl.craftattack.worldmuseum.skins.SkinCache;
 import eu.mhsl.craftattack.worldmuseum.util.Config;
 import eu.mhsl.craftattack.worldmuseum.worlds.World;
 import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
-import eu.mhsl.craftattack.worldmuseum.util.CompassManager;
+import eu.mhsl.craftattack.worldmuseum.items.CompassManager;
 import net.minestom.server.MinecraftServer;
 import net.minestom.server.entity.GameMode;
-import net.minestom.server.entity.Player;
-import net.minestom.server.entity.PlayerSkin;
 import net.minestom.server.event.GlobalEventHandler;
 import net.minestom.server.event.inventory.InventoryPreClickEvent;
 import net.minestom.server.event.player.*;
-import net.minestom.server.instance.InstanceManager;
 import net.minestom.server.timer.TaskSchedule;
 
+import java.time.Duration;
+
 public class Main {
     static int PORT = 25565;
     static String IP = "0.0.0.0";
@@ -31,6 +30,7 @@ public class Main {
 
         //temp
         MinecraftServer.getSchedulerManager().scheduleTask(new TablistUpdateTask(), TaskSchedule.tick(20), TaskSchedule.tick(20));
+        MinecraftServer.getConnectionManager().setPlayerProvider(NewPlayer::new);
 
         //load eu.mhsl.craftattack.worldmuseum.worlds / configExample file
         WorldManager worldManager = WorldManager.getInstance();
@@ -41,7 +41,7 @@ public class Main {
         config.loadConfig();
         World startworld = config.getStart_world();
 
-        //CompassManager
+        //CompassManager & GamemodeChanger
         CompassManager compassManager = CompassManager.getInstance();
         compassManager.loadCommpassManager();
 
@@ -49,11 +49,12 @@ public class Main {
         GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
 
         //listeners
-        globalEventHandler.addListener(PlayerUseItemEvent.class, new CompassUseListener());
+        globalEventHandler.addListener(PlayerUseItemEvent.class, new ItemUseListener());
         globalEventHandler.addListener(PlayerChunkUnloadEvent.class, new ChunkUnloading());
         globalEventHandler.addListener(InventoryPreClickEvent.class, new InventoryClickListener());
         globalEventHandler.addListener(PlayerBlockBreakEvent.class, new BlockBreakListener());
         globalEventHandler.addListener(PlayerBlockPlaceEvent.class, new BlockPlaceListener());
+        globalEventHandler.addListener(PlayerMoveEvent.class, new MovementListener());
 
         //commands
         MinecraftServer.getCommandManager().register(new TeleportCommand());
@@ -61,10 +62,13 @@ public class Main {
         MinecraftServer.getCommandManager().register(new GamemodeCommand());
 
         globalEventHandler.addListener(PlayerLoginEvent.class, event -> {
-            final Player player = event.getPlayer();
+            final NewPlayer player = (NewPlayer) event.getPlayer();
+            player.setSyncCooldown(Duration.ofSeconds(3));
             SkinCache.setSkin(player);
             event.setSpawningInstance(startworld);
 
+            player.setPermissionLevel(4);
+
             player.setRespawnPoint(startworld.getSpawn());
             player.setGameMode(GameMode.CREATIVE);
             player.getInventory().setItemStack(0, compassManager.getCompass());
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/NewPlayer.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/NewPlayer.java
new file mode 100644
index 0000000..d0cb386
--- /dev/null
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/NewPlayer.java
@@ -0,0 +1,56 @@
+package eu.mhsl.craftattack.worldmuseum;
+
+import eu.mhsl.craftattack.worldmuseum.worlds.World;
+import net.minestom.server.coordinate.Point;
+import net.minestom.server.coordinate.Pos;
+import net.minestom.server.entity.Player;
+import net.minestom.server.network.player.PlayerConnection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.time.Duration;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+
+public class NewPlayer extends Player {
+    private boolean allowMovemenrt = true;
+    private long lastCompassUsage = System.currentTimeMillis();
+
+    public NewPlayer(@NotNull UUID uuid, @NotNull String username, @NotNull PlayerConnection playerConnection) {
+        super(uuid, username, playerConnection);
+
+    }
+    public void setSyncCooldown(@Nullable Duration cooldown) {
+        this.setCustomSynchronizationCooldown(cooldown);
+    }
+
+    public boolean isAllowMovement() {
+        return allowMovemenrt;
+    }
+    public void update_lastCompassUsage() {
+        lastCompassUsage = System.currentTimeMillis();
+    }
+    public boolean isAllowCompassUsage() {
+        long UsageDifference = System.currentTimeMillis() - lastCompassUsage;
+        System.out.println(UsageDifference);
+        long DIFFERENCE = 10000; //in Milisec
+        if (UsageDifference >= DIFFERENCE) return true;
+        return false;
+    }
+
+    public void setAllowMovement(boolean allowMovemenrt) {
+        this.allowMovemenrt = allowMovemenrt;
+    }
+
+
+
+    public void newTeleport(Point point) {
+        this.allowMovemenrt = false;
+        World world =  (World) this.getInstance();
+        CompletableFuture.runAsync(
+                () -> world.loadOptionalChunk(point)
+                .thenRun(() -> this.teleport(new Pos(point))));
+
+
+    }
+}
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/util/CompassManager.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/items/CompassManager.java
similarity index 95%
rename from src/main/java/eu/mhsl/craftattack/worldmuseum/util/CompassManager.java
rename to src/main/java/eu/mhsl/craftattack/worldmuseum/items/CompassManager.java
index dcf7a17..79701ca 100644
--- a/src/main/java/eu/mhsl/craftattack/worldmuseum/util/CompassManager.java
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/items/CompassManager.java
@@ -1,4 +1,4 @@
-package eu.mhsl.craftattack.worldmuseum.util;
+package eu.mhsl.craftattack.worldmuseum.items;
 
 import eu.mhsl.craftattack.worldmuseum.worlds.World;
 import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
@@ -9,7 +9,6 @@ import net.minestom.server.item.ItemStack;
 import net.minestom.server.item.Material;
 public class CompassManager {
     static CompassManager instance;
-
     ItemStack compass;
     Inventory inventory;
     public static CompassManager getInstance() {
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/InventoryClickListener.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/InventoryClickListener.java
index 2184030..16b8226 100644
--- a/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/InventoryClickListener.java
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/InventoryClickListener.java
@@ -1,31 +1,35 @@
 package eu.mhsl.craftattack.worldmuseum.listener;
 
+import eu.mhsl.craftattack.worldmuseum.NewPlayer;
 import eu.mhsl.craftattack.worldmuseum.util.ChangeWorld;
 import eu.mhsl.craftattack.worldmuseum.worlds.World;
 import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
 import net.minestom.server.entity.Player;
 import net.minestom.server.event.inventory.InventoryPreClickEvent;
+import net.minestom.server.thread.MinestomThread;
+
 import java.util.Objects;
 import java.util.function.Consumer;
 
 public class InventoryClickListener implements Consumer<InventoryPreClickEvent> {
     @Override
     public void accept(InventoryPreClickEvent inventoryPreClickEvent) {
-        Player p = inventoryPreClickEvent.getPlayer();
-        inventoryPreClickEvent.setCancelled(true);
+        NewPlayer p = (NewPlayer) inventoryPreClickEvent.getPlayer();
         WorldManager worldManager = WorldManager.getInstance();
+
         for (World w : worldManager.getWorlds()) {
             if (!w.getItem().equals(inventoryPreClickEvent.getClickedItem())) continue;
             if (Objects.equals(p.getInstance(), w)) {
                 p.closeInventory();
                 p.teleport(w.getSpawn());
-                return;
             } else {
                 p.closeInventory();
-                ChangeWorld.change_world(p, w);
-
-                return;
+                Thread thread = new ChangeWorld(p, w);
+                thread.run();
             }
         }
+        inventoryPreClickEvent.setCancelled(true);
     }
+
+
 }
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/CompassUseListener.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/ItemUseListener.java
similarity index 60%
rename from src/main/java/eu/mhsl/craftattack/worldmuseum/listener/CompassUseListener.java
rename to src/main/java/eu/mhsl/craftattack/worldmuseum/listener/ItemUseListener.java
index 377c370..56c7071 100755
--- a/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/CompassUseListener.java
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/ItemUseListener.java
@@ -1,20 +1,24 @@
 package eu.mhsl.craftattack.worldmuseum.listener;
 
-import eu.mhsl.craftattack.worldmuseum.util.CompassManager;
+import eu.mhsl.craftattack.worldmuseum.NewPlayer;
+import eu.mhsl.craftattack.worldmuseum.items.CompassManager;
 import net.minestom.server.entity.Player;
 import net.minestom.server.event.player.PlayerUseItemEvent;
 import net.minestom.server.item.ItemStack;
 import java.util.function.Consumer;
 
-public class CompassUseListener implements Consumer<PlayerUseItemEvent> {
+public class ItemUseListener implements Consumer<PlayerUseItemEvent> {
 
     @Override
     public void accept(PlayerUseItemEvent playerUseItemEvent) {
-        Player p = playerUseItemEvent.getPlayer();
+        NewPlayer p = (NewPlayer) playerUseItemEvent.getPlayer();
         ItemStack usedItem = playerUseItemEvent.getItemStack();
         CompassManager compassManager = CompassManager.getInstance();
 
         if (!usedItem.equals(compassManager.getCompass())) return;
+        if (!p.isAllowCompassUsage()) return;
+        p.update_lastCompassUsage();
         p.openInventory(compassManager.getInventory());
+        playerUseItemEvent.setCancelled(true);
     }
 }
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/MovementListener.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/MovementListener.java
new file mode 100644
index 0000000..24efc49
--- /dev/null
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/listener/MovementListener.java
@@ -0,0 +1,14 @@
+package eu.mhsl.craftattack.worldmuseum.listener;
+
+import eu.mhsl.craftattack.worldmuseum.NewPlayer;
+import net.minestom.server.event.player.PlayerMoveEvent;
+
+import java.util.function.Consumer;
+
+public class MovementListener implements Consumer<PlayerMoveEvent> {
+    @Override
+    public void accept(PlayerMoveEvent playerMoveEvent) {
+        NewPlayer player = (NewPlayer) playerMoveEvent.getPlayer();
+        if (!player.isAllowMovement()) playerMoveEvent.setCancelled(true);
+    }
+}
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChangeWorld.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChangeWorld.java
index a4c4641..5a90d60 100644
--- a/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChangeWorld.java
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChangeWorld.java
@@ -1,23 +1,22 @@
 package eu.mhsl.craftattack.worldmuseum.util;
 
+import eu.mhsl.craftattack.worldmuseum.NewPlayer;
 import eu.mhsl.craftattack.worldmuseum.worlds.World;
-import net.minestom.server.MinecraftServer;
-import net.minestom.server.entity.Player;
-import net.minestom.server.utils.chunk.ChunkUtils;
-import java.util.ArrayList;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Future;
+import net.minestom.server.potion.Potion;
+import net.minestom.server.potion.PotionEffect;
+import net.minestom.server.thread.MinestomThread;
 
-public class ChangeWorld {
-    public static void change_world(Player player, World targetWorld) {
-        ArrayList<Future> futures = new ArrayList<>();
-        ChunkUtils.forChunksInRange(targetWorld.getSpawn(), MinecraftServer.getChunkViewDistance(),(v1, v2) -> {
-            futures.add(targetWorld.loadChunk(v1, v2));
-        });
-        CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).thenRun(()-> {
-            player.setRespawnPoint(targetWorld.getSpawn());
-            player.setInstance(targetWorld);
-            player.teleport(targetWorld.getSpawn());
+public class ChangeWorld extends MinestomThread {
+    public ChangeWorld(NewPlayer player, World targetWorld) {
+        super("load_world_for_player");
+        player.setAllowMovement(false);
+        player.addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 0, 1000000));
+
+        player.setRespawnPoint(targetWorld.getSpawn());
+        player.setInstance(targetWorld, targetWorld.getSpawn()).thenRun(() -> {
+            player.setAllowMovement(true);
+            player.clearEffects();
+            player.update_lastCompassUsage();
         });
     }
 }
diff --git a/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChunkLoadUtil.java b/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChunkLoadUtil.java
new file mode 100644
index 0000000..a805925
--- /dev/null
+++ b/src/main/java/eu/mhsl/craftattack/worldmuseum/util/ChunkLoadUtil.java
@@ -0,0 +1,24 @@
+package eu.mhsl.craftattack.worldmuseum.util;
+
+import eu.mhsl.craftattack.worldmuseum.worlds.World;
+import net.minestom.server.MinecraftServer;
+import net.minestom.server.coordinate.Point;
+import net.minestom.server.instance.Chunk;
+import net.minestom.server.utils.chunk.ChunkUtils;
+
+import java.util.ArrayList;
+import java.util.stream.Stream;
+
+public class ChunkLoadUtil {
+
+    public static boolean areNearbyChunksLoaded(Point point, World world) {
+        ArrayList<Chunk> chunks = new ArrayList<>();
+
+        ChunkUtils.forChunksInRange(point, MinecraftServer.getChunkViewDistance(), (x , z) -> {
+            chunks.add(world.getChunk(x, z));
+        });
+//        Stream.of(new Conditional(point, world, () -> {world.getChunkAt(point).sendChunk();}))
+        return false;
+    }
+
+}