diff options
Diffstat (limited to 'patches/server/0855-Add-Listing-API-for-Player.patch')
-rw-r--r-- | patches/server/0855-Add-Listing-API-for-Player.patch | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/patches/server/0855-Add-Listing-API-for-Player.patch b/patches/server/0855-Add-Listing-API-for-Player.patch new file mode 100644 index 0000000000..05d3d3e571 --- /dev/null +++ b/patches/server/0855-Add-Listing-API-for-Player.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Corey Shupe <[email protected]> +Date: Wed, 11 Jan 2023 16:40:39 -0500 +Subject: [PATCH] Add Listing API for Player + + +diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java +index 29b465fc1dc50e0e84ddb889c5303e80fe662874..4d67d98257b2cb9045d03c999cfd4ba2caf8453c 100644 +--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java ++++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java +@@ -37,6 +37,17 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke + this.actions = EnumSet.of(action); + this.entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry(player)); + } ++ // Paper start - Add Listing API for Player ++ public ClientboundPlayerInfoUpdatePacket(EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions, List<ClientboundPlayerInfoUpdatePacket.Entry> entries) { ++ this.actions = actions; ++ this.entries = entries; ++ } ++ ++ public ClientboundPlayerInfoUpdatePacket(EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions, ClientboundPlayerInfoUpdatePacket.Entry entry) { ++ this.actions = actions; ++ this.entries = List.of(entry); ++ } ++ // Paper end - Add Listing API for Player + + public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection<ServerPlayer> players) { + EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of( +@@ -51,6 +62,28 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke + return new ClientboundPlayerInfoUpdatePacket(enumSet, players); + } + ++ // Paper start - Add Listing API for Player ++ public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection<ServerPlayer> players, ServerPlayer forPlayer) { ++ final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); ++ final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = new java.util.ArrayList<>(players.size()); ++ final org.bukkit.craftbukkit.entity.CraftPlayer bukkitEntity = forPlayer.getBukkitEntity(); ++ for (final ServerPlayer player : players) { ++ entries.add(new ClientboundPlayerInfoUpdatePacket.Entry(player, bukkitEntity.isListed(player.getBukkitEntity()))); ++ } ++ return new ClientboundPlayerInfoUpdatePacket(enumSet, entries); ++ } ++ ++ public static ClientboundPlayerInfoUpdatePacket createSinglePlayerInitializing(ServerPlayer player, boolean listed) { ++ final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); ++ final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = List.of(new Entry(player, listed)); ++ return new ClientboundPlayerInfoUpdatePacket(enumSet, entries); ++ } ++ ++ public static ClientboundPlayerInfoUpdatePacket updateListed(UUID playerInfoId, boolean listed) { ++ EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); ++ return new ClientboundPlayerInfoUpdatePacket(enumSet, new ClientboundPlayerInfoUpdatePacket.Entry(playerInfoId, listed)); ++ } ++ // Paper end - Add Listing API for Player + private ClientboundPlayerInfoUpdatePacket(RegistryFriendlyByteBuf buf) { + this.actions = buf.readEnumSet(ClientboundPlayerInfoUpdatePacket.Action.class); + this.entries = buf.readList(buf2 -> { +@@ -161,10 +194,15 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke + @Nullable RemoteChatSession.Data chatSession + ) { + Entry(ServerPlayer player) { ++ // Paper start - Add Listing API for Player ++ this(player, true); ++ } ++ Entry(ServerPlayer player, boolean listed) { + this( ++ // Paper end - Add Listing API for Player + player.getUUID(), + player.getGameProfile(), +- true, ++ listed, // Paper - Add Listing API for Player + player.connection.latency(), + player.gameMode.getGameModeForPlayer(), + player.getTabListDisplayName(), +@@ -172,6 +210,11 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke + Optionull.map(player.getChatSession(), RemoteChatSession::asData) + ); + } ++ // Paper start - Add Listing API for Player ++ Entry(UUID profileId, boolean listed) { ++ this(profileId, null, listed, 0, GameType.DEFAULT_MODE, null, 0, null); ++ } ++ // Paper end - Add Listing API for Player + } + + static class EntryBuilder { +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index a1228d09b91dca3989a4be3120f9724a6e138040..fa951c6e33d583f9c2ca103fbaaa035e40c163f9 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -363,14 +363,22 @@ public abstract class PlayerList { + // CraftBukkit end + + // CraftBukkit start - sendAll above replaced with this loop +- ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); ++ ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player + + final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join + for (int i = 0; i < this.players.size(); ++i) { + ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); + + if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) { ++ // Paper start - Add Listing API for Player ++ if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) { ++ // Paper end - Add Listing API for Player + entityplayer1.connection.send(packet); ++ // Paper start - Add Listing API for Player ++ } else { ++ entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false)); ++ } ++ // Paper end - Add Listing API for Player + } + + if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player +@@ -381,7 +389,7 @@ public abstract class PlayerList { + } + // Paper start - Use single player info update packet on join + if (!onlinePlayers.isEmpty()) { +- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers)); ++ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player)); // Paper - Add Listing API for Player + } + // Paper end - Use single player info update packet on join + player.sentListPacket = true; +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 80877e62d0743891f38abeee5b5b04b4f3bc4010..1943cb7b691573d3f9755d21d4b5a4210c1cc329 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -206,6 +206,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + private final ConversationTracker conversationTracker = new ConversationTracker(); + private final Set<String> channels = new HashSet<String>(); + private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new HashMap<>(); ++ private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player + private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>(); + private int hash = 0; + private double health = 20; +@@ -2122,7 +2123,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + otherPlayer.setUUID(uuidOverride); + } + // Paper end +- this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(otherPlayer))); ++ this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(otherPlayer), this.getHandle())); // Paper - Add Listing API for Player + if (original != null) otherPlayer.setUUID(original); // Paper - uuid override + } + +@@ -2226,6 +2227,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it + } + ++ // Paper start - Add Listing API for Player ++ @Override ++ public boolean isListed(Player other) { ++ return !this.unlistedEntities.contains(other.getUniqueId()); ++ } ++ ++ @Override ++ public boolean unlistPlayer(@NotNull Player other) { ++ Preconditions.checkNotNull(other, "hidden entity cannot be null"); ++ if (this.getHandle().connection == null) return false; ++ if (!this.canSee(other)) return false; ++ ++ if (unlistedEntities.add(other.getUniqueId())) { ++ this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.updateListed(other.getUniqueId(), false)); ++ return true; ++ } else { ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean listPlayer(@NotNull Player other) { ++ Preconditions.checkNotNull(other, "hidden entity cannot be null"); ++ if (this.getHandle().connection == null) return false; ++ if (!this.canSee(other)) throw new IllegalStateException("Player cannot see other player"); ++ ++ if (this.unlistedEntities.remove(other.getUniqueId())) { ++ this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.updateListed(other.getUniqueId(), true)); ++ return true; ++ } else { ++ return false; ++ } ++ } ++ // Paper end - Add Listing API for Player ++ + @Override + public Map<String, Object> serialize() { + Map<String, Object> result = new LinkedHashMap<String, Object>(); |