bukkit: Implement ItemStackArgument (#257)
Fully featured on 1.13+, falls back to Material parser on legacy versions. Also some general cleanup to the Bukkit impl
This commit is contained in:
parent
e5d6ce7b90
commit
e3cc7d43cb
20 changed files with 899 additions and 180 deletions
|
|
@ -4,4 +4,5 @@
|
||||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||||
<suppressions>
|
<suppressions>
|
||||||
<suppress checks="(?:(?:Member|Method)Name|DesignForExtension|Javadoc.*)" files=".*[\\/]mixin[\\/].*"/>
|
<suppress checks="(?:(?:Member|Method)Name|DesignForExtension|Javadoc.*)" files=".*[\\/]mixin[\\/].*"/>
|
||||||
|
<suppress checks="(?:Javadoc.*)" files=".*[\\/]CraftBukkitReflection.java"/>
|
||||||
</suppressions>
|
</suppressions>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- JDA Role argument parser
|
- JDA Role argument parser
|
||||||
|
- Bukkit: Implement parser for ProtoItemStack ([#257](https://github.com/Incendo/cloud/pull/257))
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Use Command instead of TabCompleteEvent on Bukkit
|
- Use Command instead of TabCompleteEvent on Bukkit
|
||||||
|
|
|
||||||
|
|
@ -23,21 +23,25 @@
|
||||||
//
|
//
|
||||||
package cloud.commandframework.bukkit;
|
package cloud.commandframework.bukkit;
|
||||||
|
|
||||||
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.arguments.standard.UUIDArgument;
|
||||||
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.MultipleEntitySelector;
|
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector;
|
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
import cloud.commandframework.bukkit.parsers.ItemStackArgument;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
import cloud.commandframework.bukkit.parsers.location.Location2DArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.location.Location2D;
|
import cloud.commandframework.bukkit.parsers.location.LocationArgument;
|
||||||
|
import cloud.commandframework.bukkit.parsers.selector.MultipleEntitySelectorArgument;
|
||||||
|
import cloud.commandframework.bukkit.parsers.selector.MultiplePlayerSelectorArgument;
|
||||||
|
import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument;
|
||||||
|
import cloud.commandframework.bukkit.parsers.selector.SinglePlayerSelectorArgument;
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
import org.bukkit.Bukkit;
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
import org.bukkit.Location;
|
import io.leangen.geantyref.GenericTypeReflector;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import io.leangen.geantyref.TypeToken;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
@ -46,14 +50,12 @@ import java.util.logging.Level;
|
||||||
*
|
*
|
||||||
* @param <C> Command sender type
|
* @param <C> Command sender type
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
||||||
public final class BukkitBrigadierMapper<C> {
|
public final class BukkitBrigadierMapper<C> {
|
||||||
|
|
||||||
private static final int UUID_ARGUMENT_VERSION = 16;
|
private static final int UUID_ARGUMENT_VERSION = 16;
|
||||||
|
|
||||||
private final BukkitCommandManager<C> commandManager;
|
private final BukkitCommandManager<C> commandManager;
|
||||||
private final CloudBrigadierManager brigadierManager;
|
private final CloudBrigadierManager<C, ?> brigadierManager;
|
||||||
private final String nmsVersion;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,38 +66,48 @@ public final class BukkitBrigadierMapper<C> {
|
||||||
*/
|
*/
|
||||||
public BukkitBrigadierMapper(
|
public BukkitBrigadierMapper(
|
||||||
final @NonNull BukkitCommandManager<C> commandManager,
|
final @NonNull BukkitCommandManager<C> commandManager,
|
||||||
final @NonNull CloudBrigadierManager brigadierManager
|
final @NonNull CloudBrigadierManager<C, ?> brigadierManager
|
||||||
) {
|
) {
|
||||||
this.commandManager = commandManager;
|
this.commandManager = commandManager;
|
||||||
this.brigadierManager = brigadierManager;
|
this.brigadierManager = brigadierManager;
|
||||||
|
|
||||||
/* Detect Minecraft Version Metadata */
|
if (!CraftBukkitReflection.craftBukkit()) {
|
||||||
final String version = Bukkit.getServer().getClass().getPackage().getName();
|
this.commandManager.getOwningPlugin().getLogger().warning(
|
||||||
this.nmsVersion = version.substring(version.lastIndexOf(".") + 1);
|
"Could not detect relocated CraftBukkit package, NMS brigadier mappings will not be enabled.");
|
||||||
final int majorMinecraftVersion = Integer.parseInt(this.nmsVersion.split("_")[1]);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
this.registerMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerMappings() {
|
||||||
/* UUID nms argument is a 1.16+ feature */
|
/* UUID nms argument is a 1.16+ feature */
|
||||||
if (majorMinecraftVersion >= UUID_ARGUMENT_VERSION) {
|
if (CraftBukkitReflection.MAJOR_REVISION >= UUID_ARGUMENT_VERSION) {
|
||||||
/* Map UUID */
|
/* Map UUID */
|
||||||
this.mapSimpleNMS(UUID.class, this.getNMSArgument("UUID").getConstructor());
|
this.mapSimpleNMS(new TypeToken<UUIDArgument.UUIDParser<C>>() {
|
||||||
|
}, "UUID");
|
||||||
}
|
}
|
||||||
/* Map Enchantment */
|
/* Map Enchantment */
|
||||||
this.mapSimpleNMS(Enchantment.class, this.getNMSArgument("Enchantment").getConstructor());
|
this.mapSimpleNMS(new TypeToken<EnchantmentArgument.EnchantmentParser<C>>() {
|
||||||
|
}, "Enchantment");
|
||||||
|
/* Map ItemStackArgument */
|
||||||
|
this.mapSimpleNMS(new TypeToken<ItemStackArgument.Parser<C>>() {
|
||||||
|
}, "ItemStack");
|
||||||
/* Map Entity Selectors */
|
/* Map Entity Selectors */
|
||||||
this.mapComplexNMS(SingleEntitySelector.class, this.getEntitySelectorArgument(true, false));
|
this.mapNMS(new TypeToken<SingleEntitySelectorArgument.SingleEntitySelectorParser<C>>() {
|
||||||
this.mapComplexNMS(SinglePlayerSelector.class, this.getEntitySelectorArgument(true, true));
|
}, this.entitySelectorArgumentSupplier(true, false));
|
||||||
this.mapComplexNMS(MultipleEntitySelector.class, this.getEntitySelectorArgument(false, false));
|
this.mapNMS(new TypeToken<SinglePlayerSelectorArgument.SinglePlayerSelectorParser<C>>() {
|
||||||
this.mapComplexNMS(MultiplePlayerSelector.class, this.getEntitySelectorArgument(false, true));
|
}, this.entitySelectorArgumentSupplier(true, true));
|
||||||
|
this.mapNMS(new TypeToken<MultipleEntitySelectorArgument.MultipleEntitySelectorParser<C>>() {
|
||||||
|
}, this.entitySelectorArgumentSupplier(false, false));
|
||||||
|
this.mapNMS(new TypeToken<MultiplePlayerSelectorArgument.MultiplePlayerSelectorParser<C>>() {
|
||||||
|
}, this.entitySelectorArgumentSupplier(false, true));
|
||||||
/* Map Vec3 */
|
/* Map Vec3 */
|
||||||
this.mapComplexNMS(Location.class, this.getArgumentVec3());
|
this.mapNMS(new TypeToken<LocationArgument.LocationParser<C>>() {
|
||||||
|
}, this::argumentVec3);
|
||||||
/* Map Vec2I */
|
/* Map Vec2I */
|
||||||
this.mapComplexNMS(Location2D.class, this.getArgumentVec2I());
|
this.mapNMS(new TypeToken<Location2DArgument.Location2DParser<C>>() {
|
||||||
} catch (final Exception e) {
|
}, this::argumentVec2i);
|
||||||
this.commandManager.getOwningPlugin()
|
|
||||||
.getLogger()
|
|
||||||
.log(Level.WARNING, "Failed to map Bukkit types to NMS argument types", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -103,45 +115,39 @@ public final class BukkitBrigadierMapper<C> {
|
||||||
* @param playersOnly Whether the selector is for players only (true), or for all entities (false)
|
* @param playersOnly Whether the selector is for players only (true), or for all entities (false)
|
||||||
* @return The NMS ArgumentType
|
* @return The NMS ArgumentType
|
||||||
*/
|
*/
|
||||||
private @NonNull Supplier<ArgumentType<?>> getEntitySelectorArgument(
|
private @NonNull Supplier<ArgumentType<?>> entitySelectorArgumentSupplier(
|
||||||
final boolean single,
|
final boolean single,
|
||||||
final boolean playersOnly
|
final boolean playersOnly
|
||||||
) {
|
) {
|
||||||
return () -> {
|
return () -> {
|
||||||
try {
|
try {
|
||||||
final Constructor<?> constructor = this.getNMSArgument("Entity").getDeclaredConstructors()[0];
|
final Constructor<?> constructor = getNMSArgument("Entity").getDeclaredConstructors()[0];
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return (ArgumentType<?>) constructor.newInstance(single, playersOnly);
|
return (ArgumentType<?>) constructor.newInstance(single, playersOnly);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Selector Argument", e);
|
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Selector Argument", e);
|
||||||
return null;
|
return fallbackType();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("UnnecessaryLambda")
|
private @NonNull ArgumentType<?> argumentVec3() {
|
||||||
private @NonNull Supplier<ArgumentType<?>> getArgumentVec3() {
|
|
||||||
return () -> {
|
|
||||||
try {
|
try {
|
||||||
return (ArgumentType<?>) this.getNMSArgument("Vec3").getDeclaredConstructor(boolean.class)
|
return (ArgumentType<?>) getNMSArgument("Vec3").getDeclaredConstructor(boolean.class)
|
||||||
.newInstance(true);
|
.newInstance(true);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec3D argument", e);
|
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec3D argument", e);
|
||||||
return null;
|
return fallbackType();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("UnnecessaryLambda")
|
private @NonNull ArgumentType<?> argumentVec2i() {
|
||||||
private @NonNull Supplier<ArgumentType<?>> getArgumentVec2I() {
|
|
||||||
return () -> {
|
|
||||||
try {
|
try {
|
||||||
return (ArgumentType<?>) this.getNMSArgument("Vec2I").getDeclaredConstructor().newInstance();
|
return (ArgumentType<?>) getNMSArgument("Vec2I").getDeclaredConstructor().newInstance();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec2I argument", e);
|
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec2I argument", e);
|
||||||
return null;
|
return fallbackType();
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -149,40 +155,52 @@ public final class BukkitBrigadierMapper<C> {
|
||||||
*
|
*
|
||||||
* @param argument Argument type name
|
* @param argument Argument type name
|
||||||
* @return Argument class
|
* @return Argument class
|
||||||
* @throws Exception If the type cannot be retrieved
|
* @throws RuntimeException when the class is not found
|
||||||
*/
|
*/
|
||||||
@NonNull
|
private static @NonNull Class<?> getNMSArgument(final @NonNull String argument) throws RuntimeException {
|
||||||
private Class<?> getNMSArgument(final @NonNull String argument) throws Exception {
|
return CraftBukkitReflection.needNMSClass("Argument" + argument);
|
||||||
return Class.forName(String.format("net.minecraft.server.%s.Argument%s", this.nmsVersion, argument));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to register a mapping between a type and a NMS argument type
|
* Attempt to register a mapping between a cloud argument parser type and an NMS brigadier argument type which
|
||||||
|
* has a no-args constructor.
|
||||||
*
|
*
|
||||||
* @param type Type to map
|
* @param type Type to map
|
||||||
* @param constructor Constructor that construct the NMS argument type
|
* @param <T> argument parser type
|
||||||
|
* @param argumentName NMS Argument class name (without 'Argument' prefix)
|
||||||
|
* @since 1.5.0
|
||||||
*/
|
*/
|
||||||
public void mapSimpleNMS(
|
public <T extends ArgumentParser<C, ?>> void mapSimpleNMS(
|
||||||
final @NonNull Class<?> type,
|
final @NonNull TypeToken<T> type,
|
||||||
final @NonNull Constructor<?> constructor
|
final @NonNull String argumentName
|
||||||
) {
|
) {
|
||||||
|
final Constructor<?> constructor;
|
||||||
try {
|
try {
|
||||||
this.brigadierManager.registerDefaultArgumentTypeSupplier(type, () -> {
|
final Class<?> nmsArgument = getNMSArgument(argumentName);
|
||||||
|
constructor = nmsArgument.getConstructor();
|
||||||
|
} catch (final RuntimeException | ReflectiveOperationException e) {
|
||||||
|
this.commandManager.getOwningPlugin().getLogger().log(
|
||||||
|
Level.WARNING,
|
||||||
|
String.format("Failed to create mapping for NMS brigadier argument type '%s'.", argumentName),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.brigadierManager.registerMapping(type, builder -> builder.to(argument -> {
|
||||||
try {
|
try {
|
||||||
return constructor.newInstance();
|
return (ArgumentType<?>) constructor.newInstance();
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
} catch (final ReflectiveOperationException e) {
|
||||||
e.printStackTrace();
|
this.commandManager.getOwningPlugin().getLogger().log(
|
||||||
}
|
Level.WARNING,
|
||||||
return null;
|
String.format(
|
||||||
});
|
"Failed to create instance of brigadier argument type '%s'.",
|
||||||
} catch (final Exception e) {
|
GenericTypeReflector.erase(type.getType()).getCanonicalName()
|
||||||
this.commandManager.getOwningPlugin()
|
),
|
||||||
.getLogger()
|
e
|
||||||
.warning(String.format(
|
);
|
||||||
"Failed to map '%s' to a Mojang serializable argument type",
|
return fallbackType();
|
||||||
type.getCanonicalName()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -190,21 +208,61 @@ public final class BukkitBrigadierMapper<C> {
|
||||||
*
|
*
|
||||||
* @param type Type to map
|
* @param type Type to map
|
||||||
* @param argumentTypeSupplier Supplier of the NMS argument type
|
* @param argumentTypeSupplier Supplier of the NMS argument type
|
||||||
|
* @param <T> argument parser type
|
||||||
|
* @since 1.5.0
|
||||||
*/
|
*/
|
||||||
|
public <T extends ArgumentParser<C, ?>> void mapNMS(
|
||||||
|
final @NonNull TypeToken<T> type,
|
||||||
|
final @NonNull Supplier<ArgumentType<?>> argumentTypeSupplier
|
||||||
|
) {
|
||||||
|
this.brigadierManager.registerMapping(type, builder ->
|
||||||
|
builder.to(argument -> argumentTypeSupplier.get())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NonNull StringArgumentType fallbackType() {
|
||||||
|
return StringArgumentType.word();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to register a mapping between a type and a NMS argument type
|
||||||
|
*
|
||||||
|
* @param type Type to map
|
||||||
|
* @param constructor Constructor that construct the NMS argument type
|
||||||
|
* @deprecated use {@link #mapSimpleNMS(TypeToken, String)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void mapSimpleNMS(
|
||||||
|
final @NonNull Class<?> type,
|
||||||
|
final @NonNull Constructor<?> constructor
|
||||||
|
) {
|
||||||
|
this.brigadierManager.registerDefaultArgumentTypeSupplier(type, () -> {
|
||||||
|
try {
|
||||||
|
return (ArgumentType<?>) constructor.newInstance();
|
||||||
|
} catch (final ReflectiveOperationException e) {
|
||||||
|
this.commandManager.getOwningPlugin().getLogger().log(
|
||||||
|
Level.WARNING,
|
||||||
|
String.format("Failed to map brigadier argument type '%s'", type.getCanonicalName()),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return fallbackType();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to register a mapping between a type and a NMS argument type
|
||||||
|
*
|
||||||
|
* @param type Type to map
|
||||||
|
* @param argumentTypeSupplier Supplier of the NMS argument type
|
||||||
|
* @deprecated use {@link #mapNMS(TypeToken, Supplier)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public void mapComplexNMS(
|
public void mapComplexNMS(
|
||||||
final @NonNull Class<?> type,
|
final @NonNull Class<?> type,
|
||||||
final @NonNull Supplier<ArgumentType<?>> argumentTypeSupplier
|
final @NonNull Supplier<ArgumentType<?>> argumentTypeSupplier
|
||||||
) {
|
) {
|
||||||
try {
|
|
||||||
this.brigadierManager.registerDefaultArgumentTypeSupplier(type, argumentTypeSupplier);
|
this.brigadierManager.registerDefaultArgumentTypeSupplier(type, argumentTypeSupplier);
|
||||||
} catch (final Exception e) {
|
|
||||||
this.commandManager.getOwningPlugin()
|
|
||||||
.getLogger()
|
|
||||||
.warning(String.format(
|
|
||||||
"Failed to map '%s' to a Mojang serializable argument type",
|
|
||||||
type.getCanonicalName()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2021 Alexander Söderberg & Contributors
|
||||||
|
//
|
||||||
|
// 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 cloud.commandframework.bukkit;
|
||||||
|
|
||||||
|
import cloud.commandframework.keys.CloudKey;
|
||||||
|
import cloud.commandframework.keys.SimpleCloudKey;
|
||||||
|
import io.leangen.geantyref.TypeToken;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bukkit related {@link cloud.commandframework.context.CommandContext} keys.
|
||||||
|
*
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public final class BukkitCommandContextKeys {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key used to store the Bukkit native {@link CommandSender} in the {@link cloud.commandframework.context.CommandContext}.
|
||||||
|
*
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static final CloudKey<CommandSender> BUKKIT_COMMAND_SENDER = SimpleCloudKey.of(
|
||||||
|
"BukkitCommandSender",
|
||||||
|
TypeToken.get(CommandSender.class)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key used to store the active {@link CloudBukkitCapabilities} in the {@link cloud.commandframework.context.CommandContext}.
|
||||||
|
*
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static final CloudKey<Set<CloudBukkitCapabilities>> CLOUD_BUKKIT_CAPABILITIES = SimpleCloudKey.of(
|
||||||
|
"CloudBukkitCapabilities",
|
||||||
|
new TypeToken<Set<CloudBukkitCapabilities>>() {
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
private BukkitCommandContextKeys() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,10 @@ import cloud.commandframework.bukkit.arguments.selector.MultipleEntitySelector;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector;
|
import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
||||||
|
import cloud.commandframework.bukkit.data.ProtoItemStack;
|
||||||
|
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
|
||||||
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
||||||
|
import cloud.commandframework.bukkit.parsers.ItemStackArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.MaterialArgument;
|
import cloud.commandframework.bukkit.parsers.MaterialArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.OfflinePlayerArgument;
|
import cloud.commandframework.bukkit.parsers.OfflinePlayerArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
||||||
|
|
@ -81,7 +84,7 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
||||||
|
|
||||||
private final Plugin owningPlugin;
|
private final Plugin owningPlugin;
|
||||||
private final int minecraftVersion;
|
private final int minecraftVersion;
|
||||||
private final boolean paper;
|
private final boolean paper = CraftBukkitReflection.classExists("com.destroystokyo.paper.PaperConfig");
|
||||||
|
|
||||||
private final Function<CommandSender, C> commandSenderMapper;
|
private final Function<CommandSender, C> commandSenderMapper;
|
||||||
private final Function<C, CommandSender> backwardsCommandSenderMapper;
|
private final Function<C, CommandSender> backwardsCommandSenderMapper;
|
||||||
|
|
@ -134,30 +137,7 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
||||||
this.taskFactory = new TaskFactory(bukkitSynchronizer);
|
this.taskFactory = new TaskFactory(bukkitSynchronizer);
|
||||||
|
|
||||||
/* Try to determine the Minecraft version */
|
/* Try to determine the Minecraft version */
|
||||||
int version = -1;
|
this.minecraftVersion = this.getMinecraftVersion();
|
||||||
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 is fine
|
|
||||||
}
|
|
||||||
this.paper = paper;
|
|
||||||
|
|
||||||
/* Register Bukkit Preprocessor */
|
/* Register Bukkit Preprocessor */
|
||||||
this.registerCommandPreProcessor(new BukkitCommandPreprocessor<>(this));
|
this.registerCommandPreProcessor(new BukkitCommandPreprocessor<>(this));
|
||||||
|
|
@ -177,6 +157,8 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
||||||
new LocationArgument.LocationParser<>());
|
new LocationArgument.LocationParser<>());
|
||||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(Location2D.class), parserParameters ->
|
this.getParserRegistry().registerParserSupplier(TypeToken.get(Location2D.class), parserParameters ->
|
||||||
new Location2DArgument.Location2DParser<>());
|
new Location2DArgument.Location2DParser<>());
|
||||||
|
this.getParserRegistry().registerParserSupplier(TypeToken.get(ProtoItemStack.class), parserParameters ->
|
||||||
|
new ItemStackArgument.Parser<>());
|
||||||
/* Register Entity Selector Parsers */
|
/* Register Entity Selector Parsers */
|
||||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(SingleEntitySelector.class), parserParameters ->
|
this.getParserRegistry().registerParserSupplier(TypeToken.get(SingleEntitySelector.class), parserParameters ->
|
||||||
new SingleEntitySelectorArgument.SingleEntitySelectorParser<>());
|
new SingleEntitySelectorArgument.SingleEntitySelectorParser<>());
|
||||||
|
|
@ -196,6 +178,19 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
||||||
this.setCaptionRegistry(new BukkitCaptionRegistryFactory<C>().create());
|
this.setCaptionRegistry(new BukkitCaptionRegistryFactory<C>().create());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getMinecraftVersion() {
|
||||||
|
try {
|
||||||
|
final Matcher matcher = Pattern.compile("\\(MC: (\\d)\\.(\\d+)\\.?(\\d+?)?\\)").matcher(Bukkit.getVersion());
|
||||||
|
if (matcher.find()) {
|
||||||
|
return 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");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a command manager using Bukkit's {@link CommandSender} as the sender type.
|
* Create a command manager using Bukkit's {@link CommandSender} as the sender type.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ import cloud.commandframework.execution.preprocessor.CommandPreprocessingContext
|
||||||
import cloud.commandframework.execution.preprocessor.CommandPreprocessor;
|
import cloud.commandframework.execution.preprocessor.CommandPreprocessor;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command preprocessor which decorates incoming {@link cloud.commandframework.context.CommandContext}
|
* Command preprocessor which decorates incoming {@link cloud.commandframework.context.CommandContext}
|
||||||
* with Bukkit specific objects
|
* with Bukkit specific objects
|
||||||
|
|
@ -35,26 +37,29 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
*/
|
*/
|
||||||
final class BukkitCommandPreprocessor<C> implements CommandPreprocessor<C> {
|
final class BukkitCommandPreprocessor<C> implements CommandPreprocessor<C> {
|
||||||
|
|
||||||
private final BukkitCommandManager<C> mgr;
|
private final BukkitCommandManager<C> commandManager;
|
||||||
|
private final Set<CloudBukkitCapabilities> bukkitCapabilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Bukkit Command Preprocessor for storing Bukkit-specific contexts in the command contexts
|
* The Bukkit Command Preprocessor for storing Bukkit-specific contexts in the command contexts
|
||||||
*
|
*
|
||||||
* @param mgr The BukkitCommandManager
|
* @param commandManager The BukkitCommandManager
|
||||||
*/
|
*/
|
||||||
BukkitCommandPreprocessor(final @NonNull BukkitCommandManager<C> mgr) {
|
BukkitCommandPreprocessor(final @NonNull BukkitCommandManager<C> commandManager) {
|
||||||
this.mgr = mgr;
|
this.commandManager = commandManager;
|
||||||
|
this.bukkitCapabilities = commandManager.queryCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the sender mapped to {@link org.bukkit.command.CommandSender} in the context with the key "BukkitCommandSender",
|
|
||||||
* and a {@link java.util.Set} of {@link CloudBukkitCapabilities} with the key "CloudBukkitCapabilities"
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(final @NonNull CommandPreprocessingContext<C> context) {
|
public void accept(final @NonNull CommandPreprocessingContext<C> context) {
|
||||||
context.getCommandContext().store("BukkitCommandSender", this.mgr.getBackwardsCommandSenderMapper().apply(
|
context.getCommandContext().store(
|
||||||
context.getCommandContext().getSender()));
|
BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER,
|
||||||
context.getCommandContext().store("CloudBukkitCapabilities", this.mgr.queryCapabilities());
|
this.commandManager.getBackwardsCommandSenderMapper().apply(context.getCommandContext().getSender())
|
||||||
|
);
|
||||||
|
context.getCommandContext().store(
|
||||||
|
BukkitCommandContextKeys.CLOUD_BUKKIT_CAPABILITIES,
|
||||||
|
this.bukkitCapabilities
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ package cloud.commandframework.bukkit;
|
||||||
|
|
||||||
import cloud.commandframework.Command;
|
import cloud.commandframework.Command;
|
||||||
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
||||||
|
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.permission.CommandPermission;
|
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
import me.lucko.commodore.Commodore;
|
import me.lucko.commodore.Commodore;
|
||||||
|
|
@ -36,13 +36,14 @@ import org.bukkit.command.CommandSender;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
|
|
||||||
private final BukkitCommandManager<C> commandManager;
|
private final BukkitCommandManager<C> commandManager;
|
||||||
private final CloudBrigadierManager brigadierManager;
|
private final CloudBrigadierManager<C, Object> brigadierManager;
|
||||||
private final Commodore commodore;
|
private final Commodore commodore;
|
||||||
|
|
||||||
CloudCommodoreManager(final @NonNull BukkitCommandManager<C> commandManager)
|
CloudCommodoreManager(final @NonNull BukkitCommandManager<C> commandManager)
|
||||||
|
|
@ -53,17 +54,29 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
}
|
}
|
||||||
this.commandManager = commandManager;
|
this.commandManager = commandManager;
|
||||||
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
|
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
|
||||||
this.brigadierManager = new CloudBrigadierManager<>(commandManager, () ->
|
this.brigadierManager = new CloudBrigadierManager<>(commandManager, () -> new CommandContext<>(
|
||||||
new CommandContext<>(
|
|
||||||
commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender()),
|
commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender()),
|
||||||
commandManager
|
commandManager
|
||||||
));
|
));
|
||||||
this.brigadierManager.brigadierSenderMapper(
|
|
||||||
sender -> this.commandManager.getCommandSenderMapper().apply(
|
this.brigadierManager.brigadierSenderMapper(sender ->
|
||||||
this.commodore.getBukkitSender(sender)
|
this.commandManager.getCommandSenderMapper().apply(this.commodore.getBukkitSender(sender)));
|
||||||
)
|
|
||||||
);
|
|
||||||
new BukkitBrigadierMapper<>(this.commandManager, this.brigadierManager);
|
new BukkitBrigadierMapper<>(this.commandManager, this.brigadierManager);
|
||||||
|
|
||||||
|
if (!CraftBukkitReflection.craftBukkit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Class<?> vanillaCommandWrapperClass = CraftBukkitReflection.needOBCClass("command.VanillaCommandWrapper");
|
||||||
|
final Method getListenerMethod = CraftBukkitReflection.needMethod(
|
||||||
|
vanillaCommandWrapperClass, "getListener", CommandSender.class);
|
||||||
|
this.brigadierManager.backwardsBrigadierSenderMapper(cloud -> {
|
||||||
|
try {
|
||||||
|
return getListenerMethod.invoke(null, this.commandManager.getBackwardsCommandSenderMapper().apply(cloud));
|
||||||
|
} catch (final ReflectiveOperationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -72,7 +85,7 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
final @NonNull Command<?> command,
|
final @NonNull Command<?> command,
|
||||||
final @NonNull BukkitCommand<C> bukkitCommand
|
final @NonNull BukkitCommand<C> bukkitCommand
|
||||||
) {
|
) {
|
||||||
this.registerWithCommodore(label, command);
|
this.registerWithCommodore(label, (Command<C>) command);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @NonNull CloudBrigadierManager brigadierManager() {
|
protected @NonNull CloudBrigadierManager brigadierManager() {
|
||||||
|
|
@ -81,17 +94,13 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
|
|
||||||
private void registerWithCommodore(
|
private void registerWithCommodore(
|
||||||
final @NonNull String label,
|
final @NonNull String label,
|
||||||
final @NonNull Command<?> command
|
final @NonNull Command<C> command
|
||||||
) {
|
) {
|
||||||
final com.mojang.brigadier.Command<?> cmd = o -> 1;
|
|
||||||
final LiteralCommandNode<?> literalCommandNode = this.brigadierManager
|
final LiteralCommandNode<?> literalCommandNode = this.brigadierManager
|
||||||
.createLiteralCommandNode(label, command, (o, p) -> {
|
.createLiteralCommandNode(label, command, (o, p) -> {
|
||||||
final CommandSender sender = this.commodore.getBukkitSender(o);
|
final CommandSender sender = this.commodore.getBukkitSender(o);
|
||||||
return this.commandManager.hasPermission(
|
return this.commandManager.hasPermission(this.commandManager.getCommandSenderMapper().apply(sender), p);
|
||||||
this.commandManager.getCommandSenderMapper().apply(sender),
|
}, false, o -> 1);
|
||||||
(CommandPermission) p
|
|
||||||
);
|
|
||||||
}, false, cmd);
|
|
||||||
final CommandNode existingNode = this.commodore.getDispatcher().findNode(Collections.singletonList(label));
|
final CommandNode existingNode = this.commodore.getDispatcher().findNode(Collections.singletonList(label));
|
||||||
if (existingNode != null) {
|
if (existingNode != null) {
|
||||||
this.mergeChildren(existingNode, literalCommandNode);
|
this.mergeChildren(existingNode, literalCommandNode);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2021 Alexander Söderberg & Contributors
|
||||||
|
//
|
||||||
|
// 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 cloud.commandframework.bukkit.data;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intermediary result for an argument which parses a {@link Material} and optional NBT data.
|
||||||
|
*
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public interface ProtoItemStack {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link Material} of this {@link ProtoItemStack}.
|
||||||
|
*
|
||||||
|
* @return the {@link Material}
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@NonNull Material material();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether this {@link ProtoItemStack} contains extra data besides the {@link Material}.
|
||||||
|
*
|
||||||
|
* @return whether there is extra data
|
||||||
|
*/
|
||||||
|
boolean hasExtraData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link ItemStack} from the state of this {@link ProtoItemStack}.
|
||||||
|
*
|
||||||
|
* @param stackSize stack size
|
||||||
|
* @param respectMaximumStackSize whether to respect the maximum stack size for the material
|
||||||
|
* @return the created {@link ItemStack}
|
||||||
|
* @throws IllegalArgumentException if the {@link ItemStack} could not be created, due to max stack size or other reasons
|
||||||
|
*/
|
||||||
|
@NonNull ItemStack createItemStack(int stackSize, boolean respectMaximumStackSize)
|
||||||
|
throws IllegalArgumentException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2021 Alexander Söderberg & Contributors
|
||||||
|
//
|
||||||
|
// 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-bukkit data holders
|
||||||
|
*/
|
||||||
|
package cloud.commandframework.bukkit.data;
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2021 Alexander Söderberg & Contributors
|
||||||
|
//
|
||||||
|
// 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 cloud.commandframework.bukkit.internal;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for doing reflection on CraftBukkit, used by the cloud implementation.
|
||||||
|
*
|
||||||
|
* <p>This is not API to any extent, and as such, may break, change, or be removed without any notice.</p>
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public final class CraftBukkitReflection {
|
||||||
|
|
||||||
|
private static final String PREFIX_NMS = "net.minecraft.server";
|
||||||
|
private static final String PREFIX_CRAFTBUKKIT = "org.bukkit.craftbukkit";
|
||||||
|
private static final String CRAFT_SERVER = "CraftServer";
|
||||||
|
private static final String VERSION;
|
||||||
|
public static final int MAJOR_REVISION;
|
||||||
|
|
||||||
|
static {
|
||||||
|
final Class<?> serverClass = Bukkit.getServer().getClass();
|
||||||
|
final String pkg = serverClass.getPackage().getName();
|
||||||
|
final String nmsVersion = pkg.substring(pkg.lastIndexOf(".") + 1);
|
||||||
|
if (!nmsVersion.contains("_")) {
|
||||||
|
MAJOR_REVISION = -1;
|
||||||
|
VERSION = null;
|
||||||
|
} else {
|
||||||
|
MAJOR_REVISION = Integer.parseInt(nmsVersion.split("_")[1]);
|
||||||
|
String name = serverClass.getName();
|
||||||
|
name = name.substring(PREFIX_CRAFTBUKKIT.length());
|
||||||
|
name = name.substring(0, name.length() - CRAFT_SERVER.length());
|
||||||
|
VERSION = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean craftBukkit() {
|
||||||
|
return MAJOR_REVISION != -1 && VERSION != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NonNull Class<?> needNMSClass(final @NonNull String className) throws RuntimeException {
|
||||||
|
return needClass(PREFIX_NMS + VERSION + className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NonNull Class<?> needOBCClass(final @NonNull String className) throws RuntimeException {
|
||||||
|
return needClass(PREFIX_CRAFTBUKKIT + VERSION + className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NonNull Class<?> needClass(final @NonNull String className) throws RuntimeException {
|
||||||
|
try {
|
||||||
|
return Class.forName(className);
|
||||||
|
} catch (final ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable Class<?> findClass(final @NonNull String className) {
|
||||||
|
try {
|
||||||
|
return Class.forName(className);
|
||||||
|
} catch (final ClassNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NonNull Field needField(final @NonNull Class<?> holder, final @NonNull String name) throws RuntimeException {
|
||||||
|
try {
|
||||||
|
final Field field = holder.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field;
|
||||||
|
} catch (final ReflectiveOperationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean classExists(final @NonNull String className) {
|
||||||
|
try {
|
||||||
|
Class.forName(className);
|
||||||
|
return true;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NonNull Method needMethod(
|
||||||
|
final @NonNull Class<?> holder,
|
||||||
|
final @NonNull String name,
|
||||||
|
final @NonNull Class<?>... params
|
||||||
|
) throws RuntimeException {
|
||||||
|
try {
|
||||||
|
return holder.getMethod(name, params);
|
||||||
|
} catch (final NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CraftBukkitReflection() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,331 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2021 Alexander Söderberg & Contributors
|
||||||
|
//
|
||||||
|
// 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 cloud.commandframework.bukkit.parsers;
|
||||||
|
|
||||||
|
import cloud.commandframework.ArgumentDescription;
|
||||||
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.brigadier.argument.WrappedBrigadierParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandManager;
|
||||||
|
import cloud.commandframework.bukkit.data.ProtoItemStack;
|
||||||
|
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
|
||||||
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Argument type for parsing a {@link Material} and optional extra NBT data into a {@link ProtoItemStack}.
|
||||||
|
*
|
||||||
|
* <p>This argument type only provides basic suggestions by default. On Minecraft 1.13 and newer, enabling Brigadier
|
||||||
|
* compatibility through {@link BukkitCommandManager#registerBrigadier()} will allow client side validation and
|
||||||
|
* suggestions to be utilized.</p>
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public final class ItemStackArgument<C> extends CommandArgument<C, ProtoItemStack> {
|
||||||
|
|
||||||
|
private ItemStackArgument(
|
||||||
|
final boolean required,
|
||||||
|
final @NonNull String name,
|
||||||
|
final @NonNull String defaultValue,
|
||||||
|
final @Nullable BiFunction<@NonNull CommandContext<C>, @NonNull String,
|
||||||
|
@NonNull List<@NonNull String>> suggestionsProvider,
|
||||||
|
final @NonNull ArgumentDescription defaultDescription
|
||||||
|
) {
|
||||||
|
super(required, name, new Parser<>(), defaultValue, ProtoItemStack.class, suggestionsProvider, defaultDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Builder}.
|
||||||
|
*
|
||||||
|
* @param name Name of the argument
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created builder
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static <C> ItemStackArgument.@NonNull Builder<C> builder(final @NonNull String name) {
|
||||||
|
return new ItemStackArgument.Builder<>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new required {@link ItemStackArgument}.
|
||||||
|
*
|
||||||
|
* @param name Argument name
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created argument
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static <C> @NonNull CommandArgument<C, ProtoItemStack> of(final @NonNull String name) {
|
||||||
|
return ItemStackArgument.<C>builder(name).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new optional {@link ItemStackArgument}.
|
||||||
|
*
|
||||||
|
* @param name Argument name
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Created argument
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static <C> @NonNull CommandArgument<C, ProtoItemStack> optional(final @NonNull String name) {
|
||||||
|
return ItemStackArgument.<C>builder(name).asOptional().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for {@link ItemStackArgument}.
|
||||||
|
*
|
||||||
|
* @param <C> sender type
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static final class Builder<C> extends TypedBuilder<C, ProtoItemStack, Builder<C>> {
|
||||||
|
|
||||||
|
private Builder(final @NonNull String name) {
|
||||||
|
super(ProtoItemStack.class, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ItemStackArgument<C> build() {
|
||||||
|
return new ItemStackArgument<>(
|
||||||
|
this.isRequired(),
|
||||||
|
this.getName(),
|
||||||
|
this.getDefaultValue(),
|
||||||
|
this.getSuggestionsProvider(),
|
||||||
|
this.getDefaultDescription()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for {@link ProtoItemStack}. Requires a CraftBukkit based server implementation.
|
||||||
|
*
|
||||||
|
* @param <C> sender type
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public static final class Parser<C> implements ArgumentParser<C, ProtoItemStack> {
|
||||||
|
|
||||||
|
private final ArgumentParser<C, ProtoItemStack> parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link Parser}.
|
||||||
|
*
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public Parser() {
|
||||||
|
if (!CraftBukkitReflection.craftBukkit()) {
|
||||||
|
throw new UnsupportedOperationException("ItemStack parser requires CraftBukkit");
|
||||||
|
}
|
||||||
|
if (CraftBukkitReflection.MAJOR_REVISION >= 13) {
|
||||||
|
this.parser = new ModernParser<>();
|
||||||
|
} else {
|
||||||
|
this.parser = new LegacyParser<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ArgumentParseResult<ProtoItemStack> parse(
|
||||||
|
final @NonNull CommandContext<C> commandContext,
|
||||||
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
|
) {
|
||||||
|
return this.parser.parse(commandContext, inputQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull List<@NonNull String> suggestions(
|
||||||
|
final @NonNull CommandContext<C> commandContext,
|
||||||
|
final @NonNull String input
|
||||||
|
) {
|
||||||
|
return Arrays.stream(Material.values())
|
||||||
|
.map(value -> value.name().toLowerCase(Locale.ROOT))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ModernParser<C> implements ArgumentParser<C, ProtoItemStack> {
|
||||||
|
|
||||||
|
private static final Class<?> NMS_ITEM_STACK_CLASS = CraftBukkitReflection.needNMSClass("ItemStack");
|
||||||
|
private static final Class<?> CRAFT_ITEM_STACK_CLASS =
|
||||||
|
CraftBukkitReflection.needOBCClass("inventory.CraftItemStack");
|
||||||
|
private static final Class<?> ARGUMENT_ITEM_STACK_CLASS =
|
||||||
|
CraftBukkitReflection.needNMSClass("ArgumentItemStack");
|
||||||
|
private static final Class<?> ARGUMENT_PREDICATE_ITEM_STACK_CLASS =
|
||||||
|
CraftBukkitReflection.needNMSClass("ArgumentPredicateItemStack");
|
||||||
|
private static final Class<?> NMS_ITEM_CLASS = CraftBukkitReflection.needNMSClass("Item");
|
||||||
|
private static final Class<?> CRAFT_MAGIC_NUMBERS_CLASS =
|
||||||
|
CraftBukkitReflection.needOBCClass("util.CraftMagicNumbers");
|
||||||
|
private static final Method GET_MATERIAL_METHOD = CraftBukkitReflection
|
||||||
|
.needMethod(CRAFT_MAGIC_NUMBERS_CLASS, "getMaterial", NMS_ITEM_CLASS);
|
||||||
|
private static final Method CREATE_ITEM_STACK_METHOD = CraftBukkitReflection
|
||||||
|
.needMethod(ARGUMENT_PREDICATE_ITEM_STACK_CLASS, "a", int.class, boolean.class);
|
||||||
|
private static final Method AS_BUKKIT_COPY_METHOD = CraftBukkitReflection
|
||||||
|
.needMethod(CRAFT_ITEM_STACK_CLASS, "asBukkitCopy", NMS_ITEM_STACK_CLASS);
|
||||||
|
private static final Field ITEM_FIELD = CraftBukkitReflection.needField(ARGUMENT_PREDICATE_ITEM_STACK_CLASS, "b");
|
||||||
|
private static final Field COMPOUND_TAG_FIELD = CraftBukkitReflection.needField(ARGUMENT_PREDICATE_ITEM_STACK_CLASS, "c");
|
||||||
|
|
||||||
|
private final ArgumentParser<C, ProtoItemStack> parser;
|
||||||
|
|
||||||
|
ModernParser() {
|
||||||
|
try {
|
||||||
|
this.parser = this.createParser();
|
||||||
|
} catch (final ReflectiveOperationException ex) {
|
||||||
|
throw new RuntimeException("Failed to initialize modern ItemStack parser.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private ArgumentParser<C, ProtoItemStack> createParser() throws ReflectiveOperationException {
|
||||||
|
return new WrappedBrigadierParser<C, Object>(
|
||||||
|
(ArgumentType<Object>) ARGUMENT_ITEM_STACK_CLASS.getConstructor().newInstance()
|
||||||
|
).map((ctx, itemInput) -> ArgumentParseResult.success(new ModernProtoItemStack(itemInput)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ArgumentParseResult<@NonNull ProtoItemStack> parse(
|
||||||
|
@NonNull final CommandContext<@NonNull C> commandContext,
|
||||||
|
@NonNull final Queue<@NonNull String> inputQueue
|
||||||
|
) {
|
||||||
|
// Minecraft has a parser for this - just use it
|
||||||
|
return this.parser.parse(commandContext, inputQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ModernProtoItemStack implements ProtoItemStack {
|
||||||
|
|
||||||
|
private final Object itemInput;
|
||||||
|
private final Material material;
|
||||||
|
private final @Nullable String snbt;
|
||||||
|
|
||||||
|
ModernProtoItemStack(final @NonNull Object itemInput) {
|
||||||
|
this.itemInput = itemInput;
|
||||||
|
try {
|
||||||
|
this.material = (Material) GET_MATERIAL_METHOD.invoke(null, ITEM_FIELD.get(itemInput));
|
||||||
|
final Object compoundTag = COMPOUND_TAG_FIELD.get(itemInput);
|
||||||
|
if (compoundTag != null) {
|
||||||
|
this.snbt = compoundTag.toString();
|
||||||
|
} else {
|
||||||
|
this.snbt = null;
|
||||||
|
}
|
||||||
|
} catch (final ReflectiveOperationException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull Material material() {
|
||||||
|
return this.material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasExtraData() {
|
||||||
|
return this.snbt != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ItemStack createItemStack(final int stackSize, final boolean respectMaximumStackSize) {
|
||||||
|
try {
|
||||||
|
return (ItemStack) AS_BUKKIT_COPY_METHOD.invoke(
|
||||||
|
null,
|
||||||
|
CREATE_ITEM_STACK_METHOD.invoke(this.itemInput, stackSize, respectMaximumStackSize)
|
||||||
|
);
|
||||||
|
} catch (final InvocationTargetException ex) {
|
||||||
|
final Throwable cause = ex.getCause();
|
||||||
|
if (cause instanceof CommandSyntaxException) {
|
||||||
|
throw new IllegalArgumentException(cause.getMessage(), cause);
|
||||||
|
}
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
} catch (final ReflectiveOperationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class LegacyParser<C> implements ArgumentParser<C, ProtoItemStack> {
|
||||||
|
|
||||||
|
private final ArgumentParser<C, ProtoItemStack> parser = new MaterialArgument.MaterialParser<C>()
|
||||||
|
.map((ctx, material) -> ArgumentParseResult.success(new LegacyProtoItemStack(material)));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ArgumentParseResult<@NonNull ProtoItemStack> parse(
|
||||||
|
@NonNull final CommandContext<@NonNull C> commandContext,
|
||||||
|
@NonNull final Queue<@NonNull String> inputQueue
|
||||||
|
) {
|
||||||
|
return this.parser.parse(commandContext, inputQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class LegacyProtoItemStack implements ProtoItemStack {
|
||||||
|
|
||||||
|
private final Material material;
|
||||||
|
|
||||||
|
private LegacyProtoItemStack(final @NonNull Material material) {
|
||||||
|
this.material = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull Material material() {
|
||||||
|
return this.material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasExtraData() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ItemStack createItemStack(final int stackSize, final boolean respectMaximumStackSize)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
if (respectMaximumStackSize && stackSize > this.material.getMaxStackSize()) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The maximum stack size for %s is %d",
|
||||||
|
this.material,
|
||||||
|
this.material.getMaxStackSize()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return new ItemStack(this.material, stackSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -28,12 +28,14 @@ import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.captions.CaptionVariable;
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
||||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
@ -177,6 +179,10 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
||||||
List<String> output = new ArrayList<>();
|
List<String> output = new ArrayList<>();
|
||||||
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
final CommandSender bukkit = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||||
|
if (bukkit instanceof Player && !((Player) bukkit).canSee(player)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
output.add(player.getName());
|
output.add(player.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,13 @@ import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.captions.CaptionVariable;
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
||||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
@ -169,6 +171,10 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
||||||
List<String> output = new ArrayList<>();
|
List<String> output = new ArrayList<>();
|
||||||
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
final CommandSender bukkit = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||||
|
if (bukkit instanceof Player && !((Player) bukkit).canSee(player)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
output.add(player.getName());
|
output.add(player.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import cloud.commandframework.ArgumentDescription;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.bukkit.parsers.location.LocationArgument.LocationParseException;
|
import cloud.commandframework.bukkit.parsers.location.LocationArgument.LocationParseException;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import io.leangen.geantyref.TypeToken;
|
import io.leangen.geantyref.TypeToken;
|
||||||
|
|
@ -183,7 +184,7 @@ public final class Location2DArgument<C> extends CommandArgument<C, Location2D>
|
||||||
coordinates[i] = coordinate.getParsedValue().orElseThrow(NullPointerException::new);
|
coordinates[i] = coordinate.getParsedValue().orElseThrow(NullPointerException::new);
|
||||||
}
|
}
|
||||||
final Location originalLocation;
|
final Location originalLocation;
|
||||||
final CommandSender bukkitSender = commandContext.get("BukkitCommandSender");
|
final CommandSender bukkitSender = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||||
|
|
||||||
if (bukkitSender instanceof BlockCommandSender) {
|
if (bukkitSender instanceof BlockCommandSender) {
|
||||||
originalLocation = ((BlockCommandSender) bukkitSender).getBlock().getLocation();
|
originalLocation = ((BlockCommandSender) bukkitSender).getBlock().getLocation();
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
import cloud.commandframework.arguments.standard.IntegerArgument;
|
import cloud.commandframework.arguments.standard.IntegerArgument;
|
||||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.captions.Caption;
|
import cloud.commandframework.captions.Caption;
|
||||||
import cloud.commandframework.captions.CaptionVariable;
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
|
@ -191,7 +192,7 @@ public final class LocationArgument<C> extends CommandArgument<C, Location> {
|
||||||
coordinates[i] = coordinate.getParsedValue().orElseThrow(NullPointerException::new);
|
coordinates[i] = coordinate.getParsedValue().orElseThrow(NullPointerException::new);
|
||||||
}
|
}
|
||||||
final Location originalLocation;
|
final Location originalLocation;
|
||||||
final CommandSender bukkitSender = commandContext.get("BukkitCommandSender");
|
final CommandSender bukkitSender = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||||
|
|
||||||
if (bukkitSender instanceof BlockCommandSender) {
|
if (bukkitSender instanceof BlockCommandSender) {
|
||||||
originalLocation = ((BlockCommandSender) bukkitSender).getBlock().getLocation();
|
originalLocation = ((BlockCommandSender) bukkitSender).getBlock().getLocation();
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import cloud.commandframework.ArgumentDescription;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.MultipleEntitySelector;
|
import cloud.commandframework.bukkit.arguments.selector.MultipleEntitySelector;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
|
@ -38,7 +39,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
public final class MultipleEntitySelectorArgument<C> extends CommandArgument<C, MultipleEntitySelector> {
|
public final class MultipleEntitySelectorArgument<C> extends CommandArgument<C, MultipleEntitySelector> {
|
||||||
|
|
@ -133,7 +133,7 @@ public final class MultipleEntitySelectorArgument<C> extends CommandArgument<C,
|
||||||
final @NonNull CommandContext<C> commandContext,
|
final @NonNull CommandContext<C> commandContext,
|
||||||
final @NonNull Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
if (!commandContext.<Set<CloudBukkitCapabilities>>get("CloudBukkitCapabilities").contains(
|
if (!commandContext.get(BukkitCommandContextKeys.CLOUD_BUKKIT_CAPABILITIES).contains(
|
||||||
CloudBukkitCapabilities.BRIGADIER)) {
|
CloudBukkitCapabilities.BRIGADIER)) {
|
||||||
return ArgumentParseResult.failure(new SelectorParseException(
|
return ArgumentParseResult.failure(new SelectorParseException(
|
||||||
"",
|
"",
|
||||||
|
|
@ -153,7 +153,7 @@ public final class MultipleEntitySelectorArgument<C> extends CommandArgument<C,
|
||||||
|
|
||||||
List<Entity> entities;
|
List<Entity> entities;
|
||||||
try {
|
try {
|
||||||
entities = Bukkit.selectEntities(commandContext.get("BukkitCommandSender"), input);
|
entities = Bukkit.selectEntities(commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER), input);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return ArgumentParseResult.failure(new SelectorParseException(
|
return ArgumentParseResult.failure(new SelectorParseException(
|
||||||
input,
|
input,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import cloud.commandframework.ArgumentDescription;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector;
|
import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector;
|
||||||
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
||||||
|
|
@ -34,6 +35,7 @@ import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
@ -42,7 +44,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C, MultiplePlayerSelector> {
|
public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C, MultiplePlayerSelector> {
|
||||||
|
|
@ -146,7 +147,7 @@ public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C,
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
|
|
||||||
if (!commandContext.<Set<CloudBukkitCapabilities>>get("CloudBukkitCapabilities").contains(
|
if (!commandContext.get(BukkitCommandContextKeys.CLOUD_BUKKIT_CAPABILITIES).contains(
|
||||||
CloudBukkitCapabilities.BRIGADIER)) {
|
CloudBukkitCapabilities.BRIGADIER)) {
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
Player player = Bukkit.getPlayer(input);
|
Player player = Bukkit.getPlayer(input);
|
||||||
|
|
@ -159,7 +160,7 @@ public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C,
|
||||||
|
|
||||||
List<Entity> entities;
|
List<Entity> entities;
|
||||||
try {
|
try {
|
||||||
entities = Bukkit.selectEntities(commandContext.get("BukkitCommandSender"), input);
|
entities = Bukkit.selectEntities(commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER), input);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return ArgumentParseResult.failure(new SelectorParseException(
|
return ArgumentParseResult.failure(new SelectorParseException(
|
||||||
input,
|
input,
|
||||||
|
|
@ -191,6 +192,10 @@ public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C,
|
||||||
List<String> output = new ArrayList<>();
|
List<String> output = new ArrayList<>();
|
||||||
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
final CommandSender bukkit = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||||
|
if (bukkit instanceof Player && !((Player) bukkit).canSee(player)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
output.add(player.getName());
|
output.add(player.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import cloud.commandframework.ArgumentDescription;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
|
@ -38,7 +39,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
public final class SingleEntitySelectorArgument<C> extends CommandArgument<C, SingleEntitySelector> {
|
public final class SingleEntitySelectorArgument<C> extends CommandArgument<C, SingleEntitySelector> {
|
||||||
|
|
@ -139,7 +139,7 @@ public final class SingleEntitySelectorArgument<C> extends CommandArgument<C, Si
|
||||||
final @NonNull CommandContext<C> commandContext,
|
final @NonNull CommandContext<C> commandContext,
|
||||||
final @NonNull Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
if (!commandContext.<Set<CloudBukkitCapabilities>>get("CloudBukkitCapabilities").contains(
|
if (!commandContext.get(BukkitCommandContextKeys.CLOUD_BUKKIT_CAPABILITIES).contains(
|
||||||
CloudBukkitCapabilities.BRIGADIER)) {
|
CloudBukkitCapabilities.BRIGADIER)) {
|
||||||
return ArgumentParseResult.failure(new SelectorParseException(
|
return ArgumentParseResult.failure(new SelectorParseException(
|
||||||
"",
|
"",
|
||||||
|
|
@ -159,7 +159,7 @@ public final class SingleEntitySelectorArgument<C> extends CommandArgument<C, Si
|
||||||
|
|
||||||
List<Entity> entities;
|
List<Entity> entities;
|
||||||
try {
|
try {
|
||||||
entities = Bukkit.selectEntities(commandContext.get("BukkitCommandSender"), input);
|
entities = Bukkit.selectEntities(commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER), input);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return ArgumentParseResult.failure(new SelectorParseException(
|
return ArgumentParseResult.failure(new SelectorParseException(
|
||||||
input,
|
input,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import cloud.commandframework.ArgumentDescription;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCommandContextKeys;
|
||||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
||||||
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
||||||
|
|
@ -34,6 +35,7 @@ import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
@ -42,7 +44,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, SinglePlayerSelector> {
|
public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, SinglePlayerSelector> {
|
||||||
|
|
@ -152,7 +153,7 @@ public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, Si
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
|
|
||||||
if (!commandContext.<Set<CloudBukkitCapabilities>>get("CloudBukkitCapabilities").contains(
|
if (!commandContext.get(BukkitCommandContextKeys.CLOUD_BUKKIT_CAPABILITIES).contains(
|
||||||
CloudBukkitCapabilities.BRIGADIER)) {
|
CloudBukkitCapabilities.BRIGADIER)) {
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
Player player = Bukkit.getPlayer(input);
|
Player player = Bukkit.getPlayer(input);
|
||||||
|
|
@ -165,7 +166,7 @@ public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, Si
|
||||||
|
|
||||||
List<Entity> entities;
|
List<Entity> entities;
|
||||||
try {
|
try {
|
||||||
entities = Bukkit.selectEntities(commandContext.get("BukkitCommandSender"), input);
|
entities = Bukkit.selectEntities(commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER), input);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return ArgumentParseResult.failure(new SelectorParseException(
|
return ArgumentParseResult.failure(new SelectorParseException(
|
||||||
input,
|
input,
|
||||||
|
|
@ -205,6 +206,10 @@ public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, Si
|
||||||
List<String> output = new ArrayList<>();
|
List<String> output = new ArrayList<>();
|
||||||
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
final CommandSender bukkit = commandContext.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||||
|
if (bukkit instanceof Player && !((Player) bukkit).canSee(player)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
output.add(player.getName());
|
output.add(player.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,15 +27,18 @@ import cloud.commandframework.CommandTree;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
||||||
import cloud.commandframework.bukkit.BukkitBrigadierMapper;
|
import cloud.commandframework.bukkit.BukkitBrigadierMapper;
|
||||||
|
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.permission.CommandPermission;
|
import cloud.commandframework.permission.CommandPermission;
|
||||||
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
|
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
@ -46,18 +49,30 @@ class PaperBrigadierListener<C> implements Listener {
|
||||||
|
|
||||||
PaperBrigadierListener(final @NonNull PaperCommandManager<C> paperCommandManager) {
|
PaperBrigadierListener(final @NonNull PaperCommandManager<C> paperCommandManager) {
|
||||||
this.paperCommandManager = paperCommandManager;
|
this.paperCommandManager = paperCommandManager;
|
||||||
this.brigadierManager = new CloudBrigadierManager<>(
|
this.brigadierManager = new CloudBrigadierManager<>(this.paperCommandManager, () -> new CommandContext<>(
|
||||||
this.paperCommandManager,
|
this.paperCommandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender()),
|
||||||
() -> new CommandContext<>(
|
|
||||||
this.paperCommandManager.getCommandSenderMapper()
|
|
||||||
.apply(Bukkit.getConsoleSender()),
|
|
||||||
this.paperCommandManager
|
this.paperCommandManager
|
||||||
)
|
));
|
||||||
);
|
|
||||||
this.brigadierManager.brigadierSenderMapper(
|
this.brigadierManager.brigadierSenderMapper(sender ->
|
||||||
sender -> this.paperCommandManager.getCommandSenderMapper().apply(sender.getBukkitSender())
|
this.paperCommandManager.getCommandSenderMapper().apply(sender.getBukkitSender()));
|
||||||
);
|
|
||||||
new BukkitBrigadierMapper<>(this.paperCommandManager, this.brigadierManager);
|
new BukkitBrigadierMapper<>(this.paperCommandManager, this.brigadierManager);
|
||||||
|
|
||||||
|
if (!CraftBukkitReflection.craftBukkit()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Class<?> vanillaCommandWrapperClass = CraftBukkitReflection.needOBCClass("command.VanillaCommandWrapper");
|
||||||
|
final Method getListenerMethod = CraftBukkitReflection.needMethod(
|
||||||
|
vanillaCommandWrapperClass, "getListener", CommandSender.class);
|
||||||
|
this.brigadierManager.backwardsBrigadierSenderMapper(cloud -> {
|
||||||
|
try {
|
||||||
|
return (BukkitBrigadierCommandSource) getListenerMethod
|
||||||
|
.invoke(null, this.paperCommandManager.getBackwardsCommandSenderMapper().apply(cloud));
|
||||||
|
} catch (final ReflectiveOperationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @NonNull CloudBrigadierManager<C, BukkitBrigadierCommandSource> brigadierManager() {
|
protected @NonNull CloudBrigadierManager<C, BukkitBrigadierCommandSource> brigadierManager() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue