mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-01 23:47:21 +00:00
commit
52fecb48d8
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -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<Chunk, Long> 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());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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<Integer> 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<String, Double> metrics = engine.getMetrics().pull();
|
||||
try (FileWriter writer = new FileWriter(results)) {
|
||||
writer.write("-----------------\n");
|
||||
@ -178,26 +167,4 @@ public class IrisPackBenchmarking {
|
||||
private int findHighest(KList<Integer> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
});
|
||||
|
@ -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);
|
||||
|
@ -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++) {
|
||||
|
@ -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<JsonElement>();
|
||||
queue.add(json);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
var element = queue.pop();
|
||||
Collection<JsonElement> 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());
|
||||
|
@ -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<String> disks = new KList<>(getHardware.getDisk());
|
||||
KList<String> interfaces = new KList<>(getHardware.getInterfaces());
|
||||
KList<String> displays = new KList<>(getHardware.getEDID());
|
||||
KList<String> sensors = new KList<>(getHardware.getSensors());
|
||||
KList<String> gpus = new KList<>(getHardware.getGraphicsCards());
|
||||
KList<String> powersources = new KList<>(getHardware.getPowerSources());
|
||||
|
||||
KList<World> IrisWorlds = new KList<>();
|
||||
KList<World> 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];
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user