Skip to content

Commit

Permalink
Refactor hvtp command to use cloud
Browse files Browse the repository at this point in the history
  • Loading branch information
md5sha256 committed Jan 11, 2024
1 parent ae01085 commit 8396286
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.StaticArgument;
import cloud.commandframework.arguments.flags.CommandFlag;
import cloud.commandframework.arguments.standard.IntegerArgument;
import cloud.commandframework.arguments.standard.LongArgument;
import cloud.commandframework.arguments.standard.StringArgument;
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
import cloud.commandframework.bukkit.parsers.PlayerArgument;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.meta.CommandMeta;
Expand Down Expand Up @@ -62,6 +64,7 @@
import se.hyperver.hyperverse.Hyperverse;
import se.hyperver.hyperverse.commands.parser.EnumParser;
import se.hyperver.hyperverse.commands.parser.GameRuleParser;
import se.hyperver.hyperverse.commands.parser.HyperWorldParser;
import se.hyperver.hyperverse.commands.parser.WorldFlagParser;
import se.hyperver.hyperverse.commands.parser.WorldStructureSettingParser;
import se.hyperver.hyperverse.configuration.FileHyperConfiguration;
Expand Down Expand Up @@ -201,7 +204,8 @@ public HyperCloudCommandManager(
// Start building the hypervere command
var builder = this.commandManager.commandBuilder("hyperverse", "hv");
this.registerCommandCreateWorld(this.commandManager, builder)
.registerCommandImport(this.commandManager, builder);
.registerCommandImport(this.commandManager, builder)
.registerCommandTeleport(this.commandManager, builder);

}

Expand Down Expand Up @@ -637,6 +641,78 @@ public void handleList(CommandContext<CommandSender> context) {
});
}

private void registerCommandTeleport(
@NonNull final CommandManager<CommandSender> commandManager,
final Command.@NonNull Builder<CommandSender> builder
) {
HyperWorldParser<CommandSender> hyperWorldParser = new HyperWorldParser<>(this.worldManager,
HyperWorldParser.WorldState.LOADED, true
);
var commandTeleportSinglePlayer = builder.literal("teleport", "tp")
.argument(CommandArgument.<CommandSender, HyperWorld>ofType(HyperWorld.class, "world")
.withSuggestionsProvider(hyperWorldParser::suggestions))
.senderType(Player.class)
.handler(this::handleTeleportSinglePlayer)
.permission("hyperverse.teleport")
.build();
var commandTeleport = builder.literal("teleport", "tp")
.argument(CommandArgument.<CommandSender, HyperWorld>ofType(HyperWorld.class, "world")
.withSuggestionsProvider(hyperWorldParser::suggestions))
.senderType(Player.class)
.handler(this::handleTeleportSingle)
.permission("hyperverse.teleport")
.build();
var commandTeleportSinglePlayerProxy = commandManager.commandBuilder("hvtp")
.proxies(commandTeleportSinglePlayer).build();
var commandTeleportProxy = commandManager.commandBuilder("hvtp")
.proxies(commandTeleport).build();
commandManager.command(commandTeleport)
.command(commandTeleportSinglePlayer)
.command(commandTeleportProxy)
.command(commandTeleportSinglePlayerProxy);
}

private void handleTeleportSinglePlayer(CommandContext<CommandSender> context) {
CommandSender sender = context.getSender();
if (!(sender instanceof Player player)) {
throw new IllegalArgumentException("Command can only be used by a player");
}
HyperWorld world = context.getOrDefault("world", null);
if (world == null) {
MessageUtil.sendMessage(player, Messages.messageNoSuchWorld);
return;
}
if (!world.isLoaded()) {
MessageUtil.sendMessage(player, Messages.messageWorldNotLoaded);
return;
}
if (world.getBukkitWorld() == player.getWorld()) {
MessageUtil.sendMessage(player, Messages.messageAlreadyInWorld);
return;
}
MessageUtil.sendMessage(player, Messages.messageTeleporting, "%world%", world.getDisplayName());
world.teleportPlayer(player);
}

private void handleTeleportSingle(CommandContext<CommandSender> context) {
Player player = context.get("player");
HyperWorld world = context.getOrDefault("world", null);
if (world == null) {
MessageUtil.sendMessage(player, Messages.messageNoSuchWorld);
return;
}
if (!world.isLoaded()) {
MessageUtil.sendMessage(player, Messages.messageWorldNotLoaded);
return;
}
if (world.getBukkitWorld() == player.getWorld()) {
MessageUtil.sendMessage(player, Messages.messageAlreadyInWorld);
return;
}
MessageUtil.sendMessage(player, Messages.messageTeleporting, "%world%", world.getDisplayName());
world.teleportPlayer(player);
}

@Subcommand("teleport|tp")
@CommandAlias("hvtp")
@CommandPermission("hyperverse.teleport")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.util.Arrays;
Expand Down Expand Up @@ -57,7 +58,7 @@ public EnumParser(
@NonNull final Queue<@NonNull String> inputQueue
) {
if (inputQueue.isEmpty()) {
return ArgumentParseResult.failure(new IllegalStateException("Input queue is empty"));
return ArgumentParseResult.failure(new NoInputProvidedException(getClass(), commandContext));
}
return this.fromStringMapper.apply(inputQueue.poll())
.map(ArgumentParseResult::success)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import org.bukkit.GameRule;
import org.checkerframework.checker.nullness.qual.NonNull;
import se.hyperver.hyperverse.configuration.Messages;
Expand All @@ -19,7 +20,7 @@ public class GameRuleParser<C> implements ArgumentParser<C, GameRule<?>> {
@NonNull final Queue<@NonNull String> inputQueue
) {
if (inputQueue.isEmpty()) {
return ArgumentParseResult.failure(new IllegalStateException("Input queue is empty"));
return ArgumentParseResult.failure(new NoInputProvidedException(getClass(), commandContext));
}
return java.util.Optional.ofNullable(GameRule.getByName(inputQueue.poll()))
.<ArgumentParseResult<GameRule<?>>>map(ArgumentParseResult::success)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package se.hyperver.hyperverse.commands.parser;

import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import org.bukkit.entity.Entity;
import org.checkerframework.checker.nullness.qual.NonNull;
import se.hyperver.hyperverse.configuration.Messages;
import se.hyperver.hyperverse.world.HyperWorld;
import se.hyperver.hyperverse.world.WorldManager;

import java.util.Comparator;
import java.util.List;
import java.util.Queue;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class HyperWorldParser<C> implements ArgumentParser<C, HyperWorld> {

private final WorldManager worldManager;

private final boolean filterSameWorld;
private final WorldState allowedWorldState;

public enum WorldState {
ANY,
LOADED,
UNLOADED,
}

public HyperWorldParser(@NonNull final WorldManager worldManager) {
this(worldManager, WorldState.ANY, false);
}

public HyperWorldParser(
@NonNull final WorldManager worldManager,
@NonNull final WorldState allowedWorldState,
final boolean filterSameWorld
) {
this.worldManager = worldManager;
this.allowedWorldState = allowedWorldState;
this.filterSameWorld = filterSameWorld;
}

@Override
public @NonNull ArgumentParseResult<@NonNull HyperWorld> parse(
@NonNull final CommandContext<@NonNull C> commandContext,
@NonNull final Queue<@NonNull String> inputQueue
) {
if (inputQueue.isEmpty()) {
return ArgumentParseResult.failure(new NoInputProvidedException(getClass(), commandContext));
}
final String world = inputQueue.poll();
final HyperWorld hyperWorld = this.worldManager.getWorld(world);
if (hyperWorld == null) {
return ArgumentParseResult.failure(new IllegalArgumentException(Messages.messageNoSuchWorld.withoutColorCodes()));
}
if (!this.filterSameWorld && this.allowedWorldState == WorldState.ANY) {
return ArgumentParseResult.success(hyperWorld);
}
if (this.allowedWorldState == WorldState.LOADED && !hyperWorld.isLoaded()) {
return ArgumentParseResult.failure(new IllegalArgumentException(Messages.messageWorldNotLoaded.withoutColorCodes()));
} else if (this.allowedWorldState == WorldState.UNLOADED && hyperWorld.isLoaded()) {
return ArgumentParseResult.failure(new IllegalArgumentException(Messages.messageWorldAlreadyLoaded.withoutColorCodes()));
}
// Must guard calls to commandContext behind filterSameWorld check otherwise we are violating
// the contextFree contract below in #isContextFree
if (filterSameWorld && (commandContext.getSender() instanceof Entity entity)) {
HyperWorld currentWorld = this.worldManager.getWorld(entity.getWorld());
if (currentWorld != null && currentWorld.equals(hyperWorld)) {
return ArgumentParseResult.failure(new IllegalArgumentException(Messages.messagePlayerAlreadyInWorld.withoutColorCodes()));
}
}
return ArgumentParseResult.success(hyperWorld);
}

@Override
public @NonNull List<@NonNull String> suggestions(
@NonNull final CommandContext<C> commandContext,
@NonNull final String input
) {
Stream<HyperWorld> stream = this.worldManager.getWorlds().stream();
if (this.allowedWorldState == WorldState.LOADED) {
stream = stream.filter(HyperWorld::isLoaded);
} else if (this.allowedWorldState == WorldState.UNLOADED) {
stream = stream.filter(Predicate.not(HyperWorld::isLoaded));
}
return stream.map(HyperWorld::getDisplayName)
.filter(name -> name.startsWith(input))
.sorted(Comparator.naturalOrder())
.toList();
}

@Override
public boolean isContextFree() {
return !this.filterSameWorld;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import org.checkerframework.checker.nullness.qual.NonNull;
import se.hyperver.hyperverse.configuration.Messages;
import se.hyperver.hyperverse.flags.GlobalWorldFlagContainer;
Expand All @@ -27,7 +28,7 @@ public WorldFlagParser(@NonNull final GlobalWorldFlagContainer flagContainer) {
@NonNull final Queue<@NonNull String> inputQueue
) {
if (inputQueue.isEmpty()) {
return ArgumentParseResult.failure(new IllegalStateException("Input queue is empty"));
return ArgumentParseResult.failure(new NoInputProvidedException(getClass(), commandContext));
}
final WorldFlag<?, ?> flag = this.flagContainer.getFlagFromString(inputQueue.poll().toLowerCase(Locale.ENGLISH));
if (flag == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import org.checkerframework.checker.nullness.qual.NonNull;
import se.hyperver.hyperverse.configuration.Messages;
import se.hyperver.hyperverse.world.WorldStructureSetting;
Expand All @@ -22,7 +23,7 @@ public class WorldStructureSettingParser<C> implements ArgumentParser<C, WorldSt
@NonNull final Queue<@NonNull String> inputQueue
) {
if (inputQueue.isEmpty()) {
return ArgumentParseResult.failure(new IllegalArgumentException("Input queue is empty"));
return ArgumentParseResult.failure(new NoInputProvidedException(getClass(), commandContext));
}
return switch (inputQueue.poll().toLowerCase(Locale.ENGLISH)) {
case "yes", "true", "generate_structures", "structures" ->
Expand Down

0 comments on commit 8396286

Please sign in to comment.