diff --git a/src/main/java/org/mvplugins/multiverse/core/commands/WhoCommand.java b/src/main/java/org/mvplugins/multiverse/core/commands/WhoCommand.java new file mode 100644 index 00000000..13e80c72 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/core/commands/WhoCommand.java @@ -0,0 +1,162 @@ +package org.mvplugins.multiverse.core.commands; + +import co.aikar.commands.InvalidCommandArgument; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandCompletion; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Optional; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; +import com.dumptruckman.minecraft.util.Logging; +import jakarta.inject.Inject; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.commandtools.MultiverseCommand; +import org.mvplugins.multiverse.core.commandtools.MVCommandIssuer; +import org.mvplugins.multiverse.core.commandtools.MVCommandManager; +import org.mvplugins.multiverse.core.commandtools.flags.CommandValueFlag; +import org.mvplugins.multiverse.core.commandtools.flags.ParsedCommandFlags; +import org.mvplugins.multiverse.core.display.ContentDisplay; +import org.mvplugins.multiverse.core.display.filters.ContentFilter; +import org.mvplugins.multiverse.core.display.filters.DefaultContentFilter; +import org.mvplugins.multiverse.core.display.filters.RegexContentFilter; +import org.mvplugins.multiverse.core.display.handlers.PagedSendHandler; +import org.mvplugins.multiverse.core.display.parsers.MapContentProvider; +import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld; +import org.mvplugins.multiverse.core.world.WorldManager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@CommandAlias("mv") +public class WhoCommand extends MultiverseCommand { + + private final WorldManager worldManager; + + private final CommandValueFlag PAGE_FLAG = flag(CommandValueFlag + .builder("--page", Integer.class) + .addAlias("-p") + .context(value -> { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + throw new InvalidCommandArgument("Invalid page number: " + value); + } + }) + .build()); + + private final CommandValueFlag FILTER_FLAG = flag(CommandValueFlag + .builder("--filter", ContentFilter.class) + .addAlias("-f") + .context(value -> { + try { + return RegexContentFilter.fromString(value); + } catch (IllegalArgumentException e) { + throw new InvalidCommandArgument("Invalid filter: " + value); + } + }) + .build()); + + @Inject + WhoCommand(@NotNull MVCommandManager commandManager, @NotNull WorldManager worldManager) { + super(commandManager); + this.worldManager = worldManager; + } + + @Subcommand("whoall") + @CommandPermission("multiverse.core.list.who.all") + @CommandCompletion("@flags:groupName=mvwhocommand") + @Syntax("[--page ] [--filter ]") + @Description("{@@mv-core.who.all.description}") + void onWhoAllCommand( + MVCommandIssuer issuer, + + @Optional + @Syntax("[--page ] [--filter ]") + @Description("{@@mv-core.who.flags.description}") + String[] flags) { + ParsedCommandFlags parsedFlags = parseFlags(flags); + + // Send the display + getListDisplay( + worldManager.getLoadedWorlds(), + parsedFlags.flagValue(PAGE_FLAG, 1), + parsedFlags.flagValue(FILTER_FLAG, DefaultContentFilter.get()), + true + ).send(issuer); + + } + + @Subcommand("who") + @CommandPermission("multiverse.core.list.who") + @CommandCompletion("@mvworlds:scope=both @flags:groupName=mvwhocommand") + @Syntax(" [--page ] [--filter ]") + @Description("{@@mv-core.who.description}") + void onWhoCommand( + MVCommandIssuer issuer, + + @Syntax("") + @Description("{@@mv-core.who.world.description}") + LoadedMultiverseWorld inputtedWorld, + + @Optional + @Syntax("[--page ] [--filter ]") + @Description("{@@mv-core.who.flags.description}") + String[] flags) { + ParsedCommandFlags parsedFlags = parseFlags(flags); + + // Send the display + getListDisplay( + inputtedWorld, + parsedFlags.flagValue(PAGE_FLAG, 1), + parsedFlags.flagValue(FILTER_FLAG, DefaultContentFilter.get()), + false + ).send(issuer); + } + + private String phrasePlayerList(List players) { + return players.stream().map(Player::getName).collect(Collectors.joining(", ")); + } + + private ContentDisplay getListDisplay(LoadedMultiverseWorld world, int page, ContentFilter filter, boolean ignoreEmptyWorlds) { + Collection listingWorlds = new ArrayList<>(); + listingWorlds.add(world); + return getListDisplay(listingWorlds, page, filter, ignoreEmptyWorlds); + } + + private ContentDisplay getListDisplay(Collection worlds, int page, ContentFilter filter, boolean ignoreEmptyWorlds) { + HashMap outMap = new HashMap<>(); + + // Add all the worlds to our hashmap + for (LoadedMultiverseWorld world : worlds) { + @Nullable List players = world.getPlayers().getOrNull(); + + // If the world has 0 players in it, say that it is empty + if ((players == null || players.isEmpty()) && !ignoreEmptyWorlds) { + outMap.put(world.getAlias(), ChatColor.RED + "Empty"); + continue; + } + if (players == null || players.isEmpty()) { + continue; + } + + outMap.put(world.getAlias(), phrasePlayerList(players)); + } + + return ContentDisplay.create() + .addContent(MapContentProvider.forContent(outMap)) + .withSendHandler(PagedSendHandler.create() + .withHeader("%s====[ Multiverse World Players List ]====", ChatColor.AQUA) + .doPagination(true) + .withTargetPage(page) + .withFilter(filter)); + } +} diff --git a/src/main/java/org/mvplugins/multiverse/core/utils/MVCorei18n.java b/src/main/java/org/mvplugins/multiverse/core/utils/MVCorei18n.java index c257157a..8d089b98 100644 --- a/src/main/java/org/mvplugins/multiverse/core/utils/MVCorei18n.java +++ b/src/main/java/org/mvplugins/multiverse/core/utils/MVCorei18n.java @@ -101,6 +101,13 @@ public enum MVCorei18n implements MessageKeyProvider { UNLOAD_UNLOADING, UNLOAD_SUCCESS, + // who command + WHO_DESCRIPTION, + WHO_ALL_DESCRIPTION, + WHO_WORLD_DESCRIPTION, + WHO_FLAGS_DESCRIPTION, + WHO_EMPTY, + // version command VERSION_MV, VERSION_AUTHORS, diff --git a/src/main/resources/multiverse-core_en.properties b/src/main/resources/multiverse-core_en.properties index 26a9ab61..8e2f4b5a 100644 --- a/src/main/resources/multiverse-core_en.properties +++ b/src/main/resources/multiverse-core_en.properties @@ -139,6 +139,14 @@ mv-core.unload.success=&aWorld '{world}' unloaded! # /mv usage mv-core.usage.description=Show Multiverse-Core command usage. +# /mv who +# /mv whoall +mv-core.who.description=Lists the players in the world specified +mv-core.who.all.description=Lists the players in all worlds +mv-core.who.world.description=Name of the world you want to list players in +mv-core.who.flags.description=Filter - only shows entries matching this. Page - the page to show +mv-core.who.empty=&rEmpty + # /mv version mv-core.version.description=Displays version and authors mv-core.version.mv=Multiverse Core Version &fv{version}