diff --git a/src/de/steamwar/bungeecore/tablist/Tablist.java b/src/de/steamwar/bungeecore/tablist/Tablist.java index 338a38d1..b3471479 100644 --- a/src/de/steamwar/bungeecore/tablist/Tablist.java +++ b/src/de/steamwar/bungeecore/tablist/Tablist.java @@ -34,9 +34,8 @@ import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.PacketWrapper; -import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; -import net.md_5.bungee.protocol.packet.PlayerListItem; -import net.md_5.bungee.protocol.packet.Team; +import net.md_5.bungee.protocol.ProtocolConstants; +import net.md_5.bungee.protocol.packet.*; import java.util.*; import java.util.stream.Collectors; @@ -94,6 +93,7 @@ public class Tablist extends MessageToMessageDecoder { tablist.add(0, item); } else if(!tabItem.getDisplayName().equals(item.getDisplayName())) { tabItem.setDisplayName(item.getDisplayName()); + tabItem.setListed(true); update.add(tabItem); } } @@ -120,6 +120,7 @@ public class Tablist extends MessageToMessageDecoder { tabItem.setUuid(uuids[i]); tabItem.setUsername(names[i]); tabItem.setGamemode(1); + tabItem.setListed(true); tabItem.setPing(1000); current.add(tabItem); } @@ -167,7 +168,8 @@ public class Tablist extends MessageToMessageDecoder { pipeline.remove("steamwar-tablist"); pipeline.addBefore(PipelineUtils.BOSS_HANDLER, "steamwar-tablist", this); - player.unsafe().sendPacket(teamPacket); + if(oldTab()) + player.unsafe().sendPacket(teamPacket); } } @@ -214,6 +216,7 @@ public class Tablist extends MessageToMessageDecoder { for (PlayerListItem.Item item : list.getItems()) { item.setPing(1); item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText(""))); + item.setListed(false); item.setPublicKey(null); if(!player.getUniqueId().equals(item.getUuid()) && item.getGamemode() == 3) item.setGamemode(1); @@ -235,22 +238,93 @@ public class Tablist extends MessageToMessageDecoder { sendNpcPacket(names, true); break; } + } else if(packet instanceof PlayerListItemRemove) { + for(UUID uuid : ((PlayerListItemRemove) packet).getUuids()) { + synchronized (directTabItems) { + directTabItems.remove(uuid); + } + } + } else if(packet instanceof PlayerListItemUpdate) { + PlayerListItemUpdate list = (PlayerListItemUpdate) packet; + EnumSet actions = list.getActions(); + actions.remove(PlayerListItemUpdate.Action.INITIALIZE_CHAT); + actions.remove(PlayerListItemUpdate.Action.UPDATE_LATENCY); + actions.remove(PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME); + actions.remove(PlayerListItemUpdate.Action.UPDATE_LISTED); + if(actions.isEmpty()) { + packetWrapper.trySingleRelease(); + return; + } + + for(PlayerListItemUpdate.Action action : actions) { + switch (action) { + case ADD_PLAYER: + for (PlayerListItem.Item item : list.getItems()) { + item.setPing(1); + item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText(""))); + item.setListed(false); + item.setPublicKey(null); + if(!player.getUniqueId().equals(item.getUuid()) && item.getGamemode() == 3) + item.setGamemode(1); + + synchronized (directTabItems) { + directTabItems.put(item.getUuid(), item); + } + } + break; + case UPDATE_GAMEMODE: + for (PlayerListItem.Item item : list.getItems()) { + ProxiedPlayer p = ProxyServer.getInstance().getPlayer(item.getUuid()); + if(p != null && p != player && item.getGamemode() == 3) { + item.setGamemode(1); + } + } + break; + case UPDATE_LISTED: + case INITIALIZE_CHAT: + case UPDATE_LATENCY: + case UPDATE_DISPLAY_NAME: + break; + } + } + + if(actions.contains(PlayerListItemUpdate.Action.ADD_PLAYER)) { + actions.add(PlayerListItemUpdate.Action.UPDATE_LISTED); + actions.add(PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME); + actions.add(PlayerListItemUpdate.Action.UPDATE_LATENCY); + actions.add(PlayerListItemUpdate.Action.UPDATE_GAMEMODE); + } } } out.add(packetWrapper); } - private void sendTabPacket(List items, PlayerListItem.Action action) { + private boolean oldTab() { + return player.getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_19_3; + } + + private void sendTabPacket(List items, PlayerListItem.Action action) { //Breaks in 1.19.3 if action != UPDATE_DISPLAY_NAME, ADD_PLAYER or REMOVE_PLAYER if(!items.isEmpty()) { - PlayerListItem packet = new PlayerListItem(); - packet.setAction(action); - packet.setItems(items.toArray(new PlayerListItem.Item[0])); - player.unsafe().sendPacket(packet); + if(oldTab()) { + PlayerListItem packet = new PlayerListItem(); + packet.setAction(action); + packet.setItems(items.toArray(new PlayerListItem.Item[0])); + player.unsafe().sendPacket(packet); + } else if(action == PlayerListItem.Action.REMOVE_PLAYER) { + PlayerListItemRemove packet = new PlayerListItemRemove(); + packet.setUuids(items.stream().map(PlayerListItem.Item::getUuid).toArray(UUID[]::new)); + player.unsafe().sendPacket(packet); + } else { + PlayerListItemUpdate packet = new PlayerListItemUpdate(); + packet.setActions(action == PlayerListItem.Action.UPDATE_DISPLAY_NAME ? EnumSet.of(PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME, PlayerListItemUpdate.Action.UPDATE_LISTED) : EnumSet.of(PlayerListItemUpdate.Action.ADD_PLAYER, PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME, PlayerListItemUpdate.Action.UPDATE_LATENCY, PlayerListItemUpdate.Action.UPDATE_LISTED, PlayerListItemUpdate.Action.UPDATE_GAMEMODE)); + packet.setItems(items.toArray(new PlayerListItem.Item[0])); + player.unsafe().sendPacket(packet); + } } } private void sendNpcPacket(List names, boolean remove) { - if(!names.isEmpty()) { + if(oldTab() && !names.isEmpty()) { Team packet = new Team(TAB_TEAM); packet.setMode((byte) (remove ? 4 : 3)); packet.setPlayers(names.toArray(new String[0])); diff --git a/src/de/steamwar/bungeecore/util/Chat19.java b/src/de/steamwar/bungeecore/util/Chat19.java index 37a3f303..1b8315a2 100644 --- a/src/de/steamwar/bungeecore/util/Chat19.java +++ b/src/de/steamwar/bungeecore/util/Chat19.java @@ -22,9 +22,11 @@ package de.steamwar.bungeecore.util; import net.md_5.bungee.ServerConnection; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.protocol.ChatChain; +import net.md_5.bungee.protocol.SeenMessages; import net.md_5.bungee.protocol.packet.ClientChat; import net.md_5.bungee.protocol.packet.ClientCommand; +import java.util.BitSet; import java.util.Collections; public class Chat19 { @@ -33,9 +35,9 @@ public class Chat19 { public static void chat(ProxiedPlayer p, String message) { if(p.getPendingConnection().getVersion() >= 759) { if(message.startsWith("/")) { - ((ServerConnection) p.getServer()).getCh().write(new ClientCommand(message.substring(1), System.currentTimeMillis(), 0, Collections.emptyMap(), false, new ChatChain(Collections.emptyList(), null))); + ((ServerConnection) p.getServer()).getCh().write(new ClientCommand(message.substring(1), System.currentTimeMillis(), 0, Collections.emptyMap(), false, new ChatChain(Collections.emptyList(), null), new SeenMessages(0, new BitSet(0)))); } else { - ((ServerConnection) p.getServer()).getCh().write(new ClientChat(message, System.currentTimeMillis(), 0, new byte[0], false, new ChatChain(Collections.emptyList(), null))); + ((ServerConnection) p.getServer()).getCh().write(new ClientChat(message, System.currentTimeMillis(), 0, null, false, new ChatChain(Collections.emptyList(), null), new SeenMessages(0, new BitSet(0)))); } } else { p.chat(message);