/* * This file is part of Libelula Minecraft Edition Project. * * Libelula Minecraft Edition is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Libelula Minecraft Edition is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Libelula Minecraft Edition. * If not, see <http://www.gnu.org/licenses/>. * */ package me.libelula.survival; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.TreeMap; import java.util.concurrent.locks.ReentrantLock; import me.libelula.networkmanager.Main; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; 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.BlockPlaceEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerQuitEvent; /** * * @author Diego D'Onofrio <ddonofrio@member.fsf.org> */ public class EventManager implements Listener { private final Main plugin; private final TreeMap<String, List<Location>> lastEdited; private final TreeMap<String, Long> timeToEdit; private final ReentrantLock _lastEdited_mutex; public EventManager(Main plugin) { this.plugin = plugin; this.lastEdited = new TreeMap<>(); this.timeToEdit = new TreeMap<>(); this._lastEdited_mutex = new ReentrantLock(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerQuit(PlayerBucketEmptyEvent e) { if (e.getBucket().equals(Material.LAVA_BUCKET) && !e.getPlayer().hasPermission("lnm.survival.allow-lava")) { e.getPlayer().sendMessage(plugin.getPrefix() + ChatColor.RED + "Debido a tu rango no tienes permitido poner lava."); e.setCancelled(true); } } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onBlockPlace(BlockPlaceEvent e) { if (!e.getPlayer().hasPermission("lnm.lnm.survival.allow-tnt") && e.getBlock().getType() == Material.TNT) { e.setCancelled(true); e.getPlayer().sendMessage(plugin.getPrefix() + ChatColor.RED + "Debido a tu rango no tienes permitido poner TNT."); } else if (!e.getPlayer().hasPermission("lnm.survival.allow-vertical-place") && !canEdit(e.getPlayer(), e.getBlock().getLocation(), true)) { e.setCancelled(true); } } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent e) { if (!e.getPlayer().hasPermission("lnm.survival.allow-vertical-break") && !canEdit(e.getPlayer(), e.getBlock().getLocation(), false)) { e.setCancelled(true); } } private boolean canEdit(Player player, Location location, boolean placed) { boolean ret = true; _lastEdited_mutex.lock(); try { List<Location> lastBlocks = lastEdited.get(player.getName()); if (lastBlocks == null) { lastBlocks = new ArrayList<>(); lastEdited.put(player.getName(), lastBlocks); } else if (lastBlocks.size() < 5) { lastBlocks.add(location); } else { Long time = timeToEdit.get(player.getName()); if (time != null) { long now = new Date().getTime(); if (now < time) { int left = (int) (time - now) / 1000; if (left > 0) { player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Ahora deberás esperar " + left + " segundos para volver a poner un bloque."); ret = false; } } else { timeToEdit.remove(player.getName()); } } if (ret) { lastBlocks.remove(0); lastBlocks.add(location); boolean verticalPlaced = true; int direction; if (placed) { direction = -1; } else { direction = 1; } for (int i = lastBlocks.size() - 1; i > 0; i--) { if (lastBlocks.get(i).getBlockX() != lastBlocks.get(i - 1).getBlockX() || lastBlocks.get(i).getBlockZ() != lastBlocks.get(i - 1).getBlockZ() || lastBlocks.get(i).getBlockY() == lastBlocks.get(i - 1).getBlockY() + direction) { verticalPlaced = false; } } if (verticalPlaced) { if (placed) { player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Debido a tu rango no tienes permitido poner más bloques en una sola fila."); } else { player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Debido a tu rango no tienes permitido cabar más blocues en la misma fila."); } ret = false; timeToEdit.put(player.getName(), new Date().getTime() + 5000); } } } } finally { _lastEdited_mutex.unlock(); } return ret; } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerQuit(PlayerQuitEvent e) { _lastEdited_mutex.lock(); try { lastEdited.remove(e.getPlayer().getName()); timeToEdit.remove(e.getPlayer().getName()); } finally { _lastEdited_mutex.unlock(); } } }