2015-01-09 15:05:10 +01:00
|
|
|
package com.intellectualcrafters.plot.util;
|
|
|
|
|
2015-07-05 17:44:10 +02:00
|
|
|
import java.io.File;
|
2015-07-14 16:12:12 +02:00
|
|
|
import java.util.ArrayDeque;
|
2015-07-05 17:44:10 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.OfflinePlayer;
|
|
|
|
|
2015-07-03 14:15:20 +02:00
|
|
|
import com.intellectualcrafters.plot.PS;
|
2015-01-10 11:37:46 +01:00
|
|
|
import com.intellectualcrafters.plot.config.C;
|
2015-01-09 15:05:10 +01:00
|
|
|
import com.intellectualcrafters.plot.config.Settings;
|
2015-04-14 11:32:19 +02:00
|
|
|
import com.intellectualcrafters.plot.flag.Flag;
|
|
|
|
import com.intellectualcrafters.plot.flag.FlagManager;
|
2015-06-07 21:37:40 +02:00
|
|
|
import com.intellectualcrafters.plot.generator.ClassicPlotManager;
|
|
|
|
import com.intellectualcrafters.plot.generator.HybridUtils;
|
2015-07-05 17:44:10 +02:00
|
|
|
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
|
|
|
|
import com.intellectualcrafters.plot.object.Plot;
|
2015-07-18 05:19:36 +02:00
|
|
|
import com.intellectualcrafters.plot.object.PlotAnalysis;
|
2015-07-05 17:44:10 +02:00
|
|
|
import com.intellectualcrafters.plot.object.PlotHandler;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotManager;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotPlayer;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotWorld;
|
|
|
|
import com.intellectualcrafters.plot.object.RunnableVal;
|
2015-02-20 07:28:21 +01:00
|
|
|
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
|
2015-01-09 15:05:10 +01:00
|
|
|
|
|
|
|
public class ExpireManager {
|
2015-05-29 10:41:33 +02:00
|
|
|
public static ConcurrentHashMap<String, List<Plot>> expiredPlots = new ConcurrentHashMap<>();
|
2015-01-09 15:05:10 +01:00
|
|
|
public static ConcurrentHashMap<String, Boolean> updatingPlots = new ConcurrentHashMap<>();
|
2015-02-05 10:24:07 +01:00
|
|
|
public static ConcurrentHashMap<String, Long> timestamp = new ConcurrentHashMap<>();
|
2015-05-29 10:41:33 +02:00
|
|
|
public static ConcurrentHashMap<UUID, Long> dates = new ConcurrentHashMap<>();
|
2015-01-09 15:05:10 +01:00
|
|
|
public static int task;
|
2015-02-23 02:32:27 +01:00
|
|
|
|
2015-02-05 10:24:07 +01:00
|
|
|
public static long getTimeStamp(final String world) {
|
|
|
|
if (timestamp.containsKey(world)) {
|
|
|
|
return timestamp.get(world);
|
2015-02-20 07:34:19 +01:00
|
|
|
} else {
|
2015-02-05 10:24:07 +01:00
|
|
|
timestamp.put(world, 0l);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2015-02-23 02:32:27 +01:00
|
|
|
|
2015-02-05 10:24:07 +01:00
|
|
|
public static boolean updateExpired(final String world) {
|
2015-01-09 15:05:10 +01:00
|
|
|
updatingPlots.put(world, true);
|
2015-02-20 07:34:19 +01:00
|
|
|
final long now = System.currentTimeMillis();
|
2015-02-05 10:24:07 +01:00
|
|
|
if (now > getTimeStamp(world)) {
|
|
|
|
timestamp.put(world, now + 86400000l);
|
2015-02-20 07:34:19 +01:00
|
|
|
TaskManager.runTaskAsync(new Runnable() {
|
2015-01-09 15:05:10 +01:00
|
|
|
@Override
|
|
|
|
public void run() {
|
2015-05-29 10:41:33 +02:00
|
|
|
try {
|
|
|
|
final List<Plot> plots = getOldPlots(world);
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &3Found " + plots.size() + " expired plots for " + world + "!");
|
2015-05-29 10:41:33 +02:00
|
|
|
expiredPlots.put(world, plots);
|
|
|
|
updatingPlots.put(world, false);
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2015-01-09 15:05:10 +01:00
|
|
|
}
|
|
|
|
});
|
2015-02-05 10:24:07 +01:00
|
|
|
return true;
|
2015-02-20 07:34:19 +01:00
|
|
|
} else {
|
2015-01-09 15:05:10 +01:00
|
|
|
updatingPlots.put(world, false);
|
2015-02-05 10:24:07 +01:00
|
|
|
return false;
|
2015-01-09 15:05:10 +01:00
|
|
|
}
|
|
|
|
}
|
2015-02-23 02:32:27 +01:00
|
|
|
|
2015-01-09 15:05:10 +01:00
|
|
|
public static void runTask() {
|
2015-05-15 05:29:23 +02:00
|
|
|
ExpireManager.task = TaskManager.runTaskRepeat(new Runnable() {
|
2015-01-09 15:05:10 +01:00
|
|
|
@Override
|
|
|
|
public void run() {
|
2015-06-24 22:13:32 +02:00
|
|
|
try {
|
2015-07-03 14:15:20 +02:00
|
|
|
for (final String world : PS.get().getPlotWorldsString()) {
|
2015-06-24 22:13:32 +02:00
|
|
|
if (!ExpireManager.updatingPlots.containsKey(world)) {
|
|
|
|
ExpireManager.updatingPlots.put(world, false);
|
|
|
|
}
|
|
|
|
final Boolean updating = ExpireManager.updatingPlots.get(world);
|
|
|
|
if (updating) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &3Waiting on fetch...");
|
2015-02-05 10:24:07 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-06-24 22:13:32 +02:00
|
|
|
if (!expiredPlots.containsKey(world)) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &3Updating expired plots for: " + world);
|
2015-06-24 22:13:32 +02:00
|
|
|
updateExpired(world);
|
|
|
|
return;
|
2015-05-14 14:55:57 +02:00
|
|
|
}
|
2015-06-24 22:13:32 +02:00
|
|
|
final List<Plot> plots = expiredPlots.get(world);
|
|
|
|
if ((plots == null) || (plots.size() == 0)) {
|
|
|
|
if (updateExpired(world)) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &3Re-evaluating expired plots for: " + world);
|
2015-06-24 22:13:32 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
continue;
|
2015-01-10 11:37:46 +01:00
|
|
|
}
|
2015-06-24 22:13:32 +02:00
|
|
|
final Plot plot = plots.iterator().next();
|
|
|
|
if (!isExpired(plot)) {
|
|
|
|
expiredPlots.get(world).remove(plot);
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &bSkipping no longer expired: " + plot);
|
2015-06-24 22:13:32 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (final UUID helper : plot.trusted) {
|
|
|
|
final PlotPlayer player = UUIDHandler.getPlayer(helper);
|
|
|
|
if (player != null) {
|
|
|
|
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.id.toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (final UUID helper : plot.members) {
|
|
|
|
final PlotPlayer player = UUIDHandler.getPlayer(helper);
|
|
|
|
if (player != null) {
|
|
|
|
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.id.toString());
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 14:15:20 +02:00
|
|
|
final PlotManager manager = PS.get().getPlotManager(world);
|
2015-06-24 22:13:32 +02:00
|
|
|
if (manager == null) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &cThis is a friendly reminder to create or delete " + world +" as it is currently setup incorrectly");
|
2015-06-24 22:13:32 +02:00
|
|
|
expiredPlots.get(world).remove(plot);
|
|
|
|
return;
|
|
|
|
}
|
2015-07-03 14:15:20 +02:00
|
|
|
final PlotWorld plotworld = PS.get().getPlotWorld(world);
|
2015-07-18 05:19:36 +02:00
|
|
|
// RunnableVal<Integer> run = new RunnableVal<Integer>() {
|
|
|
|
// @Override
|
|
|
|
// public void run() {
|
|
|
|
// int changed = this.value;
|
|
|
|
// if (Settings.MIN_BLOCKS_CHANGED_IGNORED > 0 || Settings.MIN_BLOCKS_CHANGED > 0 && manager instanceof ClassicPlotManager) {
|
|
|
|
// if (changed >= Settings.MIN_BLOCKS_CHANGED && Settings.MIN_BLOCKS_CHANGED > 0) {
|
|
|
|
// PS.log("&7[&5Expire&dManager&7] &bKeep flag added to: " + plot.id + (changed != -1 ? " (changed " + value + ")" : ""));
|
|
|
|
// FlagManager.addPlotFlag(plot, new Flag(FlagManager.getFlag("keep"), true));
|
|
|
|
// expiredPlots.get(world).remove(plot);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// else if (changed >= Settings.MIN_BLOCKS_CHANGED_IGNORED && Settings.MIN_BLOCKS_CHANGED_IGNORED > 0) {
|
|
|
|
// PS.log("&7[&5Expire&dManager&7] &bIgnoring modified plot: " + plot.id + (changed != -1 ? " (changed " + value + ")" : ""));
|
|
|
|
// FlagManager.addPlotFlag(plot, new Flag(FlagManager.getFlag("modified-blocks"), value));
|
|
|
|
// expiredPlots.get(world).remove(plot);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// if (plot.settings.isMerged()) {
|
|
|
|
// MainUtil.unlinkPlot(plot);
|
|
|
|
// }
|
|
|
|
// plot.delete();
|
|
|
|
// expiredPlots.get(world).remove(plot);
|
|
|
|
// PS.log("&7[&5Expire&dManager&7] &cDeleted expired plot: " + plot.id + (changed != -1 ? " (changed " + value + ")" : ""));
|
|
|
|
// PS.log("&3 - World: " + plot.world);
|
|
|
|
// if (plot.hasOwner()) {
|
|
|
|
// PS.log("&3 - Owner: " + UUIDHandler.getName(plot.owner));
|
|
|
|
// } else {
|
|
|
|
// PS.log("&3 - Owner: Unowned");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
if ((Settings.MIN_BLOCKS_CHANGED_IGNORED > 0 || Settings.CLEAR_THRESHOLD != 100) && plotworld.TYPE == 0) {
|
|
|
|
PlotAnalysis analysis = plot.getComplexity();
|
|
|
|
if (analysis != null) {
|
|
|
|
/*
|
|
|
|
* TODO remove min blocks changed
|
|
|
|
* - it isn't an accurate way to determine plot complexity
|
|
|
|
*
|
|
|
|
* compare this plots complexity with every other plot:
|
|
|
|
* - If it is in the bottom (threshold)% then it will be cleared
|
|
|
|
* - That doesn't make sense, that would mean it would get significantly harder as time goes on.
|
|
|
|
* - I guess as time goes on you can become more strict?
|
|
|
|
*
|
|
|
|
* % of plots to clear - not sure how to do
|
|
|
|
* % within non cleared plots - doesn't work for first plot
|
|
|
|
* % of plots in clear queue - doesn't work if 1 plot
|
|
|
|
*
|
|
|
|
* could be determined during calibration
|
|
|
|
*
|
|
|
|
* or (faster)
|
|
|
|
*
|
|
|
|
* set threshold complexity during calibration
|
|
|
|
*
|
|
|
|
* ideal number of expired plots
|
|
|
|
*
|
|
|
|
* manually set complexity
|
|
|
|
*/
|
2015-06-24 22:13:32 +02:00
|
|
|
}
|
2015-07-18 05:19:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
Flag flag = FlagManager.getPlotFlagAbs(plot, "analysis");
|
2015-06-24 22:13:32 +02:00
|
|
|
if (flag != null) {
|
|
|
|
if ((Integer) flag.getValue() > Settings.MIN_BLOCKS_CHANGED_IGNORED) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&7[&5Expire&dManager&7] &bSkipping modified: " + plot);
|
2015-06-15 18:47:56 +02:00
|
|
|
expiredPlots.get(world).remove(plot);
|
2015-06-24 22:13:32 +02:00
|
|
|
this.run();
|
2015-06-15 18:47:56 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-06-07 21:37:40 +02:00
|
|
|
}
|
2015-06-24 22:13:32 +02:00
|
|
|
else {
|
|
|
|
HybridUtils.manager.checkModified(plot, run);
|
2015-06-07 21:37:40 +02:00
|
|
|
}
|
|
|
|
}
|
2015-06-24 22:13:32 +02:00
|
|
|
else {
|
|
|
|
run.value = -1;
|
|
|
|
run.run();
|
|
|
|
}
|
|
|
|
return;
|
2015-01-09 15:05:10 +01:00
|
|
|
}
|
2015-06-24 22:13:32 +02:00
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
2015-01-09 15:05:10 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-15 05:29:23 +02:00
|
|
|
}, Settings.CLEAR_INTERVAL * 20);
|
2015-01-09 15:05:10 +01:00
|
|
|
}
|
2015-02-23 02:32:27 +01:00
|
|
|
|
2015-02-20 07:34:19 +01:00
|
|
|
public static boolean isExpired(final UUID uuid) {
|
2015-03-20 03:13:27 +01:00
|
|
|
if (UUIDHandler.getPlayer(uuid) != null) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-02-20 07:34:19 +01:00
|
|
|
final String name = UUIDHandler.getName(uuid);
|
|
|
|
if (name != null) {
|
2015-05-29 10:41:33 +02:00
|
|
|
long last;
|
|
|
|
if (dates.contains(uuid)) {
|
|
|
|
last = dates.get(uuid);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
final OfflinePlayer op = Bukkit.getOfflinePlayer(name);
|
|
|
|
if (op.hasPlayedBefore()) {
|
|
|
|
last = op.getLastPlayed();
|
|
|
|
dates.put(uuid, last);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
2015-02-20 07:34:19 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-29 10:41:33 +02:00
|
|
|
if (last == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
final long compared = System.currentTimeMillis() - last;
|
|
|
|
if (compared >= (86400000l * Settings.AUTO_CLEAR_DAYS)) {
|
|
|
|
return true;
|
|
|
|
}
|
2015-02-20 07:34:19 +01:00
|
|
|
}
|
2015-01-09 15:05:10 +01:00
|
|
|
return false;
|
|
|
|
}
|
2015-03-20 03:13:27 +01:00
|
|
|
|
|
|
|
public static boolean isExpired(Plot plot) {
|
|
|
|
for (UUID owner : PlotHandler.getOwners(plot)) {
|
|
|
|
if (!isExpired(owner)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2015-02-23 02:32:27 +01:00
|
|
|
|
2015-05-29 10:41:33 +02:00
|
|
|
public static List<Plot> getOldPlots(final String world) {
|
2015-07-14 16:12:12 +02:00
|
|
|
final ArrayList<Plot> plots = new ArrayList<>(PS.get().getPlots(world).values());
|
2015-05-29 10:41:33 +02:00
|
|
|
final List<Plot> toRemove = new ArrayList<>();
|
2015-05-15 10:12:52 +02:00
|
|
|
Iterator<Plot> iter = plots.iterator();
|
|
|
|
while (iter.hasNext()) {
|
|
|
|
Plot plot = iter.next();
|
2015-04-14 11:32:19 +02:00
|
|
|
final Flag keepFlag = FlagManager.getPlotFlag(plot, "keep");
|
|
|
|
if (keepFlag != null && (Boolean) keepFlag.getValue()) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-03-20 05:11:02 +01:00
|
|
|
final UUID uuid = plot.owner;
|
2015-05-29 10:41:33 +02:00
|
|
|
if (uuid == null) {
|
|
|
|
toRemove.add(plot);
|
2015-01-09 15:05:10 +01:00
|
|
|
continue;
|
|
|
|
}
|
2015-02-21 13:52:50 +01:00
|
|
|
final PlotPlayer player = UUIDHandler.getPlayer(uuid);
|
2015-01-10 11:20:20 +01:00
|
|
|
if (player != null) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-05-29 10:41:33 +02:00
|
|
|
if (isExpired(plot)) {
|
2015-02-04 05:40:39 +01:00
|
|
|
if (Settings.AUTO_CLEAR_CHECK_DISK) {
|
2015-02-20 07:34:19 +01:00
|
|
|
final String worldname = Bukkit.getWorlds().get(0).getName();
|
2015-02-04 05:40:39 +01:00
|
|
|
String foldername;
|
|
|
|
String filename = null;
|
2015-07-03 14:15:20 +02:00
|
|
|
if (PS.get().IMP.checkVersion(1, 7, 5)) {
|
2015-02-04 05:40:39 +01:00
|
|
|
foldername = "playerdata";
|
2015-02-04 05:44:27 +01:00
|
|
|
try {
|
2015-05-29 10:41:33 +02:00
|
|
|
final OfflinePlotPlayer op = UUIDHandler.uuidWrapper.getOfflinePlayer(uuid);
|
2015-02-21 13:52:50 +01:00
|
|
|
filename = op.getUUID() + ".dat";
|
2015-02-20 07:34:19 +01:00
|
|
|
} catch (final Throwable e) {
|
2015-02-04 05:44:27 +01:00
|
|
|
filename = uuid.toString() + ".dat";
|
|
|
|
}
|
2015-02-20 07:34:19 +01:00
|
|
|
} else {
|
2015-02-04 05:40:39 +01:00
|
|
|
foldername = "players";
|
2015-02-20 07:34:19 +01:00
|
|
|
final String playername = UUIDHandler.getName(uuid);
|
2015-02-04 05:40:39 +01:00
|
|
|
if (playername != null) {
|
|
|
|
filename = playername + ".dat";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (filename != null) {
|
2015-02-20 07:34:19 +01:00
|
|
|
final File playerFile = new File(worldname + File.separator + foldername + File.separator + filename);
|
2015-02-04 05:40:39 +01:00
|
|
|
if (!playerFile.exists()) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("Could not find file: " + filename);
|
2015-02-20 07:34:19 +01:00
|
|
|
} else {
|
2015-02-04 05:40:39 +01:00
|
|
|
try {
|
2015-05-29 10:41:33 +02:00
|
|
|
long last = playerFile.lastModified();
|
|
|
|
long compared = System.currentTimeMillis() - last;
|
2015-02-20 07:34:19 +01:00
|
|
|
if (compared < (86400000l * Settings.AUTO_CLEAR_DAYS)) {
|
2015-02-04 05:40:39 +01:00
|
|
|
continue;
|
|
|
|
}
|
2015-02-20 07:34:19 +01:00
|
|
|
} catch (final Exception e) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("Please disable disk checking in old plot auto clearing; Could not read file: " + filename);
|
2015-02-04 05:40:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-05-29 10:41:33 +02:00
|
|
|
toRemove.add(plot);
|
2015-01-09 15:05:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return toRemove;
|
|
|
|
}
|
|
|
|
}
|