mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-19 15:09:18 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3abe671851 | ||
|
|
e164a3bb5c | ||
|
|
4dfb4441e4 | ||
|
|
e686f67453 | ||
|
|
e2eed4812a | ||
|
|
1737833bfe | ||
|
|
a4c5f46c37 | ||
|
|
025fa833c4 | ||
|
|
98cc82cc3d | ||
|
|
298365f588 | ||
|
|
90e5720e2e | ||
|
|
7cd43791f4 | ||
|
|
a251d192ad | ||
|
|
abfff28f43 | ||
|
|
fbdae4c928 | ||
|
|
526efd3ae1 |
@@ -60,7 +60,7 @@ val serverMaxHeap = "10G"
|
||||
val additionalFlags = "-XX:+AlwaysPreTouch"
|
||||
//Valid values are: none, truecolor, indexed256, indexed16, indexed8
|
||||
val color = "truecolor"
|
||||
val errorReporting = findProperty("errorReporting") as Boolean? ?: false
|
||||
val errorReporting = "true" == findProperty("errorReporting")
|
||||
|
||||
val nmsBindings = mapOf(
|
||||
"v1_21_R6" to "1.21.10-R0.1-SNAPSHOT",
|
||||
@@ -109,19 +109,21 @@ nmsBindings.forEach { (key, value) ->
|
||||
}
|
||||
}
|
||||
|
||||
val included: Configuration by configurations.creating
|
||||
val jarJar: Configuration by configurations.creating
|
||||
dependencies {
|
||||
for (key in nmsBindings.keys) {
|
||||
implementation(project(":nms:$key", "reobf"))
|
||||
included(project(":nms:$key", "reobf"))
|
||||
}
|
||||
implementation(project(":core", "shadow"))
|
||||
included(project(":core", "shadow"))
|
||||
jarJar(project(":core:agent"))
|
||||
}
|
||||
|
||||
tasks {
|
||||
jar {
|
||||
inputs.files(included)
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
from(jarJar, configurations.runtimeClasspath.map { it.resolve().map(::zipTree) })
|
||||
from(jarJar, provider { included.resolve().map(::zipTree) })
|
||||
archiveFileName.set("Iris-${project.version}.jar")
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ java {
|
||||
}
|
||||
|
||||
sentry {
|
||||
url = "http://sentry.volmit.com:8080/"
|
||||
url = "http://sentry.volmit.com:8080"
|
||||
autoInstallation.enabled = false
|
||||
includeSourceContext = true
|
||||
|
||||
@@ -175,6 +175,10 @@ tasks {
|
||||
relocate("io.github.slimjar", "$lib.slimjar")
|
||||
exclude("modules/loader-agent.isolated-jar")
|
||||
}
|
||||
|
||||
sentryCollectSourcesJava {
|
||||
dependsOn(generateTemplates)
|
||||
}
|
||||
}
|
||||
|
||||
val templateSource = file("src/main/templates")
|
||||
@@ -185,10 +189,10 @@ val generateTemplates = tasks.register<Copy>("generateTemplates") {
|
||||
"commit" to provider {
|
||||
val res = runCatching { project.extensions.getByType<Grgit>().head().id }
|
||||
res.getOrDefault("")
|
||||
.takeIf { it.length == 40 } ?: {
|
||||
logger.error("Git commit hash not found", res.exceptionOrNull())
|
||||
.takeIf { it.length == 40 } ?: run {
|
||||
this.logger.error("Git commit hash not found", res.exceptionOrNull())
|
||||
"unknown"
|
||||
}()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.volmit.iris.core.link.IrisPapiExpansion;
|
||||
import com.volmit.iris.core.link.MultiverseCoreLink;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
@@ -43,7 +42,6 @@ import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.exceptions.IrisException;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.function.NastyRunnable;
|
||||
import com.volmit.iris.util.io.FileWatcher;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
@@ -53,7 +51,6 @@ import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.misc.Bindings;
|
||||
import com.volmit.iris.util.misc.SlimJar;
|
||||
import com.volmit.iris.util.misc.getHardware;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.plugin.IrisService;
|
||||
import com.volmit.iris.util.plugin.VolmitPlugin;
|
||||
@@ -84,9 +81,6 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||
import static com.volmit.iris.core.safeguard.ServerBootSFG.passedserversoftware;
|
||||
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
public class Iris extends VolmitPlugin implements Listener {
|
||||
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
||||
@@ -308,9 +302,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
public static void info(String format, Object... args) {
|
||||
msg(C.WHITE + String.format(format, args));
|
||||
}
|
||||
public static void safeguard(String format, Object... args) {
|
||||
msg(C.RESET + String.format(format, args));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void later(NastyRunnable object) {
|
||||
@@ -449,9 +440,9 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
IO.delete(new File("iris"));
|
||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||
ServerConfigurator.configure();
|
||||
IrisSafeguard.IrisSafeguardSystem();
|
||||
IrisSafeguard.execute();
|
||||
getSender().setTag(getTag());
|
||||
IrisSafeguard.splash(true);
|
||||
IrisSafeguard.splash();
|
||||
tickets = new ChunkTickets();
|
||||
linkMultiverseCore = new MultiverseCoreLink();
|
||||
configWatcher = new FileWatcher(getDataFile("settings.json"));
|
||||
@@ -459,7 +450,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
services.values().forEach(this::registerListener);
|
||||
addShutdownHook();
|
||||
J.s(() -> {
|
||||
J.a(IrisSafeguard::suggestPaper);
|
||||
J.a(() -> IO.delete(getTemp()));
|
||||
J.a(LazyPregenerator::loadLazyGenerators, 100);
|
||||
J.a(this::bstats);
|
||||
@@ -467,7 +457,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
J.sr(this::tickQueue, 0);
|
||||
J.s(this::setupPapi);
|
||||
J.a(ServerConfigurator::configure, 20);
|
||||
IrisSafeguard.splash(false);
|
||||
|
||||
autoStartStudio();
|
||||
checkForBukkitWorlds(s -> true);
|
||||
@@ -529,9 +518,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
Player r = new KList<>(getServer().getOnlinePlayers()).getRandom();
|
||||
Iris.service(StudioSVC.class).open(r != null ? new VolmitSender(r) : getSender(), 1337, IrisSettings.get().getGenerator().getDefaultWorldType(), (w) -> {
|
||||
J.s(() -> {
|
||||
var spawn = w.getSpawnLocation();
|
||||
for (Player i : getServer().getOnlinePlayers()) {
|
||||
i.setGameMode(GameMode.SPECTATOR);
|
||||
i.teleport(new Location(w, 0, 200, 0));
|
||||
i.teleport(spawn);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -560,10 +550,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
enable();
|
||||
super.onEnable();
|
||||
Bukkit.getPluginManager().registerEvents(this, this);
|
||||
setupChecks();
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
if (IrisSafeguard.isForceShutdown()) return;
|
||||
services.values().forEach(IrisService::onDisable);
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
HandlerList.unregisterAll((Plugin) this);
|
||||
@@ -591,49 +581,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
|
||||
@Override
|
||||
public String getTag(String subTag) {
|
||||
if (unstablemode) {
|
||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.RED + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||
}
|
||||
if (warningmode) {
|
||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GOLD + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||
}
|
||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||
|
||||
}
|
||||
|
||||
private boolean setupChecks() {
|
||||
boolean passed = true;
|
||||
Iris.info("Version Information: " + instance.getServer().getVersion() + " | " + instance.getServer().getBukkitVersion());
|
||||
if (INMS.get() instanceof NMSBinding1X) {
|
||||
passed = false;
|
||||
Iris.warn("============================================");
|
||||
Iris.warn("=");
|
||||
Iris.warn("=");
|
||||
Iris.warn("=");
|
||||
Iris.warn("Iris is not compatible with this version of Minecraft.");
|
||||
Iris.warn("=");
|
||||
Iris.warn("=");
|
||||
Iris.warn("=");
|
||||
Iris.warn("============================================");
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("io.papermc.paper.configuration.PaperConfigurations");
|
||||
} catch (ClassNotFoundException e) {
|
||||
Iris.info(C.RED + "Iris requires paper or above to function properly..");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("org.purpurmc.purpur.PurpurConfig");
|
||||
} catch (ClassNotFoundException e) {
|
||||
Iris.info("We recommend using Purpur for the best experience with Iris.");
|
||||
Iris.info("Purpur is a fork of Paper that is optimized for performance and stability.");
|
||||
Iris.info("Plugins that work on Spigot / Paper work on Purpur.");
|
||||
Iris.info("You can download it here: https://purpurmc.org");
|
||||
return false;
|
||||
}
|
||||
return passed;
|
||||
return IrisSafeguard.mode().tag(subTag);
|
||||
}
|
||||
|
||||
private void checkConfigHotload() {
|
||||
@@ -741,88 +689,11 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
}
|
||||
|
||||
public void splash() {
|
||||
if (!IrisSettings.get().getGeneral().isSplashLogoStartup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String padd = Form.repeat(" ", 8);
|
||||
String padd2 = Form.repeat(" ", 4);
|
||||
String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "<rainbow>Volmit Software", padd2 + C.GRAY + " v" + C.IRIS + getDescription().getVersion()};
|
||||
if (unstablemode) {
|
||||
info = new String[]{"", "", "", "", "", padd2 + C.RED + " Iris", padd2 + C.GRAY + " by " + C.DARK_RED + "Volmit Software", padd2 + C.GRAY + " v" + C.RED + getDescription().getVersion()};
|
||||
}
|
||||
if (warningmode) {
|
||||
info = new String[]{"", "", "", "", "", padd2 + C.GOLD + " Iris", padd2 + C.GRAY + " by " + C.GOLD + "Volmit Software", padd2 + C.GRAY + " v" + C.GOLD + getDescription().getVersion()};
|
||||
}
|
||||
|
||||
String[] splashstable = {
|
||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.IRIS + " .(((()))). ",
|
||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.IRIS + " .((((((())))))). ",
|
||||
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.IRIS + " ((((((((())))))))) " + C.GRAY + " @",
|
||||
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.IRIS + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||
padd + C.GRAY + "@@@&&" + C.IRIS + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||
padd + C.GRAY + "@@" + C.IRIS + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||
padd + C.GRAY + "@" + C.IRIS + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + C.IRIS + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + C.IRIS + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||
};
|
||||
|
||||
String[] splashunstable = {
|
||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.RED + " .(((()))). ",
|
||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.RED + " .((((((())))))). ",
|
||||
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.RED + " ((((((((())))))))) " + C.GRAY + " @",
|
||||
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.RED + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||
padd + C.GRAY + "@@@&&" + C.RED + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||
padd + C.GRAY + "@@" + C.RED + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||
padd + C.GRAY + "@" + C.RED + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + C.RED + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + C.RED + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||
};
|
||||
String[] splashwarning = {
|
||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.GOLD + " .(((()))). ",
|
||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.GOLD + " .((((((())))))). ",
|
||||
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.GOLD + " ((((((((())))))))) " + C.GRAY + " @",
|
||||
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.GOLD + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||
padd + C.GRAY + "@@@&&" + C.GOLD + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||
padd + C.GRAY + "@@" + C.GOLD + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||
padd + C.GRAY + "@" + C.GOLD + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + C.GOLD + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + C.GOLD + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||
};
|
||||
String[] splash;
|
||||
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
||||
if (unstablemode) {
|
||||
splash = splashunstable;
|
||||
} else if (warningmode) {
|
||||
splash = splashwarning;
|
||||
} else {
|
||||
splash = splashstable;
|
||||
}
|
||||
|
||||
if (!passedserversoftware) {
|
||||
Iris.info("Server type & version: " + C.RED + Bukkit.getVersion());
|
||||
} else { Iris.info("Server type & version: " + Bukkit.getVersion()); }
|
||||
Iris.info("Java: " + getJava());
|
||||
if (getHardware.getProcessMemory() < 5999) {
|
||||
Iris.warn("6GB+ Ram is recommended");
|
||||
Iris.warn("Process Memory: " + getHardware.getProcessMemory() + " MB");
|
||||
}
|
||||
Iris.info("Bukkit distro: " + Bukkit.getName());
|
||||
Iris.info("Server type & version: " + Bukkit.getName() + " v" + Bukkit.getVersion());
|
||||
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
||||
setupChecks();
|
||||
printPacks();
|
||||
|
||||
for (int i = 0; i < info.length; i++) {
|
||||
splash[i] += info[i];
|
||||
}
|
||||
|
||||
Iris.info("\n\n " + new KList<>(splash).toString("\n") + "\n");
|
||||
IrisSafeguard.mode().trySplash();
|
||||
}
|
||||
|
||||
private void printPacks() {
|
||||
|
||||
@@ -31,7 +31,9 @@ import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.engine.object.IrisPosition;
|
||||
import com.volmit.iris.engine.object.annotations.Snippet;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.context.IrisContext;
|
||||
import com.volmit.iris.engine.object.IrisJigsawStructurePlacement;
|
||||
@@ -52,6 +54,7 @@ import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.jobs.Job;
|
||||
import lombok.SneakyThrows;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
@@ -92,6 +95,124 @@ public class CommandDeveloper implements DecreeExecutor {
|
||||
Iris.reportError(new Exception("This is a test"));
|
||||
}
|
||||
|
||||
@Decree(description = "Dev cmd to fix all the broken objects caused by faulty shrinkwarp")
|
||||
public void fixObjects(
|
||||
@Param(aliases = "dimension", description = "The dimension type to create the world with")
|
||||
IrisDimension type
|
||||
) {
|
||||
if (type == null) {
|
||||
sender().sendMessage("Type cant be null?");
|
||||
return;
|
||||
}
|
||||
|
||||
IrisData dm = IrisData.get(Iris.instance.getDataFolder("packs", type.getLoadKey()));
|
||||
var loader = dm.getObjectLoader();
|
||||
var processed = new KMap<String, IrisPosition>();
|
||||
|
||||
var objects = loader.getPossibleKeys();
|
||||
var pieces = dm.getJigsawPieceLoader().getPossibleKeys();
|
||||
var sender = sender();
|
||||
|
||||
sender.sendMessage(C.IRIS + "Found " + objects.length + " objects in " + type.getLoadKey());
|
||||
sender.sendMessage(C.IRIS + "Found " + pieces.length + " jigsaw pieces in " + type.getLoadKey());
|
||||
|
||||
final int total = objects.length;
|
||||
final AtomicInteger completed = new AtomicInteger();
|
||||
final AtomicInteger changed = new AtomicInteger();
|
||||
|
||||
new Job() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Fixing Objects";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Arrays.stream(pieces).parallel()
|
||||
.map(dm.getJigsawPieceLoader()::load)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(piece -> {
|
||||
var offset = processed.compute(piece.getObject(), (key, o) -> {
|
||||
if (o != null) return o;
|
||||
var obj = loader.load(key);
|
||||
if (obj == null) return new IrisPosition();
|
||||
|
||||
obj.shrinkwrap();
|
||||
try {
|
||||
if (!obj.getShrinkOffset().isZero()) {
|
||||
changed.incrementAndGet();
|
||||
obj.write(obj.getLoadFile());
|
||||
}
|
||||
completeWork();
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to write object " + obj.getLoadKey());
|
||||
e.printStackTrace();
|
||||
return new IrisPosition();
|
||||
}
|
||||
|
||||
return new IrisPosition(obj.getShrinkOffset());
|
||||
});
|
||||
if (offset.getX() == 0 && offset.getY() == 0 && offset.getZ() == 0)
|
||||
return;
|
||||
|
||||
piece.getConnectors().forEach(connector -> connector.setPosition(connector.getPosition().add(offset)));
|
||||
|
||||
try {
|
||||
IO.writeAll(piece.getLoadFile(), dm.getGson().toJson(piece));
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to write jigsaw piece " + piece.getLoadKey());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
Arrays.stream(loader.getPossibleKeys()).parallel()
|
||||
.filter(key -> !processed.containsKey(key))
|
||||
.map(loader::load)
|
||||
.forEach(obj -> {
|
||||
if (obj == null) {
|
||||
completeWork();
|
||||
return;
|
||||
}
|
||||
|
||||
obj.shrinkwrap();
|
||||
if (obj.getShrinkOffset().isZero()) {
|
||||
completeWork();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
obj.write(obj.getLoadFile());
|
||||
completeWork();
|
||||
changed.incrementAndGet();
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to write object " + obj.getLoadKey());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeWork() {
|
||||
completed.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalWork() {
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWorkCompleted() {
|
||||
return completed.get();
|
||||
}
|
||||
}.execute(sender, () -> {
|
||||
var failed = total - completed.get();
|
||||
if (failed != 0) sender.sendMessage(C.IRIS + "" + failed + " objects failed!");
|
||||
if (changed.get() != 0) sender.sendMessage(C.IRIS + "" + changed.get() + " objects had their offsets changed!");
|
||||
else sender.sendMessage(C.IRIS + "No objects had their offsets changed!");
|
||||
});
|
||||
}
|
||||
|
||||
@Decree(description = "Test")
|
||||
public void mantle(@Param(defaultValue = "false") boolean plate, @Param(defaultValue = "21474836474") String name) throws Throwable {
|
||||
var base = Iris.instance.getDataFile("dump", "pv." + name + ".ttp.lz4b.bin");
|
||||
|
||||
@@ -222,22 +222,8 @@ public class CommandStudio implements DecreeExecutor {
|
||||
job.execute(sender(), latch::countDown);
|
||||
latch.await();
|
||||
|
||||
int sections = mantle.getWorldHeight() >> 4;
|
||||
chunkMap.forEach((pos, chunk) -> {
|
||||
var c = mantle.getChunk(pos.getX(), pos.getZ()).use();
|
||||
try {
|
||||
c.copyFlags(chunk);
|
||||
c.clear();
|
||||
for (int y = 0; y < sections; y++) {
|
||||
var slice = chunk.get(y);
|
||||
if (slice == null) continue;
|
||||
var s = c.getOrCreate(y);
|
||||
slice.getSliceMap().forEach(s::putSlice);
|
||||
}
|
||||
} finally {
|
||||
c.release();
|
||||
}
|
||||
});
|
||||
chunkMap.forEach((pos, chunk) ->
|
||||
mantle.getChunk(pos.getX(), pos.getZ()).copyFrom(chunk));
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage("Error while regenerating chunks");
|
||||
e.printStackTrace();
|
||||
@@ -702,8 +688,14 @@ public class CommandStudio implements DecreeExecutor {
|
||||
}
|
||||
|
||||
sender().sendMessage(C.GREEN + "Sending you to the studio world!");
|
||||
player().teleport(Iris.service(StudioSVC.class).getActiveProject().getActiveProvider().getTarget().getWorld().spawnLocation());
|
||||
player().setGameMode(GameMode.SPECTATOR);
|
||||
var player = player();
|
||||
PaperLib.teleportAsync(player(), Iris.service(StudioSVC.class)
|
||||
.getActiveProject()
|
||||
.getActiveProvider()
|
||||
.getTarget()
|
||||
.getWorld()
|
||||
.spawnLocation()
|
||||
).thenRun(() -> player.setGameMode(GameMode.SPECTATOR));
|
||||
}
|
||||
|
||||
@Decree(description = "Update your dimension projects VSCode workspace")
|
||||
|
||||
@@ -61,14 +61,14 @@ public class JigsawEditor implements Listener {
|
||||
private Location target;
|
||||
|
||||
public JigsawEditor(Player player, IrisJigsawPiece piece, IrisObject object, File saveLocation) {
|
||||
if (editors.containsKey(player)) {
|
||||
editors.get(player).close();
|
||||
}
|
||||
if (object == null) throw new RuntimeException("Object is null! " + piece.getObject());
|
||||
editors.compute(player, ($, current) -> {
|
||||
if (current != null) {
|
||||
current.exit();
|
||||
}
|
||||
return this;
|
||||
});
|
||||
|
||||
editors.put(player, this);
|
||||
if (object == null) {
|
||||
throw new RuntimeException("Object is null! " + piece.getObject());
|
||||
}
|
||||
this.object = object;
|
||||
this.player = player;
|
||||
origin = player.getLocation().clone().add(0, 7, 0);
|
||||
|
||||
@@ -225,7 +225,7 @@ public class IrisProject {
|
||||
sender.sendMessage("Can't find dimension: " + getName());
|
||||
return;
|
||||
} else if (sender.isPlayer()) {
|
||||
sender.player().setGameMode(GameMode.SPECTATOR);
|
||||
J.s(() -> sender.player().setGameMode(GameMode.SPECTATOR));
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import io.papermc.lib.PaperLib;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class IrisSafeguard {
|
||||
private static final AtomicBoolean sfg = new AtomicBoolean(false);
|
||||
public static boolean unstablemode = false;
|
||||
public static boolean warningmode = false;
|
||||
public static boolean stablemode = false;
|
||||
|
||||
public static void IrisSafeguardSystem() {
|
||||
Iris.info("Enabled Iris SafeGuard");
|
||||
ServerBootSFG.BootCheck();
|
||||
}
|
||||
|
||||
public static void splash(boolean early) {
|
||||
if (early && (ServerBootSFG.safeguardPassed || IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode))
|
||||
return;
|
||||
|
||||
if (!sfg.getAndSet(true)) {
|
||||
Iris.instance.splash();
|
||||
UtilsSFG.splash();
|
||||
}
|
||||
}
|
||||
|
||||
public static String mode() {
|
||||
if (unstablemode) {
|
||||
return "unstable";
|
||||
} else if (warningmode) {
|
||||
return "warning";
|
||||
} else {
|
||||
return "stable";
|
||||
}
|
||||
}
|
||||
|
||||
public static void suggestPaper() {
|
||||
PaperLib.suggestPaper(Iris.instance);
|
||||
}
|
||||
|
||||
public static KMap<String, Object> asContext() {
|
||||
KMap<String, Object> m = new KMap<>();
|
||||
m.put("diskSpace", !ServerBootSFG.hasEnoughDiskSpace);
|
||||
m.put("javaVersion", !ServerBootSFG.isCorrectJDK);
|
||||
m.put("jre", ServerBootSFG.isJRE);
|
||||
m.put("missingAgent", ServerBootSFG.missingAgent);
|
||||
m.put("missingDimensionTypes", ServerBootSFG.missingDimensionTypes);
|
||||
m.put("failedInjection", ServerBootSFG.failedInjection);
|
||||
m.put("unsupportedVersion", ServerBootSFG.unsuportedversion);
|
||||
m.put("serverSoftware", !ServerBootSFG.passedserversoftware);
|
||||
KList<String> incompatiblePlugins = new KList<>();
|
||||
ServerBootSFG.incompatibilities.forEach((plugin, present) -> {
|
||||
if (present) incompatiblePlugins.add(plugin);
|
||||
});
|
||||
m.put("plugins", incompatiblePlugins);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.util.format.C;
|
||||
|
||||
public class ModesSFG {
|
||||
public static void selectMode() {
|
||||
if (IrisSafeguard.unstablemode) {
|
||||
Iris.safeguard(C.DARK_RED + "Iris is running in Unstable Mode");
|
||||
unstable();
|
||||
}
|
||||
if (IrisSafeguard.warningmode) {
|
||||
Iris.safeguard(C.GOLD + "Iris is running in Warning Mode");
|
||||
warning();
|
||||
}
|
||||
if (IrisSafeguard.stablemode) {
|
||||
stable();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stable() {
|
||||
Iris.safeguard(C.BLUE + "Iris is running Stable");
|
||||
}
|
||||
|
||||
public static void unstable() {
|
||||
|
||||
UtilsSFG.printIncompatibleWarnings();
|
||||
|
||||
if (IrisSafeguard.unstablemode) {
|
||||
Iris.info("");
|
||||
Iris.info(C.DARK_GRAY + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||
Iris.info(C.RED + "Iris is running in unstable mode which may cause the following issues:");
|
||||
Iris.info(C.DARK_RED + "Server Issues");
|
||||
Iris.info(C.RED + "- Server won't boot");
|
||||
Iris.info(C.RED + "- Data Loss");
|
||||
Iris.info(C.RED + "- Unexpected behavior.");
|
||||
Iris.info(C.RED + "- And More...");
|
||||
Iris.info(C.DARK_RED + "World Issues");
|
||||
Iris.info(C.RED + "- Worlds can't load due to corruption.");
|
||||
Iris.info(C.RED + "- Worlds may slowly corrupt until they can't load.");
|
||||
Iris.info(C.RED + "- World data loss.");
|
||||
Iris.info(C.RED + "- And More...");
|
||||
Iris.info(C.DARK_RED + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.");
|
||||
Iris.info(C.DARK_RED + "CAUSE: " + C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||
|
||||
if (IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode) {
|
||||
Iris.info(C.DARK_RED + "Boot Unstable is set to true, continuing with the startup process.");
|
||||
} else {
|
||||
Iris.info(C.DARK_RED + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed.");
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(Long.MAX_VALUE);
|
||||
} catch (InterruptedException e) {
|
||||
// no
|
||||
}
|
||||
}
|
||||
}
|
||||
Iris.info("");
|
||||
}
|
||||
}
|
||||
|
||||
public static void warning() {
|
||||
|
||||
UtilsSFG.printIncompatibleWarnings();
|
||||
|
||||
if (IrisSafeguard.warningmode) {
|
||||
Iris.info("");
|
||||
Iris.info(C.DARK_GRAY + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||
Iris.info(C.GOLD + "Iris is running in warning mode which may cause the following issues:");
|
||||
Iris.info(C.YELLOW + "- Data Loss");
|
||||
Iris.info(C.YELLOW + "- Errors");
|
||||
Iris.info(C.YELLOW + "- Broken worlds");
|
||||
Iris.info(C.YELLOW + "- Unexpected behavior.");
|
||||
Iris.info(C.YELLOW + "- And perhaps further complications.");
|
||||
Iris.info(C.GOLD + "CAUSE: " + C.YELLOW + UtilsSFG.MSGIncompatibleWarnings());
|
||||
Iris.info("");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
public class PerformanceSFG {
|
||||
public static void calculatePerformance() {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisWorlds;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.agent.Agent;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.File;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.volmit.iris.Iris.getJavaVersion;
|
||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||
|
||||
public class ServerBootSFG {
|
||||
public static final Map<String, Boolean> incompatibilities = new HashMap<>();
|
||||
public static boolean isCorrectJDK = true;
|
||||
public static boolean hasEnoughDiskSpace = true;
|
||||
public static boolean isJRE = false;
|
||||
public static boolean hasPrivileges = true;
|
||||
public static boolean unsuportedversion = false;
|
||||
public static boolean missingDimensionTypes = false;
|
||||
public static boolean missingAgent = false;
|
||||
public static boolean failedInjection = false;
|
||||
protected static boolean safeguardPassed;
|
||||
public static boolean passedserversoftware = true;
|
||||
protected static int count;
|
||||
protected static byte severityLow;
|
||||
protected static byte severityMedium;
|
||||
protected static byte severityHigh;
|
||||
public static String allIncompatibilities;
|
||||
|
||||
public static void BootCheck() {
|
||||
Iris.info("Checking for possible conflicts..");
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
Plugin[] plugins = pluginManager.getPlugins();
|
||||
|
||||
incompatibilities.clear();
|
||||
incompatibilities.put("dynmap", false);
|
||||
incompatibilities.put("Stratos", false);
|
||||
|
||||
String pluginName;
|
||||
for (Plugin plugin : plugins) {
|
||||
pluginName = plugin.getName();
|
||||
Boolean flag = incompatibilities.get(pluginName);
|
||||
if (flag != null && !flag) {
|
||||
severityHigh++;
|
||||
incompatibilities.put(pluginName, true);
|
||||
}
|
||||
}
|
||||
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (Map.Entry<String, Boolean> entry : incompatibilities.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
joiner.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
// Legacy ServerInfo
|
||||
String distro = Bukkit.getName().toLowerCase();
|
||||
if (
|
||||
!distro.contains("purpur") &&
|
||||
!distro.contains("paper") &&
|
||||
!distro.contains("spigot") &&
|
||||
!distro.contains("pufferfish") &&
|
||||
!distro.contains("bukkit")) {
|
||||
|
||||
|
||||
passedserversoftware = false;
|
||||
joiner.add("Server Software");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
|
||||
if (INMS.get() instanceof NMSBinding1X) {
|
||||
unsuportedversion = true;
|
||||
joiner.add("Unsupported Minecraft Version");
|
||||
severityHigh++;
|
||||
}
|
||||
|
||||
if (!List.of(21).contains(getJavaVersion())) {
|
||||
isCorrectJDK = false;
|
||||
joiner.add("Unsupported Java version");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
if (!isJDK()) {
|
||||
isJRE = true;
|
||||
joiner.add("Unsupported JDK");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
// if (!hasPrivileges()){
|
||||
// hasPrivileges = false;
|
||||
// joiner.add("Insufficient Privileges");
|
||||
// severityMedium++;
|
||||
// } Some servers dont like this
|
||||
|
||||
if (!enoughDiskSpace()){
|
||||
hasEnoughDiskSpace = false;
|
||||
joiner.add("Insufficient Disk Space");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
if (!Agent.install()) {
|
||||
missingAgent = true;
|
||||
joiner.add("Missing Java Agent");
|
||||
severityHigh++;
|
||||
} else {
|
||||
if (missingDimensionTypes()) {
|
||||
missingDimensionTypes = true;
|
||||
joiner.add("Missing Dimension Types");
|
||||
severityHigh++;
|
||||
}
|
||||
if (!INMS.get().injectBukkit()) {
|
||||
failedInjection = true;
|
||||
joiner.add("Failed Bukkit Injection");
|
||||
severityHigh++;
|
||||
}
|
||||
}
|
||||
|
||||
allIncompatibilities = joiner.toString();
|
||||
|
||||
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
||||
count = severityHigh + severityMedium + severityLow;
|
||||
if (safeguardPassed) {
|
||||
stablemode = true;
|
||||
Iris.safeguard("Stable mode has been activated.");
|
||||
}
|
||||
if (!safeguardPassed) {
|
||||
if (severityMedium >= 1 && severityHigh == 0) {
|
||||
warningmode = true;
|
||||
Iris.safeguard("Warning mode has been activated.");
|
||||
}
|
||||
if (severityHigh >= 1) {
|
||||
unstablemode = true;
|
||||
Iris.safeguard("Unstable mode has been activated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isJDK() {
|
||||
try {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
// If the compiler is null, it means this is a JRE environment, not a JDK.
|
||||
return compiler != null;
|
||||
} catch (Exception ignored) {}
|
||||
return false;
|
||||
}
|
||||
public static boolean hasPrivileges() {
|
||||
Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json");
|
||||
try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
|
||||
if (Files.isReadable(pv) && Files.isWritable(pv)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean enoughDiskSpace() {
|
||||
File freeSpace = Bukkit.getWorldContainer();
|
||||
double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0);
|
||||
return gigabytes > 3;
|
||||
}
|
||||
|
||||
private static boolean checkJavac(String path) {
|
||||
return !path.isEmpty() && (new File(path, "javac").exists() || new File(path, "javac.exe").exists());
|
||||
}
|
||||
|
||||
private static boolean missingDimensionTypes() {
|
||||
return INMS.get().missingDimensionTypes(getDimensionTypes().toArray(String[]::new));
|
||||
}
|
||||
|
||||
private static KSet<String> getDimensionTypes() {
|
||||
return IrisWorlds.get()
|
||||
.getDimensions()
|
||||
.map(IrisDimension::getDimensionTypeKey)
|
||||
.collect(Collectors.toCollection(KSet::new));
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.agent.Agent;
|
||||
import com.volmit.iris.util.format.C;
|
||||
|
||||
public class UtilsSFG {
|
||||
public static void splash() {
|
||||
ModesSFG.selectMode();
|
||||
}
|
||||
|
||||
public static void printIncompatibleWarnings() {
|
||||
String[] parts = Iris.instance.getDescription().getVersion().split("-");
|
||||
String minVersion = parts[1];
|
||||
String maxVersion = parts[2];
|
||||
|
||||
if (ServerBootSFG.safeguardPassed) {
|
||||
Iris.safeguard(C.BLUE + "0 Conflicts found");
|
||||
} else {
|
||||
if (IrisSafeguard.unstablemode) {
|
||||
Iris.safeguard(C.DARK_RED + "" + ServerBootSFG.count + " Conflicts found");
|
||||
}
|
||||
if (IrisSafeguard.warningmode) {
|
||||
Iris.safeguard(C.YELLOW + "" + ServerBootSFG.count + " Conflicts found");
|
||||
}
|
||||
|
||||
if (ServerBootSFG.incompatibilities.get("dynmap")) {
|
||||
Iris.safeguard(C.RED + "Dynmap");
|
||||
Iris.safeguard(C.RED + "- The plugin Dynmap is not compatible with the server.");
|
||||
Iris.safeguard(C.RED + "- If you want to have a map plugin like Dynmap, consider Bluemap.");
|
||||
}
|
||||
if (ServerBootSFG.incompatibilities.get("Stratos")) {
|
||||
Iris.safeguard(C.YELLOW + "Stratos");
|
||||
Iris.safeguard(C.YELLOW + "- Iris is not compatible with other worldgen plugins.");
|
||||
}
|
||||
if (ServerBootSFG.unsuportedversion) {
|
||||
Iris.safeguard(C.RED + "Server Version");
|
||||
Iris.safeguard(C.RED + "- Iris only supports " + minVersion + " > " + maxVersion);
|
||||
}
|
||||
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.missingAgent) {
|
||||
Iris.safeguard(C.RED + "Java Agent");
|
||||
Iris.safeguard(C.RED + "- Please enable dynamic agent loading by adding -XX:+EnableDynamicAgentLoading to your jvm arguments.");
|
||||
Iris.safeguard(C.RED + "- or add the jvm argument -javaagent:" + Agent.AGENT_JAR.getPath());
|
||||
}
|
||||
if (!ServerBootSFG.passedserversoftware) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead.");
|
||||
}
|
||||
if (!ServerBootSFG.hasPrivileges) {
|
||||
Iris.safeguard(C.YELLOW + "Insufficient Privileges");
|
||||
Iris.safeguard(C.YELLOW + "- The server has insufficient Privileges to run iris. Please contact support.");
|
||||
}
|
||||
if (!ServerBootSFG.hasEnoughDiskSpace) {
|
||||
Iris.safeguard(C.YELLOW + "Insufficient Disk Space");
|
||||
Iris.safeguard(C.YELLOW + "- The server has insufficient Free DiskSpace to run iris required 3GB+.");
|
||||
}
|
||||
if (!ServerBootSFG.isCorrectJDK) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 21 Instead of JDK " + Iris.getJavaVersion());
|
||||
}
|
||||
if (ServerBootSFG.isJRE) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported Server JDK");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 21 Instead of JRE " + Iris.getJavaVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String MSGIncompatibleWarnings() {
|
||||
return ServerBootSFG.allIncompatibilities;
|
||||
}
|
||||
}
|
||||
@@ -2,29 +2,21 @@ package com.volmit.iris.core.tools;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.object.*;
|
||||
import com.volmit.iris.util.data.Varint;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.nbt.io.NBTUtil;
|
||||
import com.volmit.iris.util.nbt.io.NamedTag;
|
||||
import com.volmit.iris.util.nbt.tag.*;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.reflect.V;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.FileUtil;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -39,13 +31,17 @@ public class IrisConverter {
|
||||
sender.sendMessage("No schematic files to convert found in " + folder.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
var stopwatch = PrecisionStopwatch.start();
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||
executorService.submit(() -> {
|
||||
for (File schem : fileList) {
|
||||
try {
|
||||
for (File schem : fileList) {
|
||||
try {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
IrisObject object;
|
||||
boolean largeObject = false;
|
||||
NamedTag tag = null;
|
||||
NamedTag tag;
|
||||
try {
|
||||
tag = NBTUtil.read(schem);
|
||||
} catch (IOException e) {
|
||||
@@ -53,17 +49,20 @@ public class IrisConverter {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
CompoundTag compound = (CompoundTag) tag.getTag();
|
||||
int version = resolveVersion(compound);
|
||||
if (!(version == 2 || version == 3))
|
||||
throw new RuntimeException(C.RED + "Unsupported schematic version: " + version);
|
||||
|
||||
if (compound.containsKey("Palette") && compound.containsKey("Width") && compound.containsKey("Height") && compound.containsKey("Length")) {
|
||||
compound = version == 3 ? (CompoundTag) compound.get("Schematic") : compound;
|
||||
int objW = ((ShortTag) compound.get("Width")).getValue();
|
||||
int objH = ((ShortTag) compound.get("Height")).getValue();
|
||||
int objD = ((ShortTag) compound.get("Length")).getValue();
|
||||
int i = -1;
|
||||
int mv = objW * objH * objD;
|
||||
AtomicInteger v = new AtomicInteger(0);
|
||||
if (mv > 500_000) {
|
||||
if (mv > 2_000_000) {
|
||||
largeObject = true;
|
||||
Iris.info(C.GRAY + "Converting.. "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
Iris.info(C.GRAY + "Converting.. " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
Iris.info(C.GRAY + "- It may take a while");
|
||||
if (sender.isPlayer()) {
|
||||
i = J.ar(() -> {
|
||||
@@ -72,6 +71,7 @@ public class IrisConverter {
|
||||
}
|
||||
}
|
||||
|
||||
compound = version == 3 ? (CompoundTag) compound.get("Blocks") : compound;
|
||||
CompoundTag paletteTag = (CompoundTag) compound.get("Palette");
|
||||
Map<Integer, BlockData> blockmap = new HashMap<>(paletteTag.size(), 0.9f);
|
||||
for (Map.Entry<String, Tag<?>> entry : paletteTag.getValue().entrySet()) {
|
||||
@@ -82,14 +82,16 @@ public class IrisConverter {
|
||||
blockmap.put(blockId, bd);
|
||||
}
|
||||
|
||||
ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData");
|
||||
boolean isBytes = version == 3 ? compound.getByteArrayTag("Data").length() < 128 : ((IntTag) compound.get("PaletteMax")).getValue() < 128;
|
||||
ByteArrayTag byteArray = version == 3 ? (ByteArrayTag) compound.get("Data") : (ByteArrayTag) compound.get("BlockData");
|
||||
byte[] originalBlockArray = byteArray.getValue();
|
||||
|
||||
IrisObject object = new IrisObject(objW, objH, objD);
|
||||
var din = new DataInputStream(new ByteArrayInputStream(originalBlockArray));
|
||||
object = new IrisObject(objW, objH, objD);
|
||||
for (int h = 0; h < objH; h++) {
|
||||
for (int d = 0; d < objD; d++) {
|
||||
for (int w = 0; w < objW; w++) {
|
||||
BlockData bd = blockmap.get(Byte.toUnsignedInt(originalBlockArray[v.get()]));
|
||||
int blockIndex = isBytes ? din.read() & 0xFF : Varint.readUnsignedVarInt(din);
|
||||
BlockData bd = blockmap.get(blockIndex);
|
||||
if (!bd.getMaterial().isAir()) {
|
||||
object.setUnsigned(w, h, d, bd);
|
||||
}
|
||||
@@ -97,42 +99,59 @@ public class IrisConverter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i != -1) J.car(i);
|
||||
try {
|
||||
object.shrinkwrap();
|
||||
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));
|
||||
} catch (IOException e) {
|
||||
Iris.info(C.RED + "Failed to save: " + schem.getName());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (sender.isPlayer()) {
|
||||
if (largeObject) {
|
||||
sender.sendMessage(C.IRIS + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||
} else {
|
||||
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
counter.incrementAndGet();
|
||||
if (sender.isPlayer()) {
|
||||
if (largeObject) {
|
||||
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||
} else {
|
||||
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
}
|
||||
}
|
||||
if (largeObject) {
|
||||
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||
} else {
|
||||
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
}
|
||||
FileUtils.delete(schem);
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(C.RED + "Failed to save: " + schem.getName());
|
||||
throw new IOException(e);
|
||||
}
|
||||
if (largeObject) {
|
||||
Iris.info(C.GRAY + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||
} else {
|
||||
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
}
|
||||
FileUtils.delete(schem);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Iris.info(C.RED + "Failed to convert: " + schem.getName());
|
||||
if (sender.isPlayer()) {
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(C.RED + "Failed to convert: " + schem.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
sender.sendMessage(C.GRAY + "converted: " + fileList.length);
|
||||
stopwatch.end();
|
||||
if (counter.get() != 0) {
|
||||
sender.sendMessage(C.GRAY + "Converted: " + counter.get() + " in " + Form.duration(stopwatch.getMillis()));
|
||||
}
|
||||
if (counter.get() < fileList.length) {
|
||||
sender.sendMessage(C.RED + "Some schematics failed to convert. Check the console for details.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static int resolveVersion(CompoundTag compound) throws Exception {
|
||||
try {
|
||||
|
||||
IntTag root = compound.getIntTag("Version");
|
||||
if (root != null) {
|
||||
return root.getValue();
|
||||
}
|
||||
CompoundTag schematic = (CompoundTag) compound.get("Schematic");
|
||||
return schematic.getIntTag("Version").getValue();
|
||||
} catch (NullPointerException e) {
|
||||
throw new Exception("Cannot resolve schematic version", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -851,7 +851,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
}
|
||||
}
|
||||
|
||||
IrisBiome biome = getBiome(x, y, z);
|
||||
IrisBiome biome = getSurfaceBiome(x, z);
|
||||
|
||||
for (IrisObjectPlacement i : biome.getObjects()) {
|
||||
if (i.getPlace().contains(object)) {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class PlannedPiece {
|
||||
this.setRotation(rot);
|
||||
this.ogObject = data.getObjectLoader().load(piece.getObject());
|
||||
this.object = structure.rotated(piece, rotation);
|
||||
this.piece = rotation.rotateCopy(piece);
|
||||
this.piece = rotation.rotateCopy(piece, new IrisPosition(object.getShrinkOffset()));
|
||||
this.piece.setLoadKey(piece.getLoadKey());
|
||||
this.object.setLoadKey(piece.getObject());
|
||||
this.ogObject.setLoadKey(piece.getObject());
|
||||
|
||||
@@ -98,6 +98,8 @@ public class IrisObject extends IrisRegistrant {
|
||||
@Getter
|
||||
@Setter
|
||||
private transient Vector3i center;
|
||||
@Getter
|
||||
private transient Vector3i shrinkOffset;
|
||||
|
||||
public IrisObject(int w, int h, int d) {
|
||||
blocks = new VectorMap<>();
|
||||
@@ -106,6 +108,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
this.h = h;
|
||||
this.d = d;
|
||||
center = new Vector3i(w / 2, h / 2, d / 2);
|
||||
shrinkOffset = new Vector3i(0, 0, 0);
|
||||
var lock = new ReentrantReadWriteLock();
|
||||
readLock = lock.readLock();
|
||||
writeLock = lock.writeLock();
|
||||
@@ -305,6 +308,9 @@ public class IrisObject extends IrisRegistrant {
|
||||
blocks.put(new Vector3i(din.readShort(), din.readShort(), din.readShort()), B.get(din.readUTF()));
|
||||
}
|
||||
|
||||
if (din.available() == 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
int size = din.readInt();
|
||||
|
||||
@@ -313,7 +319,6 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +328,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
this.h = din.readInt();
|
||||
this.d = din.readInt();
|
||||
if (!din.readUTF().equals("Iris V2 IOB;")) {
|
||||
return;
|
||||
throw new HeaderException();
|
||||
}
|
||||
center = new Vector3i(w / 2, h / 2, d / 2);
|
||||
int s = din.readShort();
|
||||
@@ -470,16 +475,14 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public void read(File file) throws IOException {
|
||||
var fin = new BufferedInputStream(new FileInputStream(file));
|
||||
try {
|
||||
try (var fin = new BufferedInputStream(new FileInputStream(file))) {
|
||||
read(fin);
|
||||
fin.close();
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
fin.close();
|
||||
fin = new BufferedInputStream(new FileInputStream(file));
|
||||
readLegacy(fin);
|
||||
fin.close();
|
||||
if (!(e instanceof HeaderException))
|
||||
Iris.reportError(e);
|
||||
try (var fin = new BufferedInputStream(new FileInputStream(file))) {
|
||||
readLegacy(fin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,8 +507,9 @@ public class IrisObject extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public void shrinkwrap() {
|
||||
BlockVector min = new BlockVector();
|
||||
BlockVector max = new BlockVector();
|
||||
if (blocks.isEmpty()) return;
|
||||
BlockVector min = new BlockVector(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
BlockVector max = new BlockVector(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
|
||||
for (BlockVector i : blocks.keys()) {
|
||||
min.setX(Math.min(min.getX(), i.getX()));
|
||||
@@ -520,6 +524,31 @@ public class IrisObject extends IrisRegistrant {
|
||||
h = max.getBlockY() - min.getBlockY() + 1;
|
||||
d = max.getBlockZ() - min.getBlockZ() + 1;
|
||||
center = new Vector3i(w / 2, h / 2, d / 2);
|
||||
|
||||
Vector3i offset = new Vector3i(
|
||||
-center.getBlockX() - min.getBlockX(),
|
||||
-center.getBlockY() - min.getBlockY(),
|
||||
-center.getBlockZ() - min.getBlockZ()
|
||||
);
|
||||
if (offset.getBlockX() == 0 && offset.getBlockY() == 0 && offset.getBlockZ() == 0)
|
||||
return;
|
||||
|
||||
VectorMap<BlockData> b = new VectorMap<>();
|
||||
VectorMap<TileData> s = new VectorMap<>();
|
||||
|
||||
blocks.forEach((vector, data) -> {
|
||||
vector.add(offset);
|
||||
b.put(vector, data);
|
||||
});
|
||||
|
||||
states.forEach((vector, data) -> {
|
||||
vector.add(offset);
|
||||
s.put(vector, data);
|
||||
});
|
||||
|
||||
shrinkOffset = offset;
|
||||
blocks = b;
|
||||
states = s;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
@@ -1150,8 +1179,8 @@ public class IrisObject extends IrisRegistrant {
|
||||
|
||||
blocks = d;
|
||||
states = dx;
|
||||
writeLock.unlock();
|
||||
shrinkwrap();
|
||||
writeLock.unlock();
|
||||
}
|
||||
|
||||
public void place(Location at) {
|
||||
@@ -1389,4 +1418,10 @@ public class IrisObject extends IrisRegistrant {
|
||||
@Override
|
||||
public void scanForErrors(JSONObject p, VolmitSender sender) {
|
||||
}
|
||||
|
||||
private static class HeaderException extends IOException {
|
||||
public HeaderException() {
|
||||
super("Invalid Header");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,13 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.*;
|
||||
import org.bukkit.block.data.type.RedstoneWire;
|
||||
import org.bukkit.block.data.type.Wall;
|
||||
import org.bukkit.block.structure.StructureRotation;
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -101,15 +101,15 @@ public class IrisObjectRotation {
|
||||
return e.rotateCopy(this);
|
||||
}
|
||||
|
||||
public IrisJigsawPiece rotateCopy(IrisJigsawPiece v) {
|
||||
public IrisJigsawPiece rotateCopy(IrisJigsawPiece v, IrisPosition offset) {
|
||||
IrisJigsawPiece piece = v.copy();
|
||||
for (IrisJigsawPieceConnector i : piece.getConnectors()) {
|
||||
i.setPosition(rotate(i.getPosition()));
|
||||
i.setPosition(rotate(i.getPosition()).add(offset));
|
||||
i.setDirection(rotate(i.getDirection()));
|
||||
}
|
||||
try {
|
||||
var translate = piece.getPlacementOptions().getTranslate();
|
||||
var pos = rotate(new IrisPosition(translate.getX(), translate.getY(), translate.getZ()));
|
||||
var pos = rotate(new IrisPosition(translate.getX(), translate.getY(), translate.getZ())).add(offset);
|
||||
translate.setX(pos.getX()).setY(pos.getY()).setZ(pos.getZ());
|
||||
} catch (NullPointerException ignored) {}
|
||||
|
||||
@@ -259,14 +259,14 @@ public class IrisObjectRotation {
|
||||
|
||||
g.setRotation(face);
|
||||
|
||||
} else if (d instanceof Orientable) {
|
||||
BlockFace f = getFace(((Orientable) d).getAxis());
|
||||
} else if (d instanceof Orientable g) {
|
||||
BlockFace f = getFace(g.getAxis());
|
||||
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
|
||||
bv = rotate(bv.clone(), spinx, spiny, spinz);
|
||||
Axis a = getAxis(bv);
|
||||
|
||||
if (!a.equals(((Orientable) d).getAxis()) && ((Orientable) d).getAxes().contains(a)) {
|
||||
((Orientable) d).setAxis(a);
|
||||
if (!a.equals(g.getAxis()) && g.getAxes().contains(a)) {
|
||||
g.setAxis(a);
|
||||
}
|
||||
} else if (d instanceof MultipleFacing g) {
|
||||
List<BlockFace> faces = new KList<>();
|
||||
@@ -304,14 +304,22 @@ public class IrisObjectRotation {
|
||||
for (BlockFace i : WALL_FACES) {
|
||||
wall.setHeight(i, faces.getOrDefault(i, Wall.Height.NONE));
|
||||
}
|
||||
} else if (d.getMaterial().equals(Material.NETHER_PORTAL) && d instanceof Orientable g) {
|
||||
//TODO: Fucks up logs
|
||||
BlockFace f = faceForAxis(g.getAxis());
|
||||
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
|
||||
bv = rotate(bv.clone(), spinx, spiny, spinz);
|
||||
BlockFace t = getFace(bv);
|
||||
Axis a = !g.getAxes().contains(Axis.Y) ? axisFor(t) : axisFor2D(t);
|
||||
((Orientable) d).setAxis(a);
|
||||
} else if (d instanceof RedstoneWire wire) {
|
||||
Map<BlockFace, RedstoneWire.Connection> faces = new HashMap<>();
|
||||
|
||||
var allowed = wire.getAllowedFaces();
|
||||
for (BlockFace i : allowed) {
|
||||
RedstoneWire.Connection connection = wire.getFace(i);
|
||||
BlockVector bv = new BlockVector(i.getModX(), i.getModY(), i.getModZ());
|
||||
bv = rotate(bv.clone(), spinx, spiny, spinz);
|
||||
BlockFace r = getFace(bv);
|
||||
if (allowed.contains(r))
|
||||
faces.put(r, connection);
|
||||
}
|
||||
|
||||
for (BlockFace i : allowed) {
|
||||
wire.setFace(i, faces.getOrDefault(i, RedstoneWire.Connection.NONE));
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
@@ -360,6 +360,7 @@ public class B {
|
||||
|
||||
public static boolean isFoliagePlantable(BlockData d) {
|
||||
return d.getMaterial().equals(Material.GRASS_BLOCK)
|
||||
|| d.getMaterial().equals(Material.MOSS_BLOCK)
|
||||
|| d.getMaterial().equals(Material.ROOTED_DIRT)
|
||||
|| d.getMaterial().equals(Material.DIRT)
|
||||
|| d.getMaterial().equals(Material.COARSE_DIRT)
|
||||
@@ -368,6 +369,7 @@ public class B {
|
||||
|
||||
public static boolean isFoliagePlantable(Material d) {
|
||||
return d.equals(Material.GRASS_BLOCK)
|
||||
|| d.equals(Material.MOSS_BLOCK)
|
||||
|| d.equals(Material.DIRT)
|
||||
|| d.equals(TALL_GRASS)
|
||||
|| d.equals(TALL_SEAGRASS)
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.volmit.iris.util.format;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.apache.commons.lang.Validate;
|
||||
@@ -495,6 +496,14 @@ public enum C {
|
||||
return STRIP_COLOR_PATTERN.matcher(input).replaceAll("");
|
||||
}
|
||||
|
||||
public static String strip(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return MiniMessage.miniMessage().stripTags(stripColor(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* DyeColor to ChatColor
|
||||
*
|
||||
|
||||
@@ -131,9 +131,13 @@ public class MantleChunk extends FlaggedChunk {
|
||||
ref.release();
|
||||
}
|
||||
|
||||
public void copyFlags(MantleChunk chunk) {
|
||||
public void copyFrom(MantleChunk chunk) {
|
||||
use();
|
||||
super.copyFlags(chunk);
|
||||
super.copyFrom(chunk, () -> {
|
||||
for (int i = 0; i < sections.length(); i++) {
|
||||
sections.set(i, chunk.get(i));
|
||||
}
|
||||
});
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public class Bindings {
|
||||
options.setEnvironment(BuildConstants.ENVIRONMENT);
|
||||
options.setBeforeSend((event, hint) -> {
|
||||
if (suppress(event.getThrowable())) return null;
|
||||
event.setTag("iris.safeguard", IrisSafeguard.mode());
|
||||
event.setTag("iris.safeguard", IrisSafeguard.mode().getId());
|
||||
event.setTag("iris.nms", INMS.get().getClass().getCanonicalName());
|
||||
var context = IrisContext.get();
|
||||
if (context != null) event.getContexts().set("engine", context.asContext());
|
||||
@@ -67,6 +67,7 @@ public class Bindings {
|
||||
Sentry.configureScope(scope -> {
|
||||
if (settings.includeServerId) scope.setUser(ServerID.asUser());
|
||||
scope.addAttachment(Attachments.PLUGINS);
|
||||
scope.addAttachment(Attachments.SAFEGUARD);
|
||||
scope.setTag("server", Bukkit.getVersion());
|
||||
scope.setTag("server.type", Bukkit.getName());
|
||||
scope.setTag("server.api", Bukkit.getBukkitVersion());
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.util.sentry;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import io.sentry.Attachment;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -12,6 +13,7 @@ import java.util.concurrent.Callable;
|
||||
public class Attachments {
|
||||
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
|
||||
public static final Attachment PLUGINS = jsonProvider(Attachments::plugins, "plugins.json");
|
||||
public static final Attachment SAFEGUARD = jsonProvider(IrisSafeguard::asAttachment, "safeguard.json");
|
||||
|
||||
public static Attachment json(Object object, String name) {
|
||||
return new Attachment(GSON.toJson(object).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true);
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.volmit.iris.core.safeguard
|
||||
|
||||
import com.volmit.iris.Iris
|
||||
import com.volmit.iris.core.IrisSettings
|
||||
import com.volmit.iris.core.safeguard.task.Diagnostic
|
||||
import com.volmit.iris.core.safeguard.task.Task
|
||||
import com.volmit.iris.core.safeguard.task.ValueWithDiagnostics
|
||||
import com.volmit.iris.core.safeguard.task.tasks
|
||||
import com.volmit.iris.util.format.C
|
||||
import com.volmit.iris.util.scheduling.J
|
||||
import org.bukkit.Bukkit
|
||||
import java.util.*
|
||||
|
||||
object IrisSafeguard {
|
||||
@Volatile
|
||||
private var forceShutdown = false
|
||||
private var results: Map<Task, ValueWithDiagnostics<Mode>> = emptyMap()
|
||||
private var context: Map<String, String> = emptyMap()
|
||||
private var attachment: Map<String, List<String>> = emptyMap()
|
||||
private var mode = Mode.STABLE
|
||||
private var count = 0
|
||||
|
||||
@JvmStatic
|
||||
fun execute() {
|
||||
val results = LinkedHashMap<Task, ValueWithDiagnostics<Mode>>(tasks.size)
|
||||
val context = LinkedHashMap<String, String>(tasks.size)
|
||||
val attachment = LinkedHashMap<String, List<String>>(tasks.size)
|
||||
var mode = Mode.STABLE
|
||||
var count = 0
|
||||
for (task in tasks) {
|
||||
var result: ValueWithDiagnostics<Mode>
|
||||
try {
|
||||
result = task.run()
|
||||
} catch (e: Throwable) {
|
||||
Iris.reportError(e)
|
||||
result = ValueWithDiagnostics(
|
||||
Mode.WARNING,
|
||||
Diagnostic(Diagnostic.Logger.ERROR, "Error while running task ${task.id}", e)
|
||||
)
|
||||
}
|
||||
mode = mode.highest(result.value)
|
||||
results[task] = result
|
||||
context[task.id] = result.value.id
|
||||
attachment[task.id] = result.diagnostics.flatMap { it.toString().split('\n') }
|
||||
if (result.value != Mode.STABLE) count++
|
||||
}
|
||||
|
||||
this.results = Collections.unmodifiableMap(results)
|
||||
this.context = Collections.unmodifiableMap(context)
|
||||
this.attachment = Collections.unmodifiableMap(attachment)
|
||||
this.mode = mode
|
||||
this.count = count
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun mode() = mode
|
||||
|
||||
@JvmStatic
|
||||
fun asContext() = context
|
||||
|
||||
@JvmStatic
|
||||
fun asAttachment() = attachment
|
||||
|
||||
@JvmStatic
|
||||
fun splash() {
|
||||
Iris.instance.splash()
|
||||
printReports()
|
||||
printFooter()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun printReports() {
|
||||
when (mode) {
|
||||
Mode.STABLE -> Iris.info(C.BLUE.toString() + "0 Conflicts found")
|
||||
Mode.WARNING -> Iris.warn(C.GOLD.toString() + "%s Issues found", count)
|
||||
Mode.UNSTABLE -> Iris.error(C.DARK_RED.toString() + "%s Issues found", count)
|
||||
}
|
||||
|
||||
results.values.forEach { it.log(withStackTrace = true) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun printFooter() {
|
||||
when (mode) {
|
||||
Mode.STABLE -> Iris.info(C.BLUE.toString() + "Iris is running Stable")
|
||||
Mode.WARNING -> warning()
|
||||
Mode.UNSTABLE -> unstable()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isForceShutdown() = forceShutdown
|
||||
|
||||
private fun warning() {
|
||||
Iris.warn(C.GOLD.toString() + "Iris is running in Warning Mode")
|
||||
|
||||
Iris.warn("")
|
||||
Iris.warn(C.DARK_GRAY.toString() + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--")
|
||||
Iris.warn(C.GOLD.toString() + "Iris is running in warning mode which may cause the following issues:")
|
||||
Iris.warn("- Data Loss")
|
||||
Iris.warn("- Errors")
|
||||
Iris.warn("- Broken worlds")
|
||||
Iris.warn("- Unexpected behavior.")
|
||||
Iris.warn("- And perhaps further complications.")
|
||||
Iris.warn("")
|
||||
}
|
||||
|
||||
private fun unstable() {
|
||||
Iris.error(C.DARK_RED.toString() + "Iris is running in Unstable Mode")
|
||||
|
||||
Iris.error("")
|
||||
Iris.error(C.DARK_GRAY.toString() + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--")
|
||||
Iris.error("Iris is running in unstable mode which may cause the following issues:")
|
||||
Iris.error(C.DARK_RED.toString() + "Server Issues")
|
||||
Iris.error("- Server won't boot")
|
||||
Iris.error("- Data Loss")
|
||||
Iris.error("- Unexpected behavior.")
|
||||
Iris.error("- And More...")
|
||||
Iris.error(C.DARK_RED.toString() + "World Issues")
|
||||
Iris.error("- Worlds can't load due to corruption.")
|
||||
Iris.error("- Worlds may slowly corrupt until they can't load.")
|
||||
Iris.error("- World data loss.")
|
||||
Iris.error("- And More...")
|
||||
Iris.error(C.DARK_RED.toString() + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.")
|
||||
|
||||
if (IrisSettings.get().general.isDoomsdayAnnihilationSelfDestructMode) {
|
||||
Iris.error(C.DARK_RED.toString() + "Boot Unstable is set to true, continuing with the startup process in 10 seconds.")
|
||||
J.sleep(10000L)
|
||||
} else {
|
||||
Iris.error(C.DARK_RED.toString() + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed.")
|
||||
Iris.error(C.DARK_RED.toString() + "The server will shutdown in 10 seconds.")
|
||||
J.sleep(10000L)
|
||||
Iris.error(C.DARK_RED.toString() + "Shutting down server.")
|
||||
forceShutdown = true
|
||||
try {
|
||||
Bukkit.getPluginManager().disablePlugins()
|
||||
} finally {
|
||||
Runtime.getRuntime().halt(42)
|
||||
}
|
||||
}
|
||||
Iris.info("")
|
||||
}
|
||||
}
|
||||
76
core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt
Normal file
76
core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.volmit.iris.core.safeguard
|
||||
|
||||
import com.volmit.iris.BuildConstants
|
||||
import com.volmit.iris.Iris
|
||||
import com.volmit.iris.core.IrisSettings
|
||||
import com.volmit.iris.util.format.C
|
||||
import com.volmit.iris.util.format.Form
|
||||
|
||||
enum class Mode(private val color: C) {
|
||||
STABLE(C.IRIS),
|
||||
WARNING(C.GOLD),
|
||||
UNSTABLE(C.RED);
|
||||
|
||||
val id = name.lowercase()
|
||||
|
||||
fun highest(m: Mode): Mode {
|
||||
return if (m.ordinal > ordinal) m else this
|
||||
}
|
||||
|
||||
fun tag(subTag: String?): String {
|
||||
if (subTag == null || subTag.isBlank()) return wrap("Iris") + C.GRAY + ": "
|
||||
return wrap("Iris") + " " + wrap(subTag) + C.GRAY + ": "
|
||||
}
|
||||
|
||||
private fun wrap(tag: String?): String {
|
||||
return C.BOLD.toString() + "" + C.DARK_GRAY + "[" + C.BOLD + color + tag + C.BOLD + C.DARK_GRAY + "]" + C.RESET
|
||||
}
|
||||
|
||||
fun trySplash() {
|
||||
if (!IrisSettings.get().general.isSplashLogoStartup) return
|
||||
splash()
|
||||
}
|
||||
|
||||
fun splash() {
|
||||
val padd = Form.repeat(" ", 8)
|
||||
val padd2 = Form.repeat(" ", 4)
|
||||
|
||||
val splash = arrayOf(
|
||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + color + " .(((()))). ",
|
||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + color + " .((((((())))))). ",
|
||||
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + color + " ((((((((())))))))) " + C.GRAY + " @",
|
||||
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + color + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||
padd + C.GRAY + "@@@&&" + color + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||
padd + C.GRAY + "@@" + color + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||
padd + C.GRAY + "@" + color + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + color + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||
padd + C.GRAY + "" + color + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@",
|
||||
)
|
||||
|
||||
val info = arrayOf(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
padd2 + color + " Iris",
|
||||
padd2 + C.GRAY + " by " + color + "Volmit Software",
|
||||
padd2 + C.GRAY + " v" + color + Iris.instance.description.version,
|
||||
padd2 + C.GRAY + " c" + color + BuildConstants.COMMIT + C.GRAY + "/" + color + BuildConstants.ENVIRONMENT,
|
||||
)
|
||||
|
||||
|
||||
val builder = StringBuilder("\n\n")
|
||||
for (i in splash.indices) {
|
||||
builder.append(splash[i])
|
||||
if (i < info.size) {
|
||||
builder.append(info[i])
|
||||
}
|
||||
builder.append("\n")
|
||||
}
|
||||
|
||||
Iris.info(builder.toString())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.volmit.iris.core.safeguard.task
|
||||
|
||||
import com.volmit.iris.core.safeguard.Mode
|
||||
import com.volmit.iris.util.format.Form
|
||||
import kotlin.properties.PropertyDelegateProvider
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
abstract class Task(
|
||||
val id: String,
|
||||
val name: String = Form.capitalizeWords(id.replace(" ", "_").lowercase()),
|
||||
) {
|
||||
|
||||
abstract fun run(): ValueWithDiagnostics<Mode>
|
||||
|
||||
companion object {
|
||||
fun of(id: String, name: String = id, action: () -> ValueWithDiagnostics<Mode>) = object : Task(id, name) {
|
||||
override fun run() = action()
|
||||
}
|
||||
|
||||
fun of(id: String, action: () -> ValueWithDiagnostics<Mode>) = object : Task(id) {
|
||||
override fun run() = action()
|
||||
}
|
||||
|
||||
fun task(action: () -> ValueWithDiagnostics<Mode>) = PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, Task>> { _, _ ->
|
||||
ReadOnlyProperty { _, property -> of(property.name, action) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.volmit.iris.core.safeguard.task
|
||||
|
||||
import com.volmit.iris.Iris
|
||||
import com.volmit.iris.core.IrisWorlds
|
||||
import com.volmit.iris.core.nms.INMS
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X
|
||||
import com.volmit.iris.core.safeguard.Mode
|
||||
import com.volmit.iris.core.safeguard.Mode.*
|
||||
import com.volmit.iris.core.safeguard.task.Diagnostic.Logger.*
|
||||
import com.volmit.iris.core.safeguard.task.Task.Companion.of
|
||||
import com.volmit.iris.util.agent.Agent
|
||||
import com.volmit.iris.util.misc.getHardware
|
||||
import org.bukkit.Bukkit
|
||||
import java.util.stream.Collectors
|
||||
import javax.tools.ToolProvider
|
||||
import kotlin.properties.PropertyDelegateProvider
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
private val memory by task {
|
||||
val mem = getHardware.getProcessMemory()
|
||||
if (mem >= 5999) STABLE.withDiagnostics()
|
||||
else STABLE.withDiagnostics(
|
||||
WARN.create("Low Memory"),
|
||||
WARN.create("- 6GB+ Ram is recommended"),
|
||||
WARN.create("- Process Memory: $mem MB")
|
||||
)
|
||||
}
|
||||
|
||||
private val incompatibilities by task {
|
||||
val plugins = mutableSetOf("dynmap", "Stratos")
|
||||
plugins.removeIf { server.pluginManager.getPlugin(it) == null }
|
||||
|
||||
if (plugins.isEmpty()) STABLE.withDiagnostics()
|
||||
else {
|
||||
val diagnostics = mutableListOf<Diagnostic>()
|
||||
if ("dynmap" in plugins) diagnostics.addAll(
|
||||
ERROR.create("Dynmap"),
|
||||
ERROR.create("- The plugin Dynmap is not compatible with the server."),
|
||||
ERROR.create("- If you want to have a map plugin like Dynmap, consider Bluemap.")
|
||||
)
|
||||
if ("Stratos" in plugins) diagnostics.addAll(
|
||||
ERROR.create("Stratos"),
|
||||
ERROR.create("- Iris is not compatible with other worldgen plugins.")
|
||||
)
|
||||
WARNING.withDiagnostics(diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
private val software by task {
|
||||
val supported = setOf(
|
||||
"purpur",
|
||||
"pufferfish",
|
||||
"paper",
|
||||
"spigot",
|
||||
"bukkit"
|
||||
)
|
||||
|
||||
if (supported.any { server.name.contains(it, true) }) STABLE.withDiagnostics()
|
||||
else WARNING.withDiagnostics(
|
||||
WARN.create("Unsupported Server Software"),
|
||||
WARN.create("- Please consider using Paper or Purpur instead.")
|
||||
)
|
||||
}
|
||||
|
||||
private val version by task {
|
||||
val parts = Iris.instance.description.version.split('-')
|
||||
val minVersion = parts[1]
|
||||
val maxVersion = parts[2]
|
||||
|
||||
if (INMS.get() !is NMSBinding1X) STABLE.withDiagnostics()
|
||||
else UNSTABLE.withDiagnostics(
|
||||
ERROR.create("Server Version"),
|
||||
ERROR.create("- Iris only supports $minVersion > $maxVersion")
|
||||
)
|
||||
}
|
||||
|
||||
private val injection by task {
|
||||
if (!Agent.install()) UNSTABLE.withDiagnostics(
|
||||
ERROR.create("Java Agent"),
|
||||
ERROR.create("- Please enable dynamic agent loading by adding -XX:+EnableDynamicAgentLoading to your jvm arguments."),
|
||||
ERROR.create("- or add the jvm argument -javaagent:" + Agent.AGENT_JAR.path)
|
||||
)
|
||||
else if (!INMS.get().injectBukkit()) UNSTABLE.withDiagnostics(
|
||||
ERROR.create("Code Injection"),
|
||||
ERROR.create("- Failed to inject code. Please contact support")
|
||||
)
|
||||
else STABLE.withDiagnostics()
|
||||
}
|
||||
|
||||
private val dimensionTypes by task {
|
||||
val keys = IrisWorlds.get()
|
||||
.dimensions
|
||||
.map { it.dimensionTypeKey }
|
||||
.collect(Collectors.toSet())
|
||||
|
||||
if (!INMS.get().missingDimensionTypes(*keys.toTypedArray())) STABLE.withDiagnostics()
|
||||
else UNSTABLE.withDiagnostics(
|
||||
ERROR.create("Dimension Types"),
|
||||
ERROR.create("- Required Iris dimension types were not loaded."),
|
||||
ERROR.create("- If this still happens after a restart please contact support.")
|
||||
)
|
||||
}
|
||||
|
||||
private val diskSpace by task {
|
||||
if (server.worldContainer.freeSpace.toDouble().div(0x4000_0000) > 3) STABLE.withDiagnostics()
|
||||
else WARNING.withDiagnostics(
|
||||
WARN.create("Insufficient Disk Space"),
|
||||
WARN.create("- 3GB of free space is required for Iris to function.")
|
||||
)
|
||||
}
|
||||
|
||||
private val java by task {
|
||||
val version = Iris.getJavaVersion()
|
||||
val jdk = runCatching { ToolProvider.getSystemJavaCompiler() }.getOrNull() != null
|
||||
if (version in setOf(21) && jdk) STABLE.withDiagnostics()
|
||||
else WARNING.withDiagnostics(
|
||||
WARN.create("Unsupported Java version"),
|
||||
WARN.create("- Please consider using JDK 21 Instead of ${if(jdk) "JDK" else "JRE"} $version")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
val tasks = listOf(
|
||||
memory,
|
||||
incompatibilities,
|
||||
software,
|
||||
version,
|
||||
injection,
|
||||
dimensionTypes,
|
||||
diskSpace,
|
||||
java,
|
||||
)
|
||||
|
||||
private val server get() = Bukkit.getServer()
|
||||
private fun <T> MutableList<T>.addAll(vararg values: T) = values.forEach(this::add)
|
||||
fun task(action: () -> ValueWithDiagnostics<Mode>) = PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, Task>> { _, _ ->
|
||||
ReadOnlyProperty { _, property -> of(property.name, action) }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.volmit.iris.core.safeguard.task
|
||||
|
||||
import com.volmit.iris.Iris
|
||||
import com.volmit.iris.util.format.C
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
|
||||
data class ValueWithDiagnostics<out T>(
|
||||
val value: T,
|
||||
val diagnostics: List<Diagnostic>
|
||||
) {
|
||||
constructor(value: T, vararg diagnostics: Diagnostic) : this(value, diagnostics.toList())
|
||||
|
||||
@JvmOverloads
|
||||
fun log(
|
||||
withException: Boolean = true,
|
||||
withStackTrace: Boolean = false
|
||||
) {
|
||||
diagnostics.forEach { it.log(withException, withStackTrace) }
|
||||
}
|
||||
}
|
||||
|
||||
data class Diagnostic @JvmOverloads constructor(
|
||||
val logger: Logger = Logger.ERROR,
|
||||
val message: String,
|
||||
val exception: Throwable? = null
|
||||
) {
|
||||
|
||||
enum class Logger(
|
||||
private val logger: (String) -> Unit
|
||||
) {
|
||||
DEBUG(Iris::debug),
|
||||
RAW(Iris::msg),
|
||||
INFO(Iris::info),
|
||||
WARN(Iris::warn),
|
||||
ERROR(Iris::error);
|
||||
|
||||
fun print(message: String) = message.split('\n').forEach(logger)
|
||||
fun create(message: String, exception: Throwable? = null) = Diagnostic(this, message, exception)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun log(
|
||||
withException: Boolean = true,
|
||||
withStackTrace: Boolean = false
|
||||
) {
|
||||
logger.print(render(withException, withStackTrace))
|
||||
}
|
||||
|
||||
fun render(
|
||||
withException: Boolean = true,
|
||||
withStackTrace: Boolean = false
|
||||
): String = buildString {
|
||||
append(message)
|
||||
if (withException && exception != null) {
|
||||
append(": ")
|
||||
append(exception)
|
||||
if (withStackTrace) {
|
||||
ByteArrayOutputStream().use { os ->
|
||||
val ps = PrintStream(os)
|
||||
exception.printStackTrace(ps)
|
||||
ps.flush()
|
||||
append("\n")
|
||||
append(os.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = C.strip(render())
|
||||
}
|
||||
|
||||
fun <T> T.withDiagnostics(vararg diagnostics: Diagnostic) = ValueWithDiagnostics(this, diagnostics.toList())
|
||||
fun <T> T.withDiagnostics(diagnostics: List<Diagnostic>) = ValueWithDiagnostics(this, diagnostics)
|
||||
@@ -35,6 +35,7 @@ class ChunkedDataCache<T> private constructor(
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun get(x: Int, z: Int): T? {
|
||||
if (!cache) {
|
||||
return stream.get((this.x + x).toDouble(), (this.z + z).toDouble())
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.volmit.iris.util.mantle
|
||||
import com.volmit.iris.util.data.Varint
|
||||
import com.volmit.iris.util.mantle.flag.MantleFlag
|
||||
import com.volmit.iris.util.parallel.AtomicBooleanArray
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.io.DataInput
|
||||
@@ -22,9 +25,21 @@ abstract class FlaggedChunk() {
|
||||
|
||||
abstract fun isClosed(): Boolean
|
||||
|
||||
protected fun copyFlags(other: FlaggedChunk) {
|
||||
protected fun copyFrom(other: FlaggedChunk, action: Runnable) = runBlocking {
|
||||
coroutineScope {
|
||||
for (i in 0 until flags.length()) {
|
||||
launch { locks[i].lock() }.start()
|
||||
}
|
||||
}
|
||||
|
||||
action.run()
|
||||
|
||||
for (i in 0 until flags.length()) {
|
||||
flags.set(i, other.flags.get(i))
|
||||
flags[i] = other.flags[i]
|
||||
}
|
||||
|
||||
for (i in 0 until flags.length()) {
|
||||
locks[i].unlock()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user