Delete unclaimed filter

This commit is contained in:
Jesse Boyd 2017-08-31 22:42:29 +10:00
parent 1dad7a6cce
commit 8564b0b80f
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
16 changed files with 335 additions and 33 deletions

View File

@ -240,10 +240,7 @@ public class FaweBukkit implements IFawe, Listener {
}
if (url != null) ReflectionUtils.setFailsafeFieldValue(url, null, null);
} catch (NoSuchFieldError | IllegalAccessException ignore) {}
catch (Throwable e) {
Fawe.debug("Error linking metrics: " + instance);
e.printStackTrace();
}
catch (Throwable e) {}
}
} catch (NoSuchFieldException ignored) { }
});

View File

@ -0,0 +1,43 @@
package com.boydti.fawe.bukkit.filter;
import com.boydti.fawe.regions.general.CuboidRegionFilter;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.TaskManager;
import com.sk89q.worldedit.BlockVector2D;
import java.util.ArrayDeque;
import java.util.Collection;
import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import org.bukkit.World;
import static com.google.common.base.Preconditions.checkNotNull;
public class GriefPreventionFilter extends CuboidRegionFilter {
private final Collection<Claim> claims;
private final World world;
public GriefPreventionFilter(World world) {
checkNotNull(world);
this.claims = TaskManager.IMP.sync(new RunnableVal<Collection<Claim>>() {
@Override
public void run(Collection<Claim> claims) {
this.value = new ArrayDeque(GriefPrevention.instance.dataStore.getClaims());
}
});
this.world = world;
}
@Override
public void calculateRegions() {
for (Claim claim : claims) {
org.bukkit.Location bot = claim.getGreaterBoundaryCorner();
if (world.equals(bot.getWorld())) {
org.bukkit.Location top = claim.getGreaterBoundaryCorner();
BlockVector2D pos1 = new BlockVector2D(bot.getBlockX(), bot.getBlockZ());
BlockVector2D pos2 = new BlockVector2D(top.getBlockX(), top.getBlockZ());
add(pos1, pos2);
}
}
}
}

View File

@ -0,0 +1,66 @@
package com.boydti.fawe.bukkit.filter;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.regions.general.CuboidRegionFilter;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.World;
import static com.google.common.base.Preconditions.checkNotNull;
public class WorldGuardFilter extends CuboidRegionFilter {
private final World world;
private boolean large;
private RegionManager manager;
public WorldGuardFilter(World world) {
checkNotNull(world);
this.world = world;
}
@Override
public void calculateRegions() {
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
WorldGuardFilter.this.manager = WorldGuardPlugin.inst().getRegionManager(world);
for (ProtectedRegion region : manager.getRegions().values()) {
BlockVector min = region.getMinimumPoint();
BlockVector max = region.getMaximumPoint();
if (max.getBlockX() - min.getBlockX() > 1024 || max.getBlockZ() - min.getBlockZ() > 1024) {
Fawe.debug("Large or complex region shapes cannot be optimized. Filtering will be slower");
large = true;
break;
}
add(min.toVector2D(), max.toVector2D());
}
}
});
}
@Override
public boolean containsChunk(int chunkX, int chunkZ) {
if (!large) return super.containsChunk(chunkX, chunkZ);
BlockVector pos1 = new BlockVector(chunkX << 4, 0, chunkZ << 4);
BlockVector pos2 = new BlockVector(pos1.getBlockX() + 15, 255, pos1.getBlockZ() + 15);
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("unimportant", pos1, pos2);
ApplicableRegionSet set = manager.getApplicableRegions(chunkRegion);
return set.size() > 0 && !set.getRegions().iterator().next().getId().equals("__global__");
}
@Override
public boolean containsRegion(int mcaX, int mcaZ) {
if (!large) return super.containsRegion(mcaX, mcaZ);
BlockVector pos1 = new BlockVector(mcaX << 9, 0, mcaZ << 9);
BlockVector pos2 = new BlockVector(pos1.getBlockX() + 511, 255, pos1.getBlockZ() + 511);
ProtectedCuboidRegion regionRegion = new ProtectedCuboidRegion("unimportant", pos1, pos2);
ApplicableRegionSet set = manager.getApplicableRegions(regionRegion);
return set.size() > 0 && !set.getRegions().iterator().next().getId().equals("__global__");
}
}

View File

@ -1,9 +1,12 @@
package com.boydti.fawe.bukkit.regions;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.filter.GriefPreventionFilter;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.general.RegionFilter;
import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -49,6 +52,10 @@ public class GriefPreventionFeature extends BukkitMaskManager implements Listene
}
}
return null;
}
@Override
public RegionFilter getFilter(String world) {
return new GriefPreventionFilter(Bukkit.getWorld(world));
}
}

View File

@ -1,7 +1,9 @@
package com.boydti.fawe.bukkit.regions;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.filter.WorldGuardFilter;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.general.RegionFilter;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
@ -108,6 +110,10 @@ public class Worldguard extends BukkitMaskManager implements Listener {
} else {
return null;
}
}
@Override
public RegionFilter getFilter(String world) {
return new WorldGuardFilter(Bukkit.getWorld(world));
}
}

View File

@ -12,6 +12,7 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.jnbt.anvil.filters.CountFilter;
import com.boydti.fawe.jnbt.anvil.filters.CountIdFilter;
import com.boydti.fawe.jnbt.anvil.filters.DeleteOldFilter;
import com.boydti.fawe.jnbt.anvil.filters.DeleteUnclaimedFilter;
import com.boydti.fawe.jnbt.anvil.filters.DeleteUninhabitedFilter;
import com.boydti.fawe.jnbt.anvil.filters.MappedReplacePatternFilter;
import com.boydti.fawe.jnbt.anvil.filters.PlotTrimFilter;
@ -219,6 +220,26 @@ public class AnvilCommands {
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
}
@Command(
aliases = {"deleteallunclaimed", "delunclaimed" },
usage = "<age-ticks> [file-age=60000]",
desc = "(Supports: WG, P2, GP) Delete all chunks which haven't been occupied AND claimed",
help = "(Supports: WG, P2, GP) Delete all chunks which aren't claimed AND haven't been occupied for `age-ticks` (20t = 1s) and \n" +
"Have not been accessed since `file-duration` (ms) after creation and\n" +
"Have not been used in the past `chunk-inactivity` (ms)" +
"The auto-save interval is the recommended value for `file-duration` and `chunk-inactivity`",
min = 2,
max = 3
)
@CommandPermissions("worldedit.anvil.deleteallunclaimed")
public void deleteAllUnclaimed(Player player, int inhabitedTicks, @Optional("60000") int fileDurationMillis) throws WorldEditException {
String folder = Fawe.imp().getWorldName(player.getWorld());
long chunkInactivityMillis = fileDurationMillis; // Use same value for now
DeleteUnclaimedFilter filter = new DeleteUnclaimedFilter(player.getWorld(), fileDurationMillis, inhabitedTicks, chunkInactivityMillis);
DeleteUnclaimedFilter result = runWithWorld(player, folder, filter, true);
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
}
@Command(
aliases = {"deletealloldregions", "deloldreg" },
usage = "<folder> <time>",

View File

@ -0,0 +1,47 @@
package com.boydti.fawe.jnbt.anvil.filters;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.jnbt.anvil.MCAFile;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.regions.general.RegionFilter;
import com.sk89q.worldedit.world.World;
import java.io.File;
import java.io.IOException;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
public class DeleteUnclaimedFilter extends DeleteUninhabitedFilter {
private ArrayList<RegionFilter> filters = new ArrayList<>();
public DeleteUnclaimedFilter(World world, long fileDuration, long inhabitedTicks, long chunkInactivity) {
super(fileDuration, inhabitedTicks, chunkInactivity);
for (FaweMaskManager m : FaweAPI.getMaskManagers()) {
RegionFilter filter = m.getFilter(Fawe.imp().getWorldName(world));
if (filter != null) {
filters.add(filter);
}
}
}
@Override
public boolean shouldDelete(File file, BasicFileAttributes attr, int mcaX, int mcaZ) throws IOException {
boolean contains = false;
for (RegionFilter filter : filters) {
if (contains = filter.containsRegion(mcaX, mcaZ)) {
break;
}
}
return !contains && super.shouldDelete(file, attr, mcaX, mcaZ);
}
@Override
public boolean shouldDeleteChunk(MCAFile mca, int cx, int cz) {
boolean contains = false;
for (RegionFilter filter : filters) {
if (contains = filter.containsChunk(cx, cz)) {
break;
}
}
return !contains && super.shouldDeleteChunk(mca, cx, cz);
}
}

View File

@ -94,7 +94,7 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
}
public boolean shouldDeleteChunk(MCAFile mca, int cx, int cz) {
return false;
return true;
}
public void filter(MCAFile mca, ForkJoinPool pool) throws IOException {
@ -103,15 +103,9 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
public void run(Integer x, Integer z, Integer offset, Integer size) {
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;
}
int cx = bx + x;
int cz = bz + z;
if (shouldDeleteChunk(mca, cx, cz)) {
Runnable task = new Runnable() {
@Override
public void run() {
@ -130,6 +124,7 @@ public class DeleteUninhabitedFilter extends MCAFilterCounter {
};
pool.submit(task);
}
}
});
}

View File

@ -0,0 +1,4 @@
package com.boydti.fawe.jnbt.anvil.filters;
public class RegionFilter {
}

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.regions;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.general.RegionFilter;
public abstract class FaweMaskManager<T> {
@ -35,4 +36,8 @@ public abstract class FaweMaskManager<T> {
public boolean isValid(FaweMask mask) {
return true;
}
public RegionFilter getFilter(String world) {
return null;
}
}

View File

@ -0,0 +1,69 @@
package com.boydti.fawe.regions.general;
import com.boydti.fawe.object.collection.LongHashSet;
import com.sk89q.worldedit.Vector2D;
public abstract class CuboidRegionFilter implements RegionFilter {
private final LongHashSet occupiedRegions;
private final LongHashSet unoccupiedChunks;
public CuboidRegionFilter() {
this.occupiedRegions = new LongHashSet();
this.unoccupiedChunks = new LongHashSet();
}
/**
* Loop over all regions and call add(...) with the corners
*/
public abstract void calculateRegions();
public void add(Vector2D pos1, Vector2D pos2) {
int ccx1 = pos1.getBlockX() >> 9;
int ccz1 = pos1.getBlockZ() >> 9;
int ccx2 = pos2.getBlockX() >> 9;
int ccz2 = pos2.getBlockZ() >> 9;
for (int x = ccx1; x <= ccx2; x++) {
for (int z = ccz1; z <= ccz2; z++) {
if (!occupiedRegions.containsKey(x, z)) {
occupiedRegions.add(x, z);
int bcx = x << 5;
int bcz = z << 5;
int tcx = bcx + 32;
int tcz = bcz + 32;
for (int cz = bcz; cz < tcz; cz++) {
for (int cx = bcx; cx < tcx; cx++) {
unoccupiedChunks.add(cx, cz);
}
}
}
}
}
int cx1 = pos1.getBlockX() >> 4;
int cz1 = pos1.getBlockZ() >> 4;
int cx2 = pos2.getBlockX() >> 4;
int cz2 = pos2.getBlockZ() >> 4;
for (int cz = cz1; cz <= cz2; cz++) {
for (int cx = cx1; cx <= cx2; cx++) {
unoccupiedChunks.remove(cx, cz);
}
}
}
public void clear() {
occupiedRegions.popAll();
unoccupiedChunks.popAll();
}
@Override
public boolean containsRegion(int mcaX, int mcaZ) {
return occupiedRegions.containsKey(mcaX, mcaZ);
}
@Override
public boolean containsChunk(int chunkX, int chunkZ) {
int mcaX = chunkX >> 5;
int mcaZ = chunkZ >> 5;
return occupiedRegions.containsKey(mcaX, mcaZ) && !unoccupiedChunks.containsKey(chunkX, chunkZ);
}
}

View File

@ -0,0 +1,7 @@
package com.boydti.fawe.regions.general;
public interface RegionFilter {
public boolean containsRegion(int mcaX, int mcaZ);
public boolean containsChunk(int chunkX, int chunkZ);
}

View File

@ -0,0 +1,29 @@
package com.boydti.fawe.regions.general.plot;
import com.boydti.fawe.regions.general.CuboidRegionFilter;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.sk89q.worldedit.BlockVector2D;
import java.util.ArrayList;
import static com.google.common.base.Preconditions.checkNotNull;
public class PlotRegionFilter extends CuboidRegionFilter {
private final PlotArea area;
public PlotRegionFilter(PlotArea area) {
checkNotNull(area);
this.area = area;
}
@Override
public void calculateRegions() {
ArrayList<Plot> plots = new ArrayList<>(area.getPlots());
for (Plot plot : plots) {
Location pos1 = plot.getBottom();
Location pos2 = plot.getTop();
add(new BlockVector2D(pos1.getX(), pos1.getZ()), new BlockVector2D(pos2.getX(), pos2.getZ()));
}
}
}

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.regions.FaweMask;
import com.boydti.fawe.regions.FaweMaskManager;
import com.boydti.fawe.regions.general.RegionFilter;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.commands.MainCommand;
import com.intellectualcrafters.plot.config.Settings;
@ -138,4 +139,9 @@ public class PlotSquaredFeature extends FaweMaskManager {
}
};
}
@Override
public RegionFilter getFilter(String world) {
return new PlotRegionFilter(PS.get().getPlotArea(world, null));
}
}

View File

@ -141,7 +141,7 @@ public final class DocumentationPrinter {
}
private static void writePermissionsWikiTable(PrintStream stream, StringBuilder content, String prefix, Class<?> cls, String name) {
stream.print(" - [`" + name + "`](#" + name.replaceAll(" ", "-").toLowerCase() + "-edittop) ");
stream.print(" - [`" + name + "`](#" + name.replaceAll(" ", "-").replaceAll("/", "").toLowerCase() + "-edittop) ");
Command cmd = cls.getAnnotation(Command.class);
if (cmd != null) {
stream.print(" (" + cmd.desc() + ")");