mirror of
https://github.com/YouHaveTrouble/BlockEdit.git
synced 2026-06-29 13:36:19 +00:00
proper argument aprsing and completion for registered providers
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package me.youhavetrouble.blockedit;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@@ -14,32 +14,44 @@ public class BELocale {
|
||||
|
||||
public final String couldNotFindWandById, selectArea, copiedSelectionToClipboard, selectionReset, firstPositionSet,
|
||||
secondPositionSet, pastingClipboard, clipboardRotated, settingBlocks, replacingBlocks, schematicLoaded,
|
||||
startedLoadingSchematic, noProviderForSchematicFileExtension, schematicLoadError, schematicNotFound;
|
||||
startedLoadingSchematic, noProviderForSchematicFileExtension, schematicLoadError, schematicNotFound,
|
||||
providerNotFound;
|
||||
|
||||
|
||||
protected BELocale(JsonObject json) {
|
||||
couldNotFindWandById = json.get("could_not_find_wand_by_id").getAsString();
|
||||
selectArea = json.get("select_area").getAsString();
|
||||
copiedSelectionToClipboard = json.get("copied_selection_to_clipboard").getAsString();
|
||||
selectionReset = json.get("selection_reset").getAsString();
|
||||
firstPositionSet = json.get("first_position_set").getAsString();
|
||||
secondPositionSet = json.get("second_position_set").getAsString();
|
||||
pastingClipboard = json.get("pasting_clipboard").getAsString();
|
||||
clipboardRotated = json.get("clipboard_rotated").getAsString();
|
||||
settingBlocks = json.get("setting_blocks").getAsString();
|
||||
replacingBlocks = json.get("replacing_blocks").getAsString();
|
||||
startedLoadingSchematic = json.get("started_loading_schematic").getAsString();
|
||||
schematicLoaded = json.get("schematic_loaded").getAsString();
|
||||
noProviderForSchematicFileExtension = json.get("no_provider_for_schematic_file_extension").getAsString();
|
||||
schematicLoadError = json.get("schematic_load_error").getAsString();
|
||||
schematicNotFound = json.get("schematic_not_found").getAsString();
|
||||
couldNotFindWandById = getString(json, "could_not_find_wand_by_id");
|
||||
selectArea = getString(json, "select_area");
|
||||
copiedSelectionToClipboard = getString(json, "copied_selection_to_clipboard");
|
||||
selectionReset = getString(json, "selection_reset");
|
||||
firstPositionSet = getString(json, "first_position_set");
|
||||
secondPositionSet = getString(json, "second_position_set");
|
||||
pastingClipboard = getString(json, "pasting_clipboard");
|
||||
clipboardRotated = getString(json, "clipboard_rotated");
|
||||
settingBlocks = getString(json, "setting_blocks");
|
||||
replacingBlocks = getString(json, "replacing_blocks");
|
||||
startedLoadingSchematic = getString(json, "started_loading_schematic");
|
||||
schematicLoaded = getString(json, "schematic_loaded");
|
||||
noProviderForSchematicFileExtension = getString(json, "no_provider_for_schematic_file_extension");
|
||||
schematicLoadError = getString(json, "schematic_load_error");
|
||||
schematicNotFound = getString(json, "schematic_not_found");
|
||||
providerNotFound = getString(json, "provider_not_found");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getString(JsonObject jsonObject, String key) {
|
||||
if (jsonObject.has(key)) {
|
||||
return jsonObject.get(key).getAsString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static void registerLocale(Locale locale, BELocale blockEditLocale) {
|
||||
locales.put(locale, blockEditLocale);
|
||||
}
|
||||
|
||||
public static BELocale getLocale(@NotNull Locale locale) {
|
||||
public static BELocale getLocale(@Nullable Locale locale) {
|
||||
if (locale == null) return locales.get(defaultLocale);
|
||||
BELocale beLocale = locales.get(locale);
|
||||
if (beLocale == null) beLocale = locales.get(defaultLocale);
|
||||
return beLocale;
|
||||
|
||||
@@ -12,12 +12,13 @@ import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolv
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||
import me.youhavetrouble.blockedit.api.BlockEditAPI;
|
||||
import me.youhavetrouble.blockedit.exception.NoProviderForSchematicFileExtensionException;
|
||||
import me.youhavetrouble.blockedit.commands.arguments.SchematicProviderArgument;
|
||||
import me.youhavetrouble.blockedit.exception.SchematicLoadException;
|
||||
import me.youhavetrouble.blockedit.operations.PasteOperation;
|
||||
import me.youhavetrouble.blockedit.operations.ReplaceOperation;
|
||||
import me.youhavetrouble.blockedit.operations.SetOperation;
|
||||
import me.youhavetrouble.blockedit.schematic.Schematic;
|
||||
import me.youhavetrouble.blockedit.schematic.SchematicProvider;
|
||||
import me.youhavetrouble.blockedit.util.Selection;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
@@ -28,6 +29,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -85,6 +87,11 @@ public class BlockEditCommands {
|
||||
"Replaces the specified block with another block"
|
||||
);
|
||||
|
||||
commands.register(
|
||||
schematicCommand(),
|
||||
"Loads a schematic"
|
||||
);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -389,26 +396,63 @@ public class BlockEditCommands {
|
||||
.requires(commandSourceStack -> {
|
||||
if (!(commandSourceStack.getSender() instanceof Player player))
|
||||
return false;
|
||||
return player.hasPermission("blockedit.command.schematic.load.file");
|
||||
return player.hasPermission("blockedit.command.schematic.load");
|
||||
})
|
||||
.executes(context -> {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
Player player = (Player) context.getSource().getSender();
|
||||
String schematicName = context.getArgument("schematic_name", String.class);
|
||||
loadSchematic(
|
||||
player,
|
||||
null, // file provider
|
||||
context.getArgument("schematic_name", String.class)
|
||||
);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
)
|
||||
)
|
||||
.then(Commands.argument("provider_name", new SchematicProviderArgument(BlockEdit.getSchematicHandler()))
|
||||
.then(Commands.argument("schematic_name", StringArgumentType.word())
|
||||
.requires(commandSourceStack -> {
|
||||
if (!(commandSourceStack.getSender() instanceof Player player))
|
||||
return false;
|
||||
return player.hasPermission("blockedit.command.schematic.load");
|
||||
})
|
||||
.executes(context -> {
|
||||
Player player = (Player) context.getSource().getSender();
|
||||
loadSchematic(
|
||||
player,
|
||||
context.getArgument("provider_name", SchematicProvider.class),
|
||||
context.getArgument("schematic_name", String.class)
|
||||
);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static void loadSchematic(@NotNull Player player, @Nullable SchematicProvider<?> provider, @NotNull String schematicName) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
player.sendMessage(Component.text(BELocale.getLocale(player.locale()).startedLoadingSchematic.formatted(schematicName), NamedTextColor.GRAY));
|
||||
|
||||
Schematic schematic;
|
||||
|
||||
if (provider == null) {
|
||||
try {
|
||||
schematic = BlockEditAPI.getSchematicHandler().loadSchematic(schematicName);
|
||||
} catch (NoProviderForSchematicFileExtensionException e) {
|
||||
player.sendMessage(Component.text(BELocale.getLocale(player.locale()).noProviderForSchematicFileExtension.formatted(e.getExtension()), NamedTextColor.RED));
|
||||
return;
|
||||
} catch (SchematicLoadException e) {
|
||||
player.sendMessage(Component.text(BELocale.getLocale(player.locale()).schematicLoadError.formatted(schematicName), NamedTextColor.RED));
|
||||
BlockEdit.getPlugin().getSLF4JLogger().error("Could not load schematic {} due to provider error ", schematicName, e);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
schematic = provider.load(schematicName);
|
||||
} catch (SchematicLoadException e) {
|
||||
player.sendMessage(Component.text(BELocale.getLocale(player.locale()).schematicLoadError.formatted(schematicName), NamedTextColor.RED));
|
||||
BlockEdit.getPlugin().getSLF4JLogger().error("Could not load schematic {} due to provider error ", schematicName, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (schematic == null) {
|
||||
player.sendMessage(Component.text(BELocale.getLocale(player.locale()).schematicNotFound.formatted(schematicName), NamedTextColor.RED));
|
||||
@@ -419,13 +463,6 @@ public class BlockEditCommands {
|
||||
bePlayer.setClipboard(schematic.asClipboard());
|
||||
player.sendMessage(Component.text(BELocale.getLocale(player.locale()).schematicLoaded.formatted(schematicName), NamedTextColor.GRAY));
|
||||
});
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -39,6 +40,14 @@ public class SchematicHandler<S extends Schematic> {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getSchematicProvidersList() {
|
||||
return schematicProvidersByName.keySet();
|
||||
}
|
||||
|
||||
public SchematicProvider<? extends Schematic> getSchematicProviderByName(String name) {
|
||||
return schematicProvidersByName.get(name);
|
||||
}
|
||||
|
||||
public void registerSchematicProvider(
|
||||
@NotNull SchematicProvider<S> schematicProvider
|
||||
) throws SchematicHandlerRegistrationException {
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package me.youhavetrouble.blockedit.commands.arguments;
|
||||
|
||||
import com.mojang.brigadier.LiteralMessage;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
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.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
|
||||
import me.youhavetrouble.blockedit.SchematicHandler;
|
||||
import me.youhavetrouble.blockedit.commands.exceptiontype.UnknownProviderExceptionType;
|
||||
import me.youhavetrouble.blockedit.schematic.Schematic;
|
||||
import me.youhavetrouble.blockedit.schematic.SchematicProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class SchematicProviderArgument implements CustomArgumentType<SchematicProvider<? extends Schematic>, String> {
|
||||
|
||||
private final SchematicHandler<?> schematicHandler;
|
||||
|
||||
public SchematicProviderArgument(@NotNull SchematicHandler<?> schematicHandler) {
|
||||
this.schematicHandler = schematicHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull SchematicProvider<? extends Schematic> parse(StringReader reader) throws CommandSyntaxException {
|
||||
int cursor = reader.getCursor();
|
||||
String arg = reader.getString().toLowerCase(Locale.ENGLISH);
|
||||
|
||||
if (!this.schematicHandler.getSchematicProvidersList().contains(arg)) {
|
||||
throw new CommandSyntaxException(
|
||||
new UnknownProviderExceptionType(),
|
||||
new LiteralMessage("Provider not found"),
|
||||
arg,
|
||||
cursor
|
||||
);
|
||||
}
|
||||
|
||||
return schematicHandler.getSchematicProviderByName(arg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArgumentType<String> getNativeType() {
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> @NotNull CompletableFuture<Suggestions> listSuggestions(@NotNull CommandContext<S> context, @NotNull SuggestionsBuilder builder) {
|
||||
for (String providerName : schematicHandler.getSchematicProvidersList()) {
|
||||
if (!providerName.startsWith(builder.getRemaining())) continue;
|
||||
builder.suggest(providerName);
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package me.youhavetrouble.blockedit.commands.exceptiontype;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandExceptionType;
|
||||
|
||||
public class UnknownProviderExceptionType implements CommandExceptionType {
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
"replacing_blocks": "Replacing blocks...",
|
||||
"started_loading_schematic": "Started loading schematic %s",
|
||||
"schematic_loaded": "Loaded schematic %s",
|
||||
"provider_not_found": "Provider not found",
|
||||
"no_provider_for_schematic_file": "No provider for schematic file type %s",
|
||||
"schematic_load_error": "Error loading schematic %s: %s",
|
||||
"schematic_not_found": "Schematic %s not found"
|
||||
|
||||
@@ -8,5 +8,11 @@
|
||||
"pasting_clipboard": "Wklejanie ze schowka...",
|
||||
"clipboard_rotated": "Schowek obrócony o %s stopni",
|
||||
"setting_blocks": "Ustawianie bloków...",
|
||||
"replacing_blocks": "Zastępowanie bloków..."
|
||||
"replacing_blocks": "Zastępowanie bloków...",
|
||||
"started_loading_schematic": "Rozpoczęto ładowanie schematu %s",
|
||||
"schematic_loaded": "Załadowano schemat %s",
|
||||
"provider_not_found": "Nie znaleziono dostawcy",
|
||||
"no_provider_for_schematic_file": "Nie znaleziono dostawcy dla typu pliku %s",
|
||||
"schematic_load_error": "Błąd podczas ładowania schematu %s: %s",
|
||||
"schematic_not_found": "Nie znaleziono schematu %s"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user