mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Fix hotloading bricking the engine
This commit is contained in:
parent
32f34f1444
commit
51802f71a5
@ -50,10 +50,7 @@ import com.volmit.iris.util.math.RNG;
|
|||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.plugin.*;
|
import com.volmit.iris.util.plugin.*;
|
||||||
import com.volmit.iris.util.reflect.ShadeFix;
|
import com.volmit.iris.util.reflect.ShadeFix;
|
||||||
import com.volmit.iris.util.scheduling.GroupedExecutor;
|
import com.volmit.iris.util.scheduling.*;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
|
||||||
import com.volmit.iris.util.scheduling.ShurikenQueue;
|
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||||
@ -71,6 +68,7 @@ import java.io.*;
|
|||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
public class Iris extends VolmitPlugin implements Listener {
|
public class Iris extends VolmitPlugin implements Listener {
|
||||||
@ -707,4 +705,37 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void dump()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File fi = Iris.instance.getDataFile("dump", "td-" + new java.sql.Date(M.ms()) + ".txt");
|
||||||
|
FileOutputStream fos = new FileOutputStream(fi );
|
||||||
|
Map<Thread, StackTraceElement[]> f = Thread.getAllStackTraces();
|
||||||
|
PrintWriter pw = new PrintWriter(fos);
|
||||||
|
for(Thread i : f.keySet())
|
||||||
|
{
|
||||||
|
pw.println("========================================");
|
||||||
|
pw.println("Thread: '" + i.getName() + "' ID: " + i.getId() + " STATUS: " + i.getState().name());
|
||||||
|
|
||||||
|
for(StackTraceElement j : f.get(i))
|
||||||
|
{
|
||||||
|
pw.println(" @ " + j.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.println("========================================");
|
||||||
|
pw.println();
|
||||||
|
pw.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.close();
|
||||||
|
System.out.println("DUMPED! See " + fi.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,13 @@ import com.volmit.iris.util.decree.DecreeOrigin;
|
|||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Decree(name = "irisd", aliases = {"ird"}, description = "Basic Command")
|
@Decree(name = "irisd", aliases = {"ird"}, description = "Basic Command")
|
||||||
public class DecIris implements DecreeExecutor {
|
public class DecIris implements DecreeExecutor {
|
||||||
|
@ -65,6 +65,8 @@ import org.bukkit.generator.BlockPopulator;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@ -287,12 +289,11 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
J.car(art);
|
|
||||||
closed = true;
|
closed = true;
|
||||||
|
J.car(art);
|
||||||
getWorldManager().close();
|
getWorldManager().close();
|
||||||
getTarget().close();
|
getTarget().close();
|
||||||
saveEngineData();
|
saveEngineData();
|
||||||
getMantle().close();
|
|
||||||
getTerrainActuator().close();
|
getTerrainActuator().close();
|
||||||
getDecorantActuator().close();
|
getDecorantActuator().close();
|
||||||
getBiomeActuator().close();
|
getBiomeActuator().close();
|
||||||
@ -300,6 +301,8 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
getRavineModifier().close();
|
getRavineModifier().close();
|
||||||
getCaveModifier().close();
|
getCaveModifier().close();
|
||||||
getPostModifier().close();
|
getPostModifier().close();
|
||||||
|
getMantle().close();
|
||||||
|
Iris.debug("Engine Fully Shutdown!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -355,7 +358,12 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
@Override
|
||||||
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<Biome> vbiomes, boolean multicore) {
|
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<Biome> vbiomes, boolean multicore) throws WrongEngineBroException {
|
||||||
|
if(closed)
|
||||||
|
{
|
||||||
|
throw new WrongEngineBroException();
|
||||||
|
}
|
||||||
|
|
||||||
context.touch();
|
context.touch();
|
||||||
getEngineData().getStatistics().generatedChunk();
|
getEngineData().getStatistics().generatedChunk();
|
||||||
try {
|
try {
|
||||||
|
@ -139,7 +139,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
double modifyZ(double z);
|
double modifyZ(double z);
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes, boolean multicore);
|
void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes, boolean multicore) throws WrongEngineBroException;
|
||||||
|
|
||||||
EngineMetrics getMetrics();
|
EngineMetrics getMetrics();
|
||||||
|
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.engine.framework;
|
||||||
|
|
||||||
|
public class WrongEngineBroException extends Exception {
|
||||||
|
}
|
@ -21,11 +21,13 @@ package com.volmit.iris.engine.platform;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
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.WrongEngineBroException;
|
||||||
import com.volmit.iris.engine.object.common.IrisWorld;
|
import com.volmit.iris.engine.object.common.IrisWorld;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.io.ReactiveFolder;
|
import com.volmit.iris.util.io.ReactiveFolder;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.Looper;
|
import com.volmit.iris.util.scheduling.Looper;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -40,8 +42,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
||||||
|
private static final int HOTLOAD_LOCKS = 1000000;
|
||||||
private final EngineProvider provider;
|
private final EngineProvider provider;
|
||||||
private final IrisWorld world;
|
private final IrisWorld world;
|
||||||
private final File dataLocation;
|
private final File dataLocation;
|
||||||
@ -50,11 +54,13 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
private final KList<BlockPopulator> populators;
|
private final KList<BlockPopulator> populators;
|
||||||
private final ChronoLatch hotloadChecker;
|
private final ChronoLatch hotloadChecker;
|
||||||
private final Looper hotloader;
|
private final Looper hotloader;
|
||||||
|
private final Semaphore hotloadLock;
|
||||||
private final boolean studio;
|
private final boolean studio;
|
||||||
|
|
||||||
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
|
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
|
||||||
populators = new KList<>();
|
populators = new KList<>();
|
||||||
this.world = world;
|
this.world = world;
|
||||||
|
this.hotloadLock = new Semaphore(HOTLOAD_LOCKS);
|
||||||
this.hotloadChecker = new ChronoLatch(1000, false);
|
this.hotloadChecker = new ChronoLatch(1000, false);
|
||||||
this.studio = studio;
|
this.studio = studio;
|
||||||
this.dataLocation = dataLocation;
|
this.dataLocation = dataLocation;
|
||||||
@ -78,9 +84,12 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
|
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Engine getEngine() {
|
public synchronized Engine getEngine() {
|
||||||
|
synchronized (provider)
|
||||||
|
{
|
||||||
return provider.getEngine();
|
return provider.getEngine();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHeadless() {
|
public boolean isHeadless() {
|
||||||
@ -89,9 +98,12 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
synchronized (provider)
|
||||||
|
{
|
||||||
hotloader.interrupt();
|
hotloader.interrupt();
|
||||||
provider.close();
|
provider.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStudio() {
|
public boolean isStudio() {
|
||||||
@ -100,19 +112,36 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hotload() {
|
public void hotload() {
|
||||||
|
J.aBukkit(() -> {
|
||||||
|
try {
|
||||||
|
hotloadLock.acquire(HOTLOAD_LOCKS);
|
||||||
initialize();
|
initialize();
|
||||||
|
hotloadLock.release(HOTLOAD_LOCKS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
|
synchronized (provider)
|
||||||
|
{
|
||||||
provider.provideEngine(world, dimensionKey, dataLocation, isStudio(), (e) -> {
|
provider.provideEngine(world, dimensionKey, dataLocation, isStudio(), (e) -> {
|
||||||
populators.clear();
|
populators.clear();
|
||||||
populators.add((BlockPopulator) e);
|
populators.add((BlockPopulator) e);
|
||||||
folder.checkIgnore();
|
folder.checkIgnore();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@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 {
|
||||||
|
hotloadLock.acquire();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Iris.debug("Generated " + x + " " + z);
|
Iris.debug("Generated " + x + " " + z);
|
||||||
PrecisionStopwatch ps = PrecisionStopwatch.start();
|
PrecisionStopwatch ps = PrecisionStopwatch.start();
|
||||||
@ -121,8 +150,11 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
|
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
|
||||||
this.world.bind(world);
|
this.world.bind(world);
|
||||||
getEngine().generate(x * 16, z * 16, blocks, biomes, true);
|
getEngine().generate(x * 16, z * 16, blocks, biomes, true);
|
||||||
|
hotloadLock.release();
|
||||||
return tc.getRaw();
|
return tc.getRaw();
|
||||||
} catch (Throwable e) {
|
}
|
||||||
|
|
||||||
|
catch (Throwable e) {
|
||||||
Iris.error("======================================");
|
Iris.error("======================================");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Iris.reportErrorChunk(x, z, e, "CHUNK");
|
Iris.reportErrorChunk(x, z, e, "CHUNK");
|
||||||
@ -136,8 +168,10 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hotloadLock.release();
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@ -179,6 +179,11 @@ public class Mantle {
|
|||||||
.get(x & 15, y & 15, z & 15);
|
.get(x & 15, y & 15, z & 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isClosed()
|
||||||
|
{
|
||||||
|
return closed.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the Mantle. By closing the mantle, you can no longer read or write
|
* Closes the Mantle. By closing the mantle, you can no longer read or write
|
||||||
* any data to the mantle or it's Tectonic Plates. Closing will also flush any
|
* any data to the mantle or it's Tectonic Plates. Closing will also flush any
|
||||||
|
Loading…
x
Reference in New Issue
Block a user