2020-01-15 02:03:06 +01:00
|
|
|
package world.bentobox.warps.listeners;
|
2018-05-29 00:42:03 +02:00
|
|
|
|
2023-01-19 21:56:31 +01:00
|
|
|
import java.util.*;
|
|
|
|
import java.util.stream.Collectors;
|
2018-08-01 04:48:13 +02:00
|
|
|
|
2021-01-04 02:54:33 +01:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.ChatColor;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Tag;
|
|
|
|
import org.bukkit.World;
|
2018-05-29 00:42:03 +02:00
|
|
|
import org.bukkit.block.Block;
|
|
|
|
import org.bukkit.block.Sign;
|
2019-10-31 22:49:26 +01:00
|
|
|
import org.bukkit.entity.Player;
|
2018-05-29 00:42:03 +02:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.EventPriority;
|
|
|
|
import org.bukkit.event.Listener;
|
|
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
|
|
import org.bukkit.event.block.SignChangeEvent;
|
2020-09-07 18:14:44 +02:00
|
|
|
import org.bukkit.event.world.ChunkLoadEvent;
|
|
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
2021-01-04 02:54:33 +01:00
|
|
|
import org.eclipse.jdt.annotation.Nullable;
|
|
|
|
|
2018-08-01 18:47:57 +02:00
|
|
|
import world.bentobox.bentobox.BentoBox;
|
2020-09-11 03:34:56 +02:00
|
|
|
import world.bentobox.bentobox.api.events.addon.AddonEvent;
|
2023-01-19 21:56:31 +01:00
|
|
|
import world.bentobox.bentobox.api.events.flags.FlagProtectionChangeEvent;
|
2020-12-27 20:14:19 +01:00
|
|
|
import world.bentobox.bentobox.api.events.team.TeamKickEvent;
|
|
|
|
import world.bentobox.bentobox.api.events.team.TeamLeaveEvent;
|
2018-08-01 18:47:57 +02:00
|
|
|
import world.bentobox.bentobox.api.user.User;
|
2023-01-19 21:56:31 +01:00
|
|
|
import world.bentobox.bentobox.database.objects.Island;
|
2019-03-04 03:53:36 +01:00
|
|
|
import world.bentobox.bentobox.util.Util;
|
2020-01-15 02:03:06 +01:00
|
|
|
import world.bentobox.warps.Warp;
|
2019-03-04 03:53:36 +01:00
|
|
|
import world.bentobox.warps.event.WarpRemoveEvent;
|
2018-05-29 00:42:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles warping. Players can add one sign
|
2018-07-27 07:42:47 +02:00
|
|
|
*
|
2018-05-29 00:42:03 +02:00
|
|
|
* @author tastybento
|
2018-07-27 07:42:47 +02:00
|
|
|
*
|
2018-05-29 00:42:03 +02:00
|
|
|
*/
|
|
|
|
public class WarpSignsListener implements Listener {
|
2018-08-04 08:32:05 +02:00
|
|
|
|
2021-08-09 03:28:19 +02:00
|
|
|
private static final String WARPS_DEACTIVATE = "warps.deactivate";
|
|
|
|
|
2021-08-09 03:09:28 +02:00
|
|
|
private final BentoBox plugin;
|
2018-05-29 00:42:03 +02:00
|
|
|
|
2021-08-09 03:09:28 +02:00
|
|
|
private final Warp addon;
|
2018-05-29 00:42:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param addon - addon
|
|
|
|
*/
|
2018-08-01 04:48:13 +02:00
|
|
|
public WarpSignsListener(Warp addon) {
|
2018-05-29 00:42:03 +02:00
|
|
|
this.addon = addon;
|
2018-08-01 04:48:13 +02:00
|
|
|
this.plugin = addon.getPlugin();
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|
|
|
|
|
2020-09-07 18:14:44 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void onChunkLoad(ChunkLoadEvent event) {
|
|
|
|
// Delay to wait the chunk to be fully loaded
|
|
|
|
new BukkitRunnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
boolean changed = false;
|
|
|
|
Iterator<Map.Entry<UUID, Location>> iterator =
|
|
|
|
addon.getWarpSignsManager().getWarpMap(event.getWorld()).entrySet().iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
Map.Entry<UUID, Location> entry = iterator.next();
|
|
|
|
UUID uuid = entry.getKey();
|
|
|
|
Location location = entry.getValue();
|
|
|
|
if (event.getChunk().getX() == location.getBlockX() >> 4
|
|
|
|
&& event.getChunk().getZ() == location.getBlockZ() >> 4
|
|
|
|
&& !Tag.SIGNS.isTagged(location.getBlock().getType())) {
|
|
|
|
iterator.remove();
|
|
|
|
// Remove sign from warp panel cache
|
2022-03-11 11:34:16 +01:00
|
|
|
addon.getSignCacheManager().removeWarp(event.getWorld(), uuid);
|
2020-09-07 18:14:44 +02:00
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (changed) {
|
|
|
|
addon.getWarpSignsManager().saveWarpList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}.runTask(plugin);
|
|
|
|
}
|
|
|
|
|
2020-01-15 02:34:28 +01:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void onPlayerLeave(TeamLeaveEvent e) {
|
|
|
|
// Remove any warp signs from this game mode
|
|
|
|
addon.getWarpSignsManager().removeWarp(e.getIsland().getWorld(), e.getPlayerUUID());
|
2021-08-09 03:28:19 +02:00
|
|
|
Objects.requireNonNull(User.getInstance(e.getPlayerUUID())).sendMessage(WARPS_DEACTIVATE);
|
2020-01-15 02:34:28 +01:00
|
|
|
}
|
2020-12-27 20:14:19 +01:00
|
|
|
|
2020-01-15 02:34:28 +01:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void onPlayerLeave(TeamKickEvent e) {
|
|
|
|
// Remove any warp signs from this game mode
|
|
|
|
addon.getWarpSignsManager().removeWarp(e.getIsland().getWorld(), e.getPlayerUUID());
|
2021-08-09 03:28:19 +02:00
|
|
|
Objects.requireNonNull(User.getInstance(e.getPlayerUUID())).sendMessage(WARPS_DEACTIVATE);
|
2020-01-15 02:34:28 +01:00
|
|
|
}
|
2020-12-27 20:14:19 +01:00
|
|
|
|
2018-05-29 00:42:03 +02:00
|
|
|
/**
|
|
|
|
* Checks to see if a sign has been broken
|
|
|
|
* @param e - event
|
|
|
|
*/
|
2018-08-05 00:54:23 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
2018-05-29 00:42:03 +02:00
|
|
|
public void onSignBreak(BlockBreakEvent e) {
|
|
|
|
Block b = e.getBlock();
|
2019-10-31 22:12:44 +01:00
|
|
|
boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld());
|
2018-05-29 00:42:03 +02:00
|
|
|
// Signs only
|
2019-05-16 00:16:15 +02:00
|
|
|
// FIXME: When we drop support for 1.13, switch to Tag.SIGNS
|
2021-01-04 02:54:33 +01:00
|
|
|
if (!b.getType().name().contains("SIGN")
|
2019-10-31 22:49:26 +01:00
|
|
|
|| (inWorld && !addon.inRegisteredWorld(b.getWorld()))
|
2021-01-04 02:54:33 +01:00
|
|
|
|| (!inWorld && !addon.getSettings().isAllowInOtherWorlds())
|
|
|
|
|| !isWarpSign(b)) {
|
2018-05-29 00:42:03 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
User user = User.getInstance(e.getPlayer());
|
2021-01-04 02:54:33 +01:00
|
|
|
UUID owner = addon.getWarpSignsManager().getWarpOwnerUUID(b.getLocation()).orElse(null);
|
|
|
|
if (isPlayersSign(e.getPlayer(), b, inWorld)) {
|
|
|
|
addon.getWarpSignsManager().removeWarp(b.getLocation());
|
|
|
|
Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(b.getLocation(), user.getUniqueId(), owner));
|
|
|
|
} else {
|
|
|
|
// Someone else's sign - not allowed
|
|
|
|
user.sendMessage("warps.error.no-remove");
|
|
|
|
e.setCancelled(true);
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-31 22:49:26 +01:00
|
|
|
private boolean isPlayersSign(Player player, Block b, boolean inWorld) {
|
|
|
|
// Welcome sign detected - check to see if it is this player's sign
|
|
|
|
Map<UUID, Location> list = addon.getWarpSignsManager().getWarpMap(b.getWorld());
|
|
|
|
String reqPerm = inWorld ? addon.getPermPrefix(b.getWorld()) + "mod.removesign" : Warp.WELCOME_WARP_SIGNS + ".mod.removesign";
|
|
|
|
return ((list.containsKey(player.getUniqueId()) && list.get(player.getUniqueId()).equals(b.getLocation()))
|
|
|
|
|| player.isOp() || player.hasPermission(reqPerm));
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isWarpSign(Block b) {
|
|
|
|
Sign s = (Sign) b.getState();
|
|
|
|
return s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())
|
|
|
|
&& addon.getWarpSignsManager().getWarpMap(b.getWorld()).containsValue(s.getLocation());
|
|
|
|
}
|
|
|
|
|
2018-05-29 00:42:03 +02:00
|
|
|
/**
|
|
|
|
* Event handler for Sign Changes
|
2018-07-27 07:42:47 +02:00
|
|
|
*
|
2018-05-29 00:42:03 +02:00
|
|
|
* @param e - event
|
|
|
|
*/
|
2018-08-05 00:54:23 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
2018-05-29 00:42:03 +02:00
|
|
|
public void onSignWarpCreate(SignChangeEvent e) {
|
|
|
|
Block b = e.getBlock();
|
2019-10-31 22:12:44 +01:00
|
|
|
boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld());
|
|
|
|
if ((inWorld && !addon.inRegisteredWorld(b.getWorld())) || (!inWorld && !addon.getSettings().isAllowInOtherWorlds()) ) {
|
2018-05-29 00:42:03 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
String title = e.getLine(0);
|
2021-08-09 02:36:03 +02:00
|
|
|
User user = Objects.requireNonNull(User.getInstance(e.getPlayer()));
|
2018-05-29 00:42:03 +02:00
|
|
|
// Check if someone is changing their own sign
|
2021-08-09 03:09:28 +02:00
|
|
|
if (title != null && title.equalsIgnoreCase(addon.getSettings().getWelcomeLine())) {
|
2018-05-29 00:42:03 +02:00
|
|
|
// Welcome sign detected - check permissions
|
2019-10-31 22:12:44 +01:00
|
|
|
if (noPerms(user, b.getWorld(), inWorld)) {
|
2018-05-29 00:42:03 +02:00
|
|
|
return;
|
|
|
|
}
|
2019-10-31 22:12:44 +01:00
|
|
|
if (inWorld && noLevelOrIsland(user, b.getWorld())) {
|
|
|
|
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
|
|
|
|
return;
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|
2023-01-19 21:56:31 +01:00
|
|
|
|
|
|
|
if(!hasCorrectIslandRank(b, user)) {
|
|
|
|
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
|
|
|
|
user.sendMessage("warps.error.not-correct-rank");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-29 00:42:03 +02:00
|
|
|
// Check if the player already has a sign
|
2018-05-29 17:17:01 +02:00
|
|
|
final Location oldSignLoc = addon.getWarpSignsManager().getWarp(b.getWorld(), user.getUniqueId());
|
2021-08-09 03:09:28 +02:00
|
|
|
if (oldSignLoc != null) {
|
2018-05-29 00:42:03 +02:00
|
|
|
// A sign already exists. Check if it still there and if
|
|
|
|
// so,
|
|
|
|
// deactivate it
|
|
|
|
Block oldSignBlock = oldSignLoc.getBlock();
|
2019-05-16 00:16:15 +02:00
|
|
|
// FIXME: When we drop support for 1.13, switch to Tag.SIGNS
|
|
|
|
if (oldSignBlock.getType().name().contains("SIGN")) {
|
2018-05-29 00:42:03 +02:00
|
|
|
// The block is still a sign
|
|
|
|
Sign oldSign = (Sign) oldSignBlock.getState();
|
2019-10-31 22:12:44 +01:00
|
|
|
if (oldSign.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) {
|
|
|
|
oldSign.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
|
|
|
|
oldSign.update(true, false);
|
2021-08-09 03:28:19 +02:00
|
|
|
user.sendMessage(WARPS_DEACTIVATE);
|
2019-10-31 22:12:44 +01:00
|
|
|
addon.getWarpSignsManager().removeWarp(oldSignBlock.getWorld(), user.getUniqueId());
|
2021-01-04 02:54:33 +01:00
|
|
|
@Nullable
|
|
|
|
UUID owner = addon.getWarpSignsManager().getWarpOwnerUUID(oldSignLoc).orElse(null);
|
|
|
|
Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(oldSign.getLocation(), user.getUniqueId(), owner));
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|
|
|
|
}
|
2018-08-01 04:48:13 +02:00
|
|
|
// Set up the new warp sign
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|
2021-08-09 03:09:28 +02:00
|
|
|
addSign(e, user, b);
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-01-19 21:56:31 +01:00
|
|
|
private boolean hasCorrectIslandRank(Block b, User user) {
|
|
|
|
final Optional<Island> islandOpt = plugin.getIslands().getIslandAt(b.getLocation());
|
|
|
|
|
|
|
|
if(islandOpt.isEmpty()) return false;
|
|
|
|
|
|
|
|
final Island island = islandOpt.get();
|
|
|
|
|
|
|
|
final int userRank = island.getRank(user);
|
|
|
|
|
|
|
|
return userRank >= island.getFlag(addon.getCreateWarpFlag());
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
public void onFlagChange(FlagProtectionChangeEvent e) {
|
|
|
|
if(!e.getEditedFlag().equals(addon.getCreateWarpFlag())) return;
|
|
|
|
if(!addon.getSettings().getRemoveExistingWarpsWhenFlagChanges()) return;
|
|
|
|
|
|
|
|
final Island island = e.getIsland();
|
|
|
|
|
|
|
|
final Map<UUID, Location> islandWarps = addon
|
|
|
|
.getWarpSignsManager()
|
|
|
|
.getWarpMap(island.getWorld())
|
|
|
|
.entrySet()
|
|
|
|
.stream()
|
|
|
|
.filter(x -> island.inIslandSpace(x.getValue()))
|
|
|
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
|
|
|
|
|
|
|
for(Map.Entry<UUID, Location> entry : islandWarps.entrySet()) {
|
|
|
|
if(island.getRank(entry.getKey()) >= e.getSetTo()) continue;
|
|
|
|
|
|
|
|
//The user has a lower rank than the new set value.
|
|
|
|
//We need to remove the warp.
|
|
|
|
addon.getWarpSignsManager().removeWarp(island.getWorld(), entry.getKey());
|
|
|
|
|
|
|
|
if(Bukkit.getPlayer(entry.getKey()) != null) {
|
|
|
|
Objects.requireNonNull(User.getInstance(entry.getKey())).sendMessage(WARPS_DEACTIVATE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-31 22:12:44 +01:00
|
|
|
private boolean noLevelOrIsland(User user, World world) {
|
|
|
|
// Get level if level addon is available
|
|
|
|
Long level = addon.getLevel(Util.getWorld(world), user.getUniqueId());
|
|
|
|
if (level != null && level < addon.getSettings().getWarpLevelRestriction()) {
|
|
|
|
user.sendMessage("warps.error.not-enough-level");
|
|
|
|
user.sendMessage("warps.error.your-level-is",
|
|
|
|
"[level]", String.valueOf(level),
|
|
|
|
"[required]", String.valueOf(addon.getSettings().getWarpLevelRestriction()));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the player is on their island
|
|
|
|
if (!(plugin.getIslands().userIsOnIsland(world, user))) {
|
|
|
|
user.sendMessage("warps.error.not-on-island");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if player has permission to execute command
|
|
|
|
* @param user - user
|
|
|
|
* @param world - world that the warp is in
|
|
|
|
* @param inWorld - true if warp is in a game world
|
|
|
|
* @return true if player does not have the required perms, false otherwise
|
|
|
|
*/
|
|
|
|
private boolean noPerms(User user, World world, boolean inWorld) {
|
2019-10-31 22:22:32 +01:00
|
|
|
String permReq = inWorld ? addon.getPermPrefix(world) + "island.addwarp" : Warp.WELCOME_WARP_SIGNS + ".addwarp";
|
2019-10-31 22:12:44 +01:00
|
|
|
if (!(user.hasPermission(permReq))) {
|
|
|
|
user.sendMessage("warps.error.no-permission");
|
|
|
|
user.sendMessage("general.errors.no-permission", "[permission]", permReq);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-01 04:48:13 +02:00
|
|
|
private void addSign(SignChangeEvent e, User user, Block b) {
|
|
|
|
if (addon.getWarpSignsManager().addWarp(user.getUniqueId(), b.getLocation())) {
|
|
|
|
user.sendMessage("warps.success");
|
2019-07-01 05:09:07 +02:00
|
|
|
e.setLine(0, ChatColor.GREEN + addon.getSettings().getWelcomeLine());
|
2018-08-01 04:48:13 +02:00
|
|
|
for (int i = 1; i<4; i++) {
|
2021-08-09 03:09:28 +02:00
|
|
|
String line = e.getLine(i);
|
|
|
|
if (line != null) {
|
|
|
|
e.setLine(i, ChatColor.translateAlternateColorCodes('&', line));
|
|
|
|
}
|
2018-08-01 04:48:13 +02:00
|
|
|
}
|
2020-09-11 03:34:56 +02:00
|
|
|
|
|
|
|
Map<String, Object> keyValues = new HashMap<>();
|
|
|
|
keyValues.put("eventName", "WarpCreateEvent");
|
|
|
|
keyValues.put("targetPlayer", user.getUniqueId());
|
|
|
|
keyValues.put("location", Util.getStringLocation(b.getLocation()));
|
2020-12-27 20:14:19 +01:00
|
|
|
|
2020-09-11 03:34:56 +02:00
|
|
|
new AddonEvent().builder().addon(addon).keyValues(keyValues).build();
|
2018-08-04 08:32:05 +02:00
|
|
|
}
|
2019-09-14 03:13:03 +02:00
|
|
|
// Else null player
|
2018-08-01 04:48:13 +02:00
|
|
|
}
|
|
|
|
|
2018-05-29 00:42:03 +02:00
|
|
|
}
|