Hide sign/frame entity from player

Discussion in 'Plugin Development' started by ZephireNZ, Jan 16, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    ZephireNZ

    I'm (hopefully) going to make a flag plugin for WorldGuard that will disable showing signs/item frames for a region, unless a player is inside that region.

    I know it's possible to hide players from players, but how would hide signs and item frames from players?
     
  2. Offline

    gomeow

    Look into packet blocking with ProtocolLib
     
  3. Offline

    ZephireNZ

    So I'm looking at PacketLib now... I'm honestly not sure how I'd stop signs etc from being viewed... A little more help?
     
  4. Offline

    MrTwiggy

    You can use player.sendBlockChange and set the material as air for all the signs.
     
  5. Offline

    ZephireNZ

    What about paintings and frames? They're entities, not blocks, so...
     
    Comphenix likes this.
  6. Offline

    Comphenix

    Right. It's possible to use BlockPatcher to prevent the sign block from ever being sent, though it's probably overkill.

    Instead, you can use sendBlockChange() to simply reset all the sign blocks as their written content is sent to the player. You can also block the painting and the item frame from being spawned as well (download):
    Code:java
    1. public class ExampleMod extends JavaPlugin {
    2. @Override
    3. public void onEnable() {
    4. final ProtocolManager manager = ProtocolLibrary.getProtocolManager();
    5.  
    6. manager.addPacketListener(
    7. new PacketAdapter(this, ConnectionSide.SERVER_SIDE,
    8. Packets.Server.VEHICLE_SPAWN,
    9. Packets.Server.ENTITY_METADATA) {
    10. @Override
    11. public void onPacketSending(PacketEvent event) {
    12. if (!event.getPlayer().hasPermission("cansee.itemframe")) {
    13. // Handle the spawn packet and the metadata packet
    14. if (event.getPacketID() == Packets.Server.VEHICLE_SPAWN) {
    15. Packet17SpawnObjectVehicle spawnFrame = new Packet17SpawnObjectVehicle(event.getPacket());
    16.  
    17. // Use getX(), getY() and getZ() to get the coordinates.
    18. if (spawnFrame.getType() == Packet17SpawnObjectVehicle.ObjectTypes.ITEM_FRAME) {
    19. // Excellent - disable it
    20. event.setCancelled(true);
    21. }
    22.  
    23. // The packet that updates the content of the item frame
    24. } else {
    25. Packet28EntityMetadata metadata = new Packet28EntityMetadata(event.getPacket());
    26.  
    27. if (metadata.getEntity(event) instanceof ItemFrame) {
    28. event.setCancelled(true);
    29. }
    30. }
    31. }
    32. }
    33. });
    34.  
    35. manager.addPacketListener(
    36. new PacketAdapter(this, ConnectionSide.SERVER_SIDE,
    37. Packets.Server.ENTITY_PAINTING) {
    38. @Override
    39. public void onPacketSending(PacketEvent event) {
    40. if (!event.getPlayer().hasPermission("cansee.painting")) {
    41. //Packet19SpawnPainting spawnPainting = new Packet19SpawnPainting(event.getPacket());
    42.  
    43. // We'll just cancel it all - but you can get the coordindates of the painting
    44. event.setCancelled(true);
    45. }
    46. }
    47. }
    48. );
    49.  
    50. manager.addPacketListener(
    51. new PacketAdapter(this, ConnectionSide.SERVER_SIDE,
    52. Packets.Server.UPDATE_SIGN) {
    53. @Override
    54. public void onPacketSending(PacketEvent event) {
    55. if (!event.getPlayer().hasPermission("cansee.sign")) {
    56. Packet82UpdateSign spawnPainting = new Packet82UpdateSign(event.getPacket());
    57. Location loc = new Location(
    58. event.getPlayer().getWorld(),
    59. spawnPainting.getX(), spawnPainting.getY(), spawnPainting.getZ());
    60.  
    61. // Don't update the sign
    62. event.setCancelled(true);
    63.  
    64. // Send a fake block update
    65. event.getPlayer().sendBlockChange(loc, Material.AIR, (byte)0);
    66. }
    67. }
    68. }
    69. );
    70. }
    71. }

    Note, you'll need to add in a few classes from PacketWrapper to get the code above working.

    The biggest problem is probably how to update players that have suddenly received permission to see the signs or paintings. A simple hack is to teleport them to a different spot, and then back again.
     
  7. Offline

    ZephireNZ

    Holy shit, thanks! That looks like it'll do everything I want! I'll take a look at it, see if I can fit it to the example I want. Again, thanks!
     
    Comphenix likes this.
Thread Status:
Not open for further replies.

Share This Page