From 959a5b5c70c9d70a93d2266e82aecb12fbf5b8df Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Thu, 3 Sep 2020 16:15:09 -0400 Subject: [PATCH] Fixes --- pom.xml | 7 + .../iris/gen/atomics/AtomicMulticache.java | 2 +- .../java/com/volmit/iris/gui/PregenGui.java | 114 +++++++ .../java/com/volmit/iris/util/PregenJob.java | 292 ++++++++++-------- .../java/com/volmit/iris/util/Spiraled.java | 7 + .../java/com/volmit/iris/util/Spiraler.java | 61 ++++ 6 files changed, 353 insertions(+), 130 deletions(-) create mode 100644 src/main/java/com/volmit/iris/gui/PregenGui.java create mode 100644 src/main/java/com/volmit/iris/util/Spiraled.java create mode 100644 src/main/java/com/volmit/iris/util/Spiraler.java diff --git a/pom.xml b/pom.xml index a9f39c4bf..9c7451e83 100644 --- a/pom.xml +++ b/pom.xml @@ -127,6 +127,13 @@ 1.16.1-R0.1-SNAPSHOT provided + + + org.bukkit.craftbukkit + cb-1.16.2 + 1.16.2 + provided + org.projectlombok diff --git a/src/main/java/com/volmit/iris/gen/atomics/AtomicMulticache.java b/src/main/java/com/volmit/iris/gen/atomics/AtomicMulticache.java index 2e61b83f0..1a2936bb1 100644 --- a/src/main/java/com/volmit/iris/gen/atomics/AtomicMulticache.java +++ b/src/main/java/com/volmit/iris/gen/atomics/AtomicMulticache.java @@ -85,7 +85,7 @@ public class AtomicMulticache private int getLimit() { - return 20000; + return 1024; } public double getHeight(int x, int z, Supplier g) diff --git a/src/main/java/com/volmit/iris/gui/PregenGui.java b/src/main/java/com/volmit/iris/gui/PregenGui.java new file mode 100644 index 000000000..ce3e5aa61 --- /dev/null +++ b/src/main/java/com/volmit/iris/gui/PregenGui.java @@ -0,0 +1,114 @@ +package com.volmit.iris.gui; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JPanel; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.ChunkPosition; +import com.volmit.iris.util.J; +import com.volmit.iris.util.KMap; +import com.volmit.iris.util.M; +import com.volmit.iris.util.PregenJob; + +public class PregenGui extends JPanel +{ + private PregenJob job; + private static final long serialVersionUID = 2094606939770332040L; + private KMap queue = new KMap<>(); + private int res = 8192; + private BufferedImage image = new BufferedImage(res, res, BufferedImage.TYPE_INT_RGB); + + public PregenGui() + { + + } + + @Override + public void paint(Graphics gx) + { + double minC = Math.floorDiv(job.min(), 16) - 4; + double maxC = Math.floorDiv(job.max(), 16) + 4; + + Graphics2D g = (Graphics2D) gx; + Graphics2D bg = (Graphics2D) image.getGraphics(); + + for(ChunkPosition i : queue.k()) + { + draw(i, queue.get(i), minC, maxC, bg); + } + + queue.clear(); + + g.drawImage(image, 0, 0, getParent().getWidth(), getParent().getHeight(), new ImageObserver() + { + @Override + public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) + { + return true; + } + }); + + J.a(() -> + { + J.sleep((long) 500); + repaint(); + }); + } + + private void draw(ChunkPosition p, Color c, double minC, double maxC, Graphics2D bg) + { + double pw = M.lerpInverse(minC, maxC, p.getX()); + double ph = M.lerpInverse(minC, maxC, p.getZ()); + double pwa = M.lerpInverse(minC, maxC, p.getX() + 1); + double pha = M.lerpInverse(minC, maxC, 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); + } + + private static void createAndShowGUI(PregenJob j) + { + JFrame frame = new JFrame("Pregen View"); + PregenGui nv = new PregenGui(); + nv.job = j; + j.subscribe((c, b) -> nv.queue.put(c, b)); + frame.add(nv); + frame.setSize(1440, 820); + 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 e) + { + + } + } + } + + public static void launch(PregenJob g) + { + J.a(() -> + { + createAndShowGUI(g); + }); + } +} diff --git a/src/main/java/com/volmit/iris/util/PregenJob.java b/src/main/java/com/volmit/iris/util/PregenJob.java index 12e303576..674c98066 100644 --- a/src/main/java/com/volmit/iris/util/PregenJob.java +++ b/src/main/java/com/volmit/iris/util/PregenJob.java @@ -1,19 +1,21 @@ package com.volmit.iris.util; +import java.awt.Color; + import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkUnloadEvent; import com.volmit.iris.Iris; +import com.volmit.iris.gui.PregenGui; -public class PregenJob +public class PregenJob implements Listener { private World world; private int size; - private int mcaX; - private int mcaZ; - private int rcx; - private int rcz; private int total; private int genned; private boolean completed; @@ -21,34 +23,63 @@ public class PregenJob private PrecisionStopwatch s; private ChronoLatch cl; private ChronoLatch clx; + private ChronoLatch clf; private MortarSender sender; + private int mcaWidth; + private int mcaX; + private int mcaZ; + private int chunkX; + private int chunkZ; private Runnable onDone; + private Spiraler spiraler; + private Spiraler chunkSpiraler; + private boolean first; + private Consumer2 consumer; public PregenJob(World world, int size, MortarSender sender, Runnable onDone) { this.s = PrecisionStopwatch.start(); + Iris.instance.registerListener(this); this.world = world; this.size = size; this.onDone = onDone; world.getWorldBorder().setCenter(0, 0); world.getWorldBorder().setWarningDistance(64); world.getWorldBorder().setSize(size); - mcaX = mca(min()); - mcaZ = mca(min()); - rcx = 0; this.sender = sender; cl = new ChronoLatch(3000); - clx = new ChronoLatch(15000); - rcz = 0; + clx = new ChronoLatch(20000); + clf = new ChronoLatch(30000); total = (size / 16) * (size / 16); genned = 0; + mcaWidth = Math.floorDiv(size >> 4, 8) + 8; + this.mcaX = 0; + this.mcaZ = 0; + this.chunkX = 0; + this.chunkZ = 0; completed = false; + first = true; + + chunkSpiraler = new Spiraler(8, 8, (x, z) -> + { + chunkX = (mcaX * 8) + x; + chunkZ = (mcaZ * 8) + z; + }); + + spiraler = new Spiraler(mcaWidth, mcaWidth, (x, z) -> + { + mcaX = x; + mcaZ = z; + chunkSpiraler.retarget(8, 8); + }); + + chunkSpiraler.setOffset(3, 3); if(task != -1) { stop(); } - + PregenGui.launch(this); task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::onTick, 0, 0); } @@ -75,7 +106,7 @@ public class PregenJob PrecisionStopwatch p = PrecisionStopwatch.start(); - while(p.getMilliseconds() < 1500) + while(p.getMilliseconds() < 5000) { tick(); } @@ -99,141 +130,139 @@ public class PregenJob public void tick() { - gen(); - nextPosition(); - } - - public void nextPosition() - { - int lx = mcaX; - int lz = mcaZ; - rcx++; - - if(rcx > 31) + if(completed) { - rcx = 0; - rcz++; - - if(rcz > 31) - { - rcz = 0; - mcaX++; - - if(mcaX > mca(Math.floorDiv(max(), 16))) - { - mcaX = mca(Math.floorDiv(min(), 16)); - mcaZ++; - - if(mcaZ > mca(Math.floorDiv(max(), 16))) - { - mcaZ = mca(Math.floorDiv(min(), 16)); - completed = true; - stop(); - Iris.info("Pregen Completed!"); - if(sender.isPlayer() && sender.player().isOnline()) - { - sender.sendMessage("Pregen Completed!"); - } - - for(Chunk i : world.getLoadedChunks()) - { - i.unload(true); - } - - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); - onDone.run(); - } - } - - if(!completed) - { - try - { - verify(lx, lz); - } - - catch(Throwable e) - { - e.printStackTrace(); - } - } - } - } - } - - private void verify(int lx, int lz) throws Throwable - { - for(int x = 0; x < 32; x++) - { - for(int z = 0; z < 32; z++) - { - if(isChunkWithin(x + (lx * 32), z + (lz * 32))) - { - Chunk c = world.getChunkAt(x + (lx * 32), z + (lz * 32)); - c.load(true); - world.unloadChunkRequest(x + (lx * 32), z + (lz * 32)); - } - } + return; } - saveAllRequest(); + if(first) + { + sender.sendMessage("Pregen Started for " + Form.f((mcaWidth * mcaWidth)) + " Regions containing " + Form.f((mcaWidth * 16) * (mcaWidth * 16)) + " Chunks"); + first = false; + spiraler.next(); + + while(chunkSpiraler.hasNext()) + { + chunkSpiraler.next(); + + if(isChunkWithin(chunkX, chunkZ)) + { + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.DARK_GRAY); + } + } + + chunkSpiraler.retarget(8, 8); + } + + if(chunkSpiraler.hasNext()) + { + chunkSpiraler.next(); + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.YELLOW); + + if(isChunkWithin(chunkX, chunkZ)) + { + world.loadChunk(chunkX, chunkZ); + + if(consumer != null) + { + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.BLUE); + } + } + + genned++; + } + + else if(spiraler.hasNext()) + { + saveAllRequest(); + spiraler.next(); + while(chunkSpiraler.hasNext()) + { + chunkSpiraler.next(); + + if(isChunkWithin(chunkX, chunkZ)) + { + consumer.accept(new ChunkPosition(chunkX, chunkZ), Color.DARK_GRAY); + } + } + chunkSpiraler.retarget(8, 8); + } + + else + { + for(Chunk i : world.getLoadedChunks()) + { + i.unload(true); + } + + saveAll(); + Iris.instance.unregisterListener(this); + completed = true; + sender.sendMessage("Pregen Completed!"); + onDone.run(); + } } public void saveAllRequest() { + if(clf.flip()) + { + int g = 0; + + for(Chunk i : world.getLoadedChunks()) + { + g++; + + if(g > 1500) + { + i.unload(true); + } + + else + { + world.unloadChunkRequest(i.getX(), i.getZ()); + } + } + } + if(clx.flip()) { saveAll(); } } + @EventHandler + public void on(ChunkUnloadEvent e) + { + if(e.getWorld().equals(world) && isChunkWithin(e.getChunk().getX(), e.getChunk().getZ())) + { + consumer.accept(new ChunkPosition(e.getChunk().getX(), e.getChunk().getZ()), Color.GREEN); + } + } + public void saveAll() { + int g = 0; + + for(Chunk i : world.getLoadedChunks()) + { + g++; + + if(g > 1500) + { + i.unload(true); + } + + else + { + world.unloadChunkRequest(i.getX(), i.getZ()); + } + } + world.save(); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); } - public void gen() - { - try - { - if(isChunkWithin(rcx + minMCA(mcaX), rcz + minMCA(mcaZ))) - { - Chunk c = world.getChunkAt(rcx + minMCA(mcaX), rcz + minMCA(mcaZ)); - c.load(true); - genned++; - } - } - - catch(Throwable e) - { - Iris.warn("Pregen Crash!"); - if(sender.isPlayer() && sender.player().isOnline()) - { - sender.sendMessage("Pregen Completed!"); - } - - onDone.run(); - e.printStackTrace(); - stop(); - } - } - - public int minMCA(int v) - { - return v << 5; - } - - public int maxMCA(int v) - { - return (v << 5) + 31; - } - - public int mca(int v) - { - return v >> 5; - } - public int max() { return size / 2; @@ -246,6 +275,11 @@ public class PregenJob public boolean isChunkWithin(int x, int z) { - return Math.abs(z * 16) <= size / 2 && Math.abs(z * 16) <= size / 2; + return !(Math.abs(x << 4) > Math.floorDiv(size, 2) + 16 || Math.abs(z << 4) > Math.floorDiv(size, 2) + 16); + } + + public void subscribe(Consumer2 s) + { + consumer = s; } } diff --git a/src/main/java/com/volmit/iris/util/Spiraled.java b/src/main/java/com/volmit/iris/util/Spiraled.java new file mode 100644 index 000000000..a606b3cc2 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/Spiraled.java @@ -0,0 +1,7 @@ +package com.volmit.iris.util; + +@FunctionalInterface +public interface Spiraled +{ + public void on(int x, int z); +} diff --git a/src/main/java/com/volmit/iris/util/Spiraler.java b/src/main/java/com/volmit/iris/util/Spiraler.java new file mode 100644 index 000000000..8edfbaba2 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/Spiraler.java @@ -0,0 +1,61 @@ +package com.volmit.iris.util; + +public class Spiraler +{ + int x, z, dx, dz, sizeX, sizeZ, t, maxI, i; + int ox, oz; + private Spiraled spiraled; + + public Spiraler(int sizeX, int sizeZ, Spiraled spiraled) + { + ox = 0; + oz = 0; + this.spiraled = spiraled; + retarget(sizeX, sizeZ); + } + + static void Spiral(int X, int Y) + { + + } + + public void setOffset(int ox, int oz) + { + this.ox = ox; + this.oz = oz; + } + + public void retarget(int sizeX, int sizeZ) + { + this.sizeX = sizeX; + this.sizeZ = sizeZ; + x = z = dx = 0; + dz = -1; + i = 0; + t = Math.max(sizeX, sizeZ); + maxI = t * t; + } + + public boolean hasNext() + { + return i < maxI; + } + + public void next() + { + if((-sizeX / 2 <= x) && (x <= sizeX / 2) && (-sizeZ / 2 <= z) && (z <= sizeZ / 2)) + { + spiraled.on(x + ox, z + ox); + } + + if((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) + { + t = dx; + dx = -dz; + dz = t; + } + x += dx; + z += dz; + i++; + } +}