mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2025-01-01 14:08:11 +01:00
minor tweaks
This commit is contained in:
parent
5d7f0b1418
commit
1bd44b270c
@ -31,6 +31,7 @@ import org.bukkit.WorldCreator;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
|
||||
@ -106,13 +107,21 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
|
||||
public static ConcurrentHashMap<Long, Long> keepLoaded = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||
|
||||
|
||||
@EventHandler
|
||||
public static void onChunkLoad(ChunkLoadEvent event) {
|
||||
Chunk chunk = event.getChunk();
|
||||
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
|
||||
keepLoaded.putIfAbsent(pair, Fawe.get().getTimer().getTickStart());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public static void onChunkUnload(ChunkUnloadEvent event) {
|
||||
Chunk chunk = event.getChunk();
|
||||
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
|
||||
Long lastLoad = keepLoaded.get(pair);
|
||||
if (lastLoad != null) {
|
||||
if (System.currentTimeMillis() - lastLoad < 10000) {
|
||||
if (Fawe.get().getTimer().getTickStart() - lastLoad < 10000) {
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
keepLoaded.remove(pair);
|
||||
|
@ -175,9 +175,9 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<net.minecraft.server.v1_11_R
|
||||
public net.minecraft.server.v1_11_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_11_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
return provider.getChunkAt(x, z, null, true);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
return provider.getChunkAt(x, z, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,9 +188,9 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
public net.minecraft.server.v1_12_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
ChunkProviderServer provider = ((CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
return provider.getChunkAt(x, z, null, true);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
return provider.getChunkAt(x, z, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.RunnableVal4;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@ -27,14 +28,18 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
|
||||
this.inhabitedTicks = inhabitedTicks;
|
||||
}
|
||||
|
||||
public long getInhabitedTicks() {
|
||||
return inhabitedTicks;
|
||||
}
|
||||
|
||||
public long getFileAgeMillis() {
|
||||
return fileAgeMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAFile applyFile(MCAFile mca) {
|
||||
File file = mca.getFile();
|
||||
try {
|
||||
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
|
||||
long creation = attr.creationTime().toMillis();
|
||||
long modified = attr.lastModifiedTime().toMillis();
|
||||
if (modified - creation < fileAgeMillis && modified > creation) {
|
||||
if (shouldDelete(mca)) {
|
||||
mca.setDeleted(true);
|
||||
get().add(512 * 512 * 256);
|
||||
return null;
|
||||
@ -44,45 +49,7 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
|
||||
try {
|
||||
ForkJoinPool pool = new ForkJoinPool();
|
||||
mca.init();
|
||||
mca.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer x, Integer z, Integer offset, Integer size) {
|
||||
try {
|
||||
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(null, 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();
|
||||
}
|
||||
}
|
||||
});
|
||||
filter(mca, pool);
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
mca.close(pool);
|
||||
pool.shutdown();
|
||||
@ -91,4 +58,77 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean shouldDelete(MCAFile mca) throws IOException {
|
||||
File file = mca.getFile();
|
||||
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
|
||||
long creation = attr.creationTime().toMillis();
|
||||
long modified = attr.lastModifiedTime().toMillis();
|
||||
if ((modified - creation < fileAgeMillis && modified > creation) || file.length() < 12288) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldDeleteChunk(MCAFile mca, int cx, int cz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void filter(MCAFile mca, ForkJoinPool pool) throws IOException {
|
||||
mca.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer x, Integer z, Integer offset, Integer size) {
|
||||
try {
|
||||
int bx = mca.getX() << 5;
|
||||
int bz = mca.getZ() << 5;
|
||||
if (shouldDeleteChunk(mca, bx, bz)) {
|
||||
MCAChunk chunk = new MCAChunk(null, x, z);
|
||||
chunk.setDeleted(true);
|
||||
synchronized (mca) {
|
||||
mca.setChunk(chunk);
|
||||
}
|
||||
get().add(16 * 16 * 256);
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
addReaders(mca, x, z, value);
|
||||
}
|
||||
});
|
||||
} catch (FaweException ignore) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
pool.submit(task);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addReaders(MCAFile mca, int x, int z, NBTStreamer streamer) {
|
||||
streamer.addReader(".Level.InhabitedTime", new RunnableVal2<Integer, Long>() {
|
||||
@Override
|
||||
public void run(Integer index, Long value) {
|
||||
if (value <= inhabitedTicks) {
|
||||
MCAChunk chunk = new MCAChunk(null, x, z);
|
||||
chunk.setDeleted(true);
|
||||
synchronized (mca) {
|
||||
mca.setChunk(chunk);
|
||||
}
|
||||
get().add(16 * 16 * 256);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
package com.boydti.fawe.jnbt.anvil.filters;
|
||||
|
||||
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.generator.HybridGen;
|
||||
import com.intellectualcrafters.plot.generator.HybridPlotWorld;
|
||||
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
|
||||
import com.sk89q.worldguard.util.collect.LongHashSet;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
public class PlotTrimFilter extends DeleteUninhabitedFilter {
|
||||
private final HybridPlotWorld hpw;
|
||||
private final HybridGen hg;
|
||||
private final MCAChunk reference;
|
||||
private final LongHashSet occupiedRegions;
|
||||
private final LongHashSet unoccupiedChunks;
|
||||
|
||||
public static boolean shouldSuggest(PlotArea area) {
|
||||
IndependentPlotGenerator gen = area.getGenerator();
|
||||
if (area instanceof HybridPlotWorld && gen instanceof HybridGen) {
|
||||
HybridPlotWorld hpw = (HybridPlotWorld) area;
|
||||
return hpw.PLOT_BEDROCK && !hpw.PLOT_SCHEMATIC && hpw.MAIN_BLOCK.length == 1 && hpw.TOP_BLOCK.length == 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PlotTrimFilter(PlotArea area, long fileAgeMillis, long inhabitedTicks) {
|
||||
super(fileAgeMillis, inhabitedTicks);
|
||||
IndependentPlotGenerator gen = area.getGenerator();
|
||||
if (!(area instanceof HybridPlotWorld) || !(gen instanceof HybridGen)) {
|
||||
throw new UnsupportedOperationException("Trim does not support non hybrid plot worlds");
|
||||
}
|
||||
this.hg = (HybridGen) gen;
|
||||
this.hpw = (HybridPlotWorld) area;
|
||||
|
||||
if (hpw.PLOT_BEDROCK && !hpw.PLOT_SCHEMATIC && hpw.MAIN_BLOCK.length == 1 && hpw.TOP_BLOCK.length == 1) {
|
||||
this.reference = new MCAChunk(null, 0, 0);
|
||||
this.reference.fillCuboid(0, 15, 0, 0, 0, 15, 7, (byte) 0);
|
||||
this.reference.fillCuboid(0, 15, 1, hpw.PLOT_HEIGHT - 1, 0, 15, hpw.MAIN_BLOCK[0].id, (byte) 0);
|
||||
this.reference.fillCuboid(0, 15, hpw.PLOT_HEIGHT, hpw.PLOT_HEIGHT, 0, 15, hpw.TOP_BLOCK[0].id, (byte) 0);
|
||||
} else {
|
||||
this.reference = null;
|
||||
}
|
||||
this.occupiedRegions = new LongHashSet();
|
||||
this.unoccupiedChunks = new LongHashSet();
|
||||
ArrayList<Plot> plots = new ArrayList<>();
|
||||
plots.addAll(PS.get().getPlots(area));
|
||||
if (ExpireManager.IMP != null) {
|
||||
plots.removeAll(ExpireManager.IMP.getPendingExpired());
|
||||
}
|
||||
for (Plot plot : plots) {
|
||||
Location pos1 = plot.getBottom();
|
||||
Location pos2 = plot.getTop();
|
||||
int ccx1 = pos1.getX() >> 9;
|
||||
int ccz1 = pos1.getZ() >> 9;
|
||||
int ccx2 = pos2.getX() >> 9;
|
||||
int ccz2 = pos2.getZ() >> 9;
|
||||
for (int x = ccx1; x <= ccx2; x++) {
|
||||
for (int z = ccz1; z <= ccz2; z++) {
|
||||
int bcx = x << 5;
|
||||
int bcz = z << 5;
|
||||
int tcx = bcx + 32;
|
||||
int tcz = bcz + 32;
|
||||
if (!occupiedRegions.containsKey(x, z)) {
|
||||
occupiedRegions.add(x, z);
|
||||
} else {
|
||||
for (int cz = bcz; cz < tcz; cz++) {
|
||||
for (int cx = bcx; cx < tcx; cx++) {
|
||||
unoccupiedChunks.add(cx, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int cx1 = pos1.getX() >> 4;
|
||||
int cz1 = pos1.getZ() >> 4;
|
||||
int cx2 = pos2.getX() >> 4;
|
||||
int cz2 = pos2.getZ() >> 4;
|
||||
for (int cz = cx1; cz < cx2; cz++) {
|
||||
for (int cx = cz1; cx < cz2; cx++) {
|
||||
unoccupiedChunks.remove(cx, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDelete(MCAFile mca) throws IOException {
|
||||
int x = mca.getX();
|
||||
int z = mca.getZ();
|
||||
return !occupiedRegions.containsKey(x, z) || super.shouldDelete(mca);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDeleteChunk(MCAFile mca, int cx, int cz) {
|
||||
return !unoccupiedChunks.containsKey(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(MCAFile mca, ForkJoinPool pool) throws IOException {
|
||||
if (reference == null) {
|
||||
super.filter(mca, pool);
|
||||
return;
|
||||
}
|
||||
mca.forEachChunk(new RunnableVal<MCAChunk>() {
|
||||
@Override
|
||||
public void run(MCAChunk value) {
|
||||
if (value.getInhabitedTime() < getInhabitedTicks()) {
|
||||
value.setDeleted(true);
|
||||
return;
|
||||
}
|
||||
if (reference.idsEqual(value, false)) {
|
||||
value.setDeleted(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -45,6 +45,7 @@ import org.bukkit.World;
|
||||
usage = "/plots moveto512 [world]"
|
||||
)
|
||||
public class MoveTo512 extends Command {
|
||||
|
||||
public MoveTo512() {
|
||||
super(MainCommand.getInstance(), true);
|
||||
}
|
||||
|
@ -56,6 +56,10 @@ public class FaweTimer implements Runnable {
|
||||
return System.currentTimeMillis() - tickStart;
|
||||
}
|
||||
|
||||
public long getTickStart() {
|
||||
return tickStart;
|
||||
}
|
||||
|
||||
private long skip = 0;
|
||||
private long skipTick = 0;
|
||||
|
||||
|
@ -57,14 +57,14 @@ public class BrushOptionsCommands extends MethodCommands {
|
||||
aliases = {"/savebrush"},
|
||||
usage = "[name]",
|
||||
desc = "Save your current brush\n" +
|
||||
"prefix with ../ to save globally",
|
||||
"use the -g flag to save globally",
|
||||
min = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.save")
|
||||
public void saveBrush(Player player, LocalSession session, String name) throws WorldEditException, IOException {
|
||||
public void saveBrush(Player player, LocalSession session, String name, @Switch('g') boolean root) throws WorldEditException, IOException {
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
if (tool != null) {
|
||||
boolean root = name.startsWith("../");
|
||||
root |= name.startsWith("../");
|
||||
name = FileSystems.getDefault().getPath(name).getFileName().toString();
|
||||
File folder = MainUtil.getFile(Fawe.imp().getDirectory(), "brushes");
|
||||
name = name.endsWith(".jsgz") ? name : name + ".jsgz";
|
||||
|
@ -68,7 +68,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
||||
}
|
||||
|
||||
protected static int MAX_RANGE = 500;
|
||||
protected int range = -1;
|
||||
protected int range = 240;
|
||||
private VisualMode visualMode = VisualMode.NONE;
|
||||
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
||||
private Mask targetMask = null;
|
||||
|
Loading…
Reference in New Issue
Block a user