Fixes & Fixes

This commit is contained in:
Daniel Mills 2020-12-04 05:07:44 -05:00
parent f3eb1bb45e
commit 4902e5b9bb
17 changed files with 402 additions and 85 deletions

View File

@ -48,6 +48,9 @@ public class IrisSettings
@DontObfuscate
public boolean ignoreWorldEdit = false;
@DontObfuscate
public boolean useGleamPregenerator = false;
@DontObfuscate
public boolean disableNMS = false;

View File

@ -4,6 +4,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.scaffold.engine.*;
import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.ChronoLatch;
import com.volmit.iris.util.J;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.RNG;
@ -17,6 +18,7 @@ import org.bukkit.generator.BlockPopulator;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class IrisEngine extends BlockPopulator implements Engine
{
@ -48,15 +50,20 @@ public class IrisEngine extends BlockPopulator implements Engine
@Setter
@Getter
private volatile int minHeight;
private int permits;
private boolean failing;
private ChronoLatch cl = new ChronoLatch(10000);
private boolean closed;
private int cacheId;
private Semaphore s;
private int art;
public IrisEngine(EngineTarget target, EngineCompound compound, int index)
{
Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)");
metrics = new EngineMetrics(32);
permits = 1000;
this.s = new Semaphore(permits);
this.target = target;
this.framework = new IrisEngineFramework(this);
worldManager = new IrisWorldManager(this);
@ -79,6 +86,11 @@ public class IrisEngine extends BlockPopulator implements Engine
getFramework().close();
}
@Override
public int getCurrentlyGenerating() {
return permits - s.availablePermits();
}
@Override
public boolean isClosed() {
return closed;
@ -98,31 +110,38 @@ public class IrisEngine extends BlockPopulator implements Engine
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<BlockData> postblocks, Hunk<Biome> vbiomes) {
try
{
s.acquire(1);
PrecisionStopwatch p = PrecisionStopwatch.start();
Hunk<Biome> biomes = vbiomes;
Hunk<BlockData> blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t));
Hunk<BlockData> pblocks = postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t));
Hunk<BlockData> fringe = Hunk.fringe(blocks, pblocks);
MultiBurst.burst.burst(
() -> getFramework().getEngineParallax().generateParallaxArea(x, z),
() -> getFramework().getBiomeActuator().actuate(x, z, biomes),
() -> getFramework().getTerrainActuator().actuate(x, z, blocks)
);
MultiBurst.burst.burst(
() -> getFramework().getCaveModifier().modify(x, z, blocks),
() -> getFramework().getRavineModifier().modify(x, z, blocks)
);
MultiBurst.burst.burst(
() -> getFramework().getDepositModifier().modify(x, z, blocks),
() -> getFramework().getPostModifier().modify(x, z, blocks),
() -> getFramework().getDecorantActuator().actuate(x, z, fringe)
);
getFramework().getEngineParallax().generateParallaxArea(x, z);
getFramework().getBiomeActuator().actuate(x, z, biomes);
getFramework().getTerrainActuator().actuate(x, z, blocks);
getFramework().getCaveModifier().modify(x, z, blocks);
getFramework().getRavineModifier().modify(x, z, blocks);
getFramework().getDepositModifier().modify(x, z, blocks);
getFramework().getPostModifier().modify(x, z, blocks);
getFramework().getDecorantActuator().actuate(x, z, fringe);
getFramework().getEngineParallax().insertParallax(x, z, fringe);
getFramework().recycle();
getMetrics().getTotal().put(p.getMilliseconds());
s.release(1);
if(cl.flip())
{
MultiBurst.burst.lazy(() -> {
try {
s.acquire(permits);
getFramework().recycle();
s.release(permits);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
catch(Throwable e)
{
fail("Failed to generate " + x + ", " + z, e);

View File

@ -260,6 +260,17 @@ public class IrisEngineCompound implements EngineCompound {
wallClock.put(p.getMilliseconds());
}
@Override
public int getCurrentlyGeneratingEngines() {
int v = 0;
for(Engine i : engines)
{
v+= i.getCurrentlyGenerating();
}
return v;
}
@Override
public int getSize() {
return engines.length;

View File

@ -10,6 +10,8 @@ import com.volmit.iris.Iris;
import com.volmit.iris.nms.INMS;
import com.volmit.iris.scaffold.cache.Cache;
import com.volmit.iris.scaffold.engine.EngineCompositeGenerator;
import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.engine.IrisAccessProvider;
import com.volmit.iris.util.*;
import net.minecraft.server.v1_16_R2.BlockPosition;
import net.minecraft.server.v1_16_R2.HeightMap;
@ -26,7 +28,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
public final class NMSChunkGenerator_16_2 extends ChunkGenerator {
public final class NMSChunkGenerator_16_2 extends ChunkGenerator implements IrisAccessProvider {
private static final IBlockData k;
private final O<WorldServer> ws;
protected final IBlockData f;
@ -595,4 +597,9 @@ public final class NMSChunkGenerator_16_2 extends ChunkGenerator {
++i1;
}
}
@Override
public IrisAccess getAccess() {
return gen;
}
}

View File

@ -10,6 +10,8 @@ import com.volmit.iris.Iris;
import com.volmit.iris.nms.INMS;
import com.volmit.iris.scaffold.cache.Cache;
import com.volmit.iris.scaffold.engine.EngineCompositeGenerator;
import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.engine.IrisAccessProvider;
import com.volmit.iris.util.*;
import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.HeightMap;
@ -26,7 +28,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
public final class NMSChunkGenerator16_3 extends ChunkGenerator {
public final class NMSChunkGenerator16_3 extends ChunkGenerator implements IrisAccessProvider {
private static final IBlockData k;
private final O<WorldServer> ws;
protected final IBlockData f;
@ -595,4 +597,9 @@ public final class NMSChunkGenerator16_3 extends ChunkGenerator {
++i1;
}
}
@Override
public IrisAccess getAccess() {
return gen;
}
}

View File

@ -2,6 +2,7 @@ package com.volmit.iris.scaffold;
import com.volmit.iris.Iris;
import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.engine.IrisAccessProvider;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.MortarSender;
import org.bukkit.Bukkit;
@ -24,7 +25,7 @@ public class IrisWorlds
return true;
}
return world.getGenerator() instanceof IrisAccess;
return world.getGenerator() instanceof IrisAccess || world.getGenerator() instanceof IrisAccessProvider;
}
public static IrisAccess access(World world)
@ -36,7 +37,7 @@ public class IrisWorlds
return provisioned.get(world.getUID().toString());
}
return ((IrisAccess) world.getGenerator());
return world.getGenerator() instanceof IrisAccessProvider ? (((IrisAccessProvider)world.getGenerator()).getAccess()) : ((IrisAccess) world.getGenerator());
}
return null;

View File

@ -26,6 +26,8 @@ import java.util.Arrays;
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable {
public void close();
public int getCurrentlyGenerating();
public boolean isClosed();
public EngineWorldManager getWorldManager();
@ -145,8 +147,11 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
if(B.isUpdatable(data))
{
getParallax().updateBlock(x,y,z);
getParallax().getMetaRW(x>>4, z>>4).setUpdates(true);
synchronized (getParallax())
{
getParallax().updateBlock(x,y,z);
getParallax().getMetaRW(x>>4, z>>4).setUpdates(true);
}
}
}

View File

@ -10,6 +10,7 @@ import com.volmit.iris.scaffold.IrisWorlds;
import com.volmit.iris.scaffold.cache.Cache;
import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.util.*;
import io.papermc.lib.PaperLib;
import lombok.Getter;
import org.bukkit.*;
import org.bukkit.block.Biome;
@ -36,6 +37,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
private long mst = 0;
private int generated = 0;
private int lgenerated = 0;
private final KMap<Long, PregeneratedData> chunkCache;
private ChronoLatch hotloadcd;
@Getter
private double generatedPerSecond = 0;
@ -48,6 +50,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
public EngineCompositeGenerator(String hint, boolean production) {
super();
chunkCache = new KMap<>();
hotloadcd = new ChronoLatch(3500);
mst = M.ms();
this.production = production;
@ -305,16 +308,70 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
return tc.getRaw();
}
public Chunk generatePaper(World world, int x, int z)
{
precache(world, x, z);
Chunk c = PaperLib.getChunkAtAsync(world, x, z, true).join();
chunkCache.remove(Cache.key(x, z));
return c;
}
public void precache(World world, int x, int z)
{
synchronized (this)
{
initialize(world);
}
synchronized (chunkCache)
{
if(chunkCache.containsKey(Cache.key(x, z)))
{
return;
}
}
PregeneratedData data = new PregeneratedData(getComposite().getHeight()-1);
compound.generate(x * 16, z * 16, data.getBlocks(), data.getPost(), data.getBiomes());
synchronized (chunkCache)
{
chunkCache.put(Cache.key(x, z), data);
}
}
@Override
public int getPrecacheSize() {
return chunkCache.size();
}
public int getCachedChunks()
{
return chunkCache.size();
}
public Runnable generateChunkRawData(World world, int x, int z, TerrainChunk tc)
{
initialize(world);
synchronized (chunkCache)
{
long g = Cache.key(x, z);
if(chunkCache.containsKey(g))
{
generated++;
return chunkCache.remove(g).inject(tc);
}
}
Hunk<BlockData> blocks = Hunk.view((ChunkData) tc);
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
Hunk<BlockData> post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth());
AtomicBoolean postMod = new AtomicBoolean(false);
Hunk<BlockData> trk = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth());
Hunk<BlockData> post = trk.trackWrite(postMod);
compound.generate(x * 16, z * 16, blocks, post, biomes);
generated++;
return () -> blocks.insertSoftly(0,0,0,post, (b) -> b == null || B.isAirOrFluid(b));
return postMod.get() ? () -> blocks.insertSoftly(0,0,0, post, (b) -> b == null || B.isAirOrFluid(b)) : () -> {};
}
@Override
@ -454,12 +511,6 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
@Override
public void regenerate(int x, int z) {
if (true)
{
return;
}
Chunk chunk = getComposite().getWorld().getChunkAt(x, z);
generateChunkRawData(getComposite().getWorld(), x, z, new TerrainChunk() {
@Override
public void setRaw(ChunkData data) {
@ -557,6 +608,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
Iris.edit.flushNow();
for (BlockPopulator i : populators) {
Chunk chunk = getComposite().getWorld().getChunkAt(x, z);
i.populate(compound.getWorld(), new RNG(Cache.key(x, z)), chunk);
}
}

View File

@ -23,10 +23,17 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider
public World getWorld();
public int getCurrentlyGeneratingEngines();
public void printMetrics(CommandSender sender);
public int getSize();
public default int getHeight()
{
return 256;
}
public Engine getEngine(int index);
public MultiBurst getBurster();

View File

@ -1,14 +1,12 @@
package com.volmit.iris.scaffold.engine;
import com.volmit.iris.generator.IrisComplex;
import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.scaffold.data.DataProvider;
import com.volmit.iris.util.M;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.generator.IrisComplex;
import com.volmit.iris.scaffold.data.DataProvider;
public interface EngineFramework extends DataProvider
{
public Engine getEngine();
@ -25,10 +23,12 @@ public interface EngineFramework extends DataProvider
{
if(M.r(0.1))
{
MultiBurst.burst.lazy(() -> {
synchronized (getEngine().getParallax())
{
getEngine().getParallax().cleanup();
getData().getObjectLoader().clean();
});
}
getData().getObjectLoader().clean();
}
}

View File

@ -4,7 +4,9 @@ import com.volmit.iris.manager.IrisDataManager;
import com.volmit.iris.object.*;
import com.volmit.iris.scaffold.data.DataProvider;
import com.volmit.iris.util.*;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import java.util.concurrent.atomic.AtomicBoolean;
@ -388,4 +390,10 @@ public interface IrisAccess extends Hotloadable, DataProvider {
}
public void clearRegeneratedLists(int x, int z);
void precache(World world, int x, int z);
int getPrecacheSize();
Chunk generatePaper(World world, int cx, int cz);
}

View File

@ -0,0 +1,5 @@
package com.volmit.iris.scaffold.engine;
public interface IrisAccessProvider {
public IrisAccess getAccess();
}

View File

@ -0,0 +1,50 @@
package com.volmit.iris.scaffold.engine;
import com.volmit.iris.scaffold.hunk.Hunk;
import com.volmit.iris.util.B;
import com.volmit.iris.util.TerrainChunk;
import lombok.Data;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator;
import java.util.concurrent.atomic.AtomicBoolean;
@Data
public class PregeneratedData {
private final Hunk<BlockData> blocks;
private final Hunk<BlockData> post;
private final Hunk<Biome> biomes;
private final AtomicBoolean postMod;
public PregeneratedData(int height)
{
postMod = new AtomicBoolean(false);
blocks = Hunk.newAtomicHunk(16, height, 16);
biomes = Hunk.newAtomicHunk(16, height, 16);
Hunk<BlockData> p = Hunk.newMappedHunkSynced(16, height, 16);
post = p.trackWrite(postMod);
}
public Runnable inject(TerrainChunk tc) {
blocks.iterateSync((x, y, z, b) -> {
if(b != null)
{
tc.setBlock(x, y, z, b);
}
Biome bf = biomes.get(x,y,z);
if(bf != null)
{
tc.setBiome(x,y,z,bf);
}
});
if(postMod.get())
{
return () -> Hunk.view((ChunkGenerator.ChunkData) tc).insertSoftly(0,0,0, post, (b) -> b == null || B.isAirOrFluid(b));
}
return () -> {};
}
}

View File

@ -15,6 +15,7 @@ import org.bukkit.generator.ChunkGenerator.ChunkData;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Predicate;
@ -82,6 +83,11 @@ public interface Hunk<T>
return new SynchronizedHunkView<>(this);
}
default Hunk<T> trackWrite(AtomicBoolean b)
{
return new WriteTrackHunk<T>(this, b);
}
public static <T> Hunk<T> newArrayHunk(int w, int h, int d)
{
return new ArrayHunk<>(w, h, d);
@ -1129,7 +1135,7 @@ public interface Hunk<T>
*/
default T getClosest(int x, int y, int z)
{
return getRaw(x >= getWidth() ? getWidth() - 1 : x, y >= getHeight() ? getHeight() - 1 : y, z >= getDepth() ? getDepth() - 1 : z);
return getRaw(x >= getWidth() ? getWidth() - 1 : x < 0 ? 0 : x, y >= getHeight() ? getHeight() - 1 : y < 0 ? 0 : y, z >= getDepth() ? getDepth() - 1 : z < 0 ? 0 : z);
}
default void fill(T t)

View File

@ -0,0 +1,57 @@
package com.volmit.iris.scaffold.hunk.view;
import com.volmit.iris.scaffold.hunk.Hunk;
import java.util.concurrent.atomic.AtomicBoolean;
public class WriteTrackHunk<T> implements Hunk<T> {
private final Hunk<T> src;
private final AtomicBoolean b;
public WriteTrackHunk(Hunk<T> src, AtomicBoolean b)
{
this.src = src;
this.b = b;
}
@Override
public void setRaw(int x, int y, int z, T t)
{
if(!b.get())
{
b.set(true);
}
src.setRaw(x,y,z,t);
}
@Override
public T getRaw(int x, int y, int z)
{
return src.getRaw(x, y, z);
}
@Override
public int getWidth()
{
return src.getWidth();
}
@Override
public int getHeight()
{
return src.getHeight();
}
@Override
public int getDepth()
{
return src.getDepth();
}
@Override
public Hunk<T> getSource()
{
return src;
}
}

View File

@ -40,20 +40,28 @@ public class AtomicAverage {
*/
public void put(double i) {
dirty = true;
if(brandNew)
try
{
DoubleArrayUtils.fill(values, i);
lastSum = size() * i;
brandNew = false;
return;
dirty = true;
if(brandNew)
{
DoubleArrayUtils.fill(values, i);
lastSum = size() * i;
brandNew = false;
return;
}
double current = values.get(cursor);
lastSum = (lastSum - current) + i;
values.set(cursor, i);
cursor = cursor + 1 < size() ? cursor + 1 : 0;
}
double current = values.get(cursor);
lastSum = (lastSum - current) + i;
values.set(cursor, i);
cursor = cursor + 1 < size() ? cursor + 1 : 0;
catch(Throwable e)
{
}
}
/**

View File

@ -3,6 +3,9 @@ package com.volmit.iris.util;
import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.manager.gui.PregenGui;
import com.volmit.iris.scaffold.IrisWorlds;
import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
@ -34,6 +37,7 @@ public class PregenJob implements Listener
private ChronoLatch clx;
private ChronoLatch clf;
private MortarSender sender;
private MultiBurst burst;
private int mcaWidth;
private int mcaX;
private int mcaZ;
@ -42,25 +46,30 @@ public class PregenJob implements Listener
private Runnable onDone;
private Spiraler spiraler;
private Spiraler chunkSpiraler;
private Spiraler preSpiraler;
private boolean first;
private static Consumer2<ChunkPosition, Color> consumer;
private double cps = 0;
private int lg = 0;
private long lt = M.ms();
private int cubeSize = 32;
private int cubeSize = IrisSettings.get().isUseGleamPregenerator() ? 32 : 32;
private long nogen = M.ms();
private KList<ChunkPosition> requeueMCA = new KList<ChunkPosition>();
private RollingSequence acps = new RollingSequence(PaperLib.isPaper() ? 8 : 32);
private boolean paused = false;
private long pausedAt = 0;
private double pms = 0;
private boolean gleaming = false;
int xc = 0;
private IrisAccess access = null;
public PregenJob(World world, int size, MortarSender sender, Runnable onDone)
{
gleaming = IrisSettings.get().isUseGleamPregenerator();
g.set(0);
burst = new MultiBurst(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc());
instance = this;
working = new Semaphore(tc());
working = new Semaphore(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc());
this.s = PrecisionStopwatch.start();
Iris.instance.registerListener(this);
this.world = world;
@ -86,6 +95,11 @@ public class PregenJob implements Listener
chunkZ = (mcaZ * cubeSize) + z;
});
preSpiraler = new Spiraler(cubeSize, cubeSize, (x, z) ->
{
});
spiraler = new Spiraler(mcaWidth, mcaWidth, (x, z) ->
{
mcaX = x;
@ -115,6 +129,17 @@ public class PregenJob implements Listener
return IrisSettings.get().maxAsyncChunkPregenThreads;
}
private IrisAccess access() {
if(access != null)
{
return access;
}
access = IrisWorlds.access(world);
return access;
}
public static void stop()
{
try
@ -183,10 +208,7 @@ public class PregenJob implements Listener
if(PaperLib.isPaper())
{
for(int i = 0; i < 16; i++)
{
tickPaper(skip);
}
tickPaper(skip);
}
else
@ -225,12 +247,12 @@ public class PregenJob implements Listener
public void tickPaper(boolean skip)
{
if(working.getQueueLength() >= tc() / 2)
if(working.getQueueLength() >= tc())
{
return;
}
for(int i = 0; i < 128; i++)
for(int i = 0; i < 64; i++)
{
tick(skip);
}
@ -326,7 +348,7 @@ public class PregenJob implements Listener
if(isChunkWithin(chunkX, chunkZ) && consumer != null)
{
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.BLUE.darker().darker());
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.BLACK.brighter());
}
}
chunkSpiraler.retarget(cubeSize, cubeSize);
@ -361,48 +383,78 @@ public class PregenJob implements Listener
{
if(PaperLib.isPaper())
{
if(consumer != null)
{
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.magenta.darker().darker().darker());
}
int cx = chunkX;
int cz = chunkZ;
J.a(() ->
if(gleaming)
{
try
if(consumer != null)
{
working.acquire();
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.cyan.darker().darker().darker());
}
if(consumer != null)
{
consumer.accept(new ChunkPosition(cx, cz), Color.magenta);
}
PaperLib.getChunkAtAsyncUrgently(world, cx, cz, true).thenAccept(chunk ->
{
J.a(() -> {
try {
working.acquire();
if(consumer != null)
{
consumer.accept(new ChunkPosition(cx, cz), Color.cyan);
}
Chunk chunk = access().generatePaper(world, cx, cz);
working.release();
genned++;
nogen = M.ms();
if(consumer != null)
{
consumer.accept(new ChunkPosition(chunk.getX(), chunk.getZ()), Color.blue);
consumer.accept(new ChunkPosition(chunk.getX(), chunk.getZ()), Color.yellow);
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
catch(InterruptedException e)
else
{if(consumer != null)
{
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.magenta.darker().darker().darker());
}
J.a(() ->
{
e.printStackTrace();
}
});
try
{
working.acquire();
if(consumer != null)
{
consumer.accept(new ChunkPosition(cx, cz), Color.magenta);
}
Chunk chunk = PaperLib.getChunkAtAsync(world, cx, cz, true).join();
working.release();
genned++;
nogen = M.ms();
if(consumer != null)
{
consumer.accept(new ChunkPosition(chunk.getX(), chunk.getZ()), Color.green);
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
});
}
}
else
{
if(consumer != null)
{
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.blue.darker().darker());
consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.black.brighter());
}
world.loadChunk(chunkX, chunkZ);
@ -533,8 +585,27 @@ public class PregenJob implements Listener
{
long eta = (long) ((total - genned) * 1000D / cps);
return new String[] {"Progress: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0), "Generated: " + Form.f(genned) + " Chunks", "Remaining: " + Form.f(total - genned) + " Chunks", "Elapsed: " + Form.duration((long) (paused ? pms : s.getMilliseconds()), 2), "Estimate: " + ((genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta, 2))), "ChunksMS: " + Form.duration(1000D / cps, 2), "Chunks/s: " + Form.f(cps, 1),
};
KList<String> vv = new KList<String>( new String[] {"Progress: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0),
"Generated: " + Form.f(genned) + " Chunks",
"Remaining: " + Form.f(total - genned) + " Chunks",
"Elapsed: " + Form.duration((long) (paused ? pms : s.getMilliseconds()), 2),
"Estimate: " + ((genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta, 2))),
"ChunksMS: " + Form.duration(1000D / cps, 2),
"Chunks/zs: " + Form.f(cps, 1),
});
try
{
vv.add("Parallelism: " + access().getCompound().getCurrentlyGeneratingEngines());
vv.add("Precache : " + access().getPrecacheSize());
}
catch(Throwable e)
{
}
return vv.toArray(new String[vv.size()]);
}
public static void pauseResume()