minor tweaks

This commit is contained in:
Jesse Boyd 2017-06-30 17:38:54 +10:00
parent 5d7f0b1418
commit 1bd44b270c
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
9 changed files with 234 additions and 53 deletions

View File

@ -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);

View File

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

View File

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

View File

@ -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,10 +49,47 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
try {
ForkJoinPool pool = new ForkJoinPool();
mca.init();
filter(mca, pool);
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
mca.close(pool);
pool.shutdown();
} catch (IOException e) {
e.printStackTrace();
}
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() {
@ -57,7 +99,25 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
mca.streamChunk(offset, new RunnableVal<NBTStreamer>() {
@Override
public void run(NBTStreamer value) {
value.addReader(".Level.InhabitedTime", new RunnableVal2<Integer, Long>() {
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) {
@ -71,24 +131,4 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
}
});
}
});
} 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;
}
}

View File

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

View File

@ -45,6 +45,7 @@ import org.bukkit.World;
usage = "/plots moveto512 [world]"
)
public class MoveTo512 extends Command {
public MoveTo512() {
super(MainCommand.getInstance(), true);
}

View File

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

View File

@ -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";

View File

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