diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 8b39d3956..d3cddf856 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.data.cache.Multicache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedWorldManager; import com.volmit.iris.engine.object.IRare; @@ -45,26 +46,37 @@ import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.matter.MatterCavern; import com.volmit.iris.util.matter.MatterFluidBody; import com.volmit.iris.util.matter.MatterMarker; +import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.Chunks; +import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; +import com.volmit.iris.util.scheduling.jobs.QueueJob; +import io.papermc.lib.PaperLib; import lombok.Data; import lombok.EqualsAndHashCode; +import org.bukkit.Bukkit; import org.bukkit.Chunk; +import org.bukkit.Location; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.ItemStack; +import java.net.MalformedURLException; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -507,6 +519,56 @@ public class IrisWorldManager extends EngineAssignedWorldManager { charge = M.ms() + 3000; } + @Override + public void teleportAsync(PlayerTeleportEvent e) { + e.setCancelled(true); + warmupAreaAsync(e.getPlayer(), e.getTo(), () + -> J.s(() -> { + ignoreTP.set(true); + e.getPlayer().teleport(e.getTo(), e.getCause()); + ignoreTP.set(false); + })); + } + + private void warmupAreaAsync(Player player, Location to, Runnable r) { + J.a(() -> { + int viewDistance = 3; + KList> futures = new KList<>(); + for(int i = -viewDistance; i <= viewDistance; i++) + { + for(int j = -viewDistance; j <= viewDistance; j++) + { + int finalJ = j; + int finalI = i; + + if(to.getWorld().isChunkLoaded((to.getBlockX() >> 4) + i, (to.getBlockZ() >> 4) + j)) + { + futures.add(CompletableFuture.completedFuture(null)); + continue; + } + + futures.add(MultiBurst.burst.completeValue(() -> PaperLib.getChunkAtAsync(to.getWorld(), (to.getBlockX() >> 4) + finalI, (to.getBlockZ() >> 4) + finalJ, true).get())); + } + } + + new QueueJob>() { + @Override + public void execute(Future chunkFuture) { + try { + chunkFuture.get(); + } catch (InterruptedException | ExecutionException e) { + + } + } + + @Override + public String getName() { + return "Loading Chunks"; + } + }.queue(futures).execute(new VolmitSender(player), true, r); + }); + } + public Map> getSpawnersFromMarkers(Chunk c) { Map> p = new KMap<>(); Set b = new KSet<>(); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java index 07cf3bd08..7b92a95c5 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java @@ -24,6 +24,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.plugin.VolmitSender; +import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Sound; @@ -31,14 +32,18 @@ import org.bukkit.entity.EnderSignal; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.event.world.WorldUnloadEvent; +import java.util.concurrent.atomic.AtomicBoolean; + public abstract class EngineAssignedWorldManager extends EngineAssignedComponent implements EngineWorldManager, Listener { private final int taskId; @@ -62,6 +67,34 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent } } + protected AtomicBoolean ignoreTP = new AtomicBoolean(false); + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void on(PlayerTeleportEvent e) { + if(ignoreTP.get()) + { + return; + } + + if(!PaperLib.isPaper() || e.getTo() == null) + { + return; + } + + try + { + if(e.getTo().getWorld().equals(getTarget().getWorld().realWorld())) + { + getEngine().getWorldManager().teleportAsync(e); + } + } + + catch(Throwable ex) + { + + } + } + @EventHandler public void on(WorldSaveEvent e) { if (e.getWorld().equals(getTarget().getWorld().realWorld())) { diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java index e80c2ab53..48f524aa7 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine.framework; import org.bukkit.Chunk; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.player.PlayerTeleportEvent; @SuppressWarnings("EmptyMethod") public interface EngineWorldManager { @@ -45,4 +46,6 @@ public interface EngineWorldManager { void onChunkLoad(Chunk e, boolean generated); void chargeEnergy(); + + void teleportAsync(PlayerTeleportEvent e); } diff --git a/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java b/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java index 9ea3b02eb..156328bf8 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java +++ b/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java @@ -55,7 +55,12 @@ public interface Job { }); } + default void execute(VolmitSender sender, Runnable whenComplete) { + execute(sender, false, whenComplete); + } + + default void execute(VolmitSender sender, boolean silentMsg, Runnable whenComplete) { PrecisionStopwatch p = PrecisionStopwatch.start(); CompletableFuture f = J.afut(this::execute); int c = J.ar(() -> { @@ -67,7 +72,10 @@ public interface Job { }, sender.isPlayer() ? 0 : 20); f.whenComplete((fs, ff) -> { J.car(c); - sender.sendMessage(C.AQUA + "Completed " + getName() + " in " + Form.duration(p.getMilliseconds(), 1)); + if(!silentMsg) + { + sender.sendMessage(C.AQUA + "Completed " + getName() + " in " + Form.duration(p.getMilliseconds(), 1)); + } whenComplete.run(); }); }