Merge branch 'MV5' into zax71/MV5/spawnCommand

This commit is contained in:
Ben Woo 2024-08-30 12:29:50 +08:00
commit 8cbf2bc050
25 changed files with 275 additions and 7 deletions

View File

@ -30,6 +30,7 @@ class CheckCommand extends MultiverseCommand {
this.destinationsProvider = destinationsProvider;
}
@CommandAlias("mvcheck")
@Subcommand("check")
@CommandPermission("multiverse.core.check")
@CommandCompletion("@players @destinations|@mvworlds")

View File

@ -46,6 +46,7 @@ class CloneCommand extends MultiverseCommand {
this.worldManager = worldManager;
}
@CommandAlias("mvcl|mvclone")
@Subcommand("clone")
@CommandPermission("multiverse.core.clone")
@CommandCompletion("@mvworlds:scope=loaded @empty @flags:groupName=mvclonecommand")

View File

@ -30,6 +30,7 @@ class ConfigCommand extends MultiverseCommand {
this.config = config;
}
@CommandAlias("mvconfig|mvconf")
@Subcommand("config")
@CommandPermission("multiverse.core.config")
@CommandCompletion("@mvconfigs @mvconfigvalues")

View File

@ -21,6 +21,7 @@ class ConfirmCommand extends MultiverseCommand {
super(commandManager);
}
@CommandAlias("mvconfirm")
@Subcommand("confirm")
@CommandPermission("multiverse.core.confirm")
@Description("{@@mv-core.confirm.description}")

View File

@ -30,7 +30,7 @@ class CoordinatesCommand extends MultiverseCommand {
super(commandManager);
this.locationManipulation = locationManipulation;
}
@CommandAlias("mvcoord|mvco")
@Subcommand("coordinates|coords|coord|co")
@CommandPermission("multiverse.core.coord")
@Description("{@@mv-core.coordinates.description}")

View File

@ -69,6 +69,7 @@ class CreateCommand extends MultiverseCommand {
this.generatorProvider = generatorProvider;
}
@CommandAlias("mvcreate|mvc")
@Subcommand("create")
@CommandPermission("multiverse.core.create")
@CommandCompletion("@empty @environments @flags:groupName=mvcreatecommand")

View File

@ -36,6 +36,7 @@ class DebugCommand extends MultiverseCommand {
this.displayDebugMode(issuer);
}
@CommandAlias("mvdebug")
@Subcommand("debug")
@CommandPermission("multiverse.core.debug")
@CommandCompletion("@range:3")

View File

@ -50,6 +50,7 @@ class DeleteCommand extends MultiverseCommand {
this.playerWorldTeleporter = playerWorldTeleporter;
}
@CommandAlias("mvdelete")
@Subcommand("delete")
@CommandPermission("multiverse.core.delete")
@CommandCompletion("@mvworlds:scope=loaded @flags:groupName=mvdeletecommand")

View File

@ -69,6 +69,7 @@ class GeneratorsCommand extends MultiverseCommand {
this.generatorProvider = generatorProvider;
}
@CommandAlias("mvgenerators|mvgens")
@Subcommand("generators|gens")
@CommandPermission("multiverse.core.generator")
@CommandCompletion("@flags:groupName=mvgeneratorscommand @flags:groupName=mvgeneratorscommand")

View File

@ -52,6 +52,7 @@ class ImportCommand extends MultiverseCommand {
this.generatorProvider = generatorProvider;
}
@CommandAlias("mvimport|mvim")
@Subcommand("import")
@CommandPermission("multiverse.core.import")
@CommandCompletion("@mvworlds:scope=potential @environments @flags:groupName=mvimportcommand")

View File

@ -75,6 +75,7 @@ class InfoCommand extends MultiverseCommand {
}
// TODO: support info for unloaded worlds
@CommandAlias("mvinfo|mvi")
@Subcommand("info")
@CommandPermission("multiverse.core.info")
@CommandCompletion("@mvworlds:scope=both|@flags:groupName=mvinfocommand @flags:groupName=mvinfocommand")

View File

@ -73,6 +73,7 @@ class ListCommand extends MultiverseCommand {
this.worldEntryCheckerProvider = worldEntryCheckerProvider;
}
@CommandAlias("mvlist|mvl")
@Subcommand("list")
@CommandPermission("multiverse.core.list.worlds")
@CommandCompletion("@flags:groupName=mvlistcommand")

View File

@ -31,6 +31,7 @@ class LoadCommand extends MultiverseCommand {
this.worldManager = worldManager;
}
@CommandAlias("mvload")
@Subcommand("load")
@CommandPermission("multiverse.core.load")
@CommandCompletion("@mvworlds:scope=unloaded")

View File

@ -10,6 +10,7 @@ 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.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@ -33,6 +34,7 @@ class ModifyCommand extends MultiverseCommand {
this.worldManager = worldManager;
}
@CommandAlias("mvmodify|mvm")
@Subcommand("modify")
@CommandPermission("multiverse.core.modify")
@CommandCompletion("@mvworlds:scope=both @propsmodifyaction @mvworldpropsname @mvworldpropsvalue")
@ -60,17 +62,27 @@ class ModifyCommand extends MultiverseCommand {
String propertyValue) {
StringPropertyHandle worldPropertyHandle = world.getStringPropertyHandle();
worldPropertyHandle.modifyProperty(propertyName, propertyValue, action).onSuccess(ignore -> {
issuer.sendMessage("Property %s set to %s for world %s.".formatted(
issuer.sendMessage("Property %s%s set to %s%s for world %s%s%s.".formatted(
propertyName,
ChatColor.BLUE,
worldPropertyHandle.getProperty(propertyName).getOrNull(),
world.getName()));
ChatColor.BLUE,
ChatColor.GRAY,
world.getName(),
ChatColor.BLUE
));
worldManager.saveWorldsConfig();
}).onFailure(exception -> {
issuer.sendMessage("Failed to %s property %s to %s for world %s.".formatted(
issuer.sendMessage("Failed to %s%s property %s%s to %s%s for world %s%s.".formatted(
action.name().toLowerCase(),
ChatColor.BLUE,
propertyName,
ChatColor.BLUE,
propertyValue,
world.getName()));
ChatColor.BLUE,
world.getName(),
ChatColor.BLUE
));
issuer.sendMessage(exception.getMessage());
});
}

View File

@ -70,6 +70,7 @@ class RegenCommand extends MultiverseCommand {
this.playerWorldTeleporter = playerWorldTeleporter;
}
@CommandAlias("mvregen")
@Subcommand("regen")
@CommandPermission("multiverse.core.regen")
@CommandCompletion("@mvworlds:scope=loaded @flags:groupName=mvregencommand")

View File

@ -44,6 +44,7 @@ class ReloadCommand extends MultiverseCommand {
this.pluginManager = pluginManager;
}
@CommandAlias("mvreload|mvr")
@Subcommand("reload")
@CommandPermission("multiverse.core.reload")
@Description("{@@mv-core.reload.description}")

View File

@ -48,6 +48,7 @@ class RemoveCommand extends MultiverseCommand {
this.playerWorldTeleporter = playerWorldTeleporter;
}
@CommandAlias("mvremove")
@Subcommand("remove")
@CommandPermission("multiverse.core.remove")
@CommandCompletion("@mvworlds:scope=both")

View File

@ -51,6 +51,7 @@ class UnloadCommand extends MultiverseCommand {
this.playerWorldTeleporter = playerWorldTeleporter;
}
@CommandAlias("mvunload")
@Subcommand("unload")
@CommandPermission("multiverse.core.unload")
@CommandCompletion("@mvworlds @flags:groupName=mvunloadcommand")

View File

@ -0,0 +1,38 @@
package org.mvplugins.multiverse.core.commands;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.MessageType;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.MultiverseCore;
import org.mvplugins.multiverse.core.commandtools.MVCommandManager;
import org.mvplugins.multiverse.core.commandtools.MultiverseCommand;
import org.mvplugins.multiverse.core.utils.MVCorei18n;
@Service
@CommandAlias("mv")
class VersionCommand extends MultiverseCommand {
private final MultiverseCore plugin;
@Inject
VersionCommand(@NotNull MVCommandManager commandManager, MultiverseCore plugin) {
super(commandManager);
this.plugin = plugin;
}
@CommandAlias("mvversion")
@Subcommand("version")
@CommandPermission("multiverse.core.version")
@Description("{@@mv-core.version.description}")
void versionCommand(BukkitCommandIssuer issuer) {
issuer.sendMessage(MessageType.INFO, MVCorei18n.VERSION_MV, "{version}", plugin.getDescription().getVersion());
issuer.sendMessage(MessageType.INFO, MVCorei18n.VERSION_AUTHORS, "{authors}", String.join(", ", plugin.getDescription().getAuthors()));
issuer.sendMessage(MessageType.INFO, MVCorei18n.VERSION_SECRETCODE); // An in joke I don't get...
}
}

View File

@ -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<Integer> 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<ContentFilter> 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 <page>] [--filter <filter>]")
@Description("{@@mv-core.who.all.description}")
void onWhoAllCommand(
MVCommandIssuer issuer,
@Optional
@Syntax("[--page <page>] [--filter <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("<world> [--page <page>] [--filter <filter>]")
@Description("{@@mv-core.who.description}")
void onWhoCommand(
MVCommandIssuer issuer,
@Syntax("<world>")
@Description("{@@mv-core.who.world.description}")
LoadedMultiverseWorld inputtedWorld,
@Optional
@Syntax("[--page <page>] [--filter <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<Player> players) {
return players.stream().map(Player::getName).collect(Collectors.joining(", "));
}
private ContentDisplay getListDisplay(LoadedMultiverseWorld world, int page, ContentFilter filter, boolean ignoreEmptyWorlds) {
Collection<LoadedMultiverseWorld> listingWorlds = new ArrayList<>();
listingWorlds.add(world);
return getListDisplay(listingWorlds, page, filter, ignoreEmptyWorlds);
}
private ContentDisplay getListDisplay(Collection<LoadedMultiverseWorld> worlds, int page, ContentFilter filter, boolean ignoreEmptyWorlds) {
HashMap<String, String> outMap = new HashMap<>();
// Add all the worlds to our hashmap
for (LoadedMultiverseWorld world : worlds) {
@Nullable List<Player> 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));
}
}

View File

@ -108,6 +108,18 @@ 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,
VERSION_SECRETCODE,
// debug command
DEBUG_INFO_OFF,
DEBUG_INFO_ON,

View File

@ -3,6 +3,7 @@ package org.mvplugins.multiverse.core.utils.result;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import org.mvplugins.multiverse.core.utils.message.MessageReplacement;
@ -67,6 +68,19 @@ public final class AsyncAttempt<T, F extends FailureReason> {
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.onSuccess(runnable)));
}
public AsyncAttempt<T, F> onFailure(Runnable runnable) {
// TODO Not sure why we creating a new instance instead of using `this`
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.onFailure(runnable)));
}
public AsyncAttempt<T, F> onFailure(Consumer<Attempt.Failure<T, F>> consumer) {
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.onFailure(consumer)));
}
public AsyncAttempt<T, F> onFailureReason(Consumer<F> consumer) {
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.onFailureReason(consumer)));
}
public Attempt<T, F> toAttempt() {
return future.join();
}

View File

@ -734,7 +734,7 @@ public class WorldManager {
* @return The world if it exists.
*/
public Option<MultiverseWorld> getWorld(@Nullable World world) {
return Option.of(world).flatMap(this::getWorld);
return Option.of(world).map(World::getName).flatMap(this::getWorld);
}
/**

View File

@ -146,6 +146,20 @@ 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}
mv-core.version.authors=Multiverse Core Authors &f{authors}
mv-core.version.secretcode=Special Code: &fFRN002
# commands error
mv-core.commands.error.playersonly=&cThis command can only be used by players
mv-core.commands.error.multiverseworldonly=&cThis can only be used in multiverse worlds

View File

@ -1,6 +1,6 @@
name: Multiverse-Core
main: org.mvplugins.multiverse.core.MultiverseCore
authors: ['dumptruckman', 'Rigby', 'fernferret', 'lithium3141', 'main--']
authors: ['dumptruckman', 'Rigby', 'fernferret', 'lithium3141', 'main--', 'benwoo1110', 'Zax71']
website: 'https://dev.bukkit.org/projects/multiverse-core'
softdepend: ['Vault', 'PlaceholderAPI']
api-version: 1.13