2020-04-16 04:52:39 +02:00
|
|
|
/*
|
|
|
|
* _____ _ _ _____ _
|
|
|
|
* | __ \| | | | / ____| | |
|
|
|
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
|
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
|
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
|
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
|
|
* | |
|
|
|
|
* |_|
|
|
|
|
* PlotSquared plot management system for Minecraft
|
|
|
|
* Copyright (C) 2020 IntellectualSites
|
|
|
|
*
|
|
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-04-11 02:19:18 +02:00
|
|
|
package com.plotsquared.bukkit.util;
|
2015-02-19 07:08:15 +01:00
|
|
|
|
2020-04-11 02:19:18 +02:00
|
|
|
import com.plotsquared.bukkit.BukkitMain;
|
|
|
|
import com.plotsquared.bukkit.player.BukkitPlayer;
|
2020-05-27 14:08:48 +02:00
|
|
|
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.PlotSquared;
|
2020-04-16 06:14:33 +02:00
|
|
|
import com.plotsquared.core.configuration.Captions;
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.location.Location;
|
|
|
|
import com.plotsquared.core.player.PlotPlayer;
|
2020-04-20 23:40:04 +02:00
|
|
|
import com.plotsquared.core.plot.Plot;
|
|
|
|
import com.plotsquared.core.util.BlockUtil;
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.util.MainUtil;
|
|
|
|
import com.plotsquared.core.util.MathMan;
|
2020-05-27 14:08:48 +02:00
|
|
|
import com.plotsquared.core.util.PlayerManager;
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.util.StringComparison;
|
2020-04-20 23:40:04 +02:00
|
|
|
import com.plotsquared.core.util.WorldUtil;
|
|
|
|
import com.plotsquared.core.util.task.RunnableVal;
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.util.task.TaskManager;
|
2019-11-04 20:58:24 +01:00
|
|
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
2018-12-20 02:23:48 +01:00
|
|
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
2020-05-13 14:54:54 +02:00
|
|
|
import com.sk89q.worldedit.math.BlockVector2;
|
2019-11-10 18:47:37 +01:00
|
|
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
|
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
2020-05-13 14:11:17 +02:00
|
|
|
import com.sk89q.worldedit.world.block.BlockCategories;
|
2019-11-04 20:58:24 +01:00
|
|
|
import com.sk89q.worldedit.world.block.BlockState;
|
2020-05-13 14:11:17 +02:00
|
|
|
import com.sk89q.worldedit.world.block.BlockType;
|
|
|
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
2020-04-07 20:19:39 +02:00
|
|
|
import io.papermc.lib.PaperLib;
|
2018-08-10 20:46:38 +02:00
|
|
|
import lombok.NonNull;
|
2020-07-05 18:14:29 +02:00
|
|
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
2016-03-14 03:44:59 +01:00
|
|
|
import org.bukkit.Bukkit;
|
2020-04-07 20:19:39 +02:00
|
|
|
import org.bukkit.Chunk;
|
2016-03-14 03:44:59 +01:00
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.OfflinePlayer;
|
|
|
|
import org.bukkit.World;
|
2019-08-06 22:08:56 +02:00
|
|
|
import org.bukkit.block.Biome;
|
|
|
|
import org.bukkit.block.Block;
|
|
|
|
import org.bukkit.block.BlockFace;
|
|
|
|
import org.bukkit.block.Sign;
|
2019-04-23 23:30:31 +02:00
|
|
|
import org.bukkit.block.data.Directional;
|
2019-09-09 00:43:47 +02:00
|
|
|
import org.bukkit.block.data.type.WallSign;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.Ambient;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.Animals;
|
2020-04-12 01:23:13 +02:00
|
|
|
import org.bukkit.entity.AreaEffectCloud;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.ArmorStand;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.Boss;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.EnderCrystal;
|
2020-04-12 01:23:13 +02:00
|
|
|
import org.bukkit.entity.EnderSignal;
|
2015-02-19 11:12:26 +01:00
|
|
|
import org.bukkit.entity.Entity;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.EntityType;
|
2020-04-12 01:23:13 +02:00
|
|
|
import org.bukkit.entity.EvokerFangs;
|
|
|
|
import org.bukkit.entity.ExperienceOrb;
|
|
|
|
import org.bukkit.entity.Explosive;
|
|
|
|
import org.bukkit.entity.FallingBlock;
|
|
|
|
import org.bukkit.entity.Firework;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.Ghast;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.Hanging;
|
2020-04-12 04:46:51 +02:00
|
|
|
import org.bukkit.entity.IronGolem;
|
2020-04-12 01:23:13 +02:00
|
|
|
import org.bukkit.entity.Item;
|
|
|
|
import org.bukkit.entity.LightningStrike;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.Monster;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.NPC;
|
|
|
|
import org.bukkit.entity.Phantom;
|
2015-02-19 11:12:26 +01:00
|
|
|
import org.bukkit.entity.Player;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.Projectile;
|
2020-04-12 04:46:51 +02:00
|
|
|
import org.bukkit.entity.Shulker;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.Slime;
|
2020-04-12 04:46:51 +02:00
|
|
|
import org.bukkit.entity.Snowman;
|
2020-04-11 22:26:31 +02:00
|
|
|
import org.bukkit.entity.Tameable;
|
|
|
|
import org.bukkit.entity.Vehicle;
|
2020-04-12 00:57:50 +02:00
|
|
|
import org.bukkit.entity.WaterMob;
|
2019-09-08 20:02:45 +02:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
2018-12-20 00:26:20 +01:00
|
|
|
|
2019-08-06 22:08:56 +02:00
|
|
|
import java.util.ArrayList;
|
2020-04-11 22:26:31 +02:00
|
|
|
import java.util.Collection;
|
2019-08-06 22:08:56 +02:00
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.List;
|
2020-05-13 14:11:17 +02:00
|
|
|
import java.util.Objects;
|
2019-08-06 22:08:56 +02:00
|
|
|
import java.util.Set;
|
2020-04-07 20:19:39 +02:00
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.function.Consumer;
|
2020-04-09 11:23:39 +02:00
|
|
|
import java.util.function.IntConsumer;
|
2020-05-13 14:11:17 +02:00
|
|
|
import java.util.stream.Stream;
|
2016-03-23 02:41:37 +01:00
|
|
|
|
2020-03-15 12:22:49 +01:00
|
|
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
|
|
public class BukkitUtil extends WorldUtil {
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2020-07-05 18:14:29 +02:00
|
|
|
public static final BukkitAudiences BUKKIT_AUDIENCES = BukkitAudiences.create(BukkitMain.getPlugin(BukkitMain.class));
|
|
|
|
|
2015-02-19 07:08:15 +01:00
|
|
|
private static String lastString = null;
|
|
|
|
private static World lastWorld = null;
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2015-02-21 05:27:01 +01:00
|
|
|
private static Player lastPlayer = null;
|
2020-05-27 14:08:48 +02:00
|
|
|
private static BukkitPlayer lastPlotPlayer = null;
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2020-06-23 18:36:53 +02:00
|
|
|
public static void removePlayer(UUID uuid) {
|
2015-05-28 17:42:17 +02:00
|
|
|
lastPlayer = null;
|
|
|
|
lastPlotPlayer = null;
|
2020-06-23 18:36:53 +02:00
|
|
|
// Make sure that it's removed internally
|
|
|
|
PlotSquared.imp().getPlayerManager().removePlayer(uuid);
|
2015-02-21 05:32:01 +01:00
|
|
|
}
|
2015-10-07 08:33:33 +02:00
|
|
|
|
2020-06-22 15:45:57 +02:00
|
|
|
public static PlotPlayer<Player> getPlayer(@NonNull final OfflinePlayer op) {
|
2015-09-13 06:04:31 +02:00
|
|
|
if (op.isOnline()) {
|
|
|
|
return getPlayer(op.getPlayer());
|
|
|
|
}
|
2018-08-10 20:54:17 +02:00
|
|
|
final Player player = OfflinePlayerUtil.loadPlayer(op);
|
2015-06-23 13:13:48 +02:00
|
|
|
player.loadData();
|
2015-08-01 22:11:28 +02:00
|
|
|
return new BukkitPlayer(player, true);
|
2015-06-23 13:13:48 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-20 11:35:41 +02:00
|
|
|
/**
|
|
|
|
* Get a plot based on the location.
|
|
|
|
*
|
|
|
|
* @param location the location to check
|
|
|
|
* @return plot if found, otherwise it creates a temporary plot
|
|
|
|
* @see Plot
|
|
|
|
*/
|
|
|
|
public static Plot getPlot(org.bukkit.Location location) {
|
|
|
|
if (location == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return getLocation(location).getPlot();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a plot based on the player location.
|
|
|
|
*
|
|
|
|
* @param player the player to check
|
|
|
|
* @return plot if found, otherwise it creates a temporary plot
|
|
|
|
* @see #getPlot(org.bukkit.Location)
|
|
|
|
* @see Plot
|
|
|
|
*/
|
|
|
|
public static Plot getPlot(Player player) {
|
|
|
|
return getPlot(player.getLocation());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the PlotPlayer for an offline player.
|
2018-11-14 15:44:07 +01:00
|
|
|
*
|
2018-08-20 11:35:41 +02:00
|
|
|
* <p>Note that this will work if the player is offline, however not all
|
|
|
|
* functionality will work.
|
|
|
|
*
|
|
|
|
* @param player the player to wrap
|
|
|
|
* @return a {@code PlotPlayer}
|
|
|
|
* @see PlotPlayer#wrap(Object)
|
|
|
|
*/
|
2020-05-27 14:08:48 +02:00
|
|
|
public static PlotPlayer<?> wrapPlayer(OfflinePlayer player) {
|
2018-08-20 11:35:41 +02:00
|
|
|
return PlotPlayer.wrap(player);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the PlotPlayer for a player. The PlotPlayer is usually cached and
|
|
|
|
* will provide useful functions relating to players.
|
|
|
|
*
|
|
|
|
* @param player the player to wrap
|
|
|
|
* @return a {@code PlotPlayer}
|
|
|
|
* @see PlotPlayer#wrap(Object)
|
|
|
|
*/
|
2020-05-27 14:08:48 +02:00
|
|
|
public static PlotPlayer<?> wrapPlayer(Player player) {
|
2018-08-20 11:35:41 +02:00
|
|
|
return PlotPlayer.wrap(player);
|
|
|
|
}
|
|
|
|
|
2020-03-15 12:22:49 +01:00
|
|
|
/**
|
|
|
|
* Gets the PlotPlayer for a UUID. The PlotPlayer is usually cached and
|
|
|
|
* will provide useful functions relating to players.
|
|
|
|
*
|
|
|
|
* @param uuid the uuid to wrap
|
|
|
|
* @return a {@code PlotPlayer}
|
|
|
|
* @see PlotPlayer#wrap(Object)
|
|
|
|
*/
|
2020-05-27 14:08:48 +02:00
|
|
|
@Override public PlotPlayer<?> wrapPlayer(UUID uuid) {
|
2020-03-15 12:22:49 +01:00
|
|
|
return PlotPlayer.wrap(Bukkit.getOfflinePlayer(uuid));
|
|
|
|
}
|
|
|
|
|
2018-08-20 11:35:41 +02:00
|
|
|
/**
|
|
|
|
* Gets the number of plots, which the player is able to build in.
|
|
|
|
*
|
|
|
|
* @param player player, for whom we're getting the plots
|
|
|
|
* @return the number of allowed plots
|
|
|
|
*/
|
|
|
|
public static int getAllowedPlots(Player player) {
|
2020-05-27 14:08:48 +02:00
|
|
|
PlotPlayer<?> plotPlayer = PlotPlayer.wrap(player);
|
2018-08-20 11:35:41 +02:00
|
|
|
return plotPlayer.getAllowedPlots();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether or not a player is in a plot.
|
|
|
|
*
|
|
|
|
* @param player who we're checking for
|
|
|
|
* @return true if the player is in a plot, false if not-
|
|
|
|
*/
|
|
|
|
public static boolean isInPlot(Player player) {
|
|
|
|
return getPlot(player) != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a collection containing the players plots.
|
|
|
|
*
|
|
|
|
* @param world Specify the world we want to select the plots from
|
|
|
|
* @param player Player, for whom we're getting the plots
|
|
|
|
* @return a set containing the players plots
|
|
|
|
* @see Plot
|
|
|
|
*/
|
|
|
|
public static Set<Plot> getPlayerPlots(String world, Player player) {
|
|
|
|
if (world == null) {
|
|
|
|
return new HashSet<>();
|
|
|
|
}
|
2020-05-27 14:08:48 +02:00
|
|
|
return BukkitPlayer.wrap(player).getPlots(world);
|
2018-08-20 11:35:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a message to a player. The message supports color codes.
|
|
|
|
*
|
|
|
|
* @param player the recipient of the message
|
|
|
|
* @param string the message
|
|
|
|
* @see MainUtil#sendMessage(PlotPlayer, String)
|
|
|
|
*/
|
|
|
|
public static void sendMessage(Player player, String string) {
|
|
|
|
MainUtil.sendMessage(BukkitUtil.getPlayer(player), string);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the player plot count.
|
|
|
|
*
|
|
|
|
* @param world Specify the world we want to select the plots from
|
|
|
|
* @param player Player, for whom we're getting the plot count
|
|
|
|
* @return the number of plots the player has
|
|
|
|
*/
|
|
|
|
public static int getPlayerPlotCount(String world, Player player) {
|
|
|
|
if (world == null) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return BukkitUtil.getPlayer(player).getPlotCount(world);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a message to a player.
|
|
|
|
*
|
|
|
|
* @param player the recipient of the message
|
|
|
|
* @param caption the message
|
|
|
|
*/
|
2019-02-22 17:51:06 +01:00
|
|
|
public static void sendMessage(Player player, Captions caption) {
|
2018-08-20 11:35:41 +02:00
|
|
|
MainUtil.sendMessage(BukkitUtil.getPlayer(player), caption);
|
|
|
|
}
|
|
|
|
|
2020-05-27 14:08:48 +02:00
|
|
|
public static BukkitPlayer getPlayer(@NonNull final Player player) {
|
2015-09-13 06:04:31 +02:00
|
|
|
if (player == lastPlayer) {
|
|
|
|
return lastPlotPlayer;
|
|
|
|
}
|
2020-05-27 14:08:48 +02:00
|
|
|
final PlayerManager<?, ?> playerManager = PlotSquared.imp().getPlayerManager();
|
2020-06-03 01:50:10 +02:00
|
|
|
return ((BukkitPlayerManager) playerManager).getPlayer(player);
|
2015-02-21 05:27:01 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
public static Location getLocation(@NonNull final org.bukkit.Location location) {
|
2018-08-10 17:01:10 +02:00
|
|
|
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
2019-10-18 07:51:01 +02:00
|
|
|
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()));
|
2015-02-20 08:10:07 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2019-10-18 08:02:44 +02:00
|
|
|
public static Location getLocationFull(@NonNull final org.bukkit.Location location) {
|
2020-03-15 12:22:49 +01:00
|
|
|
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
|
|
|
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()), location.getYaw(),
|
|
|
|
location.getPitch());
|
2019-10-18 08:02:44 +02:00
|
|
|
}
|
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
public static org.bukkit.Location getLocation(@NonNull final Location location) {
|
2018-08-10 17:01:10 +02:00
|
|
|
return new org.bukkit.Location(getWorld(location.getWorld()), location.getX(),
|
2019-10-18 07:51:01 +02:00
|
|
|
location.getY(), location.getZ());
|
2015-03-13 04:15:00 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:46:38 +02:00
|
|
|
public static World getWorld(@NonNull final String string) {
|
2017-03-23 01:10:29 +01:00
|
|
|
return Bukkit.getWorld(string);
|
2015-02-19 07:08:15 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
public static String getWorld(@NonNull final Entity entity) {
|
2015-02-19 11:12:26 +01:00
|
|
|
return entity.getWorld().getName();
|
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
public static List<Entity> getEntities(@NonNull final String worldName) {
|
2017-03-23 01:10:29 +01:00
|
|
|
World world = getWorld(worldName);
|
2019-08-06 22:08:56 +02:00
|
|
|
if (world != null) {
|
|
|
|
return world.getEntities();
|
|
|
|
} else {
|
|
|
|
return new ArrayList<>();
|
|
|
|
}
|
2015-02-19 11:12:26 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
public static Location getLocation(@NonNull final Entity entity) {
|
|
|
|
final org.bukkit.Location location = entity.getLocation();
|
2016-06-02 17:38:47 +02:00
|
|
|
String world = location.getWorld().getName();
|
2018-08-10 17:01:10 +02:00
|
|
|
return new Location(world, location.getBlockX(), location.getBlockY(),
|
|
|
|
location.getBlockZ());
|
2015-07-28 08:06:19 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2019-09-08 20:02:45 +02:00
|
|
|
@NotNull public static Location getLocationFull(@NonNull final Entity entity) {
|
2018-08-10 20:54:17 +02:00
|
|
|
final org.bukkit.Location location = entity.getLocation();
|
2018-08-10 17:01:10 +02:00
|
|
|
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
|
|
|
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()), location.getYaw(),
|
|
|
|
location.getPitch());
|
2015-07-28 08:06:19 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2019-11-04 20:55:55 +01:00
|
|
|
public static Material getMaterial(@NonNull final BlockState plotBlock) {
|
|
|
|
return BukkitAdapter.adapt(plotBlock.getBlockType());
|
2018-12-20 00:26:20 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 20:55:55 +01:00
|
|
|
@Override public boolean isBlockSame(BlockState block1, BlockState block2) {
|
2018-12-20 00:26:20 +01:00
|
|
|
if (block1.equals(block2)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
Material mat1 = getMaterial(block1), mat2 = getMaterial(block2);
|
|
|
|
return mat1 == mat2;
|
|
|
|
}
|
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
@Override public boolean isWorld(@NonNull final String worldName) {
|
2016-03-29 21:47:59 +02:00
|
|
|
return getWorld(worldName) != null;
|
2015-07-20 07:14:46 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2020-04-07 20:19:39 +02:00
|
|
|
@Override public void getBiome(String world, int x, int z, final Consumer<BiomeType> result) {
|
2020-04-30 12:01:52 +02:00
|
|
|
ensureLoaded(world, x, z,
|
|
|
|
chunk -> result.accept(BukkitAdapter.adapt(getWorld(world).getBiome(x, z))));
|
2020-04-07 20:19:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override public BiomeType getBiomeSynchronous(String world, int x, int z) {
|
2019-11-10 18:47:37 +01:00
|
|
|
return BukkitAdapter.adapt(getWorld(world).getBiome(x, z));
|
2015-02-23 12:37:36 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2020-04-30 12:01:52 +02:00
|
|
|
@Override
|
|
|
|
public void getHighestBlock(@NonNull final String world, final int x, final int z,
|
2020-04-09 11:23:39 +02:00
|
|
|
final IntConsumer result) {
|
2020-04-07 20:19:39 +02:00
|
|
|
ensureLoaded(world, x, z, chunk -> {
|
|
|
|
final World bukkitWorld = getWorld(world);
|
|
|
|
// Skip top and bottom block
|
|
|
|
int air = 1;
|
|
|
|
for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) {
|
|
|
|
Block block = bukkitWorld.getBlockAt(x, y, z);
|
|
|
|
Material type = block.getType();
|
|
|
|
if (type.isSolid()) {
|
|
|
|
if (air > 1) {
|
|
|
|
result.accept(y);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
air = 0;
|
|
|
|
} else {
|
|
|
|
if (block.isLiquid()) {
|
|
|
|
result.accept(y);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
air++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result.accept(bukkitWorld.getMaxHeight() - 1);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override public int getHighestBlockSynchronous(String world, int x, int z) {
|
2019-02-22 03:14:48 +01:00
|
|
|
final World bukkitWorld = getWorld(world);
|
|
|
|
// Skip top and bottom block
|
|
|
|
int air = 1;
|
|
|
|
for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) {
|
|
|
|
Block block = bukkitWorld.getBlockAt(x, y, z);
|
2019-08-06 22:08:56 +02:00
|
|
|
Material type = block.getType();
|
|
|
|
if (type.isSolid()) {
|
|
|
|
if (air > 1) {
|
|
|
|
return y;
|
2019-02-22 03:14:48 +01:00
|
|
|
}
|
2019-08-06 22:08:56 +02:00
|
|
|
air = 0;
|
|
|
|
} else {
|
|
|
|
if (block.isLiquid()) {
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
air++;
|
2015-10-24 12:55:34 +02:00
|
|
|
}
|
2015-02-19 07:08:15 +01:00
|
|
|
}
|
2019-02-22 03:14:48 +01:00
|
|
|
return bukkitWorld.getMaxHeight() - 1;
|
2015-02-19 07:08:15 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2020-04-30 12:01:52 +02:00
|
|
|
@Override
|
|
|
|
public void getSign(@NonNull final Location location, final Consumer<String[]> result) {
|
2020-04-07 20:19:39 +02:00
|
|
|
ensureLoaded(location, chunk -> {
|
|
|
|
final Block block = chunk.getWorld().getBlockAt(getLocation(location));
|
|
|
|
if (block.getState() instanceof Sign) {
|
|
|
|
Sign sign = (Sign) block.getState();
|
|
|
|
result.accept(sign.getLines());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override @Nullable public String[] getSignSynchronous(@NonNull final Location location) {
|
2020-03-15 12:22:49 +01:00
|
|
|
Block block = getWorld(location.getWorld())
|
|
|
|
.getBlockAt(location.getX(), location.getY(), location.getZ());
|
2019-11-05 16:23:48 +01:00
|
|
|
return TaskManager.IMP.sync(new RunnableVal<String[]>() {
|
|
|
|
@Override public void run(String[] value) {
|
|
|
|
if (block.getState() instanceof Sign) {
|
|
|
|
Sign sign = (Sign) block.getState();
|
|
|
|
this.value = sign.getLines();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2015-02-22 07:30:58 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
@Override public Location getSpawn(@NonNull final String world) {
|
|
|
|
final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
|
2018-08-10 17:01:10 +02:00
|
|
|
return new Location(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(),
|
|
|
|
temp.getYaw(), temp.getPitch());
|
2015-02-22 07:56:46 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
@Override public void setSpawn(@NonNull final Location location) {
|
|
|
|
final World world = getWorld(location.getWorld());
|
2016-03-17 10:11:07 +01:00
|
|
|
if (world != null) {
|
2016-03-23 02:41:37 +01:00
|
|
|
world.setSpawnLocation(location.getX(), location.getY(), location.getZ());
|
2016-03-17 10:11:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-10 20:54:17 +02:00
|
|
|
@Override public void saveWorld(@NonNull final String worldName) {
|
|
|
|
final World world = getWorld(worldName);
|
2016-03-17 10:11:07 +01:00
|
|
|
if (world != null) {
|
|
|
|
world.save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-22 03:14:48 +01:00
|
|
|
@Override @SuppressWarnings("deprecation")
|
|
|
|
public void setSign(@NonNull final String worldName, final int x, final int y, final int z,
|
|
|
|
@NonNull final String[] lines) {
|
2020-04-07 20:19:39 +02:00
|
|
|
ensureLoaded(worldName, x, z, chunk -> {
|
|
|
|
final World world = getWorld(worldName);
|
|
|
|
final Block block = world.getBlockAt(x, y, z);
|
|
|
|
// block.setType(Material.AIR);
|
|
|
|
final Material type = block.getType();
|
|
|
|
if (type != Material.LEGACY_SIGN && type != Material.LEGACY_WALL_SIGN) {
|
|
|
|
BlockFace facing = BlockFace.EAST;
|
|
|
|
if (world.getBlockAt(x, y, z + 1).getType().isSolid()) {
|
|
|
|
facing = BlockFace.NORTH;
|
|
|
|
} else if (world.getBlockAt(x + 1, y, z).getType().isSolid()) {
|
|
|
|
facing = BlockFace.WEST;
|
|
|
|
} else if (world.getBlockAt(x, y, z - 1).getType().isSolid()) {
|
|
|
|
facing = BlockFace.SOUTH;
|
|
|
|
}
|
|
|
|
if (PlotSquared.get().IMP.getServerVersion()[1] == 13) {
|
|
|
|
block.setType(Material.valueOf("WALL_SIGN"), false);
|
|
|
|
} else {
|
|
|
|
block.setType(Material.valueOf("OAK_WALL_SIGN"), false);
|
|
|
|
}
|
|
|
|
if (!(block.getBlockData() instanceof WallSign)) {
|
|
|
|
PlotSquared.debug(block.getBlockData().getAsString());
|
|
|
|
throw new RuntimeException("Something went wrong generating a sign");
|
|
|
|
}
|
|
|
|
final Directional sign = (Directional) block.getBlockData();
|
|
|
|
sign.setFacing(facing);
|
|
|
|
block.setBlockData(sign, false);
|
2019-02-22 03:14:48 +01:00
|
|
|
}
|
2020-04-07 20:19:39 +02:00
|
|
|
final org.bukkit.block.BlockState blockstate = block.getState();
|
|
|
|
if (blockstate instanceof Sign) {
|
|
|
|
final Sign sign = (Sign) blockstate;
|
|
|
|
for (int i = 0; i < lines.length; i++) {
|
|
|
|
sign.setLine(i, lines[i]);
|
|
|
|
}
|
|
|
|
sign.update(true);
|
2015-02-26 05:16:52 +01:00
|
|
|
}
|
2020-04-07 20:19:39 +02:00
|
|
|
});
|
2015-02-26 05:16:52 +01:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2019-11-04 20:55:55 +01:00
|
|
|
@Override public boolean isBlockSolid(@NonNull final BlockState block) {
|
|
|
|
return block.getBlockType().getMaterial().isSolid();
|
2015-04-14 15:55:00 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2019-11-04 20:55:55 +01:00
|
|
|
@Override public String getClosestMatchingName(@NonNull final BlockState block) {
|
2015-09-13 06:04:31 +02:00
|
|
|
try {
|
2018-12-17 20:57:21 +01:00
|
|
|
return getMaterial(block).name();
|
2016-04-26 16:14:22 +02:00
|
|
|
} catch (Exception ignored) {
|
2015-06-29 21:30:36 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-11-14 15:44:07 +01:00
|
|
|
@Override @Nullable
|
2019-11-04 20:55:55 +01:00
|
|
|
public StringComparison<BlockState>.ComparisonResult getClosestBlock(String name) {
|
|
|
|
BlockState state = BlockUtil.get(name);
|
|
|
|
return new StringComparison<BlockState>().new ComparisonResult(1, state);
|
2015-06-29 21:30:36 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-11-14 15:44:07 +01:00
|
|
|
@Override
|
2019-11-04 22:08:33 +01:00
|
|
|
public void setBiomes(@NonNull final String worldName, @NonNull final CuboidRegion region,
|
2019-11-10 18:47:37 +01:00
|
|
|
@NonNull final BiomeType biomeType) {
|
2018-08-10 20:54:17 +02:00
|
|
|
final World world = getWorld(worldName);
|
2020-02-11 22:13:03 +01:00
|
|
|
if (world == null) {
|
|
|
|
PlotSquared.log("An error occurred setting the biome because the world was null.");
|
|
|
|
return;
|
|
|
|
}
|
2019-11-10 18:47:37 +01:00
|
|
|
final Biome biome = BukkitAdapter.adapt(biomeType);
|
2019-11-04 22:08:33 +01:00
|
|
|
for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) {
|
2020-03-15 12:22:49 +01:00
|
|
|
for (int z = region.getMinimumPoint().getZ();
|
|
|
|
z <= region.getMaximumPoint().getZ(); z++) {
|
2020-04-20 23:40:04 +02:00
|
|
|
if (world.getBiome(x, z) != biome) {
|
2020-04-20 23:36:56 +02:00
|
|
|
world.setBiome(x, z, biome);
|
2020-02-11 22:13:03 +01:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-12-20 00:18:57 +01:00
|
|
|
public com.sk89q.worldedit.world.World getWeWorld(String world) {
|
|
|
|
return new BukkitWorld(Bukkit.getWorld(world));
|
|
|
|
}
|
|
|
|
|
2020-04-30 12:01:52 +02:00
|
|
|
@Override
|
|
|
|
public void getBlock(@NonNull final Location location, final Consumer<BlockState> result) {
|
2020-04-07 20:19:39 +02:00
|
|
|
ensureLoaded(location, chunk -> {
|
|
|
|
final World world = getWorld(location.getWorld());
|
|
|
|
final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ());
|
|
|
|
result.accept(BukkitAdapter.asBlockType(block.getType()).getDefaultState());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override public BlockState getBlockSynchronous(@NonNull final Location location) {
|
2018-08-10 20:54:17 +02:00
|
|
|
final World world = getWorld(location.getWorld());
|
|
|
|
final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ());
|
2019-11-10 18:47:37 +01:00
|
|
|
return BukkitAdapter.asBlockType(block.getType()).getDefaultState();
|
2015-07-28 08:06:19 +02:00
|
|
|
}
|
2016-02-14 02:01:18 +01:00
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public String getMainWorld() {
|
2016-02-10 19:59:51 +01:00
|
|
|
return Bukkit.getWorlds().get(0).getName();
|
|
|
|
}
|
2020-03-15 12:22:49 +01:00
|
|
|
|
|
|
|
@Override public double getHealth(PlotPlayer player) {
|
|
|
|
return Bukkit.getPlayer(player.getUUID()).getHealth();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override public int getFoodLevel(PlotPlayer player) {
|
|
|
|
return Bukkit.getPlayer(player.getUUID()).getFoodLevel();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override public void setHealth(PlotPlayer player, double health) {
|
|
|
|
Bukkit.getPlayer(player.getUUID()).setHealth(health);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override public void setFoodLevel(PlotPlayer player, int foodLevel) {
|
|
|
|
Bukkit.getPlayer(player.getUUID()).setFoodLevel(foodLevel);
|
|
|
|
}
|
2020-04-07 20:19:39 +02:00
|
|
|
|
2020-04-11 22:26:31 +02:00
|
|
|
@Override
|
2020-04-30 12:01:52 +02:00
|
|
|
public Set<com.sk89q.worldedit.world.entity.EntityType> getTypesInCategory(
|
|
|
|
final String category) {
|
2020-04-11 22:26:31 +02:00
|
|
|
final Collection<Class<?>> allowedInterfaces = new HashSet<>();
|
|
|
|
switch (category) {
|
|
|
|
case "animal": {
|
2020-04-12 04:46:51 +02:00
|
|
|
allowedInterfaces.add(IronGolem.class);
|
|
|
|
allowedInterfaces.add(Snowman.class);
|
2020-04-11 22:26:31 +02:00
|
|
|
allowedInterfaces.add(Animals.class);
|
2020-04-12 00:57:50 +02:00
|
|
|
allowedInterfaces.add(WaterMob.class);
|
|
|
|
allowedInterfaces.add(Ambient.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-11 22:26:31 +02:00
|
|
|
case "tameable": {
|
|
|
|
allowedInterfaces.add(Tameable.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-11 22:26:31 +02:00
|
|
|
case "vehicle": {
|
|
|
|
allowedInterfaces.add(Vehicle.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-11 22:26:31 +02:00
|
|
|
case "hostile": {
|
2020-04-12 04:46:51 +02:00
|
|
|
allowedInterfaces.add(Shulker.class);
|
2020-04-11 22:26:31 +02:00
|
|
|
allowedInterfaces.add(Monster.class);
|
|
|
|
allowedInterfaces.add(Boss.class);
|
|
|
|
allowedInterfaces.add(Slime.class);
|
2020-04-12 00:57:50 +02:00
|
|
|
allowedInterfaces.add(Ghast.class);
|
|
|
|
allowedInterfaces.add(Phantom.class);
|
|
|
|
allowedInterfaces.add(EnderCrystal.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-11 22:26:31 +02:00
|
|
|
case "hanging": {
|
|
|
|
allowedInterfaces.add(Hanging.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-12 00:57:50 +02:00
|
|
|
case "villager": {
|
|
|
|
allowedInterfaces.add(NPC.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-12 00:57:50 +02:00
|
|
|
case "projectile": {
|
|
|
|
allowedInterfaces.add(Projectile.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-12 01:23:13 +02:00
|
|
|
case "other": {
|
2020-04-12 00:57:50 +02:00
|
|
|
allowedInterfaces.add(ArmorStand.class);
|
2020-04-12 01:23:13 +02:00
|
|
|
allowedInterfaces.add(FallingBlock.class);
|
|
|
|
allowedInterfaces.add(Item.class);
|
|
|
|
allowedInterfaces.add(Explosive.class);
|
|
|
|
allowedInterfaces.add(AreaEffectCloud.class);
|
|
|
|
allowedInterfaces.add(EvokerFangs.class);
|
|
|
|
allowedInterfaces.add(LightningStrike.class);
|
|
|
|
allowedInterfaces.add(ExperienceOrb.class);
|
|
|
|
allowedInterfaces.add(EnderSignal.class);
|
|
|
|
allowedInterfaces.add(Firework.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-12 01:23:13 +02:00
|
|
|
case "player": {
|
|
|
|
allowedInterfaces.add(Player.class);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-11 22:26:31 +02:00
|
|
|
default: {
|
|
|
|
PlotSquared.log(Captions.PREFIX + "Unknown entity category requested: " + category);
|
2020-04-30 12:01:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2020-04-11 22:26:31 +02:00
|
|
|
}
|
|
|
|
final Set<com.sk89q.worldedit.world.entity.EntityType> types = new HashSet<>();
|
2020-04-30 12:01:52 +02:00
|
|
|
outer:
|
|
|
|
for (final EntityType bukkitType : EntityType.values()) {
|
2020-04-11 22:26:31 +02:00
|
|
|
final Class<? extends Entity> entityClass = bukkitType.getEntityClass();
|
|
|
|
if (entityClass == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (final Class<?> allowedInterface : allowedInterfaces) {
|
|
|
|
if (allowedInterface.isAssignableFrom(entityClass)) {
|
|
|
|
types.add(BukkitAdapter.adapt(bukkitType));
|
|
|
|
continue outer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return types;
|
|
|
|
}
|
|
|
|
|
2020-05-13 14:11:17 +02:00
|
|
|
private final Collection<BlockType> tileEntityTypes = new HashSet<>();
|
|
|
|
@Override public Collection<BlockType> getTileEntityTypes() {
|
|
|
|
if (this.tileEntityTypes.isEmpty()) {
|
|
|
|
// Categories
|
|
|
|
tileEntityTypes.addAll(BlockCategories.BANNERS.getAll());
|
|
|
|
tileEntityTypes.addAll(BlockCategories.SIGNS.getAll());
|
|
|
|
tileEntityTypes.addAll(BlockCategories.BEDS.getAll());
|
|
|
|
tileEntityTypes.addAll(BlockCategories.FLOWER_POTS.getAll());
|
|
|
|
// Individual Types
|
|
|
|
// Add these from strings
|
2020-05-13 14:24:04 +02:00
|
|
|
Stream.of("barrel", "beacon", "beehive", "bee_nest", "bell", "blast_furnace",
|
2020-05-13 14:11:17 +02:00
|
|
|
"brewing_stand", "campfire", "chest", "ender_chest", "trapped_chest",
|
|
|
|
"command_block", "end_gateway", "hopper", "jigsaw", "jubekox",
|
|
|
|
"lectern", "note_block", "black_shulker_box", "blue_shulker_box",
|
|
|
|
"brown_shulker_box", "cyan_shulker_box", "gray_shulker_box", "green_shulker_box",
|
|
|
|
"light_blue_shulker_box", "light_gray_shulker_box", "lime_shulker_box",
|
|
|
|
"magenta_shulker_box", "orange_shulker_box", "pink_shulker_box",
|
|
|
|
"purple_shulker_box", "red_shulker_box", "shulker_box", "white_shulker_box",
|
2020-05-13 14:24:04 +02:00
|
|
|
"yellow_shulker_box", "smoker", "structure_block", "structure_void")
|
2020-05-13 14:11:17 +02:00
|
|
|
.map(BlockTypes::get)
|
|
|
|
.filter(Objects::nonNull)
|
|
|
|
.forEach(tileEntityTypes::add);
|
|
|
|
}
|
|
|
|
return this.tileEntityTypes;
|
|
|
|
}
|
|
|
|
|
2020-05-13 14:54:54 +02:00
|
|
|
@Override
|
|
|
|
public int getTileEntityCount(String world, BlockVector2 chunk) {
|
|
|
|
return Bukkit.getWorld(world).getChunkAt(chunk.getBlockX(), chunk.getBlockZ())
|
|
|
|
.getTileEntities().length;
|
|
|
|
}
|
|
|
|
|
2020-04-30 12:01:52 +02:00
|
|
|
private static void ensureLoaded(final String world, final int x, final int z,
|
|
|
|
final Consumer<Chunk> chunkConsumer) {
|
|
|
|
PaperLib.getChunkAtAsync(getWorld(world), x >> 4, z >> 4, true)
|
|
|
|
.thenAccept(chunk -> ensureMainThread(chunkConsumer, chunk));
|
2020-04-07 20:19:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static void ensureLoaded(final Location location, final Consumer<Chunk> chunkConsumer) {
|
2020-04-30 12:01:52 +02:00
|
|
|
PaperLib.getChunkAtAsync(getLocation(location), true)
|
|
|
|
.thenAccept(chunk -> ensureMainThread(chunkConsumer, chunk));
|
2020-04-07 20:19:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static <T> void ensureMainThread(final Consumer<T> consumer, final T value) {
|
|
|
|
if (Bukkit.isPrimaryThread()) {
|
|
|
|
consumer.accept(value);
|
|
|
|
} else {
|
2020-04-30 12:01:52 +02:00
|
|
|
Bukkit.getScheduler()
|
|
|
|
.runTask(BukkitMain.getPlugin(BukkitMain.class), () -> consumer.accept(value));
|
2020-04-07 20:19:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-19 07:08:15 +01:00
|
|
|
}
|