Add support for Commodore mappings
This commit is contained in:
parent
b80e33503f
commit
1c831a3bcf
13 changed files with 320 additions and 42 deletions
|
|
@ -57,6 +57,17 @@
|
|||
<artifactId>cloud-core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.intellectualsites</groupId>
|
||||
<artifactId>cloud-brigadier</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.lucko</groupId>
|
||||
<artifactId>commodore</artifactId>
|
||||
<version>1.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -29,13 +29,18 @@ 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.Bukkit;
|
||||
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.EnumSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Command manager for the Bukkit platform, using {@link BukkitCommandSender} as the
|
||||
|
|
@ -45,7 +50,13 @@ import java.util.function.Function;
|
|||
*/
|
||||
public class BukkitCommandManager<C> extends CommandManager<C> {
|
||||
|
||||
private static final int VERSION_RADIX = 10;
|
||||
private static final int BRIGADIER_MINIMAL_VERSION = 13;
|
||||
private static final int PAPER_BRIGADIER_VERSION = 15;
|
||||
|
||||
private final Plugin owningPlugin;
|
||||
private final int minecraftVersion;
|
||||
private final boolean paper;
|
||||
|
||||
private final Function<CommandSender, C> commandSenderMapper;
|
||||
private final Function<C, CommandSender> backwardsCommandSenderMapper;
|
||||
|
|
@ -77,6 +88,29 @@ public class BukkitCommandManager<C> extends CommandManager<C> {
|
|||
this.getParserRegistry().registerParserSupplier(TypeToken.of(World.class), params -> new WorldArgument.WorldParser<>());
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.of(Material.class),
|
||||
params -> new MaterialArgument.MaterialParser<>());
|
||||
|
||||
/* Try to determine the Minecraft version */
|
||||
int version = -1;
|
||||
try {
|
||||
final Matcher matcher = Pattern.compile("\\(MC: (\\d)\\.(\\d+)\\.?(\\d+?)?\\)")
|
||||
.matcher(Bukkit.getVersion());
|
||||
if (matcher.find()) {
|
||||
version = Integer.parseInt(matcher.toMatchResult().group(2),
|
||||
VERSION_RADIX);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
this.owningPlugin.getLogger().severe("Failed to determine Minecraft version "
|
||||
+ "for cloud Bukkit capability detection");
|
||||
}
|
||||
this.minecraftVersion = version;
|
||||
|
||||
boolean paper = false;
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
paper = true;
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
this.paper = paper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,4 +157,118 @@ public class BukkitCommandManager<C> extends CommandManager<C> {
|
|||
return this.splitAliases;
|
||||
}
|
||||
|
||||
protected final void checkBrigadierCompatibility() throws BrigadierFailureException {
|
||||
if (!this.queryCapability(CloudBukkitCapabilities.BRIGADIER)) {
|
||||
throw new BrigadierFailureException(BrigadierFailureReason.VERSION_TOO_LOW,
|
||||
new IllegalArgumentException("Version: " + this.minecraftVersion));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for a specific capability
|
||||
*
|
||||
* @param capability Capability
|
||||
* @return {@code true} if the manager has the given capability, else {@code false}
|
||||
*/
|
||||
public final boolean queryCapability(@Nonnull final CloudBukkitCapabilities capability) {
|
||||
return this.queryCapabilities().contains(capability);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for the platform capabilities
|
||||
*
|
||||
* @return A set containing all capabilities of the instance
|
||||
*/
|
||||
public final Set<CloudBukkitCapabilities> queryCapabilities() {
|
||||
if (this.paper) {
|
||||
if (this.minecraftVersion >= BRIGADIER_MINIMAL_VERSION) {
|
||||
if (this.minecraftVersion >= PAPER_BRIGADIER_VERSION) {
|
||||
return EnumSet.of(CloudBukkitCapabilities.NATIVE_BRIGADIER,
|
||||
CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION,
|
||||
CloudBukkitCapabilities.BRIGADIER);
|
||||
} else {
|
||||
return EnumSet.of(CloudBukkitCapabilities.COMMODORE_BRIGADIER,
|
||||
CloudBukkitCapabilities.BRIGADIER);
|
||||
}
|
||||
} else {
|
||||
return EnumSet.of(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION);
|
||||
}
|
||||
} else {
|
||||
if (this.minecraftVersion >= BRIGADIER_MINIMAL_VERSION) {
|
||||
return EnumSet.of(CloudBukkitCapabilities.COMMODORE_BRIGADIER,
|
||||
CloudBukkitCapabilities.BRIGADIER);
|
||||
}
|
||||
}
|
||||
return EnumSet.noneOf(CloudBukkitCapabilities.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to register the Brigadier mapper, and return it.
|
||||
*
|
||||
* @throws BrigadierFailureException If Brigadier isn't
|
||||
* supported by the platform
|
||||
*/
|
||||
public void registerBrigadier() throws BrigadierFailureException {
|
||||
this.checkBrigadierCompatibility();
|
||||
try {
|
||||
final CloudCommodoreManager<C> cloudCommodoreManager = new CloudCommodoreManager<>(this);
|
||||
cloudCommodoreManager.initialize(this);
|
||||
this.setCommandRegistrationHandler(cloudCommodoreManager);
|
||||
} catch (final Throwable e) {
|
||||
throw new BrigadierFailureException(BrigadierFailureReason.COMMODORE_NOT_PRESENT, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reasons to explain why Brigadier failed to initialize
|
||||
*/
|
||||
public enum BrigadierFailureReason {
|
||||
COMMODORE_NOT_PRESENT, VERSION_TOO_LOW, PAPER_BRIGADIER_INITIALIZATION_FAILURE
|
||||
}
|
||||
|
||||
|
||||
public static final class BrigadierFailureException extends IllegalStateException {
|
||||
|
||||
private final BrigadierFailureReason reason;
|
||||
|
||||
/**
|
||||
* Initialize a new Brigadier failure exception
|
||||
*
|
||||
* @param reason Reason
|
||||
*/
|
||||
public BrigadierFailureException(@Nonnull final BrigadierFailureReason reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a new Brigadier failure exception
|
||||
*
|
||||
* @param reason Reason
|
||||
* @param cause Cause
|
||||
*/
|
||||
public BrigadierFailureException(@Nonnull final BrigadierFailureReason reason, @Nonnull final Throwable cause) {
|
||||
super(cause);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reason for the exception
|
||||
*
|
||||
* @return Reason
|
||||
*/
|
||||
@Nonnull
|
||||
public BrigadierFailureReason getReason() {
|
||||
return this.reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("Could not initialize Brigadier mappings. Reason: %s (%s)",
|
||||
this.reason.name().toLowerCase().replace("_", " "),
|
||||
this.getCause() == null ? "" : this.getCause().getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
final class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHandler {
|
||||
class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHandler {
|
||||
|
||||
private final Map<CommandArgument<?, ?>, org.bukkit.command.Command> registeredCommands = new HashMap<>();
|
||||
|
||||
|
|
@ -89,6 +89,7 @@ final class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHan
|
|||
this.registeredCommands.put(commandArgument, bukkitCommand);
|
||||
this.commandMap.register(commandArgument.getName(), this.bukkitCommandManager.getOwningPlugin().getName().toLowerCase(),
|
||||
bukkitCommand);
|
||||
this.registerExternal(commandArgument.getName(), command, bukkitCommand);
|
||||
|
||||
if (this.bukkitCommandManager.getSplitAliases()) {
|
||||
for (final String alias : aliases) {
|
||||
|
|
@ -102,6 +103,7 @@ final class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHan
|
|||
this.commandMap.register(alias, this.bukkitCommandManager.getOwningPlugin()
|
||||
.getName().toLowerCase(),
|
||||
bukkitCommand);
|
||||
this.registerExternal(alias, command, aliasCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,5 +111,9 @@ final class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHan
|
|||
return true;
|
||||
}
|
||||
|
||||
protected void registerExternal(@Nonnull final String label,
|
||||
@Nonnull final Command<?> command,
|
||||
@Nonnull final BukkitCommand<C> bukkitCommand) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// 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;
|
||||
|
||||
/**
|
||||
* Capabilities for the Bukkit module
|
||||
*/
|
||||
public enum CloudBukkitCapabilities {
|
||||
BRIGADIER, COMMODORE_BRIGADIER, NATIVE_BRIGADIER, ASYNCHRONOUS_COMPLETION
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// 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.brigadier.CloudBrigadierManager;
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import me.lucko.commodore.Commodore;
|
||||
import me.lucko.commodore.CommodoreProvider;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||
|
||||
private final CloudBrigadierManager brigadierManager;
|
||||
private final Commodore commodore;
|
||||
|
||||
CloudCommodoreManager(@Nonnull final BukkitCommandManager<C> commandManager)
|
||||
throws BukkitCommandManager.BrigadierFailureException {
|
||||
if (!CommodoreProvider.isSupported()) {
|
||||
throw new BukkitCommandManager.BrigadierFailureException(BukkitCommandManager
|
||||
.BrigadierFailureReason.COMMODORE_NOT_PRESENT);
|
||||
}
|
||||
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
|
||||
this.brigadierManager = new CloudBrigadierManager<>(commandManager, () ->
|
||||
new CommandContext<>(commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender())));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerExternal(@Nonnull final String label,
|
||||
@Nonnull final Command<?> command,
|
||||
@Nonnull final BukkitCommand<C> bukkitCommand) {
|
||||
final com.mojang.brigadier.Command<?> cmd = o -> 1;
|
||||
final LiteralCommandNode<?> literalCommandNode = this.brigadierManager
|
||||
.createLiteralCommandNode(label, command, (o, p) -> true, cmd);
|
||||
this.commodore.register(bukkitCommand, literalCommandNode, p -> p.hasPermission(command.getCommandPermission()));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue