Add Bungee implementation

This commit is contained in:
Alexander Söderberg 2020-09-19 00:21:27 +02:00
parent 04a6919c6a
commit 1a85251fc6
No known key found for this signature in database
GPG key ID: C0207FF7EA146678
29 changed files with 420 additions and 57 deletions

View file

@ -0,0 +1,126 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import com.intellectualsites.commands.Command;
import com.intellectualsites.commands.arguments.CommandArgument;
import com.intellectualsites.commands.arguments.StaticArgument;
import com.intellectualsites.commands.exceptions.ArgumentParseException;
import com.intellectualsites.commands.exceptions.InvalidCommandSenderException;
import com.intellectualsites.commands.exceptions.InvalidSyntaxException;
import com.intellectualsites.commands.exceptions.NoPermissionException;
import com.intellectualsites.commands.exceptions.NoSuchCommandException;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;
import javax.annotation.Nonnull;
import java.util.List;
final class BukkitCommand<C> extends org.bukkit.command.Command implements PluginIdentifiableCommand {
private static final String MESSAGE_NO_PERMS = ChatColor.RED
+ "I'm sorry, but you do not have permission to perform this command. "
+ "Please contact the server administrators if you believe that this is in error.";
private static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command. Type \"/help\" for help.";
private final CommandArgument<C, ?> command;
private final BukkitCommandManager<C> bukkitCommandManager;
private final Command<C, BukkitCommandMeta> cloudCommand;
@SuppressWarnings("unchecked")
BukkitCommand(@Nonnull final Command<C, BukkitCommandMeta> cloudCommand,
@Nonnull final CommandArgument<C, ?> command,
@Nonnull final BukkitCommandManager<C> bukkitCommandManager) {
super(command.getName(),
cloudCommand.getCommandMeta().getOrDefault("description", ""),
"",
((StaticArgument<C>) command).getAlternativeAliases());
this.command = command;
this.bukkitCommandManager = bukkitCommandManager;
this.cloudCommand = cloudCommand;
}
@Override
public boolean execute(final CommandSender commandSender, final String s, final String[] strings) {
/* Join input */
final StringBuilder builder = new StringBuilder(this.command.getName());
for (final String string : strings) {
builder.append(" ").append(string);
}
this.bukkitCommandManager.executeCommand(this.bukkitCommandManager.getCommandSenderMapper().apply(commandSender),
builder.toString())
.whenComplete(((commandResult, throwable) -> {
if (throwable != null) {
if (throwable instanceof InvalidSyntaxException) {
commandSender.sendMessage(ChatColor.RED + "Invalid Command Syntax. "
+ "Correct command syntax is: "
+ ChatColor.GRAY + "/"
+ ((InvalidSyntaxException) throwable).getCorrectSyntax());
} else if (throwable instanceof InvalidCommandSenderException) {
commandSender.sendMessage(ChatColor.RED + throwable.getMessage());
} else if (throwable instanceof NoPermissionException) {
commandSender.sendMessage(MESSAGE_NO_PERMS);
} else if (throwable instanceof NoSuchCommandException) {
commandSender.sendMessage(MESSAGE_UNKNOWN_COMMAND);
} else if (throwable instanceof ArgumentParseException) {
commandSender.sendMessage(ChatColor.RED + "Invalid Command Argument: "
+ ChatColor.GRAY + throwable.getCause().getMessage());
} else {
commandSender.sendMessage(throwable.getMessage());
throwable.printStackTrace();
}
}
}));
return true;
}
@Override
public String getDescription() {
return this.cloudCommand.getCommandMeta().getOrDefault("description", "");
}
@Override
public List<String> tabComplete(final CommandSender sender, final String alias, final String[] args) throws
IllegalArgumentException {
final StringBuilder builder = new StringBuilder(this.command.getName());
for (final String string : args) {
builder.append(" ").append(string);
}
return this.bukkitCommandManager.suggest(this.bukkitCommandManager.getCommandSenderMapper().apply(sender),
builder.toString());
}
@Override
public Plugin getPlugin() {
return this.bukkitCommandManager.getOwningPlugin();
}
@Override
public String getPermission() {
return this.cloudCommand.getCommandPermission();
}
}

View file

@ -0,0 +1,117 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import com.google.common.reflect.TypeToken;
import com.intellectualsites.commands.CommandManager;
import com.intellectualsites.commands.CommandTree;
import com.intellectualsites.commands.bukkit.parsers.MaterialArgument;
import com.intellectualsites.commands.bukkit.parsers.WorldArgument;
import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import javax.annotation.Nonnull;
import java.util.function.Function;
/**
* Command manager for the Bukkit platform, using {@link BukkitCommandSender} as the
* command sender type
*
* @param <C> Command sender type
*/
public class BukkitCommandManager<C>
extends CommandManager<C, BukkitCommandMeta> {
private final Plugin owningPlugin;
private final Function<CommandSender, C> commandSenderMapper;
private final Function<C, CommandSender> backwardsCommandSenderMapper;
/**
* Construct a new Bukkit command manager
*
* @param owningPlugin Plugin that is constructing the manager
* @param commandExecutionCoordinator Coordinator provider
* @param commandSenderMapper Function that maps {@link CommandSender} to the command sender type
* @param backwardsCommandSenderMapper Function that maps the command sender type to {@link CommandSender}
* @throws Exception If the construction of the manager fails
*/
public BukkitCommandManager(@Nonnull final Plugin owningPlugin,
@Nonnull final Function<CommandTree<C, BukkitCommandMeta>,
CommandExecutionCoordinator<C, BukkitCommandMeta>> commandExecutionCoordinator,
@Nonnull final Function<CommandSender, C> commandSenderMapper,
@Nonnull final Function<C, CommandSender> backwardsCommandSenderMapper)
throws Exception {
super(commandExecutionCoordinator, new BukkitPluginRegistrationHandler<>());
((BukkitPluginRegistrationHandler<C>) this.getCommandRegistrationHandler()).initialize(this);
this.owningPlugin = owningPlugin;
this.commandSenderMapper = commandSenderMapper;
this.backwardsCommandSenderMapper = backwardsCommandSenderMapper;
/* Register Bukkit parsers */
this.getParserRegistry().registerParserSupplier(TypeToken.of(World.class), params -> new WorldArgument.WorldParser<>());
this.getParserRegistry().registerParserSupplier(TypeToken.of(Material.class),
params -> new MaterialArgument.MaterialParser<>());
}
/**
* Get the plugin that owns the manager
*
* @return Owning plugin
*/
@Nonnull
public Plugin getOwningPlugin() {
return this.owningPlugin;
}
/**
* Create default command meta data
*
* @return Meta data
*/
@Nonnull
@Override
public BukkitCommandMeta createDefaultCommandMeta() {
return BukkitCommandMetaBuilder.builder().withDescription("").build();
}
/**
* Get the command sender mapper
*
* @return Command sender mapper
*/
@Nonnull
public final Function<CommandSender, C> getCommandSenderMapper() {
return this.commandSenderMapper;
}
@Override
public final boolean hasPermission(@Nonnull final C sender, @Nonnull final String permission) {
return this.backwardsCommandSenderMapper.apply(sender).hasPermission(permission);
}
}

View file

@ -0,0 +1,41 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import com.intellectualsites.commands.meta.SimpleCommandMeta;
import javax.annotation.Nonnull;
public class BukkitCommandMeta extends SimpleCommandMeta {
/**
* Bukkit command meta data
*
* @param simpleCommandMeta Simple command meta data instance that gets mirrored
*/
public BukkitCommandMeta(@Nonnull final SimpleCommandMeta simpleCommandMeta) {
super(simpleCommandMeta.getAll());
}
}

View file

@ -0,0 +1,82 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import com.intellectualsites.commands.meta.CommandMeta;
import javax.annotation.Nonnull;
public final class BukkitCommandMetaBuilder {
private BukkitCommandMetaBuilder() {
}
/**
* Create a new builder stage 1
*
* @return Builder instance
*/
@Nonnull public static BuilderStage1 builder() {
return new BuilderStage1();
}
public static final class BuilderStage1 {
private BuilderStage1() {
}
/**
* Set the command description
*
* @param description Command description
* @return Builder instance
*/
@Nonnull public BuilderStage2 withDescription(@Nonnull final String description) {
return new BuilderStage2(description);
}
}
public static final class BuilderStage2 {
private final String description;
private BuilderStage2(@Nonnull final String description) {
this.description = description;
}
/**
* Build the command meta instance
*
* @return Meta instance
*/
@Nonnull public BukkitCommandMeta build() {
return new BukkitCommandMeta(CommandMeta.simple().with("description", this.description).build());
}
}
}

View file

@ -0,0 +1,135 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import com.google.common.base.Objects;
import org.bukkit.entity.Player;
import javax.annotation.Nonnull;
/**
* Command sender that proxies {@link org.bukkit.command.CommandSender}
* {@inheritDoc}
*/
public abstract class BukkitCommandSender {
private final org.bukkit.command.CommandSender internalSender;
/**
* Create a new command sender from a Bukkit {@link org.bukkit.command.CommandSender}
*
* @param internalSender Bukkit command sender
*/
public BukkitCommandSender(@Nonnull final org.bukkit.command.CommandSender internalSender) {
this.internalSender = internalSender;
}
/**
* Construct a new {@link BukkitCommandSender} for a {@link Player}
*
* @param player Player instance
* @return Constructed command sender
*/
@Nonnull
public static BukkitCommandSender player(@Nonnull final Player player) {
return new BukkitPlayerSender(player);
}
/**
* Construct a new {@link BukkitCommandSender} for the Bukkit console
*
* @return Constructed command sender
*/
@Nonnull
public static BukkitCommandSender console() {
return new BukkitConsoleSender();
}
/**
* Construct a new {@link BukkitCommandSender} from a Bukkit {@link org.bukkit.command.CommandSender}
*
* @param sender Bukkit command sender
* @return Constructed command sender
*/
@Nonnull
public static BukkitCommandSender of(@Nonnull final org.bukkit.command.CommandSender sender) {
if (sender instanceof Player) {
return player((Player) sender);
}
return console();
}
@Override
public final boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final BukkitCommandSender that = (BukkitCommandSender) o;
return Objects.equal(internalSender, that.internalSender);
}
@Override
public final int hashCode() {
return Objects.hashCode(internalSender);
}
/**
* Get the proxied {@link org.bukkit.command.CommandSender}
*
* @return Proxied command sneder
*/
@Nonnull
public org.bukkit.command.CommandSender getInternalSender() {
return this.internalSender;
}
/**
* Check if this sender represents a player
*
* @return {@code true} if this sender represents a player, {@code false} if not
*/
public abstract boolean isPlayer();
/**
* Get this sender as a player. This can only safely be done if {@link #isPlayer()}}
* returns {@code true}
*
* @return Player object
*/
@Nonnull
public abstract Player asPlayer();
/**
* Send a message to the command sender
*
* @param message Message to send
*/
public void sendMessage(@Nonnull final String message) {
this.internalSender.sendMessage(message);
}
}

View file

@ -0,0 +1,48 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import javax.annotation.Nonnull;
final class BukkitConsoleSender extends BukkitCommandSender {
BukkitConsoleSender() {
super(Bukkit.getConsoleSender());
}
@Override
public boolean isPlayer() {
return false;
}
@Nonnull
@Override
public Player asPlayer() {
throw new UnsupportedOperationException("Cannot convert console to player");
}
}

View file

@ -0,0 +1,46 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import org.bukkit.entity.Player;
import javax.annotation.Nonnull;
final class BukkitPlayerSender extends BukkitCommandSender {
BukkitPlayerSender(@Nonnull final Player player) {
super(player);
}
@Override
public boolean isPlayer() {
return true;
}
@Nonnull
@Override
public Player asPlayer() {
return (Player) this.getInternalSender();
}
}

View file

@ -0,0 +1,87 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit;
import com.intellectualsites.commands.Command;
import com.intellectualsites.commands.arguments.CommandArgument;
import com.intellectualsites.commands.internal.CommandRegistrationHandler;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.help.GenericCommandHelpTopic;
import javax.annotation.Nonnull;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
final class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHandler<BukkitCommandMeta> {
private final Map<CommandArgument<?, ?>, org.bukkit.command.Command> registeredCommands = new HashMap<>();
private Map<String, org.bukkit.command.Command> bukkitCommands;
private BukkitCommandManager<C> bukkitCommandManager;
private CommandMap commandMap;
BukkitPluginRegistrationHandler() {
}
void initialize(@Nonnull final BukkitCommandManager<C> bukkitCommandManager) throws Exception {
final Method getCommandMap = Bukkit.getServer().getClass().getDeclaredMethod("getCommandMap");
getCommandMap.setAccessible(true);
this.commandMap = (CommandMap) getCommandMap.invoke(Bukkit.getServer());
final Field knownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands");
knownCommands.setAccessible(true);
@SuppressWarnings("ALL") final Map<String, org.bukkit.command.Command> bukkitCommands =
(Map<String, org.bukkit.command.Command>) knownCommands.get(commandMap);
this.bukkitCommands = bukkitCommands;
this.bukkitCommandManager = bukkitCommandManager;
Bukkit.getHelpMap().registerHelpTopicFactory(BukkitCommand.class, GenericCommandHelpTopic::new);
}
@Override
public boolean registerCommand(@Nonnull final Command<?, BukkitCommandMeta> command) {
/* We only care about the root command argument */
final CommandArgument<?, ?> commandArgument = command.getArguments().get(0);
if (this.registeredCommands.containsKey(commandArgument)) {
return false;
}
final String label;
if (bukkitCommands.containsKey(commandArgument.getName())) {
label = String.format("%s:%s", this.bukkitCommandManager.getOwningPlugin().getName(), commandArgument.getName());
} else {
label = commandArgument.getName();
}
@SuppressWarnings("unchecked") final BukkitCommand<C> bukkitCommand = new BukkitCommand<>(
(Command<C, BukkitCommandMeta>) command,
(CommandArgument<C, ?>) commandArgument,
this.bukkitCommandManager);
this.registeredCommands.put(commandArgument, bukkitCommand);
this.commandMap.register(commandArgument.getName(), this.bukkitCommandManager.getOwningPlugin().getName().toLowerCase(),
bukkitCommand);
return true;
}
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
/**
* cloud implementation for Bukkit 1.8-1.16
*/
package com.intellectualsites.commands.bukkit;

View file

@ -0,0 +1,162 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit.parsers;
import com.intellectualsites.commands.arguments.CommandArgument;
import com.intellectualsites.commands.arguments.parser.ArgumentParseResult;
import com.intellectualsites.commands.arguments.parser.ArgumentParser;
import com.intellectualsites.commands.context.CommandContext;
import org.bukkit.Material;
import javax.annotation.Nonnull;
import java.util.EnumSet;
import java.util.Queue;
import java.util.stream.Collectors;
/**
* cloud argument type that parses Bukkit {@link Material materials}
*
* @param <C> Command sender type
*/
public class MaterialArgument<C> extends CommandArgument<C, Material> {
protected MaterialArgument(final boolean required,
@Nonnull final String name,
@Nonnull final String defaultValue) {
super(required, name, new MaterialParser<>(), defaultValue, Material.class);
}
/**
* Create a new builder
*
* @param name Name of the argument
* @param <C> Command sender type
* @return Created builder
*/
@Nonnull
public static <C> MaterialArgument.Builder<C> newBuilder(@Nonnull final String name) {
return new MaterialArgument.Builder<>(name);
}
/**
* Create a new required argument
*
* @param name Argument name
* @param <C> Command sender type
* @return Created argument
*/
@Nonnull
public static <C> CommandArgument<C, Material> required(@Nonnull final String name) {
return MaterialArgument.<C>newBuilder(name).asRequired().build();
}
/**
* Create a new optional argument
*
* @param name Argument name
* @param <C> Command sender type
* @return Created argument
*/
@Nonnull
public static <C> CommandArgument<C, Material> optional(@Nonnull final String name) {
return MaterialArgument.<C>newBuilder(name).asOptional().build();
}
/**
* Create a new optional argument with a default value
*
* @param name Argument name
* @param material Default value
* @param <C> Command sender type
* @return Created argument
*/
@Nonnull
public static <C> CommandArgument<C, Material> optional(@Nonnull final String name,
@Nonnull final Material material) {
return MaterialArgument.<C>newBuilder(name).asOptionalWithDefault(material.name().toLowerCase()).build();
}
public static final class Builder<C> extends CommandArgument.Builder<C, Material> {
protected Builder(@Nonnull final String name) {
super(Material.class, name);
}
}
public static final class MaterialParser<C> implements ArgumentParser<C, Material> {
@Nonnull
@Override
public ArgumentParseResult<Material> parse(@Nonnull final CommandContext<C> commandContext,
@Nonnull final Queue<String> inputQueue) {
final String input = inputQueue.peek();
if (input == null) {
return ArgumentParseResult.failure(new NullPointerException("No input was provided"));
}
try {
final Material material = Material.valueOf(input.replace("minecraft:", "").toUpperCase());
inputQueue.remove();
return ArgumentParseResult.success(material);
} catch (final IllegalArgumentException exception) {
return ArgumentParseResult.failure(new MaterialParseException(input));
}
}
}
public static final class MaterialParseException extends IllegalArgumentException {
private final String input;
/**
* Construct a new MaterialParseException
*
* @param input Input
*/
public MaterialParseException(@Nonnull final String input) {
this.input = input;
}
/**
* Get the input
*
* @return Input
*/
@Nonnull
public String getInput() {
return this.input;
}
@Override
public String getMessage() {
return EnumSet.allOf(Material.class).stream().map(Material::name).map(String::toLowerCase)
.collect(Collectors.joining(", "));
}
}
}

View file

@ -0,0 +1,173 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package com.intellectualsites.commands.bukkit.parsers;
import com.intellectualsites.commands.arguments.CommandArgument;
import com.intellectualsites.commands.arguments.parser.ArgumentParseResult;
import com.intellectualsites.commands.arguments.parser.ArgumentParser;
import com.intellectualsites.commands.context.CommandContext;
import org.bukkit.Bukkit;
import org.bukkit.World;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;
/**
* cloud argument type that parses Bukkit {@link org.bukkit.World worlds}
*
* @param <C> Command sender type
*/
public class WorldArgument<C> extends CommandArgument<C, World> {
protected WorldArgument(final boolean required,
@Nonnull final String name,
@Nonnull final String defaultValue) {
super(required, name, new WorldParser<>(), defaultValue, World.class);
}
/**
* Create a new builder
*
* @param name Name of the argument
* @param <C> Command sender type
* @return Created builder
*/
@Nonnull
public static <C> CommandArgument.Builder<C, World> newBuilder(@Nonnull final String name) {
return new WorldArgument.Builder<>(name);
}
/**
* Create a new required argument
*
* @param name Argument name
* @param <C> Command sender type
* @return Created argument
*/
@Nonnull
public static <C> CommandArgument<C, World> required(@Nonnull final String name) {
return WorldArgument.<C>newBuilder(name).asRequired().build();
}
/**
* Create a new optional argument
*
* @param name Argument name
* @param <C> Command sender type
* @return Created argument
*/
@Nonnull
public static <C> CommandArgument<C, World> optional(@Nonnull final String name) {
return WorldArgument.<C>newBuilder(name).asOptional().build();
}
/**
* Create a new optional argument with a default value
*
* @param name Argument name
* @param defaultValue Default value
* @param <C> Command sender type
* @return Created argument
*/
@Nonnull
public static <C> CommandArgument<C, World> optional(@Nonnull final String name,
@Nonnull final String defaultValue) {
return WorldArgument.<C>newBuilder(name).asOptionalWithDefault(defaultValue).build();
}
public static final class Builder<C> extends CommandArgument.Builder<C, World> {
protected Builder(@Nonnull final String name) {
super(World.class, name);
}
@Nonnull
@Override
public CommandArgument<C, World> build() {
return new WorldArgument<>(this.isRequired(), this.getName(), this.getDefaultValue());
}
}
public static final class WorldParser<C> implements ArgumentParser<C, World> {
@Nonnull
@Override
public ArgumentParseResult<World> parse(@Nonnull final CommandContext<C> commandContext,
@Nonnull final Queue<String> inputQueue) {
final String input = inputQueue.peek();
if (input == null) {
return ArgumentParseResult.failure(new NullPointerException("No input was provided"));
}
final World world = Bukkit.getWorld(input);
if (world == null) {
return ArgumentParseResult.failure(new WorldParseException(input));
}
inputQueue.remove();
return ArgumentParseResult.success(world);
}
@Nonnull
@Override
public List<String> suggestions(@Nonnull final CommandContext<C> commandContext, @Nonnull final String input) {
return Bukkit.getWorlds().stream().map(World::getName).collect(Collectors.toList());
}
}
public static final class WorldParseException extends IllegalArgumentException {
private final String input;
/**
* Construct a new WorldParseException
*
* @param input Input
*/
public WorldParseException(@Nonnull final String input) {
this.input = input;
}
/**
* Get the input provided by the sender
*
* @return Input
*/
public String getInput() {
return this.input;
}
@Override
public String getMessage() {
return String.format("'%s' is not a valid Minecraft world", this.input);
}
}
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
/**
* Bukkit specific command arguments
*/
package com.intellectualsites.commands.bukkit.parsers;