mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2025-01-21 07:41:42 +01:00
Optimize anvil delete
This commit is contained in:
parent
ecedd05651
commit
974cb3fdaf
@ -3,6 +3,7 @@ package com.boydti.fawe.command;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||||
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
||||||
import com.boydti.fawe.jnbt.anvil.MCAClipboard;
|
import com.boydti.fawe.jnbt.anvil.MCAClipboard;
|
||||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||||
@ -12,6 +13,9 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue;
|
|||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
|
import com.boydti.fawe.object.RunnableVal4;
|
||||||
import com.boydti.fawe.object.mask.FaweBlockMatcher;
|
import com.boydti.fawe.object.mask.FaweBlockMatcher;
|
||||||
import com.boydti.fawe.object.number.MutableLong;
|
import com.boydti.fawe.object.number.MutableLong;
|
||||||
import com.boydti.fawe.util.ArrayUtil;
|
import com.boydti.fawe.util.ArrayUtil;
|
||||||
@ -44,6 +48,8 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -101,7 +107,7 @@ public class AnvilCommands {
|
|||||||
max = 3
|
max = 3
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.anvil.deleteallold")
|
@CommandPermissions("worldedit.anvil.deleteallold")
|
||||||
public void deleteAllOld(Player player, EditSession editSession, String folder, int inhabitedTicks, @Optional("60000") int fileAgeMillis) throws WorldEditException {
|
public void deleteAllOld(Player player, String folder, int inhabitedTicks, @Optional("60000") int fileAgeMillis) throws WorldEditException {
|
||||||
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
|
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
|
||||||
MCAQueue queue = new MCAQueue(folder, defaultQueue.getSaveFolder(), defaultQueue.hasSky());
|
MCAQueue queue = new MCAQueue(folder, defaultQueue.getSaveFolder(), defaultQueue.hasSky());
|
||||||
MCAFilterCounter result = queue.filterWorld(new MCAFilterCounter() {
|
MCAFilterCounter result = queue.filterWorld(new MCAFilterCounter() {
|
||||||
@ -115,16 +121,56 @@ public class AnvilCommands {
|
|||||||
if (modified - creation < fileAgeMillis) {
|
if (modified - creation < fileAgeMillis) {
|
||||||
mca.setDeleted(true);
|
mca.setDeleted(true);
|
||||||
get().add(512 * 512 * 256);
|
get().add(512 * 512 * 256);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
} catch (IOException | UnsupportedOperationException ignore) {}
|
} catch (IOException | UnsupportedOperationException ignore) {}
|
||||||
return mca;
|
try {
|
||||||
}
|
ForkJoinPool pool = new ForkJoinPool();
|
||||||
|
mca.init();
|
||||||
@Override
|
mca.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||||
public MCAChunk applyChunk(MCAChunk chunk, MutableLong count) {
|
@Override
|
||||||
if (chunk.getInhabitedTime() <= inhabitedTicks) {
|
public void run(Integer x, Integer z, Integer offset, Integer size) {
|
||||||
count.add(16 * 16 * 256);
|
try {
|
||||||
chunk.setDeleted(true);
|
byte[] bytes = mca.getChunkCompressedBytes(offset);
|
||||||
|
if (bytes == null) return;
|
||||||
|
Runnable task = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
mca.streamChunk(offset, new RunnableVal<NBTStreamer>() {
|
||||||
|
@Override
|
||||||
|
public void run(NBTStreamer value) {
|
||||||
|
value.addReader(".Level.InhabitedTime", new RunnableVal2<Integer, Long>() {
|
||||||
|
@Override
|
||||||
|
public void run(Integer index, Long value) {
|
||||||
|
if (value <= inhabitedTicks) {
|
||||||
|
MCAChunk chunk = new MCAChunk(queue, x, z);
|
||||||
|
chunk.setDeleted(true);
|
||||||
|
synchronized (mca) {
|
||||||
|
mca.setChunk(chunk);
|
||||||
|
}
|
||||||
|
get().add(16 * 16 * 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pool.submit(task);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
|
mca.close(pool);
|
||||||
|
pool.shutdown();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.boydti.fawe.jnbt;
|
package com.boydti.fawe.jnbt;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.RunnableVal2;
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.worldedit.Vector;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@ -26,6 +26,21 @@ public class NBTStreamer {
|
|||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void readQuick() throws IOException {
|
||||||
|
try {
|
||||||
|
is.readNamedTagLazy(new RunnableVal2<String, RunnableVal2>() {
|
||||||
|
@Override
|
||||||
|
public void run(String node, RunnableVal2 result) {
|
||||||
|
if (readers.isEmpty()) {
|
||||||
|
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
|
||||||
|
}
|
||||||
|
this.value2 = readers.remove(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (FaweException ignore) {}
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
|
||||||
public <T, V> void addReader(String node, RunnableVal2<T, V> run) {
|
public <T, V> void addReader(String node, RunnableVal2<T, V> run) {
|
||||||
if (run instanceof NBTStreamReader) {
|
if (run instanceof NBTStreamReader) {
|
||||||
((NBTStreamReader) run).init(node);
|
((NBTStreamReader) run).init(node);
|
||||||
|
@ -52,6 +52,51 @@ public class MCAChunk extends FaweChunk<Void> {
|
|||||||
private int modified;
|
private int modified;
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
|
|
||||||
|
public MCAChunk(FaweQueue queue, int x, int z) {
|
||||||
|
super(queue, x, z);
|
||||||
|
this.ids = new byte[16][];
|
||||||
|
this.data = new byte[16][];
|
||||||
|
this.skyLight = new byte[16][];
|
||||||
|
this.blockLight = new byte[16][];
|
||||||
|
this.biomes = new byte[256];
|
||||||
|
this.tiles = new HashMap<>();
|
||||||
|
this.entities = new HashMap<>();
|
||||||
|
this.lastUpdate = System.currentTimeMillis();
|
||||||
|
this.heightMap = new int[256];
|
||||||
|
this.setModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MCAChunk(MCAChunk parent, boolean shallow) {
|
||||||
|
super(parent.getParent(), parent.getX(), parent.getZ());
|
||||||
|
if (shallow) {
|
||||||
|
this.ids = parent.ids;
|
||||||
|
this.data = parent.data;
|
||||||
|
this.skyLight = parent.skyLight;
|
||||||
|
this.blockLight = parent.blockLight;
|
||||||
|
this.biomes = parent.biomes;
|
||||||
|
this.tiles = parent.tiles;
|
||||||
|
this.entities = parent.entities;
|
||||||
|
this.inhabitedTime = parent.inhabitedTime;
|
||||||
|
this.lastUpdate = parent.lastUpdate;
|
||||||
|
this.heightMap = parent.heightMap;
|
||||||
|
this.modified = parent.modified;
|
||||||
|
this.deleted = parent.deleted;
|
||||||
|
} else {
|
||||||
|
this.ids = (byte[][]) MainUtil.copyNd(parent.ids);
|
||||||
|
this.data = (byte[][]) MainUtil.copyNd(parent.data);
|
||||||
|
this.skyLight = (byte[][]) MainUtil.copyNd(parent.skyLight);
|
||||||
|
this.blockLight = (byte[][]) MainUtil.copyNd(parent.blockLight);
|
||||||
|
this.biomes = parent.biomes.clone();
|
||||||
|
this.tiles = new HashMap<>(parent.tiles);
|
||||||
|
this.entities = new HashMap<>(parent.entities);
|
||||||
|
this.inhabitedTime = parent.inhabitedTime;
|
||||||
|
this.lastUpdate = parent.lastUpdate;
|
||||||
|
this.heightMap = parent.heightMap.clone();
|
||||||
|
this.modified = parent.modified;
|
||||||
|
this.deleted = parent.deleted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] toBytes(byte[] buffer) throws IOException {
|
public byte[] toBytes(byte[] buffer) throws IOException {
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
buffer = new byte[8192];
|
buffer = new byte[8192];
|
||||||
@ -393,51 +438,6 @@ public class MCAChunk extends FaweChunk<Void> {
|
|||||||
return FaweCache.asTag(root);
|
return FaweCache.asTag(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MCAChunk(FaweQueue queue, int x, int z) {
|
|
||||||
super(queue, x, z);
|
|
||||||
this.ids = new byte[16][];
|
|
||||||
this.data = new byte[16][];
|
|
||||||
this.skyLight = new byte[16][];
|
|
||||||
this.blockLight = new byte[16][];
|
|
||||||
this.biomes = new byte[256];
|
|
||||||
this.tiles = new HashMap<>();
|
|
||||||
this.entities = new HashMap<>();
|
|
||||||
this.lastUpdate = System.currentTimeMillis();
|
|
||||||
this.heightMap = new int[256];
|
|
||||||
this.setModified();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MCAChunk(MCAChunk parent, boolean shallow) {
|
|
||||||
super(parent.getParent(), parent.getX(), parent.getZ());
|
|
||||||
if (shallow) {
|
|
||||||
this.ids = parent.ids;
|
|
||||||
this.data = parent.data;
|
|
||||||
this.skyLight = parent.skyLight;
|
|
||||||
this.blockLight = parent.blockLight;
|
|
||||||
this.biomes = parent.biomes;
|
|
||||||
this.tiles = parent.tiles;
|
|
||||||
this.entities = parent.entities;
|
|
||||||
this.inhabitedTime = parent.inhabitedTime;
|
|
||||||
this.lastUpdate = parent.lastUpdate;
|
|
||||||
this.heightMap = parent.heightMap;
|
|
||||||
this.modified = parent.modified;
|
|
||||||
this.deleted = parent.deleted;
|
|
||||||
} else {
|
|
||||||
this.ids = (byte[][]) MainUtil.copyNd(parent.ids);
|
|
||||||
this.data = (byte[][]) MainUtil.copyNd(parent.data);
|
|
||||||
this.skyLight = (byte[][]) MainUtil.copyNd(parent.skyLight);
|
|
||||||
this.blockLight = (byte[][]) MainUtil.copyNd(parent.blockLight);
|
|
||||||
this.biomes = parent.biomes.clone();
|
|
||||||
this.tiles = new HashMap<>(parent.tiles);
|
|
||||||
this.entities = new HashMap<>(parent.entities);
|
|
||||||
this.inhabitedTime = parent.inhabitedTime;
|
|
||||||
this.lastUpdate = parent.lastUpdate;
|
|
||||||
this.heightMap = parent.heightMap.clone();
|
|
||||||
this.modified = parent.modified;
|
|
||||||
this.deleted = parent.deleted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MCAChunk(NBTInputStream nis, FaweQueue parent, int x, int z, int compressedSize) throws IOException {
|
public MCAChunk(NBTInputStream nis, FaweQueue parent, int x, int z, int compressedSize) throws IOException {
|
||||||
super(parent, x, z);
|
super(parent, x, z);
|
||||||
ids = new byte[16][];
|
ids = new byte[16][];
|
||||||
|
@ -262,7 +262,7 @@ public class MCAFile {
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getChunkCompressedBytes(int offset) throws IOException{
|
public byte[] getChunkCompressedBytes(int offset) throws IOException{
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -296,15 +296,28 @@ public class MCAFile {
|
|||||||
streamChunk(getOffset(cx, cz), addReaders);
|
streamChunk(getOffset(cx, cz), addReaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void streamChunk(int offset, RunnableVal<NBTStreamer> addReaders) throws IOException {
|
public void streamChunk(int offset, RunnableVal<NBTStreamer> withStream) throws IOException {
|
||||||
if (offset == 0) {
|
byte[] data = getChunkCompressedBytes(offset);
|
||||||
return;
|
streamChunk(data, withStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void streamChunk(byte[] data, RunnableVal<NBTStreamer> withStream) throws IOException {
|
||||||
|
if (data != null) {
|
||||||
|
try {
|
||||||
|
FastByteArrayInputStream nbtIn = new FastByteArrayInputStream(data);
|
||||||
|
FastByteArrayInputStream bais = new FastByteArrayInputStream(data);
|
||||||
|
InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(), 1);
|
||||||
|
fieldBuf2.set(iis, byteStore2.get());
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(iis);
|
||||||
|
NBTInputStream nis = new NBTInputStream(bis);
|
||||||
|
fieldBuf3.set(nis, byteStore3.get());
|
||||||
|
NBTStreamer streamer = new NBTStreamer(nis);
|
||||||
|
withStream.run(streamer);
|
||||||
|
streamer.readQuick();
|
||||||
|
} catch (IllegalAccessException unlikely) {
|
||||||
|
unlikely.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NBTInputStream is = getChunkIS(offset);
|
|
||||||
NBTStreamer ns = new NBTStreamer(is);
|
|
||||||
addReaders.run(ns);
|
|
||||||
ns.readFully();
|
|
||||||
is.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -340,7 +340,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
System.out.println("Failed to load: r." + mcaX + "." + mcaZ + ".mca -> (local) " + rcx + "," + rcz);
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user