//////////////////////////////////////////////////////////////////////////////////////////////////// // PlotSquared - A plot manager and world generator for the Bukkit API / // Copyright (c) 2014 IntellectualSites/IntellectualCrafters / // / // This program is free software; you can redistribute it and/or modify / // it under the terms of the GNU General Public License as published by / // the Free Software Foundation; either version 3 of the License, or / // (at your option) any later version. / // / // This program is distributed in the hope that it will be useful, / // but WITHOUT ANY WARRANTY; without even the implied warranty of / // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / // GNU General Public License for more details. / // / // You should have received a copy of the GNU General Public License / // along with this program; if not, write to the Free Software Foundation, / // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA / // / // You can contact us via: support@intellectualsites.com / //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.util; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.database.DBFunc; import com.intellectualcrafters.plot.object.BlockLoc; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotBlock; import com.intellectualcrafters.plot.object.PlotCluster; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.object.PlotWorld; import com.intellectualcrafters.plot.object.PseudoRandom; import com.intellectualcrafters.plot.object.RunnableVal; import com.plotsquared.listener.PlotListener; /** * plot functions * * @author Citymonstret */ public class MainUtil { public final static HashMap runners = new HashMap<>(); public static boolean canSendChunk = false; public static boolean canSetFast = true; public static ArrayList runners_p = new ArrayList<>(); public static HashMap lastPlot = new HashMap<>(); public static HashMap worldBorder = new HashMap<>(); static long state = 1; static PseudoRandom random = new PseudoRandom(); public static short[][] x_loc; public static short[][] y_loc; public static short[][] z_loc; public static void initCache() { if (x_loc == null) { x_loc = new short[16][4096]; y_loc = new short[16][4096]; z_loc = new short[16][4096]; for (int i = 0; i < 16; i++) { int i4 = i << 4; for (int j = 0; j < 4096; j++) { final int y = (i4) + (j >> 8); final int a = (j - ((y & 0xF) << 8)); final int z1 = (a >> 4); final int x1 = a - (z1 << 4); x_loc[i][j] = (short) x1; y_loc[i][j] = (short) y; z_loc[i][j] = (short) z1; } } } } public static boolean isPlotArea(final Location location) { final PlotWorld plotworld = PS.get().getPlotWorld(location.getWorld()); if (plotworld == null) { return false; } if (plotworld.TYPE == 2) { return ClusterManager.getCluster(location) != null; } return true; } public static String getName(UUID owner) { if (owner == null) { return C.NONE.s(); } String name = UUIDHandler.getName(owner); if (name == null) { return C.UNKNOWN.s(); } return name; } public static List getPlayersInPlot(Plot plot) { ArrayList players = new ArrayList<>(); for (PlotPlayer pp : UUIDHandler.getPlayers().values()) { if (plot.equals(pp.getCurrentPlot())) { players.add(pp); } } return players; } public static void reEnterPlot(final Plot plot) { TaskManager.runTaskLater(new Runnable() { @Override public void run() { for (PlotPlayer pp : getPlayersInPlot(plot)) { PlotListener.plotExit(pp, plot); PlotListener.plotEntry(pp, plot); } } }, 1); } public static Location getPlotCenter(Plot plot) { Location bot = getPlotBottomLoc(plot.world, plot.id); Location top = getPlotTopLoc(plot.world, plot.id).add(1, 0, 1); return new Location(plot.world, bot.getX() + (top.getX() - bot.getX()) / 2, 0, bot.getZ() + (top.getZ() - bot.getZ()) / 2); } public static List getPlotsBySearch(String search) { String[] split = search.split(" "); int size = split.length * 2; List uuids = new ArrayList<>(); PlotId id = null; String world = null; String alias = null; for (String term : split) { try { UUID uuid = UUIDHandler.getUUID(term, null); if (uuid == null) { uuid = UUID.fromString(term); } if (uuid != null) { uuids.add(uuid); continue; } } catch (Exception e) { id = PlotId.fromString(term); if (id != null) { continue; } for (String pw : PS.get().getPlotWorlds()) { if (pw.equalsIgnoreCase(term)) { world = pw; break; } } if (world == null) { alias = term; } } } ArrayList> plotList = new ArrayList<>(size); for (int i = 0; i < size; i++) { plotList.add(new ArrayList()); } for (Plot plot : PS.get().getPlots()) { int count = 0; if (uuids.size() > 0) { for (UUID uuid : uuids) { if (plot.isOwner(uuid)) { count += 2; } else if (plot.isAdded(uuid)) { count++; } } } if (id != null) { if (plot.id.equals(id)) { count++; } } if (world != null && plot.world.equals(world)) { count++; } if (alias != null && alias.equals(plot.getSettings().getAlias())) { count+=2; } if (count != 0) { plotList.get(count - 1).add(plot); } } List plots = new ArrayList(); for (int i = plotList.size() - 1; i >= 0; i--) { if (plotList.get(i).size() > 0) { plots.addAll(plotList.get(i)); } } return plots; } public static Plot getPlotFromString(PlotPlayer player, String arg, boolean message) { if (arg == null) { if (player == null) { if (message) MainUtil.sendMessage(player, C.NOT_VALID_PLOT_WORLD); return null; } return getPlot(player.getLocation()); } String worldname = null; PlotId id = null; if (player != null) { worldname = player.getLocation().getWorld(); } String[] split = arg.split(";|,"); if (split.length == 3) { worldname = split[0]; id = PlotId.fromString(split[1] + ";" + split[2]); } else if (split.length == 2) { id = PlotId.fromString(arg); } else { if (worldname == null) { if (PS.get().getPlotWorlds().size() == 0) { if (message) MainUtil.sendMessage(player, C.NOT_VALID_PLOT_WORLD); return null; } worldname = PS.get().getPlotWorlds().iterator().next(); } for (Plot p : PS.get().getPlotsInWorld(worldname)) { String name = p.getSettings().getAlias(); if (name.length() != 0 && name.equalsIgnoreCase(arg)) { return p; } } for (String world : PS.get().getPlotWorlds()) { if (!world.endsWith(worldname)) { for (Plot p : PS.get().getPlotsInWorld(world)) { String name = p.getSettings().getAlias(); if (name.length() != 0 && name.equalsIgnoreCase(arg)) { return p; } } } } } if (worldname == null || !PS.get().isPlotWorld(worldname)) { if (message) MainUtil.sendMessage(player, C.NOT_VALID_PLOT_WORLD); return null; } if (id == null) { if (message) MainUtil.sendMessage(player, C.NOT_VALID_PLOT_ID); return null; } return getPlot(worldname, id); } /** * Merges all plots in the arraylist (with cost) * * @param world * @param plotIds * * @return boolean */ public static boolean mergePlots(final PlotPlayer player, final String world, final ArrayList plotIds) { final PlotWorld plotworld = PS.get().getPlotWorld(world); if ((EconHandler.manager != null) && plotworld.USE_ECONOMY) { final double cost = plotIds.size() * plotworld.MERGE_PRICE; if (cost > 0d) { if (EconHandler.manager.getMoney(player) < cost) { MainUtil.sendMessage(player, C.CANNOT_AFFORD_MERGE, "" + cost); return false; } EconHandler.manager.withdrawMoney(player, cost); MainUtil.sendMessage(player, C.REMOVED_BALANCE, cost + ""); } } return MainUtil.mergePlots(world, plotIds, true, true); } public static boolean unlinkPlot(final Plot plot, boolean createRoad) { final String world = plot.world; final PlotId pos1 = MainUtil.getBottomPlot(plot).id; final PlotId pos2 = MainUtil.getTopPlot(plot).id; final ArrayList ids = MainUtil.getPlotSelectionIds(pos1, pos2); final boolean result = EventUtil.manager.callUnlink(world, ids); if (!result) { return false; } final PlotManager manager = PS.get().getPlotManager(world); final PlotWorld plotworld = PS.get().getPlotWorld(world); manager.startPlotUnlink(plotworld, ids); for (final PlotId id : ids) { final Plot myplot = PS.get().getPlot(world, id); if (plot == null) { continue; } if (plot.trusted != null) { myplot.trusted = plot.trusted; } if (plot.denied != null) { myplot.denied = plot.denied; } myplot.getSettings().setMerged(new boolean[] { false, false, false, false }); DBFunc.setMerged(myplot, myplot.getSettings().getMerged()); } if (plotworld.TERRAIN != 3 && createRoad) { for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final boolean lx = x < pos2.x; final boolean ly = y < pos2.y; final Plot p = MainUtil.getPlot(world, new PlotId(x, y)); if (lx) { manager.createRoadEast(plotworld, p); if (ly) { manager.createRoadSouthEast(plotworld, p); } } if (ly) { manager.createRoadSouth(plotworld, p); } MainUtil.setSign(UUIDHandler.getName(plot.owner), plot); } } } manager.finishPlotUnlink(plotworld, ids); for (final PlotId id : ids) { final Plot myPlot = MainUtil.getPlot(world, id); if (plot.hasOwner()) { final String name = UUIDHandler.getName(myPlot.owner); if (name != null) { MainUtil.setSign(name, myPlot); } } } return true; } public static boolean isPlotAreaAbs(final Location location) { final PlotWorld plotworld = PS.get().getPlotWorld(location.getWorld()); if (plotworld == null) { return false; } if (plotworld.TYPE == 2) { return ClusterManager.getClusterAbs(location) != null; } return true; } public static boolean isPlotRoad(final Location location) { final PlotWorld plotworld = PS.get().getPlotWorld(location.getWorld()); if (plotworld.TYPE == 2) { PlotCluster cluster = ClusterManager.getCluster(location); if (cluster == null) { return false; } } PlotManager manager = PS.get().getPlotManager(location.getWorld()); return manager.getPlotId(plotworld, location.getX(), location.getY(), location.getZ()) == null; } public static boolean isPlotArea(final Plot plot) { final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); if (plotworld.TYPE == 2) { return plot.getCluster() != null; } return true; } public static boolean enteredPlot(final Location l1, final Location l2) { final PlotId p1 = MainUtil.getPlotId(l1); final PlotId p2 = MainUtil.getPlotId(l2); return (p2 != null) && ((p1 == null) || !p1.equals(p2)); } public static boolean leftPlot(final Location l1, final Location l2) { final PlotId p1 = MainUtil.getPlotId(l1); final PlotId p2 = MainUtil.getPlotId(l2); return (p1 != null) && ((p2 == null) || !p1.equals(p2)); } public static ArrayList getMaxPlotSelectionIds(final String world, PlotId pos1, PlotId pos2) { final Plot plot1 = PS.get().getPlot(world, pos1); final Plot plot2 = PS.get().getPlot(world, pos2); if (plot1 != null) { pos1 = getBottomPlot(plot1).id; } if (plot2 != null) { pos2 = getTopPlot(plot2).id; } final ArrayList myplots = new ArrayList<>(); for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { myplots.add(new PlotId(x, y)); } } return myplots; } public static boolean equals(Object a, Object b) { if (a == b) { return true; } if (a == null ^ b == null) { return false; } return a.equals(b); } /** * Get the number of plots for a player * * @param plr * * @return int plot count */ public static int getPlayerPlotCount(final String world, final PlotPlayer plr) { final UUID uuid = plr.getUUID(); int count = 0; for (final Plot plot : PS.get().getPlotsInWorld(world)) { if (plot.hasOwner() && plot.owner.equals(uuid) && (!Settings.DONE_COUNTS_TOWARDS_LIMIT || !plot.getSettings().flags.containsKey("done"))) { count++; } } return count; } /** * Get a player's total number of plots that count towards their limit * @param plr * @return */ public static int getPlayerPlotCount(final PlotPlayer plr) { int count = 0; for (final String world : PS.get().getPlotWorldsString()) { count += getPlayerPlotCount(world, plr); } return count; } public static Location getDefaultHome(Plot plot) { PlotWorld plotworld = PS.get().getPlotWorld(plot.world); if (plotworld.DEFAULT_HOME != null) { final Location bot = getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); final PlotManager manager = PS.get().getPlotManager(plot.world); final int x; final int z; if (plotworld.DEFAULT_HOME.x == Integer.MAX_VALUE && plotworld.DEFAULT_HOME.z == Integer.MAX_VALUE) { final Location top = getPlotTopLoc(plot.world, plot.id); x = ((top.getX() - bot.getX()) / 2) + bot.getX(); z = ((top.getZ() - bot.getZ()) / 2) + bot.getZ(); } else { x = bot.getX() + plotworld.DEFAULT_HOME.x; z = bot.getZ() + plotworld.DEFAULT_HOME.z; } final int y = Math.max(getHeighestBlock(plot.world, x, z), manager.getSignLoc(PS.get().getPlotWorld(plot.world), plot).getY()); return new Location(plot.world, x, y + 1, z); } final Location top = getPlotTopLoc(plot.world, plot.id); final Location bot = getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); final int x = ((top.getX() - bot.getX()) / 2) + bot.getX(); final int z = bot.getZ(); PlotManager manager = PS.get().getPlotManager(plot.world); final int y = Math.max(getHeighestBlock(plot.world, x, z), manager.getSignLoc(PS.get().getPlotWorld(plot.world), plot).getY()); return new Location(plot.world, x, y + 1, z - 1); } public static boolean teleportPlayer(final PlotPlayer player, final Location from, final Plot plot) { final Plot bot = MainUtil.getBottomPlot(plot); boolean result = EventUtil.manager.callTeleport(player, from, plot); if (result) { final Location location; if (PS.get().getPlotWorld(plot.world).HOME_ALLOW_NONMEMBER || plot.isAdded(player.getUUID())) { location = MainUtil.getPlotHome(bot); } else { location = getDefaultHome(plot); } if ((Settings.TELEPORT_DELAY == 0) || Permissions.hasPermission(player, "plots.teleport.delay.bypass")) { sendMessage(player, C.TELEPORTED_TO_PLOT); player.teleport(location); return true; } sendMessage(player, C.TELEPORT_IN_SECONDS, Settings.TELEPORT_DELAY + ""); final String name = player.getName(); TaskManager.TELEPORT_QUEUE.add(name); TaskManager.runTaskLater(new Runnable() { @Override public void run() { if (!TaskManager.TELEPORT_QUEUE.contains(name)) { sendMessage(player, C.TELEPORT_FAILED); return; } TaskManager.TELEPORT_QUEUE.remove(name); if (!player.isOnline()) { return; } sendMessage(player, C.TELEPORTED_TO_PLOT); player.teleport(location); } }, Settings.TELEPORT_DELAY * 20); return true; } return result; } public static int getBorder(final String worldname) { if (worldBorder.containsKey(worldname)) { int border = worldBorder.get(worldname) + 16; if (border == 0) { return Integer.MAX_VALUE; } else { return border; } } return Integer.MAX_VALUE; } public static void setupBorder(final String world) { final PlotWorld plotworld = PS.get().getPlotWorld(world); if (!plotworld.WORLD_BORDER) { return; } if (!worldBorder.containsKey(world)) { worldBorder.put(world, 0); } for (final Plot plot : PS.get().getPlotsInWorld(world)) { updateWorldBorder(plot); } } public static void update(String world, ChunkLoc loc) { BlockUpdateUtil.setBlockManager.update(world, Arrays.asList(loc)); } public static void update(final Plot plot) { Location bot = getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); Location top = getPlotTopLoc(plot.world, plot.id); int bx = bot.getX() >> 4; int bz = bot.getZ() >> 4; int tx = (top.getX() >> 4); int tz = (top.getZ() >> 4); ArrayList chunks = new ArrayList<>(); for (int x = bx; x <= tx; x++) { for (int z = bz; z <= tz; z++) { chunks.add(new ChunkLoc(x, z)); } } BlockUpdateUtil.setBlockManager.update(plot.world, chunks); } public static void createWorld(final String world, final String generator) { } public static PlotId parseId(final String arg) { try { final String[] split = arg.split(";"); return new PlotId(Integer.parseInt(split[0]), Integer.parseInt(split[1])); } catch (final Exception e) { return null; } } /** * direction 0 = north, 1 = south, etc: * * @param id * @param direction * * @return PlotId relative */ public static PlotId getPlotIdRelative(final PlotId id, final int direction) { switch (direction) { case 0: return new PlotId(id.x, id.y - 1); case 1: return new PlotId(id.x + 1, id.y); case 2: return new PlotId(id.x, id.y + 1); case 3: return new PlotId(id.x - 1, id.y); } return id; } /** * Get a list of plot ids within a selection * @param pos1 * @param pos2 * @return */ public static ArrayList getPlotSelectionIds(final PlotId pos1, final PlotId pos2) { final ArrayList myplots = new ArrayList<>(); for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { myplots.add(new PlotId(x, y)); } } return myplots; } /** * Get a set of owned plots within a selection (chooses the best algorithm based on selection size.
* i.e. A selection of billions of plots will work fine * @param pos1 * @param pos2 * @return */ public static HashSet getPlotSelectionOwned(String world, final PlotId pos1, final PlotId pos2) { int size = (1 + pos2.x - pos1.x) * (1 + pos2.y - pos1.y); HashSet result = new HashSet<>(); if (PS.get().isPlotWorld(world)) { if (size < PS.get().getAllPlotsRaw().get(world).size()) { for (PlotId pid : MainUtil.getPlotSelectionIds(pos1, pos2)) { Plot plot = MainUtil.getPlot(world, pid); if (plot.hasOwner()) { if (plot.id.x > pos1.x || plot.id.y > pos1.y || plot.id.x < pos2.x || plot.id.y < pos2.y) { result.add(plot); } } } } else { for (Plot plot : PS.get().getPlotsInWorld(world)) { if (plot.id.x > pos1.x || plot.id.y > pos1.y || plot.id.x < pos2.x || plot.id.y < pos2.y) { result.add(plot); } } } } return result; } /** * Completely merges a set of plots
(There are no checks to make sure you supply the correct * arguments)
- Misuse of this method can result in unusable plots
- the set of plots must belong to one * owner and be rectangular
- the plot array must be sorted in ascending order
- Road will be removed where * required
- changes will be saved to DB
* * @param world * @param plotIds * * @return boolean (success) */ public static boolean mergePlots(final String world, final ArrayList plotIds, final boolean removeRoads, final boolean updateDatabase) { if (plotIds.size() < 2) { return false; } // merged plots set db before finished merging final PlotId pos1 = plotIds.get(0); final PlotId pos2 = plotIds.get(plotIds.size() - 1); final PlotManager manager = PS.get().getPlotManager(world); final PlotWorld plotworld = PS.get().getPlotWorld(world); boolean result = EventUtil.manager.callMerge(world, getPlot(world, pos1), plotIds); if (!result) { return false; } HashSet trusted = new HashSet(); HashSet members = new HashSet(); HashSet denied = new HashSet(); manager.startPlotMerge(plotworld, plotIds); for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final PlotId id = new PlotId(x, y); final Plot plot = PS.get().getPlot(world, id); trusted.addAll(plot.getTrusted()); members.addAll(plot.getMembers()); denied.addAll(plot.getDenied()); if (removeRoads) { removeSign(plot); } } } members.removeAll(trusted); denied.removeAll(trusted); denied.removeAll(members); for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final boolean lx = x < pos2.x; final boolean ly = y < pos2.y; final PlotId id = new PlotId(x, y); final Plot plot = PS.get().getPlot(world, id); plot.setTrusted(trusted); plot.setMembers(members); plot.setDenied(denied); Plot plot2 = null; if (lx) { if (ly) { if (!plot.getSettings().getMerged(1) || !plot.getSettings().getMerged(2)) { if (removeRoads) { MainUtil.removeRoadSouthEast(plotworld, plot); } } } if (!plot.getSettings().getMerged(1)) { plot2 = PS.get().getPlot(world, new PlotId(x + 1, y)); mergePlot(world, plot, plot2, removeRoads); plot.getSettings().setMerged(1, true); plot2.getSettings().setMerged(3, true); } } if (ly) { if (!plot.getSettings().getMerged(2)) { plot2 = PS.get().getPlot(world, new PlotId(x, y + 1)); mergePlot(world, plot, plot2, removeRoads); plot.getSettings().setMerged(2, true); plot2.getSettings().setMerged(0, true); } } } } manager.finishPlotMerge(plotworld, plotIds); if (updateDatabase) { for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final PlotId id = new PlotId(x, y); final Plot plot = PS.get().getPlot(world, id); DBFunc.setMerged(plot, plot.getSettings().getMerged()); } } } return true; } public static void removeRoadSouthEast(PlotWorld plotworld, Plot plot) { if (plotworld.TYPE != 0 && plotworld.TERRAIN > 1) { if (plotworld.TERRAIN == 3) { return; } PlotId id = plot.id; PlotId id2 = new PlotId(id.x + 1, id.y + 1); Location pos1 = getPlotTopLocAbs(plot.world, id).add(1, 0, 1); Location pos2 = getPlotBottomLocAbs(plot.world, id2); pos1.setY(0); pos2.setY(256); ChunkManager.manager.regenerateRegion(pos1, pos2, null); } else { PS.get().getPlotManager(plot.world).removeRoadSouthEast(plotworld, plot); } } public static void removeRoadEast(PlotWorld plotworld, Plot plot) { if (plotworld.TYPE != 0 && plotworld.TERRAIN > 1) { if (plotworld.TERRAIN == 3) { return; } PlotId id = plot.id; PlotId id2 = new PlotId(id.x + 1, id.y); Location bot = getPlotBottomLocAbs(plot.world, id2); Location top = getPlotTopLocAbs(plot.world, id); Location pos1 = new Location(plot.world, top.getX() + 1, 0, bot.getZ() + 1); Location pos2 = new Location(plot.world, bot.getX(), 256, top.getZ()); ChunkManager.manager.regenerateRegion(pos1, pos2, null); } else { PS.get().getPlotManager(plot.world).removeRoadEast(plotworld, plot); } } public static void removeRoadSouth(PlotWorld plotworld, Plot plot) { if (plotworld.TYPE != 0 && plotworld.TERRAIN > 1) { if (plotworld.TERRAIN == 3) { return; } PlotId id = plot.id; PlotId id2 = new PlotId(id.x, id.y + 1); Location bot = getPlotBottomLocAbs(plot.world, id2); Location top = getPlotTopLocAbs(plot.world, id); Location pos1 = new Location(plot.world, bot.getX() + 1, 0, top.getZ() + 1); Location pos2 = new Location(plot.world, top.getX(), 256, bot.getZ()); ChunkManager.manager.regenerateRegion(pos1, pos2, null); } else { PS.get().getPlotManager(plot.world).removeRoadSouth(plotworld, plot); } } /** * Merges 2 plots Removes the road inbetween
- Assumes the first plot parameter is lower
- Assumes neither * are a Mega-plot
- Assumes plots are directly next to each other
- Does not save to DB * * @param world * @param lesserPlot * @param greaterPlot */ public static void mergePlot(final String world, final Plot lesserPlot, final Plot greaterPlot, final boolean removeRoads) { final PlotWorld plotworld = PS.get().getPlotWorld(world); if (lesserPlot.id.x.equals(greaterPlot.id.x)) { if (!lesserPlot.getSettings().getMerged(2)) { lesserPlot.getSettings().setMerged(2, true); greaterPlot.getSettings().setMerged(0, true); if (removeRoads) { MainUtil.removeRoadSouth(plotworld, lesserPlot); } } } else { if (!lesserPlot.getSettings().getMerged(1)) { lesserPlot.getSettings().setMerged(1, true); greaterPlot.getSettings().setMerged(3, true); if (removeRoads) { MainUtil.removeRoadEast(plotworld, lesserPlot); } } } } public static void removeSign(final Plot p) { if (!PS.get().isMainThread(Thread.currentThread())) { TaskManager.runTask(new Runnable() { @Override public void run() { removeSign(p); } }); return; } final String world = p.world; final PlotManager manager = PS.get().getPlotManager(world); final PlotWorld plotworld = PS.get().getPlotWorld(world); if (!plotworld.ALLOW_SIGNS) { return; } final Location loc = manager.getSignLoc(plotworld, p); BlockManager.setBlocks(world, new int[]{loc.getX()}, new int[]{loc.getY()}, new int[]{loc.getZ()}, new int[]{0}, new byte[]{0}); } public static void setSign(final Plot p) { if (p.owner == null) { setSign(null, p); return; } setSign(UUIDHandler.getName(p.owner), p); } public static void setSign(final String name, final Plot p) { if (!PS.get().isMainThread(Thread.currentThread())) { TaskManager.runTask(new Runnable() { @Override public void run() { setSign(name, p); } }); return; } String rename = name == null ? "unknown" : name; final PlotManager manager = PS.get().getPlotManager(p.world); final PlotWorld plotworld = PS.get().getPlotWorld(p.world); if (plotworld.ALLOW_SIGNS) { final Location loc = manager.getSignLoc(plotworld, p); final String id = p.id.x + ";" + p.id.y; final String[] lines = new String[] { C.OWNER_SIGN_LINE_1.formatted().replaceAll("%id%", id), C.OWNER_SIGN_LINE_2.formatted().replaceAll("%id%", id).replaceAll("%plr%", rename), C.OWNER_SIGN_LINE_3.formatted().replaceAll("%id%", id).replaceAll("%plr%", rename), C.OWNER_SIGN_LINE_4.formatted().replaceAll("%id%", id).replaceAll("%plr%", rename) }; BlockManager.setSign(p.world, loc.getX(), loc.getY(), loc.getZ(), lines); } } public static String getStringSized(final int max, final String string) { if (string.length() > max) { return string.substring(0, max); } return string; } public static void autoMerge(final Plot plot, final UUID uuid, boolean removeRoads) { if (plot == null) { return; } if (plot.owner == null) { return; } if (!plot.owner.equals(uuid)) { return; } ArrayList plots; boolean merge = true; int count = 0; ArrayList toUpdate = new ArrayList<>(); while (merge) { if (count > 16) { break; } merge = false; count++; final PlotId bot = getBottomPlot(plot).id; final PlotId top = getTopPlot(plot).id; plots = getPlotSelectionIds(new PlotId(bot.x, bot.y - 1), new PlotId(top.x, top.y)); if (ownsPlots(plot.world, plots, uuid, 0)) { final boolean result = mergePlots(plot.world, plots, removeRoads, false); if (result) { toUpdate.addAll(plots); merge = true; continue; } } plots = getPlotSelectionIds(new PlotId(bot.x, bot.y), new PlotId(top.x + 1, top.y)); if (ownsPlots(plot.world, plots, uuid, 1)) { final boolean result = mergePlots(plot.world, plots, removeRoads, false); if (result) { toUpdate.addAll(plots); merge = true; continue; } } plots = getPlotSelectionIds(new PlotId(bot.x, bot.y), new PlotId(top.x, top.y + 1)); if (ownsPlots(plot.world, plots, uuid, 2)) { final boolean result = mergePlots(plot.world, plots, removeRoads, false); if (result) { toUpdate.addAll(plots); merge = true; continue; } } plots = getPlotSelectionIds(new PlotId(bot.x - 1, bot.y), new PlotId(top.x, top.y)); if (ownsPlots(plot.world, plots, uuid, 3)) { final boolean result = mergePlots(plot.world, plots, removeRoads, false); if (result) { toUpdate.addAll(plots); merge = true; continue; } } } for (PlotId id : toUpdate) { DBFunc.setMerged(plot, plot.getSettings().getMerged()); } } private static boolean ownsPlots(final String world, final ArrayList plots, final UUID uuid, final int dir) { final PlotId id_min = plots.get(0); final PlotId id_max = plots.get(plots.size() - 1); for (final PlotId myid : plots) { final Plot myplot = PS.get().getPlot(world, myid); if ((myplot == null) || myplot.owner == null || !(myplot.owner.equals(uuid))) { return false; } final PlotId top = getTopPlot(myplot).id; if (((top.x > id_max.x) && (dir != 1)) || ((top.y > id_max.y) && (dir != 2))) { return false; } final PlotId bot = getBottomPlot(myplot).id; if (((bot.x < id_min.x) && (dir != 3)) || ((bot.y < id_min.y) && (dir != 0))) { return false; } } return true; } public static void updateWorldBorder(final Plot plot) { if (!worldBorder.containsKey(plot.world)) { return; } final String world = plot.world; final PlotManager manager = PS.get().getPlotManager(world); final PlotWorld plotworld = PS.get().getPlotWorld(world); PlotId id = new PlotId(Math.abs(plot.id.x) + 1, Math.abs(plot.id.x) + 1); final Location bot = manager.getPlotBottomLocAbs(plotworld, id); final Location top = manager.getPlotTopLocAbs(plotworld, id); final int border = worldBorder.get(plot.world); final int botmax = Math.max(Math.abs(bot.getX()), Math.abs(bot.getZ())); final int topmax = Math.max(Math.abs(top.getX()), Math.abs(top.getZ())); final int max = Math.max(botmax, topmax); if (max > border) { worldBorder.put(plot.world, max); } } /** * Create a plot and notify the world border and plot merger */ public static boolean createPlot(final UUID uuid, final Plot plot) { if (MainUtil.worldBorder.containsKey(plot.world)) { updateWorldBorder(plot); } final String w = plot.world; if (PS.get().getPlot(plot.world, plot.id) != null) { return true; } final Plot p = new Plot(w, plot.id, uuid); if (p.owner == null) { return false; } PS.get().updatePlot(p); DBFunc.createPlotAndSettings(p, new Runnable() { @Override public void run() { final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); if (plotworld.AUTO_MERGE) { autoMerge(p, uuid, true); } } }); return true; } /** * Create a plot without notifying the merge function or world border manager */ public static Plot createPlotAbs(final UUID uuid, final Plot plot) { final String w = plot.world; Plot p = PS.get().getPlot(plot.world, plot.id); if (p != null) { return p; } p = new Plot(w, plot.id, uuid); if (p.owner == null) { return null; } PS.get().updatePlot(p); DBFunc.createPlotAndSettings(p, null); return p; } public static String createId(final int x, final int z) { return x + ";" + z; } public static int square(final int x) { return x * x; } public static short[] getBlock(final String block) { if (block.contains(":")) { final String[] split = block.split(":"); return new short[] { Short.parseShort(split[0]), Short.parseShort(split[1]) }; } return new short[] { Short.parseShort(block), 0 }; } /** * Clear a plot and associated sections: [sign, entities, border] * * @param plot * @param isDelete * @param whenDone */ public static boolean clearAsPlayer(final Plot plot, final boolean isDelete, final Runnable whenDone) { if (runners.containsKey(plot)) { return false; } long start = System.currentTimeMillis(); ChunkManager.manager.clearAllEntities(plot.getBottom(), plot.getTop()); if (isDelete) { removeSign(plot); } clear(plot, isDelete, whenDone); return true; } public static void clear(final Plot plot, final boolean isDelete, final Runnable whenDone) { final PlotManager manager = PS.get().getPlotManager(plot.world); final Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); final int prime = 31; int h = 1; h = (prime * h) + pos1.getX(); h = (prime * h) + pos1.getZ(); state = h; System.currentTimeMillis(); final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); runners.put(plot, 1); final Runnable run = new Runnable() { @Override public void run() { if (isDelete) { manager.unclaimPlot(plotworld, plot, new Runnable() { @Override public void run() { runners.remove(plot); TaskManager.runTask(whenDone); } }); } else { runners.remove(plot); TaskManager.runTask(whenDone); } } }; if (plotworld.TERRAIN != 0 || Settings.FAST_CLEAR) { final Location pos2 = MainUtil.getPlotTopLoc(plot.world, plot.id); ChunkManager.manager.regenerateRegion(pos1, pos2, run); return; } manager.clearPlot(plotworld, plot, run); } public static void setCuboid(final String world, final Location pos1, final Location pos2, final PlotBlock[] blocks) { if (blocks.length == 1) { setSimpleCuboid(world, pos1, pos2, blocks[0]); return; } final int length = (pos2.getX() - pos1.getX()) * (pos2.getY() - pos1.getY()) * (pos2.getZ() - pos1.getZ()); final int[] xl = new int[length]; final int[] yl = new int[length]; final int[] zl = new int[length]; final int[] ids = new int[length]; final byte[] data = new byte[length]; int index = 0; for (int y = pos1.getY(); y < pos2.getY(); y++) { for (int x = pos1.getX(); x < pos2.getX(); x++) { for (int z = pos1.getZ(); z < pos2.getZ(); z++) { final int i = random.random(blocks.length); xl[index] = x; yl[index] = y; zl[index] = z; final PlotBlock block = blocks[i]; ids[index] = block.id; data[index] = block.data; index++; } } } BlockManager.setBlocks(world, xl, yl, zl, ids, data); } public static void setCuboidAsync(final String world, final Location pos1, final Location pos2, final PlotBlock[] blocks) { if (blocks.length == 1) { setSimpleCuboidAsync(world, pos1, pos2, blocks[0]); return; } for (int y = pos1.getY(); y < Math.min(256, pos2.getY()); y++) { for (int x = pos1.getX(); x < pos2.getX(); x++) { for (int z = pos1.getZ(); z < pos2.getZ(); z++) { final int i = random.random(blocks.length); final PlotBlock block = blocks[i]; SetBlockQueue.setBlock(world, x, y, z, block); } } } } public static void setSimpleCuboid(final String world, final Location pos1, final Location pos2, final PlotBlock newblock) { final int length = (pos2.getX() - pos1.getX()) * (pos2.getY() - pos1.getY()) * (pos2.getZ() - pos1.getZ()); final int[] xl = new int[length]; final int[] yl = new int[length]; final int[] zl = new int[length]; final int[] ids = new int[length]; final byte[] data = new byte[length]; int index = 0; for (int y = pos1.getY(); y < pos2.getY(); y++) { for (int x = pos1.getX(); x < pos2.getX(); x++) { for (int z = pos1.getZ(); z < pos2.getZ(); z++) { xl[index] = x; yl[index] = y; zl[index] = z; ids[index] = newblock.id; data[index] = newblock.data; index++; } } } BlockManager.setBlocks(world, xl, yl, zl, ids, data); } public static void setSimpleCuboidAsync(final String world, final Location pos1, final Location pos2, final PlotBlock newblock) { for (int y = pos1.getY(); y < Math.min(256, pos2.getY()); y++) { for (int x = pos1.getX(); x < pos2.getX(); x++) { for (int z = pos1.getZ(); z < pos2.getZ(); z++) { SetBlockQueue.setBlock(world, x, y, z, newblock); } } } } public static void setBiome(final Plot plot, final String biome, final Runnable whenDone) { Location pos1 = plot.getBottom(); Location pos2 = plot.getTop(); ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { @Override public void run() { ChunkLoc loc = new ChunkLoc(value[0], value[1]); ChunkManager.manager.loadChunk(plot.world, loc, false); setBiome(plot.world, value[2], value[3], value[4], value[5], biome); ChunkManager.manager.unloadChunk(plot.world, loc, true, true); } }, new Runnable() { @Override public void run() { update(plot); TaskManager.runTask(whenDone); } }, 5); } public static void setBiome(final String world, int p1x, int p1z, int p2x, int p2z, final String biome) { final int length = (p2x - p1x + 1) * (p2z - p1z + 1); final int[] xl = new int[length]; final int[] zl = new int[length]; int index = 0; for (int x = p1x; x <= p2x; x++) { for (int z = p1z; z <= p2z; z++) { xl[index] = x; zl[index] = z; index++; } } BlockManager.setBiomes(world, xl, zl, biome); } public static int getHeighestBlock(final String world, final int x, final int z) { final int result = BlockManager.manager.getHeighestBlock(world, x, z); if (result == 0) { return 64; } return result; } /** * Get plot home * * @param w World in which the plot is located * @param plotid Plot ID * * @return Home Location */ public static Location getPlotHome(final String w, final PlotId plotid) { final Plot plot = getPlot(w, plotid); final BlockLoc home = plot.getSettings().getPosition(); final Location bot = getPlotBottomLoc(w, plotid); final PlotManager manager = PS.get().getPlotManager(w); if ((home == null) || ((home.x == 0) && (home.z == 0))) { return getDefaultHome(plot); } else { Location loc = new Location(bot.getWorld(), bot.getX() + home.x, bot.getY() + home.y, bot.getZ() + home.z); if (BlockManager.manager.getBlock(loc).id != 0) { // sendConsoleMessage("ID was " + BukkitUtil.getBlock(loc).id); loc.setY(Math.max(getHeighestBlock(w, loc.getX(), loc.getZ()), bot.getY())); } return loc; } } /** * Get the plot home * * @param plot Plot Object * * @return Plot Home Location * */ public static Location getPlotHome(final Plot plot) { return getPlotHome(plot.world, plot.id); } /** * Gets the top plot location of a plot (all plots are treated as small plots) - To get the top loc of a mega plot * use getPlotTopLoc(...) * * @param world * @param id * * @return Location top */ public static Location getPlotTopLocAbs(final String world, final PlotId id) { final PlotWorld plotworld = PS.get().getPlotWorld(world); final PlotManager manager = PS.get().getPlotManager(world); return manager.getPlotTopLocAbs(plotworld, id); } /** * Gets the bottom plot location of a plot (all plots are treated as small plots) - To get the top loc of a mega * plot use getPlotBottomLoc(...) * * @param world * @param id * * @return Location bottom */ public static Location getPlotBottomLocAbs(final String world, final PlotId id) { final PlotWorld plotworld = PS.get().getPlotWorld(world); final PlotManager manager = PS.get().getPlotManager(world); return manager.getPlotBottomLocAbs(plotworld, id); } /** * Obtains the width of a plot (x width) * * @param world * @param id * * @return int width of plot */ public static int getPlotWidth(final String world, final PlotId id) { return getPlotTopLoc(world, id).getX() - getPlotBottomLoc(world, id).getX(); } /** * Gets the top loc of a plot (if mega, returns top loc of that mega plot) - If you would like each plot treated as * a small plot use getPlotTopLocAbs(...) * * @param world * @param id * * @return Location top of mega plot */ public static Location getPlotTopLoc(final String world, PlotId id) { final Plot plot = PS.get().getPlot(world, id); if (plot != null) { id = getTopPlot(plot).id; } final PlotWorld plotworld = PS.get().getPlotWorld(world); final PlotManager manager = PS.get().getPlotManager(world); return manager.getPlotTopLocAbs(plotworld, id); } /** * Gets the bottom loc of a plot (if mega, returns bottom loc of that mega plot) - If you would like each plot * treated as a small plot use getPlotBottomLocAbs(...) * * @param world * @param id * * @return Location bottom of mega plot * * @deprecated Incorrect offset / legacy / use plot.getBottom() * */ @Deprecated public static Location getPlotBottomLoc(final String world, PlotId id) { final Plot plot = PS.get().getPlot(world, id); if (plot != null) { id = getBottomPlot(plot).id; } final PlotWorld plotworld = PS.get().getPlotWorld(world); final PlotManager manager = PS.get().getPlotManager(world); return manager.getPlotBottomLocAbs(plotworld, id); } public static boolean canClaim(PlotPlayer player, String world, final PlotId pos1, final PlotId pos2) { for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final PlotId id = new PlotId(x, y); Plot plot = getPlot(world, id); if (!canClaim(player, plot)) { return false; } } } return true; } public static boolean canClaim(PlotPlayer player, Plot plot) { if (plot == null) { return false; } if (Settings.ENABLE_CLUSTERS) { PlotCluster cluster = plot.getCluster(); if (cluster != null) { if (!cluster.isAdded(player.getUUID()) && !Permissions.hasPermission(player, "plots.admin.command.claim")) { return false; } } } return plot.owner == null; } public static boolean isUnowned(final String world, final PlotId pos1, final PlotId pos2) { for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final PlotId id = new PlotId(x, y); if (PS.get().getPlot(world, id) != null) { if (PS.get().getPlot(world, id).owner != null) { return false; } } } } return true; } public static boolean swap(final String world, final PlotId current, final PlotId newPlot, final Runnable whenDone) { Plot p1 = PS.get().getPlot(world, current); Plot p2 = PS.get().getPlot(world, newPlot); if (p1==null || p2 == null || p1.owner == null || !p1.owner.equals(p2.owner)) { return false; } // Swap blocks ChunkManager.manager.swap(world, current, newPlot); // Swap cached PlotId temp = new PlotId(p1.id.x.intValue(), p1.id.y.intValue()); p1.id.x = p2.id.x.intValue(); p1.id.y = p2.id.y.intValue(); p2.id.x = temp.x; p2.id.y = temp.y; Map> raw = PS.get().getAllPlotsRaw(); raw.get(world).remove(p1.id); raw.get(world).remove(p2.id); p1.id.recalculateHash(); p2.id.recalculateHash(); raw.get(world).put(p1.id, p1); raw.get(world).put(p2.id, p2); // Swap database DBFunc.dbManager.swapPlots(p2, p1); return true; } public static boolean swapData(final String world, final PlotId current, final PlotId newPlot, final Runnable whenDone) { Plot p1 = PS.get().getPlot(world, current); Plot p2 = PS.get().getPlot(world, newPlot); if (p1 == null || p1.owner == null) { if (p2 != null && p2.owner != null) { moveData(p2, getPlot(world, current), whenDone); return true; } return false; } if (p2 == null || p2.owner == null) { if (p1 != null && p1.owner != null) { moveData(p1, getPlot(world, newPlot), whenDone); return true; } return false; } // Swap cached PlotId temp = new PlotId(p1.id.x.intValue(), p1.id.y.intValue()); p1.id.x = p2.id.x.intValue(); p1.id.y = p2.id.y.intValue(); p2.id.x = temp.x; p2.id.y = temp.y; Map> raw = PS.get().getAllPlotsRaw(); raw.get(world).remove(p1.id); raw.get(world).remove(p2.id); p1.id.recalculateHash(); p2.id.recalculateHash(); raw.get(world).put(p1.id, p1); raw.get(world).put(p2.id, p2); // Swap database DBFunc.dbManager.swapPlots(p2, p1); TaskManager.runTask(whenDone); return true; } public static boolean moveData(final Plot plot1, final Plot plot2, final Runnable whenDone) { if (plot1.owner == null) { PS.debug(plot2 +" is unowned (single)"); TaskManager.runTask(whenDone); return false; } final Plot pos1 = getBottomPlot(plot1); final Plot pos2 = getTopPlot(plot1); final PlotId size = MainUtil.getSize(plot1); if (!MainUtil.isUnowned(plot2.world, plot2.id, new PlotId((plot2.id.x + size.x) - 1, (plot2.id.y + size.y) - 1))) { PS.debug(plot2 +" is unowned (multi)"); TaskManager.runTask(whenDone); return false; } final int offset_x = plot2.id.x - pos1.id.x; final int offset_y = plot2.id.y - pos1.id.y; final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); for (final PlotId id : selection) { String worldOriginal = plot1.world; PlotId idOriginal = new PlotId(id.x, id.y); final Plot plot = PS.get().getPlot(plot1.world, id); Map> raw = PS.get().getAllPlotsRaw(); raw.get(plot1.world).remove(id); plot.id.x += offset_x; plot.id.y += offset_y; plot.id.recalculateHash(); raw.get(plot2.world).put(plot.id, plot); DBFunc.movePlot(getPlot(worldOriginal, idOriginal), getPlot(plot2.world, new PlotId(id.x + offset_x, id.y + offset_y))); } TaskManager.runTaskLater(whenDone, 1); return true; } public static boolean move(final Plot plot1, final Plot plot2, final Runnable whenDone) { final com.intellectualcrafters.plot.object.Location bot1 = MainUtil.getPlotBottomLoc(plot1.world, plot1.id); final com.intellectualcrafters.plot.object.Location bot2 = MainUtil.getPlotBottomLoc(plot2.world, plot2.id); final Location top = MainUtil.getPlotTopLoc(plot1.world, plot1.id); if (plot1.owner == null) { PS.debug(plot2 +" is unowned (single)"); TaskManager.runTask(whenDone); return false; } final Plot pos1 = getBottomPlot(plot1); final Plot pos2 = getTopPlot(plot1); final PlotId size = MainUtil.getSize(plot1); if (!MainUtil.isUnowned(plot2.world, plot2.id, new PlotId((plot2.id.x + size.x) - 1, (plot2.id.y + size.y) - 1))) { PS.debug(plot2 +" is unowned (multi)"); TaskManager.runTask(whenDone); return false; } final int offset_x = plot2.id.x - pos1.id.x; final int offset_y = plot2.id.y - pos1.id.y; final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); for (final PlotId id : selection) { String worldOriginal = plot1.world; PlotId idOriginal = new PlotId(id.x, id.y); final Plot plot = PS.get().getPlot(plot1.world, id); Map> raw = PS.get().getAllPlotsRaw(); raw.get(plot1.world).remove(id); plot.id.x += offset_x; plot.id.y += offset_y; plot.id.recalculateHash(); raw.get(plot2.world).put(plot.id, plot); DBFunc.movePlot(getPlot(worldOriginal, idOriginal), getPlot(plot2.world, new PlotId(id.x + offset_x, id.y + offset_y))); } ChunkManager.manager.copyRegion(bot1, top, bot2, new Runnable() { @Override public void run() { final Location bot = bot1.clone().add(1, 0, 1); ChunkManager.manager.regenerateRegion(bot, top, null); TaskManager.runTaskLater(whenDone, 1); } }); return true; } public static boolean copy(final String world, final PlotId current, final PlotId newPlot, final Runnable whenDone) { final com.intellectualcrafters.plot.object.Location bot1 = MainUtil.getPlotBottomLoc(world, current); final com.intellectualcrafters.plot.object.Location bot2 = MainUtil.getPlotBottomLoc(world, newPlot); final Location top = MainUtil.getPlotTopLoc(world, current); final Plot currentPlot = MainUtil.getPlot(world, current); if (currentPlot.owner == null) { TaskManager.runTaskLater(whenDone, 1); return false; } final Plot pos1 = getBottomPlot(currentPlot); final Plot pos2 = getTopPlot(currentPlot); final PlotId size = MainUtil.getSize(currentPlot); if (!MainUtil.isUnowned(world, newPlot, new PlotId((newPlot.x + size.x) - 1, (newPlot.y + size.y) - 1))) { TaskManager.runTaskLater(whenDone, 1); return false; } final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); final int offset_x = newPlot.x - pos1.id.x; final int offset_y = newPlot.y - pos1.id.y; for (final PlotId id : selection) { int x = id.x + offset_x; int y = id.y + offset_y; Plot plot = createPlotAbs(currentPlot.owner, getPlot(world, new PlotId(x, y))); if (currentPlot.getSettings().flags != null && currentPlot.getSettings().flags.size() > 0) { plot.getSettings().flags = currentPlot.getSettings().flags; DBFunc.setFlags(plot, currentPlot.getSettings().flags.values()); } if (currentPlot.isMerged()) { plot.getSettings().setMerged(currentPlot.getSettings().getMerged()); DBFunc.setMerged(plot, currentPlot.getSettings().getMerged()); } if (currentPlot.members != null && currentPlot.members.size() > 0) { plot.members = currentPlot.members; for (UUID member : plot.members) { DBFunc.setMember(plot, member); } } if (currentPlot.trusted != null && currentPlot.trusted.size() > 0) { plot.trusted = currentPlot.trusted; for (UUID trusted : plot.trusted) { DBFunc.setTrusted(plot, trusted); } } if (currentPlot.denied != null && currentPlot.denied.size() > 0) { plot.denied = currentPlot.denied; for (UUID denied : plot.denied) { DBFunc.setDenied(plot, denied); } } PS.get().updatePlot(plot); } ChunkManager.manager.copyRegion(bot1, top, bot2, whenDone); return true; } /** * Send a message to the player * * @param plr Player to recieve message * @param msg Message to send * * @return true Can be used in things such as commands (return PlayerFunctions.sendMessage(...)) */ public static boolean sendMessage(final PlotPlayer plr, final String msg) { return sendMessage(plr, msg, true); } public static void sendConsoleMessage(String msg) { sendMessage(null, msg); } public static void sendConsoleMessage(C caption, String... args) { sendMessage(null, caption, args); } public static boolean sendMessage(final PlotPlayer plr, String msg, final boolean prefix) { if ((msg.length() > 0) && !msg.equals("")) { if (plr == null) { PS.log((prefix ? C.PREFIX.s() : "") + msg); } else { plr.sendMessage((prefix ? C.PREFIX.s() : "") + C.color(msg)); } } return true; } public static String[] wordWrap(final String rawString, final int lineLength) { if (rawString == null) { return new String[] { "" }; } if ((rawString.length() <= lineLength) && (!rawString.contains("\n"))) { return new String[] { rawString }; } final char[] rawChars = (rawString + ' ').toCharArray(); StringBuilder word = new StringBuilder(); StringBuilder line = new StringBuilder(); final ArrayList lines = new ArrayList(); int lineColorChars = 0; for (int i = 0; i < rawChars.length; i++) { final char c = rawChars[i]; if (c == '\u00A7') { word.append('\u00A7' + (rawChars[(i + 1)])); lineColorChars += 2; i++; } else if ((c == ' ') || (c == '\n')) { if ((line.length() == 0) && (word.length() > lineLength)) { for (final String partialWord : word.toString().split("(?<=\\G.{" + lineLength + "})")) { lines.add(partialWord); } } else if (((line.length() + word.length()) - lineColorChars) == lineLength) { line.append(word); lines.add(line.toString()); line = new StringBuilder(); lineColorChars = 0; } else if (((line.length() + 1 + word.length()) - lineColorChars) > lineLength) { for (final String partialWord : word.toString().split("(?<=\\G.{" + lineLength + "})")) { lines.add(line.toString()); line = new StringBuilder(partialWord); } lineColorChars = 0; } else { if (line.length() > 0) { line.append(' '); } line.append(word); } word = new StringBuilder(); if (c == '\n') { lines.add(line.toString()); line = new StringBuilder(); } } else { word.append(c); } } if (line.length() > 0) { lines.add(line.toString()); } if ((lines.get(0).length() == 0) || (lines.get(0).charAt(0) != '\u00A7')) { lines.set(0, "\u00A7f" + lines.get(0)); } for (int i = 1; i < lines.size(); i++) { final String pLine = lines.get(i - 1); final String subLine = lines.get(i); final char color = pLine.charAt(pLine.lastIndexOf('\u00A7') + 1); if ((subLine.length() == 0) || (subLine.charAt(0) != '\u00A7')) { lines.set(i, '\u00A7' + (color) + subLine); } } return lines.toArray(new String[lines.size()]); } /** * Send a message to the player * * @param plr Player to recieve message * @param c Caption to send * * @return boolean success */ public static boolean sendMessage(final PlotPlayer plr, final C c, final String... args) { if (c.s().length() > 1) { String msg = c.s(); if ((args != null) && (args.length > 0)) { msg = C.format(c, args); } if (plr == null) { PS.log(msg); } else { sendMessage(plr, msg, c.usePrefix()); } } return true; } /** * Send a message to the player * * @param plr Player to recieve message * @param c Caption to send * * @return boolean success */ public static boolean sendMessage(final PlotPlayer plr, final C c, final Object... args) { if (c.s().length() > 1) { String msg = c.s(); if ((args != null) && (args.length > 0)) { msg = C.format(c, args); } if (plr == null) { PS.log(msg); } else { sendMessage(plr, msg, c.usePrefix()); } } return true; } public static Plot getBottomPlot(final Plot plot) { if (plot.getSettings().getMerged(0)) { final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x, plot.id.y - 1)); if (p == null) { return plot; } return getBottomPlot(p); } if (plot.getSettings().getMerged(3)) { final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x - 1, plot.id.y)); if (p == null) { return plot; } return getBottomPlot(p); } return plot; } public static Plot getTopPlot(final Plot plot) { if (plot.getSettings().getMerged(2)) { final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x, plot.id.y + 1)); if (p == null) { return plot; } return getTopPlot(p); } if (plot.getSettings().getMerged(1)) { final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x + 1, plot.id.y)); if (p == null) { return plot; } return getTopPlot(p); } return plot; } public static PlotId getSize(final Plot plot) { if (!plot.isMerged()) { return new PlotId(1, 1); } final Plot top = getTopPlot(plot); final Plot bot = getBottomPlot(plot); return new PlotId((top.id.x - bot.id.x) + 1, (top.id.y - bot.id.y) + 1); } /** * Fetches the plot from the main class */ public static Plot getPlot(final String world, final PlotId id) { if (id == null) { return null; } Plot plot = PS.get().getPlot(world, id); if (plot != null) { return plot; } return new Plot(world, id, null); } /** * Returns the plot at a location (mega plots are not considered, all plots are treated as small plots) * @param loc * @return PlotId underlying plot id of loc */ public static PlotId getPlotAbs(final Location loc) { final String world = loc.getWorld(); final PlotManager manager = PS.get().getPlotManager(world); if (manager == null) { return null; } final PlotWorld plotworld = PS.get().getPlotWorld(world); return manager.getPlotIdAbs(plotworld, loc.getX(), loc.getY(), loc.getZ()); } /** * Returns the plot id at a location (mega plots are considered) * @param loc * @return PlotId PlotId observed id */ public static PlotId getPlotId(final Location loc) { final String world = loc.getWorld(); final PlotManager manager = PS.get().getPlotManager(world); if (manager == null) { return null; } final PlotWorld plotworld = PS.get().getPlotWorld(world); final PlotId id = manager.getPlotId(plotworld, loc.getX(), loc.getY(), loc.getZ()); if ((id != null) && (plotworld.TYPE == 2)) { if (ClusterManager.getCluster(world, id) == null) { return null; } } return id; } /** * Get the maximum number of plots a player is allowed * * @param p * @return int */ public static int getAllowedPlots(final PlotPlayer p) { return Permissions.hasPermissionRange(p, "plots.plot", Settings.MAX_PLOTS); } public static Plot getPlot(final Location loc) { final PlotId id = getPlotId(loc); if (id == null) { return null; } return getPlot(loc.getWorld(), id); } public static double getAverageRating(Plot plot) { HashMap rating; if (plot.getSettings().ratings != null) { rating = plot.getSettings().ratings; } else if (Settings.CACHE_RATINGS) { rating = new HashMap<>(); } else { rating = DBFunc.getRatings(plot); } if (rating == null || rating.size() == 0) { return 0; } double val = 0; int size = 0; for (Entry entry : rating.entrySet()) { int current = entry.getValue(); if (Settings.RATING_CATEGORIES == null || Settings.RATING_CATEGORIES.size() == 0) { val += current; size++; } else { for (int i = 0 ; i < Settings.RATING_CATEGORIES.size(); i++) { val += (current % 10) - 1; current /= 10; size++; } } } return val / (double) size; } public static double[] getAverageRatings(Plot plot) { HashMap rating; if (plot.getSettings().ratings != null) { rating = plot.getSettings().ratings; } else if (Settings.CACHE_RATINGS) { rating = new HashMap<>(); } else { rating = DBFunc.getRatings(plot); } int size = 1; if (Settings.RATING_CATEGORIES != null) { size = Math.max(1, Settings.RATING_CATEGORIES.size()); } double[] ratings = new double[size]; if (rating == null || rating.size() == 0) { return ratings; } for (Entry entry : rating.entrySet()) { int current = entry.getValue(); if (Settings.RATING_CATEGORIES == null || Settings.RATING_CATEGORIES.size() == 0) { ratings[0] += current; } else { for (int i = 0 ; i < Settings.RATING_CATEGORIES.size(); i++) { ratings[i] += (current % 10) - 1; current /= 10; } } } for (int i = 0; i < size; i++) { ratings[i] /= (double) rating.size(); } return ratings; } public static void setComponent(Plot plot, String component, PlotBlock[] blocks) { PS.get().getPlotManager(plot.world).setComponent(PS.get().getPlotWorld(plot.world), plot.id, component, blocks); } }