Solved Falling Block Entity Replacing Client Side Blocks

Discussion in 'Spigot Plugin Development' started by Qruet, Jan 15, 2020.

  1. As the title would suggest, this is definitely some very odd behavior. Considering I am spawning in an entity with packets, even though it is a block entity, I am surprised to see that it will override existing blocks with air. Here is my current setup. There are of course no errors being thrown, however, I have provided a gif below that visually shows the issue.

    Code (Java):
            Block block = rblock.getBlock();
            Location loc = block.getLocation().add(0.5, 100, 0.5);
            Player player = Bukkit.getPlayer(id);
            if (player == null)
                return;

            IBlockData data = CraftMagicNumbers.getBlock(block.getType()).getBlockData();
            this.block = new EntityFallingBlock(
                    ((CraftWorld) loc.getWorld()).getHandle(),
                    loc.getX(),
                    loc.getY(),
                    loc.getZ(),
                    data);

            this.block.setNoGravity(true);
            this.block.getBukkitEntity().setGlowing(true);

            EntityPlayer ePlayer = ((CraftPlayer) player).getHandle();

            PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(this.block, net.minecraft.server.v1_15_R1.Block.getCombinedId(data));
            PacketPlayOutEntityMetadata metapacket = new PacketPlayOutEntityMetadata(this.block.getBukkitEntity().getEntityId(), this.block.getDataWatcher(), true);

            this.block.getBukkitEntity().teleport(block.getLocation().add(0.5, 0, 0.5));
            PacketPlayOutEntityTeleport packetteleport = new PacketPlayOutEntityTeleport(this.block);

            ePlayer.playerConnection.sendPacket(packet);
            ePlayer.playerConnection.sendPacket(metapacket);
            ePlayer.playerConnection.sendPacket(packetteleport);
    My latest test included the teleport packet. I was curious if teleporting the entity to its appropriate position after it spawned would help avoid the issue, but that hasn't shown a positive result as well. It is also important to note, the EntityFallingBlock never transforms into a solid block since the glow effect (only applicable to entities) remains constant.

    [​IMG]
     
    #1 Qruet, Jan 15, 2020
    Last edited: Jan 15, 2020
    • Like Like x 1
  2. Hmm, it's odd but I don't think it's not supposed to happen...
    The server-sided Block is still there, right? What I believe happens is that the singleplayer renders the block differently since it thinks that there is a falling block that should be disappearing and overridden with the appropriate block. Since you did not send another packet that says what the appropriate block is, the client simply makes the FallingBlock disappear.
    That's just thought thou, no facts to back that...
     
  3. Perhaps there's a misunderstanding. The goal here is to "highlight" certain placed blocks by the player. To do this though, I need to spawn in an entity to apply the glow effect and falling block entities are seemingly the best solution for this. This is done when the player right clicks the "special" block item that they are holding. If they are to right click it again they disable the effect, hence in the animation the glowing blocks disappear, as they should with the PacketPlayOutEntityDestroy packet. However, the original block (not a falling entity) disappears as well. In fact, the block is already removed once the entity is spawned in, which is what makes this so confusing. I'm fairly sure entities do not replace solid block objects, and should be able to clip inside of them. The blocks are placed normally. They are as is by default, registered by both the server and client.
     
  4. But from what I can see in our gif, it's only a visual thing and the block is actually there, right? Because when you jump at that wall, it seems like the block just appears out of nowhere? Or am I seeing this wrong?
     
  5. The glowing effect is registered only by the client since I only spawn in the glowing falling block entity directly to a single client. The actual block that the falling block entity receives its specific data from is registered by the server. When I jumped at the wall, the server and the client had a disagreement with the blockdata at my nearby location and a block packet sent by the server automatically is what caused the actual physical blocks to reappear.
     
  6. Well, this is basically what I said. The client thinks that there must be an air Block since that is the only thing a fallingBlock could be in at any given time, right? So when you make a block-update on the client-side, I suppose the visuals get updated as well...
     
  7. Just managed to do this so I need a bit more time to see if it'll get me anywhere, but from the example below, there isn't really a need to do any of what you suggested. The output from some further testing below shows basically what I am looking for, however, obviously I do not want a wooden oak plank overlaying a cobblestone block. I am not certain why changing the int type id parameter seems to have changed this, but I will keep testing to see if I can change the oak plank to a cobblestone block without reverting to the previous issue.
    [​IMG]

    EDIT: Further testing shows changing it to the same type of the block recreates the initial issue. I am still puzzled as to why this happens? Is the client programmed in such a way that two of the same block types regardless if its an entity override one another? I am very puzzled. :unsure:

    EDIT #2: Decided I am going to go with using a slime entity instead of falling block, however I will leave this thread open incase someone can explain the odd way that clients appear to handle falling block entities.
     
    #7 Qruet, Jan 15, 2020
    Last edited: Jan 16, 2020
  8. If/When you get the slime working can u share the code i've tried Shulkers and now FallingEntites
     
  9. I would really give it some thought as to what you are actually trying to achieve. I am actually planning on changing from utilizing the glow effect and just going for a nice particle perimeter along the block's edges instead. It has proven a bit impractical to spawn in an entity that roughly matches the size of the block since blocks come in different sizes (e.g. slabs, carpet, etc.), and I intend to have players to still be able to interact with these blocks (e.g. breaking, right-clicking etc.). When you've got an entity in the way, this can prove to be rather difficult. Perhaps I could spawn the entity globally on the server, modify its hitbox, and make it invisible and also hide the entity from other players, but this gets tedious, and isn't worth it in the end. Here is my latest code snippet I last used for the entity. I'll try to leave some comments so it can help you understand what is being done.

    Also you may want to utilize reflection instead or create a version handler so that your plugin doesn't rely on a specific version of the game to work.

    Code (Java):
        private EntityMagmaCube cube; //local instance

        public VisualizerBlock(ReinforcedBlock rblock) {
            [...]
            this.cube = new EntityMagmaCube(EntityTypes.MAGMA_CUBE, ((CraftWorld) loc.getWorld()).getHandle()); //basic Entity instance
            this.cube.getBukkitEntity().setGlowing(true); //adds glow effect to entity
            this.cube.setSize(1, true); //updates the size (and health) of entity (2 = full size block)
            this.cube.setInvulnerable(true); //god mode for the entity
            this.cube.setNoAI(true); //prevent entity from moving around
            this.cube.setInvisible(true); //up to you. Be cautious that this will cause the glow effect to actually "fill" the invisible entity instead of simply appearing along its edges (interesting effect)

            this.cube.setPositionRotation(loc.getX() + 0.5, loc.getY() + 0.25, loc.getZ() + 0.5, 0f, 0f); //update location of entity

            EntityPlayer ePlayer = ((CraftPlayer) player).getHandle();

            PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(this.cube); //spawn the entity
            PacketPlayOutEntityMetadata metapacket = new PacketPlayOutEntityMetadata(this.cube.getBukkitEntity().getEntityId(), this.cube.getDataWatcher(), true); //update the entity data on the player's client (this is important)

            ePlayer.playerConnection.sendPacket(packet); //spawn packet first
            ePlayer.playerConnection.sendPacket(metapacket); //send additional data second
        }
     
  10. thats what i went with, the whole white flicker of the WHOLE entity ruined the effect. so now i just use particle effects that asuround the border of the seleceted blocks