Compare commits

...

4 Commits

Author SHA1 Message Date
Len 76ae3103de Add SpawnMobCommand.java 2024-10-04 22:48:44 +02:00
Len 434cf6ac15 Remove EnchantmentArgument.java 2024-10-04 22:46:24 +02:00
Len d786ebcff5 Add EssentiaCommandArgument 2024-10-04 22:43:32 +02:00
Len 2ef960b189 Fix commands not being loaded by reflection. 2024-10-04 21:24:18 +02:00
9 changed files with 127 additions and 69 deletions

View File

@ -58,7 +58,7 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
} }
void loadCommands() { void loadCommands() {
Reflections reflections = new Reflections("com.alttd.essentia.commands.list"); Reflections reflections = new Reflections("com.alttd.essentia.commands");
Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(EssentiaCommand.class).asClass()); Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(EssentiaCommand.class).asClass());
LifecycleEventManager<Plugin> manager = this.getLifecycleManager(); LifecycleEventManager<Plugin> manager = this.getLifecycleManager();

View File

@ -0,0 +1,41 @@
package com.alttd.essentia.commands;
import com.alttd.essentia.util.Pair;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
public interface EssentiaArgument {
default <S> CompletableFuture<Suggestions> completedFuture(SuggestionsBuilder builder, Collection<String> possibleValues) {
String remaining = builder.getRemaining().toLowerCase();
for (String str : possibleValues) {
if (str.toLowerCase().startsWith(remaining)) {
builder.suggest(StringArgumentType.escapeIfRequired(str));
}
}
return CompletableFuture.completedFuture(
builder.build()
);
}
default <S> CompletableFuture<Suggestions> completedFuturePair(SuggestionsBuilder builder, Collection<Pair<String, Message>> possibleValues) {
String remaining = builder.getRemaining().toLowerCase();
for (Pair<String, Message> pair : possibleValues) {
String str = pair.x();
if (str.toLowerCase().startsWith(remaining)) {
builder.suggest(StringArgumentType.escapeIfRequired(str), pair.y());
}
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}

View File

@ -1,7 +1,6 @@
package com.alttd.essentia.commands.admin; package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand; import com.alttd.essentia.commands.EssentiaCommand;
import com.alttd.essentia.commands.argumement.EnchantmentArgument;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
@ -9,6 +8,7 @@ import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands; import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes; import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import io.papermc.paper.registry.RegistryKey;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Material; import org.bukkit.Material;
@ -33,7 +33,7 @@ public class EnchantCommand implements EssentiaCommand {
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()) commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
) )
.then( .then(
Commands.argument("enchantment", new EnchantmentArgument()) Commands.argument("enchantment", ArgumentTypes.resource(RegistryKey.ENCHANTMENT))
.executes((source) -> { .executes((source) -> {
if (!(source.getSource().getSender() instanceof Player player)) if (!(source.getSource().getSender() instanceof Player player))
return 1; return 1;

View File

@ -0,0 +1,55 @@
package com.alttd.essentia.commands.admin;
import com.alttd.essentia.commands.EssentiaCommand;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.registry.RegistryKey;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.jetbrains.annotations.NotNull;
// TODO -- FINISH ME - messages and options?
public class SpawnMobCommand implements EssentiaCommand {
@Override
public String commandName() {
return "spawnmob";
}
@Override
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
final LiteralArgumentBuilder<CommandSourceStack> builder =
Commands.literal(commandName())
.requires(
commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission())
)
.then(
Commands.argument("entity", ArgumentTypes.resource(RegistryKey.ENTITY_TYPE))
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
.executes((source) -> {
EntityType entityType = source.getArgument("entity", EntityType.class);
execute(source.getSource().getSender(), (Player) source.getSource().getSender(), entityType);
return 1;
})
);
return builder.build();
}
public void execute(CommandSender sender, Player target, EntityType entityType) { // TODO - implement player info
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("requester", sender.name()),
Placeholder.component("target", target.displayName())
);
target.getWorld().spawn(target.getLocation(), entityType.getEntityClass(), CreatureSpawnEvent.SpawnReason.COMMAND);
}
}

View File

@ -1,51 +0,0 @@
package com.alttd.essentia.commands.argumement;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class EnchantmentArgument implements CustomArgumentType.Converted<Enchantment, String> {
@Override
public @NotNull Enchantment convert(String nativeType) throws CommandSyntaxException {
try {
return Enchantment.getByKey(NamespacedKey.minecraft(nativeType));
} catch (Exception e) {
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid enchantment %s!".formatted(nativeType), NamedTextColor.RED));
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
}
}
@Override
public @NotNull ArgumentType<String> getNativeType() {
return StringArgumentType.word();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
for (Enchantment enchantment : RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT)) {
builder.suggest(enchantment.getKey().value());
}
return CompletableFuture.completedFuture(
builder.build()
);
}
}

View File

@ -1,5 +1,6 @@
package com.alttd.essentia.commands.argumement; package com.alttd.essentia.commands.argumement;
import com.alttd.essentia.commands.EssentiaArgument;
import com.mojang.brigadier.Message; import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
@ -15,9 +16,11 @@ import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class EquipmentArgumentType implements CustomArgumentType.Converted<EquipmentSlot, String> { public class EquipmentArgumentType implements CustomArgumentType.Converted<EquipmentSlot, String>, EssentiaArgument {
@Override @Override
public @NotNull EquipmentSlot convert(String nativeType) throws CommandSyntaxException { public @NotNull EquipmentSlot convert(String nativeType) throws CommandSyntaxException {
@ -37,13 +40,12 @@ public class EquipmentArgumentType implements CustomArgumentType.Converted<Equip
@Override @Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
Collection<String> possibleValues = new ArrayList<>();
for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) { for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
builder.suggest(equipmentSlot.name().toLowerCase()); possibleValues.add(equipmentSlot.name().toLowerCase());
} }
return CompletableFuture.completedFuture( return completedFuture(builder, possibleValues);
builder.build()
);
} }
} }

View File

@ -1,11 +1,14 @@
package com.alttd.essentia.commands.argumement; package com.alttd.essentia.commands.argumement;
import com.alttd.essentia.commands.EssentiaArgument;
import com.alttd.essentia.util.Pair;
import com.mojang.brigadier.Message; import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.MessageComponentSerializer; import io.papermc.paper.command.brigadier.MessageComponentSerializer;
@ -17,9 +20,11 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class OfflinePlayerCompletingArgument implements CustomArgumentType.Converted<OfflinePlayer, String> { public class OfflinePlayerCompletingArgument implements CustomArgumentType.Converted<OfflinePlayer, String>, EssentiaArgument {
@Override @Override
public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException { public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException {
@ -39,12 +44,11 @@ public class OfflinePlayerCompletingArgument implements CustomArgumentType.Conve
@Override @Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
Collection<Pair<String, Message>> possibleValues = new ArrayList<>();
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
builder.suggest(player.getName(), MessageComponentSerializer.message().serialize(player.displayName())); possibleValues.add(new Pair<>(player.getName(), MessageComponentSerializer.message().serialize(player.displayName())));
} }
return CompletableFuture.completedFuture( return completedFuturePair(builder, possibleValues);
builder.build()
);
} }
} }

View File

@ -1,5 +1,6 @@
package com.alttd.essentia.commands.argumement; package com.alttd.essentia.commands.argumement;
import com.alttd.essentia.commands.EssentiaArgument;
import com.mojang.brigadier.Message; import com.mojang.brigadier.Message;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
@ -15,9 +16,11 @@ import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.WeatherType; import org.bukkit.WeatherType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class WeatherArgument implements CustomArgumentType.Converted<WeatherType, String> { public class WeatherArgument implements CustomArgumentType.Converted<WeatherType, String>, EssentiaArgument {
@Override @Override
public @NotNull WeatherType convert(String nativeType) throws CommandSyntaxException { public @NotNull WeatherType convert(String nativeType) throws CommandSyntaxException {
@ -37,12 +40,11 @@ public class WeatherArgument implements CustomArgumentType.Converted<WeatherType
@Override @Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
Collection<String> possibleValues = new ArrayList<>();
for (WeatherType weatherType : WeatherType.values()) { for (WeatherType weatherType : WeatherType.values()) {
builder.suggest(weatherType.name().toLowerCase()); possibleValues.add(weatherType.name().toLowerCase());
} }
return CompletableFuture.completedFuture( return completedFuture(builder, possibleValues);
builder.build()
);
} }
} }

View File

@ -0,0 +1,5 @@
package com.alttd.essentia.util;
public record Pair<X, Y>(X x, Y y) {
}