BLOCK CHANGE packet not sending at the PlayerJoinEvent event

Discussion in 'Plugin Development' started by Darkmun, Sep 18, 2022.

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

    Darkmun

    Hello. Nothing happens when trying to send a BLOCK_CHANGE packet (using ProtocolLib and PacketWrapper) at a player join event:
    Code:
    public final class BlockChange extends JavaPlugin implements Listener {
    
        @Override
        public void onEnable() {
            getConfig().options().copyDefaults();
            saveDefaultConfig();
    
            CustomConfig.setup();
            CustomConfig.getConfig().options().copyDefaults(true);
            CustomConfig.saveConfig();
    
            getServer().getPluginManager().registerEvents(this, this);
    
            getLogger().log(Level.INFO, "Plugin enabled.");
        }
    
        @Override
        public void onDisable() {
            getLogger().log(Level.INFO, "Plugin disabled.");
        }
    
        @EventHandler (priority = EventPriority.HIGHEST)
        public void onJoin(PlayerJoinEvent e) {
            ProtocolManager manager = ProtocolLibrary.getProtocolManager();
            Player pl = e.getPlayer();
           
            WrapperPlayServerBlockChange wrapper = new WrapperPlayServerBlockChange(packet);
            wrapper.setLocation(new BlockPosition(0,4,0));
            wrapper.setBlockData(WrappedBlockData.createData(Material.DIRT));
            wrapper.sendPacket(pl);
            
        }
    }
    For example, CHAT packet is sent normal in the same event.
    Maybe is there any other way to send BLOCK_CHANGE packet to the player when he joins the server?

    (sorry, if some sentences looks strange, it's just a google translate))
     
  2. Offline

    timtower Administrator Administrator Moderator

    @Darkmun World probably gets loaded after.
     
  3. Offline

    Darkmun

    @timtower
    So, how to load it before sending blockchange in join event? At first I tried to load chunk in which I want to send blockchange. I was trying to do it with simply pl.getWorld().loadChunk() but this obviusly didn't help. Then I tried to send MapChunk packet (i don't really know how it works, so i just tried) and this wasn't helpful too.
    If I understand this right, i need to load world to client, but i don't know how and can't find info about that(
     
  4. Offline

    timtower Administrator Administrator Moderator

    Why do you need to send it right away? The protocol cancels it out...
     
  5. Offline

    Darkmun

    @timtower
    Well, my original goal is that blockchange does not disappear after the player exits. But it will not be possible to do this directly (probably), so I need to make sure that the information about the sent blockchange packets is remembered in the config (I have already done this) and the next time the player join the server, information about packets would be taken from that config and blockchange packets from there would be sent (and for player it looks like the blocks never disappeared)
     
  6. Offline

    timtower Administrator Administrator Moderator

    @Darkmun Then intercept the chunk packets and change the block in there.
    sendBlockChange does not hold up after a block update btw, so that is something to keep in mind.
     
  7. Offline

    Darkmun

    @timtower I tried to send PacketPlayOutMapChunk packet, but it's also disappears when player exit, and also don't sending in join event. Or maybe I misunderstood "intercept the chunk packets"? (and yeah, i know this about blockchange, it wouldn't interfere much with what I want to do)
     
  8. Offline

    timtower Administrator Administrator Moderator

    @Darkmun You don't send it yourself, you wait till it gets send, intercept it, change it, let it move along to the player.
     
  9. Offline

    Darkmun

    @timtower You mean something like that?
    Code:
    ProtocolManager manager = ProtocolLibrary.getProtocolManager();
    
            manager.addPacketListener(new PacketAdapter(this, PacketType.Play.Server.MAP_CHUNK) {
                @Override
                public void onPacketSending(PacketEvent event) {
                    PacketContainer packet = event.getPacket();
                    int ChunkX = packet.getIntegers().read(0);
                    int ChunkZ = packet.getIntegers().read(1);
                    if ((ChunkX == 2) && (ChunkZ == 0)) {
                        packet.getIntegers().write(0, 0);
                        
                        try {
                            manager.sendServerPacket(event.getPlayer(), packet);
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            });
     
  10. Offline

    timtower Administrator Administrator Moderator

    @Darkmun Don't forget the bulk chunk.
    And you don't send a new packet, you change this one.
     
  11. Offline

    Darkmun

    @timtower Oh, like, use event.setPacket() instead of manager.sendServerPacket()? But what's the big difference?
    And in my version (1.12.2) bulk chunk is deprecated, and there is no information about bulk chunk on protocol wiki for 1.12.2 version, so can i still use it?
     
    Last edited: Sep 19, 2022
  12. Offline

    timtower Administrator Administrator Moderator

    @Darkmun No, you don't call sendPacket in any form again.
    You just intercept it like you have now, and change it.
     
  13. Offline

    Darkmun

    @timtower Okay, but what's the difference? If I change the packet and send it, or change it and don't send it, the same thing happens
     
  14. Offline

    timtower Administrator Administrator Moderator

    The fact that it gets send twice, or multiple as you keep sending new packets based on the first one.
     
  15. Offline

    Darkmun

    @timtower ok, got it, thanks a lot :)
    But now the problem is how to change the blocks in the mapchunk packet. I checked the protocol wiki, but it's really hard to understand. As I understand it, all the information about blocks is contained in the Data field with the Byte array type, but I don't understand how it turns out at all. The note to this field says "See the data structure", but there is nothing written about how to convert all this information into a Byte array. This is a main misunderstanding, but there are many more details that are not clear to me (but maybe they will become clearer with an understanding about the data field)
     
Thread Status:
Not open for further replies.

Share This Page