mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-01 15:36:45 +00:00
commit
9cbfd5a10b
49
build.gradle
49
build.gradle
@ -33,6 +33,7 @@ plugins {
|
|||||||
id "io.github.goooler.shadow" version "8.1.7"
|
id "io.github.goooler.shadow" version "8.1.7"
|
||||||
id "de.undercouch.download" version "5.0.1"
|
id "de.undercouch.download" version "5.0.1"
|
||||||
id "xyz.jpenilla.run-paper" version "2.3.1"
|
id "xyz.jpenilla.run-paper" version "2.3.1"
|
||||||
|
id "io.sentry.jvm.gradle" version "5.7.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ shadowJar {
|
|||||||
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
||||||
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
||||||
relocate 'org.bstats', 'com.volmit.util.metrics'
|
relocate 'org.bstats', 'com.volmit.util.metrics'
|
||||||
|
relocate "io.sentry", "com.volmit.iris.util.sentry"
|
||||||
archiveFileName.set("Iris-${project.version}.jar")
|
archiveFileName.set("Iris-${project.version}.jar")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -132,6 +134,7 @@ configurations.configureEach {
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'io.sentry.jvm.gradle'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -203,6 +206,16 @@ allprojects {
|
|||||||
archiveClassifier.set('javadoc')
|
archiveClassifier.set('javadoc')
|
||||||
from javadoc.destinationDir
|
from javadoc.destinationDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sentry {
|
||||||
|
includeSourceContext = true
|
||||||
|
|
||||||
|
org = "volmit-software"
|
||||||
|
projectName = "iris"
|
||||||
|
authToken = hasProperty("sentry.auth.token") ?
|
||||||
|
property("sentry.auth.token") :
|
||||||
|
System.getenv("SENTRY_AUTH_TOKEN")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JavaVersion.current().toString() != "21") {
|
if (JavaVersion.current().toString() != "21") {
|
||||||
@ -279,3 +292,39 @@ def registerCustomOutputTaskUnix(name, path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.build.dependsOn(shadowJar)
|
tasks.build.dependsOn(shadowJar)
|
||||||
|
|
||||||
|
def cli = file("sentry-cli.exe")
|
||||||
|
tasks.register("downloadCli", Download) {
|
||||||
|
group = "sentry"
|
||||||
|
src "https://release-registry.services.sentry.io/apps/sentry-cli/latest?response=download&arch=x86_64&platform=${System.getProperty("os.name")}&package=sentry-cli"
|
||||||
|
dest cli
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
cli.setExecutable(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("release") {
|
||||||
|
group = "sentry"
|
||||||
|
dependsOn("downloadCli")
|
||||||
|
doLast {
|
||||||
|
def authToken = project.hasProperty("sentry.auth.token") ?
|
||||||
|
project.property("sentry.auth.token") :
|
||||||
|
System.getenv("SENTRY_AUTH_TOKEN")
|
||||||
|
def org = "volmit-software"
|
||||||
|
def projectName = "iris"
|
||||||
|
exec {
|
||||||
|
executable(cli)
|
||||||
|
args("releases", "new", "--auth-token", authToken, "-o", org, "-p", projectName, version)
|
||||||
|
}
|
||||||
|
exec {
|
||||||
|
executable(cli)
|
||||||
|
args("releases", "set-commits", "--auth-token", authToken, "-o", org, "-p", projectName, version, "--auto")
|
||||||
|
}
|
||||||
|
exec {
|
||||||
|
executable(cli)
|
||||||
|
args("releases", "finalize", "--auth-token", authToken, "-o", org, "-p", projectName, version)
|
||||||
|
}
|
||||||
|
cli.delete()
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,6 @@ import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
|||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.core.tools.IrisWorldCreator;
|
|
||||||
import com.volmit.iris.engine.EnginePanic;
|
import com.volmit.iris.engine.EnginePanic;
|
||||||
import com.volmit.iris.engine.object.IrisCompat;
|
import com.volmit.iris.engine.object.IrisCompat;
|
||||||
import com.volmit.iris.engine.object.IrisContextInjector;
|
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||||
@ -64,7 +63,10 @@ import com.volmit.iris.util.reflect.ShadeFix;
|
|||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
import com.volmit.iris.util.scheduling.ShurikenQueue;
|
import com.volmit.iris.util.scheduling.ShurikenQueue;
|
||||||
|
import com.volmit.iris.util.sentry.Attachments;
|
||||||
|
import com.volmit.iris.util.sentry.IrisLogger;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import io.sentry.Sentry;
|
||||||
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;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
@ -392,6 +394,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void reportError(Throwable e) {
|
public static void reportError(Throwable e) {
|
||||||
|
Sentry.captureException(e);
|
||||||
if (IrisSettings.get().getGeneral().isDebug()) {
|
if (IrisSettings.get().getGeneral().isDebug()) {
|
||||||
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber();
|
||||||
|
|
||||||
@ -456,6 +459,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
instance = this;
|
instance = this;
|
||||||
services = new KMap<>();
|
services = new KMap<>();
|
||||||
setupAudience();
|
setupAudience();
|
||||||
|
setupSentry();
|
||||||
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
||||||
INMS.get();
|
INMS.get();
|
||||||
IO.delete(new File("iris"));
|
IO.delete(new File("iris"));
|
||||||
@ -527,6 +531,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
reportError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +549,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (IrisException e) {
|
} catch (IrisException e) {
|
||||||
e.printStackTrace();
|
reportError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -940,4 +945,33 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setupSentry() {
|
||||||
|
var settings = IrisSettings.get().getSentry();
|
||||||
|
if (settings.disableAutoReporting || Sentry.isEnabled()) return;
|
||||||
|
Iris.info("Enabling Sentry for anonymous error reporting. You can disable this in the settings.");
|
||||||
|
Sentry.init(options -> {
|
||||||
|
options.setDsn("https://b16ecc222e9c1e0c48faecacb906fd89@o4509451052646400.ingest.de.sentry.io/4509452722765904");
|
||||||
|
if (settings.debug) {
|
||||||
|
options.setLogger(new IrisLogger());
|
||||||
|
options.setDebug(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.setAttachServerName(false);
|
||||||
|
options.setEnableUncaughtExceptionHandler(false);
|
||||||
|
options.setRelease(Iris.instance.getDescription().getVersion());
|
||||||
|
options.setBeforeSend((event, hint) -> {
|
||||||
|
event.setTag("iris.safeguard", IrisSafeguard.mode());
|
||||||
|
event.setTag("iris.nms", INMS.get().getClass().getCanonicalName());
|
||||||
|
return event;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Sentry.configureScope(scope -> {
|
||||||
|
scope.addAttachment(Attachments.PLUGINS);
|
||||||
|
scope.setTag("server", Bukkit.getVersion());
|
||||||
|
scope.setTag("server.type", Bukkit.getName());
|
||||||
|
scope.setTag("server.api", Bukkit.getBukkitVersion());
|
||||||
|
});
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(Sentry::close));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ public class IrisSettings {
|
|||||||
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
||||||
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
||||||
private IrisSettingsPregen pregen = new IrisSettingsPregen();
|
private IrisSettingsPregen pregen = new IrisSettingsPregen();
|
||||||
|
private IrisSettingsSentry sentry = new IrisSettingsSentry();
|
||||||
|
|
||||||
public static int getThreadCount(int c) {
|
public static int getThreadCount(int c) {
|
||||||
return switch (c) {
|
return switch (c) {
|
||||||
@ -222,6 +223,12 @@ public class IrisSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class IrisSettingsSentry {
|
||||||
|
public boolean disableAutoReporting = false;
|
||||||
|
public boolean debug = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGUI {
|
public static class IrisSettingsGUI {
|
||||||
public boolean useServerLaunchedGuis = true;
|
public boolean useServerLaunchedGuis = true;
|
||||||
|
@ -71,6 +71,11 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
.engineStatus(sender());
|
.engineStatus(sender());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Send a test exception to sentry")
|
||||||
|
public void Sentry() {
|
||||||
|
Iris.reportError(new Exception("This is a test"));
|
||||||
|
}
|
||||||
|
|
||||||
@Decree(description = "Test")
|
@Decree(description = "Test")
|
||||||
public void dumpThreads() {
|
public void dumpThreads() {
|
||||||
try {
|
try {
|
||||||
|
@ -47,6 +47,7 @@ public class WorldEditLink {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.error("Could not get selection");
|
Iris.error("Could not get selection");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
Iris.reportError(e);
|
||||||
active.reset();
|
active.reset();
|
||||||
active.aquire(() -> false);
|
active.aquire(() -> false);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +300,7 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Iris.error("Failed to create loader! " + registrant.getCanonicalName());
|
Iris.error("Failed to create loader! " + registrant.getCanonicalName());
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ public class ChunkUpdater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}, 0, 3, TimeUnit.SECONDS);
|
}, 0, 3, TimeUnit.SECONDS);
|
||||||
@ -314,6 +315,7 @@ public class ChunkUpdater {
|
|||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,10 @@ public class IrisPregenerator {
|
|||||||
private final KSet<Position2> net;
|
private final KSet<Position2> net;
|
||||||
private final ChronoLatch cl;
|
private final ChronoLatch cl;
|
||||||
private final ChronoLatch saveLatch = new ChronoLatch(30000);
|
private final ChronoLatch saveLatch = new ChronoLatch(30000);
|
||||||
|
private final IrisPackBenchmarking benchmarking;
|
||||||
|
|
||||||
public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) {
|
public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) {
|
||||||
|
benchmarking = IrisPackBenchmarking.getInstance();
|
||||||
this.listener = listenify(listener);
|
this.listener = listenify(listener);
|
||||||
cl = new ChronoLatch(5000);
|
cl = new ChronoLatch(5000);
|
||||||
generatedRegions = new KSet<>();
|
generatedRegions = new KSet<>();
|
||||||
@ -135,7 +137,7 @@ public class IrisPregenerator {
|
|||||||
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
||||||
|
|
||||||
Iris.info("%s: %s of %s (%.0f%%), %s/s ETA: %s",
|
Iris.info("%s: %s of %s (%.0f%%), %s/s ETA: %s",
|
||||||
IrisPackBenchmarking.benchmarkInProgress ? "Benchmarking" : "Pregen",
|
benchmarking != null ? "Benchmarking" : "Pregen",
|
||||||
Form.f(generated.get()),
|
Form.f(generated.get()),
|
||||||
Form.f(totalChunks.get()),
|
Form.f(totalChunks.get()),
|
||||||
percentage,
|
percentage,
|
||||||
@ -174,10 +176,10 @@ public class IrisPregenerator {
|
|||||||
task.iterateRegions((x, z) -> visitRegion(x, z, false));
|
task.iterateRegions((x, z) -> visitRegion(x, z, false));
|
||||||
Iris.info("Pregen took " + Form.duration((long) p.getMilliseconds()));
|
Iris.info("Pregen took " + Form.duration((long) p.getMilliseconds()));
|
||||||
shutdown();
|
shutdown();
|
||||||
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
if (benchmarking == null) {
|
||||||
Iris.info(C.IRIS + "Pregen stopped.");
|
Iris.info(C.IRIS + "Pregen stopped.");
|
||||||
} else {
|
} else {
|
||||||
IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory);
|
benchmarking.finishedBenchmark(chunksPerSecondHistory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.util.data.Varint;
|
import com.volmit.iris.util.data.Varint;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.parallel.HyperLock;
|
import com.volmit.iris.util.parallel.HyperLock;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
@ -70,6 +71,7 @@ class PregenCacheImpl implements PregenCache {
|
|||||||
return new Plate(key, in);
|
return new Plate(key, in);
|
||||||
} catch (IOException e){
|
} catch (IOException e){
|
||||||
Iris.error("Failed to read pregen cache " + file);
|
Iris.error("Failed to read pregen cache " + file);
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return new Plate(key);
|
return new Plate(key);
|
||||||
}
|
}
|
||||||
@ -82,10 +84,11 @@ class PregenCacheImpl implements PregenCache {
|
|||||||
hyperLock.lock(plate.pos.x, plate.pos.z);
|
hyperLock.lock(plate.pos.x, plate.pos.z);
|
||||||
try {
|
try {
|
||||||
File file = fileForPlate(plate.pos);
|
File file = fileForPlate(plate.pos);
|
||||||
try (var out = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(file)))) {
|
try {
|
||||||
plate.write(out);
|
IO.write(file, out -> new DataOutputStream(new LZ4BlockOutputStream(out)), plate::write);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Iris.error("Failed to write pregen cache " + file);
|
Iris.error("Failed to write pregen cache " + file);
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -157,7 +157,10 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.warn("Failed to increase worker threads, if you are on paper or a fork of it please increase it manually to " + adjusted);
|
Iris.warn("Failed to increase worker threads, if you are on paper or a fork of it please increase it manually to " + adjusted);
|
||||||
Iris.warn("For more information see https://docs.papermc.io/paper/reference/global-configuration#chunk_system_worker_threads");
|
Iris.warn("For more information see https://docs.papermc.io/paper/reference/global-configuration#chunk_system_worker_threads");
|
||||||
if (e instanceof InvocationTargetException) e.printStackTrace();
|
if (e instanceof InvocationTargetException) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
@ -173,6 +176,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
method.invoke(pool, i);
|
method.invoke(pool, i);
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
Iris.error("Failed to reset worker threads");
|
Iris.error("Failed to reset worker threads");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -201,6 +205,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
}).get();
|
}).get();
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -219,6 +224,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
public void generate(int x, int z, PregenListener listener) {
|
public void generate(int x, int z, PregenListener listener) {
|
||||||
PaperLib.getChunkAtAsync(world, x, z, true, urgent)
|
PaperLib.getChunkAtAsync(world, x, z, true, urgent)
|
||||||
.exceptionally(e -> {
|
.exceptionally(e -> {
|
||||||
|
Iris.reportError(e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
|
@ -20,5 +20,15 @@ public class IrisSafeguard {
|
|||||||
Iris.instance.splash();
|
Iris.instance.splash();
|
||||||
UtilsSFG.splash();
|
UtilsSFG.splash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String mode() {
|
||||||
|
if (unstablemode) {
|
||||||
|
return "unstable";
|
||||||
|
} else if (warningmode) {
|
||||||
|
return "warning";
|
||||||
|
} else {
|
||||||
|
return "stable";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,11 @@ public class GlobalCacheSVC implements IrisService {
|
|||||||
private static final Cache<String, PregenCache> REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build();
|
private static final Cache<String, PregenCache> REFERENCE_CACHE = Caffeine.newBuilder().weakValues().build();
|
||||||
private final KMap<String, PregenCache> globalCache = new KMap<>();
|
private final KMap<String, PregenCache> globalCache = new KMap<>();
|
||||||
private transient boolean lastState;
|
private transient boolean lastState;
|
||||||
|
private static boolean disabled = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
disabled = false;
|
||||||
lastState = !IrisSettings.get().getWorld().isGlobalPregenCache();
|
lastState = !IrisSettings.get().getWorld().isGlobalPregenCache();
|
||||||
if (lastState) return;
|
if (lastState) return;
|
||||||
Bukkit.getWorlds().forEach(this::createCache);
|
Bukkit.getWorlds().forEach(this::createCache);
|
||||||
@ -33,7 +35,8 @@ public class GlobalCacheSVC implements IrisService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
globalCache.values().forEach(PregenCache::write);
|
disabled = true;
|
||||||
|
globalCache.qclear((world, cache) -> cache.write());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -99,6 +102,7 @@ public class GlobalCacheSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PregenCache createDefault0(String worldName) {
|
private static PregenCache createDefault0(String worldName) {
|
||||||
|
if (disabled) return PregenCache.EMPTY;
|
||||||
return PregenCache.create(new File(Bukkit.getWorldContainer(), String.join(File.separator, worldName, "iris", "pregen"))).sync();
|
return PregenCache.create(new File(Bukkit.getWorldContainer(), String.join(File.separator, worldName, "iris", "pregen"))).sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import com.volmit.iris.util.format.Form;
|
|||||||
import com.volmit.iris.util.io.IO;
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -24,28 +23,28 @@ import java.util.Collections;
|
|||||||
|
|
||||||
|
|
||||||
public class IrisPackBenchmarking {
|
public class IrisPackBenchmarking {
|
||||||
@Getter
|
private static final ThreadLocal<IrisPackBenchmarking> instance = new ThreadLocal<>();
|
||||||
public static IrisPackBenchmarking instance;
|
|
||||||
public static boolean benchmarkInProgress = false;
|
|
||||||
private final PrecisionStopwatch stopwatch = new PrecisionStopwatch();
|
private final PrecisionStopwatch stopwatch = new PrecisionStopwatch();
|
||||||
private final IrisDimension dimension;
|
private final IrisDimension dimension;
|
||||||
private final int radius;
|
private final int radius;
|
||||||
private final boolean gui;
|
private final boolean gui;
|
||||||
|
|
||||||
public IrisPackBenchmarking(IrisDimension dimension, int radius, boolean gui) {
|
public IrisPackBenchmarking(IrisDimension dimension, int radius, boolean gui) {
|
||||||
instance = this;
|
|
||||||
this.dimension = dimension;
|
this.dimension = dimension;
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
this.gui = gui;
|
this.gui = gui;
|
||||||
runBenchmark();
|
runBenchmark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IrisPackBenchmarking getInstance() {
|
||||||
|
return instance.get();
|
||||||
|
}
|
||||||
|
|
||||||
private void runBenchmark() {
|
private void runBenchmark() {
|
||||||
Thread.ofVirtual()
|
Thread.ofVirtual()
|
||||||
.name("PackBenchmarking")
|
.name("PackBenchmarking")
|
||||||
.start(() -> {
|
.start(() -> {
|
||||||
Iris.info("Setting up benchmark environment ");
|
Iris.info("Setting up benchmark environment ");
|
||||||
benchmarkInProgress = true;
|
|
||||||
IO.delete(new File(Bukkit.getWorldContainer(), "benchmark"));
|
IO.delete(new File(Bukkit.getWorldContainer(), "benchmark"));
|
||||||
createBenchmark();
|
createBenchmark();
|
||||||
while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) {
|
while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) {
|
||||||
@ -59,10 +58,6 @@ public class IrisPackBenchmarking {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBenchmarkInProgress() {
|
|
||||||
return benchmarkInProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finishedBenchmark(KList<Integer> cps) {
|
public void finishedBenchmark(KList<Integer> cps) {
|
||||||
try {
|
try {
|
||||||
String time = Form.duration((long) stopwatch.getMilliseconds());
|
String time = Form.duration((long) stopwatch.getMilliseconds());
|
||||||
@ -132,6 +127,8 @@ public class IrisPackBenchmarking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startBenchmark() {
|
private void startBenchmark() {
|
||||||
|
try {
|
||||||
|
instance.set(this);
|
||||||
IrisToolbelt.pregenerate(PregenTask
|
IrisToolbelt.pregenerate(PregenTask
|
||||||
.builder()
|
.builder()
|
||||||
.gui(gui)
|
.gui(gui)
|
||||||
@ -139,6 +136,9 @@ public class IrisPackBenchmarking {
|
|||||||
.radiusZ(radius)
|
.radiusZ(radius)
|
||||||
.build(), Bukkit.getWorld("benchmark")
|
.build(), Bukkit.getWorld("benchmark")
|
||||||
);
|
);
|
||||||
|
} finally {
|
||||||
|
instance.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateAverage(KList<Integer> list) {
|
private double calculateAverage(KList<Integer> list) {
|
||||||
|
@ -47,9 +47,7 @@ public class EnginePlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
sample();
|
if (sample() || !IrisSettings.get().getWorld().isEffectSystem())
|
||||||
|
|
||||||
if (!IrisSettings.get().getWorld().isEffectSystem())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
J.a(() -> {
|
J.a(() -> {
|
||||||
@ -81,22 +79,22 @@ public class EnginePlayer {
|
|||||||
return M.ms() - lastSample;
|
return M.ms() - lastSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sample() {
|
public boolean sample() {
|
||||||
|
Location current = player.getLocation().clone();
|
||||||
|
if (current.getWorld() != engine.getWorld().realWorld())
|
||||||
|
return true;
|
||||||
try {
|
try {
|
||||||
if (ticksSinceLastSample() > 55 && player.getLocation().distanceSquared(lastLocation) > 9 * 9) {
|
if (ticksSinceLastSample() > 55 && current.distanceSquared(lastLocation) > 9 * 9) {
|
||||||
lastLocation = player.getLocation().clone();
|
lastLocation = current;
|
||||||
lastSample = M.ms();
|
lastSample = M.ms();
|
||||||
sampleBiomeRegion();
|
biome = engine.getBiome(current);
|
||||||
|
region = engine.getRegion(current);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
|
|
||||||
private void sampleBiomeRegion() {
|
|
||||||
Location l = player.getLocation();
|
|
||||||
biome = engine.getBiome(l);
|
|
||||||
region = engine.getRegion(l);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,9 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
|||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
|
|
||||||
for (int i = -radius; i <= radius; i++) {
|
int r = radius / 4;
|
||||||
for (int j = -radius; j <= radius; j++) {
|
for (int i = -r; i <= r; i++) {
|
||||||
|
for (int j = -r; j <= r; j++) {
|
||||||
cachedChunks.put(Cache.key(i + x, j + z), mantle.getChunk(i + x, j + z).use());
|
cachedChunks.put(Cache.key(i + x, j + z), mantle.getChunk(i + x, j + z).use());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +144,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
|||||||
|
|
||||||
if (cx >= this.x - radius && cx <= this.x + radius
|
if (cx >= this.x - radius && cx <= this.x + radius
|
||||||
&& cz >= this.z - radius && cz <= this.z + radius) {
|
&& cz >= this.z - radius && cz <= this.z + radius) {
|
||||||
MantleChunk chunk = cachedChunks.get(Cache.key(cx, cz));
|
MantleChunk chunk = cachedChunks.computeIfAbsent(Cache.key(cx, cz), k -> mantle.getChunk(cx, cz).use());
|
||||||
|
|
||||||
if (chunk == null) {
|
if (chunk == null) {
|
||||||
Iris.error("Mantle Writer Accessed " + cx + "," + cz + " and came up null (and yet within bounds!)");
|
Iris.error("Mantle Writer Accessed " + cx + "," + cz + " and came up null (and yet within bounds!)");
|
||||||
@ -152,6 +153,8 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
|||||||
|
|
||||||
Matter matter = chunk.getOrCreate(y >> 4);
|
Matter matter = chunk.getOrCreate(y >> 4);
|
||||||
matter.slice(matter.getClass(t)).set(x & 15, y & 15, z & 15, t);
|
matter.slice(matter.getClass(t)).set(x & 15, y & 15, z & 15, t);
|
||||||
|
} else {
|
||||||
|
Iris.error("Mantle Writer Accessed chunk out of bounds" + cx + "," + cz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,9 +642,10 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
cachedChunks.values().removeIf(c -> {
|
var iterator = cachedChunks.values().iterator();
|
||||||
c.release();
|
while (iterator.hasNext()) {
|
||||||
return true;
|
iterator.next().release();
|
||||||
});
|
iterator.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,9 @@ import com.volmit.iris.util.function.Consumer2;
|
|||||||
import com.volmit.iris.util.function.Consumer3;
|
import com.volmit.iris.util.function.Consumer3;
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@ -373,6 +371,20 @@ public class KMap<K, V> extends ConcurrentHashMap<K, V> {
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KMap<K, V> qclear(BiConsumer<K, V> action) {
|
||||||
|
final Iterator<Map.Entry<K, V>> it = entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
final Map.Entry<K, V> entry = it.next();
|
||||||
|
it.remove();
|
||||||
|
try {
|
||||||
|
action.accept(entry.getKey(), entry.getValue());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a keypair queue
|
* Create a keypair queue
|
||||||
*
|
*
|
||||||
|
@ -24,9 +24,13 @@ import com.google.gson.JsonObject;
|
|||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import org.apache.commons.io.function.IOConsumer;
|
||||||
|
import org.apache.commons.io.function.IOFunction;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -1638,4 +1642,19 @@ public class IO {
|
|||||||
int ch2 = input2.read();
|
int ch2 = input2.read();
|
||||||
return (ch2 == -1);
|
return (ch2 == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends OutputStream> void write(File file, IOFunction<FileOutputStream, T> builder, IOConsumer<T> action) throws IOException {
|
||||||
|
File dir = new File(file.getParentFile(), ".tmp");
|
||||||
|
dir.mkdirs();
|
||||||
|
dir.deleteOnExit();
|
||||||
|
File temp = File.createTempFile("iris",".bin", dir);
|
||||||
|
try {
|
||||||
|
try (var out = builder.apply(new FileOutputStream(temp))) {
|
||||||
|
action.accept(out);
|
||||||
|
}
|
||||||
|
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
} finally {
|
||||||
|
temp.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.RegionCoordinates;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.function.Consumer4;
|
import com.volmit.iris.util.function.Consumer4;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.matter.MatterSlice;
|
import com.volmit.iris.util.matter.MatterSlice;
|
||||||
@ -84,7 +85,7 @@ public class Mantle {
|
|||||||
this.worldHeight = worldHeight;
|
this.worldHeight = worldHeight;
|
||||||
this.ioTrim = new AtomicBoolean(false);
|
this.ioTrim = new AtomicBoolean(false);
|
||||||
this.ioTectonicUnload = new AtomicBoolean(false);
|
this.ioTectonicUnload = new AtomicBoolean(false);
|
||||||
dataFolder.mkdirs();
|
new File(dataFolder, ".tmp").mkdirs();
|
||||||
loadedRegions = new KMap<>();
|
loadedRegions = new KMap<>();
|
||||||
lastUse = new KMap<>();
|
lastUse = new KMap<>();
|
||||||
ioBurst = MultiBurst.burst;
|
ioBurst = MultiBurst.burst;
|
||||||
@ -387,6 +388,7 @@ public class Mantle {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
loadedRegions.clear();
|
loadedRegions.clear();
|
||||||
|
IO.delete(new File(dataFolder, ".tmp"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
b.complete();
|
b.complete();
|
||||||
|
@ -222,14 +222,17 @@ public class TectonicPlate {
|
|||||||
*/
|
*/
|
||||||
public void write(File file) throws IOException {
|
public void write(File file) throws IOException {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
File temp = File.createTempFile("iris-tectonic-plate", ".bin");
|
File temp = File.createTempFile("iris-tectonic-plate", ".bin", new File(file.getParentFile(), ".tmp"));
|
||||||
|
try {
|
||||||
try (DataOutputStream dos = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(temp)))) {
|
try (DataOutputStream dos = new DataOutputStream(new LZ4BlockOutputStream(new FileOutputStream(temp)))) {
|
||||||
write(dos);
|
write(dos);
|
||||||
}
|
}
|
||||||
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName() + C.RED + " in " + Form.duration(p.getMilliseconds(), 2));
|
Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName() + C.RED + " in " + Form.duration(p.getMilliseconds(), 2));
|
||||||
|
} finally {
|
||||||
temp.delete();
|
temp.delete();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write this tectonic plate to a data stream
|
* Write this tectonic plate to a data stream
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.matter.slices;
|
package com.volmit.iris.util.matter.slices;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.data.IrisCustomData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
import com.volmit.iris.util.data.palette.Palette;
|
import com.volmit.iris.util.data.palette.Palette;
|
||||||
import com.volmit.iris.util.matter.Sliced;
|
import com.volmit.iris.util.matter.Sliced;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -63,6 +63,6 @@ public class BlockMatter extends RawMatter<BlockData> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockData readNode(DataInputStream din) throws IOException {
|
public BlockData readNode(DataInputStream din) throws IOException {
|
||||||
return Bukkit.createBlockData(din.readUTF());
|
return B.get(din.readUTF());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ public abstract class Looper extends Thread {
|
|||||||
//noinspection BusyWait
|
//noinspection BusyWait
|
||||||
Thread.sleep(m);
|
Thread.sleep(m);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Iris.reportError(e);
|
|
||||||
break;
|
break;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.volmit.iris.util.sentry;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import io.sentry.Attachment;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
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 Attachment json(Object object, String name) {
|
||||||
|
return new Attachment(GSON.toJson(object).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Attachment jsonProvider(Callable<Object> object, String name) {
|
||||||
|
return new Attachment(() -> GSON.toJson(object.call()).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KMap<String, Object> plugins() {
|
||||||
|
KMap<String, String> enabled = new KMap<>();
|
||||||
|
KMap<String, String> disabled = new KMap<>();
|
||||||
|
|
||||||
|
var pm = Bukkit.getPluginManager();
|
||||||
|
for (var plugin : pm.getPlugins()) {
|
||||||
|
if (plugin.isEnabled()) {
|
||||||
|
enabled.put(plugin.getName(), plugin.getDescription().getVersion());
|
||||||
|
} else {
|
||||||
|
disabled.put(plugin.getName(), plugin.getDescription().getVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new KMap<String, Object>()
|
||||||
|
.qput("enabled", enabled)
|
||||||
|
.qput("disabled", disabled);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.volmit.iris.util.sentry;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import io.sentry.ILogger;
|
||||||
|
import io.sentry.SentryLevel;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
public class IrisLogger implements ILogger {
|
||||||
|
@Override
|
||||||
|
public void log(@NotNull SentryLevel level, @NotNull String message, @Nullable Object... args) {
|
||||||
|
Iris.msg(String.format("%s: %s", level, String.format(message, args)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(@NotNull SentryLevel level, @NotNull String message, @Nullable Throwable throwable) {
|
||||||
|
if (throwable == null) {
|
||||||
|
log(level, message);
|
||||||
|
} else {
|
||||||
|
Iris.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(@NotNull SentryLevel level, @Nullable Throwable throwable, @NotNull String message, @Nullable Object... args) {
|
||||||
|
if (throwable == null) {
|
||||||
|
log(level, message, args);
|
||||||
|
} else {
|
||||||
|
Iris.msg(String.format("%s: %s\n%s", level, String.format(message, throwable), captureStackTrace(throwable)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(@Nullable SentryLevel level) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull String captureStackTrace(@NotNull Throwable throwable) {
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
PrintWriter printWriter = new PrintWriter(stringWriter);
|
||||||
|
throwable.printStackTrace(printWriter);
|
||||||
|
return stringWriter.toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user