Protocollib identify custom packet

Discussion in 'Spigot Plugin Development' started by NubeBuster, May 13, 2016.

  1. I want to cancel the keepalive packets the server sends but not the keepalive packets I am sending myself.

    I am using Protocollib

    My current code is:
    Code (Text):
            protocolManager
            .addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.KEEP_ALIVE) {
                @Override
                public void onPacketSending(PacketEvent event) {
                    if(event.getSource() instanceof NettyProtocolInjector) {
                        NettyProtocolInjector inj = (NettyProtocolInjector) event.getSource();
                        //getting the source doesnt seem right
                    }
                }
            });
    and to send the packets
    Code (Text):
    protocolManager.sendServerPacket(p, new PacketContainer(PacketType.Play.Server.KEEP_ALIVE));

    How do I filter my custom send packets and the server's packets?
     
  2. The client won't send any KeepAlive packets if it doesn't receive any. Why exactly would you want to cancel KeepAlive packets anyways?
     
  3. Take a look at the Minecraft protocol for the KeepAlive Packet. It contains a random ID field. On thing I would suggest is take note of what that random id is in your own custom keep alive packet and put it in some datastructure (let's say a Hashtable). Then in your packet listener grab the random ID from the incoming packet and check your Hashtable to see if it exists. If it does exist this means that it must be one of your custom keep alive packets.

    EDIT: I like using PacketWrapper because it makes setting and getting things in packets very easy.
    AbstractPacket
    KeepAlive
     
  4. I am talking server side, not client side.
     
  5. The only field in the keep alive packet is the random number that the client has to reply with and so all that I can think of is picking a number that you always use when sending yours, listen for all of the keep alives sent and cancel the ones with a different id and replace the id of the ones that you catch with your id. Of course there is the small chance that the random id in the packet matches yours but this may or may not be critical depending on the intended use here.
     
  6. @MrBlobman @Kloudy
    I got so far, but how do I get the packet id? (its not event.getPacket().getID())
     
  7. Here's how to grab it:
    Code (Text):
    protocolManager
            .addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.KEEP_ALIVE) {// you want to listen for packet from the client of type KEEP_ALIVE
                @Override
                public void onPacketSending(PacketEvent event) {
                    if(event.getPacketType() == PacketType.Play.Server.KEEP_ALIVE){
                         WrapperPlayClientKeepAlive keepAlivePacket = new WrapperPlayClientKeepAlivePacket(event.getPacket());

                           int id = keepAlivePacket.getKeepAliveId(); // there's your id
                      }
                    }
                }
            });
     
    #7 Kloudy, May 13, 2016
    Last edited: May 13, 2016
    • Useful Useful x 1
  8. Here's what I'd do in your case:

    Sending your custom KeepAlive packet:
    Code (Text):
    WrapperPlayClientKeepAlive keepAlivePacket = new WrapperPlayClientKeepAlive();
    keepAlivePacket.setKeepAliveId(-5000);//lets just choose a standard number so we can check it in our listener when the client sends it back

    keepAlivePacket.sendPacket(player);
    Then in your listener you can just check if the id is -5000
     
  9. @Kloudy
    I am having trouble adding my custom packets to the list
    Code (Text):
                    PacketContainer packet = new PacketContainer(PacketType.Play.Server.KEEP_ALIVE);
                    custom.add(new WrapperPlayClientKeepAlive(packet).getKeepAliveId());
                    protocolManager.sendServerPacket(p, packet);
    throws:

    "
    [17:11:29 WARN]: [NubesHax] Task #431 for NubesHax v1.0 generated an exception
    java.lang.IllegalArgumentException: [email protected] is not a packet of type PacketPlayInKeepAlive[0, legacy: 0]
    at me.mac.hax.packets.AbstractPacket.<init>(AbstractPacket.java:43) ~[?:?]
    at me.mac.hax.packets.WrapperPlayClientKeepAlive.<init>(WrapperPlayClientKeepAlive.java:18) ~[?:?]
    at me.mac.hax.Gamer.updateKeepAlive(Gamer.java:106) ~[?:?]
    at me.mac.hax.NubesHax$5.run(NubesHax.java:165) ~[?:?]
    at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java:71) ~[spigot.jar:git-Spigot-e4d4710-e1ebe52]
    at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350) [spigot.jar:git-Spigot-e4d4710-e1ebe52]
    at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:723) [spigot.jar:git-Spigot-e4d4710-e1ebe52]
    at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot.jar:git-Spigot-e4d4710-e1ebe52]
    at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot.jar:git-Spigot-e4d4710-e1ebe52]
    at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot.jar:git-Spigot-e4d4710-e1ebe52]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
    "
     
  10. You've got some invalid arguments you're passing in. If you do what I did above it should work for ya. No need to mess with the PacketContainer stuff. It's all handled in PacketWrapper

    Code (Text):
    WrapperPlayClientKeepAlive keepAlivePacket = new WrapperPlayClientKeepAlive();
    keepAlivePacket.setKeepAliveId(-5000);//lets just choose a standard number so we can check it in our listener when the client sends it back

    keepAlivePacket.sendPacket(player);
     
  11. Actually sorry, it just dawned on me what you're trying to do. You want to cancel the server's keep alive packets and send your own. In which case use class: WrapperPlayServerKeepAlive

    -whoooops
     
    • Useful Useful x 1
  12. WrapperPlayServerKeepAlive is a packet sent from the server to the client
    WrapperPlayClientKeepAlive is a packet sent from the client to the server

    big difference, hope that helped.
     
  13. Store the handles in a set.
    Code (Text):
    private Set<Object> pluginPackets = Collections.newSetFromMap(new MapMaker().weakKeys().<Object, Boolean>makeMap());
    Save all the handles of packets you sent:
    Code (Text):
    pluginPackets.add(packetContainer.getHandle());
    Compare it when listening to packets:
    Code (Text):
    if(!pluginPackets.contains(event.getPacket().getHandle()))
    Hope I helped.