diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index cc96233c0..826746193 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -136,11 +136,19 @@ public class IrisSettings { @Data public static class IrisSettingsConcurrency { public int parallelism = -1; + public int worldGenParallelism = -1; + + public int getWorldGenThreads() { + return getThreadCount(worldGenParallelism); + } } @Data public static class IrisSettingsPregen { + public boolean useCacheByDefault = true; + public boolean useHighPriority = false; public boolean useVirtualThreads = false; + public boolean useTicketQueue = false; public int maxConcurrency = 256; } diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index ffeae3115..b3709e43f 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -71,10 +71,12 @@ public class ServerConfigurator { f.load(spigotConfig); long tt = f.getLong("settings.timeout-time"); - if (tt < TimeUnit.MINUTES.toSeconds(5)) { - Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + TimeUnit.MINUTES.toSeconds(20) + " (5 minutes)"); + long spigotTimeout = TimeUnit.MINUTES.toSeconds(5); + + if (tt < spigotTimeout) { + Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + spigotTimeout + " (5 minutes)"); Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value."); - f.set("settings.timeout-time", TimeUnit.MINUTES.toSeconds(5)); + f.set("settings.timeout-time", spigotTimeout); f.save(spigotConfig); } } @@ -84,10 +86,11 @@ public class ServerConfigurator { f.load(spigotConfig); long tt = f.getLong("watchdog.early-warning-delay"); - if (tt < TimeUnit.MINUTES.toMillis(3)) { - Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + TimeUnit.MINUTES.toMillis(15) + " (3 minutes)"); + long watchdog = TimeUnit.MINUTES.toMillis(3); + if (tt < watchdog) { + Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + watchdog + " (3 minutes)"); Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value."); - f.set("watchdog.early-warning-delay", TimeUnit.MINUTES.toMillis(3)); + f.set("watchdog.early-warning-delay", watchdog); f.save(spigotConfig); } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 46e8719a9..4723ed3e1 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -72,7 +72,6 @@ public class CommandIris implements DecreeExecutor { private CommandWhat what; private CommandEdit edit; private CommandFind find; - private CommandSupport support; private CommandDeveloper developer; public static boolean worldCreation = false; String WorldEngine; diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java b/core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java deleted file mode 100644 index 0f7baad0d..000000000 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2022 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.core.commands; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.loader.IrisData; -import com.volmit.iris.core.pregenerator.ChunkUpdater; -import com.volmit.iris.core.service.IrisEngineSVC; -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.util.collection.KList; -import com.volmit.iris.util.decree.DecreeExecutor; -import com.volmit.iris.util.decree.DecreeOrigin; -import com.volmit.iris.util.decree.annotations.Decree; -import com.volmit.iris.util.decree.annotations.Param; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.io.IO; -import com.volmit.iris.util.mantle.TectonicPlate; -import com.volmit.iris.util.misc.Hastebin; -import com.volmit.iris.util.misc.Platform; -import com.volmit.iris.util.misc.getHardware; -import com.volmit.iris.util.nbt.mca.MCAFile; -import com.volmit.iris.util.nbt.mca.MCAUtil; -import com.volmit.iris.util.plugin.VolmitSender; -import net.jpountz.lz4.LZ4BlockInputStream; -import net.jpountz.lz4.LZ4BlockOutputStream; -import net.jpountz.lz4.LZ4FrameInputStream; -import net.jpountz.lz4.LZ4FrameOutputStream; -import org.apache.commons.lang.RandomStringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.World; -import oshi.SystemInfo; - -import java.io.*; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -@Decree(name = "Support", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"support"}) -public class CommandSupport implements DecreeExecutor { - - @Decree(description = "report") - public void report() { - try { - if (sender().isPlayer()) sender().sendMessage(C.GOLD + "Creating report.."); - if (!sender().isPlayer()) Iris.info(C.GOLD + "Creating report.."); - Hastebin.enviornment(sender()); - - } catch (Exception e) { - Iris.info(C.RED + "Something went wrong: "); - e.printStackTrace(); - } - } - - -} - - diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index e2ab1dfc2..757dfcf8f 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -32,30 +32,32 @@ import io.papermc.lib.PaperLib; import org.bukkit.Chunk; import org.bukkit.World; -import java.util.ArrayList; +import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; public class AsyncPregenMethod implements PregeneratorMethod { + private static final AtomicInteger THREAD_COUNT = new AtomicInteger(); private final World world; - private final ExecutorService service; + private final Executor executor; private final Semaphore semaphore; private final int threads; + private final boolean urgent; private final Map lastUse; - public AsyncPregenMethod(World world, int threads) { + public AsyncPregenMethod(World world, int unusedThreads) { if (!PaperLib.isPaper()) { throw new UnsupportedOperationException("Cannot use PaperAsync on non paper!"); } this.world = world; - service = IrisSettings.get().getPregen().isUseVirtualThreads() ? - Executors.newVirtualThreadPerTaskExecutor() : - new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY); + this.executor = IrisSettings.get().getPregen().isUseTicketQueue() ? new TicketExecutor() : new ServiceExecutor(); this.threads = IrisSettings.get().getPregen().getMaxConcurrency(); - semaphore = new Semaphore(threads); + this.semaphore = new Semaphore(this.threads, true); + this.urgent = IrisSettings.get().getPregen().useHighPriority; this.lastUse = new KMap<>(); } @@ -67,13 +69,18 @@ public class AsyncPregenMethod implements PregeneratorMethod { return; } - for (Chunk i : new ArrayList<>(lastUse.keySet())) { - Long lastUseTime = lastUse.get(i); - if (!i.isLoaded() || (lastUseTime != null && M.ms() - lastUseTime >= 10000)) { - i.unload(); - lastUse.remove(i); + long minTime = M.ms() - 10_000; + lastUse.entrySet().removeIf(i -> { + final Chunk chunk = i.getKey(); + final Long lastUseTime = i.getValue(); + if (!chunk.isLoaded() || lastUseTime == null) + return true; + if (lastUseTime < minTime) { + chunk.unload(); + return true; } - } + return false; + }); world.save(); }).get(); } catch (Throwable e) { @@ -81,24 +88,10 @@ public class AsyncPregenMethod implements PregeneratorMethod { } } - private void completeChunk(int x, int z, PregenListener listener) { - try { - PaperLib.getChunkAtAsync(world, x, z, true).thenAccept((i) -> { - lastUse.put(i, M.ms()); - listener.onChunkGenerated(x, z); - listener.onChunkCleaned(x, z); - }).get(); - } catch (InterruptedException ignored) { - } catch (Throwable e) { - e.printStackTrace(); - } finally { - semaphore.release(); - } - } - @Override public void init() { unloadAndSaveAllChunks(); + increaseWorkerThreads(); } @Override @@ -110,7 +103,8 @@ public class AsyncPregenMethod implements PregeneratorMethod { public void close() { semaphore.acquireUninterruptibly(threads); unloadAndSaveAllChunks(); - service.shutdown(); + executor.shutdown(); + resetWorkerThreads(); } @Override @@ -136,7 +130,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } catch (InterruptedException e) { return; } - service.submit(() -> completeChunk(x, z, listener)); + executor.generate(x, z, listener); } @Override @@ -147,4 +141,94 @@ public class AsyncPregenMethod implements PregeneratorMethod { return null; } + + public static void increaseWorkerThreads() { + THREAD_COUNT.updateAndGet(i -> { + if (i > 0) return 1; + var adjusted = IrisSettings.get().getConcurrency().getWorldGenThreads(); + try { + var field = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon").getDeclaredField("WORKER_POOL"); + var pool = field.get(null); + var threads = ((Thread[]) pool.getClass().getDeclaredMethod("getCoreThreads").invoke(pool)).length; + if (threads >= adjusted) return 0; + + pool.getClass().getDeclaredMethod("adjustThreadCount", int.class).invoke(pool, adjusted); + return threads; + } 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("For more information see https://docs.papermc.io/paper/reference/global-configuration#chunk_system_worker_threads"); + if (e instanceof InvocationTargetException) e.printStackTrace(); + } + return 0; + }); + } + + public static void resetWorkerThreads() { + THREAD_COUNT.updateAndGet(i -> { + if (i == 0) return 0; + try { + var field = Class.forName("ca.spottedleaf.moonrise.common.util.MoonriseCommon").getDeclaredField("WORKER_POOL"); + var pool = field.get(null); + var method = pool.getClass().getDeclaredMethod("adjustThreadCount", int.class); + method.invoke(pool, i); + return 0; + } catch (Throwable e) { + Iris.error("Failed to reset worker threads"); + e.printStackTrace(); + } + return i; + }); + } + + private interface Executor { + void generate(int x, int z, PregenListener listener); + default void shutdown() {} + } + + private class ServiceExecutor implements Executor { + private final ExecutorService service = IrisSettings.get().getPregen().isUseVirtualThreads() ? + Executors.newVirtualThreadPerTaskExecutor() : + new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY); + + public void generate(int x, int z, PregenListener listener) { + service.submit(() -> { + try { + PaperLib.getChunkAtAsync(world, x, z, true, urgent).thenAccept((i) -> { + listener.onChunkGenerated(x, z); + listener.onChunkCleaned(x, z); + if (i == null) return; + lastUse.put(i, M.ms()); + }).get(); + } catch (InterruptedException ignored) { + } catch (Throwable e) { + e.printStackTrace(); + } finally { + semaphore.release(); + } + }); + } + + @Override + public void shutdown() { + service.shutdown(); + } + } + + private class TicketExecutor implements Executor { + @Override + public void generate(int x, int z, PregenListener listener) { + PaperLib.getChunkAtAsync(world, x, z, true, urgent) + .exceptionally(e -> { + e.printStackTrace(); + return null; + }) + .thenAccept(i -> { + semaphore.release(); + listener.onChunkGenerated(x, z); + listener.onChunkCleaned(x, z); + if (i == null) return; + lastUse.put(i, M.ms()); + }); + } + } } diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java index 2c59c2ae9..b94d7e89e 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java @@ -160,13 +160,9 @@ public class ServerBootSFG { } public static boolean enoughDiskSpace() { - File freeSpace = new File(Bukkit.getWorldContainer() + "."); + File freeSpace = Bukkit.getWorldContainer(); double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0); - if (gigabytes > 3){ - return true; - } else { - return false; - } + return gigabytes > 3; } private static boolean checkJavac(String path) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java index 8667542a9..d9c6b0bd0 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java @@ -9,6 +9,7 @@ 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.Form; +import com.volmit.iris.util.io.IO; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; @@ -17,11 +18,6 @@ import org.bukkit.Bukkit; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.time.Clock; import java.time.LocalDateTime; import java.util.Collections; @@ -50,10 +46,7 @@ public class IrisPackBenchmarking { .start(() -> { Iris.info("Setting up benchmark environment "); benchmarkInProgress = true; - File file = new File("benchmark"); - if (file.exists()) { - deleteDirectory(file.toPath()); - } + IO.delete(new File(Bukkit.getWorldContainer(), "benchmark")); createBenchmark(); while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) { J.sleep(1000); @@ -72,7 +65,7 @@ public class IrisPackBenchmarking { public void finishedBenchmark(KList cps) { try { - String time = Form.duration(stopwatch.getMillis()); + String time = Form.duration((long) stopwatch.getMilliseconds()); Engine engine = IrisToolbelt.access(Bukkit.getWorld("benchmark")).getEngine(); Iris.info("-----------------"); Iris.info("Results:"); @@ -83,11 +76,7 @@ public class IrisPackBenchmarking { Iris.info(" - Lowest CPS: " + findLowest(cps)); Iris.info("-----------------"); Iris.info("Creating a report.."); - File profilers = new File("plugins" + File.separator + "Iris" + File.separator + "packbenchmarks"); - profilers.mkdir(); - - File results = new File(profilers, dimension.getName() + " " + LocalDateTime.now(Clock.systemDefaultZone()).toString().replace(':', '-') + ".txt"); - results.getParentFile().mkdirs(); + File results = Iris.instance.getDataFile("packbenchmarks", dimension.getName() + " " + LocalDateTime.now(Clock.systemDefaultZone()).toString().replace(':', '-') + ".txt"); KMap metrics = engine.getMetrics().pull(); try (FileWriter writer = new FileWriter(results)) { writer.write("-----------------\n"); @@ -178,26 +167,4 @@ public class IrisPackBenchmarking { private int findHighest(KList list) { return Collections.max(list); } - - private boolean deleteDirectory(Path dir) { - try { - Files.walkFileTree(dir, new SimpleFileVisitor<>() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java index 15b3dc8d3..06651213c 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java @@ -142,7 +142,7 @@ public class IrisToolbelt { * @return the pregenerator job (already started) */ public static PregeneratorJob pregenerate(PregenTask task, PregeneratorMethod method, Engine engine) { - return pregenerate(task, method, engine, true); + return pregenerate(task, method, engine, IrisSettings.get().getPregen().useCacheByDefault); } /** diff --git a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java index 88c5fdc14..7224ea295 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -180,7 +180,10 @@ public class IrisEngine implements Engine { File[] roots = getData().getLoaders() .values() .stream() - .map(ResourceLoader::getRoot) + .map(ResourceLoader::getFolderName) + .map(n -> new File(getData().getDataFolder(), n)) + .filter(File::exists) + .filter(File::isDirectory) .toArray(File[]::new); hash32.complete(IO.hashRecursive(roots)); }); diff --git a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 08962e4af..28e48bd18 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -367,7 +367,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { private void spawn(IrisPosition pos, IrisEntitySpawn i) { IrisSpawner ref = i.getReferenceSpawner(); - if (!ref.canSpawn(getEngine(), pos.getX() >> 4, pos.getZ())) + if (!ref.canSpawn(getEngine(), pos.getX() >> 4, pos.getZ() >> 4)) return; int s = i.spawn(getEngine(), pos, RNG.r); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java index a507c342f..c93ffaade 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java @@ -117,7 +117,7 @@ public class IrisEntitySpawn implements IRare { if (spawns > 0) { if (referenceMarker != null) { - gen.getMantle().getMantle().remove(c.getX(), c.getY(), c.getZ(), MatterMarker.class); + gen.getMantle().getMantle().remove(c.getX(), c.getY() - gen.getWorld().minHeight(), c.getZ(), MatterMarker.class); } for (int id = 0; id < spawns; id++) { diff --git a/core/src/main/java/com/volmit/iris/util/io/IO.java b/core/src/main/java/com/volmit/iris/util/io/IO.java index a8f718885..554058244 100644 --- a/core/src/main/java/com/volmit/iris/util/io/IO.java +++ b/core/src/main/java/com/volmit/iris/util/io/IO.java @@ -18,6 +18,10 @@ package com.volmit.iris.util.io; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.volmit.iris.Iris; import com.volmit.iris.util.format.Form; @@ -134,8 +138,7 @@ public class IO { continue; } - try (var fin = new FileInputStream(file)) { - var din = new CheckedInputStream(fin, crc); + try (var din = new CheckedInputStream(readDeterministic(file), crc)) { fullTransfer(din, new VoidOutputStream(), 8192); } catch (IOException e) { Iris.reportError(e); @@ -152,10 +155,43 @@ public class IO { return 0; } + public static InputStream readDeterministic(File file) throws IOException { + if (!file.getName().endsWith(".json")) + return new FileInputStream(file); + + JsonElement json; + try (FileReader reader = new FileReader(file)) { + json = JsonParser.parseReader(reader); + } + + var queue = new LinkedList(); + queue.add(json); + + while (!queue.isEmpty()) { + var element = queue.pop(); + Collection add = List.of(); + + if (element instanceof JsonObject obj) { + var map = obj.asMap(); + var sorted = new TreeMap<>(map); + map.clear(); + map.putAll(sorted); + + add = sorted.values(); + } else if (element instanceof JsonArray array) { + add = array.asList(); + } + + add.stream().filter(e -> e.isJsonObject() || e.isJsonArray()).forEach(queue::add); + } + + return toInputStream(json.toString()); + } + public static String hash(File b) { try { MessageDigest d = MessageDigest.getInstance("SHA-256"); - DigestInputStream din = new DigestInputStream(new FileInputStream(b), d); + DigestInputStream din = new DigestInputStream(readDeterministic(b), d); fullTransfer(din, new VoidOutputStream(), 8192); din.close(); return bytesToHex(din.getMessageDigest().digest()); diff --git a/core/src/main/java/com/volmit/iris/util/misc/Hastebin.java b/core/src/main/java/com/volmit/iris/util/misc/Hastebin.java deleted file mode 100644 index 11e253b31..000000000 --- a/core/src/main/java/com/volmit/iris/util/misc/Hastebin.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.volmit.iris.util.misc; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.command.CommandSender; -import oshi.SystemInfo; - -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.File; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.file.Files; -import java.util.List; - -public class Hastebin { - - public static void enviornment(CommandSender sender) { - // Construct the server information - StringBuilder sb = new StringBuilder(); - SystemInfo systemInfo = new SystemInfo(); - KList disks = new KList<>(getHardware.getDisk()); - KList interfaces = new KList<>(getHardware.getInterfaces()); - KList displays = new KList<>(getHardware.getEDID()); - KList sensors = new KList<>(getHardware.getSensors()); - KList gpus = new KList<>(getHardware.getGraphicsCards()); - KList powersources = new KList<>(getHardware.getPowerSources()); - - KList IrisWorlds = new KList<>(); - KList BukkitWorlds = new KList<>(); - - for (World w : Bukkit.getServer().getWorlds()) { - try { - Engine engine = IrisToolbelt.access(w).getEngine(); - if (engine != null) { - IrisWorlds.add(w); - } - } catch (Exception e) { - BukkitWorlds.add(w); - } - } - - sb.append(" -- == Iris Info == -- \n"); - sb.append("Iris Version Version: ").append(Iris.instance.getDescription().getVersion()).append("\n"); - sb.append("- Iris Worlds"); - for (World w : IrisWorlds.copy()) { - sb.append(" - ").append(w.getName()); - } - sb.append("- Bukkit Worlds"); - for (World w : BukkitWorlds.copy()) { - sb.append(" - ").append(w.getName()); - } - sb.append(" -- == Platform Overview == -- " + "\n"); - sb.append("Server Type: ").append(Bukkit.getVersion()).append("\n"); - sb.append("Server Uptime: ").append(Form.stampTime(systemInfo.getOperatingSystem().getSystemUptime())).append("\n"); - sb.append("Version: ").append(Platform.getVersion()).append(" - Platform: ").append(Platform.getName()).append("\n"); - sb.append("Java Vendor: ").append(Platform.ENVIRONMENT.getJavaVendor()).append(" - Java Version: ").append(Platform.ENVIRONMENT.getJavaVersion()).append("\n"); - sb.append(" -- == Processor Overview == -- " + "\n"); - sb.append("CPU Model: ").append(getHardware.getCPUModel()); - sb.append("CPU Architecture: ").append(Platform.CPU.getArchitecture()).append(" Available Processors: ").append(Platform.CPU.getAvailableProcessors()).append("\n"); - sb.append("CPU Load: ").append(Form.pc(Platform.CPU.getCPULoad())).append(" CPU Live Process Load: ").append(Form.pc(Platform.CPU.getLiveProcessCPULoad())).append("\n"); - sb.append("-=" + " Graphics " + "=- " + "\n"); - for (String gpu : gpus) { - sb.append(" ").append(gpu).append("\n"); - } - sb.append(" -- == Memory Information == -- " + "\n"); - sb.append("Physical Memory - Total: ").append(Form.memSize(Platform.MEMORY.PHYSICAL.getTotalMemory())).append(" Free: ").append(Form.memSize(Platform.MEMORY.PHYSICAL.getFreeMemory())).append(" Used: ").append(Form.memSize(Platform.MEMORY.PHYSICAL.getUsedMemory())).append("\n"); - sb.append("Virtual Memory - Total: ").append(Form.memSize(Platform.MEMORY.VIRTUAL.getTotalMemory())).append(" Free: ").append(Form.memSize(Platform.MEMORY.VIRTUAL.getFreeMemory())).append(" Used: ").append(Form.memSize(Platform.MEMORY.VIRTUAL.getUsedMemory())).append("\n"); - sb.append(" -- == Storage Information == -- " + "\n"); - for (String disk : disks) { - sb.append(" ").append(sb.append(disk)).append("\n"); - } - sb.append(" -- == Interface Information == -- "+ "\n" ); - for (String inter : interfaces) { - sb.append(" ").append(inter).append("\n"); - } - sb.append(" -- == Display Information == -- "+ "\n" ); - for (String display : displays) { - sb.append(display).append("\n"); - } - sb.append(" -- == Sensor Information == -- " + "\n"); - for (String sensor : sensors) { - sb.append(" ").append(sensor).append("\n"); - } - sb.append(" -- == Power Information == -- " + "\n"); - for (String power : powersources) { - sb.append(" ").append(power).append("\n"); - } - - try { - String hastebinUrl = uploadToHastebin(sb.toString()); - - // Create the clickable message - TextComponent message = new TextComponent("[Link]"); - TextComponent link = new TextComponent(hastebinUrl); - link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, hastebinUrl)); - message.addExtra(link); - - // Send the clickable message to the player - sender.spigot().sendMessage(message); - } catch (Exception e) { - sender.sendMessage(C.DARK_RED + "Failed to upload server information to Hastebin."); - } - } - - private static String uploadToHastebin(String content) throws Exception { - URL url = new URL("https://paste.bytecode.ninja/documents"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "text/plain"); - conn.setDoOutput(true); - - DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); - wr.writeBytes(content); - wr.flush(); - wr.close(); - - BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String response = br.readLine(); - br.close(); - - return "https://paste.bytecode.ninja/" + response.split("\"")[3]; - } - - -} \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/misc/Platform.java b/core/src/main/java/com/volmit/iris/util/misc/Platform.java deleted file mode 100644 index afbf7c8c3..000000000 --- a/core/src/main/java/com/volmit/iris/util/misc/Platform.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.volmit.iris.util.misc; - -import com.sun.management.OperatingSystemMXBean; - -import java.io.File; -import java.lang.management.ManagementFactory; - -@SuppressWarnings("restriction") -public class Platform { - public static String getVersion() { - return getSystem().getVersion(); - } - - public static String getName() { - return getSystem().getName(); - } - - private static OperatingSystemMXBean getSystem() { - return (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); - } - - public static class ENVIRONMENT { - public static boolean canRunBatch() { - return getSystem().getName().toLowerCase().contains("windows"); - } - - public static String getJavaHome() { - return System.getProperty("java.home"); - } - - public static String getJavaVendor() { - return System.getProperty("java.vendor"); - } - - public static String getJavaVersion() { - return System.getProperty("java.version"); - } - } - - public static class STORAGE { - public static long getAbsoluteTotalSpace() { - long t = 0; - - for (File i : getRoots()) { - t += getTotalSpace(i); - } - - return t; - } - - public static long getTotalSpace() { - return getTotalSpace(new File(".")); - } - - public static long getTotalSpace(File root) { - return root.getTotalSpace(); - } - - public static long getAbsoluteFreeSpace() { - long t = 0; - - for (File i : getRoots()) { - t += getFreeSpace(i); - } - - return t; - } - - public static long getFreeSpace() { - return getFreeSpace(new File(".")); - } - - public static long getFreeSpace(File root) { - return root.getFreeSpace(); - } - - public static long getUsedSpace() { - return getTotalSpace() - getFreeSpace(); - } - - public static long getUsedSpace(File root) { - return getTotalSpace(root) - getFreeSpace(root); - } - - public static long getAbsoluteUsedSpace() { - return getAbsoluteTotalSpace() - getAbsoluteFreeSpace(); - } - - public static File[] getRoots() { - return File.listRoots(); - } - } - - public static class MEMORY { - public static class PHYSICAL { - public static long getTotalMemory() { - return getSystem().getTotalPhysicalMemorySize(); - } - - public static long getFreeMemory() { - return getSystem().getFreePhysicalMemorySize(); - } - - public static long getUsedMemory() { - return getTotalMemory() - getFreeMemory(); - } - } - - public static class VIRTUAL { - public static long getTotalMemory() { - return getSystem().getTotalSwapSpaceSize(); - } - - public static long getFreeMemory() { - return getSystem().getFreeSwapSpaceSize(); - } - - public static long getUsedMemory() { - return getTotalMemory() - getFreeMemory(); - } - - public static long getCommittedVirtualMemory() { - return getSystem().getCommittedVirtualMemorySize(); - } - } - } - - public static class CPU { - public static int getAvailableProcessors() { - return getSystem().getAvailableProcessors(); - } - - public static double getCPULoad() { - return getSystem().getSystemCpuLoad(); - } - - public static double getLiveProcessCPULoad() { - return getSystem().getProcessCpuLoad(); - } - - public static String getArchitecture() { - return getSystem().getArch(); - } - } -} \ No newline at end of file