package com.plotsquared.nukkit.listeners;
import cn.nukkit.Player;
import cn.nukkit.block.Block;
import cn.nukkit.command.CommandSender;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityCreature;
import cn.nukkit.entity.EntityHanging;
import cn.nukkit.entity.EntityHuman;
import cn.nukkit.entity.EntityLiving;
import cn.nukkit.entity.item.EntityPotion;
import cn.nukkit.entity.item.EntityVehicle;
import cn.nukkit.entity.mob.EntityMob;
import cn.nukkit.entity.passive.EntityAnimal;
import cn.nukkit.entity.passive.EntityTameable;
import cn.nukkit.entity.passive.EntityWaterAnimal;
import cn.nukkit.entity.projectile.EntityProjectile;
import cn.nukkit.event.Cancellable;
import cn.nukkit.event.Event;
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.EventPriority;
import cn.nukkit.event.Listener;
import cn.nukkit.event.block.BlockBreakEvent;
import cn.nukkit.event.block.BlockBurnEvent;
import cn.nukkit.event.block.BlockFormEvent;
import cn.nukkit.event.block.BlockGrowEvent;
import cn.nukkit.event.block.BlockPlaceEvent;
import cn.nukkit.event.block.BlockSpreadEvent;
import cn.nukkit.event.block.BlockUpdateEvent;
import cn.nukkit.event.entity.EntityBlockChangeEvent;
import cn.nukkit.event.entity.EntityCombustByEntityEvent;
import cn.nukkit.event.entity.EntityCombustEvent;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.event.entity.EntityDamageEvent;
import cn.nukkit.event.entity.EntityExplodeEvent;
import cn.nukkit.event.entity.EntitySpawnEvent;
import cn.nukkit.event.entity.ExplosionPrimeEvent;
import cn.nukkit.event.entity.ProjectileHitEvent;
import cn.nukkit.event.entity.ProjectileLaunchEvent;
import cn.nukkit.event.inventory.InventoryCloseEvent;
import cn.nukkit.event.player.PlayerBucketEmptyEvent;
import cn.nukkit.event.player.PlayerBucketFillEvent;
import cn.nukkit.event.player.PlayerChatEvent;
import cn.nukkit.event.player.PlayerCommandPreprocessEvent;
import cn.nukkit.event.player.PlayerInteractEvent;
import cn.nukkit.event.player.PlayerJoinEvent;
import cn.nukkit.event.player.PlayerMoveEvent;
import cn.nukkit.event.player.PlayerQuitEvent;
import cn.nukkit.event.player.PlayerRespawnEvent;
import cn.nukkit.event.player.PlayerTeleportEvent;
import cn.nukkit.event.potion.PotionCollideEvent;
import cn.nukkit.event.redstone.RedstoneUpdateEvent;
import cn.nukkit.metadata.MetadataValue;
import cn.nukkit.plugin.Plugin;
import com.google.common.base.Optional;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.flag.Flags;
import com.intellectualcrafters.plot.flag.IntegerFlag;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.RegExUtil;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.plotsquared.listener.PlotListener;
import com.plotsquared.nukkit.object.NukkitPlayer;
import com.plotsquared.nukkit.util.NukkitUtil;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;
public class PlayerEvents extends PlotListener implements Listener {
private boolean pistonBlocks = true;
// To prevent recursion
private boolean tmpTeleport = true;
// TODO fix this
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPhysicsEvent(BlockUpdateEvent event) {
if (event instanceof RedstoneUpdateEvent) {
Block block = event.getBlock();
Location loc = NukkitUtil.getLocation(block.getLocation());
PlotArea area = loc.getPlotArea();
if (area == null) {
return;
}
Plot plot = area.getOwnedPlot(loc);
if (plot == null) {
return;
}
if (Flags.REDSTONE.isFalse(plot)) {
event.setCancelled(true);
return;
}
if (Settings.Redstone.DISABLE_OFFLINE) {
if (UUIDHandler.getPlayer(plot.owner) == null) {
boolean disable = true;
for (UUID trusted : plot.getTrusted()) {
if (UUIDHandler.getPlayer(trusted) != null) {
disable = false;
break;
}
}
if (disable) {
event.setCancelled(true);
return;
}
}
}
if (Settings.Redstone.DISABLE_UNOCCUPIED) {
for (Map.Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
if (plot.equals(entry.getValue().getCurrentPlot())) {
return;
}
}
event.setCancelled(true);
}
} else {
Block block = event.getBlock();
Location loc = NukkitUtil.getLocation(block.getLocation());
PlotArea area = loc.getPlotArea();
if (area == null) {
return;
}
Plot plot = area.getOwnedPlotAbs(loc);
if (plot == null) {
return;
}
if (Flags.DISABLE_PHYSICS.isFalse(plot)) {
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onEntityCombustByEntity(EntityCombustEvent event) {
if (event instanceof EntityCombustByEntityEvent) {
EntityDamageByEntityEvent eventChange = new EntityDamageByEntityEvent(((EntityCombustByEntityEvent) event).getCombuster(), event.getEntity(), EntityDamageEvent.CAUSE_FIRE_TICK, event.getDuration());
onEntityDamageByEntityEvent(eventChange);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onEntityDamageByEntityEvent(EntityDamageEvent event) {
if (event instanceof EntityDamageByEntityEvent) {
EntityDamageByEntityEvent specific = (EntityDamageByEntityEvent) event;
Entity damager = specific.getDamager();
Location l = NukkitUtil.getLocation(damager);
if (!PS.get().hasPlotArea(l.getWorld())) {
return;
}
Entity victim = event.getEntity();
if (!entityDamage(damager, victim)) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onProjectileLaunch(ProjectileLaunchEvent event) {
EntityProjectile entity = event.getEntity();
if (!(entity instanceof EntityPotion)) {
return;
}
Entity shooter = entity.shootingEntity;
if (!(shooter instanceof Player)) {
return;
}
Location l = NukkitUtil.getLocation(entity);
if (!PS.get().hasPlotArea(l.getWorld())) {
return;
}
PlotPlayer pp = NukkitUtil.getPlayer((Player) shooter);
Plot plot = l.getOwnedPlot();
if (plot != null && !plot.isAdded(pp.getUUID())) {
kill(entity, event);
}
}
@EventHandler
public boolean onProjectileHit(ProjectileHitEvent event) {
EntityProjectile entity = (EntityProjectile) event.getEntity();
Location loc = NukkitUtil.getLocation(entity);
if (!PS.get().hasPlotArea(loc.getWorld())) {
return true;
}
PlotArea area = loc.getPlotArea();
if (area == null) {
return true;
}
Plot plot = area.getPlotAbs(loc);
Entity shooter = entity.shootingEntity;
if (shooter instanceof Player) {
PlotPlayer pp = NukkitUtil.getPlayer((Player) shooter);
if (plot == null) {
if (!Permissions.hasPermission(pp, C.PERMISSION_PROJECTILE_UNOWNED)) {
kill(entity, event);
return false;
}
return true;
}
if (plot.isAdded(pp.getUUID()) || Permissions.hasPermission(pp, C.PERMISSION_PROJECTILE_OTHER)) {
return true;
}
kill(entity, event);
return false;
}
if (shooter == null) {
kill(entity, event);
return false;
}
return true;
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void playerCommand(PlayerCommandPreprocessEvent event) {
String msg = event.getMessage().toLowerCase().replaceAll("/", "").trim();
if (msg.isEmpty()) {
return;
}
String[] split = msg.split(" ");
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
Plot plot = pp.getCurrentPlot();
if (plot == null) {
return;
}
Optional<List<String>> flag = plot.getFlag(Flags.BLOCKED_CMDS);
if (flag.isPresent() && !Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_BLOCKED_CMDS)) {
List<String> blocked_cmds = flag.get();
for (String s : blocked_cmds) {
Pattern pattern;
if (!RegExUtil.compiledPatterns.containsKey(s)) {
RegExUtil.compiledPatterns.put(s, pattern = Pattern.compile(s));
} else {
pattern = RegExUtil.compiledPatterns.get(s);
}
if (pattern.matcher(msg).matches()) {
String perm;
if (plot.isAdded(pp.getUUID())) {
perm = "plots.admin.command.blocked-cmds.shared";
} else {
perm = "plots.admin.command.blocked-cmds.other";
}
if (!Permissions.hasPermission(pp, perm)) {
MainUtil.sendMessage(pp, C.COMMAND_BLOCKED);
event.setCancelled(true);
}
return;
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onConnect(PlayerJoinEvent event) {
final Player player = event.getPlayer();
NukkitUtil.getPlayer(event.getPlayer()).unregister();
final PlotPlayer pp = NukkitUtil.getPlayer(player);
// Now
String name = pp.getName();
StringWrapper sw = new StringWrapper(name);
UUID uuid = pp.getUUID();
UUIDHandler.add(sw, uuid);
Location loc = pp.getLocation();
PlotArea area = loc.getPlotArea();
if (area != null) {
Plot plot = area.getPlot(loc);
if (plot != null) {
plotEntry(pp, plot);
}
}
// Delayed
// Async
TaskManager.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
if (!player.hasPlayedBefore() && player.isOnline()) {
player.save();
}
EventUtil.manager.doJoinTask(pp);
}
}, 20);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void playerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
EventUtil.manager.doRespawnTask(pp);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onTeleport(PlayerTeleportEvent event) {
if (event.getTo() == null || event.getFrom() == null) {
NukkitUtil.getPlayer(event.getPlayer()).deleteMeta("location");
NukkitUtil.getPlayer(event.getPlayer()).deleteMeta("lastplot");
return;
}
cn.nukkit.level.Location from = event.getFrom();
cn.nukkit.level.Location to = event.getTo();
int x2;
if (MathMan.roundInt(from.getX()) != (x2 = MathMan.roundInt(to.getX()))) {
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
// Cancel teleport
TaskManager.TELEPORT_QUEUE.remove(pp.getName());
// Set last location
Location loc = NukkitUtil.getLocation(to);
pp.setMeta("location", loc);
PlotArea area = loc.getPlotArea();
if (area == null) {
pp.deleteMeta("lastplot");
return;
}
Plot now = area.getPlot(loc);
Plot lastPlot = pp.getMeta("lastplot");
if (now == null) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED);
this.tmpTeleport = false;
if (lastPlot.equals(NukkitUtil.getLocation(from).getPlot())) {
player.teleport(from);
} else {
player.teleport(player.getLevel().getSpawnLocation());
}
this.tmpTeleport = true;
event.setCancelled(true);
return;
}
} else if (now.equals(lastPlot)) {
return;
} else if (!plotEntry(pp, now) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED);
this.tmpTeleport = false;
to.setComponents(from.getX(), from.getY(), from.getZ());
player.teleport(event.getTo());
this.tmpTeleport = true;
return;
}
Integer border = area.getBorder();
if (x2 > border) {
to.setComponents(border - 4, to.getY(), to.getZ());
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
return;
}
if (x2 < -border) {
to.setComponents(-border + 4, to.getY(), to.getZ());
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
return;
}
return;
}
int z2;
if (MathMan.roundInt(from.getZ()) != (z2 = MathMan.roundInt(to.getZ()))) {
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
// Cancel teleport
TaskManager.TELEPORT_QUEUE.remove(pp.getName());
// Set last location
Location loc = NukkitUtil.getLocation(to);
pp.setMeta("location", loc);
PlotArea area = loc.getPlotArea();
if (area == null) {
pp.deleteMeta("lastplot");
return;
}
Plot now = area.getPlot(loc);
Plot lastPlot = pp.getMeta("lastplot");
if (now == null) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED);
this.tmpTeleport = false;
if (lastPlot.equals(NukkitUtil.getLocation(from).getPlot())) {
player.teleport(from);
} else {
player.teleport(player.getLevel().getSpawnLocation());
}
this.tmpTeleport = true;
event.setCancelled(true);
return;
}
} else if (now.equals(lastPlot)) {
return;
} else if (!plotEntry(pp, now) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED);
this.tmpTeleport = false;
player.teleport(from);
to.setComponents(from.getX(), from.getY(), from.getZ());
player.teleport(event.getTo());
this.tmpTeleport = true;
return;
}
Integer border = area.getBorder();
if (z2 > border) {
to.setComponents(to.getX(), to.getY(), border - 4);
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
} else if (z2 < -border) {
to.setComponents(to.getX(), to.getY(), -border + 4);
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void playerMove(PlayerMoveEvent event) {
cn.nukkit.level.Location from = event.getFrom();
cn.nukkit.level.Location to = event.getTo();
int x2;
if (MathMan.roundInt(from.getX()) != (x2 = MathMan.roundInt(to.getX()))) {
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
// Cancel teleport
TaskManager.TELEPORT_QUEUE.remove(pp.getName());
// Set last location
Location loc = NukkitUtil.getLocation(to);
pp.setMeta("location", loc);
PlotArea area = loc.getPlotArea();
if (area == null) {
pp.deleteMeta("lastplot");
return;
}
Plot now = area.getPlot(loc);
Plot lastPlot = pp.getMeta("lastplot");
if (now == null) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED);
this.tmpTeleport = false;
if (lastPlot.equals(NukkitUtil.getLocation(from).getPlot())) {
player.teleport(from);
} else {
player.teleport(player.getLevel().getSpawnLocation());
}
this.tmpTeleport = true;
event.setCancelled(true);
return;
}
} else if (now.equals(lastPlot)) {
return;
} else if (!plotEntry(pp, now) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED);
this.tmpTeleport = false;
to.setComponents(from.getX(), from.getY(), from.getZ());
player.teleport(event.getTo());
this.tmpTeleport = true;
return;
}
Integer border = area.getBorder();
if (x2 > border) {
to.setComponents(border - 4, to.getY(), to.getZ());
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
return;
}
if (x2 < -border) {
to.setComponents(-border + 4, to.getY(), to.getZ());
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
return;
}
return;
}
int z2;
if (MathMan.roundInt(from.getZ()) != (z2 = MathMan.roundInt(to.getZ()))) {
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
// Cancel teleport
TaskManager.TELEPORT_QUEUE.remove(pp.getName());
// Set last location
Location loc = NukkitUtil.getLocation(to);
pp.setMeta("location", loc);
PlotArea area = loc.getPlotArea();
if (area == null) {
pp.deleteMeta("lastplot");
return;
}
Plot now = area.getPlot(loc);
Plot lastPlot = pp.getMeta("lastplot");
if (now == null) {
if (lastPlot != null && !plotExit(pp, lastPlot) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED);
this.tmpTeleport = false;
if (lastPlot.equals(NukkitUtil.getLocation(from).getPlot())) {
player.teleport(from);
} else {
player.teleport(player.getLevel().getSpawnLocation());
}
this.tmpTeleport = true;
event.setCancelled(true);
return;
}
} else if (now.equals(lastPlot)) {
return;
} else if (!plotEntry(pp, now) && this.tmpTeleport) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED);
this.tmpTeleport = false;
player.teleport(from);
to.setComponents(from.getX(), from.getY(), from.getZ());
player.teleport(event.getTo());
this.tmpTeleport = true;
return;
}
Integer border = area.getBorder();
if (z2 > border) {
to.setComponents(to.getX(), to.getY(), border - 4);
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
} else if (z2 < -border) {
to.setComponents(to.getX(), to.getY(), -border + 4);
this.tmpTeleport = false;
player.teleport(event.getTo());
this.tmpTeleport = true;
MainUtil.sendMessage(pp, C.BORDER);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onChat(PlayerChatEvent event) {
PlotPlayer plotPlayer = NukkitUtil.getPlayer(event.getPlayer());
Location location = plotPlayer.getLocation();
PlotArea area = location.getPlotArea();
if (area == null || (area.PLOT_CHAT == plotPlayer.getAttribute("chat"))) {
return;
}
Plot plot = area.getPlot(location);
if (plot == null) {
return;
}
event.setCancelled(true);
String message = event.getMessage();
String format = C.PLOT_CHAT_FORMAT.s();
String sender = event.getPlayer().getDisplayName();
PlotId id = plot.getId();
Set<CommandSender> recipients = event.getRecipients();
recipients.clear();
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue();
if (pp.getAttribute("chatspy")) {
String spy = event.getFormat();
spy = String.format(spy, sender, message);
pp.sendMessage(spy);
} else {
Plot current = pp.getCurrentPlot();
if (current != null && current.getBasePlot(false).equals(plot)) {
recipients.add(((NukkitPlayer) pp).player);
}
}
}
String partial = C.color(format.replace("%plot_id%", id.x + ";" + id.y).replace("%sender%", sender));
String full = partial.replace("%msg%", message);
for (CommandSender receiver : recipients) {
receiver.sendMessage(full);
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void blockDestroy(BlockBreakEvent event) {
Player player = event.getPlayer();
Location location = NukkitUtil.getLocation(event.getBlock().getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = area.getPlotAbs(location);
if (plot != null) {
PlotPlayer plotPlayer = NukkitUtil.getPlayer(player);
if (event.getBlock().getY() == 0) {
if (!Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL);
event.setCancelled(true);
return;
}
}
if (!plot.hasOwner()) {
if (Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_DESTROY_UNOWNED)) {
return;
}
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_UNOWNED);
event.setCancelled(true);
return;
}
if (!plot.isAdded(plotPlayer.getUUID())) {
Optional<HashSet<PlotBlock>> destroy = plot.getFlag(Flags.BREAK);
Block block = event.getBlock();
if (destroy.isPresent() && destroy.get()
.contains(PlotBlock.get((short) block.getId(), block.getDamage()))) {
return;
}
if (Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_DESTROY_OTHER)) {
return;
}
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_OTHER);
event.setCancelled(true);
} else if (Settings.Done.RESTRICT_BUILDING && plot.getFlags().containsKey(Flags.DONE)) {
if (!Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_BUILD_OTHER)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
event.setCancelled(true);
return;
}
}
return;
}
PlotPlayer pp = NukkitUtil.getPlayer(player);
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_ROAD)) {
return;
}
if (PS.get().worldedit != null && pp.getAttribute("worldedit")) {
if (player.getInventory().getItemInHand().getId() == PS.get().worldedit.getConfiguration().wandItem) {
return;
}
}
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_ROAD);
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBigBoom(ExplosionPrimeEvent event) {
Entity entity = event.getEntity();
Location location = NukkitUtil.getLocation(entity);
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
final Plot finalPlot = area.getOwnedPlot(location);
if (!entity.hasMetadata("plot")) {
entity.setMetadata("plot", new MetadataValue((Plugin) PS.get().IMP) {
private Plot plot = finalPlot;
@Override
public Object value() {
return plot;
}
@Override
public void invalidate() {
plot = null;
}
});
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBigBoom(EntityExplodeEvent event) {
Location location = NukkitUtil.getLocation(event.getPosition());
PlotArea area = location.getPlotArea();
if (area == null) {
if (!PS.get().hasPlotArea(location.getWorld())) {
return;
}
Iterator<Block> iterator = event.getBlockList().iterator();
while (iterator.hasNext()) {
iterator.next();
if (location.getPlotArea() != null) {
iterator.remove();
}
}
return;
}
Plot plot = area.getOwnedPlot(location);
if (plot != null) {
if (Flags.EXPLOSION.isTrue(plot)) {
List<MetadataValue> meta = event.getEntity().getMetadata("plot");
Plot origin;
if (meta.isEmpty()) {
origin = plot;
} else {
origin = (Plot) meta.get(0).value();
}
Iterator<Block> iterator = event.getBlockList().iterator();
while (iterator.hasNext()) {
Block block = iterator.next();
location = NukkitUtil.getLocation(block.getLocation());
if (!area.contains(location.getX(), location.getZ()) || !origin.equals(area.getOwnedPlot(location))) {
iterator.remove();
}
}
return;
}
}
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEntityBlockForm(BlockFormEvent event) {
String world = event.getBlock().getLevel().getName();
if (!PS.get().hasPlotArea(world)) {
return;
}
if (NukkitUtil.getLocation(event.getBlock().getLocation()).getPlotArea() != null) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockSpread(BlockSpreadEvent event) {
Block block = event.getBlock();
Location location = NukkitUtil.getLocation(block.getLocation());
if (location.isPlotRoad()) {
event.setCancelled(true);
return;
}
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = area.getOwnedPlot(location);
if (plot == null) {
return;
}
Block source = event.getSource();
switch (source.getId()) {
case 2:
if (Flags.GRASS_GROW.isFalse(plot)) {
event.setCancelled(true);
}
break;
case 110:
if (Flags.MYCEL_GROW.isFalse(plot)) {
event.setCancelled(true);
}
break;
case 106:
if (Flags.VINE_GROW.isFalse(plot)) {
event.setCancelled(true);
}
break;
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onGrow(BlockGrowEvent event) {
Block b = event.getBlock();
Location location = NukkitUtil.getLocation(b.getLocation());
if (location.isUnownedPlotArea()) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
PlotArea area = pp.getPlotAreaAbs();
if (area == null) {
return;
}
switch (event.getAction()) {
case PlayerInteractEvent.RIGHT_CLICK_BLOCK:
case PlayerInteractEvent.LEFT_CLICK_BLOCK:
case PlayerInteractEvent.PHYSICAL: {
Plot plot = pp.getCurrentPlot();
if (plot == null || !plot.isAdded(pp.getUUID())) {
Block block = event.getBlock();
if (block != null) {
if (plot != null && Flags.USE.contains(plot, PlotBlock.get(block.getId(), block.getDamage()))) {
return;
}
}
if (plot == null) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_ROAD.s(), true)) {
return;
}
} else if (!plot.hasOwner()) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_UNOWNED.s(), true)) {
return;
}
} else if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_OTHER.s(), true)) {
return;
}
event.setCancelled(true);
return;
}
return;
}
case PlayerInteractEvent.LEFT_CLICK_AIR:
case PlayerInteractEvent.RIGHT_CLICK_AIR: {
Plot plot = pp.getCurrentPlot();
if (plot == null || !plot.isAdded(pp.getUUID())) {
if (plot == null) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_ROAD.s(), true)) {
return;
}
} else if (!plot.hasOwner()) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_UNOWNED.s(), true)) {
return;
}
} else if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_INTERACT_OTHER.s(), true)) {
return;
}
event.setCancelled(true);
return;
}
return;
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void creatureSpawnEvent(EntitySpawnEvent event) {
Entity entity = event.getEntity();
Location location = NukkitUtil.getLocation(entity.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = area.getOwnedPlotAbs(location);
if (plot == null) {
if (!area.MOB_SPAWNING) {
kill(entity, event);
}
return;
}
if (checkEntity(entity, plot)) {
kill(entity, event);
}
}
private void kill(Entity entity, Event event) {
if (event instanceof Cancellable) {
event.setCancelled(true);
}
entity.kill();
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onEntityFall(EntityBlockChangeEvent event) {
Entity entity = event.getEntity();
Location location = NukkitUtil.getLocation(entity);
if (!PS.get().hasPlotArea(location.getWorld())) {
return;
}
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Block from = event.getFrom();
Block to = event.getTo();
final Plot finalPlot = area.getOwnedPlotAbs(location);
boolean toBlock = from == null || from.getId() == 0;
if (toBlock) {
List<MetadataValue> meta = entity.getMetadata("plot");
if (meta.isEmpty()) {
return;
}
Plot origin = (Plot) meta.get(0).value();
if (origin != null && !origin.equals(finalPlot)) {
kill(entity, event);
}
} else {
entity.setMetadata("plot", new MetadataValue((Plugin) PS.get().IMP) {
private Plot plot = finalPlot;
@Override
public Object value() {
return plot;
}
@Override
public void invalidate() {
plot = null;
}
});
}
}
public static boolean checkEntity(Plot plot, IntegerFlag... flags) {
if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(plot)) {
return true;
}
int[] mobs = null;
for (IntegerFlag flag : flags) {
int i;
switch (flag.getName()) {
case "entity-cap":
i = 0;
break;
case "mob-cap":
i = 3;
break;
case "hostile-cap":
i = 2;
break;
case "animal-cap":
i = 1;
break;
case "vehicle-cap":
i = 4;
break;
case "misc-cap":
i = 5;
break;
default:
i = 0;
}
int cap = plot.getFlag(flag, Integer.MAX_VALUE);
if (cap == Integer.MAX_VALUE) {
continue;
}
if (cap == 0) {
return true;
}
if (mobs == null) {
mobs = plot.countEntities();
}
if (mobs[i] >= cap) {
plot.setMeta("EntityCount", mobs);
plot.setMeta("EntityCountTime", System.currentTimeMillis());
return true;
}
}
if (mobs != null) {
for (IntegerFlag flag : flags) {
int i;
switch (flag.getName()) {
case "entity-cap":
i = 0;
break;
case "mob-cap":
i = 3;
break;
case "hostile-cap":
i = 2;
break;
case "animal-cap":
i = 1;
break;
case "vehicle-cap":
i = 4;
break;
case "misc-cap":
i = 5;
break;
default:
i = 0;
}
mobs[i]++;
}
plot.setMeta("EntityCount", mobs);
plot.setMeta("EntityCountTime", System.currentTimeMillis());
}
return false;
}
public static boolean checkEntity(Entity entity, Plot plot) {
if (plot == null || !plot.hasOwner() || plot.getFlags().isEmpty() && plot.getArea().DEFAULT_FLAGS.isEmpty()) {
return false;
}
if (entity instanceof EntityLiving) {
if (entity instanceof EntityCreature) {
if (entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal) {
return checkEntity(plot, Flags.ENTITY_CAP, Flags.MOB_CAP, Flags.ANIMAL_CAP);
} else if (entity instanceof EntityMob) {
return checkEntity(plot, Flags.ENTITY_CAP, Flags.MOB_CAP, Flags.HOSTILE_CAP);
} else if (entity instanceof EntityHuman){
return false;
} else {
return checkEntity(plot, Flags.ENTITY_CAP, Flags.MOB_CAP, Flags.MOB_CAP);
}
} else {
return checkEntity(plot, Flags.ENTITY_CAP, Flags.MOB_CAP);
}
} else if (entity instanceof EntityVehicle) {
return checkEntity(plot, Flags.ENTITY_CAP, Flags.VEHICLE_CAP);
} else if (entity instanceof EntityHanging){
return checkEntity(plot, Flags.ENTITY_CAP, Flags.MISC_CAP);
} else {
return checkEntity(plot, Flags.ENTITY_CAP);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBurn(BlockBurnEvent event) {
Block b = event.getBlock();
Location location = NukkitUtil.getLocation(b.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null || !plot.getFlag(Flags.BLOCK_BURN, false)) {
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
Block block = event.getBlockClicked();
Block b = block.getSide(event.getBlockFace());
Location location = NukkitUtil.getLocation(b.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
PlotPlayer pp = NukkitUtil.getPlayer(event.getPlayer());
Plot plot = area.getPlotAbs(location);
if (plot == null) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_ROAD)) {
return;
}
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_ROAD);
event.setCancelled(true);
} else if (!plot.hasOwner()) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_UNOWNED)) {
return;
}
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_UNOWNED);
event.setCancelled(true);
} else if (!plot.isAdded(pp.getUUID())) {
if (Flags.USE.contains(plot, PlotBlock.get(event.getBucket().getId(), 0))) {
return;
}
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER)) {
return;
}
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryClose(InventoryCloseEvent event) {
NukkitUtil.getPlayer(event.getPlayer()).deleteMeta("inventory");
}
@EventHandler(priority = EventPriority.MONITOR)
public void onLeave(PlayerQuitEvent event) {
if (TaskManager.TELEPORT_QUEUE.contains(event.getPlayer().getName())) {
TaskManager.TELEPORT_QUEUE.remove(event.getPlayer().getName());
}
PlotPlayer pp = NukkitUtil.getPlayer(event.getPlayer());
pp.unregister();
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBucketFill(PlayerBucketFillEvent event) {
Block b = event.getBlockClicked();
Location location = NukkitUtil.getLocation(b.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Player player = event.getPlayer();
PlotPlayer plotPlayer = NukkitUtil.getPlayer(player);
Plot plot = area.getPlotAbs(location);
if (plot == null) {
if (Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_BUILD_ROAD)) {
return;
}
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_ROAD);
event.setCancelled(true);
} else if (!plot.hasOwner()) {
if (Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_BUILD_UNOWNED)) {
return;
}
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_UNOWNED);
event.setCancelled(true);
} else if (!plot.isAdded(plotPlayer.getUUID())) {
Optional<HashSet<PlotBlock>> use = plot.getFlag(Flags.USE);
Block block = event.getBlockClicked();
if (use.isPresent() && use.get().contains(PlotBlock.get(block.getId(), block.getDamage()))) {
return;
}
if (Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_BUILD_OTHER)) {
return;
}
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPotionSplash(PotionCollideEvent event) {
EntityPotion entity = event.getThrownPotion();
Location l = NukkitUtil.getLocation(entity);
if (!PS.get().hasPlotArea(l.getWorld())) {
return;
}
Entity shooter = entity.shootingEntity;
if (shooter instanceof Player) {
PlotPlayer pp = NukkitUtil.getPlayer((Player) shooter);
Plot plot = l.getOwnedPlotAbs();
if (plot == null) {
if (!Permissions.hasPermission(pp, C.PERMISSION_PROJECTILE_UNOWNED)) {
kill(entity, event);
return;
}
return;
}
if (plot.isAdded(pp.getUUID()) || Permissions.hasPermission(pp, C.PERMISSION_PROJECTILE_OTHER)) {
return;
}
kill(entity, event);
return;
}
if (shooter == null) {
kill(entity, event);
return;
}
}
public boolean entityDamage(Entity damager, Entity victim) {
Location dloc = NukkitUtil.getLocation(damager);
Location vloc = NukkitUtil.getLocation(victim);
PlotArea dArea = dloc.getPlotArea();
PlotArea vArea = dArea != null && dArea.contains(vloc.getX(), vloc.getZ()) ? dArea : vloc.getPlotArea();
if (dArea == null && vArea == null) {
return true;
}
Plot dplot = dArea != null ? dArea.getPlot(dloc) : null;
Plot vplot = vArea != null ? vArea.getPlot(vloc) : null;
Plot plot;
String stub;
if (dplot == null && vplot == null) {
if (dArea == null) {
return true;
}
plot = null;
stub = "road";
} else {
// Prioritize plots for close to seamless pvp zones
if (victim.ticksLived > damager.ticksLived) {
if (dplot == null || !(victim instanceof Player)) {
if (vplot == null) {
plot = dplot;
} else {
plot = vplot;
}
} else {
plot = dplot;
}
} else if (dplot == null || !(victim instanceof Player)) {
if (vplot == null) {
plot = dplot;
} else {
plot = vplot;
}
} else if (vplot == null) {
plot = dplot;
} else {
plot = vplot;
}
if (plot.hasOwner()) {
stub = "other";
} else {
stub = "unowned";
}
}
Player player;
if (damager instanceof Player) { // attacker is player
player = (Player) damager;
} else if (damager instanceof EntityProjectile) {
EntityProjectile projectile = (EntityProjectile) damager;
Entity shooter = projectile.shootingEntity;
if (shooter instanceof Player) { // shooter is player
player = (Player) shooter;
} else { // shooter is not player
player = null;
}
} else { // Attacker is not player
player = null;
}
if (player != null) {
PlotPlayer plotPlayer = NukkitUtil.getPlayer(player);
if (victim instanceof EntityHanging) { // hanging
if (plot != null && (plot.getFlag(Flags.HANGING_BREAK, false) || plot.isAdded(plotPlayer.getUUID()))) {
return true;
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.destroy." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.destroy." + stub);
return false;
}
} else if (false) { // TODO armor stand
if (plot != null && (plot.getFlag(Flags.MISC_BREAK, false) || plot.isAdded(plotPlayer.getUUID()))) {
return true;
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.destroy." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.destroy." + stub);
return false;
}
} else if (victim instanceof EntityMob) { // victim is monster
if (plot != null && (plot.getFlag(Flags.HOSTILE_ATTACK, false) || plot.getFlag(Flags.PVE, false) || plot
.isAdded(plotPlayer.getUUID()))) {
return true;
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.pve." + stub);
return false;
}
} else if (victim instanceof EntityTameable) {
if (plot != null && (plot.getFlag(Flags.TAMED_ATTACK, false) || plot.getFlag(Flags.PVE, false) || plot.isAdded(plotPlayer.getUUID()))) {
return true;
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.pve." + stub);
return false;
}
} else if (victim instanceof Player) {
if (plot != null) {
if (Flags.PVP.isFalse(plot) && !Permissions.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.pvp." + stub);
return false;
} else {
return true;
}
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.pvp." + stub);
return false;
}
} else if (victim instanceof EntityCreature) { // victim is animal
if (plot != null && (plot.getFlag(Flags.ANIMAL_ATTACK, false) || plot.getFlag(Flags.PVE, false) || plot
.isAdded(plotPlayer.getUUID()))) {
return true;
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.pve." + stub);
return false;
}
} else if (victim instanceof EntityVehicle) { // Vehicles are managed in vehicle destroy event
return true;
} else { // victim is something else
if (plot != null && (plot.getFlag(Flags.PVE, false) || plot.isAdded(plotPlayer.getUUID()))) {
return true;
}
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, "plots.admin.pve." + stub);
return false;
}
}
return true;
}
// player is null
return !(damager instanceof EntityProjectile && !(victim instanceof EntityCreature));
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void blockCreate(BlockPlaceEvent event) {
Location location = NukkitUtil.getLocation(event.getBlock().getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Player player = event.getPlayer();
PlotPlayer pp = NukkitUtil.getPlayer(player);
Plot plot = area.getPlotAbs(location);
if (plot != null) {
if (!plot.hasOwner()) {
if (!Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_UNOWNED)) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_UNOWNED);
event.setCancelled(true);
return;
}
} else if (!plot.isAdded(pp.getUUID())) {
Set<PlotBlock> place = plot.getFlag(Flags.PLACE, null);
if (place != null) {
Block block = event.getBlock();
if (place.contains(PlotBlock.get((short) block.getId(), block.getDamage()))) {
return;
}
}
if (!Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER)) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
event.setCancelled(true);
return;
}
} else if (Settings.Done.RESTRICT_BUILDING && plot.getFlags().containsKey(Flags.DONE)) {
if (!Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER)) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
event.setCancelled(true);
return;
}
}
if (location.getY() > area.MAX_BUILD_HEIGHT && location.getY() < area.MIN_BUILD_HEIGHT && !Permissions
.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_HEIGHTLIMIT)) {
event.setCancelled(true);
MainUtil.sendMessage(pp, C.HEIGHT_LIMIT.s().replace("{limit}", String.valueOf(area.MAX_BUILD_HEIGHT)));
}
} else if (!Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER)) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_ROAD);
event.setCancelled(true);
}
}
}