Sending a player a false chunk

Discussion in 'Plugin Development' started by RjSowden, Nov 4, 2012.

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

    RjSowden

    Hi,

    I'm trying to send a single player a false chunk that makes everything appear to be glass in the chunk they are in. Here is the code I have so far:
    Code:
    Chunk currentChunk = subject.getWorld().getChunkAt(subject.getLocation());
            sender.sendMessage(ChatColor.GREEN + "Sending Alternate Blocks");
          int x = 0;
          int y= 0;
          int z= 0;
          while (x < 15){
              while (y < 127){
                  while (z < 15){
                      //if(currentChunk.getBlock(x, y, z).getTypeId() != 0){
                      currentChunk.getBlock(x, y, z).setTypeId(20);
                    // }
                      z+=1;
                  }
               
                  y+=1;
              }
           
              x+=1;
          }
       
          net.minecraft.server.World mcWorld = ((CraftChunk) currentChunk).getHandle().world;
          if (currentChunk.load() == false){
              log.info("FAIL");
          }else{
              log.info("Win");
          }
       
          EntityPlayer ep  =  (EntityPlayer) mcWorld.findNearbyPlayer(subject.getLocation().getX(), subject.getLocation().getY(), subject.getLocation().getZ(), 2);
    log.info(ep.displayName);
                  ep.chunkCoordIntPairQueue.add(new ChunkCoordIntPair(currentChunk.getX(), currentChunk.getZ()));
       
          sender.sendMessage(ChatColor.GREEN + "Alternate Blocks Sent");
    I considered using the sendChunkChange in the Player class, but people here have said that's buggy so I've gone for the above approach instead as reccomended by the same fourum thread. The issue I have is that it doesn't work, and I don't know why since this is the first time i've used the net.minecraft.server classes.

    Can anyone help please?
    Thanks!
     
  2. Offline

    creepycrafter4

    i would like this as plugin so you can do /glasschunk <player> or something.
    hope it can be fixed! [diamond][diamond]
     
  3. Offline

    Comphenix

    Sure thing. :)

    I've been working on BlockPatcher, which essentially is a framework for Orebfuscator plugins, and I've added the ability to select different conversion tables per chunk and per each player. That way, you can modify the chunk in the outbound packet directly, instead of performing a bunch of getTypeId() calls. It's also asynchronous, and uses multiple worker threads to perform the chunk processing.

    So ... I took your idea and implemented it using BlockPatcher. You can see the results here:
    http://imgur.com/a/ZDhHF

    It's a bit buggy at the moment though. Mobs become "invulnerable" once the chunk is resent, and BlockPatcher itself might need some optimizations. Currently, it will process every chunk sent, regardless of whether or not it has been modified. However, it's fairly quick, and it's all done asynchronously.

    You can get BlockPatcher and the Glass Chunk test (BlockTest) on GitHub. You will also need to install ProtocolLib.

    The API for BlockPatcher is fairly simple:
    Code:java
    1. @EventHandler
    2. public void onChunk(ChunkPostProcessingEvent event) {
    3. BlockVector last = glassChunk.get(event.getPlayer());
    4.  
    5. // Convert to glass
    6. if (last != null && (last.getBlockX() == event.getChunkX() && last.getBlockZ() == event.getChunkZ())) {
    7. SegmentLookup lookup = event.getLookup();
    8.  
    9. int glass = Material.GLASS.getId();
    10.  
    11. // To glass
    12. lookup.setBlockLookup(Material.BEDROCK.getId(), glass);
    13. lookup.setBlockLookup(Material.BRICK.getId(), glass);
    14. lookup.setBlockLookup(Material.CLAY.getId(), glass);
    15. lookup.setBlockLookup(Material.DIRT.getId(), glass);
    16. lookup.setBlockLookup(Material.GRASS.getId(), glass);
    17. lookup.setBlockLookup(Material.GRAVEL.getId(), glass);
    18. lookup.setBlockLookup(Material.ICE.getId(), glass);
    19. lookup.setBlockLookup(Material.OBSIDIAN.getId(), glass);
    20. lookup.setBlockLookup(Material.NETHER_BRICK.getId(), glass);
    21. lookup.setBlockLookup(Material.NETHERRACK.getId(), glass);
    22. lookup.setBlockLookup(Material.SAND.getId(), glass);
    23.  
    24. lookup.setBlockLookup(Material.SOUL_SAND.getId(), glass);
    25. lookup.setBlockLookup(Material.STONE.getId(), glass);
    26.  
    27. // To air
    28. lookup.setBlockLookup(Material.SNOW.getId(), 0);
    29. lookup.setBlockLookup(Material.WATER.getId(), 0);
    30.  
    31. lookup.setBlockLookup(Material.LAPIS_BLOCK.getId(), glass);
    32. lookup.setBlockLookup(Material.IRON_BLOCK.getId(), glass);
    33. }
    34. }

    It's also possible to convert blocks in a 16x16x16 segment only. Use "getSegmentView" for that.
     
Thread Status:
Not open for further replies.

Share This Page