From cad679a8080a2b773855a216ac89ccc845b88236 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 2 Aug 2024 23:17:52 +0200 Subject: [PATCH] Fast pregen --- .../volmit/iris/core/gui/PregeneratorJob.java | 26 +++++++++ .../core/pregenerator/IrisPregenerator.java | 54 ++++++++++++++++--- .../core/pregenerator/PregenListener.java | 2 + .../methods/AsyncPregenMethod.java | 24 ++++----- .../com/volmit/iris/engine/IrisEngine.java | 9 ---- .../volmit/iris/engine/framework/Engine.java | 2 - 6 files changed, 85 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 6d3534971..7e83d29f0 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -237,6 +237,11 @@ public class PregeneratorJob implements PregenListener { draw(x, z, COLOR_GENERATING); } + @Override + public void onServerShutdown() { + + } + @Override public void onChunkGenerated(int x, int z) { if (engine != null) { @@ -251,6 +256,27 @@ public class PregeneratorJob implements PregenListener { public void onRegionGenerated(int x, int z) { shouldGc(); rgc++; + + // Each region is 32x32 chunks + for (int chunkOffsetX = 0; chunkOffsetX < 32; chunkOffsetX++) { + for (int chunkOffsetZ = 0; chunkOffsetZ < 32; chunkOffsetZ++) { + // Calculate actual chunk coordinates + int chunkX = (x << 5) + chunkOffsetX; + int chunkZ = (z << 5) + chunkOffsetZ; + + if (engine != null) { + // Calculate the center block of the chunk + int centerBlockX = (chunkX << 4) + 8; + int centerBlockZ = (chunkZ << 4) + 8; + + // Draw the chunk + draw(chunkX, chunkZ, engine.draw(centerBlockX, centerBlockZ)); + } else { + // If engine is null, use the default color + draw(chunkX, chunkZ, COLOR_GENERATED); + } + } + } } private void shouldGc() { diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index 5fd81a650..d0a941c2c 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -18,11 +18,9 @@ package com.volmit.iris.core.pregenerator; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.IHeadless; -import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.nms.v1X.NMSBinding1X; -import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; @@ -33,7 +31,6 @@ import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RollingSequence; -import com.volmit.iris.util.misc.E; import com.volmit.iris.util.nbt.mca.Chunk; import com.volmit.iris.util.nbt.mca.MCAFile; import com.volmit.iris.util.nbt.mca.MCAUtil; @@ -44,7 +41,11 @@ import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; import org.bukkit.World; -import java.io.File; +import java.io.*; +import java.lang.reflect.Type; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -54,6 +55,7 @@ import java.util.regex.Pattern; public class IrisPregenerator { + private final String saveFile = "regions.json"; private final PregenTask task; private final PregeneratorMethod generator; private final PregenListener listener; @@ -71,14 +73,14 @@ public class IrisPregenerator { private final AtomicLong startTime; private final ChronoLatch minuteLatch; private final AtomicReference currentGeneratorMethod; - private final KSet generatedRegions; + private Set generatedRegions; private final KSet retry; private final KSet net; private final ChronoLatch cl; private final ChronoLatch saveLatch = new ChronoLatch(30000); public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) { - generatedRegions = new KSet<>(); + generatedRegions = ConcurrentHashMap.newKeySet(); this.listener = listenify(listener); cl = new ChronoLatch(5000); this.shutdown = new AtomicBoolean(false); @@ -97,6 +99,7 @@ public class IrisPregenerator { generatedLast = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0); totalChunks = new AtomicInteger(0); + loadCompletedRegions(); IrisToolbelt.access(generator.getWorld()).getEngine().saveEngineData(); task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024)); startTime = new AtomicLong(M.ms()); @@ -183,6 +186,7 @@ public class IrisPregenerator { generator.close(); ticker.interrupt(); listener.onClose(); + saveCompletedRegions(); Mantle mantle = getMantle(); if (mantle != null) { mantle.trim(0, 0); @@ -239,6 +243,7 @@ public class IrisPregenerator { Position2 pos = new Position2(x, z); if (generatedRegions.contains(pos)) { + listener.onRegionGenerated(x,z); return; } @@ -281,6 +286,31 @@ public class IrisPregenerator { generator.supportsRegions(x, z, listener); } + public void saveCompletedRegions() { + Gson gson = new Gson(); + try (Writer writer = new FileWriter(generator.getWorld().getWorldFolder().getPath() + "/" + saveFile)) { + gson.toJson(new HashSet<>(generatedRegions), writer); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void loadCompletedRegions() { + Gson gson = new Gson(); + try (Reader reader = new FileReader(generator.getWorld().getWorldFolder().getPath() + "/" + saveFile)) { + Type setType = new TypeToken>(){}.getType(); + Set loadedSet = gson.fromJson(reader, setType); + if (loadedSet != null) { + generatedRegions.clear(); + generatedRegions.addAll(loadedSet); + } + } catch (FileNotFoundException e) { + // all fine + } catch (IOException e) { + e.printStackTrace(); + } + } + public void pause() { paused.set(true); } @@ -301,6 +331,11 @@ public class IrisPregenerator { listener.onChunkGenerating(x, z); } + @Override + public void onServerShutdown() { + + } + @Override public void onChunkGenerated(int x, int z) { listener.onChunkGenerated(x, z); @@ -309,6 +344,9 @@ public class IrisPregenerator { @Override public void onRegionGenerated(int x, int z) { + generatedRegions.add(new Position2(x, z)); + saveCompletedRegions(); + generated.addAndGet(1024); // todo. not like this. listener.onRegionGenerated(x, z); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java index fb3ab3952..e28323e1f 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java @@ -23,6 +23,8 @@ public interface PregenListener { void onChunkGenerating(int x, int z); + void onServerShutdown(); + void onChunkGenerated(int x, int z); void onRegionGenerated(int x, int z); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index afb327302..2e9cb166e 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -36,10 +36,8 @@ import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; @@ -47,6 +45,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { private final World world; private final Engine engine; private final MultiBurst burst; + private final KList> future; private final Map lastUse; @@ -85,15 +84,14 @@ public class AsyncPregenMethod implements PregeneratorMethod { private void completeChunk(int x, int z, PregenListener listener) { try { - if (!engine.exists(x,z)) { - future.add(PaperLib.getChunkAtAsync(world, x, z, true).thenApply((i) -> { - if (i == null) return 0; - lastUse.put(i, M.ms()); - listener.onChunkGenerated(x, z); - listener.onChunkCleaned(x, z); - return 0; - })); - } + future.add(PaperLib.getChunkAtAsync(world, x, z, true).thenApply((i) -> { + if (i == null) return 0; + lastUse.put(i, M.ms()); + listener.onChunkGenerated(x, z); + listener.onChunkCleaned(x, z); + return 0; + })); + } catch (Throwable e) { e.printStackTrace(); } diff --git a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java index 9a9239371..a4fbf3817 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -73,7 +73,6 @@ import java.util.concurrent.locks.ReentrantLock; @EqualsAndHashCode(exclude = "context") @ToString(exclude = "context") public class IrisEngine implements Engine { - private Set chunks = ConcurrentHashMap.newKeySet(); private final AtomicInteger bud; private final AtomicInteger buds; private final AtomicInteger generated; @@ -137,7 +136,6 @@ public class IrisEngine implements Engine { failing = false; closed = false; art = J.ar(this::tickRandomPlayer, 0); - chunks = getEngineData().getGeneratedChunks(); setupEngine(); Iris.debug("Engine Initialized " + getCacheID()); } @@ -288,7 +286,6 @@ public class IrisEngine implements Engine { File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + ".json"); f.getParentFile().mkdirs(); try { - getEngineData().addGeneratedChunk(chunks); IO.writeAll(f, new Gson().toJson(getEngineData())); Iris.debug("Saved Engine Data"); } catch (IOException e) { @@ -311,7 +308,6 @@ public class IrisEngine implements Engine { public void addGenerated(int x, int z) { try { File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + ".json"); - chunks.add(x + "," + z); if (generated.incrementAndGet() == 661) { J.a(() -> getData().savePrefetch(this)); } @@ -515,11 +511,6 @@ public class IrisEngine implements Engine { bud.incrementAndGet(); } - @Override - public boolean exists(int x, int z) { - return chunks.contains(x + "," + z); - } - @Override public IrisBiome getFocus() { if (getDimension().getFocus() == null || getDimension().getFocus().trim().isEmpty()) { diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index d8f33362b..3fda9ab4b 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -266,8 +266,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat void blockUpdatedMetric(); - boolean exists(int x, int z); - @ChunkCoordinates @Override default void updateChunk(Chunk c) {