Skip to content

Commit

Permalink
misc: Initial work on parsing property map
Browse files Browse the repository at this point in the history
  • Loading branch information
MATRIX-feather committed Dec 29, 2024
1 parent b0c67b5 commit ae4f40a
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 11 deletions.
35 changes: 24 additions & 11 deletions src/main/java/xyz/nifeather/morph/commands/MorphCommand.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
package xyz.nifeather.morph.commands;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.arguments.ResourceLocationArgument;
import net.minecraft.commands.synchronization.SuggestionProviders;
import net.minecraft.resources.ResourceLocation;
import org.bukkit.Bukkit;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import xiamomc.pluginbase.Annotations.Resolved;
import xiamomc.pluginbase.Messages.FormattableMessage;
import xyz.nifeather.morph.MorphManager;
import xyz.nifeather.morph.MorphPluginObject;
import xyz.nifeather.morph.commands.brigadier.IConvertibleBrigadier;
import xyz.nifeather.morph.commands.brigadier.arguments.ValueMapArgumentType;
import xyz.nifeather.morph.messages.HelpStrings;
import xyz.nifeather.morph.messages.MessageUtils;
import xyz.nifeather.morph.messages.MorphStrings;
import xyz.nifeather.morph.misc.DisguiseMeta;
import xyz.nifeather.morph.misc.gui.DisguiseSelectScreenWrapper;

import java.util.concurrent.CompletableFuture;
import java.util.function.IntFunction;

@SuppressWarnings("UnstableApiUsage")
public class MorphCommand extends MorphPluginObject implements IConvertibleBrigadier
{
@Resolved
Expand All @@ -51,15 +48,31 @@ public boolean register(Commands dispatcher)
.requires(this::checkPermission)
.executes(this::executeNoArg)
.then(
Commands.argument("id", ResourceLocationArgument.id())
Commands.argument("id", ArgumentTypes.key())
.suggests(this::suggestID)
.executes(this::execWithID)
//.then(
// Commands.argument("properties", new ValueMapArgumentType())
// .executes(this::execExperimental)
//)
)
.build());

return true;
}

private int execExperimental(CommandContext<CommandSourceStack> context)
{
var input = ValueMapArgumentType.get("properties", context);

input.forEach((k, v) ->
{
context.getSource().getSender().sendMessage("Key '%s', Value '%s'".formatted(k, v));
});

return 1;
}

public @NotNull CompletableFuture<Suggestions> suggestID(CommandContext<CommandSourceStack> context, SuggestionsBuilder suggestionsBuilder)
{
var source = context.getSource().getExecutor();
Expand Down Expand Up @@ -123,7 +136,7 @@ private int execWithID(CommandContext<CommandSourceStack> context)
return Command.SINGLE_SUCCESS;
}

String inputID = context.getArgument("id", ResourceLocation.class).toString();
String inputID = context.getArgument("id", Key.class).toString();
morphManager.morph(sender, player, inputID, player.getTargetEntity(5));

return 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package xyz.nifeather.morph.commands.brigadier.arguments;

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.exceptions.SimpleCommandExceptionType;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import xyz.nifeather.morph.FeatherMorphMain;

import java.util.Collection;
import java.util.Map;

@SuppressWarnings("UnstableApiUsage")
public class ValueMapArgumentType implements CustomArgumentType<Map<String, String>, String>
{
public static final Collection<String> EXAMPLES = ObjectArrayList.of("[foo=bar]", "[foo=bar, aabb=\"ccdd\"]");
private static final Logger log = FeatherMorphMain.getInstance().getSLF4JLogger();
private static final Map<String, String> defaultMap = new Object2ObjectOpenHashMap<>();

public static Map<String, String> get(String name, CommandContext<CommandSourceStack> context)
{
return context.getArgument(name, defaultMap.getClass());
}

@Override
public Map<String, String> parse(StringReader reader) throws CommandSyntaxException
{
if (reader.peek() != '[')
throw new SimpleCommandExceptionType(Component.translatable("Expected square bracket to start a string")).createWithContext(reader);

if (!reader.getString().endsWith("]"))
throw new SimpleCommandExceptionType(Component.literal("Unclosed bracket string")).createWithContext(reader);

reader.skip();

Map<String, String> map = new Object2ObjectOpenHashMap<>();

while (reader.canRead())
{
var subString = readStringQuotableUntil(reader, ',');

if (subString == null) continue;

String[] split = subString.split("=", 2);
String key = split[0];
String value = split.length > 1 ? split[1] : null;

if (value != null)
map.put(key, value);
}

return map;
}

/**
* @return A string, NULL if the input equals 'terminator'
* @throws CommandSyntaxException
*/
@Nullable
public String readStringQuotableUntil(StringReader reader, char terminator) throws CommandSyntaxException
{
//log.info("Starting read... Peek is '%s'".formatted(reader.peek()));
StringBuilder builder = new StringBuilder();

while (true)
{
if (!reader.canRead())
break;

char current = reader.read();
//log.info("Current: '%s'".formatted(current));

// 遇到了结束符
if (current == terminator)
break;

// 遇到引号了
if (StringReader.isQuotedStringStart(current))
{
var str = reader.readStringUntil(current);

//log.info("APPENDING QUOTE STRING [%s]".formatted(str));
builder.append(str);
continue;
}

// 如果遇到了闭合括号,break;
if (current == ']')
break;

// 是空格
if (Character.isWhitespace(current))
continue;

// 其他情况
//log.info("APPENDING [%s]".formatted(current));
builder.append(current);
}

//log.info("DONE! result is [%s]".formatted(builder.toString()));
return builder.isEmpty() ? null : builder.toString();
}

@Override
@NotNull
public ArgumentType<String> getNativeType()
{
return StringArgumentType.greedyString();
}

@Override
@NotNull
public Collection<String> getExamples()
{
return EXAMPLES;
}
}

0 comments on commit ae4f40a

Please sign in to comment.