Compare commits
2 Commits
ee023b5d2c
...
276f5b2dc1
Author | SHA1 | Date | |
---|---|---|---|
276f5b2dc1 | |||
9c72b8cda4 |
@ -73,13 +73,13 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
RootCommandNode<CommandSourceStack> wrappedRoot = vanillaPaperDispatcher.getRoot();
|
||||
ReflectClass<?> apiMirrorRootNodeClass = Reflect.ofClassOfInstance(wrappedRoot);
|
||||
try {
|
||||
RootCommandNode<?> actualRoot = ((CommandDispatcher<?>) apiMirrorRootNodeClass.method("getDispatcher").invoke(wrappedRoot)).getRoot();
|
||||
RootCommandNode<?> unwrappedRoot = ((CommandDispatcher<?>) apiMirrorRootNodeClass.method("getDispatcher").invoke(wrappedRoot)).getRoot();
|
||||
|
||||
Reflect.ofClass(CommandNode.class).field("unwrappedCached").setValue(wrappedRoot, actualRoot);
|
||||
Reflect.ofClass(CommandNode.class).field("wrappedCached").setValue(actualRoot, wrappedRoot);
|
||||
Reflect.ofClass(CommandNode.class).field("unwrappedCached").setValue(wrappedRoot, unwrappedRoot);
|
||||
Reflect.ofClass(CommandNode.class).field("wrappedCached").setValue(unwrappedRoot, wrappedRoot);
|
||||
|
||||
} catch (InvocationTargetException|IllegalAccessException|NoSuchMethodException|NoSuchFieldException e) {
|
||||
Log.severe("Unable to trick the Paper/Brigadier unwrapper to properly handle redirecting to root command node.", e);
|
||||
Log.severe("Unable to trick the Paper/Brigadier unwrapper to properly handle commands redirecting to root command node.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,6 +183,7 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
}
|
||||
|
||||
registeredAliases = new HashSet<>(event.registrar().register(commandNode, description, List.of(aliases)));
|
||||
doPostRegistrationFixes();
|
||||
|
||||
if (registrationPolicy == RegistrationPolicy.ALL) {
|
||||
// enforce registration of aliases
|
||||
@ -233,6 +234,43 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void doPostRegistrationFixes() {
|
||||
postRegistrationFixNode(new HashSet<>(), commandNode);
|
||||
}
|
||||
|
||||
private void postRegistrationFixNode(Set<CommandNode<CommandSourceStack>> fixedNodes, CommandNode<CommandSourceStack> originalNode) {
|
||||
if (originalNode instanceof RootCommandNode)
|
||||
return;
|
||||
if (fixedNodes.contains(originalNode))
|
||||
return;
|
||||
fixedNodes.add(originalNode);
|
||||
if (originalNode.getRedirect() != null) {
|
||||
try {
|
||||
ReflectClass<CommandNode> cmdNodeClass = Reflect.ofClass(CommandNode.class);
|
||||
CommandNode<CommandSourceStack> unwrappedNode = (CommandNode<CommandSourceStack>) cmdNodeClass.field("unwrappedCached").getValue(originalNode);
|
||||
if (unwrappedNode != null) {
|
||||
cmdNodeClass.field("modifier").setValue(unwrappedNode, cmdNodeClass.field("modifier").getValue(originalNode));
|
||||
cmdNodeClass.field("forks").setValue(unwrappedNode, cmdNodeClass.field("forks").getValue(originalNode));
|
||||
}
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
postRegistrationFixNode(fixedNodes, originalNode.getRedirect());
|
||||
}
|
||||
else {
|
||||
try {
|
||||
for (CommandNode<CommandSourceStack> child : originalNode.getChildren())
|
||||
postRegistrationFixNode(fixedNodes, child);
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
// in case getChildren is not possible (vanilla commands are wrapped by Paper API)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static LiteralCommandNode<CommandSourceStack> getAliasNode(CommandNode<CommandSourceStack> commandNode, String alias) {
|
||||
return LiteralArgumentBuilder.<CommandSourceStack>literal(alias)
|
||||
.requires(commandNode.getRequirement())
|
||||
|
@ -9,7 +9,7 @@ import java.lang.reflect.Modifier;
|
||||
*/
|
||||
public final class ReflectField<T> extends ReflectMember<T, String, Field, NoSuchFieldException> {
|
||||
|
||||
/* Those fields are used to modify the value of a static variable. Depending on the current Java version,
|
||||
/* Those fields are used to modify the value of a final variable. Depending on the current Java version,
|
||||
* one of them will be used for this purpose.
|
||||
*/
|
||||
private static sun.misc.Unsafe sunMiscUnsafeInstance;
|
||||
@ -122,13 +122,30 @@ public final class ReflectField<T> extends ReflectMember<T, String, Field, NoSuc
|
||||
// if the field is final, we have to do some unsafe stuff :/
|
||||
if (sunMiscUnsafeInstance != null) { // Java >= 16
|
||||
// set the value of the field, directly in the memory
|
||||
if (Modifier.isStatic(realModifiers)) {
|
||||
long offset = sunMiscUnsafeInstance.staticFieldOffset(f);
|
||||
sunMiscUnsafeInstance.putObject(sunMiscUnsafeInstance.staticFieldBase(f), offset, value);
|
||||
} else {
|
||||
long offset = sunMiscUnsafeInstance.objectFieldOffset(f);
|
||||
sunMiscUnsafeInstance.putObject(instance, offset, value);
|
||||
}
|
||||
Object unsafeObjInstance = Modifier.isStatic(realModifiers)
|
||||
? sunMiscUnsafeInstance.staticFieldBase(f)
|
||||
: instance;
|
||||
long offset = Modifier.isStatic(realModifiers)
|
||||
? sunMiscUnsafeInstance.staticFieldOffset(f)
|
||||
: sunMiscUnsafeInstance.objectFieldOffset(f);
|
||||
if (char.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putChar(unsafeObjInstance, offset, (char)value);
|
||||
else if (byte.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putByte(unsafeObjInstance, offset, (byte)value);
|
||||
else if (short.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putShort(unsafeObjInstance, offset, (short)value);
|
||||
else if (int.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putInt(unsafeObjInstance, offset, (int)value);
|
||||
else if (long.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putLong(unsafeObjInstance, offset, (long)value);
|
||||
else if (boolean.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putBoolean(unsafeObjInstance, offset, (boolean)value);
|
||||
else if (float.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putFloat(unsafeObjInstance, offset, (float)value);
|
||||
else if (double.class.isAssignableFrom(f.getType()))
|
||||
sunMiscUnsafeInstance.putDouble(unsafeObjInstance, offset, (double)value);
|
||||
else
|
||||
sunMiscUnsafeInstance.putObject(unsafeObjInstance, offset, value);
|
||||
} else { // Java < 16
|
||||
// change the modifier in the Field instance so the method #set(instance, value) doesn't throw an exception
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user