8000 Allow developers to control Arguments' CommandSyntaxExceptions by willkroboth · Pull Request #370 · CommandAPI/CommandAPI · GitHub
[go: up one dir, main page]

Skip to content

Allow developers to control Arguments' CommandSyntaxExceptions #370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 86 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
db13e38
Add option to add custom error handling when Argument parse fails
willkroboth Nov 19, 2022
dc89c3a
Merge pull request #366 from willkroboth/dev/dev
willkroboth Nov 19, 2022
25b975d
Add Javadocs to new methods and classes
willkroboth Nov 19, 2022
e601e74
Add sender and input to ArgumentParseExceptionContext
willkroboth Nov 20, 2022
c07603a
Intercept errors during Brigadier's initial parse
willkroboth Nov 20, 2022
66c3284
Attempt serializing custom ArgumentType
willkroboth Nov 25, 2022
6aab75d
Fix ExceptionHandlingArgumentType serialization
willkroboth Nov 26, 2022
17fa93f
Clean up code and add API methods
willkroboth Nov 26, 2022
06aca10
Add InitialParseExceptionArgument to testing arguments
willkroboth Nov 26, 2022
6190486
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Nov 26, 2022
417fccb
Implement InitialParseExceptionArgument for other applicable arguments
willkroboth Nov 26, 2022
bd5fbf8
Reduce code duplication by storing InitialParseExceptionHandlers in a…
willkroboth Nov 26, 2022
d591895
Implement NMS#registerCustomArgumentType
willkroboth Nov 26, 2022
c2de33a
Clean up code
willkroboth Nov 27, 2022
cfc1be4
Make CodeFactor happier (and me a little) by reordering methods in th…
willkroboth Nov 27, 2022
ad65892
Fix 1.16.2-3 & 1.16.4-5 ExceptionHandlingArgumentSerializer method re…
willkroboth Nov 27, 2022
fea28da
Fix 1.13-1.16 method reflection
willkroboth Nov 27, 2022
84e0f39
Make GitHub Actions check NMS Common builds on all versions it is sup…
willkroboth Nov 27, 2022
6fde891
Merge remote-tracking branch 'origin/dev/argument-exceptions' into de…
willkroboth Nov 27, 2022
15f2b3a
Fix 1.17 registerCustomArgumentType
willkroboth Nov 27, 2022
537cf5a
Fix 1.18 registerCustomArgumentType
willkroboth Nov 27, 2022
e5cc28b
Remove unused (and sometimes invalid) imports from NMS_Common
willkroboth Nov 27, 2022
b25b3cd
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Nov 28, 2022
eab3466
Clean up after merge
willkroboth Nov 28, 2022
f5bef67
Add WrapperStringReader to InitialParseExceptionContext
willkroboth Dec 2, 2022
5e1f02d
Add sender, input, and previousArguments to ArgumentParseExceptionCon…
willkroboth Dec 3, 2022
597d609
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Dec 4, 2022
c68c450
Clean up imports after merging
willkroboth Dec 4, 2022
f48dc47
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Dec 19, 2022
ed01fbf
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Dec 20, 2022
df773c9
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Dec 21, 2022
5a7f377
Fix registerCustomArgumentType in 1.19.3
willkroboth Jan 3, 2023
a62ddc3
Add example command for standard testing (Bukkit)
willkroboth Jan 3, 2023
9860822
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 3, 2023
a35913f
Clean up after merge
willkroboth Jan 3, 2023
1b6511a
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 4, 2023
d3d8c34
Fix parameterization of ArgumentParseExceptionHandler
willkroboth Jan 5, 2023
bc6b58f
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 5, 2023
ab3d4e0
Hotfix tab-complete for provided suggestions in 1.19.3
willkroboth Jan 5, 2023
92c7625
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 9, 2023
574b103
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 13, 2023
c8c527b
Fix ArgumentParseExceptionHandlers not getting processed
willkroboth Jan 13, 2023
d8e726b
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 13, 2023
4fe1673
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 16, 2023
d9481cc
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Jan 25, 2023
703e14c
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Feb 1, 2023
faf5c4e
Refreeze COMMAND_ARGUMENT_TYPE registry after adding custom argument …
willkroboth Feb 1, 2023
a187f86
Implement equals, hashCode, toString for WrapperStringReader
willkroboth Feb 1, 2023
08e1592
Add @RequireField for 1.19 NMS
willkroboth Feb 1, 2023
29d82d5 8000
Remove classes for 1.13 and 1.14
willkroboth Feb 1, 2023
5ba3dbd
Fix 1.19 NMS @RequireField annotations
willkroboth Feb 2, 2023
4073c1d
Make Sonarcloud a bit happier
willkroboth Feb 2, 2023
4cae893
Add comments naming obfuscated method names
willkroboth Feb 2, 2023
5b8339e
Add TODOs explaining why Field reflection is not yet checked at compi…
willkroboth Feb 2, 2023
4086694
'fix' (?) javadoc format for added records
willkroboth Feb 2, 2023
54b538d
Implement equals, hashCode, toString for WrapperCommandSyntaxException
willkroboth Feb 2, 2023
245f969
Use VarHandles instead of static Method reflection
willkroboth Feb 2, 2023
37d489b
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Feb 3, 2023
6b27ebf
Switch dev/argument-exceptions to use CommandArguments instead of Obj…
willkroboth Feb 3, 2023
f3af7db
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Feb 19, 2023
97438e0
Add simple InitialParseExceptionArgumentTest
willkroboth Feb 20, 2023
80b828e
Only mock register ExceptionHandlingArgumentType if it is not already…
willkroboth Feb 20, 2023
677ec3c
Fix MethodHandle reflection for 1_18_R1
willkroboth Feb 20, 2023
3ba0782
Fix MethodHandle reflection for all versions
willkroboth Feb 20, 2023
56ecf24
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Feb 20, 2023
13f94ea
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Feb 21, 2023
e40d9bb
Refactor variable names in MethodHandles reflection
willkroboth Feb 21, 2023
b6cc9f7
Merge remote-tracking branch 'origin/dev/argument-exceptions' into de…
willkroboth Feb 21, 2023
c915f7e
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Feb 21, 2023
f5d6c89
Revise reflection in 1_15
willkroboth Feb 22, 2023
1b22e55
Add and use SafeVarHandle#getUnknownInstanceType
willkroboth Feb 22, 2023
0e25e98
Update use of reflection in other ArgumentSerializers
willkroboth Feb 23, 2023
4b42d10
Fix ArgumentSerializer reflection
willkroboth Feb 23, 2023
868985f
Share code between ArgumentSerializers
willkroboth Feb 23, 2023
0a195df
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Mar 9, 2023
9c27823
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Mar 13, 2023
fde031f
Don't include Object in the platform load log
willkroboth Mar 13, 2023
a7570d0
Add simple test for ArgumentParseException
willkroboth Mar 17, 2023
deda323
You gotta register the test command to use it!
willkroboth Mar 17, 2023
2e2c5dc
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Mar 21, 2023
08f5218
Update 1.19.4 NMS
willkroboth Mar 21, 2023
5652dab
Fix frozen field access in 1.19 NMS when testing
willkroboth Mar 21, 2023
b13102c
Fix register method access in 1.19 NMS when testing
willkroboth Mar 23, 2023
a36f3e0
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Mar 24, 2023
977a2c8
Merge branch 'dev/dev' into dev/argument-exceptions
willkroboth Apr 2, 2023
e3d5679
Provide the parametrized type for SafeVarHandles in ArgumentSerializers
willkroboth Apr 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix 1.18 registerCustomArgumentType
  • Loading branch information
willkroboth committed Nov 27, 2022
commit 537cf5af4642bb06770de0035c2af29b35e1f802
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package dev.jorel.commandapi.nms;

import com.google.gson.JsonObject;
import com.mojang.brigadier.arguments.ArgumentType;
import dev.jorel.commandapi.CommandAPIHandler;
import dev.jorel.commandapi.arguments.ExceptionHandlingArgumentType;
import dev.jorel.commandapi.preprocessor.Differs;
import net.minecraft.commands.synchronization.ArgumentSerializer;
import net.minecraft.commands.synchronization.ArgumentTypes;
import net.minecraft.network.FriendlyByteBuf;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

public class ExceptionHandlingArgumentSerializer_1_18_R2<T> implements ArgumentSerializer<ExceptionHandlingArgumentType<T>> {
private static Method getInfo = null;

@Override
@Differs(from = {"1.13", "1.14", "1.15", "1.16", "1.17", "1.18", "1.18.1"},
by = "ArgumentType.Entry.c -> ArgumentType.Entry.b, ArgumentType.Entry.b -> ArgumentType.Entry.a")
public void serializeToNetwork(ExceptionHandlingArgumentType<T> argument, FriendlyByteBuf friendlyByteBuf) {
try {
// Remove this key from packet
if(getInfo == null) {
getInfo = ArgumentTypes.class.getDeclaredMethod("b", ArgumentType.class);
getInfo.setAccessible(true);
}
Object myInfo = getInfo.invoke(null, argument);

Field keyField = CommandAPIHandler.getInstance().getField(myInfo.getClass(), "b");
String myKey = keyField.get(myInfo).toString();
byte[] myKeyBytes = myKey.getBytes(StandardCharsets.UTF_8);
// Removing length and size of string, assuming length is always written as 1 byte
friendlyByteBuf.writerIndex(friendlyByteBuf.writerIndex() - myKeyBytes.length - 1);

// Add baseType key instead
ArgumentType<T> baseType = argument.baseType();
Object baseInfo = getInfo.invoke(null, baseType);
String baseKey = keyField.get(baseInfo).toString();
friendlyByteBuf.writeUtf(baseKey);

// Serialize baseType
Field subSerializerField = CommandAPIHandler.getInstance().getField(baseInfo.getClass(), "a");
ArgumentSerializer<ArgumentType<T>> subSerializer = (ArgumentSerializer<ArgumentType<T>>) subSerializerField.get(baseInfo);
subSerializer.serializeToNetwork(baseType, friendlyByteBuf);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}

@Override
@Differs(from = {"1.13", "1.14", "1.15", "1.16", "1.17", "1.18", "1.18.1"},
by = "ArgumentType.Entry.c -> ArgumentType.Entry.b, ArgumentType.Entry.b -> ArgumentType.Entry.a")
public void serializeToJson(ExceptionHandlingArgumentType<T> argument, JsonObject properties) {
try {
ArgumentType<T> baseType = argument.baseType();

if(getInfo == null) {
getInfo = ArgumentTypes.class.getDeclaredMethod("b", ArgumentType.class);
getInfo.setAccessible(true);
}
Object baseInfo = getInfo.invoke(null, baseType);

Field keyField = CommandAPIHandler.getInstance().getField(baseInfo.getClass(), "b");
properties.addProperty("baseType", keyField.get(baseInfo).toString());

Field subSerializerField = CommandAPIHandler.getInstance().getField(baseInfo.getClass(), "a");
ArgumentSerializer<ArgumentType<T>> subSerializer = (ArgumentSerializer<ArgumentType<T>>) subSerializerField.get(baseInfo);

JsonObject subProperties = new JsonObject();
subSerializer.serializeToJson(baseType, subProperties);
if (subProperties.size() > 0) {
properties.add("baseProperties", subProperties);
}
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}

@Override
public ExceptionHandlingArgumentType<T> deserializeFromNetwork(FriendlyByteBuf friendlyByteBuf) {
// Since this class overrides its ArgumentRegistry key with the baseType's,
// this class's key should never show up in a packet and this method should never
// be called to deserialize the ArgumentType info that wasn't put into the packet
// anyway. Also, the server shouldn't ever deserialize a PacketPlay*Out*Commands
// either. If this method ever gets called, either you or I are doing something very wrong!
throw new IllegalStateException("This shouldn't happen! See dev.jorel.commandapi.nms.ExceptionHandlingArgumentSerializer_1_18_R2#deserializeFromNetwork for more information");
// Including a mini-stacktrace here in case this exception shows up
// on a client-disconnected screen, which is not very helpful
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
import java.util.function.ToIntFunction;

import com.mojang.brigadier.Message;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import dev.jorel.commandapi.arguments.ExceptionHandlingArgumentType;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Keyed;
Expand Down Expand Up @@ -708,6 +707,11 @@ public void resendPackets(Player player) {
MINECRAFT_SERVER.getCommands().sendCommands(((CraftPlayer) player).getHandle());
}

@Override
public void registerCustomArgumentType() {
ArgumentTypes.register("commandapi:exception_handler", ExceptionHandlingArgumentType.class, new ExceptionHandlingArgumentSerializer_1_18_R2());
}

@Override
public Message generateMessageFromJson(String json) {
return Serializer.fromJson(json);
Expand Down
1E0A
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package dev.jorel.commandapi.nms;

import com.google.gson.JsonObject;
import com.mojang.brigadier.arguments.ArgumentType;
import dev.jorel.commandapi.CommandAPIHandler;
import dev.jorel.commandapi.arguments.ExceptionHandlingArgumentType;
import net.minecraft.commands.synchronization.ArgumentSerializer;
import net.minecraft.commands.synchronization.ArgumentTypes;
import net.minecraft.network.FriendlyByteBuf;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;

public class ExceptionHandlingArgumentSerializer_1_18_R1<T> implements ArgumentSerializer<ExceptionHandlingArgumentType<T>> {
private static Method getInfo = null;

@Override
public void serializeToNetwork(ExceptionHandlingArgumentType<T> argument, FriendlyByteBuf friendlyByteBuf) {
try {
// Remove this key from packet
if(getInfo == null) {
getInfo = ArgumentTypes.class.getDeclaredMethod("b", ArgumentType.class);
getInfo.setAccessible(true);
}
Object myInfo = getInfo.invoke(null, argument);

Field keyField = CommandAPIHandler.getInstance().getField(myInfo.getClass(), "c");
String myKey = keyField.get(myInfo).toString();
byte[] myKeyBytes = myKey.getBytes(StandardCharsets.UTF_8);
// Removing length and size of string, assuming length is always written as 1 byte
friendlyByteBuf.writerIndex(friendlyByteBuf.writerIndex() - myKeyBytes.length - 1);

// Add baseType key instead
ArgumentType<T> baseType = argument.baseType();
Object baseInfo = getInfo.invoke(null, baseType);
String baseKey = keyField.get(baseInfo).toString();
friendlyByteBuf.writeUtf(baseKey);

// Serialize baseType
Field subSerializerField = CommandAPIHandler.getInstance().getField(baseInfo.getClass(), "b");
ArgumentSerializer<ArgumentType<T>> subSerializer = (ArgumentSerializer<ArgumentType<T>>) subSerializerField.get(baseInfo);
subSerializer.serializeToNetwork(baseType, friendlyByteBuf);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}

@Override
public void serializeToJson(ExceptionHandlingArgumentType<T> argument, JsonObject properties) {
try {
ArgumentType<T> baseType = argument.baseType();

if(getInfo == null) {
getInfo = ArgumentTypes.class.getDeclaredMethod("b", ArgumentType.class);
getInfo.setAccessible(true);
}
Object baseInfo = getInfo.invoke(null, baseType);

Field keyField = CommandAPIHandler.getInstance().getField(baseInfo.getClass(), "c");
properties.addProperty("baseType", keyField.get(baseInfo).toString());

Field subSerializerField = CommandAPIHandler.getInstance().getField(baseInfo.getClass(), "b");
ArgumentSerializer<ArgumentType<T>> subSerializer = (ArgumentSerializer<ArgumentType<T>>) subSerializerField.get(baseInfo);

JsonObject subProperties = new JsonObject();
subSerializer.serializeToJson(baseType, subProperties);
if (subProperties.size() > 0) {
properties.add("baseProperties", subProperties);
}
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}

@Override
public ExceptionHandlingArgumentType<T> deserializeFromNetwork(FriendlyByteBuf friendlyByteBuf) {
// Since this class overrides its ArgumentRegistry key with the baseType's,
// this class's key should never show up in a packet and this method should never
// be called to deserialize the ArgumentType info that wasn't put into the packet
// anyway. Also, the server shouldn't ever deserialize a PacketPlay*Out*Commands
// either. If this method ever gets called, either you or I are doing something very wrong!
throw new IllegalStateException("This shouldn't happen! See dev.jorel.commandapi.nms.ExceptionHandlingArgumentSerializer_1_18_R1#deserializeFromNetwork for more information");
// Including a mini-stacktrace here in case this exception shows up
// on a client-disconnected screen, which is not very helpful
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.function.ToIntFunction;

import com.mojang.brigadier.Message;
import dev.jorel.commandapi.arguments.ExceptionHandlingArgumentType;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.Bukkit;
Expand Down Expand Up @@ -585,6 +586,11 @@ public void resendPackets(Player player) {
MINECRAFT_SERVER.getCommands().sendCommands(((CraftPlayer) player).getHandle());
}

@Override
public void registerCustomArgumentType() {
ArgumentTypes.register("commandapi:exception_handler", ExceptionHandlingArgumentType.class, new ExceptionHandlingArgumentSerializer_1_18_R1());
}

@Override
public Message generateMessageFromJson(String json) {
return Serializer.fromJson(json);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,8 @@ public final void resendPackets(Player player) {
}

@Override
@Differs(from = {"1.14, 1.15, 1.16", "1.17", "1.18"},
by = "Using ArgumentTypeInfos and Registry.COMMAND_ARGUMENT_TYPE instead of ArgumentRegistry")
public void registerCustomArgumentType() {
try {
// Unfreeze registry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,6 @@ public final UUID getUUID(CommandContext<CommandSourceStack> cmdCtx, String key)
public abstract void resendPackets(Player player);

@Override
@Differs(from = {"1.14, 1.15, 1.16"}, by = "Using ArgumentTypeInfos and Registry.COMMAND_ARGUMENT_TYPE instead of ArgumentRegistry")
@Unimplemented(because = VERSION_SPECIFIC_IMPLEMENTATION)
public void registerCustomArgumentType() {}; // TODO: Make abstract
public abstract void registerCustomArgumentType();
}
0