From 4a1de4c0dad46b962920ffcb1deff63bf98937c2 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 26 Aug 2021 01:46:56 -0400 Subject: [PATCH] Chunk regeneration --- .../volmit/iris/core/command/CommandIris.java | 4 +- .../core/command/world/CommandIrisRegen.java | 141 ++++++++++++++++++ .../com/volmit/iris/engine/IrisEngine.java | 4 +- .../volmit/iris/engine/IrisWorldManager.java | 22 ++- .../engine/actuator/IrisBiomeActuator.java | 3 +- .../engine/data/chunk/LinkedTerrainChunk.java | 9 ++ .../iris/engine/data/chunk/TerrainChunk.java | 6 + .../iris/engine/mantle/EngineMantle.java | 23 ++- .../components/MantleJigsawComponent.java | 2 +- .../engine/platform/BukkitChunkGenerator.java | 122 ++++++++++++++- .../engine/platform/HeadlessGenerator.java | 7 + .../platform/PlatformChunkGenerator.java | 5 + .../iris/util/data/IrisBiomeStorage.java | 14 +- .../com/volmit/iris/util/mantle/Mantle.java | 19 ++- .../volmit/iris/util/mantle/MantleChunk.java | 20 ++- .../volmit/iris/util/mantle/MantleFlag.java | 3 +- .../iris/util/mantle/TectonicPlate.java | 19 ++- .../iris/util/parallel/BurstExecutor.java | 7 + .../com/volmit/iris/util/scheduling/J.java | 9 ++ 19 files changed, 410 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index c54885676..20601d459 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -25,8 +25,8 @@ import com.volmit.iris.core.command.pregen.CommandIrisPregen; import com.volmit.iris.core.command.studio.CommandIrisStudio; import com.volmit.iris.core.command.what.CommandIrisWhat; import com.volmit.iris.core.command.world.CommandIrisCreate; +import com.volmit.iris.core.command.world.CommandIrisRegen; import com.volmit.iris.core.command.world.CommandIrisUpdateWorld; -import com.volmit.iris.core.command.world.CommandIrisVerify; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.MortarCommand; @@ -37,7 +37,7 @@ public class CommandIris extends MortarCommand { private CommandIrisCreate create; @Command - private CommandIrisVerify verify; + private CommandIrisRegen regen; @Command private CommandIrisDebug debug; diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java new file mode 100644 index 000000000..b17df75be --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java @@ -0,0 +1,141 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.world; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.platform.PlatformChunkGenerator; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.jobs.Job; +import com.volmit.iris.util.scheduling.jobs.JobCollection; +import com.volmit.iris.util.scheduling.jobs.QueueJob; +import org.bukkit.Chunk; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class CommandIrisRegen extends MortarCommand { + public CommandIrisRegen() { + super("regen"); + requiresPermission(Iris.perm.studio); + setDescription("Regenerate nearby chunks"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (!sender.isPlayer()) + { + sender.sendMessage("Must be in an iris world."); + } + + if(IrisToolbelt.isIrisWorld(sender.player().getWorld())) + { + PlatformChunkGenerator plat = IrisToolbelt.access(sender.player().getWorld()); + Engine engine = plat.getEngine(); + try + { + int vd = Integer.parseInt(args[0]); + int rg = 0; + Chunk cx = sender.player().getLocation().getChunk(); + KList js = new KList<>(); + BurstExecutor b = MultiBurst.burst.burst(); + b.setMulticore(false); + int rad = engine.getMantle().getRealRadius(); + for(int i = -(vd+rad); i <= vd+rad; i++) { + for (int j = -(vd+rad); j <= vd+rad; j++) { + engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ()); + } + } + + for(int i = -vd; i <= vd; i++) + { + for(int j = -vd; j <= vd; j++) + { + int finalJ = j; + int finalI = i; + b.queue(() -> plat.injectChunkReplacement(sender.player().getWorld(), finalI + cx.getX(), finalJ + cx.getZ(), (f) -> { + synchronized (js) + { + js.add(f); + } + })); + } + } + + b.complete(); + sender.sendMessage("Regenerating " + Form.f(js.size()) + " Sections"); + QueueJob r = new QueueJob<>() { + final KList> futures = new KList<>(); + + @Override + public void execute(Runnable runnable) { + futures.add(J.sfut(runnable)); + + if(futures.size() > 64) + { + while(futures.isNotEmpty()) + { + try { + futures.remove(0).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + } + } + + @Override + public String getName() { + return "Regenerating"; + } + }; + r.queue(js); + r.execute(sender); + } + + catch(Throwable e) + { + sender.sendMessage("Unable to parse view-distance"); + } + } + + return true; + } + + @Override + protected String getArgsUsage() { + return "[view-distance]"; + } +} diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 575fd0fbb..916a96008 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -407,7 +407,7 @@ public class IrisEngine implements Engine { } } } else { - getMantle().generateMatter(x >> 4, z >> 4, true); + getMantle().generateMatter(x >> 4, z >> 4, multicore); burst().burst(multicore, () -> getTerrainActuator().actuate(x, z, vblocks, multicore), () -> getBiomeActuator().actuate(x, z, vbiomes, multicore) @@ -419,7 +419,7 @@ public class IrisEngine implements Engine { ); getPostModifier().modify(x, z, vblocks, multicore); burst().burst(multicore, - () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, true), + () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore), () -> getDepositModifier().modify(x, z, vblocks, multicore) ); } diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index f9d261d46..a2d673596 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -34,6 +34,8 @@ import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.ChronoLatch; @@ -221,6 +223,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } private void spawnIn(Chunk c, boolean initial) { + if(initial) + { + energy += 1.2; + } + IrisBiome biome = getEngine().getSurfaceBiome(c); IrisRegion region = getEngine().getRegion(c); //@builder @@ -362,16 +369,17 @@ public class IrisWorldManager extends EngineAssignedWorldManager { @Override public void onChunkLoad(Chunk e, boolean generated) { - if (generated) { - energy += 1.2; - J.a(() -> spawnIn(e, true), RNG.r.i(5, 50)); - } else { - energy += 0.3; - } - + J.a(() -> getMantle().raiseFlag(e.getX(), e.getZ(), MantleFlag.INITIAL_SPAWNED, + () -> J.a(() -> spawnIn(e, true), RNG.r.i(5, 200)))); + energy += 0.3; fixEnergy(); } + public Mantle getMantle() + { + return getEngine().getMantle().getMantle(); + } + @Override public void chargeEnergy() { charge = M.ms() + 3000; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index 5871fd383..45cd6dc49 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -55,8 +55,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { return true; } } catch (Throwable e) { - e.printStackTrace(); - Iris.reportError(e); + } return false; diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java index a3f62ee25..5d270b3df 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine.data.chunk; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.util.data.IrisBiomeStorage; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; @@ -35,6 +36,8 @@ public class LinkedTerrainChunk implements TerrainChunk { private final IrisBiomeStorage biome3D; private ChunkData rawChunkData; private final BiomeGrid storage; + @Setter + private boolean unsafe = false; public LinkedTerrainChunk(World world) { this(null, Bukkit.createChunkData(world)); @@ -52,6 +55,12 @@ public class LinkedTerrainChunk implements TerrainChunk { @Override public BiomeBaseInjector getBiomeBaseInjector() { + + if(unsafe) + { + return (a,b,c,d) -> {}; + } + return (x, y, z, bb) -> INMS.get().forceBiomeInto(x, y, z, bb, storage); } diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java index 8cda901cd..62c64b4e2 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java @@ -34,6 +34,12 @@ public interface TerrainChunk extends BiomeGrid, ChunkData { return new LinkedTerrainChunk(world, grid); } + static TerrainChunk createUnsafe(World world, BiomeGrid grid) { + LinkedTerrainChunk ltc = new LinkedTerrainChunk(world, grid); + ltc.setUnsafe(true); + return ltc; + } + static TerrainChunk create(ChunkData raw, BiomeGrid grid) { return new LinkedTerrainChunk(grid, raw); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index b644f1c70..8d06c2b81 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -33,6 +33,8 @@ import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleChunk; +import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import org.bukkit.Chunk; @@ -189,7 +191,12 @@ public interface EngineMantle extends IObjectPlacer { int xx = i + x; int zz = j + z; burst.queue(() -> { - getComponents().forEach((f) -> generateMantleComponent(writer, xx, zz, f, c)); + MantleChunk mc = getMantle().getChunk(xx, zz); + + for(MantleComponent k : getComponents()) + { + generateMantleComponent(writer, xx, zz, k, c, mc); + } }); } } @@ -203,8 +210,8 @@ public interface EngineMantle extends IObjectPlacer { } } - default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer post) { - getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(writer, x, z, post)); + default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer post, MantleChunk mc) { + mc.raiseFlag(c.getFlag(), () -> c.generateLayer(writer, x, z, post)); } @ChunkCoordinates @@ -274,4 +281,14 @@ public interface EngineMantle extends IObjectPlacer { return pos; } + + default boolean queueRegenerate(int x, int z) + { + return false; // TODO: + } + + default boolean dequeueRegenerate(int x, int z) + { + return false;// TODO: + } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 2a946c845..98ea2c5c2 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -44,7 +44,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { public MantleJigsawComponent(EngineMantle engineMantle) { super(engineMantle, MantleFlag.JIGSAW); - cng = NoiseStyle.STATIC.create(new RNG()); + cng = NoiseStyle.STATIC.create(new RNG(engineMantle.getEngine().getWorld().seed() + 24398848585L)); } @Override diff --git a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index 11ec5f9a0..e9ae4e2d0 100644 --- a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -29,26 +29,35 @@ import com.volmit.iris.engine.framework.WrongEngineBroException; import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.IrisBiomeStorage; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.io.ReactiveFolder; +import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; import lombok.Data; import lombok.EqualsAndHashCode; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; +import org.bukkit.generator.WorldInfo; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.List; import java.util.Random; import java.util.concurrent.Semaphore; +import java.util.function.Consumer; @EqualsAndHashCode(callSuper = true) @Data @@ -130,6 +139,96 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun return false; } + @Override + public void injectChunkReplacement(World world, int x, int z, Consumer jobs) { + try { + if (lastSeed != world.getSeed()) { + Iris.warn("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed()); + lastSeed = world.getSeed(); + engine.getTarget().getWorld().seed(lastSeed); + engine.hotload(); + Iris.success("Updated Engine seed to " + lastSeed); + } + + loadLock.acquire(); + IrisBiomeStorage st = new IrisBiomeStorage(); + TerrainChunk tc = TerrainChunk.createUnsafe(world, st); + Hunk blocks = Hunk.view((ChunkData) tc); + Hunk biomes = Hunk.view((BiomeGrid) tc); + this.world.bind(world); + getEngine().generate(x * 16, z * 16, blocks, biomes, true); + Iris.debug("Regenerated " + x + " " + z); + int t = 0; + for(int i = getEngine().getHeight() >> 4; i >= 0; i--) + { + if(!world.isChunkLoaded(x, z)) + { + continue; + } + + Chunk c = world.getChunkAt(x, z); + for(Entity ee : c.getEntities()) + { + if(ee instanceof Player) + { + continue; + } + + J.s(ee::remove); + } + + J.s(() -> engine.getWorldManager().onChunkLoad(c, false)); + + int finalI = i; + jobs.accept(() -> { + + for(int xx = 0; xx < 16; xx++) + { + for(int yy = 0; yy < 16; yy++) + { + for(int zz = 0; zz < 16; zz++) + { + if(yy + (finalI << 4) >= engine.getHeight() || yy + (finalI << 4) < 0) + { + continue; + } + + c.getBlock(xx,yy + (finalI << 4),zz).setBlockData(tc.getBlockData(xx,yy + (finalI << 4),zz), false); + } + } + } + }); + } + + loadLock.release(); + } catch (WrongEngineBroException e) { + Iris.warn("Trying to generate with a shut-down engine! Did you reload? Attempting to resolve this..."); + + try { + setupEngine(); + Iris.success("Resolved! Should generate now!"); + } catch (Throwable fe) { + Iris.error("FATAL! Iris cannot generate in this world since it was reloaded! This will cause a crash, with missing chunks, so we're crashing right now!"); + Bukkit.shutdown(); + throw new RuntimeException(); + } + } catch (Throwable e) { + loadLock.release(); + Iris.error("======================================"); + e.printStackTrace(); + Iris.reportErrorChunk(x, z, e, "CHUNK"); + Iris.error("======================================"); + + ChunkData d = Bukkit.createChunkData(world); + + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData()); + } + } + } + } + @Override public void close() { withExclusiveControl(() -> { @@ -162,8 +261,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun @Override public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { - - try { if (lastSeed != world.getSeed()) { Iris.warn("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed()); @@ -245,4 +342,25 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun public boolean shouldGenerateStructures() { return false; } + + @Override + public boolean shouldGenerateNoise() { + return false; + } + + @Override + public boolean shouldGenerateSurface() { + return false; + } + + @Override + public boolean shouldGenerateBedrock() { + return false; + } + + @Nullable + @Override + public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) { + return null; + } } diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index 9aea5b8f2..e5f13fcb1 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -42,11 +42,13 @@ import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import lombok.Data; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator; import java.io.File; import java.io.IOException; +import java.util.function.Consumer; @Data public class HeadlessGenerator implements PlatformChunkGenerator { @@ -100,6 +102,11 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } } + @Override + public void injectChunkReplacement(World world, int x, int z, Consumer jobs) { + + } + @RegionCoordinates public void generateRegion(int x, int z) { generateRegion(x, z, null); diff --git a/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java index a11d6d348..eefcd6d47 100644 --- a/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java @@ -23,6 +23,9 @@ import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.framework.Hotloadable; import com.volmit.iris.util.data.DataProvider; +import org.bukkit.World; + +import java.util.function.Consumer; public interface PlatformChunkGenerator extends Hotloadable, DataProvider { Engine getEngine(); @@ -38,6 +41,8 @@ public interface PlatformChunkGenerator extends Hotloadable, DataProvider { return getEngine().getTarget(); } + void injectChunkReplacement(World world, int x, int z, Consumer jobs); + void close(); boolean isStudio(); diff --git a/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java b/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java index 63c2c4ac3..30f885e94 100644 --- a/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java +++ b/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java @@ -21,8 +21,9 @@ package com.volmit.iris.util.data; import com.volmit.iris.util.math.IrisMathHelper; import org.bukkit.block.Biome; import org.bukkit.generator.ChunkGenerator.BiomeGrid; +import org.jetbrains.annotations.NotNull; -public class IrisBiomeStorage { +public class IrisBiomeStorage implements BiomeGrid{ private static final int e; private static final int f; public static final int a; @@ -67,6 +68,12 @@ public class IrisBiomeStorage { } } + @NotNull + @Override + public Biome getBiome(int x, int z) { + return null; + } + public Biome getBiome(final int x, final int y, final int z) { final int l = x & IrisBiomeStorage.b; final int i2 = IrisMathHelper.clamp(y, 0, IrisBiomeStorage.c); @@ -74,6 +81,11 @@ public class IrisBiomeStorage { return this.g[i2 << IrisBiomeStorage.e + IrisBiomeStorage.e | j2 << IrisBiomeStorage.e | l]; } + @Override + public void setBiome(int x, int z, @NotNull Biome bio) { + + } + public void setBiome(final int x, final int y, final int z, final Biome biome) { final int l = x & IrisBiomeStorage.b; final int i2 = IrisMathHelper.clamp(y, 0, IrisBiomeStorage.c); diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index bac9f0d8f..b8ff5d5ca 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -41,6 +41,7 @@ import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.HyperLock; import com.volmit.iris.util.parallel.MultiBurst; +import org.bukkit.Chunk; import org.bukkit.util.Vector; import java.io.File; @@ -151,6 +152,10 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } + public void deleteChunk(int x, int z) { + get(x >> 5, z >> 5).delete(x & 31, z & 31); + } + /** * Check very quickly if a tectonic plate exists via cached or the file system * @@ -426,13 +431,19 @@ public class Mantle { if (file.exists()) { try { region = TectonicPlate.read(worldHeight, file); + + if(region.getX() != x || region.getZ() != z) + { + Iris.warn("Loaded Tectonic Plate " + x + "," + z + " but read it as " + region.getX() + "," + region.getZ() + "... Assuming " + x + "," + z); + } + loadedRegions.put(k, region); Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName()); } catch (Throwable e) { Iris.error("Failed to read Tectonic Plate " + file.getAbsolutePath() + " creating a new chunk instead."); Iris.reportError(e); e.printStackTrace(); - region = new TectonicPlate(worldHeight); + region = new TectonicPlate(worldHeight, x, z); loadedRegions.put(k, region); Iris.debug("Created new Tectonic Plate (Due to Load Failure) " + C.DARK_GREEN + x + " " + z); } @@ -440,7 +451,7 @@ public class Mantle { return region; } - region = new TectonicPlate(worldHeight); + region = new TectonicPlate(worldHeight, x, z); loadedRegions.put(k, region); Iris.debug("Created new Tectonic Plate " + C.DARK_GREEN + x + " " + z); return region; @@ -925,4 +936,8 @@ public class Mantle { public int getWorldHeight() { return worldHeight; } + + public MantleChunk getChunk(Chunk e) { + return getChunk(e.getX(), e.getZ()); + } } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index 162d514c6..56f69ffe7 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -25,6 +25,7 @@ import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.MatterSlice; import com.volmit.iris.util.matter.slices.ZoneMatter; +import lombok.Getter; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -39,6 +40,10 @@ import java.util.concurrent.atomic.AtomicReferenceArray; * Mantle Chunks are fully atomic & thread safe */ public class MantleChunk { + @Getter + private final int x; + @Getter + private final int z; private static final ZoneMatter zm = new ZoneMatter(); private final AtomicIntegerArray flags; private final AtomicReferenceArray sections; @@ -50,10 +55,12 @@ public class MantleChunk { * @param sectionHeight the height of the world in sections (blocks >> 4) */ @ChunkCoordinates - public MantleChunk(int sectionHeight) { + public MantleChunk(int sectionHeight, int x, int z) { sections = new AtomicReferenceArray<>(sectionHeight); flags = new AtomicIntegerArray(MantleFlag.values().length); features = new CopyOnWriteArrayList<>(); + this.x = x; + this.z = z; for (int i = 0; i < flags.length(); i++) { flags.set(i, 0); @@ -69,7 +76,7 @@ public class MantleChunk { * @throws ClassNotFoundException shit happens */ public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException { - this(sectionHeight); + this(sectionHeight, din.readByte(), din.readByte()); int s = din.readByte(); for (int i = 0; i < flags.length(); i++) { @@ -93,6 +100,13 @@ public class MantleChunk { flags.set(flag.ordinal(), f ? 1 : 0); } + public void raiseFlag(MantleFlag flag, Runnable r) { + if (!isFlagged(flag)) { + flag(flag, true); + r.run(); + } + } + public boolean isFlagged(MantleFlag flag) { return flags.get(flag.ordinal()) == 1; } @@ -163,6 +177,8 @@ public class MantleChunk { * @throws IOException shit happens */ public void write(DataOutputStream dos) throws IOException { + dos.writeByte(x); + dos.writeByte(z); dos.writeByte(sections.length()); for (int i = 0; i < flags.length(); i++) { diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java index 351882140..f608be664 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java @@ -24,7 +24,8 @@ public enum MantleFlag { OBJECT, UPDATE, JIGSAW, - FEATURE; + FEATURE, + INITIAL_SPAWNED; static StateList getStateList() { return new StateList(MantleFlag.values()); diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java index b25d5ef14..2c88c91d2 100644 --- a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java +++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -24,6 +24,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import lombok.Getter; import java.io.*; import java.util.concurrent.atomic.AtomicReferenceArray; @@ -38,14 +39,22 @@ public class TectonicPlate { private final int sectionHeight; private final AtomicReferenceArray chunks; + @Getter + private final int x; + + @Getter + private final int z; + /** * Create a new tectonic plate * * @param worldHeight the height of the world */ - public TectonicPlate(int worldHeight) { + public TectonicPlate(int worldHeight, int x, int z) { this.sectionHeight = worldHeight >> 4; this.chunks = new AtomicReferenceArray<>(1024); + this.x = x; + this.z = z; } /** @@ -57,8 +66,7 @@ public class TectonicPlate { * @throws ClassNotFoundException real shit bro */ public TectonicPlate(int worldHeight, DataInputStream din) throws IOException, ClassNotFoundException { - this(worldHeight); - + this(worldHeight, din.readInt(), din.readInt()); for (int i = 0; i < chunks.length(); i++) { if (din.readBoolean()) { chunks.set(i, new MantleChunk(sectionHeight, din)); @@ -132,7 +140,7 @@ public class TectonicPlate { MantleChunk chunk = get(x, z); if (chunk == null) { - chunk = new MantleChunk(sectionHeight); + chunk = new MantleChunk(sectionHeight, x&31, z&31); chunks.set(index(x, z), chunk); } @@ -167,6 +175,9 @@ public class TectonicPlate { * @throws IOException shit happens */ public void write(DataOutputStream dos) throws IOException { + dos.writeInt(x); + dos.writeInt(z); + for (int i = 0; i < chunks.length(); i++) { MantleChunk chunk = chunks.get(i); diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java index 83aa394c4..7375115da 100644 --- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java +++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java @@ -23,6 +23,7 @@ import com.volmit.iris.util.collection.KList; import lombok.Setter; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -41,6 +42,12 @@ public class BurstExecutor { @SuppressWarnings("UnusedReturnValue") public Future queue(Runnable r) { + if(!multicore) + { + r.run(); + return CompletableFuture.completedFuture(null); + } + synchronized (futures) { Future c = executor.submit(r); diff --git a/src/main/java/com/volmit/iris/util/scheduling/J.java b/src/main/java/com/volmit/iris/util/scheduling/J.java index e52475bd7..91ebe829c 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/J.java +++ b/src/main/java/com/volmit/iris/util/scheduling/J.java @@ -231,6 +231,15 @@ public class J { return f; } + public static CompletableFuture sfut(Runnable r, int delay) { + CompletableFuture f = new CompletableFuture(); + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> { + r.run(); + f.complete(null); + }, delay); + return f; + } + public static CompletableFuture afut(Runnable r) { CompletableFuture f = new CompletableFuture(); J.a(() -> {