fix object saving

This commit is contained in:
Julian Krings 2025-07-20 00:50:11 +02:00
parent 68a214edb5
commit bddc62f385
No known key found for this signature in database
GPG Key ID: 208C6E08C3B718D2
3 changed files with 127 additions and 78 deletions

View File

@ -35,6 +35,7 @@ import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.SR;
import com.volmit.iris.util.scheduling.jobs.Job;
import com.volmit.iris.util.scheduling.jobs.ScanJob;
import org.bukkit.*;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
@ -86,80 +87,10 @@ public class WandSVC implements IrisService {
Cuboid c = new Cuboid(f[0], f[1]);
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
var it = c.chunkedIterator();
int total = c.getSizeX() * c.getSizeY() * c.getSizeZ();
var latch = new CountDownLatch(1);
new Job() {
private int i;
private Chunk chunk;
@Override
public String getName() {
return "Scanning Selection";
}
@Override
public void execute() {
new SR() {
@Override
public void run() {
var time = M.ms() + MS_PER_TICK;
while (time > M.ms()) {
if (!it.hasNext()) {
if (chunk != null) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = null;
}
cancel();
latch.countDown();
return;
}
try {
var b = it.next();
var bChunk = b.getChunk();
if (chunk == null) {
chunk = bChunk;
chunk.addPluginChunkTicket(Iris.instance);
} else if (chunk != bChunk) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = bChunk;
}
if (b.getType().equals(Material.AIR))
continue;
BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector();
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy);
} finally {
i++;
}
}
}
};
try {
latch.await();
} catch (InterruptedException ignored) {}
}
@Override
public void completeWork() {}
@Override
public int getTotalWork() {
return total;
}
@Override
public int getWorkCompleted() {
return i;
}
}.execute(new VolmitSender(p), true, () -> {});
try {
latch.await();
} catch (InterruptedException ignored) {}
new ScanJob("Scanning Selection", c, MS_PER_TICK, (bv, b) -> {
if (b.getType().equals(Material.AIR)) return;
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy);
}).execute(new VolmitSender(p), true, () -> {});
return s;
} catch (Throwable e) {

View File

@ -652,7 +652,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
return new CuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2);
}
public Iterator<Block> chunkedIterator() {
public Iterator<Location> chunkedIterator() {
return new ChunkedCuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2);
}
@ -751,7 +751,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
}
}
public static class ChunkedCuboidIterator implements Iterator<Block> {
public static class ChunkedCuboidIterator implements Iterator<Location> {
private final World w;
private final int minRX, minY, minRZ, maxRX, maxY, maxRZ;
private final int minCX, minCZ, maxCX, maxCZ;
@ -795,7 +795,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
}
@Override
public Block next() {
public Location next() {
if (chunk == null) {
chunk = new Position2(cX, cZ);
if (++cX > maxCX) {
@ -809,7 +809,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
rZ = chunk.getZ() == minCZ ? minRZ : 0;
}
var b = w.getBlockAt((chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ);
var b = new Location(w, (chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ);
if (++y > maxY) {
y = minY;
if (++rX > mX) {

View File

@ -0,0 +1,118 @@
package com.volmit.iris.util.scheduling.jobs;
import com.volmit.iris.Iris;
import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.plugin.VolmitSender;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.util.BlockVector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
public class ScanJob implements Job {
private final CountDownLatch latch = new CountDownLatch(1);
private final AtomicInteger completed = new AtomicInteger();
private final String name;
private final Cuboid cuboid;
private final BiConsumer<BlockVector, Block> action;
private final int msPerTick, total;
private volatile Chunk chunk;
public ScanJob(String name,
Cuboid cuboid,
int msPerTick,
BiConsumer<BlockVector, Block> action
) {
this.name = name;
this.cuboid = cuboid;
this.action = action;
this.msPerTick = msPerTick;
total = cuboid.volume();
}
@Override
public String getName() {
return name;
}
@Override
public void execute() {
Thread.ofVirtual()
.name("Iris Job - " + name)
.start(this::executeTask);
await();
}
public void await() {
try {
latch.await();
} catch (InterruptedException ignored) {}
}
private void executeTask() {
var it = cuboid.chunkedIterator();
var region = Iris.platform.getRegionScheduler();
var tmp = it.next();
while (tmp != null) {
Location finalTmp = tmp;
tmp = region.run(tmp, () -> {
var time = M.ms() + msPerTick;
var next = finalTmp;
while (time > M.ms()) {
if (!consume(next)) break;
completed.incrementAndGet();
next = it.hasNext() ? it.next() : null;
}
return next;
}).getResult().join();
}
latch.countDown();
}
private boolean consume(Location next) {
if (!Iris.platform.isOwnedByCurrentRegion(next))
return true;
final Chunk nextChunk = next.getChunk();
if (chunk == null) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = next.getChunk();
} else if (chunk != nextChunk) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = nextChunk;
chunk.addPluginChunkTicket(Iris.instance);
}
final Block block = next.getBlock();
action.accept(next.subtract(cuboid.getLowerNE().toVector()).toVector().toBlockVector(), block);
return false;
}
@Override
public void completeWork() {
}
@Override
public int getTotalWork() {
return total;
}
@Override
public int getWorkCompleted() {
return completed.get();
}
@Override
public void execute(VolmitSender sender, boolean silentMsg, Runnable whenComplete) {
Job.super.execute(sender, silentMsg, whenComplete);
await();
}
}