aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0855-Add-Listing-API-for-Player.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0855-Add-Listing-API-for-Player.patch')
-rw-r--r--patches/server/0855-Add-Listing-API-for-Player.patch186
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>();