Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import net.tfminecraft.geigercounters.config.GeigerConfiguration;
import net.tfminecraft.geigercounters.config.Messages;
import net.tfminecraft.geigercounters.managers.GeigerManager;
Expand All @@ -17,21 +20,37 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

// ====================================
// Admin command handler:
// /geiger <locate [player]|move <player> [x z]|limits <player>|resetlimits <player>|droplist [name]|reload>
// ====================================
public class GeigerCommand implements CommandExecutor, TabCompleter {
public class GeigerCommand implements CommandExecutor, TabCompleter, Listener {

private static final List<String> SUBCOMMANDS = Arrays.asList("locate", "move", "limits", "resetlimits", "droplist", "reload");

private final GeigerManager manager;
private final Map<UUID, String> knownNames = new LinkedHashMap<>();

public GeigerCommand(GeigerManager manager) {
public GeigerCommand(GeigerManager manager, OfflinePlayer[] knownPlayers) {
this.manager = manager;
for (OfflinePlayer player : knownPlayers) {
if (player.getName() != null && player.hasPlayedBefore()) {
knownNames.put(player.getUniqueId(), player.getName());
}
}
}

@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
knownNames.put(player.getUniqueId(), player.getName());
}

// Fetched per use rather than cached - /geiger reload swaps the file
Expand Down Expand Up @@ -322,6 +341,7 @@ private static boolean takesPlayer(String argument) {

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 0) return List.of();
if (args.length == 1) {
List<String> matches = new ArrayList<>();
for (String sub : SUBCOMMANDS) {
Expand Down Expand Up @@ -350,13 +370,17 @@ public List<String> onTabComplete(CommandSender sender, Command command, String

// locate, move and both limit subcommands (either spelling) take a player name
if (args.length == 2 && takesPlayer(args[0])) {
List<String> matches = new ArrayList<>();
Map<UUID, String> names = new LinkedHashMap<>();
if (args[0].equalsIgnoreCase("limit") || args[0].equalsIgnoreCase("limits")
|| args[0].equalsIgnoreCase("resetlimit") || args[0].equalsIgnoreCase("resetlimits")) {
names.putAll(knownNames);
}
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getName().toLowerCase().startsWith(args[1].toLowerCase())) {
matches.add(player.getName());
}
names.put(player.getUniqueId(), player.getName());
}
return matches;
return new LinkedHashSet<>(names.values()).stream()
.filter(name -> name.toLowerCase(Locale.ROOT).startsWith(args[1].toLowerCase(Locale.ROOT)))
.toList();
}

return new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ public void onEnable() {

GeigerManager.getInstance(this).initialize();

GeigerCommand geigerCommand = new GeigerCommand(GeigerManager.getInstance());
GeigerCommand geigerCommand = new GeigerCommand(GeigerManager.getInstance(), getServer().getOfflinePlayers());
getCommand("geiger").setExecutor(geigerCommand);
getCommand("geiger").setTabCompleter(geigerCommand);
getServer().getPluginManager().registerEvents(geigerCommand, this);

setupMetrics();

Expand Down Expand Up @@ -81,4 +82,4 @@ private static String bucketDistance(double distance) {
return "5000+";
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ void pluginLifecycleRegistersCommandsMetricsAndShutsDownResources() throws Excep
bukkit.when(Bukkit::getUnsafe).thenReturn(mock(UnsafeValues.class));
assertNotNull(new TestPluginLoader().definePluginSubclass().getConstructor().newInstance());
geiger_counter plugin = mock(geiger_counter.class, CALLS_REAL_METHODS);
Server server = mock(Server.class);
var pluginManager = mock(org.bukkit.plugin.PluginManager.class);
doReturn(server).when(plugin).getServer();
when(server.getOfflinePlayers()).thenReturn(new OfflinePlayer[0]);
when(server.getPluginManager()).thenReturn(pluginManager);
doReturn(Logger.getAnonymousLogger()).when(plugin).getLogger();
doNothing().when(plugin).saveDefaultConfig();
PluginCommand command = mock(PluginCommand.class);
Expand All @@ -61,6 +66,7 @@ void pluginLifecycleRegistersCommandsMetricsAndShutsDownResources() throws Excep
verify(manager).initialize();
verify(command).setExecutor(any());
verify(command).setTabCompleter(any());
verify(pluginManager).registerEvents(any(net.tfminecraft.geigercounters.commands.GeigerCommand.class), eq(plugin));
Metrics created = metrics.constructed().getFirst();
ArgumentCaptor<CustomChart> charts = ArgumentCaptor.forClass(CustomChart.class);
verify(created, times(4)).addCustomChart(charts.capture());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void setUp() {
when(config.isLimitEnabled()).thenReturn(true);
when(plugin.getConfig()).thenReturn(new YamlConfiguration());
when(world.getName()).thenReturn("world");
command = new GeigerCommand(manager);
command = new GeigerCommand(manager, new OfflinePlayer[0]);
}

void run(String... args) {
Expand Down Expand Up @@ -265,12 +265,54 @@ void coordinateCompletionFloorsNegativeNumbersDeduplicatesAndUsesCorrectAxis() {
void playerArgumentsCompleteOnlinePlayerNamesCaseInsensitively() {
Player first = mock(Player.class), second = mock(Player.class);
when(first.getName()).thenReturn("Hunter");
when(first.getUniqueId()).thenReturn(UUID.randomUUID());
when(second.getName()).thenReturn("Other");
when(second.getUniqueId()).thenReturn(UUID.randomUUID());
try (var bukkit = mockStatic(Bukkit.class)) {
bukkit.when(Bukkit::getOnlinePlayers).thenReturn(List.of(first, second));
for (String alias : List.of("locate", "move", "limit", "limits", "resetlimit", "resetlimits")) {
assertEquals(List.of("Hunter"), complete(sender, alias, "HU"));
}
}
}

@Test
void limitCompletionUsesKnownOfflineNamesAndJoinUpdatesWithoutProfileLookups() {
UUID knownId = UUID.randomUUID();
OfflinePlayer known = mock(OfflinePlayer.class), unnamed = mock(OfflinePlayer.class),
unknown = mock(OfflinePlayer.class);
when(known.getUniqueId()).thenReturn(knownId);
when(known.getName()).thenReturn("OldName");
when(known.hasPlayedBefore()).thenReturn(true);
when(unknown.getName()).thenReturn("NeverPlayed");
command = new GeigerCommand(manager, new OfflinePlayer[] {known, unnamed, unknown});
Player joined = mock(Player.class), online = mock(Player.class);
when(joined.getUniqueId()).thenReturn(knownId);
when(joined.getName()).thenReturn("RenamedHunter");
when(online.getUniqueId()).thenReturn(UUID.randomUUID());
when(online.getName()).thenReturn("Online");
var join = mock(org.bukkit.event.player.PlayerJoinEvent.class);
when(join.getPlayer()).thenReturn(joined);
try (var bukkit = mockStatic(Bukkit.class)) {
bukkit.when(Bukkit::getOnlinePlayers).thenReturn(List.of(online));
for (String action : List.of("limit", "limits", "resetlimit", "resetlimits")) {
assertEquals(List.of("OldName", "Online"), complete(sender, action, ""));
assertEquals(List.of("OldName"), complete(sender, action.toUpperCase(java.util.Locale.ROOT), "oLD"));
assertTrue(complete(sender, action, "absent").isEmpty());
assertTrue(complete(sender, action, "OldName", "").isEmpty());
}
for (String action : List.of("locate", "move")) {
assertEquals(List.of("Online"), complete(sender, action, ""));
assertTrue(complete(sender, action, "Old").isEmpty());
}
command.onJoin(join);
assertEquals(List.of("RenamedHunter"), complete(sender, "limits", "rEN"));
assertTrue(complete(sender, "resetlimits", "Old").isEmpty());
bukkit.when(Bukkit::getOnlinePlayers).thenReturn(List.of(joined, online));
assertEquals(List.of("RenamedHunter", "Online"), complete(sender, "limits", ""));
assertTrue(complete(sender).isEmpty());
bukkit.verify(Bukkit::getOfflinePlayers, never());
bukkit.verify(() -> Bukkit.getOfflinePlayer(anyString()), never());
}
}
}
Loading