add headless pregen to world creation

This commit is contained in:
Julian Krings 2024-08-22 20:31:24 +02:00
parent 26aae2b730
commit 4434cf6475
5 changed files with 154 additions and 36 deletions

View File

@ -103,6 +103,8 @@ public class CommandIris implements DecreeExecutor {
IrisDimension type,
@Param(description = "The seed to generate the world with", defaultValue = "1337")
long seed,
@Param(description = "The radius of chunks to generate in headless mode (-1 to disable)", defaultValue = "10", aliases = "radius")
int headlessRadius,
@Param(description = "If it should convert the dimension to match the vanilla height system.", defaultValue = "false")
boolean vanillaheight
) {
@ -132,6 +134,7 @@ public class CommandIris implements DecreeExecutor {
.sender(sender())
.studio(false)
.smartVanillaHeight(vanillaheight)
.headlessRadius(headlessRadius)
.create();
} catch (Throwable e) {
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");

View File

@ -0,0 +1,87 @@
package com.volmit.iris.core.pregenerator;
public final class EmptyListener implements PregenListener {
public static final PregenListener INSTANCE = new EmptyListener();
private EmptyListener() {}
@Override
public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) {
}
@Override
public void onChunkGenerating(int x, int z) {
}
@Override
public void onServerShutdown() {
}
@Override
public void onChunkGenerated(int x, int z) {
}
@Override
public void onRegionGenerated(int x, int z) {
}
@Override
public void onRegionGenerating(int x, int z) {
}
@Override
public void onChunkCleaned(int x, int z) {
}
@Override
public void onRegionSkipped(int x, int z) {
}
@Override
public void onNetworkStarted(int x, int z) {
}
@Override
public void onNetworkFailed(int x, int z) {
}
@Override
public void onNetworkReclaim(int revert) {
}
@Override
public void onNetworkGeneratedChunk(int x, int z) {
}
@Override
public void onNetworkDownloaded(int x, int z) {
}
@Override
public void onClose() {
}
@Override
public void onSaving() {
}
@Override
public void onChunkExistsInRegionGen(int x, int z) {
}
}

View File

@ -83,6 +83,11 @@ public class IrisCreator {
*/
private boolean benchmark = false;
private boolean smartVanillaHeight = false;
/**
* Radius of chunks to pregenerate in the headless mode
* if set to -1, headless mode is disabled
*/
private int headlessRadius = 10;
public static boolean removeFromBukkitYml(String name) throws IOException {
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
@ -130,7 +135,6 @@ public class IrisCreator {
Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name()));
}
PlatformChunkGenerator access = null;
AtomicReference<World> world = new AtomicReference<>();
AtomicDouble pp = new AtomicDouble(0);
O<Boolean> done = new O<>();
@ -142,21 +146,26 @@ public class IrisCreator {
.studio(studio)
.smartVanillaHeight(smartVanillaHeight)
.create();
PlatformChunkGenerator access = (PlatformChunkGenerator) wc.generator();
if (access == null) {
throw new IrisException("Access is null. Something bad happened.");
}
access = (PlatformChunkGenerator) wc.generator();
PlatformChunkGenerator finalAccess1 = access;
J.a(() ->
{
try {
access.prepareSpawnChunks(seed, headlessRadius);
} catch (Throwable e) {
Iris.error("Failed to prepare spawn chunks for " + name);
e.printStackTrace();
}
J.a(() -> {
Supplier<Integer> g = () -> {
if (finalAccess1 == null || finalAccess1.getEngine() == null) {
if (access.getEngine() == null) {
return 0;
}
return finalAccess1.getEngine().getGenerated();
return access.getEngine().getGenerated();
};
if (!benchmark) {
if (finalAccess1 == null) return;
int req = finalAccess1.getSpawnChunks().join();
int req = access.getSpawnChunks().join();
while (g.get() < req) {
double v = (double) g.get() / (double) req;
@ -180,10 +189,6 @@ public class IrisCreator {
e.printStackTrace();
}
if (access == null) {
throw new IrisException("Access is null. Something bad happened.");
}
done.set(true);
if (sender.isPlayer() && !benchmark) {

View File

@ -21,6 +21,8 @@ package com.volmit.iris.engine.platform;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.pregenerator.EmptyListener;
import com.volmit.iris.core.pregenerator.methods.HeadlessPregenMethod;
import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.engine.data.chunk.TerrainChunk;
@ -132,27 +134,26 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
if (initialized || !world.name().equals(event.getWorld().getName()))
return;
world.setRawWorldSeed(event.getWorld().getSeed());
Engine engine = getEngine(event.getWorld());
if (engine == null) {
Iris.warn("Failed to get Engine!");
J.s(() -> {
Engine engine1 = getEngine(event.getWorld());
if (engine1 != null) {
try {
INMS.get().inject(event.getWorld().getSeed(), engine1, event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
initialized = true;
} catch (Throwable e) {
e.printStackTrace();
}
}
}, 10);
} else {
INMS.get().inject(event.getWorld().getSeed(), engine, event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
spawnChunks.complete(INMS.get().getSpawnChunkCount(event.getWorld()));
initialized = true;
Engine engine = getEngine(event.getWorld());
if (engine == null) {
Iris.warn("Failed to get Engine!");
J.s(() -> {
Engine engine1 = getEngine(event.getWorld());
if (engine1 != null) {
try {
INMS.get().inject(event.getWorld().getSeed(), engine1, event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
initialized = true;
} catch (Throwable e) {
e.printStackTrace();
}
}
}, 10);
} else {
INMS.get().inject(event.getWorld().getSeed(), engine, event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
spawnChunks.complete(INMS.get().getSpawnChunkCount(event.getWorld()));
initialized = true;
}
} catch (Throwable e) {
e.printStackTrace();
@ -265,7 +266,10 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
}
private Engine getEngine(WorldInfo world) {
return getEngine(world.getSeed());
}
private Engine getEngine(long seed) {
if (setup.get()) {
return getEngine();
}
@ -278,7 +282,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
}
getWorld().setRawWorldSeed(world.getSeed());
getWorld().setRawWorldSeed(seed);
setupEngine();
setup.set(true);
this.hotloader = studio ? new Looper() {
@ -349,6 +353,23 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
getEngine(world);
}
@Override
public void prepareSpawnChunks(long seed, int radius) {
if (radius < 0 || new File(world.worldFolder(), "level.dat").exists())
return;
var engine = getEngine(seed);
var headless = new HeadlessPregenMethod(engine);
Iris.info("Generating " + world.name() + " in headless mode");
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
headless.generateChunk(x, z, EmptyListener.INSTANCE);
}
}
headless.close();
Iris.info("Done generating " + world.name() + " in headless mode");
}
@Override
public void generateNoise(@NotNull WorldInfo world, @NotNull Random random, int x, int z, @NotNull ChunkGenerator.ChunkData d) {
try {

View File

@ -49,4 +49,6 @@ public interface PlatformChunkGenerator extends Hotloadable, DataProvider {
void touch(World world);
CompletableFuture<Integer> getSpawnChunks();
void prepareSpawnChunks(long seed, int radius);
}