1.13.2 Send different packet based on player's version

Discussion in 'Spigot Plugin Development' started by teegah, Mar 24, 2020.

  1. I have a plugin that uses scoreboard teams to set custom prefixes/suffixes to the player nametag but 1.13+ clients dont see the prefixes/suffixes but it works fine for 1.12 and lower players.

    The ScoreboardTeam packet was changed between 1.12 - 1.13 so I tried:
    Listen for team packets -> look at version of player who receives the packet -> if 1.13+ -> cancel packet sending and reconstruct the packet to match 1.13-> send them that packet.

    This is the error I got
    com.comphenix.protocol.reflect.FieldAccessException: No field with type net.minecraft.server.v1_12_R1.IChatBaseComponent exists in class PacketPlayOutScoreboardTeam.

    Is this a bug for ViaVersion to fix or is there anything I can do?

    Code (Java):
    ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(plugin, PacketType.Play.Server.SCOREBOARD_TEAM) {

                @Override
                public void onPacketSending(final PacketEvent event){

                    Player player = event.getPlayer();
                    PacketContainer packet = event.getPacket();
                    if(Via.getAPI().getPlayerVersion(player) > 340){

                        Bukkit.broadcastMessage("Player " + player.getName() + " is on version higher than 1.12");
                        Bukkit.broadcastMessage("Player " + player.getName() + " is on version higher than 1.12");
                        WrapperPlayServerScoreboardTeam wrapped = new WrapperPlayServerScoreboardTeam(packet);
                        wrapped.setDisplayName(WrappedChatComponent.fromText(packet.getStrings().read(1)));
                        wrapped.setPrefix(WrappedChatComponent.fromText(packet.getStrings().read(2)));
                        wrapped.setSuffix(WrappedChatComponent.fromText(packet.getStrings().read(3)));
                        wrapped.setNameTagVisibility(packet.getStrings().read(4));
                        wrapped.setColor(ChatColor.RESET);
                        wrapped.setCollisionRule(packet.getStrings().read(5));
                        wrapped.setMode(packet.getIntegers().read(1));
                        wrapped.setPackOptionData(packet.getIntegers().read(2));
                        event.setPacket(wrapped.getHandle());
                    }

                }
            });
     
    #1 teegah, Mar 24, 2020
    Last edited: Mar 24, 2020
  2. via version mostly serves to convert packets from one version to another. It wont generate the classes on the client end. I dont work with via version myself, so I cannot offer you a specific solution here, but you should be fine so long you implement your code based on the server version you are running on. Via version should take care of conversion on its own ... probably?

    someone else might be better informed.
     
  3. Agreed with this. ViaVersion is basically a middleman that converts server version packets to client version and vice versa. Your plugin sits on the server side of ViaVersion so you cannot interact with the client protocols (save for boss bars and some select other features Via has included in its API).

    If clients of different versions are seeing something different for something that should be available to both versions, it sounds like either ViaVersion has a bug or you are not implementing scoreboards correctly.