Major cleanup.

Added todo comments to many 1.13 issues still lingering. Changed access to some methods to be weaker. Removed cluster flags (most of it). Java 8 stuff added. Hid more PlotSetting methods. etc.

Signed-off-by: matt <4009945+MattBDev@users.noreply.github.com>
This commit is contained in:
matt 2019-01-31 14:20:48 -05:00
parent cd8a1a0816
commit 8ac9b862f8
78 changed files with 14311 additions and 14509 deletions

View File

@ -134,7 +134,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
private final BlockRegistry<Material> blockRegistry = private final BlockRegistry<Material> blockRegistry =
new BukkitBlockRegistry(Material.values()); new BukkitBlockRegistry(Material.values());
private int[] version; private int[] version;
@Getter private String pluginName; private String pluginName;
@Getter private SingleWorldListener singleWorldListener; @Getter private SingleWorldListener singleWorldListener;
private Method methodUnloadChunk0; private Method methodUnloadChunk0;
private boolean methodUnloadSetup = false; private boolean methodUnloadSetup = false;
@ -165,9 +165,9 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return Bukkit.getVersion(); return Bukkit.getVersion();
} }
@Override public void onEnable() { @Override public void onEnable() {
this.pluginName = getDescription().getName(); this.pluginName = getDescription().getName();
getServer().getName();
PlotPlayer.registerConverter(Player.class, BukkitUtil::getPlayer); PlotPlayer.registerConverter(Player.class, BukkitUtil::getPlayer);
@ -319,6 +319,11 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return getDescription().getVersion(); return getDescription().getVersion();
} }
@Override
public String getPluginName() {
return pluginName;
}
@Override public void registerCommands() { @Override public void registerCommands() {
final BukkitCommand bukkitCommand = new BukkitCommand(); final BukkitCommand bukkitCommand = new BukkitCommand();
final PluginCommand plotCommand = getCommand("plots"); final PluginCommand plotCommand = getCommand("plots");
@ -586,6 +591,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
@Override @Nullable @Override @Nullable
public final ChunkGenerator getDefaultWorldGenerator(final String world, final String id) { public final ChunkGenerator getDefaultWorldGenerator(final String world, final String id) {
PlotSquared.log("DEFAULT WORLD GENERATOR RUN");
final IndependentPlotGenerator result; final IndependentPlotGenerator result;
if (id != null && id.equalsIgnoreCase("single")) { if (id != null && id.equalsIgnoreCase("single")) {
result = new SingleWorldGenerator(); result = new SingleWorldGenerator();
@ -802,7 +808,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
ChunkGenerator gen = world.getGenerator(); ChunkGenerator gen = world.getGenerator();
if (gen instanceof BukkitPlotGenerator) { if (gen instanceof BukkitPlotGenerator) {
PlotSquared.get().loadWorld(worldName, (BukkitPlotGenerator) gen); PlotSquared.get().loadWorld(worldName, (GeneratorWrapper<?>) gen);
} else if (gen != null) { } else if (gen != null) {
PlotSquared.get().loadWorld(worldName, new BukkitPlotGenerator(worldName, gen)); PlotSquared.get().loadWorld(worldName, new BukkitPlotGenerator(worldName, gen));
} else if (PlotSquared.get().worlds.contains("worlds." + worldName)) { } else if (PlotSquared.get().worlds.contains("worlds." + worldName)) {

View File

@ -320,34 +320,6 @@ public class FancyMessage
return this; return this;
} }
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param which The achievement to display.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final Achievement which) {
try {
Object achievement = Reflection
.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSAchievement",
Achievement.class).invoke(null, which);
return achievementTooltip(
(String) Reflection.getField(Reflection.getNMSClass("Achievement"), "name")
.get(achievement));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger()
.log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/** /**
* Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text. * Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>

View File

@ -1,63 +0,0 @@
package com.github.intellectualsites.plotsquared.bukkit.events;
import com.github.intellectualsites.plotsquared.plot.flag.Flag;
import com.github.intellectualsites.plotsquared.plot.object.PlotCluster;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a flag is removed from a plot.
*/
public class ClusterFlagRemoveEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final PlotCluster cluster;
private final Flag flag;
private boolean cancelled;
/**
* PlotFlagRemoveEvent: Called when a flag is removed from a plot.
*
* @param flag Flag that was removed
* @param cluster PlotCluster from which the flag was removed
*/
public ClusterFlagRemoveEvent(Flag flag, PlotCluster cluster) {
this.cluster = cluster;
this.flag = flag;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Get the cluster involved.
*
* @return PlotCluster
*/
public PlotCluster getCluster() {
return this.cluster;
}
/**
* Get the flag involved.
*
* @return Flag
*/
public Flag getFlag() {
return this.flag;
}
@Override public HandlerList getHandlers() {
return handlers;
}
@Override public boolean isCancelled() {
return this.cancelled;
}
@Override public void setCancelled(boolean b) {
this.cancelled = b;
}
}

View File

@ -1,5 +1,7 @@
package com.github.intellectualsites.plotsquared.bukkit.listeners; package com.github.intellectualsites.plotsquared.bukkit.listeners;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
@ -9,6 +11,8 @@ import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefCla
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefField; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefField;
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import java.lang.reflect.Method;
import java.util.HashSet;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
@ -27,11 +31,6 @@ import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.ChunkUnloadEvent;
import java.lang.reflect.Method;
import java.util.HashSet;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ChunkListener implements Listener { public class ChunkListener implements Listener {
@ -60,48 +59,46 @@ public class ChunkListener implements Listener {
for (World world : Bukkit.getWorlds()) { for (World world : Bukkit.getWorlds()) {
world.setAutoSave(false); world.setAutoSave(false);
} }
TaskManager.runTaskRepeat(new Runnable() { TaskManager.runTaskRepeat(() -> {
@Override public void run() { try {
try { HashSet<Chunk> toUnload = new HashSet<>();
HashSet<Chunk> toUnload = new HashSet<>(); for (World world : Bukkit.getWorlds()) {
for (World world : Bukkit.getWorlds()) { String worldName = world.getName();
String worldName = world.getName(); if (!PlotSquared.get().hasPlotArea(worldName)) {
if (!PlotSquared.get().hasPlotArea(worldName)) { continue;
}
Object w = world.getClass().getDeclaredMethod("getHandle").invoke(world);
Object chunkMap =
w.getClass().getDeclaredMethod("getPlayerChunkMap").invoke(w);
Method methodIsChunkInUse = chunkMap.getClass()
.getDeclaredMethod("isChunkInUse", int.class, int.class);
Chunk[] chunks = world.getLoadedChunks();
for (Chunk chunk : chunks) {
if ((boolean) methodIsChunkInUse
.invoke(chunkMap, chunk.getX(), chunk.getZ())) {
continue; continue;
} }
Object w = world.getClass().getDeclaredMethod("getHandle").invoke(world); int x = chunk.getX();
Object chunkMap = int z = chunk.getZ();
w.getClass().getDeclaredMethod("getPlayerChunkMap").invoke(w); if (!shouldSave(worldName, x, z)) {
Method methodIsChunkInUse = chunkMap.getClass() unloadChunk(worldName, chunk, false);
.getDeclaredMethod("isChunkInUse", int.class, int.class); continue;
Chunk[] chunks = world.getLoadedChunks();
for (Chunk chunk : chunks) {
if ((boolean) methodIsChunkInUse
.invoke(chunkMap, chunk.getX(), chunk.getZ())) {
continue;
}
int x = chunk.getX();
int z = chunk.getZ();
if (!shouldSave(worldName, x, z)) {
unloadChunk(worldName, chunk, false);
continue;
}
toUnload.add(chunk);
} }
toUnload.add(chunk);
} }
if (toUnload.isEmpty()) { }
if (toUnload.isEmpty()) {
return;
}
long start = System.currentTimeMillis();
for (Chunk chunk : toUnload) {
if (System.currentTimeMillis() - start > 5) {
return; return;
} }
long start = System.currentTimeMillis(); chunk.unload(true, false);
for (Chunk chunk : toUnload) {
if (System.currentTimeMillis() - start > 5) {
return;
}
chunk.unload(true, false);
}
} catch (Throwable e) {
e.printStackTrace();
} }
} catch (Throwable e) {
e.printStackTrace();
} }
}, 1); }, 1);
} }
@ -112,7 +109,7 @@ public class ChunkListener implements Listener {
} }
Object c = this.methodGetHandleChunk.of(chunk).call(); Object c = this.methodGetHandleChunk.of(chunk).call();
RefField.RefExecutor field = this.mustSave.of(c); RefField.RefExecutor field = this.mustSave.of(c);
if ((Boolean) field.get() == true) { if ((Boolean) field.get()) {
field.set(false); field.set(false);
if (chunk.isLoaded()) { if (chunk.isLoaded()) {
ignoreUnload = true; ignoreUnload = true;
@ -226,18 +223,28 @@ public class ChunkListener implements Listener {
private void cleanChunk(final Chunk chunk) { private void cleanChunk(final Chunk chunk) {
TaskManager.index.incrementAndGet(); TaskManager.index.incrementAndGet();
final Integer currentIndex = TaskManager.index.get(); final Integer currentIndex = TaskManager.index.get();
Integer task = TaskManager.runTaskRepeat(new Runnable() { Integer task = TaskManager.runTaskRepeat(() -> {
@Override public void run() { if (!chunk.isLoaded()) {
if (!chunk.isLoaded()) { Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); TaskManager.tasks.remove(currentIndex);
TaskManager.tasks.remove(currentIndex); PlotSquared
PlotSquared .debug(C.PREFIX.s() + "&aSuccessfully processed and unloaded chunk!");
.debug(C.PREFIX.s() + "&aSuccessfully processed and unloaded chunk!"); chunk.unload(true, true);
chunk.unload(true, true); return;
return; }
} BlockState[] tiles = chunk.getTileEntities();
BlockState[] tiles = chunk.getTileEntities(); if (tiles.length == 0) {
if (tiles.length == 0) { Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared
.debug(C.PREFIX.s() + "&aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
long start = System.currentTimeMillis();
int i = 0;
while (System.currentTimeMillis() - start < 250) {
if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex); TaskManager.tasks.remove(currentIndex);
PlotSquared PlotSquared
@ -245,20 +252,8 @@ public class ChunkListener implements Listener {
chunk.unload(true, true); chunk.unload(true, true);
return; return;
} }
long start = System.currentTimeMillis(); tiles[i].getBlock().setType(Material.AIR, false);
int i = 0; i++;
while (System.currentTimeMillis() - start < 250) {
if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared
.debug(C.PREFIX.s() + "&aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
tiles[i].getBlock().setType(Material.AIR, false);
i++;
}
} }
}, 5); }, 5);
TaskManager.tasks.put(currentIndex, task); TaskManager.tasks.put(currentIndex, task);

View File

@ -16,89 +16,90 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@SuppressWarnings("unused") public class ForceFieldListener { @SuppressWarnings("unused")
public class ForceFieldListener {
private static Set<PlotPlayer> getNearbyPlayers(Player player, Plot plot) { private static Set<PlotPlayer> getNearbyPlayers(Player player, Plot plot) {
Set<PlotPlayer> players = new HashSet<>(); Set<PlotPlayer> players = new HashSet<>();
for (Player nearPlayer : Iterables for (Player nearPlayer : Iterables
.filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) { .filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) {
PlotPlayer plotPlayer; PlotPlayer plotPlayer;
if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot
.equals(plotPlayer.getCurrentPlot())) { .equals(plotPlayer.getCurrentPlot())) {
continue; continue;
} }
if (!plot.isAdded(plotPlayer.getUUID())) { if (!plot.isAdded(plotPlayer.getUUID())) {
players.add(plotPlayer); players.add(plotPlayer);
} }
}
return players;
} }
return players;
}
private static PlotPlayer hasNearbyPermitted(Player player, Plot plot) { private static PlotPlayer hasNearbyPermitted(Player player, Plot plot) {
for (Player nearPlayer : Iterables for (Player nearPlayer : Iterables
.filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) { .filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) {
PlotPlayer plotPlayer; PlotPlayer plotPlayer;
if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot
.equals(plotPlayer.getCurrentPlot())) { .equals(plotPlayer.getCurrentPlot())) {
continue; continue;
} }
if (plot.isAdded(plotPlayer.getUUID())) { if (plot.isAdded(plotPlayer.getUUID())) {
return plotPlayer; return plotPlayer;
} }
}
return null;
} }
return null;
}
private static Vector calculateVelocity(PlotPlayer player, PlotPlayer e) { private static Vector calculateVelocity(PlotPlayer player, PlotPlayer e) {
Location playerLocation = player.getLocationFull(); Location playerLocation = player.getLocationFull();
Location oPlayerLocation = e.getLocation(); Location oPlayerLocation = e.getLocation();
double playerX = playerLocation.getX(); double playerX = playerLocation.getX();
double playerY = playerLocation.getY(); double playerY = playerLocation.getY();
double playerZ = playerLocation.getZ(); double playerZ = playerLocation.getZ();
double oPlayerX = oPlayerLocation.getX(); double oPlayerX = oPlayerLocation.getX();
double oPlayerY = oPlayerLocation.getY(); double oPlayerY = oPlayerLocation.getY();
double oPlayerZ = oPlayerLocation.getZ(); double oPlayerZ = oPlayerLocation.getZ();
double x = 0d; double x = 0d;
if (playerX < oPlayerX) { if (playerX < oPlayerX) {
x = 1.0d; x = 1.0d;
} else if (playerX > oPlayerX) { } else if (playerX > oPlayerX) {
x = -1.0d; x = -1.0d;
}
double y = 0d;
if (playerY < oPlayerY) {
y = 0.5d;
} else if (playerY > oPlayerY) {
y = -0.5d;
}
double z = 0d;
if (playerZ < oPlayerZ) {
z = 1.0d;
} else if (playerZ > oPlayerZ) {
z = -1.0d;
}
return new Vector(x, y, z);
} }
double y = 0d;
if (playerY < oPlayerY) {
y = 0.5d;
} else if (playerY > oPlayerY) {
y = -0.5d;
}
double z = 0d;
if (playerZ < oPlayerZ) {
z = 1.0d;
} else if (playerZ > oPlayerZ) {
z = -1.0d;
}
return new Vector(x, y, z);
}
public static void handleForcefield(Player player, PlotPlayer plotPlayer, Plot plot) { public static void handleForcefield(Player player, PlotPlayer plotPlayer, Plot plot) {
if (Flags.FORCEFIELD.isTrue(plot)) { if (Flags.FORCEFIELD.isTrue(plot)) {
UUID uuid = plotPlayer.getUUID(); UUID uuid = plotPlayer.getUUID();
if (plot.isAdded(uuid)) { if (plot.isAdded(uuid)) {
Set<PlotPlayer> players = getNearbyPlayers(player, plot); Set<PlotPlayer> players = getNearbyPlayers(player, plot);
for (PlotPlayer oPlayer : players) { for (PlotPlayer oPlayer : players) {
if (!Permissions.hasPermission(oPlayer, C.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) { if (!Permissions.hasPermission(oPlayer, C.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
((BukkitPlayer) oPlayer).player ((BukkitPlayer) oPlayer).player
.setVelocity(calculateVelocity(plotPlayer, oPlayer)); .setVelocity(calculateVelocity(plotPlayer, oPlayer));
} }
}
} else {
PlotPlayer oPlayer = hasNearbyPermitted(player, plot);
if (oPlayer == null) {
return;
}
if (!Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
player.setVelocity(calculateVelocity(oPlayer, plotPlayer));
}
}
} }
} else {
PlotPlayer oPlayer = hasNearbyPermitted(player, plot);
if (oPlayer == null) {
return;
}
if (!Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
player.setVelocity(calculateVelocity(oPlayer, plotPlayer));
}
}
} }
}
} }

View File

@ -10,6 +10,7 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -37,45 +38,43 @@ public class PlotPlusListener extends PlotListener implements Listener {
private static final HashMap<UUID, Interval> healRunnable = new HashMap<>(); private static final HashMap<UUID, Interval> healRunnable = new HashMap<>();
public static void startRunnable(JavaPlugin plugin) { public static void startRunnable(JavaPlugin plugin) {
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
@Override public void run() { if (!healRunnable.isEmpty()) {
if (!healRunnable.isEmpty()) { for (Iterator<Entry<UUID, Interval>> iterator =
for (Iterator<Entry<UUID, Interval>> iterator = healRunnable.entrySet().iterator(); iterator.hasNext(); ) {
healRunnable.entrySet().iterator(); iterator.hasNext(); ) { Entry<UUID, Interval> entry = iterator.next();
Entry<UUID, Interval> entry = iterator.next(); Interval value = entry.getValue();
Interval value = entry.getValue(); ++value.count;
++value.count; if (value.count == value.interval) {
if (value.count == value.interval) { value.count = 0;
value.count = 0; Player player = Bukkit.getPlayer(entry.getKey());
Player player = Bukkit.getPlayer(entry.getKey()); if (player == null) {
if (player == null) { iterator.remove();
iterator.remove(); continue;
continue; }
} double level = player.getHealth();
double level = player.getHealth(); if (level != value.max) {
if (level != value.max) { player.setHealth(Math.min(level + value.amount, value.max));
player.setHealth(Math.min(level + value.amount, value.max));
}
} }
} }
} }
if (!feedRunnable.isEmpty()) { }
for (Iterator<Entry<UUID, Interval>> iterator = if (!feedRunnable.isEmpty()) {
feedRunnable.entrySet().iterator(); iterator.hasNext(); ) { for (Iterator<Entry<UUID, Interval>> iterator =
Entry<UUID, Interval> entry = iterator.next(); feedRunnable.entrySet().iterator(); iterator.hasNext(); ) {
Interval value = entry.getValue(); Entry<UUID, Interval> entry = iterator.next();
++value.count; Interval value = entry.getValue();
if (value.count == value.interval) { ++value.count;
value.count = 0; if (value.count == value.interval) {
Player player = Bukkit.getPlayer(entry.getKey()); value.count = 0;
if (player == null) { Player player = Bukkit.getPlayer(entry.getKey());
iterator.remove(); if (player == null) {
continue; iterator.remove();
} continue;
int level = player.getFoodLevel(); }
if (level != value.max) { int level = player.getFoodLevel();
player.setFoodLevel(Math.min(level + value.amount, value.max)); if (level != value.max) {
} player.setFoodLevel(Math.min(level + value.amount, value.max));
} }
} }
} }
@ -108,7 +107,7 @@ public class PlotPlusListener extends PlotListener implements Listener {
if (event.getEntityType() != EntityType.PLAYER) { if (event.getEntityType() != EntityType.PLAYER) {
return; return;
} }
Player player = (Player) event.getEntity(); Entity player = event.getEntity();
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot(); Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
if (plot == null) { if (plot == null) {
return; return;

View File

@ -1,9 +1,13 @@
package com.github.intellectualsites.plotsquared.bukkit.listeners; package com.github.intellectualsites.plotsquared.bukkit.listeners;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager; import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager; import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
@ -14,11 +18,6 @@ import org.bukkit.event.world.ChunkEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
@SuppressWarnings("unused") public class SingleWorldListener implements Listener { @SuppressWarnings("unused") public class SingleWorldListener implements Listener {
private Method methodGetHandleChunk; private Method methodGetHandleChunk;
@ -33,8 +32,8 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
this.done = classChunk.getField("done").getRealField(); this.done = classChunk.getField("done").getRealField();
this.lit = classChunk.getField("lit").getRealField(); this.lit = classChunk.getField("lit").getRealField();
this.s = classChunk.getField("s").getRealField(); this.s = classChunk.getField("s").getRealField();
} catch (Throwable ignore) { } catch (NoSuchFieldException exception) {
ignore.printStackTrace(); exception.printStackTrace();
} }
Bukkit.getPluginManager().registerEvents(this, plugin); Bukkit.getPluginManager().registerEvents(this, plugin);
} }

View File

@ -20,6 +20,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.bukkit.inventory.meta.Damageable;
public class StateWrapper { public class StateWrapper {
@ -241,7 +242,7 @@ public class StateWrapper {
public Map<String, Tag> serializeItem(ItemStack item) { public Map<String, Tag> serializeItem(ItemStack item) {
Map<String, Tag> data = new HashMap<>(); Map<String, Tag> data = new HashMap<>();
data.put("id", new StringTag(item.getType().name())); data.put("id", new StringTag(item.getType().name()));
data.put("Damage", new ShortTag(item.getDurability())); data.put("Damage", new ShortTag((short) ((Damageable)item.getItemMeta()).getDamage()));
data.put("Count", new ByteTag((byte) item.getAmount())); data.put("Count", new ByteTag((byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) { if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<>(); List<CompoundTag> enchantmentList = new ArrayList<>();

View File

@ -187,11 +187,7 @@ public abstract class TitleManager {
throws IllegalArgumentException, ReflectiveOperationException, SecurityException; throws IllegalArgumentException, ReflectiveOperationException, SecurityException;
private Class<?> getPrimitiveType(Class<?> clazz) { private Class<?> getPrimitiveType(Class<?> clazz) {
if (CORRESPONDING_TYPES.containsKey(clazz)) { return CORRESPONDING_TYPES.getOrDefault(clazz, clazz);
return CORRESPONDING_TYPES.get(clazz);
} else {
return clazz;
}
} }
private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) { private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) {

View File

@ -335,7 +335,7 @@ public class TitleManager_1_11 {
} }
private Class<?> getPrimitiveType(Class<?> clazz) { private Class<?> getPrimitiveType(Class<?> clazz) {
return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz; return CORRESPONDING_TYPES.getOrDefault(clazz, clazz);
} }
private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) { private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) {

View File

@ -99,10 +99,6 @@ public final class BukkitEventUtil extends EventUtil {
new PlotChangeOwnerEvent(getPlayer(initiator), plot, oldOwner, newOwner, hasOldOwner)); new PlotChangeOwnerEvent(getPlayer(initiator), plot, oldOwner, newOwner, hasOldOwner));
} }
@Override public boolean callFlagRemove(Flag flag, Object object, PlotCluster cluster) {
return callEvent(new ClusterFlagRemoveEvent(flag, cluster));
}
@Override @Nullable public Rating callRating(PlotPlayer player, Plot plot, Rating rating) { @Override @Nullable public Rating callRating(PlotPlayer player, Plot plot, Rating rating) {
PlotRateEvent event = new PlotRateEvent(player, rating, plot); PlotRateEvent event = new PlotRateEvent(player, rating, plot);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);

View File

@ -83,7 +83,7 @@ public class BukkitInventoryUtil extends InventoryUtil {
} }
// int id = item.getTypeId(); // int id = item.getTypeId();
Material id = item.getType(); Material id = item.getType();
short data = item.getDurability(); //short data = item.getDurability();
int amount = item.getAmount(); int amount = item.getAmount();
String name = null; String name = null;
String[] lore = null; String[] lore = null;
@ -94,7 +94,7 @@ public class BukkitInventoryUtil extends InventoryUtil {
} }
if (meta.hasLore()) { if (meta.hasLore()) {
List<String> itemLore = meta.getLore(); List<String> itemLore = meta.getLore();
lore = itemLore.toArray(new String[itemLore.size()]); lore = itemLore.toArray(new String[0]);
} }
} }
return new PlotItemStack(id.name(), amount, name, lore); return new PlotItemStack(id.name(), amount, name, lore);

View File

@ -1,5 +1,7 @@
package com.github.intellectualsites.plotsquared.bukkit.util; package com.github.intellectualsites.plotsquared.bukkit.util;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer; import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.ChunkLoc; import com.github.intellectualsites.plotsquared.plot.object.ChunkLoc;
@ -12,52 +14,49 @@ import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefFie
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.bukkit.Bukkit;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass; import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
/** /**
* An utility that can be used to send chunks, rather than using bukkit code * An utility that can be used to send chunks, rather than using bukkit code to do so (uses heavy
* to do so (uses heavy NMS). * NMS).
*/ */
public class SendChunk { public class SendChunk {
private final RefMethod methodGetHandlePlayer; private final RefMethod methodGetHandlePlayer;
private final RefMethod methodGetHandleChunk; private final RefMethod methodGetHandleChunk;
private final RefConstructor mapChunk; private final RefConstructor mapChunk;
private final RefField connection; private final RefField connection;
private final RefMethod send; private final RefMethod send;
private final RefMethod methodInitLighting; private final RefMethod methodInitLighting;
/** /**
* Constructor. * Constructor.
*/ */
public SendChunk() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException { public SendChunk() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
RefConstructor tempMapChunk; RefConstructor tempMapChunk;
RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer"); RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer");
this.methodGetHandlePlayer = classCraftPlayer.getMethod("getHandle"); this.methodGetHandlePlayer = classCraftPlayer.getMethod("getHandle");
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle"); this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
RefClass classChunk = getRefClass("{nms}.Chunk"); RefClass classChunk = getRefClass("{nms}.Chunk");
this.methodInitLighting = classChunk.getMethod("initLighting"); this.methodInitLighting = classChunk.getMethod("initLighting");
RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk"); RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk");
tempMapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), int.class); tempMapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), int.class);
this.mapChunk = tempMapChunk; this.mapChunk = tempMapChunk;
RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer"); RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
this.connection = classEntityPlayer.getField("playerConnection"); this.connection = classEntityPlayer.getField("playerConnection");
RefClass classPacket = getRefClass("{nms}.Packet"); RefClass classPacket = getRefClass("{nms}.Packet");
RefClass classConnection = getRefClass("{nms}.PlayerConnection"); RefClass classConnection = getRefClass("{nms}.PlayerConnection");
this.send = classConnection.getMethod("sendPacket", classPacket.getRealClass()); this.send = classConnection.getMethod("sendPacket", classPacket.getRealClass());
} }
public void sendChunk(Collection<Chunk> input) { public void sendChunk(Collection<Chunk> input) {
HashSet<Chunk> chunks = new HashSet<>(input); HashSet<Chunk> chunks = new HashSet<>(input);
@ -97,54 +96,52 @@ public class SendChunk {
Player player = ((BukkitPlayer) pp).player; Player player = ((BukkitPlayer) pp).player;
Object entity = this.methodGetHandlePlayer.of(player).call(); Object entity = this.methodGetHandlePlayer.of(player).call();
for (Chunk chunk : list) { for (Chunk chunk : list) {
int dx = Math.abs(cx - chunk.getX()); int dx = Math.abs(cx - chunk.getX());
int dz = Math.abs(cz - chunk.getZ()); int dz = Math.abs(cz - chunk.getZ());
if ((dx > view) || (dz > view)) { if ((dx > view) || (dz > view)) {
continue; continue;
}
Object c = this.methodGetHandleChunk.of(chunk).call();
chunks.remove(chunk);
Object con = this.connection.of(entity).get();
Object packet = null;
try {
packet = this.mapChunk.create(c, 65535);
} catch (Exception ignored) {
}
if (packet == null) {
PlotSquared.debug("Error with PacketPlayOutMapChunk reflection.");
}
this.send.of(con).call(packet);
}
} }
for (final Chunk chunk : chunks) { Object c = this.methodGetHandleChunk.of(chunk).call();
TaskManager.runTask(new Runnable() { chunks.remove(chunk);
@Override public void run() { Object con = this.connection.of(entity).get();
try { Object packet = null;
chunk.unload(true, false); try {
} catch (Throwable ignored) { packet = this.mapChunk.create(c, 65535);
String worldName = chunk.getWorld().getName(); } catch (Exception ignored) {
PlotSquared.debug(
"$4Could not save chunk: " + worldName + ';' + chunk.getX() + ";"
+ chunk.getZ());
PlotSquared
.debug("$3 - $4File may be open in another process (e.g. MCEdit)");
PlotSquared.debug("$3 - $4" + worldName + "/level.dat or " + worldName
+ "/level_old.dat may be corrupt (try repairing or removing these)");
}
}
});
} }
if (packet == null) {
PlotSquared.debug("Error with PacketPlayOutMapChunk reflection.");
}
this.send.of(con).call(packet);
}
} }
for (final Chunk chunk : chunks) {
TaskManager.runTask(() -> {
try {
chunk.unload(true, false);
} catch (Throwable ignored) {
String worldName = chunk.getWorld().getName();
PlotSquared.debug(
"$4Could not save chunk: " + worldName + ';' + chunk.getX() + ";"
+ chunk.getZ());
PlotSquared
.debug("$3 - $4File may be open in another process (e.g. MCEdit)");
PlotSquared.debug("$3 - $4" + worldName + "/level.dat or " + worldName
+ "/level_old.dat may be corrupt (try repairing or removing these)");
}
});
}
}
public void sendChunk(String worldName, Collection<ChunkLoc> chunkLocations) { public void sendChunk(String worldName, Collection<ChunkLoc> chunkLocations) {
World myWorld = Bukkit.getWorld(worldName); World myWorld = Bukkit.getWorld(worldName);
ArrayList<Chunk> chunks = new ArrayList<>(); ArrayList<Chunk> chunks = new ArrayList<>();
for (ChunkLoc loc : chunkLocations) { for (ChunkLoc loc : chunkLocations) {
if (myWorld.isChunkLoaded(loc.x, loc.z)) { if (myWorld.isChunkLoaded(loc.x, loc.z)) {
chunks.add(myWorld.getChunkAt(loc.x, loc.z)); chunks.add(myWorld.getChunkAt(loc.x, loc.z));
} }
}
sendChunk(chunks);
} }
sendChunk(chunks);
}
} }

View File

@ -192,8 +192,7 @@ public class BukkitLocalQueue<T> extends BasicLocalBlockQueue<T> {
for (int x = 0; x < lc.biomes.length; x++) { for (int x = 0; x < lc.biomes.length; x++) {
String[] biomes2 = lc.biomes[x]; String[] biomes2 = lc.biomes[x];
if (biomes2 != null) { if (biomes2 != null) {
for (int y = 0; y < biomes2.length; y++) { for (String biomeStr : biomes2) {
String biomeStr = biomes2[y];
if (biomeStr != null) { if (biomeStr != null) {
if (last == null || !StringMan.isEqual(last, biomeStr)) { if (last == null || !StringMan.isEqual(last, biomeStr)) {
biome = Biome.valueOf(biomeStr.toUpperCase()); biome = Biome.valueOf(biomeStr.toUpperCase());

View File

@ -5,12 +5,13 @@ import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper; import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
import java.util.Arrays;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import java.util.UUID; import java.util.UUID;
public class DefaultUUIDWrapper extends UUIDWrapper { public class DefaultUUIDWrapper implements UUIDWrapper {
@Override public UUID getUUID(PlotPlayer player) { @Override public UUID getUUID(PlotPlayer player) {
return ((BukkitPlayer) player).player.getUniqueId(); return ((BukkitPlayer) player).player.getUniqueId();
@ -30,11 +31,8 @@ public class DefaultUUIDWrapper extends UUIDWrapper {
@Override public OfflinePlotPlayer[] getOfflinePlayers() { @Override public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers(); OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length]; return Arrays.stream(ops).map(BukkitOfflinePlayer::new)
for (int i = 0; i < ops.length; i++) { .toArray(BukkitOfflinePlayer[]::new);
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
}
return toReturn;
} }
@Override public OfflinePlotPlayer getOfflinePlayer(String name) { @Override public OfflinePlotPlayer getOfflinePlayer(String name) {

View File

@ -47,204 +47,200 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
} else { } else {
world = worlds.get(0).getName(); world = worlds.get(0).getName();
} }
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { PlotSquared.debug(C.PREFIX + "&6Starting player data caching for: " + world);
PlotSquared.debug(C.PREFIX + "&6Starting player data caching for: " + world); File uuidFile = new File(PlotSquared.get().IMP.getDirectory(), "uuids.txt");
File uuidFile = new File(PlotSquared.get().IMP.getDirectory(), "uuids.txt"); if (uuidFile.exists()) {
if (uuidFile.exists()) { try {
try { List<String> lines =
List<String> lines = Files.readAllLines(uuidFile.toPath(), StandardCharsets.UTF_8);
Files.readAllLines(uuidFile.toPath(), StandardCharsets.UTF_8); for (String line : lines) {
for (String line : lines) { try {
try { line = line.trim();
line = line.trim(); if (line.isEmpty()) {
if (line.isEmpty()) { continue;
continue;
}
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
String[] split = line.split("\\|");
String name = split[0];
if (name.isEmpty() || (name.length() > 16) || !StringMan
.isAlphanumericUnd(name)) {
continue;
}
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
if (uuid == null) {
continue;
}
UUIDHandler.add(new StringWrapper(name), uuid);
} catch (Exception e2) {
e2.printStackTrace();
} }
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
String[] split = line.split("\\|");
String name = split[0];
if (name.isEmpty() || (name.length() > 16) || !StringMan
.isAlphanumericUnd(name)) {
continue;
}
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
if (uuid == null) {
continue;
}
UUIDHandler.add(new StringWrapper(name), uuid);
} catch (Exception e2) {
e2.printStackTrace();
} }
} catch (IOException e) {
e.printStackTrace();
} }
} catch (IOException e) {
e.printStackTrace();
} }
HashBiMap<StringWrapper, UUID> toAdd = }
HashBiMap.create(new HashMap<StringWrapper, UUID>()); HashBiMap<StringWrapper, UUID> toAdd =
if (Settings.UUID.NATIVE_UUID_PROVIDER) { HashBiMap.create(new HashMap<>());
HashSet<UUID> all = UUIDHandler.getAllUUIDS(); if (Settings.UUID.NATIVE_UUID_PROVIDER) {
PlotSquared.debug("&aFast mode UUID caching enabled!"); HashSet<UUID> all = UUIDHandler.getAllUUIDS();
File playerDataFolder = PlotSquared.debug("&aFast mode UUID caching enabled!");
new File(container, world + File.separator + "playerdata"); File playerDataFolder =
String[] dat = playerDataFolder.list(new DatFileFilter()); new File(container, world + File.separator + "playerdata");
boolean check = all.isEmpty(); String[] dat = playerDataFolder.list(new DatFileFilter());
if (dat != null) { boolean check = all.isEmpty();
for (String current : dat) { if (dat != null) {
String s = current.replaceAll(".dat$", ""); for (String current : dat) {
try { String s = current.replaceAll(".dat$", "");
UUID uuid = UUID.fromString(s); try {
if (check || all.remove(uuid)) { UUID uuid = UUID.fromString(s);
File file = new File(playerDataFolder, current); if (check || all.remove(uuid)) {
NbtFactory.NbtCompound compound = NbtFactory File file = new File(playerDataFolder, current);
.fromStream(new FileInputStream(file), NbtFactory.NbtCompound compound = NbtFactory
NbtFactory.StreamOptions.GZIP_COMPRESSION); .fromStream(new FileInputStream(file),
if (!compound.containsKey("bukkit")) { NbtFactory.StreamOptions.GZIP_COMPRESSION);
PlotSquared.debug("ERROR: Player data (" + uuid.toString() if (!compound.containsKey("bukkit")) {
+ ".dat) does not contain the the key \"bukkit\""); PlotSquared.debug("ERROR: Player data (" + uuid.toString()
} else { + ".dat) does not contain the the key \"bukkit\"");
NbtFactory.NbtCompound bukkit = } else {
(NbtFactory.NbtCompound) compound.get("bukkit"); NbtFactory.NbtCompound bukkit =
String name = (String) bukkit.get("lastKnownName"); (NbtFactory.NbtCompound) compound.get("bukkit");
long last = (long) bukkit.get("lastPlayed"); String name = (String) bukkit.get("lastKnownName");
long first = (long) bukkit.get("firstPlayed"); long last = (long) bukkit.get("lastPlayed");
if (ExpireManager.IMP != null) { long first = (long) bukkit.get("firstPlayed");
ExpireManager.IMP.storeDate(uuid, last); if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeAccountAge(uuid, last - first); ExpireManager.IMP.storeDate(uuid, last);
} ExpireManager.IMP.storeAccountAge(uuid, last - first);
toAdd.put(new StringWrapper(name), uuid);
} }
} toAdd.put(new StringWrapper(name), uuid);
} catch (Exception e) {
e.printStackTrace();
PlotSquared.debug(C.PREFIX + "Invalid playerdata: " + current);
}
}
}
add(toAdd);
if (all.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
} else {
PlotSquared.debug("Failed to cache: " + all.size()
+ " uuids - slowly processing all files");
}
}
HashSet<String> worlds = Sets.newHashSet(world, "world");
HashSet<UUID> uuids = new HashSet<>();
HashSet<String> names = new HashSet<>();
File playerDataFolder = null;
for (String worldName : worlds) {
// Getting UUIDs
playerDataFolder =
new File(container, worldName + File.separator + "playerdata");
String[] dat = playerDataFolder.list(new DatFileFilter());
if ((dat != null) && (dat.length != 0)) {
for (String current : dat) {
String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (Exception ignored) {
PlotSquared.debug(C.PREFIX + "Invalid PlayerData: " + current);
}
}
break;
}
// Getting names
File playersFolder = new File(worldName + File.separator + "players");
dat = playersFolder.list(new DatFileFilter());
if ((dat != null) && (dat.length != 0)) {
for (String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
break;
}
}
for (UUID uuid : uuids) {
try {
File file =
new File(playerDataFolder + File.separator + uuid.toString() + ".dat");
if (!file.exists()) {
continue;
}
NbtFactory.NbtCompound compound = NbtFactory
.fromStream(new FileInputStream(file),
NbtFactory.StreamOptions.GZIP_COMPRESSION);
if (!compound.containsKey("bukkit")) {
PlotSquared.debug("ERROR: Player data (" + uuid.toString()
+ ".dat) does not contain the the key \"bukkit\"");
} else {
NbtFactory.NbtCompound bukkit =
(NbtFactory.NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) {
long last = (long) bukkit.get("lastPlayed");
long first = (long) bukkit.get("firstPlayed");
if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase()
.equals(name)) {
uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
} else {
long most = (long) compound.get("UUIDMost");
long least = (long) compound.get("UUIDLeast");
uuid = new UUID(most, least);
}
}
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
ExpireManager.IMP.storeAccountAge(uuid, last - first);
}
toAdd.put(wrap, uuid);
}
}
} catch (Exception ignored) {
PlotSquared
.debug(C.PREFIX + "&6Invalid PlayerData: " + uuid.toString() + ".dat");
}
}
for (String name : names) {
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
StringWrapper nameWrap = new StringWrapper(name);
toAdd.put(nameWrap, uuid);
}
if (getUUIDMap().isEmpty()) {
for (OfflinePlotPlayer op : FileUUIDHandler.this.uuidWrapper
.getOfflinePlayers()) {
long last = op.getLastPlayed();
if (last != 0) {
String name = op.getName();
StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) {
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(op);
toAdd.put(wrap, uuid);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
} }
} }
} catch (Exception e) {
e.printStackTrace();
PlotSquared.debug(C.PREFIX + "Invalid playerdata: " + current);
} }
} }
} }
add(toAdd); add(toAdd);
if (whenDone != null) { if (all.isEmpty()) {
whenDone.run(); if (whenDone != null) {
whenDone.run();
}
return;
} else {
PlotSquared.debug("Failed to cache: " + all.size()
+ " uuids - slowly processing all files");
} }
} }
HashSet<String> worlds1 = Sets.newHashSet(world, "world");
HashSet<UUID> uuids = new HashSet<>();
HashSet<String> names = new HashSet<>();
File playerDataFolder = null;
for (String worldName : worlds1) {
// Getting UUIDs
playerDataFolder =
new File(container, worldName + File.separator + "playerdata");
String[] dat = playerDataFolder.list(new DatFileFilter());
if ((dat != null) && (dat.length != 0)) {
for (String current : dat) {
String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (Exception ignored) {
PlotSquared.debug(C.PREFIX + "Invalid PlayerData: " + current);
}
}
break;
}
// Getting names
File playersFolder = new File(worldName + File.separator + "players");
dat = playersFolder.list(new DatFileFilter());
if ((dat != null) && (dat.length != 0)) {
for (String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
break;
}
}
for (UUID uuid : uuids) {
try {
File file =
new File(playerDataFolder + File.separator + uuid.toString() + ".dat");
if (!file.exists()) {
continue;
}
NbtFactory.NbtCompound compound = NbtFactory
.fromStream(new FileInputStream(file),
NbtFactory.StreamOptions.GZIP_COMPRESSION);
if (!compound.containsKey("bukkit")) {
PlotSquared.debug("ERROR: Player data (" + uuid.toString()
+ ".dat) does not contain the the key \"bukkit\"");
} else {
NbtFactory.NbtCompound bukkit =
(NbtFactory.NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) {
long last = (long) bukkit.get("lastPlayed");
long first = (long) bukkit.get("firstPlayed");
if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase()
.equals(name)) {
uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
} else {
long most = (long) compound.get("UUIDMost");
long least = (long) compound.get("UUIDLeast");
uuid = new UUID(most, least);
}
}
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
ExpireManager.IMP.storeAccountAge(uuid, last - first);
}
toAdd.put(wrap, uuid);
}
}
} catch (Exception ignored) {
PlotSquared
.debug(C.PREFIX + "&6Invalid PlayerData: " + uuid.toString() + ".dat");
}
}
for (String name : names) {
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
StringWrapper nameWrap = new StringWrapper(name);
toAdd.put(nameWrap, uuid);
}
if (getUUIDMap().isEmpty()) {
for (OfflinePlotPlayer op : FileUUIDHandler.this.uuidWrapper
.getOfflinePlayers()) {
long last = op.getLastPlayed();
if (last != 0) {
String name = op.getName();
StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) {
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(op);
toAdd.put(wrap, uuid);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
}
}
}
}
add(toAdd);
if (whenDone != null) {
whenDone.run();
}
}); });
return true; return true;
} }
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) { @Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { ifFetch.value = FileUUIDHandler.this.uuidWrapper.getUUID(name);
ifFetch.value = FileUUIDHandler.this.uuidWrapper.getUUID(name); TaskManager.runTask(ifFetch);
TaskManager.runTask(ifFetch);
}
}); });
} }
} }

View File

@ -9,6 +9,7 @@ import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper; import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import java.util.Arrays;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Server; import org.bukkit.Server;
@ -19,7 +20,7 @@ import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.UUID; import java.util.UUID;
public class OfflineUUIDWrapper extends UUIDWrapper { public class OfflineUUIDWrapper implements UUIDWrapper {
private final Object[] arg = new Object[0]; private final Object[] arg = new Object[0];
private Method getOnline = null; private Method getOnline = null;
@ -59,18 +60,15 @@ public class OfflineUUIDWrapper extends UUIDWrapper {
return new BukkitOfflinePlayer(op); return new BukkitOfflinePlayer(op);
} }
} }
for (OfflinePlayer player : Bukkit.getOfflinePlayers()) { return Arrays.stream(Bukkit.getOfflinePlayers())
if (getUUID(player).equals(uuid)) { .filter(player -> getUUID(player).equals(uuid)).findFirst()
return new BukkitOfflinePlayer(player); .map(BukkitOfflinePlayer::new).orElse(null);
}
}
return null;
} }
public Player[] getOnlinePlayers() { public Player[] getOnlinePlayers() {
if (this.getOnline == null) { if (this.getOnline == null) {
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers(); Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[onlinePlayers.size()]); return onlinePlayers.toArray(new Player[0]);
} }
try { try {
Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg); Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg);
@ -79,13 +77,13 @@ public class OfflineUUIDWrapper extends UUIDWrapper {
} else { } else {
@SuppressWarnings("unchecked") Collection<? extends Player> p = @SuppressWarnings("unchecked") Collection<? extends Player> p =
(Collection<? extends Player>) players; (Collection<? extends Player>) players;
return p.toArray(new Player[p.size()]); return p.toArray(new Player[0]);
} }
} catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException ignored) { } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException ignored) {
PlotSquared.debug("Failed to resolve online players"); PlotSquared.debug("Failed to resolve online players");
this.getOnline = null; this.getOnline = null;
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers(); Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[onlinePlayers.size()]); return onlinePlayers.toArray(new Player[0]);
} }
} }
@ -95,11 +93,8 @@ public class OfflineUUIDWrapper extends UUIDWrapper {
@Override public OfflinePlotPlayer[] getOfflinePlayers() { @Override public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers(); OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length]; return Arrays.stream(ops).map(BukkitOfflinePlayer::new)
for (int i = 0; i < ops.length; i++) { .toArray(BukkitOfflinePlayer[]::new);
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
}
return toReturn;
} }
@Override public OfflinePlotPlayer getOfflinePlayer(String name) { @Override public OfflinePlotPlayer getOfflinePlayer(String name) {

View File

@ -71,96 +71,90 @@ public class SQLUUIDHandler extends UUIDHandlerImplementation {
if (!super.startCaching(whenDone)) { if (!super.startCaching(whenDone)) {
return false; return false;
} }
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { try {
try { HashBiMap<StringWrapper, UUID> toAdd =
HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<>());
HashBiMap.create(new HashMap<StringWrapper, UUID>()); try (PreparedStatement statement = getConnection()
try (PreparedStatement statement = getConnection() .prepareStatement("SELECT `uuid`, `username` FROM `usercache`");
.prepareStatement("SELECT `uuid`, `username` FROM `usercache`"); ResultSet resultSet = statement.executeQuery()) {
ResultSet resultSet = statement.executeQuery()) { while (resultSet.next()) {
while (resultSet.next()) { StringWrapper username =
StringWrapper username = new StringWrapper(resultSet.getString("username"));
new StringWrapper(resultSet.getString("username")); UUID uuid = UUID.fromString(resultSet.getString("uuid"));
UUID uuid = UUID.fromString(resultSet.getString("uuid")); toAdd.put(new StringWrapper(username.value), uuid);
toAdd.put(new StringWrapper(username.value), uuid);
}
} }
add(toAdd); }
// This should be called as long as there are some unknown plots add(toAdd);
final ArrayDeque<UUID> toFetch = new ArrayDeque<>(); // This should be called as long as there are some unknown plots
for (UUID u : UUIDHandler.getAllUUIDS()) { final ArrayDeque<UUID> toFetch = new ArrayDeque<>();
if (!uuidExists(u)) { for (UUID u : UUIDHandler.getAllUUIDS()) {
toFetch.add(u); if (!uuidExists(u)) {
} toFetch.add(u);
} }
if (toFetch.isEmpty()) { }
if (toFetch.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
}
FileUUIDHandler fileHandler =
new FileUUIDHandler(SQLUUIDHandler.this.uuidWrapper);
fileHandler.startCaching(() -> {
// If the file based UUID handler didn't cache it, then we can't cache offline mode
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
if (Settings.UUID.OFFLINE) {
if (whenDone != null) { if (whenDone != null) {
whenDone.run(); whenDone.run();
} }
return; return;
} }
FileUUIDHandler fileHandler =
new FileUUIDHandler(SQLUUIDHandler.this.uuidWrapper);
fileHandler.startCaching(new Runnable() {
@Override public void run() {
// If the file based UUID handler didn't cache it, then we can't cache offline mode
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
if (Settings.UUID.OFFLINE) {
if (whenDone != null) {
whenDone.run();
}
return;
}
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { while (!toFetch.isEmpty()) {
while (!toFetch.isEmpty()) { try {
try { for (int i = 0;
for (int i = 0; i < Math.min(500, toFetch.size()); i++) {
i < Math.min(500, toFetch.size()); i++) { UUID uuid = toFetch.pop();
UUID uuid = toFetch.pop(); HttpURLConnection connection =
HttpURLConnection connection = (HttpURLConnection) new URL(
(HttpURLConnection) new URL( SQLUUIDHandler.this.PROFILE_URL + uuid
SQLUUIDHandler.this.PROFILE_URL + uuid .toString().replace("-", ""))
.toString().replace("-", "")) .openConnection();
.openConnection(); try (InputStream con = connection
try (InputStream con = connection .getInputStream()) {
.getInputStream()) { InputStreamReader reader =
InputStreamReader reader = new InputStreamReader(con);
new InputStreamReader(con); JSONObject response =
JSONObject response = (JSONObject) SQLUUIDHandler.this.jsonParser
(JSONObject) SQLUUIDHandler.this.jsonParser .parse(reader);
.parse(reader); String name = (String) response.get("name");
String name = (String) response.get("name"); if (name != null) {
if (name != null) { add(new StringWrapper(name), uuid);
add(new StringWrapper(name), uuid);
}
}
connection.disconnect();
}
} catch (IOException | ParseException e) {
PlotSquared.debug(
"Invalid response from Mojang: Some UUIDs will be cached later. (`unknown` until then or player joins)");
}
try {
Thread.sleep(INTERVAL * 50);
} catch (InterruptedException e) {
e.printStackTrace();
break;
} }
} }
if (whenDone != null) { connection.disconnect();
whenDone.run();
}
return;
} }
}); } catch (IOException | ParseException e) {
PlotSquared.debug(
"Invalid response from Mojang: Some UUIDs will be cached later. (`unknown` until then or player joins)");
}
try {
Thread.sleep(INTERVAL * 50);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
} }
if (whenDone != null) {
whenDone.run();
}
return;
}); });
} catch (SQLException e) { });
throw new SQLUUIDHandlerException("Couldn't select :s", e); } catch (SQLException e) {
} throw new SQLUUIDHandlerException("Couldn't select :s", e);
} }
}); });
return true; return true;
@ -172,34 +166,32 @@ public class SQLUUIDHandler extends UUIDHandlerImplementation {
if (ifFetch == null) { if (ifFetch == null) {
return; return;
} }
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { try {
try { URL url = new URL(SQLUUIDHandler.this.PROFILE_URL);
URL url = new URL(SQLUUIDHandler.this.PROFILE_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST");
connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Content-Type", "application/json"); connection.setUseCaches(false);
connection.setUseCaches(false); connection.setDoInput(true);
connection.setDoInput(true); connection.setDoOutput(true);
connection.setDoOutput(true); String body = JSONArray.toJSONString(Collections.singletonList(name));
String body = JSONArray.toJSONString(Collections.singletonList(name)); OutputStream stream = connection.getOutputStream();
OutputStream stream = connection.getOutputStream(); stream.write(body.getBytes());
stream.write(body.getBytes()); stream.flush();
stream.flush(); stream.close();
stream.close(); JSONArray array = (JSONArray) SQLUUIDHandler.this.jsonParser
JSONArray array = (JSONArray) SQLUUIDHandler.this.jsonParser .parse(new InputStreamReader(connection.getInputStream()));
.parse(new InputStreamReader(connection.getInputStream())); JSONObject jsonProfile = (JSONObject) array.get(0);
JSONObject jsonProfile = (JSONObject) array.get(0); String id = (String) jsonProfile.get("id");
String id = (String) jsonProfile.get("id"); String name1 = (String) jsonProfile.get("name");
String name = (String) jsonProfile.get("name"); ifFetch.value = UUID.fromString(
ifFetch.value = UUID.fromString( id.substring(0, 8) + '-' + id.substring(8, 12) + '-' + id.substring(12, 16)
id.substring(0, 8) + '-' + id.substring(8, 12) + '-' + id.substring(12, 16) + '-' + id.substring(16, 20) + '-' + id.substring(20, 32));
+ '-' + id.substring(16, 20) + '-' + id.substring(20, 32)); } catch (IOException | ParseException e) {
} catch (IOException | ParseException e) { e.printStackTrace();
e.printStackTrace();
}
TaskManager.runTask(ifFetch);
} }
TaskManager.runTask(ifFetch);
}); });
} }
@ -215,18 +207,16 @@ public class SQLUUIDHandler extends UUIDHandlerImplementation {
@Override public boolean add(final StringWrapper name, final UUID uuid) { @Override public boolean add(final StringWrapper name, final UUID uuid) {
// Ignoring duplicates // Ignoring duplicates
if (super.add(name, uuid)) { if (super.add(name, uuid)) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { try (PreparedStatement statement = getConnection().prepareStatement(
try (PreparedStatement statement = getConnection().prepareStatement( "REPLACE INTO usercache (`uuid`, `username`) VALUES(?, ?)")) {
"REPLACE INTO usercache (`uuid`, `username`) VALUES(?, ?)")) { statement.setString(1, uuid.toString());
statement.setString(1, uuid.toString()); statement.setString(2, name.toString());
statement.setString(2, name.toString()); statement.execute();
statement.execute(); PlotSquared
PlotSquared .debug(C.PREFIX + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'");
.debug(C.PREFIX + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'"); } catch (SQLException e) {
} catch (SQLException e) { e.printStackTrace();
e.printStackTrace();
}
} }
}); });
return true; return true;
@ -239,18 +229,16 @@ public class SQLUUIDHandler extends UUIDHandlerImplementation {
*/ */
@Override public void rename(final UUID uuid, final StringWrapper name) { @Override public void rename(final UUID uuid, final StringWrapper name) {
super.rename(uuid, name); super.rename(uuid, name);
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { try (PreparedStatement statement = getConnection()
try (PreparedStatement statement = getConnection() .prepareStatement("UPDATE usercache SET `username`=? WHERE `uuid`=?")) {
.prepareStatement("UPDATE usercache SET `username`=? WHERE `uuid`=?")) { statement.setString(1, name.value);
statement.setString(1, name.value); statement.setString(2, uuid.toString());
statement.setString(2, uuid.toString()); statement.execute();
statement.execute(); PlotSquared.debug(
PlotSquared.debug( C.PREFIX + "Name change for '" + uuid + "' to '" + name.value + '\'');
C.PREFIX + "Name change for '" + uuid + "' to '" + name.value + '\''); } catch (SQLException e) {
} catch (SQLException e) { e.printStackTrace();
e.printStackTrace();
}
} }
}); });
} }

View File

@ -1,6 +1,7 @@
package com.github.intellectualsites.plotsquared.configuration; package com.github.intellectualsites.plotsquared.configuration;
import java.util.Map; import java.util.Map;
import javax.annotation.Nonnull;
/** /**
* Represents a source of configurable options and settings. * Represents a source of configurable options and settings.
@ -20,7 +21,7 @@ public interface Configuration extends ConfigurationSection {
* @param value Value to set the default to. * @param value Value to set the default to.
* @throws IllegalArgumentException Thrown if path is null. * @throws IllegalArgumentException Thrown if path is null.
*/ */
@Override void addDefault(String path, Object value); @Override void addDefault(@Nonnull String path, Object value);
/** /**
* Sets the default values of the given paths as provided. * Sets the default values of the given paths as provided.

View File

@ -31,7 +31,7 @@ class ConfigurationOptions {
* *
* @return Path separator * @return Path separator
*/ */
public char pathSeparator() { char pathSeparator() {
return pathSeparator; return pathSeparator;
} }
@ -64,7 +64,7 @@ class ConfigurationOptions {
* *
* @return Whether or not defaults are directly copied * @return Whether or not defaults are directly copied
*/ */
public boolean copyDefaults() { boolean copyDefaults() {
return copyDefaults; return copyDefaults;
} }

View File

@ -3,6 +3,7 @@ package com.github.intellectualsites.plotsquared.configuration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull;
/** /**
* Represents a section of a {@link Configuration}. * Represents a section of a {@link Configuration}.
@ -52,7 +53,7 @@ public interface ConfigurationSection {
* default or being set. * default or being set.
* @throws IllegalArgumentException Thrown when path is {@code null}. * @throws IllegalArgumentException Thrown when path is {@code null}.
*/ */
boolean contains(String path); boolean contains(@Nonnull String path);
/** /**
* Checks if this {@link ConfigurationSection} has a value set for the * Checks if this {@link ConfigurationSection} has a value set for the
@ -66,7 +67,7 @@ public interface ConfigurationSection {
* having a default. * having a default.
* @throws IllegalArgumentException Thrown when path is {@code null}. * @throws IllegalArgumentException Thrown when path is {@code null}.
*/ */
boolean isSet(String path); boolean isSet(@Nonnull String path);
/** /**
* Gets the path of this {@link ConfigurationSection} from its root {@link * Gets the path of this {@link ConfigurationSection} from its root {@link
@ -151,7 +152,7 @@ public interface ConfigurationSection {
* @param defaultValue The default value to return if the path is not found. * @param defaultValue The default value to return if the path is not found.
* @return Requested Object. * @return Requested Object.
*/ */
Object get(String path, Object defaultValue); Object getOrDefault(@Nonnull String path, Object defaultValue);
/** /**
* Sets the specified path to the given value. * Sets the specified path to the given value.
@ -644,5 +645,5 @@ public interface ConfigurationSection {
* @param value Value to set the default to * @param value Value to set the default to
* @throws IllegalArgumentException Thrown if path is {@code null} * @throws IllegalArgumentException Thrown if path is {@code null}
*/ */
void addDefault(String path, Object value); void addDefault(@Nonnull String path, Object value);
} }

View File

@ -1,6 +1,7 @@
package com.github.intellectualsites.plotsquared.configuration; package com.github.intellectualsites.plotsquared.configuration;
import java.util.Map; import java.util.Map;
import javax.annotation.Nonnull;
/** /**
* This is a {@link Configuration} implementation that does not save or load * This is a {@link Configuration} implementation that does not save or load
@ -28,7 +29,7 @@ public class MemoryConfiguration extends MemorySection implements Configuration
this.defaults = defaults; this.defaults = defaults;
} }
@Override public void addDefault(String path, Object value) { @Override public void addDefault(@Nonnull String path, Object value) {
if (this.defaults == null) { if (this.defaults == null) {
this.defaults = new MemoryConfiguration(); this.defaults = new MemoryConfiguration();
} }

View File

@ -6,6 +6,7 @@ import com.github.intellectualsites.plotsquared.configuration.MemoryConfiguratio
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import javax.annotation.Nonnull;
/** /**
* This is a base class for all File based implementations of {@link * This is a base class for all File based implementations of {@link
@ -82,7 +83,7 @@ public abstract class FileConfiguration extends MemoryConfiguration {
* a valid Configuration. * a valid Configuration.
* @throws IllegalArgumentException Thrown when file is null. * @throws IllegalArgumentException Thrown when file is null.
*/ */
public void load(File file) throws IOException, InvalidConfigurationException { public void load(@Nonnull File file) throws IOException, InvalidConfigurationException {
FileInputStream stream = new FileInputStream(file); FileInputStream stream = new FileInputStream(file);

View File

@ -83,7 +83,7 @@ public class YamlConfiguration extends FileConfiguration {
Map<?, ?> input; Map<?, ?> input;
try { try {
input = (Map<?, ?>) yaml.load(contents); input = yaml.load(contents);
} catch (YAMLException e) { } catch (YAMLException e) {
throw new InvalidConfigurationException(e); throw new InvalidConfigurationException(e);
} catch (ClassCastException ignored) { } catch (ClassCastException ignored) {

View File

@ -42,7 +42,7 @@ public class YamlConfigurationOptions extends FileConfigurationOptions {
* *
* @return How much to indent by * @return How much to indent by
*/ */
public int indent() { int indent() {
return indent; return indent;
} }

View File

@ -9,7 +9,7 @@ import org.yaml.snakeyaml.nodes.Tag;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
public class YamlConstructor extends SafeConstructor { class YamlConstructor extends SafeConstructor {
YamlConstructor() { YamlConstructor() {
yamlConstructors.put(Tag.MAP, new ConstructCustomObject()); yamlConstructors.put(Tag.MAP, new ConstructCustomObject());

View File

@ -76,7 +76,9 @@ public interface IPlotMain extends ILogger {
* *
* @return * @return
*/ */
String getPluginName(); default String getPluginName() {
return "PlotSquared";
}
/** /**
* Get the version of Minecraft that is running. * Get the version of Minecraft that is running.

View File

@ -1,6 +1,6 @@
package com.github.intellectualsites.plotsquared.plot; package com.github.intellectualsites.plotsquared.plot;
public enum Platform { public enum Platform {
Bukkit, Sponge, Spigot, Cauldron Bukkit, Sponge, Spigot
} }

File diff suppressed because one or more lines are too long

View File

@ -104,36 +104,34 @@ import java.util.Set;
final String path = final String path =
"worlds." + area.worldname + ".areas." + area.id + '-' "worlds." + area.worldname + ".areas." + area.id + '-'
+ object.min + '-' + object.max; + object.min + '-' + object.max;
Runnable run = new Runnable() { Runnable run = () -> {
@Override public void run() { if (offsetX != 0) {
if (offsetX != 0) { PlotSquared.get().worlds
PlotSquared.get().worlds .set(path + ".road.offset.x", offsetX);
.set(path + ".road.offset.x", offsetX); }
} if (offsetZ != 0) {
if (offsetZ != 0) { PlotSquared.get().worlds
PlotSquared.get().worlds .set(path + ".road.offset.z", offsetZ);
.set(path + ".road.offset.z", offsetZ); }
} final String world = SetupUtils.manager.setupWorld(object);
final String world = SetupUtils.manager.setupWorld(object); if (WorldUtil.IMP.isWorld(world)) {
if (WorldUtil.IMP.isWorld(world)) { PlotSquared.get().loadWorld(world, null);
PlotSquared.get().loadWorld(world, null); C.SETUP_FINISHED.send(player);
C.SETUP_FINISHED.send(player); player.teleport(WorldUtil.IMP.getSpawn(world));
player.teleport(WorldUtil.IMP.getSpawn(world)); if (area.TERRAIN != 3) {
if (area.TERRAIN != 3) { ChunkManager.largeRegionTask(world, region,
ChunkManager.largeRegionTask(world, region, new RunnableVal<ChunkLoc>() {
new RunnableVal<ChunkLoc>() { @Override public void run(ChunkLoc value) {
@Override public void run(ChunkLoc value) { AugmentedUtils
AugmentedUtils .generate(world, value.x, value.z,
.generate(world, value.x, value.z, null);
null); }
} }, null);
}, null);
}
} else {
MainUtil.sendMessage(player,
"An error occurred while creating the world: "
+ area.worldname);
} }
} else {
MainUtil.sendMessage(player,
"An error occurred while creating the world: "
+ area.worldname);
} }
}; };
if (hasConfirmation(player)) { if (hasConfirmation(player)) {
@ -228,32 +226,30 @@ import java.util.Set;
C.SETUP_WORLD_TAKEN.send(player, pa.worldname); C.SETUP_WORLD_TAKEN.send(player, pa.worldname);
return false; return false;
} }
Runnable run = new Runnable() { Runnable run = () -> {
@Override public void run() { String path = "worlds." + pa.worldname;
String path = "worlds." + pa.worldname; if (!PlotSquared.get().worlds.contains(path)) {
if (!PlotSquared.get().worlds.contains(path)) { PlotSquared.get().worlds.createSection(path);
PlotSquared.get().worlds.createSection(path); }
} ConfigurationSection section =
ConfigurationSection section = PlotSquared.get().worlds.getConfigurationSection(path);
PlotSquared.get().worlds.getConfigurationSection(path); pa.saveConfiguration(section);
pa.saveConfiguration(section); pa.loadConfiguration(section);
pa.loadConfiguration(section); object.plotManager = PlotSquared.imp().getPluginName();
object.plotManager = PlotSquared.imp().getPluginName(); object.setupGenerator = PlotSquared.imp().getPluginName();
object.setupGenerator = PlotSquared.imp().getPluginName(); String world = SetupUtils.manager.setupWorld(object);
String world = SetupUtils.manager.setupWorld(object); if (WorldUtil.IMP.isWorld(world)) {
if (WorldUtil.IMP.isWorld(world)) { C.SETUP_FINISHED.send(player);
C.SETUP_FINISHED.send(player); player.teleport(WorldUtil.IMP.getSpawn(world));
player.teleport(WorldUtil.IMP.getSpawn(world)); } else {
} else { MainUtil.sendMessage(player,
MainUtil.sendMessage(player, "An error occurred while creating the world: "
"An error occurred while creating the world: " + pa.worldname);
+ pa.worldname); }
} try {
try { PlotSquared.get().worlds.save(PlotSquared.get().worldsFile);
PlotSquared.get().worlds.save(PlotSquared.get().worldsFile); } catch (IOException e) {
} catch (IOException e) { e.printStackTrace();
e.printStackTrace();
}
} }
}; };
if (hasConfirmation(player)) { if (hasConfirmation(player)) {
@ -422,11 +418,7 @@ import java.util.Set;
@Override public void run(ChunkLoc value) { @Override public void run(ChunkLoc value) {
AugmentedUtils.generate(area.worldname, value.x, value.z, null); AugmentedUtils.generate(area.worldname, value.x, value.z, null);
} }
}, new Runnable() { }, () -> player.sendMessage("Regen complete"));
@Override public void run() {
player.sendMessage("Regen complete");
}
});
return true; return true;
} }
case "goto": case "goto":

View File

@ -82,22 +82,14 @@ public class Claim extends SubCommand {
if (plot.canClaim(player)) { if (plot.canClaim(player)) {
plot.owner = player.getUUID(); plot.owner = player.getUUID();
final String finalSchematic = schematic; final String finalSchematic = schematic;
DBFunc.createPlotSafe(plot, new Runnable() { DBFunc.createPlotSafe(plot, () -> TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override public void run() { @Override public void run(Object value) {
TaskManager.IMP.sync(new RunnableVal<Object>() { plot.claim(player, true, finalSchematic, false);
@Override public void run(Object value) { if (area.AUTO_MERGE) {
plot.claim(player, true, finalSchematic, false); plot.autoMerge(-1, Integer.MAX_VALUE, player.getUUID(), true);
if (area.AUTO_MERGE) { }
plot.autoMerge(-1, Integer.MAX_VALUE, player.getUUID(), true);
}
}
});
} }
}, new Runnable() { }), () -> sendMessage(player, C.PLOT_NOT_CLAIMED));
@Override public void run() {
sendMessage(player, C.PLOT_NOT_CLAIMED);
}
});
return true; return true;
} else { } else {
sendMessage(player, C.PLOT_NOT_CLAIMED); sendMessage(player, C.PLOT_NOT_CLAIMED);

View File

@ -302,6 +302,7 @@ import java.util.UUID;
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area == null) { if (area == null) {
C.NOT_IN_PLOT_WORLD.send(player); C.NOT_IN_PLOT_WORLD.send(player);
return false;
} }
PlotCluster cluster = area.getCluster(player.getLocation()); PlotCluster cluster = area.getCluster(player.getLocation());
if (cluster == null) { if (cluster == null) {
@ -347,6 +348,7 @@ import java.util.UUID;
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area == null) { if (area == null) {
C.NOT_IN_PLOT_WORLD.send(player); C.NOT_IN_PLOT_WORLD.send(player);
return false;
} }
PlotCluster cluster = area.getCluster(player.getLocation()); PlotCluster cluster = area.getCluster(player.getLocation());
if (cluster == null) { if (cluster == null) {
@ -405,6 +407,7 @@ import java.util.UUID;
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area == null) { if (area == null) {
C.NOT_IN_PLOT_WORLD.send(player); C.NOT_IN_PLOT_WORLD.send(player);
return false;
} }
PlotCluster cluster; PlotCluster cluster;
if (args.length == 2) { if (args.length == 2) {
@ -440,7 +443,6 @@ import java.util.UUID;
PlotSquared.get().getPlots(player.getLocation().getWorld(), uuid))) { PlotSquared.get().getPlots(player.getLocation().getWorld(), uuid))) {
PlotCluster current = plot.getCluster(); PlotCluster current = plot.getCluster();
if (current != null && current.equals(cluster)) { if (current != null && current.equals(cluster)) {
player.getLocation().getWorld();
plot.unclaim(); plot.unclaim();
} }
} }
@ -462,6 +464,7 @@ import java.util.UUID;
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area == null) { if (area == null) {
C.NOT_IN_PLOT_WORLD.send(player); C.NOT_IN_PLOT_WORLD.send(player);
return false;
} }
PlotCluster cluster = area.getCluster(player.getLocation()); PlotCluster cluster = area.getCluster(player.getLocation());
if (cluster == null) { if (cluster == null) {
@ -534,6 +537,7 @@ import java.util.UUID;
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area == null) { if (area == null) {
C.NOT_IN_PLOT_WORLD.send(player); C.NOT_IN_PLOT_WORLD.send(player);
return false;
} }
PlotCluster cluster; PlotCluster cluster;
if (args.length == 2) { if (args.length == 2) {
@ -581,6 +585,7 @@ import java.util.UUID;
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area == null) { if (area == null) {
C.NOT_IN_PLOT_WORLD.send(player); C.NOT_IN_PLOT_WORLD.send(player);
return false;
} }
PlotCluster cluster = area.getCluster(player.getLocation()); PlotCluster cluster = area.getCluster(player.getLocation());
if (cluster == null) { if (cluster == null) {

View File

@ -65,6 +65,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
sizes.add(size - 1); sizes.add(size - 1);
} }
// Sort plots by size (buckets?)] // Sort plots by size (buckets?)]
//noinspection unchecked
ArrayList<Plot>[] buckets = new ArrayList[maxSize]; ArrayList<Plot>[] buckets = new ArrayList[maxSize];
for (int i = 0; i < plots.size(); i++) { for (int i = 0; i < plots.size(); i++) {
Plot plot = plots.get(i); Plot plot = plots.get(i);
@ -126,13 +127,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
i++; i++;
final AtomicBoolean result = new AtomicBoolean(false); final AtomicBoolean result = new AtomicBoolean(false);
result.set(origin.move(possible, new Runnable() { result.set(origin.move(possible, () -> {
@Override public void run() { if (result.get()) {
if (result.get()) { MainUtil.sendMessage(player,
MainUtil.sendMessage(player, "Moving: " + origin + " -> " + possible);
"Moving: " + origin + " -> " + possible); TaskManager.runTaskLater(task, 1);
TaskManager.runTaskLater(task, 1);
}
} }
}, false)); }, false));
if (result.get()) { if (result.get()) {

View File

@ -25,174 +25,163 @@ import java.util.Map.Entry;
@CommandDeclaration(command = "database", aliases = {"convert"}, @CommandDeclaration(command = "database", aliases = {"convert"},
category = CommandCategory.ADMINISTRATION, permission = "plots.database", category = CommandCategory.ADMINISTRATION, permission = "plots.database",
description = "Convert/Backup Storage", requiredType = RequiredType.CONSOLE, description = "Convert/Backup Storage", requiredType = RequiredType.CONSOLE,
usage = "/plot database [area] <sqlite|mysql|import>") public class Database usage = "/plot database [area] <sqlite|mysql|import>")
public class Database
extends SubCommand { extends SubCommand {
public static void insertPlots(final SQLManager manager, final List<Plot> plots, public static void insertPlots(final SQLManager manager, final List<Plot> plots,
final PlotPlayer player) { final PlotPlayer player) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { try {
try { ArrayList<Plot> ps = new ArrayList<>(plots);
ArrayList<Plot> ps = new ArrayList<>(); MainUtil.sendMessage(player, "&6Starting...");
for (Plot p : plots) { manager.createPlotsAndData(ps, () -> {
ps.add(p); MainUtil.sendMessage(player, "&6Database conversion finished!");
} manager.close();
MainUtil.sendMessage(player, "&6Starting...");
manager.createPlotsAndData(ps, new Runnable() {
@Override public void run() {
MainUtil.sendMessage(player, "&6Database conversion finished!");
manager.close();
}
});
} catch (Exception e) {
MainUtil.sendMessage(player,
"Failed to insert plot objects, see stacktrace for info");
e.printStackTrace();
}
}
}); });
} } catch (Exception e) {
MainUtil.sendMessage(player,
"Failed to insert plot objects, see stacktrace for info");
e.printStackTrace();
}
});
}
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override
if (args.length < 1) { public boolean onCommand(final PlotPlayer player, String[] args) {
MainUtil.sendMessage(player, "/plot database [area] <sqlite|mysql|import>"); if (args.length < 1) {
return false; MainUtil.sendMessage(player, "/plot database [area] <sqlite|mysql|import>");
} return false;
List<Plot> plots;
PlotArea area = PlotSquared.get().getPlotAreaByString(args[0]);
if (area != null) {
plots = PlotSquared.get().sortPlotsByTemp(area.getPlots());
args = Arrays.copyOfRange(args, 1, args.length);
} else {
plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getPlots());
}
if (args.length < 1) {
MainUtil.sendMessage(player, "/plot database [world] <sqlite|mysql|import>");
MainUtil.sendMessage(player, "[arg] indicates an optional argument");
return false;
}
try {
com.github.intellectualsites.plotsquared.plot.database.Database implementation;
String prefix = "";
switch (args[0].toLowerCase()) {
case "import":
if (args.length < 2) {
MainUtil
.sendMessage(player, "/plot database import <sqlite file> [prefix]");
return false;
}
File file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
args[1].endsWith(".db") ? args[1] : args[1] + ".db");
if (!file.exists()) {
MainUtil.sendMessage(player, "&6Database does not exist: " + file);
return false;
}
MainUtil.sendMessage(player, "&6Starting...");
implementation = new SQLite(file);
SQLManager manager =
new SQLManager(implementation, args.length == 3 ? args[2] : "", true);
HashMap<String, HashMap<PlotId, Plot>> map = manager.getPlots();
plots = new ArrayList<>();
for (Entry<String, HashMap<PlotId, Plot>> entry : map.entrySet()) {
String areaname = entry.getKey();
PlotArea pa = PlotSquared.get().getPlotAreaByString(areaname);
if (pa != null) {
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
Plot plot = entry2.getValue();
if (pa.getOwnedPlotAbs(plot.getId()) != null) {
if (pa instanceof SinglePlotArea) {
Plot newPlot = pa.getNextFreePlot(null, plot.getId());
if (newPlot != null) {
PlotId newId = newPlot.getId();
PlotId id = plot.getId();
File worldFile =
new File(PlotSquared.imp().getWorldContainer(),
id.toCommaSeparatedString());
if (worldFile.exists()) {
File newFile =
new File(PlotSquared.imp().getWorldContainer(),
newId.toCommaSeparatedString());
worldFile.renameTo(newFile);
}
id.x = newId.x;
id.y = newId.y;
id.recalculateHash();
plot.setArea(pa);
plots.add(plot);
continue;
}
}
MainUtil.sendMessage(player,
"Skipping duplicate plot: " + plot + " | id=" + plot.temp);
continue;
}
plot.setArea(pa);
plots.add(plot);
}
} else {
HashMap<PlotId, Plot> plotmap =
PlotSquared.get().plots_tmp.get(areaname);
if (plotmap == null) {
plotmap = new HashMap<>();
PlotSquared.get().plots_tmp.put(areaname, plotmap);
}
plotmap.putAll(entry.getValue());
}
}
DBFunc.createPlotsAndData(plots, new Runnable() {
@Override public void run() {
MainUtil.sendMessage(player, "&6Database conversion finished!");
}
});
return true;
case "mysql":
if (args.length < 6) {
return MainUtil.sendMessage(player,
"/plot database mysql [host] [port] [username] [password] [database] {prefix}");
}
String host = args[1];
String port = args[2];
String username = args[3];
String password = args[4];
String database = args[5];
if (args.length > 6) {
prefix = args[6];
}
implementation = new MySQL(host, port, database, username, password);
break;
case "sqlite":
if (args.length < 2) {
return MainUtil.sendMessage(player, "/plot database sqlite [file]");
}
File sqliteFile =
MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), args[1] + ".db");
implementation = new SQLite(sqliteFile);
break;
default:
return MainUtil.sendMessage(player, "/plot database [sqlite/mysql]");
}
try {
SQLManager manager = new SQLManager(implementation, prefix, true);
Database.insertPlots(manager, plots, player);
return true;
} catch (ClassNotFoundException | SQLException e) {
MainUtil.sendMessage(player, "$1Failed to save plots, read stacktrace for info");
MainUtil.sendMessage(player,
"&d==== Here is an ugly stacktrace, if you are interested in those things ===");
e.printStackTrace();
MainUtil.sendMessage(player, "&d==== End of stacktrace ====");
MainUtil
.sendMessage(player, "$1Please make sure you are using the correct arguments!");
return false;
}
} catch (ClassNotFoundException | SQLException e) {
MainUtil.sendMessage(player, "$1Failed to open connection, read stacktrace for info");
MainUtil.sendMessage(player,
"&d==== Here is an ugly stacktrace, if you are interested in those things ===");
e.printStackTrace();
MainUtil.sendMessage(player, "&d==== End of stacktrace ====");
MainUtil.sendMessage(player, "$1Please make sure you are using the correct arguments!");
return false;
}
} }
List<Plot> plots;
PlotArea area = PlotSquared.get().getPlotAreaByString(args[0]);
if (area != null) {
plots = PlotSquared.get().sortPlotsByTemp(area.getPlots());
args = Arrays.copyOfRange(args, 1, args.length);
} else {
plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getPlots());
}
if (args.length < 1) {
MainUtil.sendMessage(player, "/plot database [world] <sqlite|mysql|import>");
MainUtil.sendMessage(player, "[arg] indicates an optional argument");
return false;
}
try {
com.github.intellectualsites.plotsquared.plot.database.Database implementation;
String prefix = "";
switch (args[0].toLowerCase()) {
case "import":
if (args.length < 2) {
MainUtil
.sendMessage(player, "/plot database import <sqlite file> [prefix]");
return false;
}
File file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
args[1].endsWith(".db") ? args[1] : args[1] + ".db");
if (!file.exists()) {
MainUtil.sendMessage(player, "&6Database does not exist: " + file);
return false;
}
MainUtil.sendMessage(player, "&6Starting...");
implementation = new SQLite(file);
SQLManager manager =
new SQLManager(implementation, args.length == 3 ? args[2] : "", true);
HashMap<String, HashMap<PlotId, Plot>> map = manager.getPlots();
plots = new ArrayList<>();
for (Entry<String, HashMap<PlotId, Plot>> entry : map.entrySet()) {
String areaname = entry.getKey();
PlotArea pa = PlotSquared.get().getPlotAreaByString(areaname);
if (pa != null) {
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
Plot plot = entry2.getValue();
if (pa.getOwnedPlotAbs(plot.getId()) != null) {
if (pa instanceof SinglePlotArea) {
Plot newPlot = pa.getNextFreePlot(null, plot.getId());
if (newPlot != null) {
PlotId newId = newPlot.getId();
PlotId id = plot.getId();
File worldFile =
new File(PlotSquared.imp().getWorldContainer(),
id.toCommaSeparatedString());
if (worldFile.exists()) {
File newFile =
new File(PlotSquared.imp().getWorldContainer(),
newId.toCommaSeparatedString());
worldFile.renameTo(newFile);
}
id.x = newId.x;
id.y = newId.y;
id.recalculateHash();
plot.setArea(pa);
plots.add(plot);
continue;
}
}
MainUtil.sendMessage(player,
"Skipping duplicate plot: " + plot + " | id=" + plot.temp);
continue;
}
plot.setArea(pa);
plots.add(plot);
}
} else {
HashMap<PlotId, Plot> plotmap =
PlotSquared.get().plots_tmp
.computeIfAbsent(areaname, k -> new HashMap<>());
plotmap.putAll(entry.getValue());
}
}
DBFunc.createPlotsAndData(plots,
() -> MainUtil.sendMessage(player, "&6Database conversion finished!"));
return true;
case "mysql":
if (args.length < 6) {
return MainUtil.sendMessage(player,
"/plot database mysql [host] [port] [username] [password] [database] {prefix}");
}
String host = args[1];
String port = args[2];
String username = args[3];
String password = args[4];
String database = args[5];
if (args.length > 6) {
prefix = args[6];
}
implementation = new MySQL(host, port, database, username, password);
break;
case "sqlite":
if (args.length < 2) {
return MainUtil.sendMessage(player, "/plot database sqlite [file]");
}
File sqliteFile =
MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), args[1] + ".db");
implementation = new SQLite(sqliteFile);
break;
default:
return MainUtil.sendMessage(player, "/plot database [sqlite/mysql]");
}
try {
SQLManager manager = new SQLManager(implementation, prefix, true);
Database.insertPlots(manager, plots, player);
return true;
} catch (ClassNotFoundException | SQLException e) {
MainUtil.sendMessage(player, "$1Failed to save plots, read stacktrace for info");
MainUtil.sendMessage(player,
"&d==== Here is an ugly stacktrace, if you are interested in those things ===");
e.printStackTrace();
MainUtil.sendMessage(player, "&d==== End of stacktrace ====");
MainUtil
.sendMessage(player, "$1Please make sure you are using the correct arguments!");
return false;
}
} catch (ClassNotFoundException | SQLException e) {
MainUtil.sendMessage(player, "$1Failed to open connection, read stacktrace for info");
MainUtil.sendMessage(player,
"&d==== Here is an ugly stacktrace, if you are interested in those things ===");
e.printStackTrace();
MainUtil.sendMessage(player, "&d==== End of stacktrace ====");
MainUtil.sendMessage(player, "$1Please make sure you are using the correct arguments!");
return false;
}
}
} }

View File

@ -57,9 +57,7 @@ public class Help extends Command {
public void displayHelp(PlotPlayer player, String cat, int page) { public void displayHelp(PlotPlayer player, String cat, int page) {
CommandCategory catEnum = null; CommandCategory catEnum = null;
if (cat != null) { if (cat != null) {
if (StringMan.isEqualIgnoreCase(cat, "all")) { if (!StringMan.isEqualIgnoreCase(cat, "all")) {
catEnum = null;
} else {
for (CommandCategory c : CommandCategory.values()) { for (CommandCategory c : CommandCategory.values()) {
if (StringMan.isEqualIgnoreCaseToAny(cat, c.name(), c.toString())) { if (StringMan.isEqualIgnoreCaseToAny(cat, c.name(), c.toString())) {
catEnum = c; catEnum = c;

View File

@ -165,9 +165,8 @@ import java.util.Optional;
inbox.clearInbox(plot); inbox.clearInbox(plot);
Optional<ArrayList<PlotComment>> comments = Optional<ArrayList<PlotComment>> comments =
plot.getSettings().getComments(inbox.toString()); plot.getSettings().getComments(inbox.toString());
if (comments.isPresent()) { comments
plot.getSettings().removeComments(comments.get()); .ifPresent(plotComments -> plot.getSettings().removeComments(plotComments));
}
MainUtil.sendMessage(player, C.COMMENT_REMOVED, "*"); MainUtil.sendMessage(player, C.COMMENT_REMOVED, "*");
return true; return true;
default: default:

View File

@ -60,9 +60,9 @@ public class Merge extends SubCommand {
} }
final PlotArea plotArea = plot.getArea(); final PlotArea plotArea = plot.getArea();
Expression<Double> priceExr = Expression<Double> priceExr =
plotArea.PRICES.containsKey("merge") ? plotArea.PRICES.get("merge") : null; plotArea.PRICES.getOrDefault("merge", Expression.constant(0d));
final int size = plot.getConnectedPlots().size(); final int size = plot.getConnectedPlots().size();
final double price = priceExr == null ? 0d : priceExr.evaluate((double) size); final double price = priceExr.evaluate((double) size);
if (EconHandler.manager != null && plotArea.USE_ECONOMY && price > 0d if (EconHandler.manager != null && plotArea.USE_ECONOMY && price > 0d
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.manager.getMoney(player) < price) {
sendMessage(player, C.CANNOT_AFFORD_MERGE, String.valueOf(price)); sendMessage(player, C.CANNOT_AFFORD_MERGE, String.valueOf(price));

View File

@ -108,9 +108,7 @@ import java.util.UUID;
if (unknown && UUIDHandler.getName(plot.owner) != null) { if (unknown && UUIDHandler.getName(plot.owner) != null) {
continue; continue;
} }
for (Plot current : plot.getConnectedPlots()) { toDelete.addAll(plot.getConnectedPlots());
toDelete.add(current);
}
} }
if (PlotSquared.get().plots_tmp != null) { if (PlotSquared.get().plots_tmp != null) {
for (Entry<String, HashMap<PlotId, Plot>> entry : PlotSquared.get().plots_tmp for (Entry<String, HashMap<PlotId, Plot>> entry : PlotSquared.get().plots_tmp
@ -143,23 +141,21 @@ import java.util.UUID;
} }
String cmd = String cmd =
"/plot purge " + StringMan.join(args, " ") + " (" + toDelete.size() + " plots)"; "/plot purge " + StringMan.join(args, " ") + " (" + toDelete.size() + " plots)";
Runnable run = new Runnable() { Runnable run = () -> {
@Override public void run() { PlotSquared.debug("Calculating plots to purge, please wait...");
PlotSquared.debug("Calculating plots to purge, please wait..."); HashSet<Integer> ids = new HashSet<>();
HashSet<Integer> ids = new HashSet<>(); for (Plot plot : toDelete) {
for (Plot plot : toDelete) { if (plot.temp != Integer.MAX_VALUE) {
if (plot.temp != Integer.MAX_VALUE) { ids.add(plot.temp);
ids.add(plot.temp); plot.getArea().removePlot(plot.getId());
plot.getArea().removePlot(plot.getId()); for (PlotPlayer pp : plot.getPlayersInPlot()) {
for (PlotPlayer pp : plot.getPlayersInPlot()) { PlotListener.plotEntry(pp, plot);
PlotListener.plotEntry(pp, plot);
}
plot.removeSign();
} }
plot.removeSign();
} }
DBFunc.purgeIds(ids);
C.PURGE_SUCCESS.send(player, ids.size() + "/" + toDelete.size());
} }
DBFunc.purgeIds(ids);
C.PURGE_SUCCESS.send(player, ids.size() + "/" + toDelete.size());
}; };
if (hasConfirmation(player)) { if (hasConfirmation(player)) {
CmdConfirm.addPending(player, cmd, run); CmdConfirm.addPending(player, cmd, run);

View File

@ -22,25 +22,23 @@ import java.util.Map.Entry;
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "next": { case "next": {
ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getBasePlots()); ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getBasePlots());
Collections.sort(plots, new Comparator<Plot>() { plots.sort((p1, p2) -> {
@Override public int compare(Plot p1, Plot p2) { double v1 = 0;
double v1 = 0; if (!p1.getRatings().isEmpty()) {
if (!p1.getRatings().isEmpty()) { for (Entry<UUID, Rating> entry : p1.getRatings().entrySet()) {
for (Entry<UUID, Rating> entry : p1.getRatings().entrySet()) { v1 -= 11 - entry.getValue().getAverageRating();
v1 -= 11 - entry.getValue().getAverageRating();
}
} }
double v2 = 0;
if (!p2.getRatings().isEmpty()) {
for (Entry<UUID, Rating> entry : p2.getRatings().entrySet()) {
v2 -= 11 - entry.getValue().getAverageRating();
}
}
if (v1 == v2) {
return -0;
}
return v2 > v1 ? 1 : -1;
} }
double v2 = 0;
if (!p2.getRatings().isEmpty()) {
for (Entry<UUID, Rating> entry : p2.getRatings().entrySet()) {
v2 -= 11 - entry.getValue().getAverageRating();
}
}
if (v1 == v2) {
return -0;
}
return v2 > v1 ? 1 : -1;
}); });
UUID uuid = player.getUUID(); UUID uuid = player.getUUID();
for (Plot p : plots) { for (Plot p : plots) {
@ -123,7 +121,7 @@ import java.util.Map.Entry;
return true; return true;
} }
}; };
inventory.setItem(0, new PlotItemStack(35, (short) 12, 0, "0/8")); inventory.setItem(0, new PlotItemStack("minecraft:brown_wool", 0, "0/8"));
inventory.setItem(1, new PlotItemStack(35, (short) 14, 1, "1/8")); inventory.setItem(1, new PlotItemStack(35, (short) 14, 1, "1/8"));
inventory.setItem(2, new PlotItemStack(35, (short) 1, 2, "2/8")); inventory.setItem(2, new PlotItemStack(35, (short) 1, 2, "2/8"));
inventory.setItem(3, new PlotItemStack(35, (short) 4, 3, "3/8")); inventory.setItem(3, new PlotItemStack(35, (short) 4, 3, "3/8"));
@ -137,11 +135,9 @@ import java.util.Map.Entry;
}; };
if (plot.getSettings().ratings == null) { if (plot.getSettings().ratings == null) {
if (!Settings.Enabled_Components.RATING_CACHE) { if (!Settings.Enabled_Components.RATING_CACHE) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { plot.getSettings().ratings = DBFunc.getRatings(plot);
plot.getSettings().ratings = DBFunc.getRatings(plot); run.run();
run.run();
}
}); });
return true; return true;
} }
@ -167,26 +163,22 @@ import java.util.Map.Entry;
return false; return false;
} }
final UUID uuid = player.getUUID(); final UUID uuid = player.getUUID();
final Runnable run = new Runnable() { final Runnable run = () -> {
@Override public void run() { if (plot.getRatings().containsKey(uuid)) {
if (plot.getRatings().containsKey(uuid)) { sendMessage(player, C.RATING_ALREADY_EXISTS, plot.getId().toString());
sendMessage(player, C.RATING_ALREADY_EXISTS, plot.getId().toString()); return;
return; }
} Rating result = EventUtil.manager.callRating(player, plot, new Rating(rating));
Rating result = EventUtil.manager.callRating(player, plot, new Rating(rating)); if (result != null) {
if (result != null) { plot.addRating(uuid, result);
plot.addRating(uuid, result); sendMessage(player, C.RATING_APPLIED, plot.getId().toString());
sendMessage(player, C.RATING_APPLIED, plot.getId().toString());
}
} }
}; };
if (plot.getSettings().ratings == null) { if (plot.getSettings().ratings == null) {
if (!Settings.Enabled_Components.RATING_CACHE) { if (!Settings.Enabled_Components.RATING_CACHE) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { plot.getSettings().ratings = DBFunc.getRatings(plot);
plot.getSettings().ratings = DBFunc.getRatings(plot); run.run();
run.run();
}
}); });
return true; return true;
} }

View File

@ -143,14 +143,6 @@ public interface AbstractDB {
*/ */
void setFlags(Plot plot, HashMap<Flag<?>, Object> flags); void setFlags(Plot plot, HashMap<Flag<?>, Object> flags);
/**
* Set cluster flags.
*
* @param cluster PlotCluster Object
* @param flags flags to set (flag[])
*/
void setFlags(PlotCluster cluster, HashMap<Flag<?>, Object> flags);
/** /**
* Rename a cluster to the given name. * Rename a cluster to the given name.
* *

View File

@ -13,6 +13,7 @@ import java.util.*;
* Database Functions * Database Functions
* - These functions do not update the local plot objects and only make changes to the DB * - These functions do not update the local plot objects and only make changes to the DB
*/ */
@SuppressWarnings("deprecation")
public class DBFunc { public class DBFunc {
/** /**
* The "global" uuid. * The "global" uuid.
@ -298,17 +299,6 @@ public class DBFunc {
DBFunc.dbManager.setFlags(plot, flags); DBFunc.dbManager.setFlags(plot, flags);
} }
public static void setFlags(PlotCluster cluster, HashMap<Flag<?>, Object> flags) {
if (dbManager == null) {
return;
}
DBFunc.dbManager.setFlags(cluster, flags);
}
/**
* @param plot
* @param alias
*/
public static void setAlias(Plot plot, String alias) { public static void setAlias(Plot plot, String alias) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -330,10 +320,6 @@ public class DBFunc {
DBFunc.dbManager.purge(area, plotIds); DBFunc.dbManager.purge(area, plotIds);
} }
/**
* @param plot
* @param position
*/
public static void setPosition(Plot plot, String position) { public static void setPosition(Plot plot, String position) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -341,10 +327,6 @@ public class DBFunc {
DBFunc.dbManager.setPosition(plot, position); DBFunc.dbManager.setPosition(plot, position);
} }
/**
* @param plot
* @param comment
*/
public static void removeComment(Plot plot, PlotComment comment) { public static void removeComment(Plot plot, PlotComment comment) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -359,10 +341,6 @@ public class DBFunc {
DBFunc.dbManager.clearInbox(plot, inbox); DBFunc.dbManager.clearInbox(plot, inbox);
} }
/**
* @param plot
* @param comment
*/
public static void setComment(Plot plot, PlotComment comment) { public static void setComment(Plot plot, PlotComment comment) {
if (plot != null && plot.temp == -1 || dbManager == null) { if (plot != null && plot.temp == -1 || dbManager == null) {
return; return;
@ -370,9 +348,6 @@ public class DBFunc {
DBFunc.dbManager.setComment(plot, comment); DBFunc.dbManager.setComment(plot, comment);
} }
/**
* @param plot
*/
public static void getComments(Plot plot, String inbox, public static void getComments(Plot plot, String inbox,
RunnableVal<List<PlotComment>> whenDone) { RunnableVal<List<PlotComment>> whenDone) {
if (plot != null && plot.temp == -1 || dbManager == null) { if (plot != null && plot.temp == -1 || dbManager == null) {
@ -381,10 +356,6 @@ public class DBFunc {
DBFunc.dbManager.getComments(plot, inbox, whenDone); DBFunc.dbManager.getComments(plot, inbox, whenDone);
} }
/**
* @param plot
* @param uuid
*/
public static void removeTrusted(Plot plot, UUID uuid) { public static void removeTrusted(Plot plot, UUID uuid) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -392,10 +363,6 @@ public class DBFunc {
DBFunc.dbManager.removeTrusted(plot, uuid); DBFunc.dbManager.removeTrusted(plot, uuid);
} }
/**
* @param cluster
* @param uuid
*/
public static void removeHelper(PlotCluster cluster, UUID uuid) { public static void removeHelper(PlotCluster cluster, UUID uuid) {
if (dbManager == null) { if (dbManager == null) {
return; return;
@ -403,9 +370,6 @@ public class DBFunc {
DBFunc.dbManager.removeHelper(cluster, uuid); DBFunc.dbManager.removeHelper(cluster, uuid);
} }
/**
* @param cluster
*/
public static void createCluster(PlotCluster cluster) { public static void createCluster(PlotCluster cluster) {
if (dbManager == null) { if (dbManager == null) {
return; return;
@ -413,11 +377,6 @@ public class DBFunc {
DBFunc.dbManager.createCluster(cluster); DBFunc.dbManager.createCluster(cluster);
} }
/**
* @param current
* @param min
* @param max
*/
public static void resizeCluster(PlotCluster current, PlotId min, PlotId max) { public static void resizeCluster(PlotCluster current, PlotId min, PlotId max) {
if (dbManager == null) { if (dbManager == null) {
return; return;
@ -425,10 +384,6 @@ public class DBFunc {
DBFunc.dbManager.resizeCluster(current, min, max); DBFunc.dbManager.resizeCluster(current, min, max);
} }
/**
* @param plot
* @param uuid
*/
public static void removeMember(Plot plot, UUID uuid) { public static void removeMember(Plot plot, UUID uuid) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -436,10 +391,6 @@ public class DBFunc {
DBFunc.dbManager.removeMember(plot, uuid); DBFunc.dbManager.removeMember(plot, uuid);
} }
/**
* @param cluster
* @param uuid
*/
public static void removeInvited(PlotCluster cluster, UUID uuid) { public static void removeInvited(PlotCluster cluster, UUID uuid) {
if (dbManager == null) { if (dbManager == null) {
return; return;
@ -447,10 +398,6 @@ public class DBFunc {
DBFunc.dbManager.removeInvited(cluster, uuid); DBFunc.dbManager.removeInvited(cluster, uuid);
} }
/**
* @param plot
* @param uuid
*/
public static void setTrusted(Plot plot, UUID uuid) { public static void setTrusted(Plot plot, UUID uuid) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -465,10 +412,6 @@ public class DBFunc {
DBFunc.dbManager.setHelper(cluster, uuid); DBFunc.dbManager.setHelper(cluster, uuid);
} }
/**
* @param plot
* @param uuid
*/
public static void setMember(Plot plot, UUID uuid) { public static void setMember(Plot plot, UUID uuid) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -483,10 +426,6 @@ public class DBFunc {
DBFunc.dbManager.setInvited(cluster, uuid); DBFunc.dbManager.setInvited(cluster, uuid);
} }
/**
* @param plot
* @param uuid
*/
public static void removeDenied(Plot plot, UUID uuid) { public static void removeDenied(Plot plot, UUID uuid) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;
@ -494,10 +433,6 @@ public class DBFunc {
DBFunc.dbManager.removeDenied(plot, uuid); DBFunc.dbManager.removeDenied(plot, uuid);
} }
/**
* @param plot
* @param uuid
*/
public static void setDenied(Plot plot, UUID uuid) { public static void setDenied(Plot plot, UUID uuid) {
if (plot.temp == -1 || dbManager == null) { if (plot.temp == -1 || dbManager == null) {
return; return;

View File

@ -11,9 +11,9 @@ import java.sql.Statement;
* @author -_Husky_- * @author -_Husky_-
* @author tips48 * @author tips48
*/ */
public abstract class Database { public interface Database {
public abstract Connection forceConnection() throws SQLException, ClassNotFoundException; Connection forceConnection() throws SQLException, ClassNotFoundException;
/** /**
* Opens a connection with the database. * Opens a connection with the database.
@ -22,7 +22,7 @@ public abstract class Database {
* @throws SQLException if the connection can not be opened * @throws SQLException if the connection can not be opened
* @throws ClassNotFoundException if the driver cannot be found * @throws ClassNotFoundException if the driver cannot be found
*/ */
public abstract Connection openConnection() throws SQLException, ClassNotFoundException; Connection openConnection() throws SQLException, ClassNotFoundException;
/** /**
* Checks if a connection is open with the database. * Checks if a connection is open with the database.
@ -30,14 +30,14 @@ public abstract class Database {
* @return true if the connection is open * @return true if the connection is open
* @throws SQLException if the connection cannot be checked * @throws SQLException if the connection cannot be checked
*/ */
public abstract boolean checkConnection() throws SQLException; boolean checkConnection() throws SQLException;
/** /**
* Gets the connection with the database. * Gets the connection with the database.
* *
* @return Connection with the database, null if none * @return Connection with the database, null if none
*/ */
public abstract Connection getConnection(); Connection getConnection();
/** /**
* Closes the connection with the database. * Closes the connection with the database.
@ -45,7 +45,7 @@ public abstract class Database {
* @return true if successful * @return true if successful
* @throws SQLException if the connection cannot be closed * @throws SQLException if the connection cannot be closed
*/ */
public abstract boolean closeConnection() throws SQLException; boolean closeConnection() throws SQLException;
/** /**
* Executes a SQL Query. * Executes a SQL Query.
@ -56,7 +56,7 @@ public abstract class Database {
* @throws SQLException If the query cannot be executed * @throws SQLException If the query cannot be executed
* @throws ClassNotFoundException If the driver cannot be found; see {@link #openConnection()} * @throws ClassNotFoundException If the driver cannot be found; see {@link #openConnection()}
*/ */
public abstract ResultSet querySQL(String query) throws SQLException, ClassNotFoundException; ResultSet querySQL(String query) throws SQLException, ClassNotFoundException;
/** /**
* Executes an Update SQL Query. * Executes an Update SQL Query.
@ -68,5 +68,5 @@ public abstract class Database {
* @throws SQLException If the query cannot be executed * @throws SQLException If the query cannot be executed
* @throws ClassNotFoundException If the driver cannot be found; see {@link #openConnection()} * @throws ClassNotFoundException If the driver cannot be found; see {@link #openConnection()}
*/ */
public abstract int updateSQL(String query) throws SQLException, ClassNotFoundException; int updateSQL(String query) throws SQLException, ClassNotFoundException;
} }

View File

@ -11,7 +11,7 @@ import java.sql.*;
* @author -_Husky_- * @author -_Husky_-
* @author tips48 * @author tips48
*/ */
public class MySQL extends Database { public class MySQL implements Database {
private final String user; private final String user;
private final String database; private final String database;

View File

@ -9,7 +9,7 @@ import java.sql.*;
/** /**
* Connects to and uses a SQLite database. * Connects to and uses a SQLite database.
*/ */
public class SQLite extends Database { public class SQLite implements Database {
private final String dbLocation; private final String dbLocation;
private Connection connection; private Connection connection;

View File

@ -114,6 +114,7 @@ public class FlagManager {
* @param flag * @param flag
* @return * @return
*/ */
@SuppressWarnings("deprecation")
public static <V> V getPlotFlagRaw(Plot plot, Flag<V> flag) { public static <V> V getPlotFlagRaw(Plot plot, Flag<V> flag) {
if (plot.owner == null) { if (plot.owner == null) {
return null; return null;
@ -141,13 +142,6 @@ public class FlagManager {
return true; return true;
} }
public static <V> boolean addClusterFlag(PlotCluster cluster, Flag<V> flag, V value) {
getSettingFlag(cluster.area, cluster.settings, flag);
cluster.settings.flags.put(flag, value);
DBFunc.setFlags(cluster, cluster.settings.flags);
return true;
}
/** /**
* Returns a map of the {@link Flag}s and their values for the specified plot. * Returns a map of the {@link Flag}s and their values for the specified plot.
* *
@ -217,20 +211,6 @@ public class FlagManager {
return true; return true;
} }
public static boolean removeClusterFlag(PlotCluster cluster, Flag id) {
Object object = cluster.settings.flags.remove(id);
if (object == null) {
return false;
}
boolean result = EventUtil.manager.callFlagRemove(id, object, cluster);
if (!result) {
cluster.settings.flags.put(id, object);
return false;
}
DBFunc.setFlags(cluster, cluster.settings.flags);
return true;
}
public static void setPlotFlags(Plot origin, HashMap<Flag<?>, Object> flags) { public static void setPlotFlags(Plot origin, HashMap<Flag<?>, Object> flags) {
for (Plot plot : origin.getConnectedPlots()) { for (Plot plot : origin.getConnectedPlots()) {
if (flags != null && !flags.isEmpty()) { if (flags != null && !flags.isEmpty()) {
@ -248,20 +228,6 @@ public class FlagManager {
} }
} }
public static void setClusterFlags(PlotCluster cluster, Set<Flag> flags) {
if (flags != null && !flags.isEmpty()) {
cluster.settings.flags.clear();
for (Flag flag : flags) {
cluster.settings.flags.put(flag, flag);
}
} else if (cluster.settings.flags.isEmpty()) {
return;
} else {
cluster.settings.flags.clear();
}
DBFunc.setFlags(cluster, cluster.settings.flags);
}
/** /**
* Get a list of registered {@link Flag} objects based on player permissions. * Get a list of registered {@link Flag} objects based on player permissions.
* *

View File

@ -277,11 +277,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
id = rotate(id); id = rotate(id);
} }
int pair = MathMan.pair(x, z); int pair = MathMan.pair(x, z);
BaseBlock[] existing = this.G_SCH.get(pair); BaseBlock[] existing = this.G_SCH.computeIfAbsent(pair, k -> new BaseBlock[height]);
if (existing == null) {
existing = new BaseBlock[height];
this.G_SCH.put(pair, existing);
}
existing[y] = id; existing[y] = id;
} }
} }

View File

@ -1,5 +1,6 @@
package com.github.intellectualsites.plotsquared.plot.logger; package com.github.intellectualsites.plotsquared.plot.logger;
@FunctionalInterface
public interface ILogger { public interface ILogger {
void log(String message); void log(String message);
} }

View File

@ -4,9 +4,12 @@ import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.commands.DebugExec; import com.github.intellectualsites.plotsquared.plot.commands.DebugExec;
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand; import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
import javax.annotation.Nonnull;
import javax.script.ScriptException; import javax.script.ScriptException;
public abstract class Expression<T> { public abstract class Expression<T> {
@Nonnull
public static <U> Expression<U> constant(final U value) { public static <U> Expression<U> constant(final U value) {
return new Expression<U>() { return new Expression<U>() {
@Override public U evaluate(U arg) { @Override public U evaluate(U arg) {

View File

@ -721,6 +721,9 @@ public abstract class PlotArea {
} else { } else {
start = start.getNextId(1); start = start.getNextId(1);
} }
if (start == null) {
PlotSquared.debug("NPE possible in getNextFreePlot");
}
currentId = new PlotId(center.x + start.x, center.y + start.y); currentId = new PlotId(center.x + start.x, center.y + start.y);
Plot plot = getPlotAbs(currentId); Plot plot = getPlotAbs(currentId);
if (plot != null && plot.canClaim(player)) { if (plot != null && plot.canClaim(player)) {

View File

@ -5,19 +5,25 @@ import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import java.util.HashSet; import java.util.HashSet;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull;
import lombok.Getter;
public class PlotCluster { public class PlotCluster {
public PlotArea area; public PlotArea area;
@Nonnull
@Getter
public PlotSettings settings; public PlotSettings settings;
public UUID owner; public UUID owner;
public HashSet<UUID> helpers = new HashSet<>(); public HashSet<UUID> helpers = new HashSet<>();
public HashSet<UUID> invited = new HashSet<>(); public HashSet<UUID> invited = new HashSet<>();
public int temp; public int temp;
@Nonnull
private PlotId pos1; private PlotId pos1;
@Nonnull
private PlotId pos2; private PlotId pos2;
private RegionWrapper region; private RegionWrapper region;
public PlotCluster(PlotArea area, PlotId pos1, PlotId pos2, UUID owner) { public PlotCluster(PlotArea area, @Nonnull PlotId pos1, @Nonnull PlotId pos2, UUID owner) {
this.area = area; this.area = area;
this.pos1 = pos1; this.pos1 = pos1;
this.pos2 = pos2; this.pos2 = pos2;
@ -27,7 +33,7 @@ public class PlotCluster {
setRegion(); setRegion();
} }
public PlotCluster(PlotArea area, PlotId pos1, PlotId pos2, UUID owner, int temp) { public PlotCluster(PlotArea area, @Nonnull PlotId pos1, PlotId pos2, UUID owner, int temp) {
this.area = area; this.area = area;
this.pos1 = pos1; this.pos1 = pos1;
this.pos2 = pos2; this.pos2 = pos2;
@ -82,6 +88,11 @@ public class PlotCluster {
return this.settings.getAlias(); return this.settings.getAlias();
} }
public String getAlias() {
return this.settings.getAlias();
}
public void setName(String name) { this.settings.setAlias(name);}
/** /**
* Get the area (in plots). * Get the area (in plots).
* *

View File

@ -13,6 +13,7 @@ public class PlotMessage {
try { try {
reset(ChatManager.manager); reset(ChatManager.manager);
} catch (Throwable e) { } catch (Throwable e) {
assert PlotSquared.imp() != null;
PlotSquared.debug( PlotSquared.debug(
PlotSquared.imp().getPluginName() + " doesn't support fancy chat for " + PlotSquared PlotSquared.imp().getPluginName() + " doesn't support fancy chat for " + PlotSquared
.get().IMP.getServerVersion()); .get().IMP.getServerVersion());

View File

@ -42,7 +42,7 @@ public class PlotSettings {
/** /**
* Flags. * Flags.
* *
* @deprecated Raw access * @deprecated Raw access. Not compatible with PlotClusters.
*/ */
@Deprecated public HashMap<Flag<?>, Object> flags = new HashMap<>(); @Deprecated public HashMap<Flag<?>, Object> flags = new HashMap<>();
/** /**
@ -85,7 +85,7 @@ public class PlotSettings {
return this.ratings; return this.ratings;
} }
public boolean setMerged(int direction, boolean merged) { boolean setMerged(int direction, boolean merged) {
if (this.merged[direction] != merged) { if (this.merged[direction] != merged) {
this.merged[direction] = merged; this.merged[direction] = merged;
return true; return true;
@ -142,6 +142,7 @@ public class PlotSettings {
} }
} }
//todo need a plot method
public Optional<ArrayList<PlotComment>> getComments(String inbox) { public Optional<ArrayList<PlotComment>> getComments(String inbox) {
ArrayList<PlotComment> c = new ArrayList<>(); ArrayList<PlotComment> c = new ArrayList<>();
if (this.comments == null) { if (this.comments == null) {
@ -155,22 +156,26 @@ public class PlotSettings {
return Optional.of(c); return Optional.of(c);
} }
//todo need a plot method
public void setComments(List<PlotComment> comments) { public void setComments(List<PlotComment> comments) {
this.comments = comments; this.comments = comments;
} }
//todo need a plot method
public void removeComment(PlotComment comment) { public void removeComment(PlotComment comment) {
if (this.comments.contains(comment)) { if (this.comments.contains(comment)) {
this.comments.remove(comment); this.comments.remove(comment);
} }
} }
//todo need a plot method
public void removeComments(List<PlotComment> comments) { public void removeComments(List<PlotComment> comments) {
for (PlotComment comment : comments) { for (PlotComment comment : comments) {
removeComment(comment); removeComment(comment);
} }
} }
//todo need a plot method
public void addComment(PlotComment comment) { public void addComment(PlotComment comment) {
if (this.comments == null) { if (this.comments == null) {
this.comments = new ArrayList<>(); this.comments = new ArrayList<>();

View File

@ -4,30 +4,31 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
public class AbstractDelegateOutputStream extends OutputStream { public class AbstractDelegateOutputStream extends OutputStream {
private final OutputStream parent;
public AbstractDelegateOutputStream(OutputStream os) { private final OutputStream parent;
this.parent = os;
}
@Override public void write(int b) throws IOException { public AbstractDelegateOutputStream(OutputStream os) {
parent.write(b); this.parent = os;
} }
@Override public void write(byte[] b) throws IOException { @Override
parent.write(b); public void write(int b) throws IOException {
} parent.write(b);
}
@Override public void write(byte[] b, int off, int len) throws IOException { @Override
parent.write(b, off, len); public void write(byte[] b) throws IOException {
} parent.write(b);
}
@Override public void flush() throws IOException { @Override
parent.flush(); public void flush() throws IOException {
} parent.flush();
}
@Override public void close() throws IOException { @Override
parent.close(); public void close() throws IOException {
} parent.close();
}
} }

View File

@ -88,9 +88,9 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
HashSet<PlotArea> globalAreas = new HashSet<>(Arrays.asList(plotAreas)); HashSet<PlotArea> globalAreas = new HashSet<>(Arrays.asList(plotAreas));
localAreas.add(plotArea); localAreas.add(plotArea);
globalAreas.add(plotArea); globalAreas.add(plotArea);
this.plotAreas = globalAreas.toArray(new PlotArea[globalAreas.size()]); this.plotAreas = globalAreas.toArray(new PlotArea[0]);
this.plotAreaMap this.plotAreaMap
.put(plotArea.worldname, localAreas.toArray(new PlotArea[localAreas.size()])); .put(plotArea.worldname, localAreas.toArray(new PlotArea[0]));
QuadMap<PlotArea> map = this.plotAreaGrid.get(plotArea.worldname); QuadMap<PlotArea> map = this.plotAreaGrid.get(plotArea.worldname);
if (map == null) { if (map == null) {
map = new QuadMap<PlotArea>(Integer.MAX_VALUE, 0, 0) { map = new QuadMap<PlotArea>(Integer.MAX_VALUE, 0, 0) {
@ -104,15 +104,15 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
} }
@Override public void removePlotArea(PlotArea area) { @Override public void removePlotArea(PlotArea area) {
ArrayList<PlotArea> globalAreas = new ArrayList<PlotArea>(Arrays.asList(plotAreas)); ArrayList<PlotArea> globalAreas = new ArrayList<>(Arrays.asList(plotAreas));
globalAreas.remove(area); globalAreas.remove(area);
this.plotAreas = globalAreas.toArray(new PlotArea[globalAreas.size()]); this.plotAreas = globalAreas.toArray(new PlotArea[0]);
if (globalAreas.isEmpty()) { if (globalAreas.isEmpty()) {
this.plotAreaMap.remove(area.worldname); this.plotAreaMap.remove(area.worldname);
this.plotAreaGrid.remove(area.worldname); this.plotAreaGrid.remove(area.worldname);
} else { } else {
this.plotAreaMap this.plotAreaMap
.put(area.worldname, globalAreas.toArray(new PlotArea[globalAreas.size()])); .put(area.worldname, globalAreas.toArray(new PlotArea[0]));
this.plotAreaGrid.get(area.worldname).remove(area); this.plotAreaGrid.get(area.worldname).remove(area);
} }
} }
@ -206,7 +206,7 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
return noPlotAreas; return noPlotAreas;
} else { } else {
Set<PlotArea> found = areas.get(region); Set<PlotArea> found = areas.get(region);
return found.toArray(new PlotArea[found.size()]); return found.toArray(new PlotArea[0]);
} }
} }
@ -217,14 +217,14 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
Set<String> tmp = new LinkedHashSet<>(); Set<String> tmp = new LinkedHashSet<>();
Collections.addAll(tmp, worlds); Collections.addAll(tmp, worlds);
tmp.add(worldName); tmp.add(worldName);
worlds = tmp.toArray(new String[tmp.size()]); worlds = tmp.toArray(new String[0]);
} }
@Override public void removeWorld(String worldName) { @Override public void removeWorld(String worldName) {
Set<String> tmp = new LinkedHashSet<>(); Set<String> tmp = new LinkedHashSet<>();
Collections.addAll(tmp, worlds); Collections.addAll(tmp, worlds);
tmp.remove(worldName); tmp.remove(worldName);
worlds = tmp.toArray(new String[tmp.size()]); worlds = tmp.toArray(new String[0]);
} }
@Override public String[] getAllWorlds() { @Override public String[] getAllWorlds() {

View File

@ -5,24 +5,24 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper; import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper;
public interface PlotAreaManager { public interface PlotAreaManager {
public PlotArea getApplicablePlotArea(Location location); PlotArea getApplicablePlotArea(Location location);
public PlotArea getPlotArea(Location location); PlotArea getPlotArea(Location location);
public PlotArea getPlotArea(String world, String id); PlotArea getPlotArea(String world, String id);
public PlotArea[] getPlotAreas(String world, RegionWrapper region); PlotArea[] getPlotAreas(String world, RegionWrapper region);
public PlotArea[] getAllPlotAreas(); PlotArea[] getAllPlotAreas();
public String[] getAllWorlds(); String[] getAllWorlds();
public void addPlotArea(PlotArea area); void addPlotArea(PlotArea area);
public void removePlotArea(PlotArea area); void removePlotArea(PlotArea area);
public void addWorld(String worldName); void addWorld(String worldName);
public void removeWorld(String worldName); void removeWorld(String worldName);
} }

View File

@ -7,6 +7,7 @@ import com.github.intellectualsites.plotsquared.plot.object.*;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull;
public class SinglePlot extends Plot { public class SinglePlot extends Plot {
private HashSet<RegionWrapper> regions; private HashSet<RegionWrapper> regions;
@ -40,6 +41,7 @@ public class SinglePlot extends Plot {
return getId().toCommaSeparatedString(); return getId().toCommaSeparatedString();
} }
@Nonnull
@Override public SinglePlotArea getArea() { @Override public SinglePlotArea getArea() {
return (SinglePlotArea) super.getArea(); return (SinglePlotArea) super.getArea();
} }

View File

@ -35,8 +35,7 @@ public class SinglePlotAreaManager extends DefaultPlotAreaManager {
if (chars.length == 1 && chars[0] == '*') { if (chars.length == 1 && chars[0] == '*') {
return true; return true;
} }
for (int i = 0; i < chars.length; i++) { for (char c : chars) {
char c = chars[i];
switch (mode) { switch (mode) {
case 0: case 0:
mode = 1; mode = 1;

View File

@ -30,12 +30,10 @@ public class SinglePlotManager extends PlotManager {
SetupUtils.manager.unload(plot.getWorldName(), false); SetupUtils.manager.unload(plot.getWorldName(), false);
final File worldFolder = final File worldFolder =
new File(PlotSquared.get().IMP.getWorldContainer(), plot.getWorldName()); new File(PlotSquared.get().IMP.getWorldContainer(), plot.getWorldName());
TaskManager.IMP.taskAsync(new Runnable() { TaskManager.IMP.taskAsync(() -> {
@Override public void run() { MainUtil.deleteDirectory(worldFolder);
MainUtil.deleteDirectory(worldFolder); if (whenDone != null)
if (whenDone != null) whenDone.run();
whenDone.run();
}
}); });
return true; return true;
} }

View File

@ -15,6 +15,6 @@ public abstract class AbstractTitle {
} }
} }
public abstract void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, protected abstract void sendTitle(PlotPlayer player, String head, String sub, int in, int delay,
int out); int out);
} }

View File

@ -71,41 +71,39 @@ public abstract class ChunkManager {
public static void largeRegionTask(final String world, final RegionWrapper region, public static void largeRegionTask(final String world, final RegionWrapper region,
final RunnableVal<ChunkLoc> task, final Runnable whenDone) { final RunnableVal<ChunkLoc> task, final Runnable whenDone) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { HashSet<ChunkLoc> chunks = new HashSet<>();
HashSet<ChunkLoc> chunks = new HashSet<>(); Set<ChunkLoc> mcrs = manager.getChunkChunks(world);
Set<ChunkLoc> mcrs = manager.getChunkChunks(world); for (ChunkLoc mcr : mcrs) {
for (ChunkLoc mcr : mcrs) { int bx = mcr.x << 9;
int bx = mcr.x << 9; int bz = mcr.z << 9;
int bz = mcr.z << 9; int tx = bx + 511;
int tx = bx + 511; int tz = bz + 511;
int tz = bz + 511; if (bx <= region.maxX && tx >= region.minX && bz <= region.maxZ
if (bx <= region.maxX && tx >= region.minX && bz <= region.maxZ && tz >= region.minZ) {
&& tz >= region.minZ) { for (int x = bx >> 4; x <= (tx >> 4); x++) {
for (int x = bx >> 4; x <= (tx >> 4); x++) { int cbx = x << 4;
int cbx = x << 4; int ctx = cbx + 15;
int ctx = cbx + 15; if (cbx <= region.maxX && ctx >= region.minX) {
if (cbx <= region.maxX && ctx >= region.minX) { for (int z = bz >> 4; z <= (tz >> 4); z++) {
for (int z = bz >> 4; z <= (tz >> 4); z++) { int cbz = z << 4;
int cbz = z << 4; int ctz = cbz + 15;
int ctz = cbz + 15; if (cbz <= region.maxZ && ctz >= region.minZ) {
if (cbz <= region.maxZ && ctz >= region.minZ) { chunks.add(new ChunkLoc(x, z));
chunks.add(new ChunkLoc(x, z));
}
} }
} }
} }
} }
} }
TaskManager.objectTask(chunks, new RunnableVal<ChunkLoc>() {
@Override public void run(ChunkLoc value) {
if (manager.loadChunk(world, value, false)) {
task.run(value);
}
}
}, whenDone);
} }
TaskManager.objectTask(chunks, new RunnableVal<ChunkLoc>() {
@Override public void run(ChunkLoc value) {
if (manager.loadChunk(world, value, false)) {
task.run(value);
}
}
}, whenDone);
}); });
} }
@ -239,20 +237,18 @@ public abstract class ChunkManager {
public void deleteRegionFiles(final String world, final Collection<ChunkLoc> chunks, public void deleteRegionFiles(final String world, final Collection<ChunkLoc> chunks,
final Runnable whenDone) { final Runnable whenDone) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { for (ChunkLoc loc : chunks) {
for (ChunkLoc loc : chunks) { String directory =
String directory = world + File.separator + "region" + File.separator + "r." + loc.x + "."
world + File.separator + "region" + File.separator + "r." + loc.x + "." + loc.z + ".mca";
+ loc.z + ".mca"; File file = new File(PlotSquared.get().IMP.getWorldContainer(), directory);
File file = new File(PlotSquared.get().IMP.getWorldContainer(), directory); PlotSquared.log("&6 - Deleting file: " + file.getName() + " (max 1024 chunks)");
PlotSquared.log("&6 - Deleting file: " + file.getName() + " (max 1024 chunks)"); if (file.exists()) {
if (file.exists()) { file.delete();
file.delete();
}
} }
TaskManager.runTask(whenDone);
} }
TaskManager.runTask(whenDone);
}); });
} }

View File

@ -19,11 +19,9 @@ public class CmdConfirm {
removePending(player); removePending(player);
if (commandStr != null) if (commandStr != null)
MainUtil.sendMessage(player, C.REQUIRES_CONFIRM, commandStr); MainUtil.sendMessage(player, C.REQUIRES_CONFIRM, commandStr);
TaskManager.runTaskLater(new Runnable() { TaskManager.runTaskLater(() -> {
@Override public void run() { CmdInstance cmd = new CmdInstance(runnable);
CmdInstance cmd = new CmdInstance(runnable); player.setMeta("cmdConfirm", cmd);
player.setMeta("cmdConfirm", cmd);
}
}, 1); }, 1);
} }
} }

View File

@ -20,34 +20,32 @@ public class CommentManager {
if (!Settings.Enabled_Components.COMMENT_NOTIFIER || !plot.isOwner(player.getUUID())) { if (!Settings.Enabled_Components.COMMENT_NOTIFIER || !plot.isOwner(player.getUUID())) {
return; return;
} }
TaskManager.runTaskLaterAsync(new Runnable() { TaskManager.runTaskLaterAsync(() -> {
@Override public void run() { Collection<CommentInbox> boxes = CommentManager.inboxes.values();
Collection<CommentInbox> boxes = CommentManager.inboxes.values(); final AtomicInteger count = new AtomicInteger(0);
final AtomicInteger count = new AtomicInteger(0); final AtomicInteger size = new AtomicInteger(boxes.size());
final AtomicInteger size = new AtomicInteger(boxes.size()); for (final CommentInbox inbox : inboxes.values()) {
for (final CommentInbox inbox : inboxes.values()) { inbox.getComments(plot, new RunnableVal<List<PlotComment>>() {
inbox.getComments(plot, new RunnableVal<List<PlotComment>>() { @Override public void run(List<PlotComment> value) {
@Override public void run(List<PlotComment> value) { int total;
int total; if (value != null) {
if (value != null) { int num = 0;
int num = 0; for (PlotComment comment : value) {
for (PlotComment comment : value) { if (comment.timestamp > getTimestamp(player,
if (comment.timestamp > getTimestamp(player, inbox.toString())) {
inbox.toString())) { num++;
num++;
}
} }
total = count.addAndGet(num);
} else {
total = count.get();
}
if ((size.decrementAndGet() == 0) && (total > 0)) {
AbstractTitle.sendTitle(player, "",
C.INBOX_NOTIFICATION.s().replaceAll("%s", "" + total));
} }
total = count.addAndGet(num);
} else {
total = count.get();
} }
}); if ((size.decrementAndGet() == 0) && (total > 0)) {
} AbstractTitle.sendTitle(player, "",
C.INBOX_NOTIFICATION.s().replaceAll("%s", "" + total));
}
}
});
} }
}, 20); }, 20);
} }

View File

@ -43,8 +43,6 @@ public abstract class EventUtil {
public abstract boolean callFlagRemove(Flag<?> flag, Plot plot, Object value); public abstract boolean callFlagRemove(Flag<?> flag, Plot plot, Object value);
public abstract boolean callFlagRemove(Flag<?> flag, Object value, PlotCluster cluster);
public abstract boolean callMerge(Plot plot, int dir, int max); public abstract boolean callMerge(Plot plot, int dir, int max);
public abstract boolean callAutoMerge(Plot plot, List<PlotId> plots); public abstract boolean callAutoMerge(Plot plot, List<PlotId> plots);
@ -78,11 +76,7 @@ public abstract class EventUtil {
} }
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();
if (Settings.Teleport.ON_LOGIN && plot != null) { if (Settings.Teleport.ON_LOGIN && plot != null) {
TaskManager.runTask(new Runnable() { TaskManager.runTask(() -> plot.teleportPlayer(player));
@Override public void run() {
plot.teleportPlayer(player);
}
});
MainUtil.sendMessage(player, MainUtil.sendMessage(player,
C.TELEPORTED_TO_ROAD.f() + " (on-login) " + "(" + plot.getId().x + ";" + plot C.TELEPORTED_TO_ROAD.f() + " (on-login) " + "(" + plot.getId().x + ";" + plot
.getId().y + ")"); .getId().y + ")");

View File

@ -411,7 +411,7 @@ public class MainUtil {
ArrayList<ArrayList<Plot>> plotList = new ArrayList<>(size); ArrayList<ArrayList<Plot>> plotList = new ArrayList<>(size);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
plotList.add(new ArrayList<Plot>()); plotList.add(new ArrayList<>());
} }
for (Plot plot : PlotSquared.get().getPlots()) { for (Plot plot : PlotSquared.get().getPlots()) {
@ -430,7 +430,7 @@ public class MainUtil {
count++; count++;
} }
} }
if (area != null && plot.getArea().equals(area)) { if (plot.getArea().equals(area)) {
count++; count++;
} }
if (alias != null && alias.equals(plot.getAlias())) { if (alias != null && alias.equals(plot.getAlias())) {
@ -622,14 +622,12 @@ public class MainUtil {
if (caption.s().isEmpty()) { if (caption.s().isEmpty()) {
return true; return true;
} }
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { String m = C.format(caption, args);
String m = C.format(caption, args); if (player == null) {
if (player == null) { PlotSquared.log(m);
PlotSquared.log(m); } else {
} else { player.sendMessage(m);
player.sendMessage(m);
}
} }
}); });
return true; return true;
@ -780,31 +778,29 @@ public class MainUtil {
info = info.replace("%desc%", "No description set."); info = info.replace("%desc%", "No description set.");
if (info.contains("%rating%")) { if (info.contains("%rating%")) {
final String newInfo = info; final String newInfo = info;
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(() -> {
@Override public void run() { int max = 10;
int max = 10; if (Settings.Ratings.CATEGORIES != null && !Settings.Ratings.CATEGORIES
if (Settings.Ratings.CATEGORIES != null && !Settings.Ratings.CATEGORIES .isEmpty()) {
.isEmpty()) { max = 8;
max = 8;
}
String info;
if (full && Settings.Ratings.CATEGORIES != null
&& Settings.Ratings.CATEGORIES.size() > 1) {
double[] ratings = MainUtil.getAverageRatings(plot);
String rating = "";
String prefix = "";
for (int i = 0; i < ratings.length; i++) {
rating += prefix + Settings.Ratings.CATEGORIES.get(i) + '=' + String
.format("%.1f", ratings[i]);
prefix = ",";
}
info = newInfo.replaceAll("%rating%", rating);
} else {
info = newInfo.replaceAll("%rating%",
String.format("%.1f", plot.getAverageRating()) + '/' + max);
}
whenDone.run(info);
} }
String info1;
if (full && Settings.Ratings.CATEGORIES != null
&& Settings.Ratings.CATEGORIES.size() > 1) {
double[] ratings = MainUtil.getAverageRatings(plot);
String rating = "";
String prefix = "";
for (int i = 0; i < ratings.length; i++) {
rating += prefix + Settings.Ratings.CATEGORIES.get(i) + '=' + String
.format("%.1f", ratings[i]);
prefix = ",";
}
info1 = newInfo.replaceAll("%rating%", rating);
} else {
info1 = newInfo.replaceAll("%rating%",
String.format("%.1f", plot.getAverageRating()) + '/' + max);
}
whenDone.run(info1);
}); });
return; return;
} }
@ -815,10 +811,9 @@ public class MainUtil {
if (directory.exists()) { if (directory.exists()) {
File[] files = directory.listFiles(); File[] files = directory.listFiles();
if (null != files) { if (null != files) {
for (int i = 0; i < files.length; i++) { for (File file : files) {
File file = files[i];
if (file.isDirectory()) { if (file.isDirectory()) {
deleteDirectory(files[i]); deleteDirectory(file);
} else { } else {
PlotSquared.debug("Deleting file: " + file + " | " + file.delete()); PlotSquared.debug("Deleting file: " + file + " | " + file.delete());
} }

View File

@ -87,7 +87,7 @@ public abstract class SchematicHandler {
} else { } else {
MainUtil.sendMessage(null, "&7 - &a success: " + plot.getId()); MainUtil.sendMessage(null, "&7 - &a success: " + plot.getId());
} }
TaskManager.runTask(() -> THIS.run()); TaskManager.runTask(THIS);
}); });
} }
} }

View File

@ -13,292 +13,292 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class GlobalBlockQueue { public class GlobalBlockQueue {
public static GlobalBlockQueue IMP; public static GlobalBlockQueue IMP;
private final int PARALLEL_THREADS; private final int PARALLEL_THREADS;
private final ConcurrentLinkedDeque<LocalBlockQueue> activeQueues; private final ConcurrentLinkedDeque<LocalBlockQueue> activeQueues;
private final ConcurrentLinkedDeque<LocalBlockQueue> inactiveQueues; private final ConcurrentLinkedDeque<LocalBlockQueue> inactiveQueues;
private final ConcurrentLinkedDeque<Runnable> runnables; private final ConcurrentLinkedDeque<Runnable> runnables;
private final AtomicBoolean running; private final AtomicBoolean running;
private QueueProvider provider; private QueueProvider provider;
/** /**
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server * Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the
*/ * server
private long last; */
private long secondLast; private long last;
private long lastSuccess; private long secondLast;
private final RunnableVal2<Long, LocalBlockQueue> SET_TASK = private long lastSuccess;
new RunnableVal2<Long, LocalBlockQueue>() { private final RunnableVal2<Long, LocalBlockQueue> SET_TASK =
@Override public void run(Long free, LocalBlockQueue queue) { new RunnableVal2<Long, LocalBlockQueue>() {
do { @Override
boolean more = queue.next(); public void run(Long free, LocalBlockQueue queue) {
if (!more) { do {
lastSuccess = last; boolean more = queue.next();
if (inactiveQueues.size() == 0 && activeQueues.size() == 0) { if (!more) {
tasks(); lastSuccess = last;
} if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
return; tasks();
} }
} while (((GlobalBlockQueue.this.secondLast = System.currentTimeMillis()) return;
- GlobalBlockQueue.this.last) < free);
} }
}; } while (((GlobalBlockQueue.this.secondLast = System.currentTimeMillis())
- GlobalBlockQueue.this.last) < free);
public GlobalBlockQueue(QueueProvider provider, int threads) {
this.provider = provider;
activeQueues = new ConcurrentLinkedDeque<>();
inactiveQueues = new ConcurrentLinkedDeque<>();
runnables = new ConcurrentLinkedDeque<>();
running = new AtomicBoolean();
this.PARALLEL_THREADS = threads;
}
public QueueProvider getProvider() {
return provider;
}
public void setProvider(QueueProvider provider) {
this.provider = provider;
}
public LocalBlockQueue getNewQueue(String world, boolean autoQueue) {
LocalBlockQueue queue = provider.getNewQueue(world);
if (autoQueue) {
inactiveQueues.add(queue);
} }
return queue; };
}
public boolean stop() { public GlobalBlockQueue(QueueProvider provider, int threads) {
if (!running.get()) { this.provider = provider;
return false; activeQueues = new ConcurrentLinkedDeque<>();
} inactiveQueues = new ConcurrentLinkedDeque<>();
running.set(false); runnables = new ConcurrentLinkedDeque<>();
return true; running = new AtomicBoolean();
} this.PARALLEL_THREADS = threads;
}
public boolean runTask() { public QueueProvider getProvider() {
if (running.get()) { return provider;
return false; }
}
running.set(true);
TaskManager.runTaskRepeat(new Runnable() {
@Override public void run() {
if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
lastSuccess = System.currentTimeMillis();
tasks();
return;
}
SET_TASK.value1 = 50 + Math.min(
(50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last =
System.currentTimeMillis()),
GlobalBlockQueue.this.secondLast - System.currentTimeMillis());
SET_TASK.value2 = getNextQueue();
if (SET_TASK.value2 == null) {
return;
}
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException(
"This shouldn't be possible for placement to occur off the main thread");
}
// Disable the async catcher as it can't discern async vs parallel
SET_TASK.value2.startSet(true);
try {
if (PARALLEL_THREADS <= 1) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
}
}
}, 1);
return true;
}
public QueueStage getStage(LocalBlockQueue queue) { public void setProvider(QueueProvider provider) {
if (activeQueues.contains(queue)) { this.provider = provider;
return QueueStage.ACTIVE; }
} else if (inactiveQueues.contains(queue)) {
return QueueStage.INACTIVE;
}
return QueueStage.NONE;
}
public boolean isStage(LocalBlockQueue queue, QueueStage stage) { public LocalBlockQueue getNewQueue(String world, boolean autoQueue) {
switch (stage) { LocalBlockQueue queue = provider.getNewQueue(world);
case ACTIVE: if (autoQueue) {
return activeQueues.contains(queue); inactiveQueues.add(queue);
case INACTIVE:
return inactiveQueues.contains(queue);
case NONE:
return !activeQueues.contains(queue) && !inactiveQueues.contains(queue);
}
return false;
} }
return queue;
}
public void enqueue(LocalBlockQueue queue) { public boolean stop() {
inactiveQueues.remove(queue); if (!running.get()) {
if (queue.size() > 0 && !activeQueues.contains(queue)) { return false;
queue.optimize();
activeQueues.add(queue);
}
} }
running.set(false);
return true;
}
public void dequeue(LocalBlockQueue queue) { public boolean runTask() {
inactiveQueues.remove(queue); if (running.get()) {
activeQueues.remove(queue); return false;
} }
running.set(true);
public List<LocalBlockQueue> getAllQueues() { TaskManager.runTaskRepeat(() -> {
ArrayList<LocalBlockQueue> list = if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
new ArrayList<LocalBlockQueue>(activeQueues.size() + inactiveQueues.size()); lastSuccess = System.currentTimeMillis();
list.addAll(inactiveQueues); tasks();
list.addAll(activeQueues); return;
return list; }
} SET_TASK.value1 = 50 + Math.min(
(50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last =
public List<LocalBlockQueue> getActiveQueues() { System.currentTimeMillis()),
return new ArrayList<>(activeQueues); GlobalBlockQueue.this.secondLast - System.currentTimeMillis());
} SET_TASK.value2 = getNextQueue();
if (SET_TASK.value2 == null) {
public List<LocalBlockQueue> getInactiveQueues() { return;
return new ArrayList<>(inactiveQueues); }
} if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException(
public void flush(LocalBlockQueue queue) { "This shouldn't be possible for placement to occur off the main thread");
SET_TASK.value1 = Long.MAX_VALUE; }
SET_TASK.value2 = queue; // Disable the async catcher as it can't discern async vs parallel
if (SET_TASK.value2 == null) { SET_TASK.value2.startSet(true);
return; try {
} if (PARALLEL_THREADS <= 1) {
if (PlotSquared.get().isMainThread(Thread.currentThread())) { SET_TASK.run();
throw new IllegalStateException("Must be flushed on the main thread!"); } else {
} ArrayList<Thread> threads = new ArrayList<Thread>();
// Disable the async catcher as it can't discern async vs parallel for (int i = 0; i < PARALLEL_THREADS; i++) {
SET_TASK.value2.startSet(true); threads.add(new Thread(SET_TASK));
try { }
if (PARALLEL_THREADS <= 1) { for (Thread thread : threads) {
SET_TASK.run(); thread.start();
} else { }
ArrayList<Thread> threads = new ArrayList<Thread>(); for (Thread thread : threads) {
for (int i = 0; i < PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
dequeue(queue);
}
}
public LocalBlockQueue getNextQueue() {
long now = System.currentTimeMillis();
while (activeQueues.size() > 0) {
LocalBlockQueue queue = activeQueues.peek();
if (queue != null && queue.size() > 0) {
queue.setModified(now);
return queue;
} else {
activeQueues.poll();
}
}
int size = inactiveQueues.size();
if (size > 0) {
Iterator<LocalBlockQueue> iter = inactiveQueues.iterator();
try { try {
int total = 0; thread.join();
LocalBlockQueue firstNonEmpty = null; } catch (InterruptedException e) {
while (iter.hasNext()) { e.printStackTrace();
LocalBlockQueue queue = iter.next();
long age = now - queue.getModified();
total += queue.size();
if (queue.size() == 0) {
if (age > 1000) {
iter.remove();
}
continue;
}
if (firstNonEmpty == null) {
firstNonEmpty = queue;
}
if (total > 64) {
firstNonEmpty.setModified(now);
return firstNonEmpty;
}
if (age > 60000) {
queue.setModified(now);
return queue;
}
}
} catch (ConcurrentModificationException e) {
e.printStackTrace();
} }
}
} }
return null; } catch (Throwable e) {
} e.printStackTrace();
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
}
}, 1);
return true;
}
public boolean isDone() { public QueueStage getStage(LocalBlockQueue queue) {
return activeQueues.size() == 0 && inactiveQueues.size() == 0; if (activeQueues.contains(queue)) {
return QueueStage.ACTIVE;
} else if (inactiveQueues.contains(queue)) {
return QueueStage.INACTIVE;
} }
return QueueStage.NONE;
}
public boolean addTask(final Runnable whenDone) { public boolean isStage(LocalBlockQueue queue, QueueStage stage) {
if (this.isDone()) { switch (stage) {
// Run case ACTIVE:
this.tasks(); return activeQueues.contains(queue);
if (whenDone != null) { case INACTIVE:
whenDone.run(); return inactiveQueues.contains(queue);
case NONE:
return !activeQueues.contains(queue) && !inactiveQueues.contains(queue);
}
return false;
}
public void enqueue(LocalBlockQueue queue) {
inactiveQueues.remove(queue);
if (queue.size() > 0 && !activeQueues.contains(queue)) {
queue.optimize();
activeQueues.add(queue);
}
}
public void dequeue(LocalBlockQueue queue) {
inactiveQueues.remove(queue);
activeQueues.remove(queue);
}
public List<LocalBlockQueue> getAllQueues() {
ArrayList<LocalBlockQueue> list =
new ArrayList<>(activeQueues.size() + inactiveQueues.size());
list.addAll(inactiveQueues);
list.addAll(activeQueues);
return list;
}
public List<LocalBlockQueue> getActiveQueues() {
return new ArrayList<>(activeQueues);
}
public List<LocalBlockQueue> getInactiveQueues() {
return new ArrayList<>(inactiveQueues);
}
public void flush(LocalBlockQueue queue) {
SET_TASK.value1 = Long.MAX_VALUE;
SET_TASK.value2 = queue;
if (SET_TASK.value2 == null) {
return;
}
if (PlotSquared.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException("Must be flushed on the main thread!");
}
// Disable the async catcher as it can't discern async vs parallel
SET_TASK.value2.startSet(true);
try {
if (PARALLEL_THREADS <= 1) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<>();
for (int i = 0; i < PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
dequeue(queue);
}
}
public LocalBlockQueue getNextQueue() {
long now = System.currentTimeMillis();
while (activeQueues.size() > 0) {
LocalBlockQueue queue = activeQueues.peek();
if (queue != null && queue.size() > 0) {
queue.setModified(now);
return queue;
} else {
activeQueues.poll();
}
}
int size = inactiveQueues.size();
if (size > 0) {
Iterator<LocalBlockQueue> iter = inactiveQueues.iterator();
try {
int total = 0;
LocalBlockQueue firstNonEmpty = null;
while (iter.hasNext()) {
LocalBlockQueue queue = iter.next();
long age = now - queue.getModified();
total += queue.size();
if (queue.size() == 0) {
if (age > 1000) {
iter.remove();
} }
return true; continue;
}
if (firstNonEmpty == null) {
firstNonEmpty = queue;
}
if (total > 64) {
firstNonEmpty.setModified(now);
return firstNonEmpty;
}
if (age > 60000) {
queue.setModified(now);
return queue;
}
} }
if (whenDone != null) { } catch (ConcurrentModificationException e) {
this.runnables.add(whenDone); e.printStackTrace();
} }
return false;
} }
return null;
}
public synchronized boolean tasks() { public boolean isDone() {
if (this.runnables.isEmpty()) { return activeQueues.size() == 0 && inactiveQueues.size() == 0;
return false; }
}
final ArrayList<Runnable> tmp = new ArrayList<>(this.runnables);
this.runnables.clear();
for (final Runnable runnable : tmp) {
runnable.run();
}
return true;
}
public enum QueueStage { public boolean addTask(final Runnable whenDone) {
INACTIVE, ACTIVE, NONE; if (this.isDone()) {
// Run
this.tasks();
if (whenDone != null) {
whenDone.run();
}
return true;
} }
if (whenDone != null) {
this.runnables.add(whenDone);
}
return false;
}
public synchronized boolean tasks() {
if (this.runnables.isEmpty()) {
return false;
}
final ArrayList<Runnable> tmp = new ArrayList<>(this.runnables);
this.runnables.clear();
for (final Runnable runnable : tmp) {
runnable.run();
}
return true;
}
public enum QueueStage {
INACTIVE, ACTIVE, NONE
}
} }

View File

@ -19,454 +19,435 @@ import java.util.concurrent.ConcurrentLinkedDeque;
public class ExpireManager { public class ExpireManager {
public static ExpireManager IMP; public static ExpireManager IMP;
private final ConcurrentHashMap<UUID, Long> dates_cache; private final ConcurrentHashMap<UUID, Long> dates_cache;
private final ConcurrentHashMap<UUID, Long> account_age_cache; private final ConcurrentHashMap<UUID, Long> account_age_cache;
private volatile HashSet<Plot> plotsToDelete; private volatile HashSet<Plot> plotsToDelete;
private ArrayDeque<ExpiryTask> tasks; private ArrayDeque<ExpiryTask> tasks;
/** /**
* 0 = stopped, 1 = stopping, 2 = running * 0 = stopped, 1 = stopping, 2 = running
*/ */
private int running; private int running;
public ExpireManager() { public ExpireManager() {
tasks = new ArrayDeque<>(); tasks = new ArrayDeque<>();
dates_cache = new ConcurrentHashMap<>(); dates_cache = new ConcurrentHashMap<>();
account_age_cache = new ConcurrentHashMap<>(); account_age_cache = new ConcurrentHashMap<>();
}
public void addTask(ExpiryTask task) {
PlotSquared.debug("Adding new expiry task!");
this.tasks.add(task);
}
public void handleJoin(PlotPlayer pp) {
storeDate(pp.getUUID(), System.currentTimeMillis());
if (plotsToDelete != null && !plotsToDelete.isEmpty()) {
for (Plot plot : pp.getPlots()) {
plotsToDelete.remove(plot);
}
} }
confirmExpiry(pp);
}
public void addTask(ExpiryTask task) { public void handleEntry(PlotPlayer pp, Plot plot) {
PlotSquared.debug("Adding new expiry task!"); if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp
this.tasks.add(task); .hasPermission("plots.admin.command.autoclear") && plotsToDelete.contains(plot)) {
} if (!isExpired(new ArrayDeque<>(tasks), plot).isEmpty()) {
public void handleJoin(PlotPlayer pp) {
storeDate(pp.getUUID(), System.currentTimeMillis());
if (plotsToDelete != null && !plotsToDelete.isEmpty()) {
for (Plot plot : pp.getPlots()) {
plotsToDelete.remove(plot);
}
}
confirmExpiry(pp); confirmExpiry(pp);
} else {
plotsToDelete.remove(plot);
confirmExpiry(pp);
}
} }
}
public void handleEntry(PlotPlayer pp, Plot plot) { /**
if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp * Gets the account last joined - first joined (or Long.MAX_VALUE)
.hasPermission("plots.admin.command.autoclear") && plotsToDelete.contains(plot)) { *
if (!isExpired(new ArrayDeque<>(tasks), plot).isEmpty()) { * @return result
confirmExpiry(pp); */
} else { public long getAccountAge(UUID uuid) {
plotsToDelete.remove(plot); Long value = this.account_age_cache.get(uuid);
confirmExpiry(pp); return value == null ? Long.MAX_VALUE : value;
} }
}
public long getTimestamp(UUID uuid) {
Long value = this.dates_cache.get(uuid);
return value == null ? 0 : value;
}
public void updateExpired(Plot plot) {
if (plotsToDelete != null && !plotsToDelete.isEmpty() && plotsToDelete.contains(plot)) {
if (isExpired(new ArrayDeque<>(tasks), plot).isEmpty()) {
plotsToDelete.remove(plot);
}
} }
}
/** public void confirmExpiry(final PlotPlayer pp) {
* Gets the account last joined - first joined (or Long.MAX_VALUE) if (pp.getMeta("ignoreExpireTask") != null) {
* return;
* @param uuid
* @return result
*/
public long getAccountAge(UUID uuid) {
Long value = this.account_age_cache.get(uuid);
return value == null ? Long.MAX_VALUE : value;
} }
if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp
public long getTimestamp(UUID uuid) { .hasPermission("plots.admin.command.autoclear")) {
Long value = this.dates_cache.get(uuid); final int num = plotsToDelete.size();
return value == null ? 0 : value; while (!plotsToDelete.isEmpty()) {
} Iterator<Plot> iter = plotsToDelete.iterator();
final Plot current = iter.next();
public void updateExpired(Plot plot) { if (!isExpired(new ArrayDeque<>(tasks), current).isEmpty()) {
if (plotsToDelete != null && !plotsToDelete.isEmpty() && plotsToDelete.contains(plot)) { TaskManager.runTask(() -> {
if (isExpired(new ArrayDeque<>(tasks), plot).isEmpty()) { pp.setMeta("ignoreExpireTask", true);
plotsToDelete.remove(plot); pp.teleport(current.getCenter());
} pp.deleteMeta("ignoreExpireTask");
} PlotMessage msg = new PlotMessage().text(
} num + " " + (num > 1 ? "plots are" : "plot is") + " expired: ")
.color("$1").text(current.toString()).color("$2")
public void confirmExpiry(final PlotPlayer pp) { .suggest("/plot list expired").tooltip("/plot list expired")
if (pp.getMeta("ignoreExpireTask") != null) { //.text("\n - ").color("$3").text("Delete all (/plot delete expired)").color("$2").command("/plot delete expired")
return; .text("\n - ").color("$3").text("Delete this (/plot delete)")
} .color("$2").suggest("/plot delete").tooltip("/plot delete")
if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp .text("\n - ").color("$3").text("Remind later (/plot set keep 1d)")
.hasPermission("plots.admin.command.autoclear")) { .color("$2").suggest("/plot set keep 1d")
final int num = plotsToDelete.size(); .tooltip("/plot set keep 1d").text("\n - ").color("$3")
while (!plotsToDelete.isEmpty()) { .text("Keep this (/plot set keep true)").color("$2")
Iterator<Plot> iter = plotsToDelete.iterator(); .suggest("/plot set keep true").tooltip("/plot set keep true")
final Plot current = iter.next(); .text("\n - ").color("$3").text("Don't show me this").color("$2")
if (!isExpired(new ArrayDeque<>(tasks), current).isEmpty()) { .suggest("/plot toggle clear-confirmation")
TaskManager.runTask(new Runnable() { .tooltip("/plot toggle clear-confirmation");
@Override public void run() { msg.send(pp);
pp.setMeta("ignoreExpireTask", true); });
pp.teleport(current.getCenter()); return;
pp.deleteMeta("ignoreExpireTask");
PlotMessage msg = new PlotMessage().text(
num + " " + (num > 1 ? "plots are" : "plot is") + " expired: ")
.color("$1").text(current.toString()).color("$2")
.suggest("/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 delete)")
.color("$2").suggest("/plot delete").tooltip("/plot delete")
.text("\n - ").color("$3").text("Remind later (/plot set keep 1d)")
.color("$2").suggest("/plot set keep 1d")
.tooltip("/plot set keep 1d").text("\n - ").color("$3")
.text("Keep this (/plot set keep true)").color("$2")
.suggest("/plot set keep true").tooltip("/plot set keep true")
.text("\n - ").color("$3").text("Don't show me this").color("$2")
.suggest("/plot toggle clear-confirmation")
.tooltip("/plot toggle clear-confirmation");
msg.send(pp);
}
});
return;
} else {
iter.remove();
}
}
plotsToDelete.clear();
}
}
public boolean cancelTask() {
if (this.running != 2) {
return false;
}
this.running = 1;
return true;
}
public boolean runAutomatedTask() {
return runTask(new RunnableVal3<Plot, Runnable, Boolean>() {
@Override public void run(Plot plot, Runnable runnable, Boolean confirm) {
if (confirm) {
if (plotsToDelete == null) {
plotsToDelete = new HashSet<>();
}
plotsToDelete.add(plot);
runnable.run();
} else {
deleteWithMessage(plot, runnable);
}
}
});
}
public Collection<ExpiryTask> isExpired(ArrayDeque<ExpiryTask> applicable, Plot plot) {
// Filter out invalid worlds
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask et = applicable.poll();
if (et.applies(plot.getArea())) {
applicable.add(et);
}
}
if (applicable.isEmpty()) {
return new ArrayList<>();
}
boolean shouldCheckAccountAge = false;
long diff = getAge(plot);
if (diff == 0) {
return new ArrayList<>();
}
// Filter out non old plots
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask et = applicable.poll();
if (et.applies(diff)) {
applicable.add(et);
shouldCheckAccountAge |= et.getSettings().SKIP_ACCOUNT_AGE_DAYS != -1;
}
}
if (applicable.isEmpty()) {
return new ArrayList<>();
}
// Check account age
if (shouldCheckAccountAge) {
long accountAge = getAge(plot);
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask et = applicable.poll();
if (et.appliesAccountAge(accountAge)) {
applicable.add(et);
}
}
if (applicable.isEmpty()) {
return new ArrayList<>();
}
}
// Run applicable non confirming tasks
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask expiryTask = applicable.poll();
if (!expiryTask.needsAnalysis() || plot.getArea().TYPE != 0) {
if (!expiryTask.requiresConfirmation()) {
return Collections.singletonList(expiryTask);
}
}
applicable.add(expiryTask);
}
// Run applicable confirming tasks
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask expiryTask = applicable.poll();
if (!expiryTask.needsAnalysis() || plot.getArea().TYPE != 0) {
return Collections.singletonList(expiryTask);
}
applicable.add(expiryTask);
}
return applicable;
}
public ArrayDeque<ExpiryTask> getTasks(PlotArea area) {
ArrayDeque<ExpiryTask> queue = new ArrayDeque<>(tasks);
Iterator<ExpiryTask> iter = queue.iterator();
while (iter.hasNext()) {
if (!iter.next().applies(area)) {
iter.remove();
}
}
return queue;
}
public void passesComplexity(PlotAnalysis analysis, Collection<ExpiryTask> applicable,
RunnableVal<Boolean> success, Runnable failure) {
if (analysis != null) {
// Run non confirming tasks
for (ExpiryTask et : applicable) {
if (!et.requiresConfirmation() && et.applies(analysis)) {
success.run(false);
return;
}
}
for (ExpiryTask et : applicable) {
if (et.applies(analysis)) {
success.run(true);
return;
}
}
failure.run();
}
}
public boolean runTask(final RunnableVal3<Plot, Runnable, Boolean> expiredTask) {
if (this.running != 0) {
return false;
}
this.running = 2;
final ConcurrentLinkedDeque<Plot> plots =
new ConcurrentLinkedDeque<Plot>(PlotSquared.get().getPlots());
TaskManager.runTaskAsync(new Runnable() {
@Override public void run() {
final Runnable task = this;
if (ExpireManager.this.running != 2) {
ExpireManager.this.running = 0;
return;
}
long start = System.currentTimeMillis();
while (!plots.isEmpty()) {
if (ExpireManager.this.running != 2) {
ExpireManager.this.running = 0;
return;
}
Plot plot = plots.poll();
PlotArea area = plot.getArea();
final Plot newPlot = area.getPlot(plot.getId());
final ArrayDeque<ExpiryTask> applicable = new ArrayDeque<>(tasks);
final Collection<ExpiryTask> expired = isExpired(applicable, newPlot);
if (expired.isEmpty()) {
continue;
}
for (ExpiryTask expiryTask : expired) {
if (!expiryTask.needsAnalysis()) {
expiredTask.run(newPlot, new Runnable() {
@Override public void run() {
TaskManager.IMP.taskLaterAsync(task, 1);
}
}, expiryTask.requiresConfirmation());
return;
}
}
final RunnableVal<PlotAnalysis> handleAnalysis =
new RunnableVal<PlotAnalysis>() {
@Override public void run(final PlotAnalysis changed) {
passesComplexity(changed, expired, new RunnableVal<Boolean>() {
@Override public void run(Boolean confirmation) {
expiredTask.run(newPlot, new Runnable() {
@Override public void run() {
TaskManager.IMP.taskLaterAsync(task, 1);
}
}, confirmation);
}
}, new Runnable() {
@Override public void run() {
FlagManager
.addPlotFlag(newPlot, Flags.ANALYSIS, changed.asList());
TaskManager.runTaskLaterAsync(task, 20);
}
});
}
};
final Runnable doAnalysis = new Runnable() {
@Override public void run() {
HybridUtils.manager.analyzePlot(newPlot, handleAnalysis);
}
};
PlotAnalysis analysis = newPlot.getComplexity(null);
if (analysis != null) {
passesComplexity(analysis, expired, new RunnableVal<Boolean>() {
@Override public void run(Boolean value) {
doAnalysis.run();
}
}, new Runnable() {
@Override public void run() {
TaskManager.IMP.taskLaterAsync(task, 1);
}
});
} else {
doAnalysis.run();
}
return;
}
if (plots.isEmpty()) {
ExpireManager.this.running = 3;
TaskManager.runTaskLater(new Runnable() {
@Override public void run() {
if (ExpireManager.this.running == 3) {
ExpireManager.this.running = 2;
runTask(expiredTask);
}
}
}, 86400000);
} else {
TaskManager.runTaskLaterAsync(task, 20 * 10);
}
}
});
return true;
}
public void storeDate(UUID uuid, long time) {
Long existing = this.dates_cache.put(uuid, time);
if (existing != null) {
long diff = time - existing;
if (diff > 0) {
Long account_age = this.account_age_cache.get(uuid);
if (account_age != null)
this.account_age_cache.put(uuid, account_age + diff);
}
}
}
public void storeAccountAge(UUID uuid, long time) {
this.account_age_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 (UUID helper : plot.getTrusted()) {
PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.toString());
}
}
for (UUID helper : plot.getMembers()) {
PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.toString());
}
}
Set<Plot> plots = plot.getConnectedPlots();
plot.deletePlot(whenDone);
PlotAnalysis changed = plot.getComplexity(null);
int changes = changed == null ? 0 : changed.changes_sd;
int modified = changed == null ? 0 : changed.changes;
PlotSquared.debug(
"$2[&5Expire&dManager$2] &cDeleted expired plot: " + plot + " User:" + plot.owner
+ " Delta:" + changes + "/" + modified + " Connected: " + StringMan
.getString(plots));
PlotSquared.debug("$4 - Area: " + plot.getArea());
if (plot.hasOwner()) {
PlotSquared.debug("$4 - Owner: " + UUIDHandler.getName(plot.owner));
} else { } else {
PlotSquared.debug("$4 - Owner: Unowned"); iter.remove();
} }
}
plotsToDelete.clear();
}
}
public boolean cancelTask() {
if (this.running != 2) {
return false;
}
this.running = 1;
return true;
}
public boolean runAutomatedTask() {
return runTask(new RunnableVal3<Plot, Runnable, Boolean>() {
@Override
public void run(Plot plot, Runnable runnable, Boolean confirm) {
if (confirm) {
if (plotsToDelete == null) {
plotsToDelete = new HashSet<>();
}
plotsToDelete.add(plot);
runnable.run();
} else {
deleteWithMessage(plot, runnable);
}
}
});
}
public Collection<ExpiryTask> isExpired(ArrayDeque<ExpiryTask> applicable, Plot plot) {
// Filter out invalid worlds
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask et = applicable.poll();
if (et.applies(plot.getArea())) {
applicable.add(et);
}
}
if (applicable.isEmpty()) {
return new ArrayList<>();
}
boolean shouldCheckAccountAge = false;
long diff = getAge(plot);
if (diff == 0) {
return new ArrayList<>();
}
// Filter out non old plots
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask et = applicable.poll();
if (et.applies(diff)) {
applicable.add(et);
shouldCheckAccountAge |= et.getSettings().SKIP_ACCOUNT_AGE_DAYS != -1;
}
}
if (applicable.isEmpty()) {
return new ArrayList<>();
}
// Check account age
if (shouldCheckAccountAge) {
long accountAge = getAge(plot);
for (int i = 0; i < applicable.size(); i++) {
ExpiryTask et = applicable.poll();
if (et.appliesAccountAge(accountAge)) {
applicable.add(et);
}
}
if (applicable.isEmpty()) {
return new ArrayList<>();
}
} }
public long getAge(UUID uuid) { // Run applicable non confirming tasks
if (UUIDHandler.getPlayer(uuid) != null) { for (int i = 0; i < applicable.size(); i++) {
return 0; ExpiryTask expiryTask = applicable.poll();
if (!expiryTask.needsAnalysis() || plot.getArea().TYPE != 0) {
if (!expiryTask.requiresConfirmation()) {
return Collections.singletonList(expiryTask);
} }
String name = UUIDHandler.getName(uuid); }
if (name != null) { applicable.add(expiryTask);
Long last = this.dates_cache.get(uuid); }
if (last == null) { // Run applicable confirming tasks
OfflinePlotPlayer opp; for (int i = 0; i < applicable.size(); i++) {
if (Settings.UUID.NATIVE_UUID_PROVIDER) { ExpiryTask expiryTask = applicable.poll();
opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(uuid); if (!expiryTask.needsAnalysis() || plot.getArea().TYPE != 0) {
} else { return Collections.singletonList(expiryTask);
opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(name); }
} applicable.add(expiryTask);
if (opp != null && (last = opp.getLastPlayed()) != 0) { }
this.dates_cache.put(uuid, last); return applicable;
} else { }
return 0;
} public ArrayDeque<ExpiryTask> getTasks(PlotArea area) {
} ArrayDeque<ExpiryTask> queue = new ArrayDeque<>(tasks);
if (last == 0) { queue.removeIf(expiryTask -> !expiryTask.applies(area));
return 0; return queue;
} }
return System.currentTimeMillis() - last;
public void passesComplexity(PlotAnalysis analysis, Collection<ExpiryTask> applicable,
RunnableVal<Boolean> success, Runnable failure) {
if (analysis != null) {
// Run non confirming tasks
for (ExpiryTask et : applicable) {
if (!et.requiresConfirmation() && et.applies(analysis)) {
success.run(false);
return;
} }
}
for (ExpiryTask et : applicable) {
if (et.applies(analysis)) {
success.run(true);
return;
}
}
failure.run();
}
}
public boolean runTask(final RunnableVal3<Plot, Runnable, Boolean> expiredTask) {
if (this.running != 0) {
return false;
}
this.running = 2;
final ConcurrentLinkedDeque<Plot> plots =
new ConcurrentLinkedDeque<>(PlotSquared.get().getPlots());
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
final Runnable task = this;
if (ExpireManager.this.running != 2) {
ExpireManager.this.running = 0;
return;
}
long start = System.currentTimeMillis();
while (!plots.isEmpty()) {
if (ExpireManager.this.running != 2) {
ExpireManager.this.running = 0;
return;
}
Plot plot = plots.poll();
PlotArea area = plot.getArea();
final Plot newPlot = area.getPlot(plot.getId());
final ArrayDeque<ExpiryTask> applicable = new ArrayDeque<>(tasks);
final Collection<ExpiryTask> expired = isExpired(applicable, newPlot);
if (expired.isEmpty()) {
continue;
}
for (ExpiryTask expiryTask : expired) {
if (!expiryTask.needsAnalysis()) {
expiredTask.run(newPlot, () -> TaskManager.IMP.taskLaterAsync(task, 1),
expiryTask.requiresConfirmation());
return;
}
}
final RunnableVal<PlotAnalysis> handleAnalysis =
new RunnableVal<PlotAnalysis>() {
@Override
public void run(final PlotAnalysis changed) {
passesComplexity(changed, expired, new RunnableVal<Boolean>() {
@Override
public void run(Boolean confirmation) {
expiredTask.run(newPlot,
() -> TaskManager.IMP.taskLaterAsync(task, 1), confirmation);
}
}, () -> {
FlagManager
.addPlotFlag(newPlot, Flags.ANALYSIS, changed.asList());
TaskManager.runTaskLaterAsync(task, 20);
});
}
};
final Runnable doAnalysis = () -> HybridUtils.manager
.analyzePlot(newPlot, handleAnalysis);
PlotAnalysis analysis = newPlot.getComplexity(null);
if (analysis != null) {
passesComplexity(analysis, expired, new RunnableVal<Boolean>() {
@Override
public void run(Boolean value) {
doAnalysis.run();
}
}, () -> TaskManager.IMP.taskLaterAsync(task, 1));
} else {
doAnalysis.run();
}
return;
}
if (plots.isEmpty()) {
ExpireManager.this.running = 3;
TaskManager.runTaskLater(() -> {
if (ExpireManager.this.running == 3) {
ExpireManager.this.running = 2;
runTask(expiredTask);
}
}, 86400000);
} else {
TaskManager.runTaskLaterAsync(task, 20 * 10);
}
}
});
return true;
}
public void storeDate(UUID uuid, long time) {
Long existing = this.dates_cache.put(uuid, time);
if (existing != null) {
long diff = time - existing;
if (diff > 0) {
Long account_age = this.account_age_cache.get(uuid);
if (account_age != null) {
this.account_age_cache.put(uuid, account_age + diff);
}
}
}
}
public void storeAccountAge(UUID uuid, long time) {
this.account_age_cache.put(uuid, time);
}
public HashSet<Plot> getPendingExpired() {
return plotsToDelete == null ? new HashSet<>() : plotsToDelete;
}
public void deleteWithMessage(Plot plot, Runnable whenDone) {
if (plot.isMerged()) {
plot.unlinkPlot(true, false);
}
for (UUID helper : plot.getTrusted()) {
PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.toString());
}
}
for (UUID helper : plot.getMembers()) {
PlotPlayer player = UUIDHandler.getPlayer(helper);
if (player != null) {
MainUtil.sendMessage(player, C.PLOT_REMOVED_USER, plot.toString());
}
}
Set<Plot> plots = plot.getConnectedPlots();
plot.deletePlot(whenDone);
PlotAnalysis changed = plot.getComplexity(null);
int changes = changed == null ? 0 : changed.changes_sd;
int modified = changed == null ? 0 : changed.changes;
PlotSquared.debug(
"$2[&5Expire&dManager$2] &cDeleted expired plot: " + plot + " User:" + plot.owner
+ " Delta:" + changes + "/" + modified + " Connected: " + StringMan
.getString(plots));
PlotSquared.debug("$4 - Area: " + plot.getArea());
if (plot.hasOwner()) {
PlotSquared.debug("$4 - Owner: " + UUIDHandler.getName(plot.owner));
} else {
PlotSquared.debug("$4 - Owner: Unowned");
}
}
public long getAge(UUID uuid) {
if (UUIDHandler.getPlayer(uuid) != null) {
return 0;
}
String name = UUIDHandler.getName(uuid);
if (name != null) {
Long last = this.dates_cache.get(uuid);
if (last == null) {
OfflinePlotPlayer opp;
if (Settings.UUID.NATIVE_UUID_PROVIDER) {
opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(uuid);
} else {
opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(name);
}
if (opp != null && (last = opp.getLastPlayed()) != 0) {
this.dates_cache.put(uuid, last);
} else {
return 0;
}
}
if (last == 0) {
return 0; return 0;
}
return System.currentTimeMillis() - last;
} }
return 0;
}
public long getAccountAge(Plot plot) { public long getAccountAge(Plot plot) {
if (!plot.hasOwner() || Objects.equals(DBFunc.EVERYONE, plot.owner) if (!plot.hasOwner() || Objects.equals(DBFunc.EVERYONE, plot.owner)
|| UUIDHandler.getPlayer(plot.owner) != null || plot.getRunning() > 0) { || UUIDHandler.getPlayer(plot.owner) != null || plot.getRunning() > 0) {
return Long.MAX_VALUE; return Long.MAX_VALUE;
}
long max = 0;
for (UUID owner : plot.getOwners()) {
long age = getAccountAge(owner);
max = Math.max(age, max);
}
return max;
} }
long max = 0;
for (UUID owner : plot.getOwners()) {
long age = getAccountAge(owner);
max = Math.max(age, max);
}
return max;
}
public long getAge(Plot plot) { public long getAge(Plot plot) {
if (!plot.hasOwner() || Objects.equals(DBFunc.EVERYONE, plot.owner) if (!plot.hasOwner() || Objects.equals(DBFunc.EVERYONE, plot.owner)
|| UUIDHandler.getPlayer(plot.owner) != null || plot.getRunning() > 0) { || UUIDHandler.getPlayer(plot.owner) != null || plot.getRunning() > 0) {
return 0; return 0;
}
Optional<?> keep = plot.getFlag(Flags.KEEP);
if (keep.isPresent()) {
Object value = keep.get();
if (value instanceof Boolean) {
if (Boolean.TRUE.equals(value)) {
return 0;
}
} else if (value instanceof Long) {
if ((Long) value > System.currentTimeMillis()) {
return 0;
}
} else { // Invalid?
return 0;
}
}
long min = Long.MAX_VALUE;
for (UUID owner : plot.getOwners()) {
long age = getAge(owner);
if (age < min) {
min = age;
}
}
return min;
} }
Optional<?> keep = plot.getFlag(Flags.KEEP);
if (keep.isPresent()) {
Object value = keep.get();
if (value instanceof Boolean) {
if (Boolean.TRUE.equals(value)) {
return 0;
}
} else if (value instanceof Long) {
if ((Long) value > System.currentTimeMillis()) {
return 0;
}
} else { // Invalid?
return 0;
}
}
long min = Long.MAX_VALUE;
for (UUID owner : plot.getOwners()) {
long age = getAge(owner);
if (age < min) {
min = age;
}
}
return min;
}
} }

View File

@ -5,7 +5,6 @@ import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.PlotFilter; import com.github.intellectualsites.plotsquared.plot.object.PlotFilter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View File

@ -118,16 +118,14 @@ public class PlotAnalysis {
final AtomicInteger mi = new AtomicInteger(0); final AtomicInteger mi = new AtomicInteger(0);
Thread ratingAnalysis = new Thread(new Runnable() { Thread ratingAnalysis = new Thread(() -> {
@Override public void run() { for (; mi.intValue() < plots.size(); mi.incrementAndGet()) {
for (; mi.intValue() < plots.size(); mi.incrementAndGet()) { int i = mi.intValue();
int i = mi.intValue(); Plot plot = plots.get(i);
Plot plot = plots.get(i); ratings[i] = (int) (
ratings[i] = (int) ( (plot.getAverageRating() + plot.getSettings().getRatings().size())
(plot.getAverageRating() + plot.getSettings().getRatings().size()) * 100);
* 100); PlotSquared.debug(" | " + plot + " (rating) " + ratings[i]);
PlotSquared.debug(" | " + plot + " (rating) " + ratings[i]);
}
} }
}); });
ratingAnalysis.start(); ratingAnalysis.start();
@ -424,9 +422,6 @@ public class PlotAnalysis {
/** /**
* A simple array squaring algorithm. * A simple array squaring algorithm.
* - Used for calculating the variance * - Used for calculating the variance
*
* @param array
* @return
*/ */
public static int[] square(int[] array) { public static int[] square(int[] array) {
array = array.clone(); array = array.clone();
@ -439,8 +434,6 @@ public class PlotAnalysis {
/** /**
* An optimized lossy standard deviation algorithm. * An optimized lossy standard deviation algorithm.
* *
* @param ranks
* @return
*/ */
public static int[] getSD(int[]... ranks) { public static int[] getSD(int[]... ranks) {
if (ranks.length == 0) { if (ranks.length == 0) {
@ -468,19 +461,13 @@ public class PlotAnalysis {
* - Input is an array of int with a max size of 102400<br> * - Input is an array of int with a max size of 102400<br>
* - A reduced sample space allows for sorting (and ranking in this case) in linear time * - A reduced sample space allows for sorting (and ranking in this case) in linear time
* *
* @param input
* @param input
* @return
*/ */
public static int[] rank(int[] input) { public static int[] rank(int[] input) {
return rank(input, 102400); return rank(input, 102400);
} }
/** /**
* An optimized algorithm for ranking a very specific set of inputs * An optimized algorithm for ranking a very specific set of inputs.
*
* @param input
* @return
*/ */
public static int[] rank(int[] input, int size) { public static int[] rank(int[] input, int size) {
int[] cache = new int[size]; int[] cache = new int[size];

View File

@ -5,17 +5,17 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import java.util.UUID; import java.util.UUID;
public abstract class UUIDWrapper { public interface UUIDWrapper {
public abstract UUID getUUID(PlotPlayer player); UUID getUUID(PlotPlayer player);
public abstract UUID getUUID(OfflinePlotPlayer player); UUID getUUID(OfflinePlotPlayer player);
public abstract UUID getUUID(String name); UUID getUUID(String name);
public abstract OfflinePlotPlayer getOfflinePlayer(UUID uuid); OfflinePlotPlayer getOfflinePlayer(UUID uuid);
public abstract OfflinePlotPlayer getOfflinePlayer(String name); OfflinePlotPlayer getOfflinePlayer(String name);
public abstract OfflinePlotPlayer[] getOfflinePlayers(); OfflinePlotPlayer[] getOfflinePlayers();
} }

View File

@ -84,10 +84,7 @@ public class AbstractDBTest implements AbstractDB {
@Override public void setFlags(Plot plot, HashMap<Flag<?>, Object> flags) { @Override public void setFlags(Plot plot, HashMap<Flag<?>, Object> flags) {
} }
@Override public void setFlags(PlotCluster cluster, HashMap<Flag<?>, Object> flags) { @Override public void setClusterName(PlotCluster cluster, String name) {
}
@Override public void setClusterName(PlotCluster cluster, String name) {
} }
@Override public void setAlias(Plot plot, String alias) { @Override public void setAlias(Plot plot, String alias) {

View File

@ -40,11 +40,7 @@ public class EventUtilTest extends EventUtil {
return true; return true;
} }
@Override public boolean callFlagRemove(Flag<?> flag, Object value, PlotCluster cluster) { @Override public boolean callMerge(Plot plot, int dir, int max){
return true;
}
@Override public boolean callMerge(Plot plot, int dir, int max){
return false; return false;
} }