mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-21 19:55:00 +00:00
242 lines
4.2 KiB
Java
242 lines
4.2 KiB
Java
package com.volmit.iris.util;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Chunk;
|
|
import org.bukkit.World;
|
|
|
|
import com.volmit.iris.Iris;
|
|
|
|
public class PregenJob
|
|
{
|
|
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;
|
|
public static int task = -1;
|
|
private PrecisionStopwatch s;
|
|
private ChronoLatch cl;
|
|
private MortarSender sender;
|
|
private Runnable onDone;
|
|
|
|
public PregenJob(World world, int size, MortarSender sender, Runnable onDone)
|
|
{
|
|
this.s = PrecisionStopwatch.start();
|
|
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);
|
|
rcz = 0;
|
|
total = (size / 16) * (size / 16);
|
|
genned = 0;
|
|
completed = false;
|
|
|
|
if(task != -1)
|
|
{
|
|
stop();
|
|
}
|
|
|
|
task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::onTick, 0, 0);
|
|
}
|
|
|
|
public static void stop()
|
|
{
|
|
try
|
|
{
|
|
Bukkit.getScheduler().cancelTask(task);
|
|
}
|
|
|
|
catch(Throwable e)
|
|
{
|
|
|
|
}
|
|
task = -1;
|
|
}
|
|
|
|
public void onTick()
|
|
{
|
|
if(completed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
|
|
while(p.getMilliseconds() < 1500)
|
|
{
|
|
tick();
|
|
}
|
|
|
|
if(cl.flip())
|
|
{
|
|
tickMetrics();
|
|
}
|
|
}
|
|
|
|
private void tickMetrics()
|
|
{
|
|
long eta = (long) ((total - genned) * (s.getMilliseconds() / (double) genned));
|
|
String ss = "Pregen: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0) + ", Elapsed: " + Form.duration((long) s.getMilliseconds()) + ", ETA: " + (genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta)) + " MS: " + Form.duration((s.getMilliseconds() / (double) genned), 2);
|
|
Iris.info(ss);
|
|
if(sender.isPlayer() && sender.player().isOnline())
|
|
{
|
|
sender.sendMessage(ss);
|
|
}
|
|
}
|
|
|
|
public void tick()
|
|
{
|
|
gen();
|
|
nextPosition();
|
|
}
|
|
|
|
public void nextPosition()
|
|
{
|
|
int lx = mcaX;
|
|
int lz = mcaZ;
|
|
rcx++;
|
|
|
|
if(rcx > 31)
|
|
{
|
|
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);
|
|
Iris.verbose("Verified " + 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
saveAll();
|
|
}
|
|
|
|
public void saveAll()
|
|
{
|
|
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;
|
|
}
|
|
|
|
public int min()
|
|
{
|
|
return -max();
|
|
}
|
|
|
|
public boolean isChunkWithin(int x, int z)
|
|
{
|
|
return Math.abs(z * 16) <= size / 2 && Math.abs(z * 16) <= size / 2;
|
|
}
|
|
}
|