Packets and reloads

Discussion in 'Plugin Development' started by xTrollxDudex, Jul 10, 2013.

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

    xTrollxDudex

    How do I work with packets? Like sending, applying it to an entity. Where can I find a full list of them? Make it packet-noob friendly. I've never ever worked with packets before. You don't need to have bukkit stuff, just the whole packets idea.

    One more question. What are examples of handling reloads for hashmaps?

    PLZ don't spam the comments with ProtocolLib. But if you can show me a basic example (not the complex ones like aadnk posted) then you can refer to ProtocolLib
     
  2. Offline

    andf54

    http://mc.kev009.com/Protocol

    Code:
    public static void sendPacket(Packet packet)
     {
        ((CraftServer)Bukkit.getServer()).getServer().getPlayerList().sendAll((packet));
     }
    
    There are also methods for sending packets to certain players only.
     
  3. Offline

    Comphenix

    You don't need ProtocolLib if you're just interested in sending packets - it only becomes necessary if you want to modify the packets Bukkit sends, or the packets that are recieved from each client. For instance, an Orebfuscator-like plugin would modify each outgoing Map Chunk (bulk) packet and remove blocks (with a random pattern or as stone) that are supposed to be invisible to the player. You can't do that safely (and efficently) if you're just limited to sending packets using the standard methods. So, more often than not, intercepting packets really is necessary - just take a look here.

    But you should be really careful - if you send an invalid packet to a client by mistake, you may very likely crash it (usually with no stack trace). This can be pretty difficult to debug, especially if you're new to programming in Java. If you're faced with these problems - you may have to read the partially obfuscated source code in CraftBukkit and Minecraft to solve the problem. Though, if you stick to simple packets such as Packet3Chat, you're probably safe from most of this complexity.

    No offense, but if you feel ProtocolLib is too hard for you, you might be a litte over your head. Though it depends on
    what you intend to do.

    Examples of handling reloads? I'm not entirely sure what you want here, but if you don't store players as keys (just store their name), it shouldn't be a concern.
     
  4. Offline

    xTrollxDudex

    Comphenix
    Oh so protocol lib only modifies packets? Hmm. I never knew that

    And being "experienced" with bukkit meant I know Player objects cause memory leaks. What I've heard is if you have a regular HashMap, you would lose data in a reload or something along the lines of "unhandled reload"...

    EDIT: andf54 so what would the send packet do? Send all the players that can see the player this is being applied to or it magically makes a mysterious player for everyone? Again I am a noob with packets

    Code:java
    1.  
    2. Packet63WorldParticle packet = new Packet63WorldParticle("smoke", player.getLocation.getX(), player.getLocation().getY(), player.getLocation().getZ(), 0, 0, 0, 0.5, 6);
    3.  
    4. ((CraftServer) Bukkit.getServer()).getServer().getPlayerList().sendAll(packet);
    5. //would that work? The arguments are player x,y,z, the offset x,y,z, the speed, and amount.
    6. //I have no idea what offset is or the parameters for speed and amount
     
  5. Offline

    andf54

    I believe ProtocolLib can send packets as well. However since you can do it yourself, it isn't necessary.

    sendAll will send to everyone, whether they see it or not. Depending on the packet it may not affect players. For example if you make a particle at a location X, far a way from player Y and then send it to Y, then the player will get the package, but he will not see the effect.

    Its not practical to send the packet to all players. Just send it to players within a certain radius. Use other methods instead of sendAll.

    Particles are random. The offset determines how far from the spawn location they can appear. Speed determines how fast will they move. Amount determines the amount of particles. Each will fly in a random direction (offset > 0).
     
    xTrollxDudex likes this.
  6. Offline

    Comphenix

    You can also send packets without having to depend on a particular version of CraftBukkit, as in your current method. But it is primarily used to modify packets, yeah.

    Yes, if you want to persist it through reloads and restarts, I suggest you simply save the map entries to a file. You could use a YamlConfiguration, or perhaps just plain old Java serialization.
     
  7. Offline

    TeeePeee

    Comphenix
    I don't mean to gravedig or hijack this thread, but what about sending packets to players that log in after the packet has been constructed? Specifically Packet 20 (NamedEntitySpawn). If the entity already exists and the packet is stored in a java.util.List, how would one send this packet to the newly logged-in player?
    Code for the packet:
    Code:java
    1. Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn();
    2. packet.a = zombie.getBukkitEntity().getEntityId(); // Entity ID.
    3. packet.b = "Bill"; // Name.
    4. packet.c = (int) LOCATION.getX() * 32; // X
    5. packet.d = (int) LOCATION.getY() * 32; // Y
    6. packet.e = (int) LOCATION.getZ() * 32; // Z
    7. packet.f = 0; // Pitch
    8. packet.g = 0; // Yaw
    9. packet.h = zombie.getEquipment(0) != null ? zombie.getEquipment(0).id : 0; // Hand item
    10.  
    11. DataWatcher datawatcher = new DataWatcher(); // DataWatcher
    12. datawatcher.a(0, (Object) (byte) 0);
    13. datawatcher.a(1, (Object) (short) 0);
    14. datawatcher.a(8, (Object) (byte) 0);
    15. // Apply the DataWatcher.
    16. try {
    17. Field f = packet.getClass().getDeclaredField("i");
    18. f.setAccessible(true);
    19. f.set(packet, datawatcher);
    20. } catch (Exception e) {
    21. e.printStackTrace();
    22. }
    23. // Send the packet to a player.
    24. ((CraftPlayer) PLAYER).getHandle().playerConnection.sendPacket(packet);
    25. // Now store the packet in a HashMap with the value being the world name so it can be sent to players that aren't currently online for when they log into the correct world.
    26. packetList.put(packet, LOCATION.getWorld().getName());
     
  8. Offline

    The_Doctor_123

    TeeePeee
    Little too late to reply..
     
    xTrollxDudex likes this.
  9. Offline

    xTrollxDudex

    TeeePeee
    Only human NPCs can be spawned with packet 20
     
  10. Offline

    TeeePeee

    xTrollxDudex
    Any entity can be spawned and their entity ID can be used in the construction of Packet 20 which will make the entity appear to be a human NPC.
     
  11. Offline

    xTrollxDudex

    TeeePeee
    Okay, then you'll need to remove that zombie entity before spawning, or else the ids will conflict. Listen for player logo even and loop through the map, sending off the packets
     
  12. Offline

    TeeePeee

    xTrollxDudex
    I think you're misunderstanding. The entity is spawned and the packet is constructed with the entities ID so that it appears to be a player. In this way, all zombies are disguised as players.
    If I send the same packet that was constructed when they entity spawned after the player re-logs, the player still sees the entity as a zombie, not a player as desired.
    [EDIT]
    Added a 5 tick delay and it seemed to solve it. Guess the chunk wasn't loading or the initial packet had not yet been sent to the player.
     
Thread Status:
Not open for further replies.

Share This Page