1.9.4 Client-side | Lava to (fake) water

Discussion in 'Spigot Plugin Development' started by MonkeyKiller123, Jan 13, 2020.

  1. Hello, I am doing a troll plugin and in one of its functions I want to make all the lava look like water (without using texture packages), but that the rest of the players see how it really is, try this code:
    Code (Text):

    public static void b() {
       (new BukkitRunnable() {
           public void run() {
               for (Player bb : lavahide)
                 try {
                     getBlocks(bb.getLocation().getBlock(), 50, bb);
                       
                 } catch (Exception e) {
                   }
              }
          }).runTaskTimer(plugin, 5L, 5L);
    }

    public static ArrayList<Block> getBlocks(Block start, int radius, Player p){
        ArrayList<Block> blocks = new ArrayList<Block>();
        for(double x = start.getLocation().getX() - radius; x <= start.getLocation().getX() + radius; x++){
          for(double y = start.getLocation().getY() - radius; y <= start.getLocation().getY() + radius; y++){
            for(double z = start.getLocation().getZ() - radius; z <= start.getLocation().getZ() + radius; z++){
              Location loc = new Location(start.getWorld(), x, y, z);
              if (loc.getBlock().getType() == Material.LAVA) {
                 p.sendBlockChange(loc, Material.WATER, loc.getBlock().getData());
                 }
                 if (loc.getBlock().getType() == Material.STATIONARY_LAVA) {
                 p.sendBlockChange(loc, Material.STATIONARY_WATER, loc.getBlock().getData());
                 }
         }
         }
        }
        return blocks;
        }
     
    But the problem is that the server wipes and you get to see that it is lava.

    How can I solve that?
    PS: Sorry for the translator, I'm from Argentina
     
  2. md_5

    Administrator Developer

    What do you mean?
     
  3. I meant that the server does not respond instantly, and it is seen for an instant that it is lava
    [​IMG]
     
    #3 MonkeyKiller123, Jan 17, 2020
    Last edited: Jan 17, 2020
  4. What is the Runnable for?
     
  5. You're using a BukkitRunnable, which means it will be delayed by 1/4 of a second. If you want it to be instantly, listen for the bucket use event and check if it is lava or listen for the block update change event.
     
  6. Here is what is happening now:

    1. You place the lava block (or the lava block flows into another block)
    2. The lava block (or update) is sent to the player
    3. You then overwrite the block to be water through the runnable

    The time in between 2 and 3 is the reason why you see the lava. In order to stop this, you need to prevent step 2 from happening by intercepting any block change or map chunk packets where the lava block is sent to the player and replace it with water. This is where something like ProtocolLib would be useful.
     
    • Like Like x 1
  7. What is the event?
     
  8. I thought about that, but I don't know much about the Protocollib
     
  9. PlayerBucketEmptyEvent and Im not sure, but I think fluid liquids also trigger the BlockPhysicsEvent.
     
  10. [​IMG]
     
  11. So it works with the block physics event, did you set up the player bucket empty event too^ Whats your current code
     
  12. I don't want to detect when a player uses a lava bucket, but I'm going to put it, this is the code
    Code (Text):

        @SuppressWarnings({ "deprecation", "static-access" })
       @EventHandler
       private void onBlockPhysics(BlockPhysicsEvent e) {
           if(e.getChangedType() == Material.LAVA || e.getBlock().getType() == Material.LAVA) {
               for(Player p : plugin.tl.lavahide) {
                   p.sendBlockChange(e.getBlock().getLocation(), Material.WATER, e.getBlock().getData());           }
           }
       }
     
     
  13. ProtocolLib is definitely the way to go here IMO, you can intercept the packets to make it seamless. Your current method is going to not work whenever a player loads the chunk.

    If you would like an implementation of ProtocolLib, I have one on my git. https://github.com/BigBadE/Enchantm...ntmenttokens/listeners/SignPacketHandler.java has my code for doing the same thing with signs. In your case you should use MAP_CHUNK (chunk load), Block change, and Block update.
    Check https://wiki.vg/Protocol for the packet data.