Add Listing API for Player

This commit is contained in:
Corey Shupe 2023-01-11 16:40:39 -05:00
parent 8e05d19854
commit 53fab9663b
3 changed files with 170 additions and 32 deletions

View File

@ -1,6 +1,72 @@
--- a/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java --- a/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
+++ b/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java +++ b/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
@@ -116,7 +116,15 @@ @@ -38,7 +38,18 @@
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(
ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER,
@@ -53,6 +64,46 @@
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,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LIST_ORDER
+ );
+ 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,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT,
+ ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LIST_ORDER
+ );
+ 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 -> {
@@ -116,7 +167,15 @@
}), }),
INITIALIZE_CHAT( INITIALIZE_CHAT(
(serialized, buf) -> serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read), (serialized, buf) -> serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read),
@ -17,3 +83,32 @@
), ),
UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())), UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())),
UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())), UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())),
@@ -157,10 +216,15 @@
@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(),
@@ -169,6 +233,11 @@
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, true, 0, null);
+ }
+ // Paper end - Add Listing API for Player
}
static class EntryBuilder {

View File

@ -235,7 +235,7 @@
playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot()); playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
ServerStatus serverping = this.server.getStatus(); ServerStatus serverping = this.server.getStatus();
@@ -222,17 +327,101 @@ @@ -222,17 +327,109 @@
player.sendServerStatus(serverping); player.sendServerStatus(serverping);
} }
@ -279,14 +279,22 @@
+ // CraftBukkit end + // CraftBukkit end
+ +
+ // CraftBukkit start - sendAll above replaced with this loop + // 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 + 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) { + for (int i = 0; i < this.players.size(); ++i) {
+ ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); + ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
+ +
+ if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) { + 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); + 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 + if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player
@ -297,7 +305,7 @@
+ } + }
+ // Paper start - Use single player info update packet on join + // Paper start - Use single player info update packet on join
+ if (!onlinePlayers.isEmpty()) { + 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 + // Paper end - Use single player info update packet on join
+ player.sentListPacket = true; + player.sentListPacket = true;
@ -342,7 +350,7 @@
} }
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
@@ -269,30 +458,31 @@ @@ -269,30 +466,31 @@
} }
public void addWorldborderListener(ServerLevel world) { public void addWorldborderListener(ServerLevel world) {
@ -379,7 +387,7 @@
} }
@Override @Override
@@ -319,14 +509,15 @@ @@ -319,14 +517,15 @@
} }
protected void save(ServerPlayer player) { protected void save(ServerPlayer player) {
@ -397,7 +405,7 @@
if (advancementdataplayer != null) { if (advancementdataplayer != null) {
advancementdataplayer.save(); advancementdataplayer.save();
@@ -334,95 +525,210 @@ @@ -334,95 +533,210 @@
} }
@ -596,11 +604,10 @@
} }
- return ichatmutablecomponent; - return ichatmutablecomponent;
- } else {
- return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(profile) ? Component.translatable("multiplayer.disconnect.server_full") : null;
+ // return chatmessage; + // return chatmessage;
+ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure + event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
+ } else { } else {
- return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(profile) ? Component.translatable("multiplayer.disconnect.server_full") : null;
+ // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; + // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null;
+ if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { + if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) {
+ event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure + event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
@ -647,7 +654,7 @@
if (entityplayer1 != null) { if (entityplayer1 != null) {
set.add(entityplayer1); set.add(entityplayer1);
@@ -431,72 +737,160 @@ @@ -431,72 +745,160 @@
Iterator iterator1 = set.iterator(); Iterator iterator1 = set.iterator();
while (iterator1.hasNext()) { while (iterator1.hasNext()) {
@ -829,7 +836,7 @@
return entityplayer1; return entityplayer1;
} }
@@ -516,15 +910,32 @@ @@ -516,15 +918,32 @@
} }
public void sendPlayerPermissionLevel(ServerPlayer player) { public void sendPlayerPermissionLevel(ServerPlayer player) {
@ -864,11 +871,10 @@
this.sendAllPlayerInfoIn = 0; this.sendAllPlayerInfoIn = 0;
} }
@@ -540,6 +951,25 @@ @@ -541,6 +960,25 @@
}
} }
+
+ // CraftBukkit start - add a world/entity limited version + // CraftBukkit start - add a world/entity limited version
+ public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) { + public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) {
+ for (int i = 0; i < this.players.size(); ++i) { + for (int i = 0; i < this.players.size(); ++i) {
@ -887,10 +893,11 @@
+ +
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+
public void broadcastAll(Packet<?> packet, ResourceKey<Level> dimension) { public void broadcastAll(Packet<?> packet, ResourceKey<Level> dimension) {
Iterator iterator = this.players.iterator(); Iterator iterator = this.players.iterator();
@@ -554,7 +984,7 @@
@@ -554,7 +992,7 @@
} }
@ -899,7 +906,7 @@
PlayerTeam scoreboardteam = source.getTeam(); PlayerTeam scoreboardteam = source.getTeam();
if (scoreboardteam != null) { if (scoreboardteam != null) {
@@ -573,7 +1003,7 @@ @@ -573,7 +1011,7 @@
} }
} }
@ -908,7 +915,7 @@
PlayerTeam scoreboardteam = source.getTeam(); PlayerTeam scoreboardteam = source.getTeam();
if (scoreboardteam == null) { if (scoreboardteam == null) {
@@ -619,7 +1049,7 @@ @@ -619,7 +1057,7 @@
} }
public void deop(GameProfile profile) { public void deop(GameProfile profile) {
@ -917,7 +924,7 @@
ServerPlayer entityplayer = this.getPlayer(profile.getId()); ServerPlayer entityplayer = this.getPlayer(profile.getId());
if (entityplayer != null) { if (entityplayer != null) {
@@ -629,6 +1059,11 @@ @@ -629,6 +1067,11 @@
} }
private void sendPlayerPermissionLevel(ServerPlayer player, int permissionLevel) { private void sendPlayerPermissionLevel(ServerPlayer player, int permissionLevel) {
@ -929,7 +936,7 @@
if (player.connection != null) { if (player.connection != null) {
byte b0; byte b0;
@@ -643,35 +1078,52 @@ @@ -643,35 +1086,52 @@
player.connection.send(new ClientboundEntityEventPacket(player, b0)); player.connection.send(new ClientboundEntityEventPacket(player, b0));
} }
@ -995,7 +1002,7 @@
if (entityplayer != player && entityplayer.level().dimension() == worldKey) { if (entityplayer != player && entityplayer.level().dimension() == worldKey) {
double d4 = x - entityplayer.getX(); double d4 = x - entityplayer.getX();
@@ -687,10 +1139,12 @@ @@ -687,10 +1147,12 @@
} }
public void saveAll() { public void saveAll() {
@ -1008,7 +1015,7 @@
} }
public UserWhiteList getWhiteList() { public UserWhiteList getWhiteList() {
@@ -712,15 +1166,19 @@ @@ -712,15 +1174,19 @@
public void reloadWhiteList() {} public void reloadWhiteList() {}
public void sendLevelInfo(ServerPlayer player, ServerLevel world) { public void sendLevelInfo(ServerPlayer player, ServerLevel world) {
@ -1032,7 +1039,7 @@
} }
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
@@ -729,8 +1187,16 @@ @@ -729,8 +1195,16 @@
public void sendAllPlayerInfo(ServerPlayer player) { public void sendAllPlayerInfo(ServerPlayer player) {
player.inventoryMenu.sendAllDataToRemote(); player.inventoryMenu.sendAllDataToRemote();
@ -1050,7 +1057,7 @@
} }
public int getPlayerCount() { public int getPlayerCount() {
@@ -746,6 +1212,7 @@ @@ -746,6 +1220,7 @@
} }
public void setUsingWhiteList(boolean whitelistEnabled) { public void setUsingWhiteList(boolean whitelistEnabled) {
@ -1058,7 +1065,7 @@
this.doWhiteList = whitelistEnabled; this.doWhiteList = whitelistEnabled;
} }
@@ -786,12 +1253,36 @@ @@ -786,12 +1261,36 @@
} }
public void removeAll() { public void removeAll() {
@ -1097,7 +1104,7 @@
public void broadcastSystemMessage(Component message, boolean overlay) { public void broadcastSystemMessage(Component message, boolean overlay) {
this.broadcastSystemMessage(message, (entityplayer) -> { this.broadcastSystemMessage(message, (entityplayer) -> {
return message; return message;
@@ -819,24 +1310,43 @@ @@ -819,24 +1318,43 @@
} }
public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) { public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) {
@ -1144,7 +1151,7 @@
} }
if (flag1 && sender != null) { if (flag1 && sender != null) {
@@ -845,20 +1355,27 @@ @@ -845,20 +1363,27 @@
} }
@ -1177,7 +1184,7 @@
Path path = file2.toPath(); Path path = file2.toPath();
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
@@ -867,7 +1384,7 @@ @@ -867,7 +1392,7 @@
} }
serverstatisticmanager = new ServerStatsCounter(this.server, file1); serverstatisticmanager = new ServerStatsCounter(this.server, file1);
@ -1186,7 +1193,7 @@
} }
return serverstatisticmanager; return serverstatisticmanager;
@@ -875,13 +1392,13 @@ @@ -875,13 +1400,13 @@
public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) { public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) {
UUID uuid = player.getUUID(); UUID uuid = player.getUUID();
@ -1202,7 +1209,7 @@
} }
advancementdataplayer.setPlayer(player); advancementdataplayer.setPlayer(player);
@@ -932,15 +1449,39 @@ @@ -932,15 +1457,39 @@
} }
public void reloadResources() { public void reloadResources() {

View File

@ -206,6 +206,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private final ConversationTracker conversationTracker = new ConversationTracker(); private final ConversationTracker conversationTracker = new ConversationTracker();
private final Set<String> channels = new HashSet<String>(); private final Set<String> channels = new HashSet<String>();
private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new HashMap<>(); 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 static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
private int hash = 0; private int hash = 0;
private double health = 20; private double health = 20;
@ -2104,7 +2105,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
otherPlayer.setUUID(uuidOverride); otherPlayer.setUUID(uuidOverride);
} }
// Paper end // 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 if (original != null) otherPlayer.setUUID(original); // Paper - uuid override
} }
@ -2208,6 +2209,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 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 @Override
public Map<String, Object> serialize() { public Map<String, Object> serialize() {
Map<String, Object> result = new LinkedHashMap<String, Object>(); Map<String, Object> result = new LinkedHashMap<String, Object>();