From e3bea9ee77ac84d6178050026dcb4e8668dc7574 Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Tue, 22 Nov 2022 13:25:12 +0200 Subject: [PATCH] Add online player names to player tab completion Affects issues: - Close #2216 --- .../plan/gathering/BukkitSensor.java | 11 ++++ .../plan/gathering/BungeeSensor.java | 12 ++++ .../plan/commands/TabCompleteCache.java | 66 +++++++++++-------- .../plan/gathering/ServerSensor.java | 5 ++ .../plan/gathering/FabricSensor.java | 7 ++ .../plan/gathering/NukkitSensor.java | 11 ++++ .../plan/gathering/SpongeSensor.java | 8 +++ .../plan/gathering/VelocitySensor.java | 12 ++++ 8 files changed, 106 insertions(+), 26 deletions(-) diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java index 313947b1b..95a5c5e12 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java @@ -16,11 +16,15 @@ */ package com.djrapitops.plan.gathering; +import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.World; +import org.bukkit.entity.Player; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.List; +import java.util.stream.Collectors; @Singleton public class BukkitSensor implements ServerSensor { @@ -118,4 +122,11 @@ public class BukkitSensor implements ServerSensor { return false; } } + + @Override + public List getOnlinePlayerNames() { + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .collect(Collectors.toList()); + } } diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java index b9a276884..b446d6248 100644 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java @@ -19,19 +19,26 @@ package com.djrapitops.plan.gathering; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.identification.properties.RedisCheck; import com.djrapitops.plan.identification.properties.RedisPlayersOnlineSupplier; +import net.md_5.bungee.api.connection.ProxiedPlayer; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Collection; +import java.util.List; import java.util.function.IntSupplier; +import java.util.function.Supplier; +import java.util.stream.Collectors; @Singleton public class BungeeSensor implements ServerSensor { private final IntSupplier onlinePlayerCountSupplier; private final IntSupplier onlinePlayerCountBungee; + private final Supplier> getPlayers; @Inject public BungeeSensor(PlanBungee plugin) { + getPlayers = plugin.getProxy()::getPlayers; onlinePlayerCountBungee = plugin.getProxy()::getOnlineCount; onlinePlayerCountSupplier = RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : onlinePlayerCountBungee; } @@ -46,4 +53,9 @@ public class BungeeSensor implements ServerSensor { int count = onlinePlayerCountSupplier.getAsInt(); return count != -1 ? count : onlinePlayerCountBungee.getAsInt(); } + + @Override + public List getOnlinePlayerNames() { + return getPlayers.get().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()); + } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/TabCompleteCache.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/TabCompleteCache.java index 0be2ba566..8b4fb5979 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/TabCompleteCache.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/TabCompleteCache.java @@ -18,6 +18,7 @@ package com.djrapitops.plan.commands; import com.djrapitops.plan.SubSystem; import com.djrapitops.plan.delivery.domain.auth.User; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.identification.ServerUUID; import com.djrapitops.plan.processing.Processing; @@ -43,25 +44,28 @@ public class TabCompleteCache implements SubSystem { private final Processing processing; private final PlanFiles files; private final DBSystem dbSystem; + private final ServerSensor serverSensor; - private final List playerIdentifiers; - private final List serverIdentifiers; - private final List userIdentifiers; - private final List backupFileNames; + private final Set playerIdentifiers; + private final Set serverIdentifiers; + private final Set userIdentifiers; + private final Set backupFileNames; @Inject public TabCompleteCache( Processing processing, PlanFiles files, - DBSystem dbSystem + DBSystem dbSystem, + ServerSensor serverSensor ) { this.processing = processing; this.files = files; this.dbSystem = dbSystem; - playerIdentifiers = new ArrayList<>(); - serverIdentifiers = new ArrayList<>(); - userIdentifiers = new ArrayList<>(); - backupFileNames = new ArrayList<>(); + this.serverSensor = serverSensor; + playerIdentifiers = new HashSet<>(); + serverIdentifiers = new HashSet<>(); + userIdentifiers = new HashSet<>(); + backupFileNames = new HashSet<>(); } @Override @@ -71,11 +75,6 @@ public class TabCompleteCache implements SubSystem { refreshServerIdentifiers(); refreshUserIdentifiers(); refreshBackupFileNames(); - - Collections.sort(playerIdentifiers); - Collections.sort(serverIdentifiers); - Collections.sort(userIdentifiers); - Collections.sort(backupFileNames); }); } @@ -115,30 +114,45 @@ public class TabCompleteCache implements SubSystem { } public List getMatchingServerIdentifiers(String searchFor) { - if (searchFor == null || searchFor.isEmpty()) { - return serverIdentifiers.size() < 100 ? serverIdentifiers : Collections.emptyList(); + if (serverIdentifiers.size() >= 100) { + return Collections.emptyList(); } - return serverIdentifiers.stream().filter(identifier -> identifier.startsWith(searchFor)).collect(Collectors.toList()); + return serverIdentifiers.stream() + .filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor)) + .sorted(String.CASE_INSENSITIVE_ORDER) + .collect(Collectors.toList()); } public List getMatchingPlayerIdentifiers(String searchFor) { - if (searchFor == null || searchFor.isEmpty()) { - return playerIdentifiers.size() < 100 ? playerIdentifiers : Collections.emptyList(); + if (playerIdentifiers.size() >= 100) { + return Collections.emptyList(); } - return playerIdentifiers.stream().filter(identifier -> identifier.startsWith(searchFor)).collect(Collectors.toList()); + + playerIdentifiers.addAll(serverSensor.getOnlinePlayerNames()); + + return playerIdentifiers.stream() + .filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor)) + .sorted(String.CASE_INSENSITIVE_ORDER) + .collect(Collectors.toList()); } public List getMatchingUserIdentifiers(String searchFor) { - if (searchFor == null || searchFor.isEmpty()) { - return userIdentifiers.size() < 100 ? userIdentifiers : Collections.emptyList(); + if (userIdentifiers.size() >= 100) { + return Collections.emptyList(); } - return userIdentifiers.stream().filter(identifier -> identifier.startsWith(searchFor)).collect(Collectors.toList()); + return userIdentifiers.stream() + .filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor)) + .sorted(String.CASE_INSENSITIVE_ORDER) + .collect(Collectors.toList()); } public List getMatchingBackupFilenames(String searchFor) { - if (searchFor == null || searchFor.isEmpty()) { - return backupFileNames.size() < 100 ? backupFileNames : Collections.emptyList(); + if (backupFileNames.size() >= 100) { + return Collections.emptyList(); } - return backupFileNames.stream().filter(identifier -> identifier.startsWith(searchFor)).collect(Collectors.toList()); + return backupFileNames.stream() + .filter(identifier -> searchFor == null || searchFor.isEmpty() || identifier.startsWith(searchFor)) + .sorted(String.CASE_INSENSITIVE_ORDER) + .collect(Collectors.toList()); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java index 59c696553..8c1817196 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java @@ -17,6 +17,7 @@ package com.djrapitops.plan.gathering; import java.util.Collections; +import java.util.List; /** * Allows sensing values from different server platforms. @@ -55,4 +56,8 @@ public interface ServerSensor { default int getEntityCount(W world) { return -1; } + + default List getOnlinePlayerNames() { + return Collections.emptyList(); + } } diff --git a/Plan/fabric/src/main/java/net/playeranalytics/plan/gathering/FabricSensor.java b/Plan/fabric/src/main/java/net/playeranalytics/plan/gathering/FabricSensor.java index dba5b9020..6e15bc586 100644 --- a/Plan/fabric/src/main/java/net/playeranalytics/plan/gathering/FabricSensor.java +++ b/Plan/fabric/src/main/java/net/playeranalytics/plan/gathering/FabricSensor.java @@ -23,6 +23,8 @@ import net.minecraft.server.world.ServerWorld; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeUnit; @Singleton @@ -82,4 +84,9 @@ public class FabricSensor implements ServerSensor { public int getOnlinePlayerCount() { return server.getCurrentPlayerCount(); } + + @Override + public List getOnlinePlayerNames() { + return Arrays.asList(server.getPlayerNames()); + } } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java index 8a9cca8a0..e395e3956 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java @@ -16,11 +16,14 @@ */ package com.djrapitops.plan.gathering; +import cn.nukkit.Player; import cn.nukkit.level.Level; import com.djrapitops.plan.PlanNukkit; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.List; +import java.util.stream.Collectors; @Singleton public class NukkitSensor implements ServerSensor { @@ -63,4 +66,12 @@ public class NukkitSensor implements ServerSensor { public Iterable getWorlds() { return plugin.getServer().getLevels().values(); } + + @Override + public List getOnlinePlayerNames() { + return plugin.getServer().getOnlinePlayers() + .values().stream() + .map(Player::getName) + .collect(Collectors.toList()); + } } diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java index 1b68f2692..6b33c3f6c 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java @@ -17,12 +17,15 @@ package com.djrapitops.plan.gathering; import org.spongepowered.api.Game; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.api.world.chunk.WorldChunk; import org.spongepowered.api.world.server.ServerWorld; import javax.inject.Inject; import javax.inject.Singleton; import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; @Singleton public class SpongeSensor implements ServerSensor { @@ -73,4 +76,9 @@ public class SpongeSensor implements ServerSensor { public int getEntityCount(ServerWorld world) { return world.entities().size(); } + + @Override + public List getOnlinePlayerNames() { + return game.server().onlinePlayers().stream().map(ServerPlayer::name).collect(Collectors.toList()); + } } diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java index e40972dd5..5e9b2f67c 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java @@ -19,18 +19,25 @@ package com.djrapitops.plan.gathering; import com.djrapitops.plan.PlanVelocity; import com.djrapitops.plan.identification.properties.VelocityRedisCheck; import com.djrapitops.plan.identification.properties.VelocityRedisPlayersOnlineSupplier; +import com.velocitypowered.api.proxy.Player; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Collection; +import java.util.List; import java.util.function.IntSupplier; +import java.util.function.Supplier; +import java.util.stream.Collectors; @Singleton public class VelocitySensor implements ServerSensor { private final IntSupplier onlinePlayerCountSupplier; + private final Supplier> getPlayers; @Inject public VelocitySensor(PlanVelocity plugin) { + getPlayers = plugin.getProxy()::getAllPlayers; onlinePlayerCountSupplier = VelocityRedisCheck.isClassAvailable() ? new VelocityRedisPlayersOnlineSupplier() : plugin.getProxy()::getPlayerCount; @@ -45,4 +52,9 @@ public class VelocitySensor implements ServerSensor { public int getOnlinePlayerCount() { return onlinePlayerCountSupplier.getAsInt(); } + + @Override + public List getOnlinePlayerNames() { + return getPlayers.get().stream().map(Player::getUsername).collect(Collectors.toList()); + } }