chore: revert (mostly) ConnectionManager#getOnlinePlayers change

This commit is contained in:
mworzala 2023-12-24 13:12:16 -05:00 committed by Matt Worzala
parent 197daae608
commit 8859af87ba
13 changed files with 48 additions and 89 deletions

View File

@ -19,17 +19,14 @@ public class PlayersCommand extends Command {
} }
private void usage(CommandSender sender, CommandContext context) { private void usage(CommandSender sender, CommandContext context) {
final var players = List.copyOf(MinecraftServer.getConnectionManager().getPlayers()); final var players = List.copyOf(MinecraftServer.getConnectionManager().getOnlinePlayers());
final int playerCount = players.size(); final int playerCount = players.size();
sender.sendMessage(Component.text("Total players: " + playerCount)); sender.sendMessage(Component.text("Total players: " + playerCount));
final int limit = 15; final int limit = 15;
for (int i = 0; i < Math.min(limit, playerCount); i++) { for (int i = 0; i < Math.min(limit, playerCount); i++) {
final var player = players.get(i); final var player = players.get(i);
var msg = Component.text(player.getUsername()); sender.sendMessage(Component.text(player.getUsername()));
if (player.getPlayerConnection().getServerState() == ConnectionState.CONFIGURATION)
msg = msg.append(Component.text(" (config)"));
sender.sendMessage(msg);
} }
if (playerCount > limit) sender.sendMessage(Component.text("...")); if (playerCount > limit) sender.sendMessage(Component.text("..."));

View File

@ -26,7 +26,7 @@ public class TeleportCommand extends Command {
private void onPlayerTeleport(CommandSender sender, CommandContext context) { private void onPlayerTeleport(CommandSender sender, CommandContext context) {
final String playerName = context.get("player"); final String playerName = context.get("player");
Player pl = MinecraftServer.getConnectionManager().getPlayer(playerName); Player pl = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(playerName);
if (sender instanceof Player player) { if (sender instanceof Player player) {
player.teleport(pl.getPosition()); player.teleport(pl.getPosition());
} }

View File

@ -5,7 +5,6 @@ import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed; import net.kyori.adventure.key.Keyed;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.network.ConnectionState;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -42,7 +41,7 @@ public class Audiences {
* @return all audience members * @return all audience members
*/ */
public static @NotNull Audience all() { public static @NotNull Audience all() {
return Audience.audience(audience.server(), audience.customs()); return Audience.audience(audience.server, audience.customs());
} }
/** /**
@ -51,7 +50,7 @@ public class Audiences {
* @return all players * @return all players
*/ */
public static @NotNull Audience players() { public static @NotNull Audience players() {
return audience.players(); return audience.players;
} }
/** /**
@ -61,8 +60,7 @@ public class Audiences {
* @return all players matching the predicate * @return all players matching the predicate
*/ */
public static @NotNull Audience players(@NotNull Predicate<Player> filter) { public static @NotNull Audience players(@NotNull Predicate<Player> filter) {
return PacketGroupingAudience.of(MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY) return PacketGroupingAudience.of(MinecraftServer.getConnectionManager().getOnlinePlayers().stream().filter(filter).toList());
.stream().filter(filter).toList());
} }
/** /**
@ -80,7 +78,7 @@ public class Audiences {
* @return the audience of all players and the console * @return the audience of all players and the console
*/ */
public static @NotNull Audience server() { public static @NotNull Audience server() {
return audience.server(); return audience.server;
} }
/** /**

View File

@ -5,7 +5,6 @@ import net.kyori.adventure.key.Key;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.command.ConsoleSender; import net.minestom.server.command.ConsoleSender;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.network.ConnectionState;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,12 +35,12 @@ class IterableAudienceProvider implements AudienceProvider<Iterable<? extends Au
@Override @Override
public @NotNull Iterable<? extends Audience> players() { public @NotNull Iterable<? extends Audience> players() {
return MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY); return MinecraftServer.getConnectionManager().getOnlinePlayers();
} }
@Override @Override
public @NotNull Iterable<? extends Audience> players(@NotNull Predicate<Player> filter) { public @NotNull Iterable<? extends Audience> players(@NotNull Predicate<Player> filter) {
return MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY).stream().filter(filter).toList(); return MinecraftServer.getConnectionManager().getOnlinePlayers().stream().filter(filter).toList();
} }
@Override @Override

View File

@ -4,7 +4,6 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Key;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.network.ConnectionState;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -16,6 +15,8 @@ import java.util.function.Predicate;
class SingleAudienceProvider implements AudienceProvider<Audience> { class SingleAudienceProvider implements AudienceProvider<Audience> {
protected final IterableAudienceProvider collection = new IterableAudienceProvider(); protected final IterableAudienceProvider collection = new IterableAudienceProvider();
protected final Audience players = PacketGroupingAudience.of(MinecraftServer.getConnectionManager().getOnlinePlayers());
protected final Audience server = Audience.audience(this.players, MinecraftServer.getCommandManager().getConsoleSender());
protected SingleAudienceProvider() { protected SingleAudienceProvider() {
} }
@ -31,18 +32,17 @@ class SingleAudienceProvider implements AudienceProvider<Audience> {
@Override @Override
public @NotNull Audience all() { public @NotNull Audience all() {
return Audience.audience(this.server(), this.customs()); return Audience.audience(this.server, this.customs());
} }
@Override @Override
public @NotNull Audience players() { public @NotNull Audience players() {
return PacketGroupingAudience.of(MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY)); return this.players;
} }
@Override @Override
public @NotNull Audience players(@NotNull Predicate<Player> filter) { public @NotNull Audience players(@NotNull Predicate<Player> filter) {
return PacketGroupingAudience.of(MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY) return PacketGroupingAudience.of(MinecraftServer.getConnectionManager().getOnlinePlayers().stream().filter(filter).toList());
.stream().filter(filter).toList());
} }
@Override @Override
@ -52,7 +52,7 @@ class SingleAudienceProvider implements AudienceProvider<Audience> {
@Override @Override
public @NotNull Audience server() { public @NotNull Audience server() {
return Audience.audience(players(), MinecraftServer.getCommandManager().getConsoleSender()); return this.server;
} }
@Override @Override

View File

@ -303,7 +303,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
PacketUtils.broadcastPlayPacket(getAddPlayerToList()); PacketUtils.broadcastPlayPacket(getAddPlayerToList());
var connectionManager = MinecraftServer.getConnectionManager(); var connectionManager = MinecraftServer.getConnectionManager();
for (var player : connectionManager.getPlayers(ConnectionState.PLAY)) { for (var player : connectionManager.getOnlinePlayers()) {
if (player != this) { if (player != this) {
sendPacket(player.getAddPlayerToList()); sendPacket(player.getAddPlayerToList());
if (player.displayName != null) { if (player.displayName != null) {

View File

@ -33,7 +33,7 @@ public class FullQueryResponse implements Writeable {
this.kv.put(key.getKey(), key.getValue()); this.kv.put(key.getKey(), key.getValue());
} }
this.players = MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY) this.players = MinecraftServer.getConnectionManager().getOnlinePlayers()
.stream() .stream()
.map(player -> PLAIN.serialize(player.getName())) .map(player -> PLAIN.serialize(player.getName()))
.toList(); .toList();

View File

@ -39,7 +39,7 @@ public class ChatMessageListener {
return; return;
} }
final Collection<Player> players = CONNECTION_MANAGER.getPlayers(ConnectionState.PLAY); final Collection<Player> players = CONNECTION_MANAGER.getOnlinePlayers();
PlayerChatEvent playerChatEvent = new PlayerChatEvent(player, players, () -> buildDefaultChatMessage(player, message), message); PlayerChatEvent playerChatEvent = new PlayerChatEvent(player, players, () -> buildDefaultChatMessage(player, message), message);
// Call the event // Call the event

View File

@ -7,21 +7,16 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.extras.MojangAuth; import net.minestom.server.extras.MojangAuth;
import net.minestom.server.extras.bungee.BungeeCordProxy; import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.extras.mojangAuth.MojangCrypt;
import net.minestom.server.extras.velocity.VelocityProxy; import net.minestom.server.extras.velocity.VelocityProxy;
import net.minestom.server.message.Messenger;
import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.client.login.ClientEncryptionResponsePacket; import net.minestom.server.network.packet.client.login.ClientEncryptionResponsePacket;
import net.minestom.server.network.packet.client.login.ClientLoginAcknowledgedPacket; import net.minestom.server.network.packet.client.login.ClientLoginAcknowledgedPacket;
import net.minestom.server.network.packet.client.login.ClientLoginPluginResponsePacket; import net.minestom.server.network.packet.client.login.ClientLoginPluginResponsePacket;
import net.minestom.server.network.packet.client.login.ClientLoginStartPacket; import net.minestom.server.network.packet.client.login.ClientLoginStartPacket;
import net.minestom.server.network.packet.server.common.PluginMessagePacket;
import net.minestom.server.network.packet.server.common.TagsPacket;
import net.minestom.server.network.packet.server.configuration.RegistryDataPacket;
import net.minestom.server.network.packet.server.login.EncryptionRequestPacket; import net.minestom.server.network.packet.server.login.EncryptionRequestPacket;
import net.minestom.server.network.packet.server.login.LoginDisconnectPacket; import net.minestom.server.network.packet.server.login.LoginDisconnectPacket;
import net.minestom.server.network.packet.server.login.LoginPluginRequestPacket; import net.minestom.server.network.packet.server.login.LoginPluginRequestPacket;
@ -30,7 +25,6 @@ import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.network.player.PlayerSocketConnection; import net.minestom.server.network.player.PlayerSocketConnection;
import net.minestom.server.utils.async.AsyncUtils; import net.minestom.server.utils.async.AsyncUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBT;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import java.math.BigInteger; import java.math.BigInteger;
@ -71,7 +65,7 @@ public final class LoginListener {
if (MojangAuth.isEnabled() && isSocketConnection) { if (MojangAuth.isEnabled() && isSocketConnection) {
// Mojang auth // Mojang auth
if (CONNECTION_MANAGER.getPlayer(packet.username()) != null) { if (CONNECTION_MANAGER.getOnlinePlayerByUsername(packet.username()) != null) {
connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED)); connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED));
connection.disconnect(); connection.disconnect();
return; return;

View File

@ -59,6 +59,9 @@ public final class ConnectionManager {
// Players in play state // Players in play state
private final Set<Player> playPlayers = new CopyOnWriteArraySet<>(); private final Set<Player> playPlayers = new CopyOnWriteArraySet<>();
private final Set<Player> unmodifiableConfigurationPlayers = Collections.unmodifiableSet(configurationPlayers);
private final Set<Player> unmodifiablePlayPlayers = Collections.unmodifiableSet(playPlayers);
// The uuid provider once a player login // The uuid provider once a player login
private volatile UuidProvider uuidProvider = (playerConnection, username) -> UUID.randomUUID(); private volatile UuidProvider uuidProvider = (playerConnection, username) -> UUID.randomUUID();
@ -75,41 +78,25 @@ public final class ConnectionManager {
} }
/** /**
* Gets players filtered by state. * Returns an unmodifiable set containing the players currently in the play state.
*
* <p>The returned collection has no defined update behavior relative to the state of the server,
* so it should be refetched whenever used, rather than kept and reused.</p>
*
* @param states The state(s) to return players, if empty all players (play and config) are returned.
* <b>Only</b> {@link ConnectionState#CONFIGURATION} and {@link ConnectionState#PLAY} are valid.
*
* @return An unmodifiable collection containing the filtered players.
*/ */
public @NotNull Collection<@NotNull Player> getPlayers(@NotNull ConnectionState... states) { public @NotNull Collection<@NotNull Player> getOnlinePlayers() {
boolean play = false, config = false; return unmodifiablePlayPlayers;
for (var state : states) { }
switch (state) {
case PLAY -> play = true;
case CONFIGURATION -> config = true;
default -> throw new IllegalArgumentException("Cannot fetch players in " + state + "!");
}
}
if (config && !play) { // Only play /**
return Collections.unmodifiableCollection(configurationPlayers); * Returns an unmodifiable set containing the players currently in the configuration state.
} else if (!config && play) { // Only configuration */
return Collections.unmodifiableCollection(playPlayers); public @NotNull Collection<@NotNull Player> getConfigPlayers() {
} else { // Both or neither was specified return unmodifiableConfigurationPlayers;
final var players = new ArrayList<Player>(playPlayers.size() + configurationPlayers.size());
players.addAll(configurationPlayers);
players.addAll(playPlayers);
return Collections.unmodifiableCollection(players);
}
} }
/** /**
* Gets the {@link Player} linked to a {@link PlayerConnection}. * Gets the {@link Player} linked to a {@link PlayerConnection}.
* *
* <p>The player will be returned whether they are in the play or config state,
* so be sure to check before sending packets to them.</p>
*
* @param connection the player connection * @param connection the player connection
* @return the player linked to the connection * @return the player linked to the connection
*/ */
@ -118,17 +105,15 @@ public final class ConnectionManager {
} }
/** /**
* Gets the first player which validate {@link String#equalsIgnoreCase(String)}. * Gets the first player in the play state which validates {@link String#equalsIgnoreCase(String)}.
* <p> * <p>
* This can cause issue if two or more players have the same username. * This can cause issue if two or more players have the same username.
* *
* @param username the player username (case-insensitive) * @param username the player username (case-insensitive)
* @param states The state(s) to return players, if empty all players (play and config) are returned.
* <b>Only</b> {@link ConnectionState#CONFIGURATION} and {@link ConnectionState#PLAY} are valid.
* @return the first player who validate the username condition, null if none was found * @return the first player who validate the username condition, null if none was found
*/ */
public @Nullable Player getPlayer(@NotNull String username, @NotNull ConnectionState... states) { public @Nullable Player getOnlinePlayerByUsername(@NotNull String username) {
for (Player player : getPlayers(states)) { for (Player player : getOnlinePlayers()) {
if (player.getUsername().equalsIgnoreCase(username)) if (player.getUsername().equalsIgnoreCase(username))
return player; return player;
} }
@ -136,17 +121,15 @@ public final class ConnectionManager {
} }
/** /**
* Gets the first player which validate {@link UUID#equals(Object)}. * Gets the first player in the play state which validates {@link UUID#equals(Object)}.
* <p> * <p>
* This can cause issue if two or more players have the same UUID. * This can cause issue if two or more players have the same UUID.
* *
* @param uuid the player UUID * @param uuid the player UUID
* @param states The state(s) to return players, if empty all players (play and config) are returned.
* <b>Only</b> {@link ConnectionState#CONFIGURATION} and {@link ConnectionState#PLAY} are valid.
* @return the first player who validate the UUID condition, null if none was found * @return the first player who validate the UUID condition, null if none was found
*/ */
public @Nullable Player getPlayer(@NotNull UUID uuid, @NotNull ConnectionState... states) { public @Nullable Player getOnlinePlayerByUuid(@NotNull UUID uuid) {
for (Player player : getPlayers(states)) { for (Player player : getOnlinePlayers()) {
if (player.getUuid().equals(uuid)) if (player.getUuid().equals(uuid))
return player; return player;
} }
@ -154,15 +137,13 @@ public final class ConnectionManager {
} }
/** /**
* Finds the closest player matching a given username. * Finds the closest player in the play state matching a given username.
* *
* @param username the player username (can be partial) * @param username the player username (can be partial)
* @param states The state(s) to return players, if empty all players (play and config) are returned.
* <b>Only</b> {@link ConnectionState#CONFIGURATION} and {@link ConnectionState#PLAY} are valid.
* @return the closest match, null if no players are online * @return the closest match, null if no players are online
*/ */
public @Nullable Player findPlayer(@NotNull String username, @NotNull ConnectionState... states) { public @Nullable Player findOnlinePlayer(@NotNull String username) {
Player exact = getPlayer(username); Player exact = getOnlinePlayerByUsername(username);
if (exact != null) return exact; if (exact != null) return exact;
final String username1 = username.toLowerCase(Locale.ROOT); final String username1 = username.toLowerCase(Locale.ROOT);
@ -170,7 +151,7 @@ public final class ConnectionManager {
final String username2 = player.getUsername().toLowerCase(Locale.ROOT); final String username2 = player.getUsername().toLowerCase(Locale.ROOT);
return StringUtils.jaroWinklerScore(username1, username2); return StringUtils.jaroWinklerScore(username1, username2);
}; };
return getPlayers(states).stream() return getOnlinePlayers().stream()
.min(Comparator.comparingDouble(distanceFunction::apply)) .min(Comparator.comparingDouble(distanceFunction::apply))
.filter(player -> distanceFunction.apply(player) > 0) .filter(player -> distanceFunction.apply(player) > 0)
.orElse(null); .orElse(null);
@ -214,16 +195,6 @@ public final class ConnectionManager {
this.playerProvider = playerProvider != null ? playerProvider : Player::new; this.playerProvider = playerProvider != null ? playerProvider : Player::new;
} }
/**
* Retrieves the current {@link PlayerProvider}, can be the default one if none is defined.
*
* @return the current {@link PlayerProvider}
*/
public @NotNull PlayerProvider getPlayerProvider() {
return playerProvider;
}
/** /**
* Creates a player object and begins the transition from the login state to the config state. * Creates a player object and begins the transition from the login state to the config state.
*/ */

View File

@ -472,7 +472,7 @@ public class Team implements PacketGroupingAudience {
this.playerMembers.clear(); this.playerMembers.clear();
for (String member : this.members) { for (String member : this.members) {
Player player = MinecraftServer.getConnectionManager().getPlayer(member); Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(member);
if (player != null) { if (player != null) {
this.playerMembers.add(player); this.playerMembers.add(player);

View File

@ -154,7 +154,7 @@ public final class PacketUtils {
} }
public static void broadcastPlayPacket(@NotNull ServerPacket packet) { public static void broadcastPlayPacket(@NotNull ServerPacket packet) {
sendGroupedPacket(MinecraftServer.getConnectionManager().getPlayers(ConnectionState.PLAY), packet); sendGroupedPacket(MinecraftServer.getConnectionManager().getOnlinePlayers(), packet);
} }
@ApiStatus.Experimental @ApiStatus.Experimental

View File

@ -131,7 +131,7 @@ public class EntityFinder {
public @NotNull List<@NotNull Entity> find(@Nullable Instance instance, @Nullable Entity self) { public @NotNull List<@NotNull Entity> find(@Nullable Instance instance, @Nullable Entity self) {
if (targetSelector == TargetSelector.MINESTOM_USERNAME) { if (targetSelector == TargetSelector.MINESTOM_USERNAME) {
Check.notNull(constantName, "The player name should not be null when searching for it"); Check.notNull(constantName, "The player name should not be null when searching for it");
final Player player = MinecraftServer.getConnectionManager().getPlayer(constantName); final Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(constantName);
return player != null ? List.of(player) : List.of(); return player != null ? List.of(player) : List.of();
} else if (targetSelector == TargetSelector.MINESTOM_UUID) { } else if (targetSelector == TargetSelector.MINESTOM_UUID) {
Check.notNull(constantUuid, "The UUID should not be null when searching for it"); Check.notNull(constantUuid, "The UUID should not be null when searching for it");
@ -310,7 +310,7 @@ public class EntityFinder {
private static @NotNull List<@NotNull Entity> findTarget(@Nullable Instance instance, private static @NotNull List<@NotNull Entity> findTarget(@Nullable Instance instance,
@NotNull TargetSelector targetSelector, @NotNull TargetSelector targetSelector,
@NotNull Point startPosition, @Nullable Entity self) { @NotNull Point startPosition, @Nullable Entity self) {
final var players = instance != null ? instance.getPlayers() : CONNECTION_MANAGER.getPlayers(ConnectionState.PLAY); final var players = instance != null ? instance.getPlayers() : CONNECTION_MANAGER.getOnlinePlayers();
if (targetSelector == TargetSelector.NEAREST_PLAYER) { if (targetSelector == TargetSelector.NEAREST_PLAYER) {
return players.stream() return players.stream()
.min(Comparator.comparingDouble(p -> p.getPosition().distanceSquared(startPosition))) .min(Comparator.comparingDouble(p -> p.getPosition().distanceSquared(startPosition)))