Skip to content

Instantly share code, notes, and snippets.

@NeatMonster
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NeatMonster/f29b5fcb681c4231102c to your computer and use it in GitHub Desktop.
Save NeatMonster/f29b5fcb681c4231102c to your computer and use it in GitHub Desktop.
package fr.neatmonster.keylocks;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
public class KeyLocks extends JavaPlugin implements Listener {
private static final ItemStack BUNCHOFKEYS;
private static final ItemMeta BUNCHOFKEYS_META;
private static final int BUNCHOFKEYS_SIZE = 9;
private static final ItemMeta CHEST_META;
private static final ItemStack KEY;
private static final ItemStack KEY_CLONE;
private static final ItemMeta KEY_META;
private static final ItemStack MASTERKEY;
private static final ItemMeta MASTERKEY_META;
static {
KEY = new ItemStack(Material.TRIPWIRE_HOOK);
KEY_META = KEY.getItemMeta();
KEY_META.setDisplayName(ChatColor.GOLD + "Key");
KEY.setItemMeta(KEY_META);
KEY_CLONE = KEY.clone();
KEY_CLONE.setAmount(2);
BUNCHOFKEYS = new ItemStack(Material.NAME_TAG);
BUNCHOFKEYS_META = BUNCHOFKEYS.getItemMeta();
BUNCHOFKEYS_META.setDisplayName(ChatColor.GOLD + "Bunch of Keys");
BUNCHOFKEYS.setItemMeta(BUNCHOFKEYS_META);
CHEST_META = new ItemStack(Material.CHEST).getItemMeta();
CHEST_META.setDisplayName(ChatColor.GOLD + "Locked Chest");
MASTERKEY = new ItemStack(Material.TRIPWIRE_HOOK);
MASTERKEY_META = MASTERKEY.getItemMeta();
MASTERKEY_META.setDisplayName(ChatColor.GOLD + "Master Key");
MASTERKEY.setItemMeta(MASTERKEY_META);
}
private static String getChestName(final Block block) {
if (block != null && block.getType() == Material.CHEST)
return ((Chest) block.getState()).getInventory().getName();
return null;
}
private static List<String> getLore(final ItemStack item) {
final List<String> lore = new ArrayList<String>();
if (item != null && item.hasItemMeta() && item.getItemMeta().getLore() != null)
lore.addAll(item.getItemMeta().getLore());
return lore;
}
private static String getUUID(final String name) {
if (name != null && name.contains("#"))
return name.split("#")[1].replaceAll(ChatColor.COLOR_CHAR + "", "");
return null;
}
private static boolean isBunchOfKeys(final ItemStack item) {
return item != null && item.getType() == Material.NAME_TAG && item.hasItemMeta()
&& item.getItemMeta().getDisplayName().equals(BUNCHOFKEYS_META.getDisplayName());
}
private static boolean isChest(final ItemStack item) {
return item != null && item.getType() == Material.CHEST && item.hasItemMeta()
&& item.getItemMeta().getDisplayName().startsWith(CHEST_META.getDisplayName());
}
private static boolean isKey(final ItemStack item) {
return item != null && item.getType() == Material.TRIPWIRE_HOOK && item.hasItemMeta()
&& item.getItemMeta().getDisplayName().equals(KEY_META.getDisplayName());
}
private static boolean isMasterKey(final ItemStack item) {
return item != null && item.getType() == Material.TRIPWIRE_HOOK && item.hasItemMeta()
&& item.getItemMeta().getDisplayName().equals(MASTERKEY_META.getDisplayName());
}
private static String obfuscate(final String text) {
String obfuscated = "";
for (final char c : text.toCharArray())
obfuscated += ChatColor.COLOR_CHAR + "" + c;
return obfuscated;
}
private static void setChestName(final Block block, final String name) {
try {
if (block != null && block.getType() == Material.CHEST) {
final Chest chest = (Chest) block.getState();
final Field chestField = chest.getClass().getDeclaredField("chest");
chestField.setAccessible(true);
final Object tileEntityChest = chestField.get(chest);
final Method aMethod = tileEntityChest.getClass().getMethod("a", String.class);
aMethod.invoke(tileEntityChest, name);
}
} catch (final Exception e) {
e.printStackTrace();
}
}
private static void setLore(final ItemStack item, final List<String> lore) {
if (item != null) {
final ItemMeta itemMeta = item.getItemMeta();
itemMeta.setLore(lore);
item.setItemMeta(itemMeta);
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockBreak(final BlockBreakEvent event) {
final Block block = event.getBlock();
final String name = getChestName(block);
if (getUUID(name) != null) {
block.setType(Material.AIR);
final ItemStack chest = new ItemStack(Material.CHEST);
final ItemMeta chestMeta = chest.getItemMeta();
chestMeta.setDisplayName(name);
chest.setItemMeta(chestMeta);
block.getWorld().dropItemNaturally(block.getLocation(), chest);
for (final BlockFace face : Arrays.asList(BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST))
if (getChestName(block.getRelative(face)) != null)
setChestName(block.getRelative(face), null);
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent event) {
if (isKey(event.getItemInHand()) || isMasterKey(event.getItemInHand()))
event.setCancelled(true);
}
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler(ignoreCancelled = true)
public void onEntityExplode(final EntityExplodeEvent event) {
for (final Block block : new ArrayList<Block>(event.blockList()))
if (getChestName(block) != null)
event.blockList().remove(block);
}
@EventHandler(ignoreCancelled = true)
public void onInventoryClick(final InventoryClickEvent event) {
final ItemStack item = event.getCurrentItem();
final ItemStack cursor = event.getCursor();
if (isBunchOfKeys(item) && getLore(item).size() == 0)
event.setCancelled(true);
else if (event.getInventory().getName().equals(BUNCHOFKEYS_META.getDisplayName())
&& event.getRawSlot() < BUNCHOFKEYS_SIZE && item != null && (!isKey(item) || getLore(item).size() == 0)
&& cursor != null && (!isKey(cursor) || getLore(cursor).size() == 0))
event.setCancelled(true);
else if (event.getInventory().getName().equals(BUNCHOFKEYS_META.getDisplayName())
&& event.getRawSlot() < BUNCHOFKEYS_SIZE && cursor != null && isKey(cursor)
&& getLore(cursor).size() > 0)
for (int slot = 0; slot < BUNCHOFKEYS_SIZE; slot++)
if (cursor.equals(event.getInventory().getItem(slot))) {
event.setCancelled(true);
break;
} else if (event.getInventory() instanceof AnvilInventory && event.getRawSlot() == 0 && cursor != null
&& (isChest(cursor) || isKey(cursor) || isBunchOfKeys(cursor) || isMasterKey(cursor)))
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true)
public void onInventoryClose(final InventoryCloseEvent event) {
final ItemStack item = event.getPlayer().getItemInHand();
if (isBunchOfKeys(item) && getLore(item).size() == 0) {
final List<String> lore = new ArrayList<String>();
for (final ItemStack key : event.getInventory().all(Material.TRIPWIRE_HOOK).values())
lore.addAll(key.getItemMeta().getLore());
if (lore.isEmpty())
event.getPlayer().getInventory().setItemInHand(null);
else
setLore(item, lore);
}
}
@EventHandler(ignoreCancelled = true)
public void onInventoryDrag(final InventoryDragEvent event) {
final ItemStack cursor = event.getOldCursor();
if (event.getInventory().getName().equals(BUNCHOFKEYS_META.getDisplayName()))
for (final int slot : event.getRawSlots())
if (slot < BUNCHOFKEYS_SIZE && cursor != null && (!isKey(cursor) || getLore(cursor).size() == 0)) {
event.setCancelled(true);
break;
}
}
@Override
public void onLoad() {
final ShapedRecipe keyRecipe = new ShapedRecipe(KEY);
keyRecipe.shape(new String[] { "I", "L" });
keyRecipe.setIngredient('I', Material.IRON_INGOT);
keyRecipe.setIngredient('L', Material.LEVER);
getServer().addRecipe(keyRecipe);
final ShapedRecipe cloneRecipe = new ShapedRecipe(KEY_CLONE);
cloneRecipe.shape(new String[] { "TT" });
cloneRecipe.setIngredient('T', Material.TRIPWIRE_HOOK);
getServer().addRecipe(cloneRecipe);
final ShapedRecipe bunchOfKeysRecipe = new ShapedRecipe(BUNCHOFKEYS);
bunchOfKeysRecipe.shape(" S ", "STS", " S ");
bunchOfKeysRecipe.setIngredient('S', Material.STRING);
bunchOfKeysRecipe.setIngredient('T', Material.TRIPWIRE_HOOK);
getServer().addRecipe(bunchOfKeysRecipe);
final ShapedRecipe masterKeyRecipe = new ShapedRecipe(MASTERKEY);
masterKeyRecipe.shape("C", "L");
masterKeyRecipe.setIngredient('C', Material.COMMAND);
masterKeyRecipe.setIngredient('L', Material.LEVER);
getServer().addRecipe(masterKeyRecipe);
}
@EventHandler(ignoreCancelled = true)
public void onPlayerDropItem(final PlayerDropItemEvent event) {
final ItemStack item = event.getItemDrop().getItemStack();
if (isBunchOfKeys(item) && getLore(item).size() == 0)
event.setCancelled(true);
}
@EventHandler
public void onPlayerInteract(final PlayerInteractEvent event) {
final Block block = event.getClickedBlock();
final String name = getChestName(block);
final ItemStack item = event.getItem();
final boolean isKey = isKey(item);
final boolean isBunchOfKeys = isBunchOfKeys(item);
final boolean isMasterKey = isMasterKey(item);
final boolean isBlank = (isKey || isBunchOfKeys) && getLore(item).size() == 0;
String uuid = getUUID(name);
if (event.getAction() == Action.LEFT_CLICK_BLOCK && name != null && uuid == null && isKey && isBlank) {
uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
setChestName(block, CHEST_META.getDisplayName() + obfuscate("#" + uuid));
final String lore = ChatColor.BLUE + "" + block.getX() + ", " + block.getY() + ", " + block.getZ();
if (item.getAmount() == 1)
setLore(item, Arrays.asList(lore + obfuscate("#" + uuid)));
else {
item.setAmount(item.getAmount() - 1);
final ItemStack singleItem = item.clone();
singleItem.setAmount(1);
setLore(singleItem, Arrays.asList(lore + obfuscate("#" + uuid)));
event.getPlayer().getInventory().addItem(singleItem);
}
block.getWorld().playSound(block.getLocation(), Sound.ANVIL_USE, 1f, 1f);
} else if (name != null) {
if (uuid == null || isMasterKey)
return;
if (isKey && !isBlank || isBunchOfKeys)
for (final String oldLore : getLore(item))
if (uuid.equals(getUUID(oldLore))) {
final String newLore = ChatColor.BLUE + "" + block.getX() + ", " + block.getY() + ", "
+ block.getZ() + obfuscate("#" + uuid);
if (!oldLore.equals(newLore)) {
final List<String> lore = getLore(item);
lore.set(lore.indexOf(oldLore), newLore);
setLore(item, lore);
}
return;
}
block.getWorld().playSound(block.getLocation(), Sound.ITEM_BREAK, 1f, 1f);
} else if (event.getAction() == Action.RIGHT_CLICK_AIR && isBunchOfKeys) {
final Inventory inventory = getServer().createInventory(event.getPlayer(), BUNCHOFKEYS_SIZE,
item.getItemMeta().getDisplayName());
inventory.setMaxStackSize(1);
for (final String lore : getLore(item)) {
final ItemStack keyItem = KEY.clone();
setLore(keyItem, Arrays.asList(lore));
inventory.addItem(keyItem);
}
event.getPlayer().openInventory(inventory);
setLore(item, new ArrayList<String>());
} else
return;
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true)
public void onPlayerInteractEntity(final PlayerInteractEntityEvent event) {
if (isBunchOfKeys(event.getPlayer().getItemInHand()))
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true)
public void onPrepareItemCraft(final PrepareItemCraftEvent event) {
final CraftingInventory inventory = event.getInventory();
if (event.getRecipe().getResult().equals(KEY_CLONE)) {
ItemStack key = null;
ItemStack blankKey = null;
for (final ItemStack item : inventory.all(Material.TRIPWIRE_HOOK).values()) {
key = isKey(item) && getLore(item).size() > 0 ? item : key;
blankKey = isKey(item) && getLore(item).size() == 0 ? item : blankKey;
}
if (key != null && blankKey != null)
setLore(inventory.getResult(), key.getItemMeta().getLore());
else
inventory.setResult(null);
} else if (event.getRecipe().getResult().equals(BUNCHOFKEYS)) {
final ItemStack key = inventory.getItem(inventory.first(Material.TRIPWIRE_HOOK));
if (isKey(key) && getLore(key).size() > 0)
setLore(inventory.getResult(), key.getItemMeta().getLore());
else
event.getInventory().setResult(null);
}
}
}
name: KeyLocks
version: 1.0.1
author: NeatMonster
main: fr.neatmonster.keylocks.KeyLocks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment