Created
April 13, 2014 00:44
-
-
Save aadnk/10563822 to your computer and use it in GitHub Desktop.
Detect when anvils are broken by overuse.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.comphenix.example; | |
import java.util.Map; | |
import org.bukkit.Bukkit; | |
import org.bukkit.Location; | |
import org.bukkit.Material; | |
import org.bukkit.block.Block; | |
import org.bukkit.block.BlockState; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.HandlerList; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.block.Action; | |
import org.bukkit.event.inventory.InventoryClickEvent; | |
import org.bukkit.event.player.PlayerInteractEvent; | |
import org.bukkit.event.player.PlayerQuitEvent; | |
import org.bukkit.event.player.PlayerTeleportEvent; | |
import org.bukkit.plugin.Plugin; | |
import com.comphenix.protocol.PacketType; | |
import com.comphenix.protocol.ProtocolLibrary; | |
import com.comphenix.protocol.events.PacketAdapter; | |
import com.comphenix.protocol.events.PacketEvent; | |
import com.comphenix.protocol.events.PacketListener; | |
import com.comphenix.protocol.reflect.StructureModifier; | |
import com.google.common.base.Preconditions; | |
import com.google.common.collect.Maps; | |
public abstract class AnvilListener { | |
private static final int RANDOM_ANVIL_BREAK = 1020; | |
private boolean closed; | |
private PacketListener packetListener; | |
private Listener bukkitListener; | |
private Map<Player, BlockState> originalState = Maps.newConcurrentMap(); | |
/** | |
* Construct a new listener for specific Anvil events, such as being broken by overuse. | |
* @param plugin - the plugin. | |
*/ | |
public AnvilListener(Plugin plugin) { | |
Preconditions.checkNotNull(plugin, "plugin cannot be NULL"); | |
registerPackets(plugin); | |
registerBukkit(plugin); | |
} | |
private void registerPackets(Plugin plugin) { | |
ProtocolLibrary.getProtocolManager().addPacketListener( | |
packetListener = new PacketAdapter(plugin, PacketType.Play.Server.WORLD_EVENT) { | |
@SuppressWarnings("deprecation") | |
@Override | |
public void onPacketSending(PacketEvent event) { | |
Player player = event.getPlayer(); | |
StructureModifier<Integer> integers = event.getPacket().getIntegers(); | |
int effectId = integers.read(0); | |
if (effectId == RANDOM_ANVIL_BREAK) { | |
int x = integers.read(2); | |
int y = integers.read(3); | |
int z = integers.read(4); | |
final Location loc = new Location(player.getWorld(), x, y, z); | |
// Must be the same world as the receiving player | |
if (onAnvilDestroyed(loc)) { | |
// Cancel the sound | |
event.setCancelled(true); | |
// Revert to the original anvil state | |
BlockState state = originalState.get(player); | |
if (state != null) { | |
state.update(true, true); | |
player.updateInventory(); | |
} | |
} | |
} | |
} | |
}); | |
} | |
private void registerBukkit(Plugin plugin) { | |
Bukkit.getPluginManager().registerEvents(bukkitListener = new Listener() { | |
@EventHandler | |
public void onAnvilClickedEvent(PlayerInteractEvent e) { | |
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { | |
final Block block = e.getClickedBlock(); | |
if (block.getType() == Material.ANVIL) { | |
// Save this for later | |
originalState.put(e.getPlayer(), block.getState()); | |
} | |
} | |
} | |
@EventHandler | |
public void onInventoryClicked(InventoryClickEvent e) { | |
BlockState original = originalState.get(e.getWhoClicked()); | |
if (original != null) { | |
// Update block state | |
originalState.put((Player) e.getWhoClicked(), original.getBlock().getState()); | |
} | |
} | |
@EventHandler | |
public void onWorldChangedEvent(PlayerTeleportEvent e) { | |
if (e.getFrom().getWorld() != e.getTo().getWorld()) { | |
originalState.remove(e.getPlayer()); | |
} | |
} | |
@EventHandler | |
public void onPlayerQuitEvent(PlayerQuitEvent e) { | |
originalState.remove(e.getPlayer()); | |
} | |
}, plugin); | |
} | |
/** | |
* Invoked when an anvil has been destroyed due to overuse. | |
* @param loc - the anvil that was destroyed. | |
* @return TRUE to cancel the destruction, FALSE otherwise. | |
*/ | |
protected abstract boolean onAnvilDestroyed(Location loc); | |
/** | |
* Close the current anvil listener. | |
* <p> | |
* This is purely optional - any resources will be cleaned up by ProtocolLib | |
* when the current plugin is disabled. | |
*/ | |
public void close() { | |
if (!closed) { | |
closed = true; | |
ProtocolLibrary.getProtocolManager().removePacketListener(packetListener); | |
HandlerList.unregisterAll(bukkitListener); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment