Plot auto clear confirmation
Add timediff to keep flag
Add expired parameter to list cmd
Fixes some compatibility issues
This commit is contained in:
Jesse Boyd 2016-03-02 06:56:50 +11:00
parent 106c3c5cb4
commit 8bf3ceac6f
21 changed files with 419 additions and 392 deletions

View File

@ -369,11 +369,11 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
if (PS.get().checkVersion(getServerVersion(), 1, 8, 0)) {
try {
return new FastQueue_1_8_3();
} catch (NoSuchMethodException | RuntimeException e) {
} catch (Throwable e) {
e.printStackTrace();
try {
return new FastQueue_1_8();
} catch (NoSuchMethodException e2) {
} catch (Throwable e2) {
e2.printStackTrace();
return new SlowQueue();
}
@ -381,7 +381,8 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
}
try {
return new FastQueue_1_7();
} catch (NoSuchMethodException e) {
} catch (Throwable e) {
e.printStackTrace();
return new SlowQueue();
}
}

View File

@ -343,14 +343,11 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen
Location loc = pp.getLocation();
PlotArea area = loc.getPlotArea();
final Plot plot;
if (area != null) {
plot = area.getPlot(loc);
Plot plot = area.getPlot(loc);
if (plot != null) {
plotEntry(pp, plot);
}
} else {
plot = null;
}
// Delayed
@ -361,24 +358,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen
if (!player.hasPlayedBefore() && player.isOnline()) {
player.saveData();
}
ExpireManager.dates.put(uuid, System.currentTimeMillis());
if (BukkitMain.worldEdit != null) {
if (pp.getAttribute("worldedit")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASSED);
}
}
if (PS.get().update != null && Permissions.hasPermission(pp, C.PERMISSION_ADMIN_UPDATE) && Settings.UPDATE_NOTIFICATIONS) {
MainUtil.sendMessage(pp, "&6An update for PlotSquared is available: &7/plot update");
}
if (Settings.TELEPORT_ON_LOGIN && plot != null) {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
plot.teleportPlayer(pp);
}
});
MainUtil.sendMessage(pp, C.TELEPORTED_TO_ROAD);
}
EventUtil.manager.doJoinTask(pp);
}
}, 20);
}

View File

@ -668,11 +668,8 @@ public class BukkitChunkManager extends ChunkManager {
if (!pLoc.getChunkLoc().equals(loc)) {
continue;
}
PlotBlock plotblock = WorldUtil.IMP.getBlock(pLoc);
if (plotblock.id != 0) {
Plot plot = pp.getCurrentPlot();
pp.teleport(plot.getDefaultHome());
}
pLoc.setY(WorldUtil.IMP.getHighestBlock(world, pLoc.getX(), pLoc.getZ()));
pp.teleport(pLoc);
}
}
@ -996,20 +993,7 @@ public class BukkitChunkManager extends ChunkManager {
final int tx = pos2.getX();
final int tz = pos2.getZ();
for (final Entity entity : entities) {
if (entity instanceof Player) {
final org.bukkit.Location loc = entity.getLocation();
if (loc.getX() >= bx && loc.getX() <= tx && loc.getZ() >= bz && loc.getZ() <= tz) {
final Player player = (Player) entity;
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Plot plot = pp.getCurrentPlot();
if (plot != null) {
final Location plotHome = plot.getDefaultHome();
if (pp.getLocation().getY() <= plotHome.getY()) {
pp.teleport(plotHome);
}
}
}
} else {
if (!(entity instanceof Player)) {
final org.bukkit.Location loc = entity.getLocation();
if (loc.getX() >= bx && loc.getX() <= tx && loc.getZ() >= bz && loc.getZ() <= tz) {
entity.remove();

View File

@ -5,17 +5,9 @@ import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.schematic.PlotItem;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.StringComparison;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.*;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
@ -25,12 +17,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.material.Sandstone;
import org.bukkit.material.Step;
import org.bukkit.material.Tree;
import org.bukkit.material.WoodenStep;
import org.bukkit.material.Wool;
import org.bukkit.material.*;
import java.util.Arrays;
import java.util.List;

View File

@ -6,9 +6,9 @@ import com.google.common.collect.HashBiMap;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.io.ByteSink;
import com.google.common.io.ByteSource;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import com.google.common.primitives.Primitives;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@ -147,21 +147,20 @@ public class NbtFactory {
* @return The decoded NBT compound.
* @throws IOException If anything went wrong.
*/
public static NbtCompound fromStream(final ByteSource stream, final StreamOptions option) throws IOException {
public static NbtCompound fromStream(final InputSupplier<? extends InputStream> stream, final StreamOptions option) throws IOException {
InputStream input = null;
DataInputStream data = null;
boolean suppress = true;
try {
input = stream.openStream();
input = stream.getInput();
data = new DataInputStream(new BufferedInputStream(option == StreamOptions.GZIP_COMPRESSION ? new GZIPInputStream(input) : input));
final NbtCompound result = fromCompound(get().LOAD_COMPOUND.loadNbt(data));
suppress = false;
return result;
}
finally {
} finally {
if (data != null) {
Closeables.close(data, suppress);
} else if (input != null) {

View File

@ -34,7 +34,7 @@ public class SlowChunk extends PlotChunk<Chunk> {
if (result[y >> 4] == null) {
result[y >> 4] = new PlotBlock[4096];
}
result[MainUtil.CACHE_I[x][y][z]][MainUtil.CACHE_J[x][y][z]] = new PlotBlock((short) id, data);
result[MainUtil.CACHE_I[y][x][z]][MainUtil.CACHE_J[y][x][z]] = new PlotBlock((short) id, data);
}
@Override

View File

@ -123,6 +123,9 @@ public class SlowQueue implements PlotQueue<Chunk> {
final int z = MainUtil.z_loc[i][j];
Block block = chunk.getBlock(x, y, z);
PlotBlock newBlock = result2[j];
if (newBlock == null) {
continue;
}
switch (newBlock.id) {
case -1:
if (block.getData() == newBlock.data) {

View File

@ -2,6 +2,7 @@ package com.plotsquared.bukkit.uuid;
import com.google.common.collect.HashBiMap;
import com.google.common.io.ByteSource;
import com.google.common.io.InputSupplier;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
@ -9,17 +10,14 @@ import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.ExpireManager;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
import com.intellectualcrafters.plot.util.*;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.util.NbtFactory;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -102,12 +100,14 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
final UUID uuid = UUID.fromString(s);
if (check || all.remove(uuid)) {
final File file = new File(playerdataFolder + File.separator + current);
final ByteSource is = com.google.common.io.Files.asByteSource(file);
final InputSupplier<FileInputStream> is = com.google.common.io.Files.newInputStreamSupplier(file);
final NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
final NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
final String name = (String) bukkit.get("lastKnownName");
final long last = (long) bukkit.get("lastPlayed");
ExpireManager.dates.put(uuid, last);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
toAdd.put(new StringWrapper(name), uuid);
}
} catch (final Exception e) {
@ -190,7 +190,9 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
uuid = new UUID(most, least);
}
}
ExpireManager.dates.put(uuid, last);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
toAdd.put(new StringWrapper(name), uuid);
} catch (final Throwable e) {
PS.debug(C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat");
@ -210,7 +212,9 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
final StringWrapper wrap = new StringWrapper(name);
final UUID uuid = uuidWrapper.getUUID(op);
toAdd.put(wrap, uuid);
ExpireManager.dates.put(uuid, last);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
}
}
}

View File

@ -168,12 +168,15 @@ public class PS {
}
}
}
// Auto clearing
if (Settings.AUTO_CLEAR) {
ExpireManager.runTask();
ExpireManager.IMP = new ExpireManager();
if (Settings.AUTO_CLEAR_CONFIRMATION) {
ExpireManager.IMP.runConfirmedTask();
} else {
ExpireManager.IMP.runAutomatedTask();
}
}
// PlotMe
if (Settings.CONVERT_PLOTME || Settings.CACHE_PLOTME) {
TaskManager.runTaskLater(new Runnable() {
@ -1893,7 +1896,7 @@ public class PS {
*/
public void setupDefaultFlags() {
final List<String> booleanFlags = Arrays.asList("notify-enter", "notify-leave", "item-drop", "invincible", "instabreak", "drop-protection", "forcefield", "titles", "pve", "pvp",
"no-worldedit", "redstone", "keep");
"no-worldedit", "redstone");
final List<String> intervalFlags = Arrays.asList("feed", "heal");
final List<String> stringFlags = Arrays.asList("greeting", "farewell");
final List<String> intFlags = Arrays.asList("misc-cap", "entity-cap", "mob-cap", "animal-cap", "hostile-cap", "vehicle-cap", "music");
@ -1937,6 +1940,26 @@ public class PS {
FlagManager.addFlag(new AbstractFlag("use", new FlagValue.PlotBlockListValue()));
FlagManager.addFlag(new AbstractFlag("blocked-cmds", new FlagValue.StringListValue()));
FlagManager.addFlag(new AbstractFlag("ice-melt", new FlagValue.BooleanValue()));
FlagManager.addFlag(new AbstractFlag("keep") {
@Override
public Object parseValueRaw(final String value) {
if (MathMan.isInteger(value)) {
return Long.parseLong(value);
}
switch (value.toLowerCase()) {
case "true":
return true;
case "false":
return false;
default:
return (MainUtil.timeToSec(value) * 1000) + System.currentTimeMillis();
}
}
@Override
public String getValueDesc() {
return "Flag value must a timestamp or a boolean";
}
});
FlagManager.addFlag(new AbstractFlag("gamemode") {
@Override

View File

@ -20,23 +20,6 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.intellectualcrafters.plot.commands;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import com.google.common.io.Files;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
@ -44,32 +27,18 @@ import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.generator.HybridUtils;
import com.intellectualcrafters.plot.object.ConsolePlayer;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotAnalysis;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.AbstractTitle;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.ExpireManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.object.*;
import com.intellectualcrafters.plot.util.*;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import javax.script.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.*;
@CommandDeclaration(command = "debugexec", permission = "plots.admin", description = "Mutli-purpose debug command", aliases = "exec",
category = CommandCategory.DEBUG)
public class DebugExec extends SubCommand {
@ -204,12 +173,9 @@ public class DebugExec extends SubCommand {
}, threshold);
return true;
case "stop-expire":
if (ExpireManager.task != -1) {
PS.get().TASK.cancelTask(ExpireManager.task);
} else {
if (ExpireManager.IMP == null || !ExpireManager.IMP.cancelTask()) {
return MainUtil.sendMessage(player, "Task already halted");
}
ExpireManager.task = -1;
return MainUtil.sendMessage(player, "Cancelled task.");
case "remove-flag":
if (args.length != 2) {
@ -254,41 +220,20 @@ public class DebugExec extends SubCommand {
MainUtil.sendMessage(player, "&cCancelling task... (please wait)");
return true;
case "start-expire":
if (ExpireManager.task == -1) {
ExpireManager.runTask();
if (ExpireManager.IMP == null) {
ExpireManager.IMP = new ExpireManager();
}
boolean result;
if (Settings.AUTO_CLEAR_CONFIRMATION) {
result = ExpireManager.IMP.runConfirmedTask();
} else {
result = ExpireManager.IMP.runAutomatedTask();
}
if (result) {
return MainUtil.sendMessage(player, "Started plot expiry task");
} else {
return MainUtil.sendMessage(player, "Plot expiry task already started");
}
return MainUtil.sendMessage(player, "Started plot expiry task");
case "update-expired":
if (args.length > 1) {
PlotArea area = PS.get().getPlotAreaByString(args[1]);
if (area == null || !WorldUtil.IMP.isWorld(area.worldname)) {
C.NOT_VALID_PLOT_WORLD.send(player, args[1]);
return false;
}
MainUtil.sendMessage(player, "Updating expired plot list");
ExpireManager.updateExpired(area);
return true;
}
return MainUtil.sendMessage(player, "Use /plot debugexec update-expired <world>");
case "show-expired":
if (args.length > 1) {
final String world = args[1];
if (!WorldUtil.IMP.isWorld(world)) {
return MainUtil.sendMessage(player, "Invalid world: " + args[1]);
}
if (!ExpireManager.expiredPlots.containsKey(args[1])) {
return MainUtil.sendMessage(player, "No task for world: " + args[1]);
}
MainUtil.sendMessage(player, "Expired plots (" + ExpireManager.expiredPlots.get(args[1]).size() + "):");
for (final Plot plot : ExpireManager.expiredPlots.get(args[1])) {
MainUtil.sendMessage(player,
" - " + plot.getArea() + ";" + plot.getId().x + ";" + plot.getId().y + ";" + UUIDHandler.getName(plot.owner) + " : " + ExpireManager.dates.get(plot.owner));
}
return true;
}
return MainUtil.sendMessage(player, "Use /plot debugexec show-expired <world>");
case "seen":
if (args.length != 2) {
return MainUtil.sendMessage(player, "Use /plot debugexec seen <player>");

View File

@ -31,13 +31,7 @@ import com.intellectualcrafters.plot.object.PlotMessage;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.Rating;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.StringComparison;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.*;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.ArrayList;
@ -93,6 +87,9 @@ public class list extends SubCommand {
if (Permissions.hasPermission(player, "plots.list.done")) {
args.add("done");
}
if (Permissions.hasPermission(player, "plots.list.expired")) {
args.add("expired");
}
if (Permissions.hasPermission(player, "plots.list.fuzzy")) {
args.add("fuzzy <search...>");
}
@ -163,6 +160,14 @@ public class list extends SubCommand {
plots = new ArrayList<>(PS.get().getPlots(world));
break;
}
case "expired": {
if (!Permissions.hasPermission(plr, "plots.list.expired")) {
MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.expired");
return false;
}
plots = ExpireManager.IMP == null ? new ArrayList<Plot>() : new ArrayList<>(ExpireManager.IMP.getPendingExpired());
break;
}
case "area": {
if (!Permissions.hasPermission(plr, "plots.list.area")) {
MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.area");

View File

@ -163,7 +163,7 @@ public class Settings {
* Auto clear enabled
*/
public static boolean AUTO_CLEAR = false;
public static boolean AUTO_CLEAR_CONFIRMATION = true; // TODO FIXME
public static boolean AUTO_CLEAR_CONFIRMATION = false;
/**
* Days until a plot gets cleared
*/

View File

@ -32,8 +32,6 @@ import java.util.*;
/**
* Flag Manager Utility
*
*/
public class FlagManager {

View File

@ -44,6 +44,11 @@ public abstract class HybridUtils {
public abstract void analyzeRegion(final String world, final RegionWrapper region, final RunnableVal<PlotAnalysis> whenDone);
public void analyzePlot(final Plot origin, final RunnableVal<PlotAnalysis> whenDone) {
PlotAnalysis existing = origin.getComplexity();
if (existing != null) {
whenDone.run(existing);
return;
}
final ArrayDeque<RegionWrapper> zones = new ArrayDeque<>(origin.getRegions());
final ArrayList<PlotAnalysis> analysis = new ArrayList<>();
Runnable run = new Runnable() {

View File

@ -1048,6 +1048,9 @@ public class Plot {
DBFunc.delete(current);
current.owner = null;
current.settings = null;
for (PlotPlayer pp : current.getPlayersInPlot()) {
PlotListener.plotEntry(pp, current);
}
}
return true;
}
@ -1066,7 +1069,7 @@ public class Plot {
final Location top = corners[0];
final Location bot = corners[1];
Location loc = new Location(this.area.worldname, (top.getX() + bot.getX()) / 2, (top.getY() + bot.getY()) / 2, (top.getZ() + bot.getZ()) / 2);
loc.setY(WorldUtil.IMP.getHighestBlock(top.getWorld(), loc.getX(), loc.getY()));
loc.setY(1 + Math.max(WorldUtil.IMP.getHighestBlock(area.worldname, loc.getX(), loc.getZ()), getManager().getSignLoc(area, this).getY()));
return loc;
}
@ -1722,7 +1725,7 @@ public class Plot {
return false;
}
final Plot other = (Plot) obj;
return (this.hashCode() == other.hashCode()) && this.id.x.equals(other.id.x) && this.id.y.equals(other.id.y) && (this.area == other.area);
return (this.hashCode() == other.hashCode()) && this.id.equals(other.id) && (this.area == other.area);
}
/**

View File

@ -382,7 +382,9 @@ public abstract class PlotPlayer implements CommandCaller {
}
}
String name = getName();
ExpireManager.dates.put(getUUID(), System.currentTimeMillis());
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(getUUID(), System.currentTimeMillis());
}
UUIDHandler.getPlayers().remove(name);
PS.get().IMP.unregister(this);
}

View File

@ -1,24 +1,17 @@
package com.intellectualcrafters.plot.util;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.*;
import com.plotsquared.listener.PlayerBlockEventType;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.UUID;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.LazyBlock;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotCluster;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.Rating;
import com.plotsquared.listener.PlayerBlockEventType;
public abstract class EventUtil {
public static EventUtil manager = null;
@ -53,6 +46,30 @@ public abstract class EventUtil {
public abstract void callMember(final PlotPlayer initiator, final Plot plot, final UUID player, final boolean added);
public void doJoinTask(final PlotPlayer pp) {
if (ExpireManager.IMP != null) {
ExpireManager.IMP.handleJoin(pp);
}
if (PS.get().worldedit != null) {
if (pp.getAttribute("worldedit")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASSED);
}
}
if (PS.get().update != null && Permissions.hasPermission(pp, C.PERMISSION_ADMIN_UPDATE) && Settings.UPDATE_NOTIFICATIONS) {
MainUtil.sendMessage(pp, "&6An update for PlotSquared is available: &7/plot update");
}
final Plot plot = pp.getCurrentPlot();
if (Settings.TELEPORT_ON_LOGIN && plot != null) {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
plot.teleportPlayer(pp);
}
});
MainUtil.sendMessage(pp, C.TELEPORTED_TO_ROAD);
}
}
public boolean checkPlayerBlockEvent(final PlotPlayer pp, final PlayerBlockEventType type, final Location loc, final LazyBlock block, boolean notifyPerms) {
PlotArea area = PS.get().getPlotAreaAbs(loc);
Plot plot = area != null ? area.getPlot(loc) : null;

View File

@ -1,185 +1,230 @@
package com.intellectualcrafters.plot.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.generator.HybridUtils;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotAnalysis;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class ExpireManager {
public static ConcurrentHashMap<String, List<Plot>> expiredPlots = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Boolean> updatingPlots = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Long> timestamp = new ConcurrentHashMap<>();
public static ConcurrentHashMap<UUID, Long> dates = new ConcurrentHashMap<>();
public static int task;
public static long getTimeStamp(PlotArea area) {
Long timestamp = (Long) area.getMeta("expiredTimestamp");
return timestamp != null ? timestamp : 0;
public static ExpireManager IMP;
private static HashSet<Plot> plotsToDelete;
private ConcurrentHashMap<UUID, Long> dates_cache = new ConcurrentHashMap<>();
/**
* 0 = stopped, 1 = stopping, 2 = running
*/
private int running;
public void handleJoin(PlotPlayer pp) {
storeDate(pp.getUUID(), System.currentTimeMillis());
confirmExpiry(pp);
}
public static boolean updateExpired(final PlotArea area) {
area.setMeta("updatingExpired", true);
final long now = System.currentTimeMillis();
if (now > getTimeStamp(area)) {
area.setMeta("expiredTimestamp", now + 86400000l);
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
final List<Plot> plots = getOldPlots(area);
PS.debug("$2[&5Expire&dManager$2] $4Found " + plots.size() + " expired plots for " + area + "!");
area.setMeta("expiredPlots", plots);
area.setMeta("updatingExpired", false);
} catch (final Exception e) {
e.printStackTrace();
}
}
});
return true;
} else {
area.setMeta("updatingExpired", false);
return false;
public void handleEntry(PlotPlayer pp, Plot plot) {
if (Settings.AUTO_CLEAR_CONFIRMATION && plotsToDelete != null && !plotsToDelete.isEmpty() && pp.hasPermission("plots.admin.command.autoclear") && plotsToDelete.contains(plot) && !isExpired(plot)) {
plotsToDelete.remove(plot);
confirmExpiry(pp);
}
}
public static void runTask() {
ExpireManager.task = TaskManager.runTaskRepeatAsync(new Runnable() {
@Override
public void run() {
try {
for (final PlotArea area : PS.get().getPlotAreas()) {
Boolean updating = (Boolean) area.getMeta("updatingExpired");
if (updating == null) {
updating = false;
area.setMeta("updatingExpired", false);
}
if (updating) {
PS.debug("$2[&5Expire&dManager$2] $4Waiting on fetch...");
return;
}
List<Plot> plots = (List<Plot>) area.getMeta("expiredPlots");
if (plots == null) {
PS.debug("$2[&5Expire&dManager$2] $4Updating expired plots for: " + area);
updateExpired(area);
return;
}
if ((plots.isEmpty())) {
if (updateExpired(area)) {
PS.debug("$2[&5Expire&dManager$2] $4Re-evaluating expired plots for: " + area);
return;
}
continue;
}
final Iterator<Plot> iter = plots.iterator();
final Plot plot = iter.next();
if (!isExpired(plot)) {
iter.remove();
PS.debug("$2[&5Expire&dManager$2] &bSkipping no longer expired: " + plot);
return;
}
for (final UUID helper : plot.getTrusted()) {
final PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.getId().toString());
}
}
for (final UUID helper : plot.getMembers()) {
final PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.getId().toString());
}
}
final RunnableVal<PlotAnalysis> run = new RunnableVal<PlotAnalysis>() {
@Override
public void run(PlotAnalysis changed) {
if ((Settings.CLEAR_THRESHOLD != -1) && (area.TYPE == 0) && (changed != null)) {
if ((changed.changes != 0) && (changed.getComplexity() > Settings.CLEAR_THRESHOLD)) {
PS.debug("$2[&5Expire&dManager$2] &bIgnoring modified plot: " + plot + " : " + changed.getComplexity() + " - " + changed.changes);
iter.remove();
FlagManager.addPlotFlag(plot, new Flag(FlagManager.getFlag("analysis"), changed.asList()));
return;
}
}
if (plot.isMerged()) {
plot.unlinkPlot(true, false);
}
plot.deletePlot(null);
iter.remove();
final int complexity = changed == null ? 0 : changed.getComplexity();
final int modified = changed == null ? 0 : changed.changes;
PS.debug("$2[&5Expire&dManager$2] &cDeleted expired plot: " + plot + " : " + complexity + " - " + modified);
PS.debug("$4 - Area: " + plot.getArea());
if (plot.hasOwner()) {
PS.debug("$4 - Owner: " + UUIDHandler.getName(plot.owner));
} else {
PS.debug("$4 - Owner: Unowned");
}
}
};
if (plot.getRunning() > 0) {
PS.debug("$2[&5Expire&dManager$2] &bSkipping plot in use: " + plot);
iter.remove();
run();
return;
}
if ((Settings.CLEAR_THRESHOLD != -1) && (area.TYPE == 0)) {
final PlotAnalysis analysis = plot.getComplexity();
if (analysis != null) {
if (analysis.getComplexity() > Settings.CLEAR_THRESHOLD) {
PS.debug("$2[&5Expire&dManager$2] &bSkipping modified: " + plot);
iter.remove();
run();
return;
}
}
HybridUtils.manager.analyzePlot(plot, run);
} else {
run.value = null;
run.run();
}
return;
}
} catch (final Exception e) {
e.printStackTrace();
public void confirmExpiry(final PlotPlayer pp) {
if (Settings.AUTO_CLEAR_CONFIRMATION && plotsToDelete != null && !plotsToDelete.isEmpty() && pp.hasPermission("plots.admin.command.autoclear")) {
int num = plotsToDelete.size();
Iterator<Plot> iter = plotsToDelete.iterator();
while (iter.hasNext()) {
Plot current = iter.next();
if (isExpired(current)) {
final Plot plot = current;
pp.teleport(plot.getCenter());
PlotMessage msg = new PlotMessage()
.text(num + " " + (num > 1 ? "plots are" : "plot is") + " expired:").color("$1").command("/plot list expired").tooltip("/plot list expired")
// .text("\n - ").color("$3").text("Delete all (/plot delete expired)").color("$2").command("/plot delete expired")
.text("\n - ").color("$3").text("Delete this (/plot expired)").color("$2").command("/plot delete").tooltip("/plot delete")
.text("\n - ").color("$3").text("Remind later (/plot set keep 1d)").color("$2").command("/plot set keep 1d").tooltip("/plot set keep 1d")
.text("\n - ").color("$3").text("Keep this (/plot set keep true)").color("$2").command("/plot set keep true").tooltip("/plot set keep true");
msg.send(pp);
return;
}
}
}, Settings.CLEAR_INTERVAL * 20);
plotsToDelete.clear();
return;
}
}
public static boolean isExpired(final UUID uuid) {
public boolean cancelTask() {
if (running != 2) {
return false;
}
running = 1;
return true;
}
public boolean runConfirmedTask() {
if (plotsToDelete == null) {
plotsToDelete = new HashSet<>();
}
return runTask(new RunnableVal2<Plot, Runnable>() {
@Override
public void run(Plot plot, Runnable runnable) {
plotsToDelete.add(plot);
runnable.run();
}
});
}
public boolean runAutomatedTask() {
return runTask(new RunnableVal2<Plot, Runnable>() {
@Override
public void run(Plot plot, Runnable runnable) {
deleteWithMessage(plot, runnable);
}
});
}
public boolean runTask(final RunnableVal2<Plot, Runnable> expiredTask) {
if (running != 0) {
return false;
}
running = 2;
final Set<Plot> plots = PS.get().getPlots();
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
if (running != 2) {
running = 0;
return;
}
final Runnable task = this;
long start = System.currentTimeMillis();
Iterator<Plot> iter = plots.iterator();
while (iter.hasNext() && System.currentTimeMillis() - start < 2) {
if (running != 2) {
running = 0;
return;
}
final Plot plot = iter.next();
iter.remove();
if (!isExpired(plot)) {
continue;
}
PlotArea area = plot.getArea();
if ((Settings.CLEAR_THRESHOLD != -1) && (area.TYPE == 0)) {
final PlotAnalysis analysis = plot.getComplexity();
if (analysis != null) {
if (analysis.getComplexity() > Settings.CLEAR_THRESHOLD) {
PS.debug("$2[&5Expire&dManager$2] &bSkipping modified: " + plot);
continue;
}
}
HybridUtils.manager.analyzePlot(plot, new RunnableVal<PlotAnalysis>() {
@Override
public void run(PlotAnalysis changed) {
if ((changed.changes != 0) && (changed.getComplexity() > Settings.CLEAR_THRESHOLD)) {
PS.debug("$2[&5Expire&dManager$2] &bIgnoring modified plot: " + plot + " : " + changed.getComplexity() + " - " + changed.changes);
FlagManager.addPlotFlag(plot, new Flag(FlagManager.getFlag("analysis"), changed.asList()));
TaskManager.runTaskLaterAsync(task, Settings.CLEAR_INTERVAL * 20);
} else {
expiredTask.run(plot, new Runnable() {
@Override
public void run() {
TaskManager.runTaskLater(task, Settings.CLEAR_INTERVAL * 20);
}
});
}
}
});
} else {
expiredTask.run(plot, this);
}
return;
}
if (plots.size() == 0) {
running = 3;
TaskManager.runTaskLater(new Runnable() {
@Override
public void run() {
if (running == 3) {
running = 2;
runTask(expiredTask);
}
}
}, 86400000);
return;
} else {
TaskManager.runTaskLaterAsync(task, Settings.CLEAR_INTERVAL * 20);
}
}
});
return true;
}
public void storeDate(UUID uuid, long time) {
dates_cache.put(uuid, time);
}
public HashSet<Plot> getPendingExpired() {
return plotsToDelete == null ? new HashSet<Plot>() : plotsToDelete;
}
public void deleteWithMessage(Plot plot, Runnable whenDone) {
if (plot.isMerged()) {
plot.unlinkPlot(true, false);
}
for (final UUID helper : plot.getTrusted()) {
final PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.toString());
}
}
for (final UUID helper : plot.getMembers()) {
final PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.toString());
}
}
plot.deletePlot(whenDone);
final PlotAnalysis changed = plot.getComplexity();
final int complexity = changed == null ? 0 : changed.getComplexity();
final int modified = changed == null ? 0 : changed.changes;
PS.debug("$2[&5Expire&dManager$2] &cDeleted expired plot: " + plot + " : " + complexity + " - " + modified);
PS.debug("$4 - Area: " + plot.getArea());
if (plot.hasOwner()) {
PS.debug("$4 - Owner: " + UUIDHandler.getName(plot.owner));
} else {
PS.debug("$4 - Owner: Unowned");
}
}
public boolean isExpired(final UUID uuid) {
if (UUIDHandler.getPlayer(uuid) != null) {
return false;
}
final String name = UUIDHandler.getName(uuid);
if (name != null) {
long last;
if (dates.containsKey(uuid)) {
last = dates.get(uuid);
} else {
Long last = dates_cache.get(uuid);
if (last == null) {
OfflinePlotPlayer opp;
if (Settings.TWIN_MODE_UUID) {
opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(uuid);
} else {
opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(name);
}
last = opp.getLastPlayed();
if (last != 0) {
dates.put(uuid, last);
} else {
if ((last = opp.getLastPlayed()) != 0) {
dates_cache.put(uuid, last);
}
else {
return false;
}
}
@ -194,7 +239,25 @@ public class ExpireManager {
return false;
}
public static boolean isExpired(final Plot plot) {
public boolean isExpired(final Plot plot) {
if (!plot.hasOwner() || DBFunc.everyone.equals(plot.owner) || UUIDHandler.getPlayer(plot.owner) != null || plot.getRunning() > 0) {
return false;
}
Flag keep = plot.getFlag("keep");
if (keep != null) {
Object value = keep.getValue();
if (value instanceof Boolean) {
if (Boolean.TRUE.equals(value)) {
return false;
}
} else if (value instanceof Long) {
if (((Long) value) > System.currentTimeMillis()) {
return false;
}
} else { // Invalid?
return false;
}
}
for (final UUID owner : plot.getOwners()) {
if (!isExpired(owner)) {
return false;
@ -202,28 +265,4 @@ public class ExpireManager {
}
return true;
}
public static List<Plot> getOldPlots(final PlotArea area) {
final ArrayList<Plot> plots = new ArrayList<>(area.getPlots());
final List<Plot> toRemove = new ArrayList<>();
for (Plot plot : plots) {
final Flag keepFlag = FlagManager.getPlotFlagRaw(plot, "keep");
if ((keepFlag != null) && (Boolean) keepFlag.getValue()) {
continue;
}
final UUID uuid = plot.owner;
if (uuid == null) {
toRemove.add(plot);
continue;
}
final PlotPlayer player = UUIDHandler.getPlayer(uuid);
if (player != null) {
continue;
}
if (isExpired(plot)) {
toRemove.add(plot);
}
}
return toRemove;
}
}

View File

@ -120,6 +120,61 @@ public class MainUtil {
return false;
}
public static long timeToSec(String string) {
if (MathMan.isInteger(string)) {
return Long.parseLong(string);
}
if (string == null) {
return 0;
}
string = string.toLowerCase().trim().toLowerCase();
if (string.equalsIgnoreCase("false")) {
return 0;
}
String[] split = string.split(" ");
long time = 0;
for (int i = 0; i < split.length; i++) {
String value = split[i];
int nums = Integer.parseInt(value.replaceAll("[^\\d]", ""));
String letters = value.replaceAll("[^a-z]", "");
switch (letters) {
case "week":
case "weeks":
case "wks":
case "w": {
time += 604800 * nums;
}
case "days":
case "day":
case "d": {
time += 86400 * nums;
}
case "hour":
case "hr":
case "hrs":
case "hours":
case "h": {
time += 3600 * nums;
}
case "minutes":
case "minute":
case "mins":
case "min":
case "m": {
time += 60 * nums;
}
case "seconds":
case "second":
case "secs":
case "sec":
case "s":{
time += nums;
}
}
}
return time;
}
/**
* Hashcode of a boolean array.<br>
* - Used for traversing mega plots quickly.

View File

@ -29,16 +29,7 @@ import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.AbstractTitle;
import com.intellectualcrafters.plot.util.CommentManager;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.PlotGamemode;
import com.intellectualcrafters.plot.util.PlotWeather;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.*;
import java.util.HashMap;
import java.util.Map;
@ -58,6 +49,9 @@ public class PlotListener {
if ((last != null) && !last.getId().equals(plot.getId())) {
plotExit(pp, last);
}
if (ExpireManager.IMP != null) {
ExpireManager.IMP.handleEntry(pp, plot);
}
pp.setMeta("lastplot", plot);
EventUtil.manager.callEntry(pp, plot);
if (plot.hasOwner()) {

View File

@ -656,24 +656,7 @@ public class MainListener {
TaskManager.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
ExpireManager.dates.put(uuid, System.currentTimeMillis());
if (PS.get().worldedit != null) {
if (pp.getAttribute("worldedit")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASSED);
}
}
if (PS.get().update != null && Permissions.hasPermission(pp, C.PERMISSION_ADMIN_UPDATE) && Settings.UPDATE_NOTIFICATIONS) {
MainUtil.sendMessage(pp, "&6An update for PlotSquared is available: &7/plot update");
}
if (Settings.TELEPORT_ON_LOGIN && plot != null) {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
plot.teleportPlayer(pp);
}
});
MainUtil.sendMessage(pp, C.TELEPORTED_TO_ROAD);
}
EventUtil.manager.doJoinTask(pp);
}
}, 20);
}