Iris/src/main/java/com/volmit/iris/util/PregenJob.java
Daniel Mills b8c4d66160 Tweaks
2020-08-19 02:18:31 -04:00

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;
}
}