mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-19 10:43:14 +00:00
Cleanup old compat
This commit is contained in:
parent
326bddad2a
commit
18195b778a
@ -78,9 +78,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
public static MultiverseCoreLink linkMultiverseCore;
|
||||
public static MythicMobsLink linkMythicMobs;
|
||||
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
||||
public static boolean customModels = doesSupportCustomModels();
|
||||
public static boolean awareEntities = doesSupportAwareness();
|
||||
public static boolean lowMemoryMode = false;
|
||||
public static IrisCompat compat;
|
||||
public static FileWatcher configWatcher;
|
||||
|
||||
@ -94,7 +91,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
instance = this;
|
||||
INMS.get();
|
||||
IO.delete(new File("iris"));
|
||||
lowMemoryMode = Runtime.getRuntime().maxMemory() < 4000000000L; // 4 * 1000 * 1000 * 1000 // 4;
|
||||
installDataPacks();
|
||||
}
|
||||
|
||||
@ -155,30 +151,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
Iris.info("Data Packs Setup!");
|
||||
}
|
||||
|
||||
private static boolean doesSupportCustomModels() {
|
||||
try {
|
||||
int v = Integer.parseInt(Bukkit.getBukkitVersion().split("\\Q-\\E")[0].split("\\Q.\\E")[1]);
|
||||
|
||||
return v >= 14;
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean doesSupportAwareness() {
|
||||
try {
|
||||
int v = Integer.parseInt(Bukkit.getBukkitVersion().split("\\Q-\\E")[0].split("\\Q.\\E")[1]);
|
||||
|
||||
return v >= 15;
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
@ -545,18 +517,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
}
|
||||
|
||||
Iris.info("\n\n " + new KList<>(splash).toString("\n") + "\n");
|
||||
|
||||
if (lowMemoryMode) {
|
||||
Iris.verbose("* Low Memory mode Activated! For better performance, allocate 4gb or more to this server.");
|
||||
}
|
||||
|
||||
if (!customModels) {
|
||||
Iris.verbose("* This version of minecraft does not support custom model data in loot items (1.14 and up). Iris will generate as normal, but loot will not have custom models.");
|
||||
}
|
||||
|
||||
if (!doesSupportAwareness()) {
|
||||
Iris.verbose("* This version of minecraft does not support entity awareness.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -63,7 +63,7 @@ public class IrisSettings {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return c < 0 ? Runtime.getRuntime().availableProcessors() / -c : c;
|
||||
return Math.max(2, c < 0 ? Runtime.getRuntime().availableProcessors() / -c : c);
|
||||
}
|
||||
|
||||
@Data
|
||||
@ -73,8 +73,12 @@ public class IrisSettings {
|
||||
|
||||
@Data
|
||||
public static class IrisSettingsConcurrency {
|
||||
public int threadCount = -1;
|
||||
public int engineThreadCount = -1;
|
||||
public int engineThreadPriority = 6;
|
||||
public int pregenThreadCount = -1;
|
||||
public int pregenThreadPriority = 8;
|
||||
public int miscThreadCount = -4;
|
||||
public int miscThreadPriority = 3;
|
||||
}
|
||||
|
||||
@Data
|
||||
|
@ -21,7 +21,6 @@ package com.volmit.iris.core.command.world;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisDataManager;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.gui.components.Pregenerator;
|
||||
import com.volmit.iris.core.link.MultiverseCoreLink;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.tools.IrisWorldCreator;
|
||||
@ -161,8 +160,7 @@ public class CommandIrisCreate extends MortarCommand {
|
||||
sender.sendMessage("Pregenerating " + worldName + " " + size + " x " + size);
|
||||
sender.sendMessage("Expect server lag during this time. Use '/iris pregen stop' to cancel");
|
||||
|
||||
new Pregenerator(world.get(), size, () ->
|
||||
b.set(true));
|
||||
|
||||
}
|
||||
|
||||
World ww = world.get();
|
||||
@ -248,15 +246,6 @@ public class CommandIrisCreate extends MortarCommand {
|
||||
|
||||
World w = INMS.get().createWorld(wc);
|
||||
world.set(w);
|
||||
|
||||
try {
|
||||
if (pregen.get() > 0) {
|
||||
new Pregenerator(w, pregen.get());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
done.set(true);
|
||||
});
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.plugin.MortarCommand;
|
||||
@ -108,12 +109,11 @@ public class CommandIrisPregen extends MortarCommand {
|
||||
}
|
||||
}
|
||||
try {
|
||||
new PregeneratorJob(PregenTask
|
||||
IrisToolbelt.pregenerate(PregenTask
|
||||
.builder()
|
||||
.center(new Position2(0, 0))
|
||||
.radius(((getVal(args[0])>>4)>>5) + 1)
|
||||
.build(),
|
||||
new HybridPregenMethod(world, Runtime.getRuntime().availableProcessors()));
|
||||
.center(new Position2(0, 0))
|
||||
.radius(((getVal(args[0])>>4)>>5) + 1)
|
||||
.build(), world);
|
||||
} catch (NumberFormatException e) {
|
||||
Iris.reportError(e);
|
||||
sender.sendMessage("Invalid argument in command");
|
||||
|
@ -1,638 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.gui.components;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.tools.IrisWorlds;
|
||||
import com.volmit.iris.engine.data.mca.MCAFile;
|
||||
import com.volmit.iris.engine.data.mca.NBTWorld;
|
||||
import com.volmit.iris.engine.framework.IrisAccess;
|
||||
import com.volmit.iris.engine.parallel.BurstExecutor;
|
||||
import com.volmit.iris.engine.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.function.Consumer2;
|
||||
import com.volmit.iris.util.function.Consumer3;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import com.volmit.iris.util.scheduling.SR;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import lombok.Data;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Deprecated
|
||||
@Data
|
||||
public class Pregenerator implements Listener {
|
||||
private static Pregenerator instance;
|
||||
private static final Color COLOR_ERROR = Color.decode("#E34113");
|
||||
private static final Color COLOR_MCA_PREPARE = Color.decode("#3CAAB5");
|
||||
private static final Color COLOR_MCA_RELOAD = Color.decode("#41FF61");
|
||||
private static final Color COLOR_MCA_GENERATE = Color.decode("#33FF8F");
|
||||
private static final Color COLOR_MCA_GENERATE_SLOW = Color.decode("#13BAE3");
|
||||
private static final Color COLOR_MCA_GENERATE_SLOW_ASYNC = Color.decode("#13BAE3");
|
||||
private static final Color COLOR_MCA_GENERATED = Color.decode("#33FF8F");
|
||||
private static final Color COLOR_MCA_GENERATED_MCA = Color.decode("#13E3C9");
|
||||
private static final Color COLOR_MCA_SEALED = Color.decode("#33FF8F");
|
||||
private static final Color COLOR_MCA_DEFERRED = Color.decode("#3CB57A");
|
||||
private final World world;
|
||||
private int lowestBedrock;
|
||||
private final NBTWorld directWriter;
|
||||
private final AtomicBoolean active;
|
||||
private final AtomicBoolean running;
|
||||
private final KList<Position2> errors;
|
||||
private final KList<Runnable> onComplete;
|
||||
private final Position2 max;
|
||||
private final Position2 min;
|
||||
private final MCAPregenGui gui;
|
||||
private final KList<Position2> mcaDefer;
|
||||
private final AtomicInteger generated;
|
||||
private final AtomicInteger generatedLast;
|
||||
private final RollingSequence perSecond;
|
||||
private final RollingSequence perMinute;
|
||||
private final AtomicInteger totalChunks;
|
||||
private final AtomicLong memory;
|
||||
private final AtomicReference<String> memoryMetric;
|
||||
private final AtomicReference<String> method;
|
||||
private final AtomicInteger vmcax;
|
||||
private final AtomicInteger vmcaz;
|
||||
private final AtomicInteger vcax;
|
||||
private final AtomicInteger vcaz;
|
||||
private final long elapsed;
|
||||
private final ChronoLatch latch;
|
||||
private IrisAccess access;
|
||||
private final KList<Position2> regionReload;
|
||||
private KList<Position2> wait = new KList<>();
|
||||
|
||||
public Pregenerator(World world, int blockSize, Runnable onComplete) {
|
||||
this(world, blockSize);
|
||||
this.onComplete.add(onComplete);
|
||||
}
|
||||
|
||||
public Pregenerator(World world, int blockSize) throws HeadlessException {
|
||||
this(world, blockSize, true);
|
||||
}
|
||||
|
||||
public Pregenerator(World world, int blockSize, boolean dogui) throws HeadlessException {
|
||||
instance();
|
||||
regionReload = new KList<>();
|
||||
latch = new ChronoLatch(5000);
|
||||
memoryMetric = new AtomicReference<>("...");
|
||||
method = new AtomicReference<>("STARTUP");
|
||||
memory = new AtomicLong(0);
|
||||
this.world = world;
|
||||
errors = new KList<>();
|
||||
vmcax = new AtomicInteger();
|
||||
vmcaz = new AtomicInteger();
|
||||
vcax = new AtomicInteger();
|
||||
vcaz = new AtomicInteger();
|
||||
perMinute = new RollingSequence(200);
|
||||
perSecond = new RollingSequence(20);
|
||||
generatedLast = new AtomicInteger(0);
|
||||
totalChunks = new AtomicInteger(0);
|
||||
generated = new AtomicInteger(0);
|
||||
mcaDefer = new KList<>();
|
||||
access = IrisWorlds.access(world);
|
||||
this.directWriter = new NBTWorld(world.getWorldFolder());
|
||||
this.running = new AtomicBoolean(true);
|
||||
this.active = new AtomicBoolean(true);
|
||||
MultiBurst burst = new MultiBurst("Iris Pregenerator", 9, Runtime.getRuntime().availableProcessors());
|
||||
int mcaSize = (((blockSize >> 4) + 2) >> 5) + 1;
|
||||
onComplete = new KList<>();
|
||||
max = new Position2(0, 0);
|
||||
min = new Position2(0, 0);
|
||||
KList<Runnable> draw = new KList<>();
|
||||
new Spiraler(mcaSize, mcaSize, (xx, zz) -> {
|
||||
min.setX(Math.min(xx << 5, min.getX()));
|
||||
min.setZ(Math.min(zz << 5, min.getZ()));
|
||||
max.setX(Math.max((xx << 5) + 31, max.getX()));
|
||||
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
|
||||
totalChunks.getAndAdd(1024);
|
||||
draw.add(() -> drawMCA(xx, zz, COLOR_MCA_PREPARE));
|
||||
}).drain();
|
||||
if (access != null) {
|
||||
lowestBedrock = access.getCompound().getLowestBedrock();
|
||||
}
|
||||
gui = dogui ? (IrisSettings.get().getGui().isLocalPregenGui() && IrisSettings.get().getGui().isUseServerLaunchedGuis() ? MCAPregenGui.createAndShowGUI(this) : null) : null;
|
||||
flushWorld();
|
||||
KList<Position2> order = computeChunkOrder();
|
||||
Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration =
|
||||
(ox, oz, r) -> order.forEach((i)
|
||||
-> r.accept(i.getX() + ox, i.getZ() + oz));
|
||||
draw.forEach(Runnable::run);
|
||||
Spiraler spiraler = new Spiraler(mcaSize, mcaSize, (xx, zz) -> {
|
||||
vmcax.set(xx);
|
||||
vmcaz.set(zz);
|
||||
flushWorld();
|
||||
drawMCA(xx, zz, COLOR_MCA_PREPARE);
|
||||
if (access != null && generateMCARegion(xx, zz, burst, access, mcaIteration)) {
|
||||
flushWorld();
|
||||
}
|
||||
});
|
||||
|
||||
elapsed = M.ms();
|
||||
|
||||
new Thread(() -> {
|
||||
flushWorld();
|
||||
J.sleep(2000);
|
||||
flushWorld();
|
||||
|
||||
while (running.get() && spiraler.hasNext()) {
|
||||
if (active.get()) {
|
||||
spiraler.next();
|
||||
}
|
||||
}
|
||||
|
||||
mcaDefer.removeDuplicates();
|
||||
|
||||
while (running.get() && mcaDefer.isNotEmpty()) {
|
||||
Position2 p = mcaDefer.popLast();
|
||||
vmcax.set(p.getX());
|
||||
vmcaz.set(p.getZ());
|
||||
generateDeferedMCARegion(p.getX(), p.getZ(), burst, mcaIteration);
|
||||
flushWorld();
|
||||
}
|
||||
|
||||
while (wait.isNotEmpty()) {
|
||||
J.sleep(50);
|
||||
}
|
||||
|
||||
burst.shutdownNow();
|
||||
directWriter.close();
|
||||
flushWorld();
|
||||
onComplete.forEach(Runnable::run);
|
||||
running.set(false);
|
||||
active.set(false);
|
||||
if (gui != null) {
|
||||
gui.close();
|
||||
}
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
|
||||
while (running.get() && active.get()) {
|
||||
int m = generated.get();
|
||||
int w = generatedLast.get();
|
||||
int up = m - w;
|
||||
double dur = p.getMilliseconds();
|
||||
perSecond.put((int) (up / (dur / 1000D)));
|
||||
perMinute.put((int) (up / (dur / 60000D)));
|
||||
p.reset();
|
||||
p.begin();
|
||||
updateProgress();
|
||||
generatedLast.set(m);
|
||||
J.sleep(100);
|
||||
long lmem = memory.get();
|
||||
memory.set(Runtime.getRuntime().freeMemory());
|
||||
|
||||
if (memory.get() > lmem) {
|
||||
long free = memory.get();
|
||||
long max = Runtime.getRuntime().maxMemory();
|
||||
long total = Runtime.getRuntime().totalMemory();
|
||||
long use = total - free;
|
||||
memoryMetric.set(Form.memSize(use, 2) + " (" + Form.pc((double) use / (double) max, 0) + ")");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private boolean generateMCARegion(int x, int z, MultiBurst burst, IrisAccess access, Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration) {
|
||||
if (!Iris.instance.isMCA()) {
|
||||
generateDeferedMCARegion(x, z, burst, mcaIteration);
|
||||
return false;
|
||||
}
|
||||
|
||||
File mca = directWriter.getRegionFile(x, z);
|
||||
BurstExecutor e = burst.burst(1024);
|
||||
int mcaox = x << 5;
|
||||
int mcaoz = z << 5;
|
||||
if (isMCAWritable(x, z) && !mca.exists()) {
|
||||
method.set("Direct (Fast)");
|
||||
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> {
|
||||
draw(ii, jj, COLOR_MCA_GENERATE);
|
||||
access.directWriteChunk(access.getCompound().getWorld(), ii, jj, directWriter);
|
||||
draw(ii, jj, COLOR_MCA_GENERATED_MCA);
|
||||
generated.getAndIncrement();
|
||||
vcax.set(ii);
|
||||
vcaz.set(jj);
|
||||
}));
|
||||
e.complete();
|
||||
//verifyMCA(x, z, burst);
|
||||
directWriter.save();
|
||||
} else {
|
||||
totalChunks.getAndAdd(1024);
|
||||
mcaDefer.add(new Position2(x, z));
|
||||
e.complete();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void verifyMCA(int x, int z, MultiBurst burst) {
|
||||
MCAFile rg = directWriter.getMCA(x, z);
|
||||
KList<Runnable> requeue = new KList<>();
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
for(int j = 0; j < 32; j++)
|
||||
{
|
||||
com.volmit.iris.engine.data.mca.Chunk c = rg.getChunk(i, j);
|
||||
|
||||
if(c == null)
|
||||
{
|
||||
draw(((x << 5) + i), ((z << 5) + j), COLOR_ERROR);
|
||||
int finalI = i;
|
||||
int finalJ = j;
|
||||
requeue.add(() -> {
|
||||
draw(((x << 5) + finalI), ((z << 5) + finalJ), COLOR_MCA_GENERATE);
|
||||
access.directWriteChunk(access.getCompound().getWorld(), ((x << 5) + finalI), ((z << 5) + finalJ), directWriter);
|
||||
draw(((x << 5) + finalI), ((z << 5) + finalJ), COLOR_MCA_GENERATED_MCA);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(requeue.isNotEmpty())
|
||||
{
|
||||
burst.burst(requeue);
|
||||
verifyMCA(x, z, burst);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateProgress() {
|
||||
if (!latch.flip()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] v = getProgress();
|
||||
Iris.info("Pregeneration " + v[0] + " | " + v[1] + " | " + v[2] + " | " + v[3]);
|
||||
}
|
||||
|
||||
private void generateDeferedMCARegion(int x, int z, MultiBurst burst, Consumer3<Integer, Integer, Consumer2<Integer, Integer>> mcaIteration) {
|
||||
int mcaox = x << 5;
|
||||
int mcaoz = z << 5;
|
||||
if (PaperLib.isPaper()) {
|
||||
method.set("PaperAsync (Slow)");
|
||||
|
||||
while (wait.size() > 16) {
|
||||
J.sleep(5);
|
||||
}
|
||||
|
||||
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> {
|
||||
Position2 cx = new Position2(ii, jj);
|
||||
PaperLib.getChunkAtAsync(world, ii, jj).thenAccept((c) -> {
|
||||
draw(ii, jj, COLOR_MCA_GENERATE_SLOW_ASYNC);
|
||||
draw(ii, jj, COLOR_MCA_GENERATED);
|
||||
generated.getAndIncrement();
|
||||
vcax.set(ii);
|
||||
vcaz.set(jj);
|
||||
|
||||
synchronized (wait) {
|
||||
wait.remove(cx);
|
||||
}
|
||||
});
|
||||
|
||||
wait.add(cx);
|
||||
});
|
||||
} else {
|
||||
AtomicInteger m = new AtomicInteger();
|
||||
method.set("Spigot (Very Slow)");
|
||||
KList<Runnable> q = new KList<>();
|
||||
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> q.add(() -> {
|
||||
draw(ii, jj, COLOR_MCA_GENERATE_SLOW);
|
||||
world.getChunkAt(ii, jj).load(true);
|
||||
Chunk c = world.getChunkAt(ii, jj);
|
||||
draw(ii, jj, COLOR_MCA_GENERATED);
|
||||
m.getAndIncrement();
|
||||
generated.getAndIncrement();
|
||||
vcax.set(ii);
|
||||
vcaz.set(jj);
|
||||
}));
|
||||
ChronoLatch tick = new ChronoLatch(1000);
|
||||
new SR(0) {
|
||||
@Override
|
||||
public void run() {
|
||||
if (tick.flip()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.isEmpty()) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
q.pop().run();
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
while (m.get() < 1024) {
|
||||
J.sleep(25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private KList<Position2> computeChunkOrder() {
|
||||
Position2 center = new Position2(15, 15);
|
||||
KList<Position2> p = new KList<>();
|
||||
new Spiraler(33, 33, (x, z) -> {
|
||||
int xx = x + 15;
|
||||
int zz = z + 15;
|
||||
if (xx < 0 || xx > 31 || zz < 0 || zz > 31) {
|
||||
return;
|
||||
}
|
||||
|
||||
p.add(new Position2(xx, zz));
|
||||
}).drain();
|
||||
p.sort(Comparator.comparing((i) -> i.distance(center)));
|
||||
return p;
|
||||
}
|
||||
|
||||
public static Pregenerator getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static boolean shutdownInstance() {
|
||||
if (instance != null) {
|
||||
instance.shutdown();
|
||||
instance = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void pauseResume() {
|
||||
instance.active.set(!instance.active.get());
|
||||
}
|
||||
|
||||
public static boolean isPaused() {
|
||||
return instance.paused();
|
||||
}
|
||||
|
||||
private void instance() {
|
||||
if (instance != null) {
|
||||
instance.shutdown();
|
||||
}
|
||||
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
running.set(false);
|
||||
active.set(false);
|
||||
}
|
||||
|
||||
private void draw(int cx, int cz, Color color) {
|
||||
if (gui != null) {
|
||||
gui.func.accept(new Position2(cx, cz), color);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawMCA(int cx, int cz, Color color) {
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (int j = 0; j < 32; j++) {
|
||||
draw((cx << 5) + i, (cz << 5) + j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void flushWorld() {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
flushWorldSync();
|
||||
return;
|
||||
}
|
||||
|
||||
AtomicBoolean b = new AtomicBoolean(false);
|
||||
J.s(() -> {
|
||||
flushWorldSync();
|
||||
b.set(true);
|
||||
});
|
||||
|
||||
while (!b.get()) {
|
||||
J.sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void flushWorldSync() {
|
||||
for (Chunk i : world.getLoadedChunks()) {
|
||||
i.unload(true);
|
||||
}
|
||||
|
||||
world.save();
|
||||
}
|
||||
|
||||
private boolean isMCAWritable(int x, int z) {
|
||||
File mca = new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca");
|
||||
|
||||
if (mca.exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Chunk i : world.getLoadedChunks()) {
|
||||
if (i.getX() >> 5 == x && i.getZ() >> 5 == z) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String[] getProgress() {
|
||||
long eta = (long) ((totalChunks.get() - generated.get()) * ((double) (M.ms() - elapsed) / (double) generated.get()));
|
||||
|
||||
return new String[]{
|
||||
"Progress: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (" + Form.pc((double) generated.get() / (double) totalChunks.get(), 0) + ")",
|
||||
"ETA: " + Form.duration(eta, 0),
|
||||
"Chunks/s: " + Form.f((int) perSecond.getAverage()) + " (" + Form.f((int)perSecond.getMax()) + " Peak)",
|
||||
"Chunks/min: " + Form.f((int) perMinute.getAverage())+ " (" + Form.f((int)perMinute.getMax()) + " Peak)",
|
||||
"Memory: " + memoryMetric.get(),
|
||||
"Cursor: " + "MCA(" + vmcax.get() + ", " + vmcaz.get() + ") @ (" + vcax.get() + ", " + vcaz.get() + ")",
|
||||
"Gen Mode: " + method.get(),
|
||||
};
|
||||
}
|
||||
|
||||
public boolean paused() {
|
||||
return !active.get();
|
||||
}
|
||||
|
||||
public static class MCAPregenGui extends JPanel implements KeyListener {
|
||||
private Pregenerator job;
|
||||
private static final long serialVersionUID = 2094606939770332040L;
|
||||
private final KList<Runnable> order = new KList<>();
|
||||
private final int res = 512;
|
||||
Graphics2D bg;
|
||||
private ReentrantLock l;
|
||||
private final BufferedImage image = new BufferedImage(res, res, BufferedImage.TYPE_INT_RGB);
|
||||
private Consumer2<Position2, Color> func;
|
||||
private JFrame frame;
|
||||
|
||||
public MCAPregenGui() {
|
||||
|
||||
}
|
||||
|
||||
public void paint(int x, int z, Color c) {
|
||||
func.accept(new Position2(x, z), c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics gx) {
|
||||
Graphics2D g = (Graphics2D) gx;
|
||||
bg = (Graphics2D) image.getGraphics();
|
||||
|
||||
l.lock();
|
||||
while (order.isNotEmpty()) {
|
||||
try {
|
||||
order.pop().run();
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
}
|
||||
}
|
||||
l.unlock();
|
||||
|
||||
g.drawImage(image, 0, 0, getParent().getWidth(), getParent().getHeight(), (img, infoflags, x, y, width, height) -> true);
|
||||
|
||||
g.setColor(Color.WHITE);
|
||||
g.setFont(new Font("Hevetica", Font.BOLD, 28));
|
||||
String[] prog = job.getProgress();
|
||||
int h = g.getFontMetrics().getHeight() + 5;
|
||||
int hh = 20;
|
||||
|
||||
if (job.paused()) {
|
||||
g.drawString("PAUSED", 20, hh += h);
|
||||
|
||||
g.drawString("Press P to Resume", 20, hh += h);
|
||||
} else {
|
||||
for (String i : prog) {
|
||||
g.drawString(i, 20, hh += h);
|
||||
}
|
||||
|
||||
g.drawString("Press P to Pause", 20, hh += h);
|
||||
}
|
||||
|
||||
J.sleep(IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250);
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void draw(Position2 p, Color c, Graphics2D bg) {
|
||||
double pw = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX());
|
||||
double ph = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ());
|
||||
double pwa = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX() + 1);
|
||||
double pha = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ() + 1);
|
||||
int x = (int) M.lerp(0, res, pw);
|
||||
int z = (int) M.lerp(0, res, ph);
|
||||
int xa = (int) M.lerp(0, res, pwa);
|
||||
int za = (int) M.lerp(0, res, pha);
|
||||
bg.setColor(c);
|
||||
bg.fillRect(x, z, xa - x, za - z);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static MCAPregenGui createAndShowGUI(Pregenerator j) throws HeadlessException {
|
||||
JFrame frame;
|
||||
frame = new JFrame("Pregen View");
|
||||
MCAPregenGui nv = new MCAPregenGui();
|
||||
frame.addKeyListener(nv);
|
||||
nv.l = new ReentrantLock();
|
||||
nv.frame = frame;
|
||||
nv.job = j;
|
||||
nv.func = (c, b) ->
|
||||
{
|
||||
if (b.equals(Color.pink) && c.equals(new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE))) {
|
||||
frame.hide();
|
||||
}
|
||||
nv.l.lock();
|
||||
nv.order.add(() -> nv.draw(c, b, nv.bg));
|
||||
nv.l.unlock();
|
||||
};
|
||||
frame.add(nv);
|
||||
frame.setSize(1000, 1000);
|
||||
frame.setVisible(true);
|
||||
File file = Iris.getCached("Iris Icon", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/icon.png");
|
||||
|
||||
if (file != null) {
|
||||
try {
|
||||
frame.setIconImage(ImageIO.read(file));
|
||||
} catch (IOException ignored) {
|
||||
Iris.reportError(ignored);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nv;
|
||||
}
|
||||
|
||||
public static void launch(Pregenerator g) {
|
||||
J.a(() ->
|
||||
{
|
||||
createAndShowGUI(g);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_P) {
|
||||
Pregenerator.pauseResume();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
frame.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
}
|
||||
|
||||
this.world = world;
|
||||
burst = new MultiBurst("Iris PaperAsync Pregenerator", 6, threads);
|
||||
burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads);
|
||||
future = new KList<>(1024);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ package com.volmit.iris.core.tools;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisDataManager;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||
@ -121,7 +122,24 @@ public class IrisToolbelt {
|
||||
return pregenerate(task, new HeadlessPregenMethod(access.getHeadlessGenerator().getWorld(), access.getHeadlessGenerator()));
|
||||
}
|
||||
|
||||
return pregenerate(task, new HybridPregenMethod(access.getCompound().getWorld().realWorld(), Runtime.getRuntime().availableProcessors()));
|
||||
return pregenerate(task, new HybridPregenMethod(access.getCompound().getWorld().realWorld(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a pregenerator task. If the supplied generator is headless, headless mode is used,
|
||||
* otherwise Hybrid mode is used.
|
||||
* @param task the scheduled task
|
||||
* @param world the World
|
||||
* @return the pregenerator job (already started)
|
||||
*/
|
||||
public static PregeneratorJob pregenerate(PregenTask task, World world)
|
||||
{
|
||||
if(isIrisWorld(world))
|
||||
{
|
||||
return pregenerate(task, access(world));
|
||||
}
|
||||
|
||||
return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,7 @@ package com.volmit.iris.engine;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisDataManager;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineCompound;
|
||||
import com.volmit.iris.engine.framework.EngineData;
|
||||
@ -98,7 +99,7 @@ public class IrisEngineCompound implements EngineCompound {
|
||||
} else {
|
||||
double totalWeight = 0D;
|
||||
engines = new Engine[rootDimension.getDimensionalComposite().size()];
|
||||
burster = engines.length > 1 ? new MultiBurst(engines.length) : null;
|
||||
burster = engines.length > 1 ? new MultiBurst("Iris Compound " + rootDimension.getName(), IrisSettings.get().getConcurrency().getEngineThreadPriority(), engines.length) : null;
|
||||
int threadDist = (Math.max(2, maximumThreads - engines.length)) / engines.length;
|
||||
|
||||
if ((threadDist * engines.length) + engines.length > maximumThreads) {
|
||||
|
@ -357,8 +357,13 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
return getCompound().isStudio();
|
||||
}
|
||||
|
||||
default MultiBurst burst()
|
||||
{
|
||||
return getTarget().getBurster();
|
||||
}
|
||||
|
||||
default void clean() {
|
||||
MultiBurst.burst.lazy(() -> getParallax().cleanup());
|
||||
burst().lazy(() -> getParallax().cleanup());
|
||||
}
|
||||
|
||||
default IrisBiome getBiome(Location l) {
|
||||
|
@ -302,7 +302,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
|
||||
initialized.set(true);
|
||||
IrisDimension dim = getDimension(world);
|
||||
IrisDataManager data = production ? new IrisDataManager(getDataFolder(world)) : dim.getLoader().copy();
|
||||
compound.set(new IrisEngineCompound(world, dim, data, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getThreadCount())));
|
||||
compound.set(new IrisEngineCompound(world, dim, data, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount())));
|
||||
compound.get().setStudio(!production);
|
||||
populators.clear();
|
||||
populators.addAll(compound.get().getPopulators());
|
||||
|
@ -19,6 +19,7 @@
|
||||
package com.volmit.iris.engine.framework;
|
||||
|
||||
import com.volmit.iris.core.IrisDataManager;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.engine.object.common.IrisWorld;
|
||||
import com.volmit.iris.engine.parallax.ParallaxWorld;
|
||||
@ -43,7 +44,7 @@ public class EngineTarget {
|
||||
this.dimension = dimension;
|
||||
this.data = data;
|
||||
this.inverted = inverted;
|
||||
this.burster = new MultiBurst("Iris Engine " + dimension.getName(), threads, 6);
|
||||
this.burster = new MultiBurst("Iris Engine " + dimension.getName(), IrisSettings.get().getConcurrency().getEngineThreadPriority(), threads);
|
||||
this.parallaxWorld = new ParallaxWorld(burster, 256, new File(world.worldFolder(), "iris/" + dimension.getLoadKey() + "/parallax"));
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ public class LightingTaskBatch implements LightingTask {
|
||||
LightingChunk nextChunk = null;
|
||||
CompletableFuture<Void> nextChunkFuture = null;
|
||||
synchronized (chunks_lock) {
|
||||
for (; i < chunks.length && numBeingLoaded < IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getThreadCount()); i++) {
|
||||
for (; i < chunks.length && numBeingLoaded < IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()); i++) {
|
||||
LightingChunk lc = chunks[i];
|
||||
if (lc.loadingStarted) {
|
||||
continue; // Already (being) loaded
|
||||
|
@ -279,7 +279,7 @@ public class IrisEntity extends IrisRegistrant {
|
||||
}, 1);
|
||||
}
|
||||
|
||||
if (Iris.awareEntities && e instanceof Mob) {
|
||||
if (e instanceof Mob) {
|
||||
Mob m = (Mob) e;
|
||||
m.setAware(isAware());
|
||||
}
|
||||
|
@ -142,10 +142,15 @@ public class IrisLoot {
|
||||
i.apply(rng, m);
|
||||
}
|
||||
|
||||
if (Iris.customModels) {
|
||||
try
|
||||
{
|
||||
m.setCustomModelData(getCustomModel());
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.reportError(e);
|
||||
}
|
||||
m.setLocalizedName(C.translateAlternateColorCodes('&', displayName));
|
||||
m.setDisplayName(C.translateAlternateColorCodes('&', displayName));
|
||||
m.setUnbreakable(isUnbreakable());
|
||||
@ -226,10 +231,16 @@ public class IrisLoot {
|
||||
i.apply(rng, m);
|
||||
}
|
||||
|
||||
if (Iris.customModels) {
|
||||
try
|
||||
{
|
||||
m.setCustomModelData(getCustomModel());
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
m.setLocalizedName(C.translateAlternateColorCodes('&', displayName));
|
||||
m.setDisplayName(C.translateAlternateColorCodes('&', displayName));
|
||||
m.setUnbreakable(isUnbreakable());
|
||||
|
@ -257,7 +257,7 @@ public class ParallaxWorld implements ParallaxAccess {
|
||||
|
||||
@Override
|
||||
public void saveAll() {
|
||||
MultiBurst.burst.lazy(this::saveAllNOW);
|
||||
burst.lazy(this::saveAllNOW);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,17 +19,17 @@
|
||||
package com.volmit.iris.engine.parallel;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class MultiBurst {
|
||||
public static final MultiBurst burst = new MultiBurst("Iris", 6, Runtime.getRuntime().availableProcessors());
|
||||
public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount()));
|
||||
private final ExecutorService service;
|
||||
private ExecutorService syncService;
|
||||
private int tid;
|
||||
|
||||
|
||||
public MultiBurst(int tc) {
|
||||
this("Iris", 6, tc);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user