@EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerInteract(PlayerInteractEvent event) {
    if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.useInteractedBlock() == Result.DENY)
      return;

    if (event.getAction() == Action.RIGHT_CLICK_BLOCK
        && event.getClickedBlock().getState() instanceof Chest) {
      boolean silentchest = false;
      boolean anychest = false;
      int x = event.getClickedBlock().getX();
      int y = event.getClickedBlock().getY();
      int z = event.getClickedBlock().getZ();

      if (PermissionRelay.hasPermission(event.getPlayer(), "silent")
          && OpenInv.GetPlayerSilentChestStatus(event.getPlayer().getName())) {
        silentchest = true;
      }

      if (PermissionRelay.hasPermission(event.getPlayer(), "anychest")
          && OpenInv.GetPlayerAnyChestStatus(event.getPlayer().getName())) {
        try {
          // FOR REFERENCE, LOOK AT net.minecraft.server.BlockChest
          EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
          World world = player.world;
          // If block on top
          if (world.e(x, y + 1, z)) anychest = true;

          // If block next to chest is chest and has a block on top
          if ((world.getTypeId(x - 1, y, z) == Block.CHEST.id) && (world.e(x - 1, y + 1, z)))
            anychest = true;
          if ((world.getTypeId(x + 1, y, z) == Block.CHEST.id) && (world.e(x + 1, y + 1, z)))
            anychest = true;
          if ((world.getTypeId(x, y, z - 1) == Block.CHEST.id) && (world.e(x, y + 1, z - 1)))
            anychest = true;
          if ((world.getTypeId(x, y, z + 1) == Block.CHEST.id) && (world.e(x, y + 1, z + 1)))
            anychest = true;
        } catch (Exception e) {
          event
              .getPlayer()
              .sendMessage(
                  ChatColor.RED + "Error while executing openinv. Unsupported CraftBukkit.");
          e.printStackTrace();
        }
      }

      // If the anychest or silentchest is active
      if (anychest || silentchest) {
        EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
        World world = player.world;
        Object chest = (TileEntityChest) world.getTileEntity(x, y, z);
        if (chest == null) return;

        if (!anychest) {
          if (world.e(x, y + 1, z)) return;
          if ((world.getTypeId(x - 1, y, z) == Block.CHEST.id) && (world.e(x - 1, y + 1, z)))
            return;
          if ((world.getTypeId(x + 1, y, z) == Block.CHEST.id) && (world.e(x + 1, y + 1, z)))
            return;
          if ((world.getTypeId(x, y, z - 1) == Block.CHEST.id) && (world.e(x, y + 1, z - 1)))
            return;
          if ((world.getTypeId(x, y, z + 1) == Block.CHEST.id) && (world.e(x, y + 1, z + 1)))
            return;
        }

        if (world.getTypeId(x - 1, y, z) == Block.CHEST.id)
          chest =
              new InventoryLargeChest(
                  "Large chest",
                  (TileEntityChest) world.getTileEntity(x - 1, y, z),
                  (IInventory) chest);
        if (world.getTypeId(x + 1, y, z) == Block.CHEST.id)
          chest =
              new InventoryLargeChest(
                  "Large chest",
                  (IInventory) chest,
                  (TileEntityChest) world.getTileEntity(x + 1, y, z));
        if (world.getTypeId(x, y, z - 1) == Block.CHEST.id)
          chest =
              new InventoryLargeChest(
                  "Large chest",
                  (TileEntityChest) world.getTileEntity(x, y, z - 1),
                  (IInventory) chest);
        if (world.getTypeId(x, y, z + 1) == Block.CHEST.id)
          chest =
              new InventoryLargeChest(
                  "Large chest",
                  (IInventory) chest,
                  (TileEntityChest) world.getTileEntity(x, y, z + 1));

        if (!silentchest) {
          player.a((IInventory) chest);
        } else {
          try {
            Field windowID;
            try {
              windowID = player.getClass().getDeclaredField("cl");
            } catch (NoSuchFieldException e) {
              windowID = player.getClass().getDeclaredField("ci");
            }
            windowID.setAccessible(true);
            int id = windowID.getInt(player);
            id = id % 100 + 1;
            windowID.setInt(player, id);
            player.netServerHandler.sendPacket(
                new Packet100OpenWindow(
                    id, 0, ((IInventory) chest).getName(), ((IInventory) chest).getSize()));
            player.activeContainer =
                new SilentContainerChest(player.inventory, ((IInventory) chest));
            player.activeContainer.windowId = id;
            player.activeContainer.a((ICrafting) player);
            event.getPlayer().sendMessage("You are opening a chest silently.");
            event.setUseInteractedBlock(Result.DENY);
            event.setCancelled(true);
          } catch (Exception e) {
            e.printStackTrace();
            event.getPlayer().sendMessage(ChatColor.RED + "Error while sending silent chest.");
          }
        }

        if (anychest) event.getPlayer().sendMessage("You are opening a blocked chest.");
      }
    }

    if (event.getAction() == Action.RIGHT_CLICK_BLOCK
        && event.getClickedBlock().getState() instanceof Sign) {
      Player player = event.getPlayer();
      try {
        Sign sign = ((Sign) event.getClickedBlock().getState());
        if (PermissionRelay.hasPermission(player, "openinv")
            && sign.getLine(0).equalsIgnoreCase("[openinv]")) {
          String text = sign.getLine(1).trim() + sign.getLine(2).trim() + sign.getLine(3).trim();
          player.performCommand("openinv " + text);
        }
      } catch (Exception ex) {
        player.sendMessage("Internal Error.");
        ex.printStackTrace();
      }
    }

    if (event.getAction() == Action.RIGHT_CLICK_AIR
        || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
      Player player = event.getPlayer();

      if (!(player.getItemInHand().getType().getId() == OpenInv.GetItemOpenInvItem())
          || (!OpenInv.GetPlayerItemOpenInvStatus(player.getName()))
          || !PermissionRelay.hasPermission(player, "openinv")) {
        return;
      }

      player.performCommand("openinv");
    }
  }
  @Override
  public void onPlayerInteract(PlayerInteractEvent event) {
    if (event.useInteractedBlock() == Result.DENY || event.isCancelled()) return;

    boolean silentchest = false;
    boolean anychest = false;
    int x = event.getClickedBlock().getX();
    int y = event.getClickedBlock().getY();
    int z = event.getClickedBlock().getZ();

    if (event.getAction() == Action.RIGHT_CLICK_BLOCK
        && event.getClickedBlock().getState() instanceof Chest
        && PermissionRelay.hasPermission(event.getPlayer(), "OpenInv.silent")
        && OpenInv.GetPlayerSilentChestStatus(event.getPlayer().getName())) {
      silentchest = true;
    }

    if (event.getAction() == Action.RIGHT_CLICK_BLOCK
        && event.getClickedBlock().getState() instanceof Chest
        && PermissionRelay.hasPermission(event.getPlayer(), "OpenInv.anychest")) {
      try {
        EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
        World world = player.world;
        // If block on top
        if (world.e(x, y + 1, z)) anychest = true;

        // If block next to chest is chest and has a block on top
        if ((world.getTypeId(x - 1, y, z) == Block.CHEST.id) && (world.e(x - 1, y + 1, z)))
          anychest = true;
        if ((world.getTypeId(x + 1, y, z) == Block.CHEST.id) && (world.e(x + 1, y + 1, z)))
          anychest = true;
        if ((world.getTypeId(x, y, z - 1) == Block.CHEST.id) && (world.e(x, y + 1, z - 1)))
          anychest = true;
        if ((world.getTypeId(x, y, z + 1) == Block.CHEST.id) && (world.e(x, y + 1, z + 1)))
          anychest = true;
      } catch (Exception e) // Incompatible CraftBukkit?
      {
        e.printStackTrace();
        event
            .getPlayer()
            .sendMessage(ChatColor.RED + "Error while executing openinv. Unsupported CraftBukkit.");
      }
    }

    // If the chest is blocked
    if (anychest || silentchest) {
      EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
      World world = player.world;
      Object chest = (TileEntityChest) world.getTileEntity(x, y, z);
      if (chest == null) return;

      if (!anychest) {
        if (world.e(x, y + 1, z)) return;
        if ((world.getTypeId(x - 1, y, z) == Block.CHEST.id) && (world.e(x - 1, y + 1, z))) return;
        if ((world.getTypeId(x + 1, y, z) == Block.CHEST.id) && (world.e(x + 1, y + 1, z))) return;
        if ((world.getTypeId(x, y, z - 1) == Block.CHEST.id) && (world.e(x, y + 1, z - 1))) return;
        if ((world.getTypeId(x, y, z + 1) == Block.CHEST.id) && (world.e(x, y + 1, z + 1))) return;
      }

      if (world.getTypeId(x - 1, y, z) == Block.CHEST.id)
        chest =
            new InventoryLargeChest(
                "Large chest",
                (TileEntityChest) world.getTileEntity(x - 1, y, z),
                (IInventory) chest);
      if (world.getTypeId(x + 1, y, z) == Block.CHEST.id)
        chest =
            new InventoryLargeChest(
                "Large chest",
                (IInventory) chest,
                (TileEntityChest) world.getTileEntity(x + 1, y, z));
      if (world.getTypeId(x, y, z - 1) == Block.CHEST.id)
        chest =
            new InventoryLargeChest(
                "Large chest",
                (TileEntityChest) world.getTileEntity(x, y, z - 1),
                (IInventory) chest);
      if (world.getTypeId(x, y, z + 1) == Block.CHEST.id)
        chest =
            new InventoryLargeChest(
                "Large chest",
                (IInventory) chest,
                (TileEntityChest) world.getTileEntity(x, y, z + 1));

      if (!silentchest) {
        player.a((IInventory) chest);
      } else {
        try {
          Field ciField = player.getClass().getDeclaredField("ci");
          ciField.setAccessible(true);
          int ci = ciField.getInt(player);
          ci = ci % 100 + 1;
          ciField.setInt(player, ci);
          player.netServerHandler.sendPacket(
              new Packet100OpenWindow(
                  ci, 0, ((IInventory) chest).getName(), ((IInventory) chest).getSize()));
          player.activeContainer = new SilentContainerChest(player.inventory, ((IInventory) chest));
          System.out.println(player.activeContainer.toString());
          player.activeContainer.windowId = ci;
          player.activeContainer.a((ICrafting) player);
          event.getPlayer().sendMessage("You are opening a silent chest.");
        } catch (Exception e) {
          e.printStackTrace();
          event.getPlayer().sendMessage(ChatColor.RED + "Error while sending silent chest.");
        }
      }

      if (anychest) event.getPlayer().sendMessage("You are opening a blocked chest.");
    }

    if (event.getAction() == Action.RIGHT_CLICK_BLOCK
        && (event.getClickedBlock() == Block.CHEST
            || event.getClickedBlock() == Block.FURNACE
            || event.getClickedBlock() == Block.DISPENSER)) {
      return;
    }

    if (event.getAction() == Action.RIGHT_CLICK_AIR
        || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
      Player player = event.getPlayer();

      if (!(player.getItemInHand().getType() == Material.STICK)
          || (!OpenInv.GetPlayerItemOpenInvStatus(player.getName()))
          || !PermissionRelay.hasPermission(player, "openinv")) {
        return;
      }

      player.performCommand("openinv");
    }

    if (event.getAction() == Action.LEFT_CLICK_BLOCK
        && event.getClickedBlock().getState() instanceof Sign) {
      Player player = event.getPlayer();
      try {
        if (PermissionRelay.hasPermission(player, "openinv")
            && ((Sign) event.getClickedBlock().getState())
                .getLine(0)
                .equalsIgnoreCase("[openinv]")) {
          if (plugin.getServer().getPlayer(((Sign) event.getClickedBlock().getState()).getLine(1))
              != null) {
            Sign sign = ((Sign) event.getClickedBlock().getState());
            String text = sign.getLine(1).trim() + sign.getLine(2).trim() + sign.getLine(2).trim();
            player.performCommand("openinv " + text);
          } else {
            player.sendMessage("Player not found.");
          }
        }
      } catch (Exception ex) {
        player.sendMessage("Internal Error.");
        ex.printStackTrace();
      }
    }
  }