mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 10:12:53 +00:00
Prepatch
This commit is contained in:
parent
6dc3e74607
commit
7b6405fba7
@ -167,6 +167,7 @@ shadowJar
|
|||||||
include(dependency('io.papermc:paperlib'))
|
include(dependency('io.papermc:paperlib'))
|
||||||
include(dependency('com.dfsek:Paralithic'))
|
include(dependency('com.dfsek:Paralithic'))
|
||||||
include(dependency('net.kyori:'))
|
include(dependency('net.kyori:'))
|
||||||
|
include(dependency('com.github.Querz:NBT'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +186,7 @@ dependencies {
|
|||||||
implementation "net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT"
|
implementation "net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT"
|
||||||
implementation "net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT"
|
implementation "net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT"
|
||||||
implementation 'net.kyori:adventure-api:4.8.1'
|
implementation 'net.kyori:adventure-api:4.8.1'
|
||||||
|
implementation 'com.github.Querz:NBT:6.1'
|
||||||
|
|
||||||
// Dynamically Loaded
|
// Dynamically Loaded
|
||||||
implementation 'io.timeandspace:smoothie-map:2.0.2'
|
implementation 'io.timeandspace:smoothie-map:2.0.2'
|
||||||
|
@ -128,7 +128,8 @@ public class IrisToolbelt {
|
|||||||
return pregenerate(task, new HeadlessPregenMethod(((HeadlessGenerator) gen).getWorld(), (HeadlessGenerator) gen));
|
return pregenerate(task, new HeadlessPregenMethod(((HeadlessGenerator) gen).getWorld(), (HeadlessGenerator) gen));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(), IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())));
|
return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(),
|
||||||
|
IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,10 @@ import com.volmit.iris.util.scheduling.J;
|
|||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import net.minecraft.world.level.block.state.IBlockData;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -405,8 +408,21 @@ public class IrisEngine implements Engine {
|
|||||||
context.touch();
|
context.touch();
|
||||||
getEngineData().getStatistics().generatedChunk();
|
getEngineData().getStatistics().generatedChunk();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
|
Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
|
||||||
|
|
||||||
|
if(multicore)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
for (int j = 0; j < 16; j++) {
|
||||||
|
blocks.set(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
getMantle().generateMatter(x >> 4, z >> 4, multicore);
|
getMantle().generateMatter(x >> 4, z >> 4, multicore);
|
||||||
|
|
||||||
burst().burst(multicore,
|
burst().burst(multicore,
|
||||||
@ -425,6 +441,9 @@ public class IrisEngine implements Engine {
|
|||||||
() -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore),
|
() -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore),
|
||||||
() -> getDepositModifier().modify(x, z, vblocks, multicore)
|
() -> getDepositModifier().modify(x, z, vblocks, multicore)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getMetrics().getTotal().put(p.getMilliseconds());
|
getMetrics().getTotal().put(p.getMilliseconds());
|
||||||
generated.incrementAndGet();
|
generated.incrementAndGet();
|
||||||
|
@ -18,107 +18,82 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine.data.cache;
|
package com.volmit.iris.engine.data.cache;
|
||||||
|
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.scheduling.IrisLock;
|
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class AtomicCache<T> {
|
public class AtomicCache<T> {
|
||||||
private transient volatile T t;
|
private transient final AtomicReference<T> t;
|
||||||
private transient volatile long a;
|
private transient final AtomicBoolean set;
|
||||||
private transient volatile int validations;
|
private transient final ReentrantLock lock;
|
||||||
private final IrisLock check;
|
private transient final boolean nullSupport;
|
||||||
private final IrisLock time;
|
|
||||||
private final IrisLock write;
|
|
||||||
private final boolean nullSupport;
|
|
||||||
|
|
||||||
public AtomicCache() {
|
public AtomicCache() {
|
||||||
this(false);
|
this(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AtomicCache(boolean nullSupport) {
|
public AtomicCache(boolean nullSupport) {
|
||||||
|
set = nullSupport ? new AtomicBoolean() : null;
|
||||||
|
t = new AtomicReference<>();
|
||||||
|
lock = new ReentrantLock();
|
||||||
this.nullSupport = nullSupport;
|
this.nullSupport = nullSupport;
|
||||||
check = new IrisLock("Check");
|
|
||||||
write = new IrisLock("Write");
|
|
||||||
time = new IrisLock("Time");
|
|
||||||
validations = 0;
|
|
||||||
a = -1;
|
|
||||||
t = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
check.lock();
|
t.set(null);
|
||||||
write.lock();
|
|
||||||
time.lock();
|
if(nullSupport)
|
||||||
a = -1;
|
{
|
||||||
t = null;
|
set.set(false);
|
||||||
time.unlock();
|
}
|
||||||
write.unlock();
|
|
||||||
check.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T aquire(Supplier<T> t) {
|
public T aquire(Supplier<T> t) {
|
||||||
if (nullSupport) {
|
if(this.t.get() != null)
|
||||||
return aquireNull(t);
|
{
|
||||||
|
return this.t.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.t != null && validations > 1000) {
|
else if(nullSupport && set.get())
|
||||||
return this.t;
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.t != null && M.ms() - a > 1000) {
|
lock.lock();
|
||||||
if (this.t != null) {
|
|
||||||
//noinspection NonAtomicOperationOnVolatileField
|
if(this.t.get() != null)
|
||||||
validations++;
|
{
|
||||||
|
lock.unlock();
|
||||||
|
return this.t.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.t;
|
else if(nullSupport && set.get())
|
||||||
|
{
|
||||||
|
lock.unlock();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
check.lock();
|
try
|
||||||
|
{
|
||||||
|
this.t.set(t.get());
|
||||||
|
|
||||||
if (this.t == null) {
|
if(nullSupport)
|
||||||
write.lock();
|
{
|
||||||
this.t = t.get();
|
set.set(true);
|
||||||
|
}
|
||||||
time.lock();
|
}
|
||||||
|
|
||||||
if (a == -1) {
|
catch(Throwable e)
|
||||||
a = M.ms();
|
{
|
||||||
}
|
Iris.error("Atomic cache failure!");
|
||||||
|
e.printStackTrace();
|
||||||
time.unlock();
|
}
|
||||||
write.unlock();
|
|
||||||
}
|
lock.unlock();
|
||||||
|
|
||||||
check.unlock();
|
return t.get();
|
||||||
return this.t;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T aquireNull(Supplier<T> t) {
|
|
||||||
if (validations > 1000) {
|
|
||||||
return this.t;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (M.ms() - a > 1000) {
|
|
||||||
//noinspection NonAtomicOperationOnVolatileField
|
|
||||||
validations++;
|
|
||||||
return this.t;
|
|
||||||
}
|
|
||||||
|
|
||||||
check.lock();
|
|
||||||
write.lock();
|
|
||||||
this.t = t.get();
|
|
||||||
|
|
||||||
time.lock();
|
|
||||||
|
|
||||||
if (a == -1) {
|
|
||||||
a = M.ms();
|
|
||||||
}
|
|
||||||
|
|
||||||
time.unlock();
|
|
||||||
write.unlock();
|
|
||||||
check.unlock();
|
|
||||||
return this.t;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,8 +198,8 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
|||||||
private final transient AtomicCache<KMap<String, IrisBiomeGeneratorLink>> genCache = new AtomicCache<>();
|
private final transient AtomicCache<KMap<String, IrisBiomeGeneratorLink>> genCache = new AtomicCache<>();
|
||||||
private final transient AtomicCache<KMap<String, Integer>> genCacheMax = new AtomicCache<>();
|
private final transient AtomicCache<KMap<String, Integer>> genCacheMax = new AtomicCache<>();
|
||||||
private final transient AtomicCache<KMap<String, Integer>> genCacheMin = new AtomicCache<>();
|
private final transient AtomicCache<KMap<String, Integer>> genCacheMin = new AtomicCache<>();
|
||||||
private final transient AtomicCache<KList<IrisObjectPlacement>> surfaceObjectsCache = new AtomicCache<>(false);
|
private final transient AtomicCache<KList<IrisObjectPlacement>> surfaceObjectsCache = new AtomicCache<>();
|
||||||
private final transient AtomicCache<KList<IrisObjectPlacement>> carveObjectsCache = new AtomicCache<>(false);
|
private final transient AtomicCache<KList<IrisObjectPlacement>> carveObjectsCache = new AtomicCache<>();
|
||||||
private final transient AtomicCache<Color> cacheColor = new AtomicCache<>();
|
private final transient AtomicCache<Color> cacheColor = new AtomicCache<>();
|
||||||
private final transient AtomicCache<Color> cacheColorObjectDensity = new AtomicCache<>();
|
private final transient AtomicCache<Color> cacheColorObjectDensity = new AtomicCache<>();
|
||||||
private final transient AtomicCache<Color> cacheColorDecoratorLoad = new AtomicCache<>();
|
private final transient AtomicCache<Color> cacheColorDecoratorLoad = new AtomicCache<>();
|
||||||
|
@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.project.loader.IrisData;
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
import com.volmit.iris.engine.platform.HeadlessGenerator;
|
import com.volmit.iris.engine.platform.HeadlessGenerator;
|
||||||
@ -65,8 +66,24 @@ public class HeadlessWorld {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
public HeadlessGenerator generate() {
|
public HeadlessGenerator generate() {
|
||||||
return new HeadlessGenerator(this);
|
Engine e = null;
|
||||||
|
|
||||||
|
if(getWorld().tryGetRealWorld())
|
||||||
|
{
|
||||||
|
if(IrisToolbelt.isIrisWorld(getWorld().realWorld()))
|
||||||
|
{
|
||||||
|
e = IrisToolbelt.access(getWorld().realWorld()).getEngine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e != null)
|
||||||
|
{
|
||||||
|
Iris.info("Using Existing Engine " + getWorld().name() + " for Headless Pregeneration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return e != null ? new HeadlessGenerator(this, e) : new HeadlessGenerator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public World load() {
|
public World load() {
|
||||||
@ -81,7 +98,8 @@ public class HeadlessWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static HeadlessWorld from(World world) {
|
public static HeadlessWorld from(World world) {
|
||||||
return new HeadlessWorld(world.getName(), IrisToolbelt.access(world).getEngine().getTarget().getDimension(), world.getSeed());
|
return new HeadlessWorld(world.getName(), IrisToolbelt.access(world)
|
||||||
|
.getEngine().getTarget().getDimension(), world.getSeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HeadlessWorld from(String name, String dimension, long seed) {
|
public static HeadlessWorld from(String name, String dimension, long seed) {
|
||||||
|
@ -24,6 +24,7 @@ import com.volmit.iris.util.collection.KList;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -61,6 +62,24 @@ public class IrisWorld {
|
|||||||
.environment(world.getEnvironment());
|
.environment(world.getEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean tryGetRealWorld()
|
||||||
|
{
|
||||||
|
if(hasRealWorld())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
World w = Bukkit.getWorld(name);
|
||||||
|
|
||||||
|
if(w != null)
|
||||||
|
{
|
||||||
|
realWorld = w;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasRealWorld() {
|
public boolean hasRealWorld() {
|
||||||
return realWorld != null;
|
return realWorld != null;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,8 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
|
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(lastSeed != world.getSeed())
|
if(lastSeed != world.getSeed())
|
||||||
{
|
{
|
||||||
|
@ -24,16 +24,20 @@ import com.volmit.iris.core.nms.INMS;
|
|||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.engine.IrisEngine;
|
import com.volmit.iris.engine.IrisEngine;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
import com.volmit.iris.engine.data.chunk.MCATerrainChunk;
|
import com.volmit.iris.engine.data.chunk.MCATerrainChunk;
|
||||||
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.framework.EngineTarget;
|
import com.volmit.iris.engine.framework.EngineTarget;
|
||||||
|
import com.volmit.iris.engine.framework.WrongEngineBroException;
|
||||||
import com.volmit.iris.engine.object.common.HeadlessWorld;
|
import com.volmit.iris.engine.object.common.HeadlessWorld;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.nbt.mca.MCAFile;
|
import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||||
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||||
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||||
@ -56,12 +60,17 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
private final NBTWorld writer;
|
private final NBTWorld writer;
|
||||||
private final MultiBurst burst;
|
private final MultiBurst burst;
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
|
private final long rkey = RNG.r.lmax();
|
||||||
|
|
||||||
public HeadlessGenerator(HeadlessWorld world) {
|
public HeadlessGenerator(HeadlessWorld world) {
|
||||||
|
this(world, new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), world.isStudio()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeadlessGenerator(HeadlessWorld world, Engine engine) {
|
||||||
|
this.engine = engine;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
burst = MultiBurst.burst;
|
burst = MultiBurst.burst;
|
||||||
writer = new NBTWorld(world.getWorld().worldFolder());
|
writer = new NBTWorld(world.getWorld().worldFolder());
|
||||||
engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
@ -79,6 +88,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
getEngine().generate(x * 16, z * 16,
|
getEngine().generate(x * 16, z * 16,
|
||||||
Hunk.view((ChunkGenerator.ChunkData) tc), Hunk.view((ChunkGenerator.BiomeGrid) tc),
|
Hunk.view((ChunkGenerator.ChunkData) tc), Hunk.view((ChunkGenerator.BiomeGrid) tc),
|
||||||
false);
|
false);
|
||||||
|
chunk.cleanupPalettesAndBlockStates();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.error("======================================");
|
Iris.error("======================================");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -102,7 +112,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
@RegionCoordinates
|
@RegionCoordinates
|
||||||
public void generateRegion(int x, int z, PregenListener listener) {
|
public void generateRegion(int x, int z, PregenListener listener) {
|
||||||
BurstExecutor e = burst.burst(1024);
|
BurstExecutor e = burst.burst(1024);
|
||||||
MCAFile f = writer.getMCA(x, x);
|
MCAFile f = writer.getMCA(x, z);
|
||||||
PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> {
|
PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onChunkGenerating(ii, jj);
|
listener.onChunkGenerating(ii, jj);
|
||||||
@ -132,7 +142,6 @@ public class HeadlessGenerator implements PlatformChunkGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
getEngine().close();
|
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,21 +28,49 @@ import com.volmit.iris.util.math.M;
|
|||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import com.volmit.iris.util.nbt.tag.StringTag;
|
import com.volmit.iris.util.nbt.tag.StringTag;
|
||||||
import com.volmit.iris.util.parallel.HyperLock;
|
import com.volmit.iris.util.parallel.HyperLock;
|
||||||
import com.volmit.iris.util.scheduling.IrisLock;
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import javax.management.RuntimeErrorException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class NBTWorld {
|
public class NBTWorld {
|
||||||
private static final BlockData AIR = B.get("AIR");
|
private static final BlockData AIR = B.get("AIR");
|
||||||
private static final Map<String, CompoundTag> blockDataCache = new KMap<>();
|
private static final Map<BlockData, CompoundTag> blockDataCache = new KMap<>();
|
||||||
|
private static final Function<BlockData, CompoundTag> BLOCK_DATA_COMPUTE = (blockData) -> {
|
||||||
|
CompoundTag s = new CompoundTag();
|
||||||
|
String data = blockData.getAsString(true);
|
||||||
|
NamespacedKey key = blockData.getMaterial().getKey();
|
||||||
|
s.putString("Name", key.getNamespace() + ":" + key.getKey());
|
||||||
|
|
||||||
|
if (data.contains("[")) {
|
||||||
|
String raw = data.split("\\Q[\\E")[1].replaceAll("\\Q]\\E", "");
|
||||||
|
CompoundTag props = new CompoundTag();
|
||||||
|
if (raw.contains(",")) {
|
||||||
|
for (String i : raw.split("\\Q,\\E")) {
|
||||||
|
String[] m = i.split("\\Q=\\E");
|
||||||
|
String k = m[0];
|
||||||
|
String v = m[1];
|
||||||
|
props.put(k, new StringTag(v));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String[] m = raw.split("\\Q=\\E");
|
||||||
|
String k = m[0];
|
||||||
|
String v = m[1];
|
||||||
|
props.put(k, new StringTag(v));
|
||||||
|
}
|
||||||
|
s.put("Properties", props);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
};
|
||||||
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
|
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
|
||||||
private final KMap<Long, MCAFile> loadedRegions;
|
private final KMap<Long, MCAFile> loadedRegions;
|
||||||
private final HyperLock hyperLock = new HyperLock();
|
private final HyperLock hyperLock = new HyperLock();
|
||||||
@ -184,38 +212,8 @@ public class NBTWorld {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompoundTag getCompound(BlockData blockData) {
|
public static CompoundTag getCompound(BlockData bd) {
|
||||||
String data = blockData.getAsString(true);
|
return blockDataCache.computeIfAbsent(bd, BLOCK_DATA_COMPUTE).clone();
|
||||||
|
|
||||||
if (blockDataCache.containsKey(data)) {
|
|
||||||
return blockDataCache.get(data).clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
CompoundTag s = new CompoundTag();
|
|
||||||
NamespacedKey key = blockData.getMaterial().getKey();
|
|
||||||
s.putString("Name", key.getNamespace() + ":" + key.getKey());
|
|
||||||
|
|
||||||
if (data.contains("[")) {
|
|
||||||
String raw = data.split("\\Q[\\E")[1].replaceAll("\\Q]\\E", "");
|
|
||||||
CompoundTag props = new CompoundTag();
|
|
||||||
if (raw.contains(",")) {
|
|
||||||
for (String i : raw.split("\\Q,\\E")) {
|
|
||||||
String[] m = i.split("\\Q=\\E");
|
|
||||||
String k = m[0];
|
|
||||||
String v = m[1];
|
|
||||||
props.put(k, new StringTag(v));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String[] m = raw.split("\\Q=\\E");
|
|
||||||
String k = m[0];
|
|
||||||
String v = m[1];
|
|
||||||
props.put(k, new StringTag(v));
|
|
||||||
}
|
|
||||||
s.put("Properties", props);
|
|
||||||
}
|
|
||||||
|
|
||||||
blockDataCache.put(data, s.clone());
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockData getBlockData(int x, int y, int z) {
|
public BlockData getBlockData(int x, int y, int z) {
|
||||||
@ -275,6 +273,13 @@ public class NBTWorld {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Chunk getNewChunk(MCAFile mca, int x, int z) {
|
||||||
|
Chunk c = Chunk.newChunk();
|
||||||
|
mca.setChunk(x & 31, z & 31, c);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
public long getIdleDuration(int x, int z) {
|
public long getIdleDuration(int x, int z) {
|
||||||
return hyperLock.withResult(x, z, () -> {
|
return hyperLock.withResult(x, z, () -> {
|
||||||
Long l = lastUse.get(Cache.key(x, z));
|
Long l = lastUse.get(Cache.key(x, z));
|
||||||
|
@ -25,6 +25,7 @@ import com.volmit.iris.util.nbt.tag.CompoundTag;
|
|||||||
import com.volmit.iris.util.nbt.tag.ListTag;
|
import com.volmit.iris.util.nbt.tag.ListTag;
|
||||||
import com.volmit.iris.util.nbt.tag.LongArrayTag;
|
import com.volmit.iris.util.nbt.tag.LongArrayTag;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
|
import net.minecraft.world.level.chunk.DataPaletteGlobal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -148,7 +149,7 @@ public class Section {
|
|||||||
* @param blockZ The z-coordinate of the block in this Section
|
* @param blockZ The z-coordinate of the block in this Section
|
||||||
* @return The block state data of this block.
|
* @return The block state data of this block.
|
||||||
*/
|
*/
|
||||||
public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
|
public synchronized CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
|
||||||
try {
|
try {
|
||||||
int index = getBlockIndex(blockX, blockY, blockZ);
|
int index = getBlockIndex(blockX, blockY, blockZ);
|
||||||
int paletteIndex = getPaletteIndex(index);
|
int paletteIndex = getPaletteIndex(index);
|
||||||
@ -172,7 +173,7 @@ public class Section {
|
|||||||
* This option should only be used moderately to avoid unnecessary recalculation of the palette indices.
|
* This option should only be used moderately to avoid unnecessary recalculation of the palette indices.
|
||||||
* Recalculating the Palette should only be executed once right before saving the Section to file.
|
* Recalculating the Palette should only be executed once right before saving the Section to file.
|
||||||
*/
|
*/
|
||||||
public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
|
public synchronized void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
|
||||||
int paletteIndex = addToPalette(state);
|
int paletteIndex = addToPalette(state);
|
||||||
int paletteSizeBefore = palette.size();
|
int paletteSizeBefore = palette.size();
|
||||||
//power of 2 --> bits must increase, but only if the palette size changed
|
//power of 2 --> bits must increase, but only if the palette size changed
|
||||||
@ -184,7 +185,6 @@ public class Section {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPaletteIndex(getBlockIndex(blockX, blockY, blockZ), paletteIndex, blockStates);
|
setPaletteIndex(getBlockIndex(blockX, blockY, blockZ), paletteIndex, blockStates);
|
||||||
|
|
||||||
if (cleanup) {
|
if (cleanup) {
|
||||||
cleanupPaletteAndBlockStates();
|
cleanupPaletteAndBlockStates();
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ public class Section {
|
|||||||
* @param blockStateIndex The index of the block in this section, ranging from 0-4095.
|
* @param blockStateIndex The index of the block in this section, ranging from 0-4095.
|
||||||
* @return The index of the block data in the palette.
|
* @return The index of the block data in the palette.
|
||||||
*/
|
*/
|
||||||
public int getPaletteIndex(int blockStateIndex) {
|
public synchronized int getPaletteIndex(int blockStateIndex) {
|
||||||
int bits = blockStates.length() >> 6;
|
int bits = blockStates.length() >> 6;
|
||||||
|
|
||||||
if (dataVersion < 2527) {
|
if (dataVersion < 2527) {
|
||||||
@ -251,7 +251,7 @@ public class Section {
|
|||||||
*
|
*
|
||||||
* @return The palette of this Section.
|
* @return The palette of this Section.
|
||||||
*/
|
*/
|
||||||
public ListTag<CompoundTag> getPalette() {
|
public synchronized ListTag<CompoundTag> getPalette() {
|
||||||
return palette;
|
return palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ public class Section {
|
|||||||
/**
|
/**
|
||||||
* @return The indices of the block states of this Section.
|
* @return The indices of the block states of this Section.
|
||||||
*/
|
*/
|
||||||
public AtomicLongArray getBlockStates() {
|
public synchronized AtomicLongArray getBlockStates() {
|
||||||
return blockStates;
|
return blockStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,7 +431,7 @@ public class Section {
|
|||||||
* @param y The Y-value of this Section
|
* @param y The Y-value of this Section
|
||||||
* @return A reference to the raw CompoundTag this Section is based on
|
* @return A reference to the raw CompoundTag this Section is based on
|
||||||
*/
|
*/
|
||||||
public CompoundTag updateHandle(int y) {
|
public synchronized CompoundTag updateHandle(int y) {
|
||||||
data.putByte("Y", (byte) y);
|
data.putByte("Y", (byte) y);
|
||||||
if (palette != null) {
|
if (palette != null) {
|
||||||
data.put("Palette", palette);
|
data.put("Palette", palette);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user