9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-29 20:19:06 +00:00

Merge remote-tracking branch 'origin/dev' into feat/headless

# Conflicts:
#	core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java
#	core/src/main/java/com/volmit/iris/core/commands/CommandIris.java
#	core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java
#	core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java
#	nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java
#	nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java
#	nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java
#	nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java
#	nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java
#	nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java
#	nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java
This commit is contained in:
Julian Krings
2025-04-02 16:33:51 +02:00
33 changed files with 1366 additions and 250 deletions

View File

@@ -35,6 +35,7 @@ import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.core.tools.IrisWorldCreator;
import com.volmit.iris.engine.EnginePanic;
import com.volmit.iris.engine.object.IrisCompat;
import com.volmit.iris.engine.object.IrisContextInjector;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisWorld;
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
@@ -458,9 +459,12 @@ public class Iris extends VolmitPlugin implements Listener {
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
INMS.get();
IO.delete(new File("iris"));
compat = IrisCompat.configured(getDataFile("compat.json"));
ServerConfigurator.configure();
new IrisContextInjector();
IrisSafeguard.IrisSafeguardSystem();
getSender().setTag(getTag());
compat = IrisCompat.configured(getDataFile("compat.json"));
IrisSafeguard.earlySplash();
linkMultiverseCore = new MultiverseCoreLink();
linkMythicMobs = new MythicMobsLink();
configWatcher = new FileWatcher(getDataFile("settings.json"));
@@ -515,11 +519,10 @@ public class Iris extends VolmitPlugin implements Listener {
Iris.info("Loading World: %s | Generator: %s", s, generator);
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
new WorldCreator(s)
.type(IrisWorldCreator.IRIS)
WorldCreator c = new WorldCreator(s)
.generator(getDefaultWorldGenerator(s, generator))
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
.createWorld();
.environment(IrisData.loadAnyDimension(generator).getEnvironment());
INMS.get().createWorld(c);
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
}
} catch (Throwable e) {

View File

@@ -181,6 +181,7 @@ public class IrisSettings {
public boolean splashLogoStartup = true;
public boolean useConsoleCustomColors = true;
public boolean useCustomColorsIngame = true;
public boolean adjustVanillaHeight = false;
public String forceMainWorld = "";
public int spinh = -20;
public int spins = 7;

View File

@@ -28,21 +28,24 @@ import com.volmit.iris.engine.object.IrisBiomeCustom;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisRange;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.misc.ServerProperties;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import lombok.Data;
import lombok.NonNull;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
@@ -89,12 +92,13 @@ public class ServerConfigurator {
}
}
private static List<File> getDatapacksFolder() {
private static KList<File> getDatapacksFolder() {
if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) {
return new KList<File>().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
}
KList<File> worlds = new KList<>();
Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks")));
if (worlds.isEmpty()) worlds.add(new File(Bukkit.getWorldContainer(), ServerProperties.LEVEL_NAME + "/datapacks"));
return worlds;
}
@@ -105,14 +109,16 @@ public class ServerConfigurator {
public static void installDataPacks(IDataFixer fixer, boolean fullInstall) {
Iris.info("Checking Data Packs...");
DimensionHeight height = new DimensionHeight(fixer);
KList<File> folders = getDatapacksFolder();
KMap<String, KSet<String>> biomes = new KMap<>();
allPacks().flatMap(height::merge)
.parallel()
.forEach(dim -> {
for (File dpack : getDatapacksFolder()) {
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
dim.installDataPack(fixer, dim::getLoader, dpack, height);
}
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
dim.installBiomes(fixer, dim::getLoader, folders, biomes.computeIfAbsent(dim.getLoadKey(), k -> new KSet<>()));
});
IrisDimension.writeShared(folders, height);
Iris.info("Data Packs Setup!");
@@ -164,7 +170,7 @@ public class ServerConfigurator {
Iris.warn("This will only happen when your pack changes (updates/first time setup)");
Iris.warn("(You can disable this auto restart in iris settings)");
J.s(() -> {
Iris.warn("Looks like the restart command diddn't work. Stopping the server instead!");
Iris.warn("Looks like the restart command didn't work. Stopping the server instead!");
Bukkit.shutdown();
}, 100);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart");
@@ -172,22 +178,24 @@ public class ServerConfigurator {
}
public static boolean verifyDataPackInstalled(IrisDimension dimension) {
IrisData idm = IrisData.get(Iris.instance.getDataFolder("packs", dimension.getLoadKey()));
KSet<String> keys = new KSet<>();
boolean warn = false;
for (IrisBiome i : dimension.getAllBiomes(() -> idm)) {
for (IrisBiome i : dimension.getAllBiomes(dimension::getLoader)) {
if (i.isCustom()) {
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
keys.add(dimension.getLoadKey() + ":" + j.getId());
}
}
}
String key = getWorld(dimension.getLoader());
if (key == null) key = dimension.getLoadKey();
else key += "/" + dimension.getLoadKey();
if (!INMS.get().supportsDataPacks()) {
if (!keys.isEmpty()) {
Iris.warn("===================================================================================");
Iris.warn("Pack " + dimension.getLoadKey() + " has " + keys.size() + " custom biome(s). ");
Iris.warn("Pack " + key + " has " + keys.size() + " custom biome(s). ");
Iris.warn("Your server version does not yet support datapacks for iris.");
Iris.warn("The world will generate these biomes as backup biomes.");
Iris.warn("====================================================================================");
@@ -206,7 +214,7 @@ public class ServerConfigurator {
}
if (warn) {
Iris.error("The Pack " + dimension.getLoadKey() + " is INCAPABLE of generating custom biomes");
Iris.error("The Pack " + key + " is INCAPABLE of generating custom biomes");
Iris.error("If not done automatically, restart your server before generating with this pack!");
}
@@ -220,6 +228,17 @@ public class ServerConfigurator {
.map(IrisData::get);
}
@Nullable
public static String getWorld(@NonNull IrisData data) {
String worldContainer = Bukkit.getWorldContainer().getAbsolutePath();
if (!worldContainer.endsWith(File.separator)) worldContainer += File.separator;
String path = data.getDataFolder().getAbsolutePath();
if (!path.startsWith(worldContainer)) return null;
int l = path.endsWith(File.separator) ? 11 : 10;
return path.substring(worldContainer.length(), path.length() - l);
}
private static Stream<File> listFiles(File parent) {
var files = parent.listFiles();
return files == null ? Stream.empty() : Arrays.stream(files);

View File

@@ -145,7 +145,7 @@ public class CommandDeveloper implements DecreeExecutor {
public void packBenchmark(
@Param(description = "The pack to bench", aliases = {"pack"}, defaultValue = "overworld")
IrisDimension dimension,
@Param(description = "Diameter in regions", defaultValue = "5")
@Param(description = "Diameter in regions", defaultValue = "2048")
int diameter,
@Param(description = "Headless", defaultValue = "true")
boolean headless,

View File

@@ -602,10 +602,10 @@ public class CommandIris implements DecreeExecutor {
continue;
}
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
new WorldCreator(s)
WorldCreator c = new WorldCreator(s)
.generator(getDefaultWorldGenerator(s, generator))
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
.createWorld();
.environment(IrisData.loadAnyDimension(generator).getEnvironment());
INMS.get().createWorld(c);
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
}
} catch (Throwable e) {

View File

@@ -19,9 +19,7 @@
package com.volmit.iris.core.commands;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.PregeneratorJob;
import com.volmit.iris.core.pregenerator.LazyPregenerator;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.util.decree.DecreeExecutor;
@@ -29,12 +27,9 @@ import com.volmit.iris.util.decree.annotations.Decree;
import com.volmit.iris.util.decree.annotations.Param;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.Position2;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.util.Vector;
import java.io.File;
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
public class CommandPregen implements DecreeExecutor {
@Decree(description = "Pregenerate a world")
@@ -52,13 +47,12 @@ public class CommandPregen implements DecreeExecutor {
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
}
radius = Math.max(radius, 1024);
int w = (radius >> 9 + 1) * 2;
IrisToolbelt.pregenerate(PregenTask
.builder()
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
.center(new Position2(center.getBlockX(), center.getBlockZ()))
.gui(true)
.width(w)
.height(w)
.radiusX(radius)
.radiusZ(radius)
.build(), world);
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
sender().sendMessage(msg);

View File

@@ -24,7 +24,6 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.Form;
@@ -45,8 +44,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
public class PregeneratorJob implements PregenListener {
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
@@ -81,12 +78,12 @@ public class PregeneratorJob implements PregenListener {
this.task = task;
this.pregenerator = new IrisPregenerator(task, method, this);
max = new Position2(0, 0);
min = new Position2(0, 0);
task.iterateRegions((xx, zz) -> {
min.setX(Math.min(xx << 5, min.getX()));
min.setZ(Math.min(zz << 5, min.getZ()));
max.setX(Math.max((xx << 5) + 31, max.getX()));
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE);
task.iterateAllChunks((xx, zz) -> {
min.setX(Math.min(xx, min.getX()));
min.setZ(Math.min(zz, min.getZ()));
max.setX(Math.max(xx, max.getX()));
max.setZ(Math.max(zz, max.getZ()));
});
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
@@ -162,7 +159,7 @@ public class PregeneratorJob implements PregenListener {
}
public void drawRegion(int x, int z, Color color) {
J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> {
J.a(() -> task.iterateChunks(x, z, (xx, zz) -> {
draw(xx, zz, color);
J.sleep(3);
}));

View File

@@ -37,7 +37,7 @@ public class INMS {
"1.21.4", "v1_21_R3"
);
private static final List<Version> PACKS = List.of(
new Version(21, 4, "31010"),
new Version(21, 4, "31020"),
new Version(21, 2, "31000"),
new Version(20, 1, "3910")
);

View File

@@ -18,7 +18,9 @@
package com.volmit.iris.core.nms;
import com.volmit.iris.core.nms.container.AutoClosing;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.nms.container.Pair;
import com.volmit.iris.core.nms.datapack.DataVersion;
import com.volmit.iris.core.nms.headless.IRegionStorage;
import com.volmit.iris.engine.framework.Engine;
@@ -89,7 +91,12 @@ public interface INMSBinding {
MCABiomeContainer newBiomeContainer(int min, int max);
default World createWorld(WorldCreator c) {
return c.createWorld();
if (missingDimensionTypes(true, true, true))
throw new IllegalStateException("Missing dimenstion types to create world");
try (var ignored = injectLevelStems()) {
return c.createWorld();
}
}
int countCustomBiomes();
@@ -125,4 +132,10 @@ public interface INMSBinding {
IRegionStorage createRegionStorage(Engine engine);
KList<String> getStructureKeys();
AutoClosing injectLevelStems();
Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end);
boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end);
}

View File

@@ -0,0 +1,22 @@
package com.volmit.iris.core.nms.container;
import com.volmit.iris.util.function.NastyRunnable;
import lombok.AllArgsConstructor;
import java.util.concurrent.atomic.AtomicBoolean;
@AllArgsConstructor
public class AutoClosing implements AutoCloseable {
private final AtomicBoolean closed = new AtomicBoolean();
private final NastyRunnable action;
@Override
public void close() {
if (closed.getAndSet(true)) return;
try {
action.run();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -20,46 +20,6 @@ public interface IDataFixer {
return obj;
}
default JSONObject createPreset() {
return new JSONObject("""
{
"dimensions": {
"minecraft:overworld": {
"type": "iris:overworld",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "minecraft:multi_noise",
"preset": "minecraft:overworld"
},
"settings": "minecraft:overworld"
}
},
"minecraft:the_end": {
"type": "iris:the_end",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "minecraft:the_end"
},
"settings": "minecraft:end"
}
},
"minecraft:the_nether": {
"type": "iris:the_nether",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "minecraft:multi_noise",
"preset": "minecraft:nether"
},
"settings": "minecraft:nether"
}
}
}
}""");
}
enum Dimension {
OVERRWORLD,
NETHER,

View File

@@ -20,8 +20,10 @@ package com.volmit.iris.core.nms.v1X;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMSBinding;
import com.volmit.iris.core.nms.container.AutoClosing;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.nms.headless.IRegionStorage;
import com.volmit.iris.core.nms.container.Pair;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
@@ -124,6 +126,21 @@ public class NMSBinding1X implements INMSBinding {
return new KList<>(list);
}
@Override
public AutoClosing injectLevelStems() {
return new AutoClosing(() -> {});
}
@Override
public Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
return new Pair<>(0, new AutoClosing(() -> {}));
}
@Override
public boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end) {
return false;
}
@Override
public CompoundTag serializeEntity(Entity location) {
return null;

View File

@@ -165,8 +165,11 @@ public class ChunkUpdater {
if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) {
return;
}
if (!new File(world.getWorldFolder(), "region" + File.separator + rX + "." + rZ + ".mca").exists()) {
return;
}
PregenTask.iterateRegion(rX, rZ, (x, z) -> {
task.iterateChunks(rX, rZ, (x, z) -> {
while (paused.get() && !cancelled.get()) {
J.sleep(50);
}
@@ -348,8 +351,8 @@ public class ChunkUpdater {
int width = maxZ - minZ + 1;
return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder()
.width((int) Math.ceil(width / 2d))
.height((int) Math.ceil(height / 2d))
.radiusZ((int) Math.ceil(width / 2d * 512))
.radiusX((int) Math.ceil(height / 2d * 512))
.center(new Position2(oX, oZ))
.build());
}

View File

@@ -19,7 +19,6 @@
package com.volmit.iris.core.pregenerator;
import com.volmit.iris.Iris;
import com.volmit.iris.core.pack.IrisPack;
import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KSet;
@@ -83,7 +82,7 @@ public class IrisPregenerator {
generatedLast = new AtomicInteger(0);
generatedLastMinute = new AtomicInteger(0);
totalChunks = new AtomicInteger(0);
task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024));
task.iterateAllChunks((_a, _b) -> totalChunks.incrementAndGet());
startTime = new AtomicLong(M.ms());
ticker = new Looper() {
@Override
@@ -194,7 +193,7 @@ public class IrisPregenerator {
} else if (!regions) {
hit = true;
listener.onRegionGenerating(x, z);
PregenTask.iterateRegion(x, z, (xx, zz) -> {
task.iterateChunks(x, z, (xx, zz) -> {
while (paused.get() && !shutdown.get()) {
J.sleep(50);
}

View File

@@ -32,17 +32,26 @@ import java.util.Comparator;
@Data
public class PregenTask {
private static final Position2 ZERO = new Position2(0, 0);
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
@Builder.Default
private boolean gui = false;
private final boolean gui = false;
@Builder.Default
private Position2 center = new Position2(0, 0);
private final Position2 center = new Position2(0, 0);
@Builder.Default
private int width = 1;
private final int radiusX = 1;
@Builder.Default
private int height = 1;
private final int radiusZ = 1;
private final Bounds bounds = new Bounds();
protected PregenTask(boolean gui, Position2 center, int radiusX, int radiusZ) {
this.gui = gui;
this.center = new ProxiedPos(center);
this.radiusX = radiusX;
this.radiusZ = radiusZ;
bounds.update();
}
public static void iterateRegion(int xr, int zr, Spiraled s, Position2 pull) {
for (Position2 i : ORDERS.computeIfAbsent(pull, PregenTask::computeOrder)) {
@@ -70,29 +79,72 @@ public class PregenTask {
return p;
}
private static KList<Position2> computeChunkOrder() {
Position2 center = new Position2(15, 15);
KList<Position2> p = new KList<>();
new Spiraler(33, 33, (x, z) -> {
int xx = x + 15;
int zz = z + 15;
if (xx < 0 || xx > 31 || zz < 0 || zz > 31) {
return;
}
p.add(new Position2(xx, zz));
}).drain();
p.sort(Comparator.comparing((i) -> i.distance(center)));
return p;
public void iterateRegions(Spiraled s) {
var bound = bounds.region();
new Spiraler(bound.sizeX, bound.sizeZ, ((x, z) -> {
if (bound.check(x, z)) s.on(x, z);
})).setOffset(center.getX() >> 9, center.getZ() >> 9).drain();
}
public void iterateRegions(Spiraled s) {
new Spiraler(getWidth() * 2, getHeight() * 2, s)
.setOffset(center.getX(), center.getZ()).drain();
public void iterateChunks(int rX, int rZ, Spiraled s) {
var bound = bounds.chunk();
iterateRegion(rX, rZ, ((x, z) -> {
if (bound.check(x, z)) s.on(x, z);
}));
}
public void iterateAllChunks(Spiraled s) {
new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s))
.setOffset(center.getX(), center.getZ()).drain();
iterateRegions(((rX, rZ) -> iterateChunks(rX, rZ, s)));
}
private class Bounds {
private Bound chunk = null;
private Bound region = null;
public void update() {
int maxX = center.getX() + radiusX;
int maxZ = center.getZ() + radiusZ;
int minX = center.getX() - radiusX;
int minZ = center.getZ() - radiusZ;
chunk = new Bound(minX >> 4, minZ >> 4, Math.ceilDiv(maxX, 16), Math.ceilDiv(maxZ, 16));
region = new Bound(minX >> 9, minZ >> 9, Math.ceilDiv(maxX, 512), Math.ceilDiv(maxZ, 512));
}
public Bound chunk() {
if (chunk == null) update();
return chunk;
}
public Bound region() {
if (region == null) update();
return region;
}
}
private record Bound(int minX, int maxX, int minZ, int maxZ, int sizeX, int sizeZ) {
private Bound(int minX, int minZ, int maxX, int maxZ) {
this(minX, maxX, minZ, maxZ, maxZ - minZ + 1, maxZ - minZ + 1);
}
boolean check(int x, int z) {
return x >= minX && x <= maxX && z >= minZ && z <= maxZ;
}
}
private static class ProxiedPos extends Position2 {
public ProxiedPos(Position2 p) {
super(p.getX(), p.getZ());
}
@Override
public void setX(int x) {
throw new IllegalStateException("This Position2 may not be modified");
}
@Override
public void setZ(int z) {
throw new IllegalStateException("This Position2 may not be modified");
}
}
}

View File

@@ -1,6 +1,7 @@
package com.volmit.iris.core.safeguard;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
public class IrisSafeguard {
public static boolean unstablemode = false;
@@ -11,5 +12,13 @@ public class IrisSafeguard {
Iris.info("Enabled Iris SafeGuard");
ServerBootSFG.BootCheck();
}
public static void earlySplash() {
if (ServerBootSFG.safeguardPassed || IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode)
return;
Iris.instance.splash();
UtilsSFG.splash();
}
}

View File

@@ -3,6 +3,7 @@ package com.volmit.iris.core.safeguard;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
import com.volmit.iris.engine.object.IrisContextInjector;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
@@ -29,6 +30,7 @@ public class ServerBootSFG {
public static boolean isJRE = false;
public static boolean hasPrivileges = true;
public static boolean unsuportedversion = false;
public static boolean missingDimensionTypes = false;
protected static boolean safeguardPassed;
public static boolean passedserversoftware = true;
protected static int count;
@@ -110,6 +112,12 @@ public class ServerBootSFG {
severityMedium++;
}
if (IrisContextInjector.isMissingDimensionTypes()) {
missingDimensionTypes = true;
joiner.add("Missing Dimension Types");
severityHigh++;
}
allIncompatibilities = joiner.toString();
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);

View File

@@ -39,6 +39,11 @@ public class UtilsSFG {
Iris.safeguard(C.RED + "Server Version");
Iris.safeguard(C.RED + "- Iris only supports 1.20.1 > 1.21.4");
}
if (ServerBootSFG.missingDimensionTypes) {
Iris.safeguard(C.RED + "Dimension Types");
Iris.safeguard(C.RED + "- Required Iris dimension types were not loaded.");
Iris.safeguard(C.RED + "- If this still happens after a restart please contact support.");
}
if (!ServerBootSFG.passedserversoftware) {
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead.");

View File

@@ -22,6 +22,7 @@ import com.google.common.util.concurrent.AtomicDouble;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.ServerConfigurator;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.object.IrisDimension;
@@ -200,7 +201,7 @@ public class IrisCreator {
try {
J.sfut(() -> {
world.set(wc.createWorld());
world.set(INMS.get().createWorld(wc));
}).get();
} catch (Throwable e) {
e.printStackTrace();

View File

@@ -174,8 +174,8 @@ public class IrisPackBenchmarking {
IrisToolbelt.pregenerate(PregenTask
.builder()
.gui(gui)
.width(diameter)
.height(diameter)
.radiusX(diameter)
.radiusZ(diameter)
.build(), headless ?
new HeadlessPregenMethod(engine) :
new HybridPregenMethod(

View File

@@ -32,8 +32,6 @@ import sun.misc.Unsafe;
import java.io.File;
public class IrisWorldCreator {
public static final WorldType IRIS;
private String name;
private boolean studio = false;
private String dimensionName = null;
@@ -85,7 +83,6 @@ public class IrisWorldCreator {
return new WorldCreator(name)
.type(IRIS)
.environment(findEnvironment())
.generateStructures(true)
.generator(g).seed(seed);
@@ -104,17 +101,4 @@ public class IrisWorldCreator {
this.studio = studio;
return this;
}
static {
try {
var unsafe = new WrappedField<Unsafe, Unsafe>(Unsafe.class, "theUnsafe").get();
var iris = (WorldType) unsafe.allocateInstance(WorldType.class);
unsafe.putIntVolatile(iris, unsafe.objectFieldOffset(Enum.class.getDeclaredField("ordinal")), 0);
unsafe.putObjectVolatile(iris, unsafe.objectFieldOffset(Enum.class.getDeclaredField("name")), "IRIS");
IRIS = iris;
} catch (Throwable e) {
throw new ExceptionInInitializerError(e);
}
}
}

View File

@@ -0,0 +1,77 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.container.AutoClosing;
import com.volmit.iris.util.misc.ServerProperties;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import java.util.List;
import static com.volmit.iris.Iris.instance;
public class IrisContextInjector implements Listener {
@Getter
private static boolean missingDimensionTypes = false;
private AutoClosing autoClosing = null;
private final int totalWorlds;
private int worldCounter = 0;
public IrisContextInjector() {
if (!Bukkit.getWorlds().isEmpty()) {
totalWorlds = 0;
return;
}
String levelName = ServerProperties.LEVEL_NAME;
List<String> irisWorlds = irisWorlds();
boolean overworld = irisWorlds.contains(levelName);
boolean nether = irisWorlds.contains(levelName + "_nether");
boolean end = irisWorlds.contains(levelName + "_end");
int i = 1;
if (Bukkit.getAllowNether()) i++;
if (Bukkit.getAllowEnd()) i++;
if (INMS.get().missingDimensionTypes(overworld, nether, end)) {
missingDimensionTypes = true;
totalWorlds = 0;
return;
}
if (overworld || nether || end) {
var pair = INMS.get().injectUncached(overworld, nether, end);
i += pair.getA() - 3;
autoClosing = pair.getB();
}
totalWorlds = i;
instance.registerListener(this);
}
@EventHandler
public void on(WorldInitEvent event) {
if (++worldCounter < totalWorlds) return;
if (autoClosing != null) {
autoClosing.close();
autoClosing = null;
}
instance.unregisterListener(this);
}
private List<String> irisWorlds() {
var config = YamlConfiguration.loadConfiguration(ServerProperties.BUKKIT_YML);
ConfigurationSection section = config.getConfigurationSection("worlds");
if (section == null) return List.of();
return section.getKeys(false)
.stream()
.filter(k -> section.getString(k + ".generator", "").startsWith("Iris"))
.toList();
}
}

View File

@@ -19,6 +19,7 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.ServerConfigurator.DimensionHeight;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.loader.IrisRegistrant;
@@ -27,6 +28,7 @@ import com.volmit.iris.core.nms.datapack.IDataFixer;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONObject;
@@ -377,60 +379,35 @@ public class IrisDimension extends IrisRegistrant {
return landBiomeStyle;
}
public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks, DimensionHeight height) {
boolean write = false;
boolean changed = false;
IO.delete(new File(datapacks, "iris/data/" + getLoadKey().toLowerCase()));
for (IrisBiome i : getAllBiomes(data)) {
if (i.isCustom()) {
write = true;
for (IrisBiomeCustom j : i.getCustomDerivitives()) {
File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json");
if (!output.exists()) {
changed = true;
}
Iris.verbose(" Installing Data Pack Biome: " + output.getPath());
output.getParentFile().mkdirs();
try {
IO.writeAll(output, j.generateJson(fixer));
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
}
}
Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\"");
changed = writeDimensionType(changed, datapacks, height);
Iris.verbose(" Installing Data Pack World Preset: \"minecraft:iris\"");
changed = writeWorldPreset(changed, datapacks, fixer);
if (write) {
File mcm = new File(datapacks, "iris/pack.mcmeta");
try {
IO.writeAll(mcm, """
{
"pack": {
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
"pack_format": {}
}
public void installBiomes(IDataFixer fixer, DataProvider data, KList<File> folders, KSet<String> biomes) {
getAllBiomes(data)
.stream()
.filter(IrisBiome::isCustom)
.map(IrisBiome::getCustomDerivitives)
.flatMap(KList::stream)
.parallel()
.forEach(j -> {
String json = j.generateJson(fixer);
synchronized (biomes) {
if (!biomes.add(j.getId())) {
Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + j.getId());
return;
}
""".replace("{}", INMS.get().getDataVersion().getPackFormat() + ""));
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath());
}
}
return changed;
for (File datapacks : folders) {
File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json");
Iris.verbose(" Installing Data Pack Biome: " + output.getPath());
output.getParentFile().mkdirs();
try {
IO.writeAll(output, json);
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
});
}
@Override
@@ -448,56 +425,55 @@ public class IrisDimension extends IrisRegistrant {
}
public boolean writeDimensionType(boolean changed, File datapacks, DimensionHeight height) {
File dimTypeOverworld = new File(datapacks, "iris/data/iris/dimension_type/overworld.json");
if (!dimTypeOverworld.exists())
changed = true;
dimTypeOverworld.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeOverworld, height.overworldType());
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
public static void writeShared(KList<File> folders, DimensionHeight height) {
Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\"");
for (File datapacks : folders) {
write(datapacks, "overworld", height.overworldType());
write(datapacks, "the_nether", height.netherType());
write(datapacks, "the_end", height.endType());
}
String raw = """
{
"pack": {
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
"pack_format": {}
}
}
""".replace("{}", INMS.get().getDataVersion().getPackFormat() + "");
File dimTypeNether = new File(datapacks, "iris/data/iris/dimension_type/the_nether.json");
if (!dimTypeNether.exists())
changed = true;
dimTypeNether.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeNether, height.netherType());
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
for (File datapacks : folders) {
File mcm = new File(datapacks, "iris/pack.mcmeta");
try {
IO.writeAll(mcm, raw);
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath());
}
File dimTypeEnd = new File(datapacks, "iris/data/iris/dimension_type/the_end.json");
if (!dimTypeEnd.exists())
changed = true;
dimTypeEnd.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeEnd, height.endType());
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
return changed;
}
public boolean writeWorldPreset(boolean changed, File datapacks, IDataFixer fixer) {
File worldPreset = new File(datapacks, "iris/data/minecraft/worldgen/world_preset/iris.json");
if (!worldPreset.exists())
changed = true;
private static void write(File datapacks, String type, String json) {
File dimType = new File(datapacks, "iris/data/iris/dimension_type/" + type + ".json");
File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json");
dimType.getParentFile().mkdirs();
try {
IO.writeAll(worldPreset, fixer.createPreset());
IO.writeAll(dimType, json);
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
return changed;
if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) {
dimTypeVanilla.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeVanilla, json);
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
}
}

View File

@@ -63,7 +63,7 @@ public class Spiraler {
public void next() {
if ((-sizeX / 2 <= x) && (x <= sizeX / 2) && (-sizeZ / 2 <= z) && (z <= sizeZ / 2)) {
spiraled.on(x + ox, z + ox);
spiraled.on(x + ox, z + oz);
}
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) {

View File

@@ -0,0 +1,44 @@
package com.volmit.iris.util.misc;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ServerProperties {
public static final Properties DATA = new Properties();
public static final File SERVER_PROPERTIES;
public static final File BUKKIT_YML;
public static final String LEVEL_NAME;
static {
String[] args = ProcessHandle.current()
.info()
.arguments()
.orElse(new String[0]);
String propertiesPath = "server.properties";
String bukkitYml = "bukkit.yml";
String levelName = null;
for (int i = 0; i < args.length - 1; i++) {
switch (args[i]) {
case "-c", "--config" -> propertiesPath = args[i + 1];
case "-b", "--bukkit-settings" -> bukkitYml = args[i + 1];
case "-w", "--level-name", "--world" -> levelName = args[i + 1];
}
}
SERVER_PROPERTIES = new File(propertiesPath);
BUKKIT_YML = new File(bukkitYml);
try (FileInputStream in = new FileInputStream(SERVER_PROPERTIES)){
DATA.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (levelName != null) LEVEL_NAME = levelName;
else LEVEL_NAME = DATA.getProperty("level-name", "world");
}
}