Skip to content

Instantly share code, notes, and snippets.

@aadnk
Created April 13, 2014 00:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aadnk/10563822 to your computer and use it in GitHub Desktop.
Save aadnk/10563822 to your computer and use it in GitHub Desktop.
Detect when anvils are broken by overuse.
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