Merge pull request #43

*  Add a new caption system to allow for the configuration of…

*  Add caption support to all numerical types

* Add more standard pasres to the registry

* Add default messages for captions

*  Improve captions in core

* Add captions for Bukkit

*  Add FactoryDelegatingCaptionRegistry.java
This commit is contained in:
Alexander Söderberg 2020-10-12 18:13:23 +02:00 committed by GitHub
parent 378d57964f
commit 6ab1c8a2e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 1482 additions and 200 deletions

View file

@ -0,0 +1,78 @@
//
// MIT License
//
// Copyright (c) 2020 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.captions.Caption;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
/**
* {@link Caption} instances for messages in cloud-bukkit
*/
public final class BukkitCaptionKeys {
private static final Collection<Caption> RECOGNIZED_CAPTIONS = new LinkedList<>();
/**
* Variables: {input}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_ENCHANTMENT = of("argument.parse.failure.enchantment");
/**
* Variables: {input}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_MATERIAL = of("argument.parse.failure.material");
/**
* Variables: {input}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER = of("argument.parse.failure.offlineplayer");
/**
* Variables: {input}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_PLAYER = of("argument.parse.failure.player");
/**
* Variables: {input}
*/
public static final Caption ARGUMENT_PARSE_FAILURE_WORLD = of("argument.parse.failure.world");
private BukkitCaptionKeys() {
}
private static @NonNull Caption of(final @NonNull String key) {
final Caption caption = Caption.of(key);
RECOGNIZED_CAPTIONS.add(caption);
return caption;
}
/**
* Get an immutable collection containing all standard caption keys
*
* @return Immutable collection of keys
*/
public static @NonNull Collection<@NonNull Caption> getBukkitCaptionKeys() {
return Collections.unmodifiableCollection(RECOGNIZED_CAPTIONS);
}
}

View file

@ -0,0 +1,80 @@
//
// MIT License
//
// Copyright (c) 2020 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.captions.SimpleCaptionRegistry;
/**
* Caption registry that uses bi-functions to produce messages
*
* @param <C> Command sender type
*/
public class BukkitCaptionRegistry<C> extends SimpleCaptionRegistry<C> {
/**
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
*/
public static final String ARGUMENT_PARSE_FAILURE_ENCHANTMENT = "'{input}' is not a valid enchantment";
/**
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
*/
public static final String ARGUMENT_PARSE_FAILURE_MATERIAL = "'{input}' is not a valid material name";
/**
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
*/
public static final String ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER = "No player found for input '{input}'";
/**
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
*/
public static final String ARGUMENT_PARSE_FAILURE_PLAYER = "No player found for input '{input}'";
/**
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
*/
public static final String ARGUMENT_PARSE_FAILURE_WORLD = "'{input}' is not a valid Minecraft world";
protected BukkitCaptionRegistry() {
super();
this.registerMessageFactory(
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_ENCHANTMENT,
(caption, sender) -> ARGUMENT_PARSE_FAILURE_ENCHANTMENT
);
this.registerMessageFactory(
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_MATERIAL,
(caption, sender) -> ARGUMENT_PARSE_FAILURE_MATERIAL
);
this.registerMessageFactory(
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER,
(caption, sender) -> ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER
);
this.registerMessageFactory(
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER,
(caption, sender) -> ARGUMENT_PARSE_FAILURE_PLAYER
);
this.registerMessageFactory(
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_WORLD,
(caption, sender) -> ARGUMENT_PARSE_FAILURE_WORLD
);
}
}

View file

@ -0,0 +1,44 @@
//
// MIT License
//
// Copyright (c) 2020 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 org.checkerframework.checker.nullness.qual.NonNull;
/**
* Factory creating {@link BukkitCaptionRegistry} instances
*
* @param <C> Command sender type
*/
public final class BukkitCaptionRegistryFactory<C> {
/**
* Create a new bukkit caption registry instance
*
* @return Created instance
*/
public @NonNull BukkitCaptionRegistry<C> create() {
return new BukkitCaptionRegistry<>();
}
}

View file

@ -162,6 +162,8 @@ public class BukkitCommandManager<C> extends CommandManager<C> {
new CommandSuggestionsListener<>(this),
this.owningPlugin
);
this.registerDefaultCaptions(new BukkitCaptionRegistryFactory<C>().create());
}
/**

View file

@ -54,7 +54,10 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
this.commandManager = commandManager;
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
this.brigadierManager = new CloudBrigadierManager<>(commandManager, () ->
new CommandContext<>(commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender())));
new CommandContext<>(
commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender()),
commandManager.getCaptionRegistry()
));
new BukkitBrigadierMapper<>(this.commandManager, this.brigadierManager);
}

View file

@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.bukkit.BukkitCaptionKeys;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.ParserException;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -143,7 +146,7 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
final Enchantment enchantment = Enchantment.getByKey(key);
if (enchantment == null) {
return ArgumentParseResult.failure(new EnchantmentParseException(input));
return ArgumentParseResult.failure(new EnchantmentParseException(input, commandContext));
}
inputQueue.remove();
return ArgumentParseResult.success(enchantment);
@ -168,16 +171,26 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
}
public static final class EnchantmentParseException extends IllegalArgumentException {
public static final class EnchantmentParseException extends ParserException {
private final String input;
/**
* Construct a new EnchantmentParseException
*
* @param input Input
* @param input Input
* @param context Command context
*/
public EnchantmentParseException(final @NonNull String input) {
public EnchantmentParseException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
EnchantmentParser.class,
context,
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_ENCHANTMENT,
CaptionVariable.of("input", input)
);
this.input = input;
}
@ -190,11 +203,6 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
return this.input;
}
@Override
public String getMessage() {
return String.format("'%s' is not a valid enchantment", this.input);
}
}
}

View file

@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.bukkit.BukkitCaptionKeys;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.ParserException;
import org.bukkit.Material;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -136,7 +139,7 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
inputQueue.remove();
return ArgumentParseResult.success(material);
} catch (final IllegalArgumentException exception) {
return ArgumentParseResult.failure(new MaterialParseException(input));
return ArgumentParseResult.failure(new MaterialParseException(input, commandContext));
}
}
@ -155,16 +158,26 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
}
public static final class MaterialParseException extends IllegalArgumentException {
public static final class MaterialParseException extends ParserException {
private final String input;
/**
* Construct a new MaterialParseException
*
* @param input Input
* @param input Input
* @param context Command context
*/
public MaterialParseException(final @NonNull String input) {
public MaterialParseException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
MaterialParser.class,
context,
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_MATERIAL,
CaptionVariable.of("input", input)
);
this.input = input;
}
@ -177,11 +190,6 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
return this.input;
}
@Override
public String getMessage() {
return String.format("'%s' is not a valid material name", this.input);
}
}
}

View file

@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.bukkit.BukkitCaptionKeys;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.ParserException;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
@ -146,7 +149,7 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
OfflinePlayer player = Bukkit.getOfflinePlayer(input);
if (player == null || (!player.hasPlayedBefore() && !player.isOnline())) {
return ArgumentParseResult.failure(new OfflinePlayerParseException(input));
return ArgumentParseResult.failure(new OfflinePlayerParseException(input, commandContext));
}
return ArgumentParseResult.success(player);
@ -172,16 +175,26 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
/**
* OfflinePlayer parse exception
*/
public static final class OfflinePlayerParseException extends IllegalArgumentException {
public static final class OfflinePlayerParseException extends ParserException {
private final String input;
/**
* Construct a new OfflinePlayer parse exception
*
* @param input String input
* @param input String input
* @param context Command context
*/
public OfflinePlayerParseException(final @NonNull String input) {
public OfflinePlayerParseException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
OfflinePlayerParser.class,
context,
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER,
CaptionVariable.of("input", input)
);
this.input = input;
}
@ -194,11 +207,6 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
return input;
}
@Override
public String getMessage() {
return String.format("No player found for input '%s'.", input);
}
}
}

View file

@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.bukkit.BukkitCaptionKeys;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.ParserException;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -140,7 +143,7 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
Player player = Bukkit.getPlayer(input);
if (player == null) {
return ArgumentParseResult.failure(new PlayerParseException(input));
return ArgumentParseResult.failure(new PlayerParseException(input, commandContext));
}
return ArgumentParseResult.success(player);
@ -166,16 +169,26 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
/**
* Player parse exception
*/
public static final class PlayerParseException extends IllegalArgumentException {
public static final class PlayerParseException extends ParserException {
private final String input;
/**
* Construct a new Player parse exception
*
* @param input String input
* @param input String input
* @param context Command context
*/
public PlayerParseException(final @NonNull String input) {
public PlayerParseException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
PlayerParser.class,
context,
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER,
CaptionVariable.of("input", input)
);
this.input = input;
}
@ -188,11 +201,6 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
return input;
}
@Override
public String getMessage() {
return String.format("No player found for input '%s'.", input);
}
}
}

View file

@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.bukkit.BukkitCaptionKeys;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.ParserException;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -130,7 +133,7 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
final World world = Bukkit.getWorld(input);
if (world == null) {
return ArgumentParseResult.failure(new WorldParseException(input));
return ArgumentParseResult.failure(new WorldParseException(input, commandContext));
}
inputQueue.remove();
@ -145,16 +148,26 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
}
public static final class WorldParseException extends IllegalArgumentException {
public static final class WorldParseException extends ParserException {
private final String input;
/**
* Construct a new WorldParseException
*
* @param input Input
* @param input Input
* @param context Command context
*/
public WorldParseException(final @NonNull String input) {
public WorldParseException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
WorldParser.class,
context,
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_WORLD,
CaptionVariable.of("input", input)
);
this.input = input;
}
@ -167,11 +180,6 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
return this.input;
}
@Override
public String getMessage() {
return String.format("'%s' is not a valid Minecraft world", this.input);
}
}
}

View file

@ -146,7 +146,7 @@ public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C,
Player player = Bukkit.getPlayer(input);
if (player == null) {
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input));
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input, commandContext));
}
return ArgumentParseResult.success(new MultiplePlayerSelector(input, ImmutableList.of(player)));
}

View file

@ -144,7 +144,7 @@ public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, Si
Player player = Bukkit.getPlayer(input);
if (player == null) {
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input));
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input, commandContext));
}
return ArgumentParseResult.success(new SinglePlayerSelector(input, ImmutableList.of(player)));
}