[Lib] [1.7.9] ProtocolLib 3.4.0 - Safely and easily modify sent and recieved packets

Discussion in 'Resources' started by Comphenix, Sep 15, 2012.

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


    Unfortunately, no. Even if you somehow patched that part of ItemMeta, you'd still run the risk of losing data if the server is run without your plugin. Not to mention that such a patch would probably run afoul of the BukkitDev policy.

    Your best bet is to store the data (or a reference to the data) as a part of standard ItemStack data, such as lore, name or attributes. I prefer attributes as its (mostly) invisible to the user, but you could also store the data in the lore section and use ProtocolLib to hide it. Just read this thread for more information.
    p000ison likes this.
  2. Offline


    thanks for your response :D I think I'll just encode my data to store it as lores or attributes. Finally a good answere :D btw do you know if it works for mobs to save nbt data?
  3. Offline


    You could try using entity equipment and store the data in an item stack. If you don't want the entity to possess any equipment, you could remove it as soon as its loaded, or use ProtocolLib to hide it on the client side (Packet5EntityEquipment).
    p000ison likes this.
  4. Offline


    ProtocolLib 3.0.1

    Build: #174

    ProtocolLib has now been fully updated to run on CraftBukkit and Spigot 1.7.2, together with all the necessary API needed by plugins to read the new packet types. It has undergone extensive testing by hundreds of willing server owners, and I can be reasonably certain the latest version is stable enough for public consumption. This is helped by the fact that Netty is significantly easier to inject into, leading to more performant and stable code.
    I would like to extend my sincerest thanks to all of those who put in their time and effort to report any issues. Without them, ProtocolLib wouldn't be half as stable as it is currently.



    Unfortunately, the new 1.7.2 update did affect the core API, and I had to deprecate the entire Packets-class integer enum and all methods that use it or raw integers, as nearly every packet ID have been altered. For instance, Packets.Server.NAMED_ENTITY_SPAWN had the ID 20 in Minecraft 1.6.4 - now it has been changed to ID 12 (0xC). Furthermore, packet IDs are no longer globally unique on the server and the client, meaning that the same ID can be used to represent the packet, such as STEER_VEHICLE (12) on the client side.
    Finally, the protocol has now been divided into four separated sub-protocols, each with their own packets. Packet IDs will overlap here as well:
    • HANDSHAKING - Initial state - this can either branch into STATUS or LOGIN.
    • STATUS - Query the server for the current message of the day, players online and the favicon.
    • LOGIN - Setup encryption and transition into PLAY.
    • PLAY - After the player has logged in. The client and server will remain in this protocol for the duration of the game.
    All of this prompted me to deprecate the Packets integers (as they no longer apply) with the new PacketType semi-enum class:

    2. ProtocolLibrary.getProtocolManager().addPacketListener(
    3. new PacketAdapter(this, PacketType.Play.Server.LOGIN) {
    4. @Override
    5. public void onPacketSending(PacketEvent event) {
    6. System.out.println("GameMode: " +
    7. event.getPacket().getGameModes().read(0));
    8. System.out.println("Difficulty: " +
    9. event.getPacket().getDifficulties().read(0));
    10. System.out.println("WorldType: " +
    11. event.getPacket().getWorldTypeModifier().read(0));
    12. }
    13. });

    A packet can be accessed in the following fashion:
    As you can see, it is no longer necessary to specify GamePhase, as it is implied by the packet type. You also no longer have to worry about GamePhase, as ProtocolLib will infer it in 1.6.4, and it has been made irrelevant in 1.7.2.

    Additions to PacketContainer

    I have also added a number of new modifiers to accommodate changes in the packet classes:
    • getBlocks()
    • getGameProfiles()
    • getChatComponents()
    • getServerPings()
    • getProtocols()
    • getClientCommands()
    • getChatVisibilities()
    • getDifficulties()
    • getEntityUseActions()
    • getGameModes()
    Here, ServerPing is a high-level wrapper around ServerPing, and allows you to modify the appearance of your server in the server menu to a great detail. You can set the player ratio, the name of the players displayed when you hover over the server, or even change the favicon (server image), all with a relatively simple API.
    There is also a ChatComponent wrapper. It is not as powerful as ServerPing, but it will allow you to get and change the raw JSON string that is transmitted when the server sends a message to the client.

    • Updated ProtocolLib to Minecraft 1.7.4 (version 3.0.1)
    • See GitHub for more details.
  5. Offline


    How can i access nbt data for blocks from protocllib?

    UPD: nvm, event nbt is not persistent , looks like i will have to find another way to store persistent data for block.
  6. Offline


    Wow Protocollib has gone a long way since I last checked on it, can't wait to start using it for my new plugin :)
  7. Offline


    Nice job with the new update, was looking forward to the ServerPing wrapper being added!
    Minecrell likes this.
  8. Offline


    I should probably mention that there is a new cool feature in ProtocolLib - a built-in server ping wrapper that allows you to modify the appearance of your server in the multiplayer menu:
    1. @Override
    2. public void onEnable() {
    3. ProtocolLibrary.getProtocolManager().addPacketListener(
    4. // I mark my listener as async, as I don't use the Bukkit API. Please note that
    5. // your listener may be executed on the main thread regardless.
    6. new PacketAdapter(this, ListenerPriority.NORMAL,
    7. Arrays.asList(PacketType.Status.Server.OUT_SERVER_INFO), ListenerOptions.ASYNC) {
    9. @Override
    10. public void onPacketSending(PacketEvent event) {
    11. handlePing(event.getPacket().getServerPings().read(0));
    12. }
    13. });
    14. }
    16. private void handlePing(WrappedServerPing ping) {
    17. ping.setPlayers(Arrays.asList(
    18. new WrappedGameProfile("id1", ChatColor.RED + "Hello. " + ChatColor.RESET +
    19. "This is line number one."),
    20. new WrappedGameProfile("id2", "Hello. This is line number two."),
    21. new WrappedGameProfile("id3", "Hello. This is line number three.")
    22. ));
    23. }

    Which looks like so when the user hovers over the player count:
    You can also set the favicon, and display an image next to your server:
    1. @Override
    2. public void onEnable() {
    3. ProtocolLibrary.getProtocolManager().addPacketListener(
    4. new PacketAdapter(this, ListenerPriority.NORMAL,
    5. Arrays.asList(PacketType.Status.Server.OUT_SERVER_INFO), ListenerOptions.ASYNC) {
    6. @Override
    7. public void onPacketSending(PacketEvent event) {
    8. handlePing(event.getPacket().getServerPings().read(0));
    9. }
    10. });
    11. }
    13. private void handlePing(WrappedServerPing ping) {
    14. try {
    15. // Place this next to your plugin.yml
    16. ping.setFavicon(CompressedImage.fromPng(getClassLoader().getResourceAsStream("tux.png")));
    17. } catch (IOException e) {
    18. throw new IllegalArgumentException("Cannot access image.", e);
    19. }
    20. }

    Which looks like this in the server menu:
    This is more powerful than simply placing the image in your server directory, as the image may depend on the IP address of the connected client, be dynamically generated, and so on.
  9. Offline


    I do not know if this is a bug or not but I can not display information when you hover over the player count. I am running the version of jenkins you recommended (3.0.2)(Also using latest craftbukkit) and getting this error:
    1. [11:08:13] [Server thread/ERROR]: [CorePlugin] Unhandled exception occured in onPacketSending(PacketEvent) for CorePlugin
    2. java.lang.RuntimeException: Cannot set field private net.minecraft.util.com.mojang.authlib.GameProfile[] net.minecraft.server.v1_7_R1.ServerPingPlayerSample.c to value [Lnet.minecraft.util.com.mojang.authlib.GameProfile;@201d1057
    3. at com.comphenix.protocol.reflect.accessors.DefaultFieldAccessor.set(DefaultFieldAccessor.java:28) ~[ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    4. at com.comphenix.protocol.wrappers.WrappedServerPing.setPlayers(WrappedServerPing.java:188) ~[ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    5. at com.core.coreplugin.CorePlugin.handlePing(CorePlugin.java:156) ~[CorePlugin.jar:?]
    6. at com.core.coreplugin.CorePlugin.access$0(CorePlugin.java:154) ~[CorePlugin.jar:?]
    7. at com.core.coreplugin.CorePlugin$1.onPacketSending(CorePlugin.java:87) ~[CorePlugin.jar:?]
    8. at com.comphenix.protocol.injector.SortedPacketListenerList.invokeSendingListener(SortedPacketListenerList.java:195) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    9. at com.comphenix.protocol.injector.SortedPacketListenerList.invokePacketSending(SortedPacketListenerList.java:149) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    10. at com.comphenix.protocol.injector.PacketFilterManager.handlePacket(PacketFilterManager.java:574) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    11. at com.comphenix.protocol.injector.PacketFilterManager.invokePacketSending(PacketFilterManager.java:550) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    12. at com.comphenix.protocol.injector.netty.NettyProtocolInjector.packetQueued(NettyProtocolInjector.java:273) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    13. at com.comphenix.protocol.injector.netty.NettyProtocolInjector.onPacketSending(NettyProtocolInjector.java:224) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    14. at com.comphenix.protocol.injector.netty.ChannelInjector.processSending(ChannelInjector.java:260) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    15. at com.comphenix.protocol.injector.netty.ChannelInjector.access$000(ChannelInjector.java:52) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    16. at com.comphenix.protocol.injector.netty.ChannelInjector$2.onMessageScheduled(ChannelInjector.java:239) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    17. at com.comphenix.protocol.injector.netty.ChannelProxy$2.schedulingRunnable(ChannelProxy.java:91) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    18. at com.comphenix.protocol.injector.netty.EventLoopProxy.execute(EventLoopProxy.java:76) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    19. at net.minecraft.server.v1_7_R1.NetworkManager.b(NetworkManager.java:110) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    20. at net.minecraft.server.v1_7_R1.NetworkManager.handle(NetworkManager.java:88) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    21. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_21]
    22. at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_21]
    23. at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_21]
    24. at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_21]
    25. at com.comphenix.protocol.injector.netty.ChannelInjector.invokeSendPacket(ChannelInjector.java:456) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    26. at com.comphenix.protocol.injector.netty.ChannelInjector.access$200(ChannelInjector.java:52) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    27. at com.comphenix.protocol.injector.netty.ChannelInjector$3.run(ChannelInjector.java:354) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    28. at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.7.0_21]
    29. at com.comphenix.executors.CallableTask.compute(CallableTask.java:93) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    30. at com.comphenix.executors.CallableTask.run(CallableTask.java:102) [ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    31. at org.bukkit.craftbukkit.v1_7_R1.scheduler.CraftTask.run(CraftTask.java:53) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    32. at org.bukkit.craftbukkit.v1_7_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:345) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    33. at net.minecraft.server.v1_7_R1.MinecraftServer.u(MinecraftServer.java:587) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    34. at net.minecraft.server.v1_7_R1.DedicatedServer.u(DedicatedServer.java:250) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    35. at net.minecraft.server.v1_7_R1.MinecraftServer.t(MinecraftServer.java:545) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    36. at net.minecraft.server.v1_7_R1.MinecraftServer.run(MinecraftServer.java:457) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    37. at net.minecraft.server.v1_7_R1.ThreadServerApplication.run(SourceFile:617) [Server.jar:git-Bukkit-1.6.4-R2.0-50-g402ee87-b2958jnks]
    38. Caused by: java.lang.IllegalArgumentException: Can not set [Lnet.minecraft.util.com.mojang.authlib.GameProfile; field net.minecraft.server.v1_7_R1.ServerPingPlayerSample.c to net.minecraft.server.v1_7_R1.ServerPing
    39. at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source) ~[?:1.7.0_21]
    40. at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source) ~[?:1.7.0_21]
    41. at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source) ~[?:1.7.0_21]
    42. at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source) ~[?:1.7.0_21]
    43. at java.lang.reflect.Field.set(Unknown Source) ~[?:1.7.0_21]
    44. at com.comphenix.protocol.reflect.accessors.DefaultFieldAccessor.set(DefaultFieldAccessor.java:26) ~[ProtocolLib-3.0.2-SNAPSHOT.jar:?]
    45. ... 34 more
    46. [11:08:13] [Server thread/ERROR]: Parameters:
    47. net.minecraft.server.v1_7_R1.PacketStatusOutServerInfo@6f4c58ee[
    48. b=net.minecraft.server.v1_7_R1.ServerPing@132cc337
    49. timestamp=1387123693770
    50. ]

    I am using the exact copy and pasted code from the example above as well.
    Has anyone ever had this error before?
  10. Offline


    Sorry, I forgot to mention this is my previous post, but ServerPing only actually works in the latest developer build of ProtocolLib (can be downloaded from my Jenkins server).

    I'll update ProtocolLib on BukkitDev soon.
  11. Offline


    That was using your latest version from your Jenkins (Build 181).
  12. Offline


    Strange, I did test the example code before I posted it here, but somehow my fix must have accidentally been left out of the last commit. I might have clicked undo one too many times ...

    It should be live in #182, though. Let me know if it works for you.
  13. Offline


  14. Offline


    Is there a simple implementation for packet sending/receiving that could be used in the case of protocol lib not being installed?
  15. Offline


    Doesn't seem to be working for me, even using 182...
    Any thought of where I may have gone wrong if it works for yourself?
  16. Offline


    Perhaps something like this:

    Please note that it requires CraftBukkit, is tied to specific version (for now) and that it's much more limited than ProtocolLib. For instance, the packet "events" will be executed asynchronously on in the Netty threads, so you cannot use the Bukkit API safely. It only supports PLAY packets, and only if they are sent after a player has logged in properly.

    But other than that, it works rather well:
    1. private Function<Object, String> CHAT_MESSAGE = TinyProtocol.
    2. getFieldAccessor(PacketPlayInChat.class, String.class, 0);
    4. @Override
    5. public void onEnable() {
    6. new TinyProtocol(this) {
    7. @Override
    8. public Object onPacketInAsync(Player sender, Object packet) {
    9. // Cancel chat packets
    10. if (packet instanceof PacketPlayInChat) {
    11. if (CHAT_MESSAGE.apply(packet).contains("dirty"))
    12. return null;
    13. }
    14. return super.onPacketInAsync(sender, packet);
    15. }
    16. };
    17. }

    I don't see a point in making TinyProtocol version independent, as you should use ProtocolLib for that. Just remeber to place your custom TinyProtocol in a separate class, and load it if it's necessary.

    Just upgrade to #184.
    Cybermaxke and Minecrell like this.
  17. Offline


    Thanks! That is exactly what I wasn't doing... :)
  18. Offline


    Hello Comphenix!

    Thanks for all these updates to make our lives better.
    I have just one question.

    I used to be able to change the playername in a packet in 1.6, but since 1.7 i cant figure out how to do it.

    I tried to create a new gameProfile with the withName from WrappedGameProfile, but this removes my acess to commands and permissions.
    This is not always, but mostly after a start/reload

    The entity itself cannot be changed since a Player doenst listen to the CustomName.
    I tried to look at protocollib, but that doesnt specifically handle this.

    Any help would be appreaciated!
    (i have also looked in the packets with jd-gui, so i know what i can expect in a packet)


    this problem appeared to be essentials.
    removing it resolved it.
    i guess it didnt like the colored names or something
  19. Offline


    ProtocolLib 3.1.0

    Build: #189

    This update corrects numerous stability issues, discovered thanks to the community, as well as new API and wrappers that were missed in the previous version. In addtion, the ServerPing wrapper should now function properly.
    I have also fixed a critical deadlock that would lock up the server entirely. If you're running 3.0.1, I urge you to update.

    Minecraft 1.7.2
    Small fixes
    • Updated ProtocolLib to Minecraft 1.7.4 (version 3.0.1)
    • See GitHub for more details.
    brord and Minecrell like this.
  20. Offline


    Hello there,

    I'm new to ProtocolLib, but can already tell how useful it will be to me, and I was hoping you'd be able to answer a quick question of mine.

    What I'd like to have overall is a mob that doesn't produce sound, is invisible, yet keeps a custom name. I'm aware of Minecraft's mechanic to make mobs invisible through applying potion effects, but unfortunately that also hides the name. Would there be any chance I could achieve what I need, through the use of something like ProtocolLib?
  21. Offline


    No, as this is a client-side limitation. But you could probably hide the entity inside another (or a block), provided it is small enough. I suggest a bat.
  22. Offline



    Ah, sadly that would be no good to me, as I need them moving around and whatnot.

    Any sort of work around? Are things such as arrows able to be given names? Then I could set the entity to invisible, and have an arrow "riding" it?
  23. Offline


    No, I've tried that before, and it doesn't work. It has to be a LivingEntity.
  24. Offline



    Oh darn...

    What about when an item is inside of an ItemFrame, you're able to see the name when hovering over. is it then classed as a Living Entity?
  25. Offline


    Doesnt have health, so no, sorry!
  26. Offline


    With the newest Jenkins build I got this error when trying the command "/packet page"

    [19:05:06] [Server thread/ERROR]:  [ProtocolLib] INTERNAL ERROR: Cannot execute command packet.
      If this problem hasn't already been reported, please open a ticket
      at http://dev.bukkit.org/server-mods/protocollib/ with the following data:
                ===== STACK TRACE =====
      java.lang.ArrayIndexOutOfBoundsException: 1
          at com.comphenix.protocol.CommandPacket.handleCommand(CommandPacket.java:174)
          at com.comphenix.protocol.CommandBase.onCommand(CommandBase.java:76)
          at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
          at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:196)
          at org.bukkit.craftbukkit.v1_7_R1.CraftServer.dispatchCommand(CraftServer.java:542)
          at net.minecraft.server.v1_7_R1.PlayerConnection.handleCommand(PlayerConnection.java:932)
          at net.minecraft.server.v1_7_R1.PlayerConnection.a(PlayerConnection.java:814)
          at net.minecraft.server.v1_7_R1.PacketPlayInChat.a(PacketPlayInChat.java:28)
          at net.minecraft.server.v1_7_R1.PacketPlayInChat.handle(PacketPlayInChat.java:47)
          at net.minecraft.server.v1_7_R1.NetworkManager.a(NetworkManager.java:146)
          at net.minecraft.server.v1_7_R1.ServerConnection.c(SourceFile:134)
          at net.minecraft.server.v1_7_R1.MinecraftServer.u(MinecraftServer.java:655)
          at net.minecraft.server.v1_7_R1.DedicatedServer.u(DedicatedServer.java:250)
          at net.minecraft.server.v1_7_R1.MinecraftServer.t(MinecraftServer.java:545)
          at net.minecraft.server.v1_7_R1.MinecraftServer.run(MinecraftServer.java:457)
          at net.minecraft.server.v1_7_R1.ThreadServerApplication.run(SourceFile:617)
                ===== DUMP =====
          entity=EntityPlayer['Chemox'/343, l='world', x=-21,43, y=71,00, z=202,74](Chemox at -21.433717204309463,71.0,202.73696714855015)
            minecraftVersion=(MC: 1.7.2)
          plugin=ProtocolLib v3.1.1-SNAPSHOT
        ProtocolLib v3.1.1-SNAPSHOT
        git-Bukkit-1.7.2-R0.2-b2974jnks (MC: 1.7.2)
  27. Offline



    Also this occurs after joining a client when having "client LOGIN" added to the listeners

    Yes I found it out myself just after I posted it but because I posted 2 problems in one post I just edited out the first part.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
    Last edited by a moderator: May 28, 2016
  28. Offline



    I have recently been using ProtocolLib and have been trying to make a basic mob disguise plugin. I have used your example to spawn on the mob (a chicken instead of a ghast!), but I am stuck on what to do next, it seems 1.7 has changed a lot of stuff rendering a lot of old tutorials useless, at least forum posts anyway. So I have a few questions I would like to ask.

    The first is about the best way to "move" a client side mob. I want to update the mob's position everytime the player moves, is there a way to move a client side mob with a packet, and how can I "identify" the mob. I hate to be such a n00b at this, but it really would be helpful if you could post some code =)

    The second is how to move the head position/rotation of the mob. It looks stupid having the mob constantly face one direction, and the old threads don't seem to apply to 1.7 ;( - It appears you have to create another packet to "update" the mob's head position, but as before, I have no idea how to do it. (Again, code would be a diamond to me!). Seeing as this is currently to disguise the player, getting the players head position and rotation directly seems like a good idea.

    Thanks a lot in advance, this code could prove extremely helpful to me!


    PS: I have been using this tutorial/example code, https://gist.github.com/aadnk/4286005 , if possible, could you base the answer around this please? I don't mind if not, it would just fit in a bit better =)
  29. Offline


    Comphenix What would be the best way to change a entities type?
Thread Status:
Not open for further replies.

Share This Page