953 lines
55 KiB
Java
Executable File
953 lines
55 KiB
Java
Executable File
package net.coreprotect.listener.player;
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.Statement;
|
|
import java.util.Arrays;
|
|
import java.util.EnumSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import org.bukkit.GameMode;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.Tag;
|
|
import org.bukkit.World;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockState;
|
|
import org.bukkit.block.Chest;
|
|
import org.bukkit.block.DoubleChest;
|
|
import org.bukkit.block.Jukebox;
|
|
import org.bukkit.block.Sign;
|
|
import org.bukkit.block.data.Bisected;
|
|
import org.bukkit.block.data.Bisected.Half;
|
|
import org.bukkit.block.data.BlockData;
|
|
import org.bukkit.block.data.Lightable;
|
|
import org.bukkit.block.data.Waterlogged;
|
|
import org.bukkit.block.data.type.Bed;
|
|
import org.bukkit.block.data.type.Bed.Part;
|
|
import org.bukkit.block.data.type.Cake;
|
|
import org.bukkit.entity.EnderCrystal;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.Event;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.block.Action;
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
import org.bukkit.inventory.BlockInventoryHolder;
|
|
import org.bukkit.inventory.EquipmentSlot;
|
|
import org.bukkit.inventory.InventoryHolder;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import net.coreprotect.CoreProtect;
|
|
import net.coreprotect.bukkit.BukkitAdapter;
|
|
import net.coreprotect.config.Config;
|
|
import net.coreprotect.config.ConfigHandler;
|
|
import net.coreprotect.consumer.Queue;
|
|
import net.coreprotect.database.Database;
|
|
import net.coreprotect.database.lookup.BlockLookup;
|
|
import net.coreprotect.database.lookup.ChestTransactionLookup;
|
|
import net.coreprotect.database.lookup.InteractionLookup;
|
|
import net.coreprotect.database.lookup.SignMessageLookup;
|
|
import net.coreprotect.language.Phrase;
|
|
import net.coreprotect.listener.block.CampfireStartListener;
|
|
import net.coreprotect.model.BlockGroup;
|
|
import net.coreprotect.paper.PaperAdapter;
|
|
import net.coreprotect.thread.CacheHandler;
|
|
import net.coreprotect.thread.Scheduler;
|
|
import net.coreprotect.utility.Chat;
|
|
import net.coreprotect.utility.Color;
|
|
import net.coreprotect.utility.Util;
|
|
|
|
public final class PlayerInteractListener extends Queue implements Listener {
|
|
|
|
public static ConcurrentHashMap<String, Object[]> lastInspectorEvent = new ConcurrentHashMap<>();
|
|
public static ConcurrentHashMap<String, Object[]> suspiciousBlockEvent = new ConcurrentHashMap<>();
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
protected void onPlayerInspect(PlayerInteractEvent event) {
|
|
Player player = event.getPlayer();
|
|
World world = player.getWorld();
|
|
|
|
if (!Boolean.TRUE.equals(ConfigHandler.inspecting.get(player.getName()))) {
|
|
return;
|
|
}
|
|
|
|
if (!player.hasPermission("coreprotect.inspect")) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
|
ConfigHandler.inspecting.put(player.getName(), false);
|
|
return;
|
|
}
|
|
|
|
if (event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
|
|
BlockState checkBlock = event.getClickedBlock().getState();
|
|
int x = checkBlock.getX();
|
|
int y = checkBlock.getY();
|
|
int z = checkBlock.getZ();
|
|
|
|
/* Check if clicking top half of double plant */
|
|
BlockData checkBlockData = checkBlock.getBlockData();
|
|
if (checkBlockData instanceof Bisected && !(checkBlockData instanceof Waterlogged)) {
|
|
if (((Bisected) checkBlockData).getHalf().equals(Half.TOP) && y > BukkitAdapter.ADAPTER.getMinHeight(world)) {
|
|
checkBlock = world.getBlockAt(checkBlock.getX(), checkBlock.getY() - 1, checkBlock.getZ()).getState();
|
|
}
|
|
}
|
|
/* Check if clicking top half of bed */
|
|
if (checkBlockData instanceof Bed) {
|
|
Bed bed = (Bed) checkBlockData;
|
|
if (bed.getPart().equals(Part.HEAD)) {
|
|
checkBlock = event.getClickedBlock().getRelative(bed.getFacing().getOppositeFace()).getState();
|
|
}
|
|
}
|
|
|
|
final BlockState blockFinal = checkBlock;
|
|
class BasicThread implements Runnable {
|
|
@Override
|
|
public void run() {
|
|
if (ConfigHandler.converterRunning) {
|
|
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
if (ConfigHandler.purgeRunning) {
|
|
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
|
|
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
|
|
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
|
|
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
return;
|
|
}
|
|
}
|
|
|
|
try (Connection connection = Database.getConnection(true)) {
|
|
if (connection != null) {
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
|
|
Statement statement = connection.createStatement();
|
|
|
|
String resultData = BlockLookup.performLookup(null, statement, blockFinal, player, 0, 1, 7);
|
|
if (resultData.contains("\n")) {
|
|
for (String b : resultData.split("\n")) {
|
|
Chat.sendComponent(player, b);
|
|
}
|
|
}
|
|
else if (resultData.length() > 0) {
|
|
Chat.sendComponent(player, resultData);
|
|
}
|
|
|
|
statement.close();
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
|
|
|
|
if (blockFinal instanceof Sign && player.getGameMode() != GameMode.CREATIVE) {
|
|
Thread.sleep(1500);
|
|
Sign sign = (Sign) blockFinal;
|
|
player.sendSignChange(sign.getLocation(), sign.getLines(), sign.getColor());
|
|
}
|
|
}
|
|
else {
|
|
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
Runnable runnable = new BasicThread();
|
|
Thread thread = new Thread(runnable);
|
|
thread.start();
|
|
|
|
if (checkBlockData instanceof Bisected) {
|
|
int worldMaxHeight = world.getMaxHeight();
|
|
if (y < (worldMaxHeight - 1)) {
|
|
Block y1 = world.getBlockAt(x, y + 1, z);
|
|
player.sendBlockChange(y1.getLocation(), y1.getBlockData());
|
|
}
|
|
|
|
int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(world);
|
|
if (y > worldMinHeight) {
|
|
Block y2 = world.getBlockAt(x, y - 1, z);
|
|
player.sendBlockChange(y2.getLocation(), y2.getBlockData());
|
|
}
|
|
}
|
|
|
|
Block x1 = world.getBlockAt(x + 1, y, z);
|
|
Block x2 = world.getBlockAt(x - 1, y, z);
|
|
Block z1 = world.getBlockAt(x, y, z + 1);
|
|
Block z2 = world.getBlockAt(x, y, z - 1);
|
|
player.sendBlockChange(x1.getLocation(), x1.getBlockData());
|
|
player.sendBlockChange(x2.getLocation(), x2.getBlockData());
|
|
player.sendBlockChange(z1.getLocation(), z1.getBlockData());
|
|
player.sendBlockChange(z2.getLocation(), z2.getBlockData());
|
|
event.setCancelled(true);
|
|
}
|
|
else if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
|
|
Block block = event.getClickedBlock();
|
|
if (block != null) {
|
|
final Material type = block.getType();
|
|
boolean isInteractBlock = BlockGroup.INTERACT_BLOCKS.contains(type);
|
|
boolean isContainerBlock = BlockGroup.CONTAINERS.contains(type);
|
|
boolean isSignBlock = BukkitAdapter.ADAPTER.isSign(type);
|
|
|
|
if (isInteractBlock || isContainerBlock || isSignBlock) {
|
|
final Block clickedBlock = event.getClickedBlock();
|
|
|
|
if (isSignBlock) {
|
|
Location location = clickedBlock.getLocation();
|
|
|
|
// sign messages
|
|
class BasicThread implements Runnable {
|
|
@Override
|
|
public void run() {
|
|
if (ConfigHandler.converterRunning) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
|
|
if (ConfigHandler.purgeRunning) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
|
|
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
|
|
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
|
|
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
return;
|
|
}
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
|
|
|
|
try (Connection connection = Database.getConnection(true)) {
|
|
if (connection != null) {
|
|
Statement statement = connection.createStatement();
|
|
List<String> signData = SignMessageLookup.performLookup(null, statement, location, player, 1, 7);
|
|
for (String signMessage : signData) {
|
|
String bypass = null;
|
|
|
|
if (signMessage.contains("\n")) {
|
|
String[] split = signMessage.split("\n");
|
|
signMessage = split[0];
|
|
bypass = split[1];
|
|
}
|
|
|
|
if (signMessage.length() > 0) {
|
|
Chat.sendComponent(player, signMessage, bypass);
|
|
}
|
|
}
|
|
|
|
statement.close();
|
|
}
|
|
else {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
|
|
}
|
|
}
|
|
|
|
Runnable runnable = new BasicThread();
|
|
Thread thread = new Thread(runnable);
|
|
thread.start();
|
|
event.setCancelled(true);
|
|
}
|
|
else if (isContainerBlock && Config.getConfig(world).ITEM_TRANSACTIONS) {
|
|
Location location = null;
|
|
if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST)) {
|
|
Chest chest = (Chest) clickedBlock.getState();
|
|
InventoryHolder inventoryHolder = chest.getInventory().getHolder();
|
|
|
|
if (inventoryHolder instanceof DoubleChest) {
|
|
DoubleChest doubleChest = (DoubleChest) inventoryHolder;
|
|
location = doubleChest.getLocation();
|
|
}
|
|
else {
|
|
location = chest.getLocation();
|
|
}
|
|
}
|
|
|
|
if (location == null) {
|
|
location = clickedBlock.getLocation();
|
|
}
|
|
|
|
Location finalLocation = location;
|
|
|
|
// logged chest items
|
|
class BasicThread implements Runnable {
|
|
@Override
|
|
public void run() {
|
|
if (ConfigHandler.converterRunning) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
|
|
if (ConfigHandler.purgeRunning) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
|
|
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
|
|
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
|
|
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
return;
|
|
}
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
|
|
|
|
try (Connection connection = Database.getConnection(true)) {
|
|
if (connection != null) {
|
|
Statement statement = connection.createStatement();
|
|
List<String> blockData = ChestTransactionLookup.performLookup(null, statement, finalLocation, player, 1, 7, false);
|
|
for (String data : blockData) {
|
|
Chat.sendComponent(player, data);
|
|
}
|
|
|
|
statement.close();
|
|
}
|
|
else {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
|
|
}
|
|
}
|
|
|
|
Runnable runnable = new BasicThread();
|
|
Thread thread = new Thread(runnable);
|
|
thread.start();
|
|
event.setCancelled(true);
|
|
}
|
|
else if (isInteractBlock) {
|
|
// standard player interactions
|
|
Block interactBlock = clickedBlock;
|
|
if (BlockGroup.DOORS.contains(type)) {
|
|
int y = interactBlock.getY() - 1;
|
|
Block blockUnder = interactBlock.getWorld().getBlockAt(interactBlock.getX(), y, interactBlock.getZ());
|
|
|
|
if (blockUnder.getType().equals(type)) {
|
|
interactBlock = blockUnder;
|
|
}
|
|
}
|
|
|
|
final Block finalInteractBlock = interactBlock;
|
|
class BasicThread implements Runnable {
|
|
@Override
|
|
public void run() {
|
|
if (ConfigHandler.converterRunning) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
if (ConfigHandler.purgeRunning) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
|
|
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
|
|
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
return;
|
|
}
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
|
|
|
|
try (Connection connection = Database.getConnection(true)) {
|
|
if (connection != null) {
|
|
Statement statement = connection.createStatement();
|
|
String blockData = InteractionLookup.performLookup(null, statement, finalInteractBlock, player, 0, 1, 7);
|
|
|
|
if (blockData.contains("\n")) {
|
|
for (String splitData : blockData.split("\n")) {
|
|
Chat.sendComponent(player, splitData);
|
|
}
|
|
}
|
|
else {
|
|
Chat.sendComponent(player, blockData);
|
|
}
|
|
|
|
statement.close();
|
|
}
|
|
else {
|
|
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
|
|
}
|
|
}
|
|
|
|
Runnable runnable = new BasicThread();
|
|
Thread thread = new Thread(runnable);
|
|
thread.start();
|
|
|
|
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(type) || player.isSneaking()) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
boolean performLookup = true;
|
|
EquipmentSlot eventHand = event.getHand();
|
|
String uuid = event.getPlayer().getUniqueId().toString();
|
|
long systemTime = System.currentTimeMillis();
|
|
|
|
if (lastInspectorEvent.get(uuid) != null) {
|
|
Object[] lastEvent = lastInspectorEvent.get(uuid);
|
|
long lastTime = (long) lastEvent[0];
|
|
EquipmentSlot lastHand = (EquipmentSlot) lastEvent[1];
|
|
|
|
long timeSince = systemTime - lastTime;
|
|
if (timeSince < 50 && !eventHand.equals(lastHand)) {
|
|
performLookup = false;
|
|
}
|
|
}
|
|
|
|
if (performLookup) {
|
|
final Player finalPlayer = player;
|
|
final BlockState finalBlock = event.getClickedBlock().getRelative(event.getBlockFace()).getState();
|
|
|
|
class BasicThread implements Runnable {
|
|
@Override
|
|
public void run() {
|
|
if (ConfigHandler.converterRunning) {
|
|
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
|
|
if (ConfigHandler.purgeRunning) {
|
|
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
|
|
return;
|
|
}
|
|
|
|
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
|
|
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
|
|
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
|
|
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
return;
|
|
}
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
|
|
|
|
try (Connection connection = Database.getConnection(true)) {
|
|
if (connection != null) {
|
|
Statement statement = connection.createStatement();
|
|
if (finalBlock.getType().equals(Material.AIR) || finalBlock.getType().equals(Material.CAVE_AIR)) {
|
|
String blockData = BlockLookup.performLookup(null, statement, finalBlock, finalPlayer, 0, 1, 7);
|
|
|
|
if (blockData.contains("\n")) {
|
|
for (String b : blockData.split("\n")) {
|
|
Chat.sendComponent(finalPlayer, b);
|
|
}
|
|
}
|
|
else if (blockData.length() > 0) {
|
|
Chat.sendComponent(finalPlayer, blockData);
|
|
}
|
|
}
|
|
else {
|
|
String blockData = BlockLookup.performLookup(null, statement, finalBlock, finalPlayer, 0, 1, 7);
|
|
if (blockData.contains("\n")) {
|
|
for (String splitData : blockData.split("\n")) {
|
|
Chat.sendComponent(finalPlayer, splitData);
|
|
}
|
|
}
|
|
else if (blockData.length() > 0) {
|
|
Chat.sendComponent(finalPlayer, blockData);
|
|
}
|
|
}
|
|
|
|
statement.close();
|
|
}
|
|
else {
|
|
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() });
|
|
}
|
|
}
|
|
|
|
Runnable runnable = new BasicThread();
|
|
Thread thread = new Thread(runnable);
|
|
thread.start();
|
|
|
|
Util.updateInventory(event.getPlayer());
|
|
lastInspectorEvent.put(uuid, new Object[] { systemTime, eventHand });
|
|
|
|
if (event.hasItem()) {
|
|
Material eventItem = event.getItem().getType();
|
|
if (eventItem.isBlock() && (eventItem.createBlockData() instanceof Bisected)) {
|
|
int x = finalBlock.getX();
|
|
int y = finalBlock.getY();
|
|
int z = finalBlock.getZ();
|
|
int worldMaxHeight = world.getMaxHeight();
|
|
if (y < (worldMaxHeight - 1)) {
|
|
Block blockBisected = world.getBlockAt(x, y + 1, z);
|
|
player.sendBlockChange(blockBisected.getLocation(), blockBisected.getBlockData());
|
|
}
|
|
int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(world);
|
|
if (y > worldMinHeight) {
|
|
Block blockBisected = world.getBlockAt(x, y - 1, z);
|
|
player.sendBlockChange(blockBisected.getLocation(), blockBisected.getBlockData());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
protected void onPlayerInteract(PlayerInteractEvent event) {
|
|
/* Logging for players punching out fire blocks. */
|
|
if (event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
|
|
World world = event.getClickedBlock().getWorld();
|
|
if (event.useInteractedBlock() != Event.Result.DENY) {
|
|
Block block = event.getClickedBlock();
|
|
if (block.getType() == Material.DRAGON_EGG) {
|
|
clickedDragonEgg(event.getPlayer(), block);
|
|
}
|
|
|
|
if (Config.getConfig(world).BLOCK_BREAK) {
|
|
Block relativeBlock = event.getClickedBlock().getRelative(event.getBlockFace());
|
|
|
|
if (BlockGroup.FIRE.contains(relativeBlock.getType())) {
|
|
Player player = event.getPlayer();
|
|
Material type = relativeBlock.getType();
|
|
Queue.queueBlockBreak(player.getName(), relativeBlock.getState(), type, relativeBlock.getBlockData().getAsString(), 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) || event.getAction().equals(Action.RIGHT_CLICK_AIR)) {
|
|
Player player = event.getPlayer();
|
|
Block block = event.getClickedBlock();
|
|
World world = player.getWorld();
|
|
|
|
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && block != null) {
|
|
final Material type = block.getType();
|
|
if (event.useInteractedBlock() != Event.Result.DENY) {
|
|
boolean isCake = false;
|
|
|
|
if (BukkitAdapter.ADAPTER.isSign(type)) {
|
|
// check if right clicked sign with dye
|
|
Set<Material> dyeSet = EnumSet.of(Material.BLACK_DYE, Material.BLUE_DYE, Material.BROWN_DYE, Material.CYAN_DYE, Material.GRAY_DYE, Material.GREEN_DYE, Material.LIGHT_BLUE_DYE, Material.LIGHT_GRAY_DYE, Material.LIME_DYE, Material.MAGENTA_DYE, Material.ORANGE_DYE, Material.PINK_DYE, Material.PURPLE_DYE, Material.RED_DYE, Material.WHITE_DYE, Material.YELLOW_DYE);
|
|
Material handType = null;
|
|
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null) {
|
|
handType = mainHand.getType();
|
|
}
|
|
|
|
if (handType != null && (dyeSet.contains(handType) || handType.name().endsWith("INK_SAC") || handType == Material.HONEYCOMB) && Config.getConfig(block.getWorld()).SIGN_TEXT) {
|
|
BlockState blockState = block.getState();
|
|
Sign sign = (Sign) blockState;
|
|
String line1 = PaperAdapter.ADAPTER.getLine(sign, 0);
|
|
String line2 = PaperAdapter.ADAPTER.getLine(sign, 1);
|
|
String line3 = PaperAdapter.ADAPTER.getLine(sign, 2);
|
|
String line4 = PaperAdapter.ADAPTER.getLine(sign, 3);
|
|
String line5 = PaperAdapter.ADAPTER.getLine(sign, 4);
|
|
String line6 = PaperAdapter.ADAPTER.getLine(sign, 5);
|
|
String line7 = PaperAdapter.ADAPTER.getLine(sign, 6);
|
|
String line8 = PaperAdapter.ADAPTER.getLine(sign, 7);
|
|
|
|
boolean isFront = true;
|
|
int oldColor = BukkitAdapter.ADAPTER.getColor(sign, isFront);
|
|
int oldColorSecondary = BukkitAdapter.ADAPTER.getColor(sign, !isFront);
|
|
boolean oldFrontGlowing = BukkitAdapter.ADAPTER.isGlowing(sign, isFront);
|
|
boolean oldBackGlowing = BukkitAdapter.ADAPTER.isGlowing(sign, !isFront);
|
|
boolean oldIsWaxed = BukkitAdapter.ADAPTER.isWaxed(sign);
|
|
|
|
if (!oldIsWaxed) {
|
|
Scheduler.runTask(CoreProtect.getInstance(), () -> {
|
|
BlockState newState = block.getState();
|
|
if (newState instanceof Sign) {
|
|
Sign newSign = (Sign) newState;
|
|
int newColor = BukkitAdapter.ADAPTER.getColor(newSign, isFront);
|
|
int newColorSecondary = BukkitAdapter.ADAPTER.getColor(newSign, !isFront);
|
|
boolean newFrontGlowing = BukkitAdapter.ADAPTER.isGlowing(newSign, isFront);
|
|
boolean newBackGlowing = BukkitAdapter.ADAPTER.isGlowing(newSign, !isFront);
|
|
boolean newIsWaxed = BukkitAdapter.ADAPTER.isWaxed(newSign);
|
|
|
|
boolean modifyingFront = oldBackGlowing == newBackGlowing && oldColorSecondary == newColorSecondary;
|
|
if (oldColor != newColor || oldColorSecondary != newColorSecondary || oldFrontGlowing != newFrontGlowing || oldBackGlowing != newBackGlowing || oldIsWaxed != newIsWaxed) {
|
|
Location location = blockState.getLocation();
|
|
Queue.queueSignText(player.getName(), location, 0, oldColor, oldColorSecondary, oldFrontGlowing, oldBackGlowing, oldIsWaxed, modifyingFront, line1, line2, line3, line4, line5, line6, line7, line8, 1); // 1 second timeOffset
|
|
Queue.queueBlockPlace(player.getName(), blockState, block.getType(), blockState, block.getType(), -1, 0, blockState.getBlockData().getAsString());
|
|
Queue.queueSignText(player.getName(), location, 2, newColor, newColorSecondary, newFrontGlowing, newBackGlowing, newIsWaxed, modifyingFront, line1, line2, line3, line4, line5, line6, line7, line8, 0);
|
|
}
|
|
|
|
}
|
|
|
|
}, block.getLocation());
|
|
}
|
|
}
|
|
}
|
|
else if (BlockGroup.INTERACT_BLOCKS.contains(type)) {
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && Config.getConfig(world).PLAYER_INTERACTIONS) {
|
|
Block interactBlock = event.getClickedBlock();
|
|
if (BlockGroup.DOORS.contains(type)) {
|
|
int y = interactBlock.getY() - 1;
|
|
Block blockUnder = interactBlock.getWorld().getBlockAt(interactBlock.getX(), y, interactBlock.getZ());
|
|
|
|
if (blockUnder.getType().equals(type)) {
|
|
interactBlock = blockUnder;
|
|
}
|
|
}
|
|
|
|
Queue.queuePlayerInteraction(player.getName(), interactBlock.getState(), type);
|
|
}
|
|
}
|
|
else if (BlockGroup.LIGHTABLES.contains(type)) { // extinguishing a lit block such as a campfire
|
|
BlockData blockData = block.getBlockData();
|
|
if (blockData instanceof Lightable && ((Lightable) blockData).isLit() && ((BlockGroup.CANDLES.contains(type) && event.getMaterial() == Material.AIR) || (!BlockGroup.CANDLES.contains(type) && event.getMaterial().name().endsWith("_SHOVEL")))) {
|
|
((Lightable) blockData).setLit(false);
|
|
Queue.queueBlockPlace(player.getName(), block.getState(), type, block.getState(), type, -1, 0, blockData.getAsString());
|
|
|
|
/*
|
|
BlockState blockState = block.getState();
|
|
Bukkit.getServer().getScheduler().runTask(CoreProtect.getInstance(), () -> {
|
|
try {
|
|
BlockData validateBlockData = block.getBlockData();
|
|
if (validateBlockData instanceof Lightable && !((Lightable) validateBlockData).isLit()) {
|
|
Queue.queueBlockPlace(player.getName(), blockState, type, blockState, type, -1, 0, validateBlockData.getAsString());
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
});
|
|
*/
|
|
}
|
|
else if (CampfireStartListener.useCampfireStartEvent && (type == Material.CAMPFIRE || type == Material.SOUL_CAMPFIRE)) {
|
|
ItemStack handItem = null;
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
ItemStack offHand = player.getInventory().getItemInOffHand();
|
|
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null && mainHand.getType() != Material.BUCKET) {
|
|
handItem = mainHand;
|
|
}
|
|
else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand != null) {
|
|
handItem = offHand;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
|
|
if (player.getGameMode() != GameMode.CREATIVE) {
|
|
Location location = block.getLocation();
|
|
long time = System.currentTimeMillis();
|
|
int wid = Util.getWorldId(location.getWorld().getName());
|
|
int x = location.getBlockX();
|
|
int y = location.getBlockY();
|
|
int z = location.getBlockZ();
|
|
String coordinates = x + "." + y + "." + z + "." + wid + "." + type.name();
|
|
CacheHandler.interactCache.put(coordinates, new Object[] { time, handItem, player.getName() });
|
|
}
|
|
}
|
|
|
|
isCake = type.name().endsWith(Material.CAKE.name());
|
|
}
|
|
else if (type == Material.JUKEBOX) {
|
|
BlockState blockState = block.getState();
|
|
if (blockState instanceof Jukebox) {
|
|
Jukebox jukebox = (Jukebox) blockState;
|
|
ItemStack jukeboxRecord = jukebox.isPlaying() ? jukebox.getRecord() : new ItemStack(Material.AIR);
|
|
ItemStack oldItemState = jukeboxRecord.clone();
|
|
ItemStack newItemState = new ItemStack(Material.AIR);
|
|
|
|
if (jukeboxRecord.getType() == Material.AIR) {
|
|
ItemStack handItem = null;
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
ItemStack offHand = player.getInventory().getItemInOffHand();
|
|
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null && Tag.ITEMS_MUSIC_DISCS.isTagged(mainHand.getType())) {
|
|
handItem = mainHand;
|
|
}
|
|
else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand != null && Tag.ITEMS_MUSIC_DISCS.isTagged(offHand.getType())) {
|
|
handItem = offHand;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
|
|
oldItemState = new ItemStack(Material.AIR);
|
|
newItemState = handItem.clone();
|
|
}
|
|
|
|
if (!oldItemState.equals(newItemState)) {
|
|
if (Config.getConfig(player.getWorld()).PLAYER_INTERACTIONS) {
|
|
Queue.queuePlayerInteraction(player.getName(), blockState, type);
|
|
}
|
|
|
|
if (Config.getConfig(block.getWorld()).ITEM_TRANSACTIONS) {
|
|
boolean logDrops = player.getGameMode() != GameMode.CREATIVE;
|
|
ItemStack[] oldState = new ItemStack[] { oldItemState };
|
|
ItemStack[] newState = new ItemStack[] { newItemState };
|
|
PlayerInteractEntityListener.queueContainerSpecifiedItems(player.getName(), Material.JUKEBOX, new Object[] { oldState, newState }, jukebox.getLocation(), logDrops);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (BukkitAdapter.ADAPTER.isChiseledBookshelf(type)) {
|
|
BlockState blockState = block.getState();
|
|
if (blockState instanceof BlockInventoryHolder) {
|
|
ItemStack book = BukkitAdapter.ADAPTER.getChiseledBookshelfBook(blockState, event);
|
|
if (book != null) {
|
|
ItemStack oldItemState = book.clone();
|
|
ItemStack newItemState = new ItemStack(Material.AIR);
|
|
|
|
if (book.getType() == Material.AIR) {
|
|
ItemStack handItem = null;
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
ItemStack offHand = player.getInventory().getItemInOffHand();
|
|
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null && BukkitAdapter.ADAPTER.isBookshelfBook(mainHand.getType())) {
|
|
handItem = mainHand;
|
|
}
|
|
else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand != null && BukkitAdapter.ADAPTER.isBookshelfBook(offHand.getType())) {
|
|
handItem = offHand;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
|
|
oldItemState = new ItemStack(Material.AIR);
|
|
newItemState = handItem.clone();
|
|
}
|
|
|
|
if (!oldItemState.equals(newItemState)) {
|
|
if (Config.getConfig(player.getWorld()).PLAYER_INTERACTIONS) {
|
|
Queue.queuePlayerInteraction(player.getName(), blockState, type);
|
|
}
|
|
|
|
InventoryChangeListener.inventoryTransaction(player.getName(), blockState.getLocation(), null);
|
|
}
|
|
}
|
|
else { // fallback if unable to determine bookshelf slot
|
|
InventoryChangeListener.inventoryTransaction(player.getName(), blockState.getLocation(), null);
|
|
}
|
|
}
|
|
}
|
|
else if (BukkitAdapter.ADAPTER.isDecoratedPot(type)) {
|
|
BlockState blockState = block.getState();
|
|
InventoryChangeListener.inventoryTransaction(player.getName(), blockState.getLocation(), null);
|
|
}
|
|
else if (BukkitAdapter.ADAPTER.isSuspiciousBlock(type)) {
|
|
ItemStack handItem = null;
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
ItemStack offHand = player.getInventory().getItemInOffHand();
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null) {
|
|
handItem = mainHand;
|
|
}
|
|
else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand != null) {
|
|
handItem = offHand;
|
|
}
|
|
|
|
if (handItem.getType() == Material.BRUSH) {
|
|
BlockState blockState = block.getState();
|
|
Location blockLocation = block.getLocation();
|
|
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
|
Material newType = block.getType();
|
|
if (type == newType || (newType != Material.SAND && newType != Material.GRAVEL)) {
|
|
return;
|
|
}
|
|
|
|
long systemTime = System.currentTimeMillis();
|
|
boolean logChange = true;
|
|
if (suspiciousBlockEvent.get(player.getName()) != null) {
|
|
Object[] lastEvent = suspiciousBlockEvent.get(player.getName());
|
|
long lastTime = (long) lastEvent[0];
|
|
long timeSince = systemTime - lastTime;
|
|
Location lastLocation = (Location) lastEvent[1];
|
|
if (timeSince < 5000 && blockLocation.equals(lastLocation)) {
|
|
logChange = false;
|
|
}
|
|
}
|
|
|
|
if (logChange) {
|
|
Queue.queueBlockPlace(player.getName(), blockState, newType, blockState, newType, -1, 0, null);
|
|
suspiciousBlockEvent.put(player.getName(), new Object[] { systemTime, blockLocation });
|
|
}
|
|
}, blockLocation, 100);
|
|
}
|
|
}
|
|
else if (type == Material.DRAGON_EGG) {
|
|
clickedDragonEgg(player, block);
|
|
}
|
|
|
|
if (isCake || type == Material.CAKE) {
|
|
boolean placeCandle = false;
|
|
if (type == Material.CAKE) { // check if placing a candle on a cake
|
|
Material handType = null;
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null) {
|
|
handType = mainHand.getType();
|
|
}
|
|
|
|
if (handType != null && BlockGroup.CANDLES.contains(handType) && Config.getConfig(block.getWorld()).BLOCK_PLACE) {
|
|
BlockState blockState = block.getState();
|
|
BlockData blockData = blockState.getBlockData();
|
|
Material newMaterial = Material.getMaterial(handType.name() + "_" + Material.CAKE.name());
|
|
if (newMaterial != null && ((Cake) blockData).getBites() == 0) {
|
|
Queue.queueBlockPlace(player.getName(), block.getState(), block.getType(), blockState, newMaterial, -1, 0, blockData.getAsString());
|
|
placeCandle = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!placeCandle) {
|
|
String userUUID = player.getUniqueId().toString();
|
|
Location location = player.getLocation();
|
|
long time = System.currentTimeMillis();
|
|
int wid = Util.getWorldId(location.getWorld().getName());
|
|
int x = location.getBlockX();
|
|
int y = location.getBlockY();
|
|
int z = location.getBlockZ();
|
|
String coordinates = x + "." + y + "." + z + "." + wid + "." + userUUID;
|
|
CacheHandler.interactCache.put(coordinates, new Object[] { time, Material.CAKE, block.getState() });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (event.useItemInHand() != Event.Result.DENY) {
|
|
List<Material> entityBlockTypes = Arrays.asList(Material.ARMOR_STAND, Material.END_CRYSTAL, Material.BOW, Material.CROSSBOW, Material.TRIDENT, Material.EXPERIENCE_BOTTLE, Material.SPLASH_POTION, Material.LINGERING_POTION, Material.ENDER_PEARL, Material.FIREWORK_ROCKET, Material.EGG, Material.SNOWBALL);
|
|
ItemStack handItem = null;
|
|
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
|
ItemStack offHand = player.getInventory().getItemInOffHand();
|
|
|
|
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand != null && entityBlockTypes.contains(mainHand.getType())) {
|
|
handItem = mainHand;
|
|
}
|
|
else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand != null && entityBlockTypes.contains(offHand.getType())) {
|
|
handItem = offHand;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
|
|
if (handItem.getType().equals(Material.END_CRYSTAL)) {
|
|
if (block != null && Config.getConfig(world).BLOCK_PLACE && (block.getType().equals(Material.OBSIDIAN) || block.getType().equals(Material.BEDROCK))) {
|
|
Location crystalLocation = block.getLocation().clone();
|
|
crystalLocation.setY(crystalLocation.getY() + 1);
|
|
boolean exists = false;
|
|
|
|
for (Entity entity : crystalLocation.getChunk().getEntities()) {
|
|
if (entity instanceof EnderCrystal && entity.getLocation().getBlockX() == crystalLocation.getBlockX() && entity.getLocation().getBlockY() == crystalLocation.getBlockY() && entity.getLocation().getBlockZ() == crystalLocation.getBlockZ()) {
|
|
exists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!exists) {
|
|
final Player playerFinal = player;
|
|
final Location locationFinal = crystalLocation;
|
|
Scheduler.runTask(CoreProtect.getInstance(), () -> {
|
|
try {
|
|
boolean blockExists = false;
|
|
int showingBottom = 0;
|
|
|
|
for (Entity entity : locationFinal.getChunk().getEntities()) {
|
|
if (entity instanceof EnderCrystal && entity.getLocation().getBlockX() == locationFinal.getBlockX() && entity.getLocation().getBlockY() == locationFinal.getBlockY() && entity.getLocation().getBlockZ() == locationFinal.getBlockZ()) {
|
|
EnderCrystal enderCrystal = (EnderCrystal) entity;
|
|
showingBottom = enderCrystal.isShowingBottom() ? 1 : 0;
|
|
blockExists = true;
|
|
break;
|
|
}
|
|
}
|
|
if (blockExists) {
|
|
Queue.queueBlockPlace(playerFinal.getName(), locationFinal.getBlock().getState(), locationFinal.getBlock().getType(), locationFinal.getBlock().getState(), Material.END_CRYSTAL, showingBottom, 1, null);
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}, locationFinal);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Location relativeBlockLocation = player.getLocation().clone();
|
|
relativeBlockLocation.setY(relativeBlockLocation.getY() + 1);
|
|
Location blockLocation = relativeBlockLocation.clone();
|
|
blockLocation.setY(blockLocation.getY() + 1);
|
|
|
|
if (handItem.getType() == Material.ARMOR_STAND || handItem.getType() == Material.FIREWORK_ROCKET) {
|
|
if (block == null) {
|
|
return;
|
|
}
|
|
|
|
Block relativeBlock = block.getRelative(event.getBlockFace());
|
|
relativeBlockLocation = relativeBlock.getLocation();
|
|
blockLocation = block.getLocation();
|
|
}
|
|
|
|
String relativeBlockKey = world.getName() + "-" + relativeBlockLocation.getBlockX() + "-" + relativeBlockLocation.getBlockY() + "-" + relativeBlockLocation.getBlockZ();
|
|
String blockKey = world.getName() + "-" + blockLocation.getBlockX() + "-" + blockLocation.getBlockY() + "-" + blockLocation.getBlockZ();
|
|
Object[] keys = new Object[] { System.currentTimeMillis(), relativeBlockKey, blockKey, handItem };
|
|
ConfigHandler.entityBlockMapper.put(player.getName(), keys);
|
|
}
|
|
}
|
|
}
|
|
else if (event.getAction().equals(Action.PHYSICAL)) {
|
|
Block block = event.getClickedBlock();
|
|
if (block == null || (!block.getType().equals(Material.FARMLAND) && !block.getType().equals(Material.TURTLE_EGG))) {
|
|
return;
|
|
}
|
|
|
|
World world = block.getWorld();
|
|
if (event.useInteractedBlock() != Event.Result.DENY && Config.getConfig(world).BLOCK_BREAK) {
|
|
Player player = event.getPlayer();
|
|
if (block.getType().equals(Material.FARMLAND)) {
|
|
Block blockAbove = world.getBlockAt(block.getX(), block.getY() + 1, block.getZ());
|
|
Material type = blockAbove.getType();
|
|
|
|
if (!type.equals(Material.AIR) && !type.equals(Material.CAVE_AIR)) {
|
|
/* Trampled crops, such as wheat */
|
|
Queue.queueBlockBreak(player.getName(), blockAbove.getState(), type, blockAbove.getBlockData().getAsString(), 0);
|
|
}
|
|
}
|
|
|
|
Queue.queueBlockBreak(player.getName(), block.getState(), block.getType(), block.getBlockData().getAsString(), 0);
|
|
Queue.queueBlockPlaceDelayed(player.getName(), block.getLocation(), block.getType(), null, null, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void clickedDragonEgg(Player player, Block block) {
|
|
Location location = block.getLocation();
|
|
long time = System.currentTimeMillis();
|
|
int wid = Util.getWorldId(location.getWorld().getName());
|
|
int x = location.getBlockX();
|
|
int y = location.getBlockY();
|
|
int z = location.getBlockZ();
|
|
String coordinates = x + "." + y + "." + z + "." + wid + "." + Material.DRAGON_EGG.name();
|
|
CacheHandler.interactCache.put(coordinates, new Object[] { time, Material.DRAGON_EGG, player.getName() });
|
|
}
|
|
|
|
}
|