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.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
import org.bukkit.event.world.WorldInitEvent;
|
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);
|
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
|
@EventHandler
|
||||||
public static void onChunkUnload(ChunkUnloadEvent event) {
|
public static void onChunkUnload(ChunkUnloadEvent event) {
|
||||||
Chunk chunk = event.getChunk();
|
Chunk chunk = event.getChunk();
|
||||||
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
|
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
|
||||||
Long lastLoad = keepLoaded.get(pair);
|
Long lastLoad = keepLoaded.get(pair);
|
||||||
if (lastLoad != null) {
|
if (lastLoad != null) {
|
||||||
if (System.currentTimeMillis() - lastLoad < 10000) {
|
if (Fawe.get().getTimer().getTickStart() - lastLoad < 10000) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
} else {
|
} else {
|
||||||
keepLoaded.remove(pair);
|
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) {
|
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();
|
net.minecraft.server.v1_11_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||||
if (generate) {
|
if (generate) {
|
||||||
return provider.getOrLoadChunkAt(x, z);
|
return provider.getChunkAt(x, z, null, true);
|
||||||
} else {
|
} 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) {
|
public net.minecraft.server.v1_12_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||||
ChunkProviderServer provider = ((CraftWorld) world).getHandle().getChunkProviderServer();
|
ChunkProviderServer provider = ((CraftWorld) world).getHandle().getChunkProviderServer();
|
||||||
if (generate) {
|
if (generate) {
|
||||||
return provider.getOrLoadChunkAt(x, z);
|
return provider.getChunkAt(x, z, null, true);
|
||||||
} else {
|
} 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.RunnableVal;
|
||||||
import com.boydti.fawe.object.RunnableVal2;
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
import com.boydti.fawe.object.RunnableVal4;
|
import com.boydti.fawe.object.RunnableVal4;
|
||||||
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -27,14 +28,18 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
|
|||||||
this.inhabitedTicks = inhabitedTicks;
|
this.inhabitedTicks = inhabitedTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getInhabitedTicks() {
|
||||||
|
return inhabitedTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFileAgeMillis() {
|
||||||
|
return fileAgeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MCAFile applyFile(MCAFile mca) {
|
public MCAFile applyFile(MCAFile mca) {
|
||||||
File file = mca.getFile();
|
|
||||||
try {
|
try {
|
||||||
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
|
if (shouldDelete(mca)) {
|
||||||
long creation = attr.creationTime().toMillis();
|
|
||||||
long modified = attr.lastModifiedTime().toMillis();
|
|
||||||
if (modified - creation < fileAgeMillis && modified > creation) {
|
|
||||||
mca.setDeleted(true);
|
mca.setDeleted(true);
|
||||||
get().add(512 * 512 * 256);
|
get().add(512 * 512 * 256);
|
||||||
return null;
|
return null;
|
||||||
@ -44,45 +49,7 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
|
|||||||
try {
|
try {
|
||||||
ForkJoinPool pool = new ForkJoinPool();
|
ForkJoinPool pool = new ForkJoinPool();
|
||||||
mca.init();
|
mca.init();
|
||||||
mca.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
filter(mca, pool);
|
||||||
@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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
mca.close(pool);
|
mca.close(pool);
|
||||||
pool.shutdown();
|
pool.shutdown();
|
||||||
@ -91,4 +58,77 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
|
|||||||
}
|
}
|
||||||
return null;
|
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]"
|
usage = "/plots moveto512 [world]"
|
||||||
)
|
)
|
||||||
public class MoveTo512 extends Command {
|
public class MoveTo512 extends Command {
|
||||||
|
|
||||||
public MoveTo512() {
|
public MoveTo512() {
|
||||||
super(MainCommand.getInstance(), true);
|
super(MainCommand.getInstance(), true);
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,10 @@ public class FaweTimer implements Runnable {
|
|||||||
return System.currentTimeMillis() - tickStart;
|
return System.currentTimeMillis() - tickStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getTickStart() {
|
||||||
|
return tickStart;
|
||||||
|
}
|
||||||
|
|
||||||
private long skip = 0;
|
private long skip = 0;
|
||||||
private long skipTick = 0;
|
private long skipTick = 0;
|
||||||
|
|
||||||
|
@ -57,14 +57,14 @@ public class BrushOptionsCommands extends MethodCommands {
|
|||||||
aliases = {"/savebrush"},
|
aliases = {"/savebrush"},
|
||||||
usage = "[name]",
|
usage = "[name]",
|
||||||
desc = "Save your current brush\n" +
|
desc = "Save your current brush\n" +
|
||||||
"prefix with ../ to save globally",
|
"use the -g flag to save globally",
|
||||||
min = 1
|
min = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.save")
|
@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);
|
BrushTool tool = session.getBrushTool(player);
|
||||||
if (tool != null) {
|
if (tool != null) {
|
||||||
boolean root = name.startsWith("../");
|
root |= name.startsWith("../");
|
||||||
name = FileSystems.getDefault().getPath(name).getFileName().toString();
|
name = FileSystems.getDefault().getPath(name).getFileName().toString();
|
||||||
File folder = MainUtil.getFile(Fawe.imp().getDirectory(), "brushes");
|
File folder = MainUtil.getFile(Fawe.imp().getDirectory(), "brushes");
|
||||||
name = name.endsWith(".jsgz") ? name : name + ".jsgz";
|
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 static int MAX_RANGE = 500;
|
||||||
protected int range = -1;
|
protected int range = 240;
|
||||||
private VisualMode visualMode = VisualMode.NONE;
|
private VisualMode visualMode = VisualMode.NONE;
|
||||||
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
||||||
private Mask targetMask = null;
|
private Mask targetMask = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user