BungeeCord Packets (sound)

Discussion in 'BungeeCord Plugin Development' started by kaarma, Jan 19, 2020.

Thread Status:
Not open for further replies.
  1. Hi, I am trying to send a "custom" packet from bungeecord (the namedplaysound). So far i have done some things.

    First, I have my packet class:
    Code (Java):
    public class OutNamedSoundEffect extends DefinedPacket {

        public int name;
        public int cat;
        private int x;
        private int y;
        private int z;
        private float volume;
        private float pitch;

        public OutNamedSoundEffect(){}

        public OutNamedSoundEffect(int sound, int cat, double x, double y, double z, float volume, float pitch) {
            this.name = sound;
            this.cat = cat;
            setX(x);
            setY(y);
            setZ(z);
            this.volume = volume;
            this.pitch = pitch;
        }

        public void setX(double x) {
            this.x = ((int)(x * 8.0D));
        }

        public void setY(double y) {
            this.y = ((int)(y * 8.0D));
        }

        public void setZ(double z) {
            this.z = ((int)(z * 8.0D));
        }

        @Override
        public void handle(AbstractPacketHandler abstractPacketHandler) throws Exception {
           
        }

     
        @Override
        public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
            this.sound = readVarInt(buf);
            this.cat = readVarInt(buf);
            this.x = buf.readInt();
            this.y = buf.readInt();
            this.z = buf.readInt();
            this.volume = buf.readFloat();
            this.pitch = buf.readFloat();
        }

        @Override
        public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
            writeVarInt(sound, buf);
            writeVarInt(cat, buf);

            buf.writeInt(this.x);
            buf.writeInt(this.y);
            buf.writeInt(this.z);

            buf.writeFloat(this.volume);
            buf.writeFloat(this.pitch);
        }

        @Override
        public boolean equals(Object o) {
            return false;
        }

        @Override
        public int hashCode() {
            return 0;
        }

        @Override
        public String toString() {
            return getClass().getName();
        }
    }
    I have my class that register this packet:
    Code (Java):
    public class PacketReg {

        private static Method map, regPacket;
        private static Class<?> protocolMapping, protocolMappingArray;
        private static Object TO_CLIENT;


        public static void processReflexion(){
            try {
                Field f = Protocol.class.getDeclaredField("TO_CLIENT");
                map = Protocol.class.getDeclaredMethod("map", int.class, int.class);
                f.setAccessible(true);
                map.setAccessible(true);
                protocolMapping = map.getReturnType();
                protocolMappingArray = Array.newInstance(protocolMapping, 0).getClass();
                TO_CLIENT = f.get(Protocol.GAME);
                regPacket = TO_CLIENT.getClass().getDeclaredMethod("registerPacket", Class.class, protocolMappingArray);
                regPacket.setAccessible(true);
            } catch (IllegalAccessException | NoSuchFieldException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }

        public static void regPacket(Class<?> c, int id){
            Object[] array = (Object[]) Array.newInstance(protocolMapping, 1);
            try {
                array[0] = map.invoke(null, 573, id); //573 is the protocol version for 1.15
                regPacket.invoke(TO_CLIENT, c, array);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }

    }
     
    And then i register the packet:
    Code (Java):
    PacketReg.processReflexion();
    PacketReg.regPacket(OutNamedSoundEffect.class, 82); //82 is the id of sound efect in 1.15 ( see [URL]https://wiki.vg/Pre-release_protocol[/URL])
    So i think all of this works.

    But when i try to send it:
    Code (Java):
    ((ProxiedPlayer) sender).unsafe().
                        sendPacket(new OutNamedSoundEffect(12, 8, 0, 13, 0, 1F, 1F));//12 is for
    BLOCK_ANVIL_PLACE and 8 is for AMBIENT sound category
    The I get disconected with this message:
    [​IMG]

    So i tried to do the same thing on spigot, and get the paket as an byte array (with
    PacketDataSerializer), and i get this :

    [12, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 63, -128, 0, 0, 63, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    And then i did the same thing in my bungee packet and i get this:

    [12, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 63, -128, 0, 0, 63, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    As you can see, they are the same.

    So I am the sending the same thing from bungee and from spigot, but it doesnt work when i send it from bungee, and i dont know why...

    (and nothing is throw in bungee console or minecraft console)
     
    #1 kaarma, Jan 19, 2020
    Last edited: Jan 24, 2020
  2. Perhaps you're sending it in the wrong spot? Where do you send the packet to the player?
     
  3. I jsut dis a test command and used this
     
  4. Ok so I tried to do the same thing but with an other packet, the update health.

    This is what i come up with:
    Code (Text):
    public class OutHealth extends DefinedPacket {

        float health;
        int food;
        float saturation;

        public OutHealth(){

        }

        public OutHealth(float h, int f, float s){
            this.health = h;
            this.food = f;
            this.saturation = s;
        }

        @Override
        public void handle(AbstractPacketHandler abstractPacketHandler) {

        }

        public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
            this.health = buf.readFloat();
            this.food = i(buf);
            this.saturation = buf.readFloat();
        }

        public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
            buf.writeFloat(this.health);
            d(buf, this.food);
            buf.writeFloat(this.saturation);
        }

        public void d(ByteBuf b, int i){
            while((i & -128) != 0) {
                b.writeByte(i & 127 | 128);
                i >>>= 7;
            }
            b.writeByte(i);
        }

        public int i(ByteBuf buf) {
            int i = 0;
            int j = 0;

            byte b0;
            do {
                b0 = buf.readByte();
                i |= (b0 & 127) << j++ * 7;
                if (j > 5) {
                    throw new RuntimeException("VarInt too big");
                }
            } while((b0 & 128) == 128);

            return i;
        }

        @Override
        public boolean equals(Object o) {
            return false;
        }

        @Override
        public int hashCode() {
            return 0;
        }

        @Override
        public String toString() {
            return "OutHealth";
        }
    }
    And i register it:

    Code (Text):
    PacketReg.regPacket(OutHealth.class, 73);
    And it worked just fine. So all the packet registration work, and it send it well. So the problem i have come from what i am doing in the packet NamedSoundEffect
     
  5. OK I found the solution. So the problem was the id. The minecraft packet is named "PacketPlayOutNamedSoundEffect", so i though i had to use the packet id of "Named Sound Effect" on https://wiki.vg/, but no, the id for the packet "PacketPlayOutNamedSoundEffect" is the id of "Sound Effect" on https://wiki.vg/, not very intuitive...
    (I changed the code i wrote on my first post, so that it work if someone want to use it)
     
Thread Status:
Not open for further replies.