From 7a03b327efc2061034d1085c7fe51892f2358df4 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 3 Jul 2025 18:00:17 +0200 Subject: [PATCH] Fix tablist for real --- .../velocitycore/tablist/Tablist.java | 29 +---- .../tablist/UpdateTeamsPacket21.java | 103 ++++++++++++++++++ 2 files changed, 106 insertions(+), 26 deletions(-) create mode 100644 VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java index 1447ee3c..6afb69c7 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java @@ -51,7 +51,7 @@ public class Tablist extends ChannelInboundHandlerAdapter { private static final UUID[] swUuids = IntStream.range(0, 80).mapToObj(i -> UUID.randomUUID()).toArray(UUID[]::new); private static final String[] swNames = IntStream.range(0, 80).mapToObj(i -> " »SW« " + String.format("%02d", i)).toArray(String[]::new); - public static final UpdateTeamsPacket createTeamPacket = new UpdateTeamsPacket("zzzzzsw-tab", UpdateTeamsPacket.Mode.CREATE, Component.empty(), Component.empty(), Component.empty(), UpdateTeamsPacket.NameTagVisibility.NEVER, UpdateTeamsPacket.CollisionRule.ALWAYS, 21, (byte)0x00, Arrays.stream(Tablist.swNames).toList()); + public static final UpdateTeamsPacket createTeamPacket = new UpdateTeamsPacket21("zzzzzsw-tab", UpdateTeamsPacket.Mode.CREATE, Component.empty(), Component.empty(), Component.empty(), UpdateTeamsPacket.NameTagVisibility.NEVER, UpdateTeamsPacket.CollisionRule.ALWAYS, 21, (byte)0x00, Arrays.stream(Tablist.swNames).toList()); private final Map directTabItems; private final List current = new ArrayList<>(); @@ -75,26 +75,12 @@ public class Tablist extends ChannelInboundHandlerAdapter { List tablist = new ArrayList<>(); List direct = new ArrayList<>(); global.print(viewer, player, tablist, direct); - - // NPC handling - List update = new ArrayList<>(); - synchronized (directTabItems) { - for (TablistPart.Item item : direct) { - UpsertPlayerInfoPacket.Entry tabItem = directTabItems.get(item.getUuid()); - - if(tabItem == null) { - tablist.add(0, item); - } else if(!item.getDisplayName().equals(getDisplayName(tabItem))) { - tabItem.setDisplayName(new ComponentHolder(player.getProtocolVersion(), item.getDisplayName())); - tabItem.setListed(true); - update.add(tabItem); - } - } - } + tablist.addAll(0, direct); // Main list handling int i = 0; List add = new ArrayList<>(); + List update = new ArrayList<>(); List remove = new ArrayList<>(); for (; i < tablist.size() && i < 80; i++) { TablistPart.Item item = tablist.get(i); @@ -148,15 +134,6 @@ public class Tablist extends ChannelInboundHandlerAdapter { current.clear(); } - if (player.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_21_5)) { - sendTabPacket(new ArrayList<>(directTabItems.values()), null); - directTabItems.clear(); - sendTabPacket(current, null); - current.clear(); - // TODO: Misformed Team Packet? - return; - } - sendPacket(player, createTeamPacket); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java new file mode 100644 index 00000000..3feab317 --- /dev/null +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java @@ -0,0 +1,103 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.velocitycore.tablist; + +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.packet.UpdateTeamsPacket; +import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder; +import io.netty.buffer.ByteBuf; +import net.kyori.adventure.text.Component; + +import java.util.List; + +public class UpdateTeamsPacket21 extends UpdateTeamsPacket { + + private String name; + private Mode mode; + private Component displayName; + private Component prefix; + private Component suffix; + private NameTagVisibility nameTagVisibility; + private CollisionRule collisionRule; + private int color; + private byte friendlyFlags; + private List players; + + public UpdateTeamsPacket21(String name, Mode mode, Component displayName, Component prefix, Component suffix, NameTagVisibility nameTagVisibility, CollisionRule collisionRule, int color, byte friendlyFlags, List players) { + super(name, mode, displayName, prefix, suffix, nameTagVisibility, collisionRule, color, friendlyFlags, players); + this.name = name; + this.mode = mode; + this.displayName = displayName; + this.prefix = prefix; + this.suffix = suffix; + this.nameTagVisibility = nameTagVisibility; + this.collisionRule = collisionRule; + this.color = color; + this.friendlyFlags = friendlyFlags; + this.players = players; + } + + @Override + public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { + ProtocolUtils.writeString(byteBuf, this.name); + byteBuf.writeByte(this.mode.ordinal()); + switch (this.mode) { + case CREATE: + case UPDATE: + (new ComponentHolder(protocolVersion, this.displayName)).write(byteBuf); + if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_13)) { + (new ComponentHolder(protocolVersion, this.prefix)).write(byteBuf); + (new ComponentHolder(protocolVersion, this.suffix)).write(byteBuf); + } + + byteBuf.writeByte(this.friendlyFlags); + if (protocolVersion.noLessThan(ProtocolVersion.MINECRAFT_1_21_5)) { + ProtocolUtils.writeVarInt(byteBuf, this.nameTagVisibility.ordinal()); + ProtocolUtils.writeVarInt(byteBuf, this.collisionRule.ordinal()); + } else { + ProtocolUtils.writeString(byteBuf, this.nameTagVisibility.getValue()); + ProtocolUtils.writeString(byteBuf, this.collisionRule.getValue()); + } + if (protocolVersion.greaterThan(ProtocolVersion.MINECRAFT_1_12_2)) { + ProtocolUtils.writeVarInt(byteBuf, this.color); + (new ComponentHolder(protocolVersion, this.prefix)).write(byteBuf); + (new ComponentHolder(protocolVersion, this.suffix)).write(byteBuf); + } else { + byteBuf.writeByte((byte)this.color); + } + + ProtocolUtils.writeVarInt(byteBuf, this.players.size()); + + for(String player : this.players) { + ProtocolUtils.writeString(byteBuf, player); + } + break; + case ADD_PLAYER: + case REMOVE_PLAYER: + ProtocolUtils.writeVarInt(byteBuf, this.players.size()); + + for(String player : this.players) { + ProtocolUtils.writeString(byteBuf, player); + } + case REMOVE: + } + } +}