Skip to content

Commit

Permalink
fix(bukkit): create registry ResourceKey directly (#96)
Browse files Browse the repository at this point in the history
* fix(bukkit): create registry ResourceKey directly

Previously they were fetched from registry instances which are
harder to obtain. Now it just creates them using the static
methods available on ResourceKey.

* spotless
  • Loading branch information
Machine-Maker authored Aug 21, 2024
1 parent 473f9ff commit d1a5d25
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private void registerUUID() {
final @NonNull String registryName
) {
this.mapNMS(parserType, "resource_key", type -> (ArgumentType<?>) type.getDeclaredConstructors()[0]
.newInstance(RegistryReflection.registryKey(RegistryReflection.registryByName(registryName))));
.newInstance(RegistryReflection.registryKey(registryName)));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private static final class ArgumentTypeGetterImpl implements MinecraftArgumentTy
private final Map<?, ?> byClassMap;

private ArgumentTypeGetterImpl() {
this.argumentRegistry = Suppliers.memoize(() -> RegistryReflection.registryByName("command_argument_type"));
this.argumentRegistry = Suppliers.memoize(() -> RegistryReflection.builtInRegistryByName("command_argument_type"));
try {
final Field declaredField = CraftBukkitReflection.needMCClass("commands.synchronization.ArgumentTypeInfos")
.getDeclaredFields()[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ public final class RegistryReflection {
"net.minecraft.resources.MinecraftKey",
"net.minecraft.resources.ResourceLocation"
);
private static final Class<?> RESOURCE_KEY_CLASS = CraftBukkitReflection.needNMSClassOrElse(
"ResourceKey",
"net.minecraft.resources.ResourceKey"
);
private static final Executable NEW_RESOURCE_LOCATION;
private static final Executable CREATE_REGISTRY_RESOURCE_KEY;

private RegistryReflection() {
}
Expand All @@ -63,6 +68,7 @@ private RegistryReflection() {
REGISTRY_GET = null;
REGISTRY_KEY = null;
NEW_RESOURCE_LOCATION = null;
CREATE_REGISTRY_RESOURCE_KEY = null;
} else {
registryClass = CraftBukkitReflection.firstNonNullOrThrow(
() -> "Registry",
Expand Down Expand Up @@ -95,13 +101,20 @@ private RegistryReflection() {
CraftBukkitReflection.findMethod(RESOURCE_LOCATION_CLASS, "parse", String.class), // 1.21+
CraftBukkitReflection.findMethod(RESOURCE_LOCATION_CLASS, "a", String.class)
);

CREATE_REGISTRY_RESOURCE_KEY = CraftBukkitReflection.firstNonNullOrThrow(
() -> "Could not find ResourceKey#createRegistryKey(ResourceLocation)",
CraftBukkitReflection.findMethod(RESOURCE_KEY_CLASS, "createRegistryKey", RESOURCE_LOCATION_CLASS),
CraftBukkitReflection.findMethod(RESOURCE_KEY_CLASS, "a", RESOURCE_LOCATION_CLASS)
);
}
}

public static Object registryKey(final Object registry) {
Objects.requireNonNull(REGISTRY_KEY, "REGISTRY_KEY");
public static Object registryKey(final String registryName) {
Objects.requireNonNull(CREATE_REGISTRY_RESOURCE_KEY, "CREATE_REGISTRY_RESOURCE_KEY");
try {
return REGISTRY_KEY.invoke(registry);
final Object resourceLocation = createResourceLocation(registryName);
return CraftBukkitReflection.invokeConstructorOrStaticMethod(CREATE_REGISTRY_RESOURCE_KEY, resourceLocation);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
Expand All @@ -116,7 +129,7 @@ public static Object get(final Object registry, final String resourceLocation) {
}
}

public static Object registryByName(final String name) {
public static Object builtInRegistryByName(final String name) {
Objects.requireNonNull(REGISTRY_REGISTRY, "REGISTRY_REGISTRY");
try {
return get(REGISTRY_REGISTRY.get(null), name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ private ArgumentParser<C, BlockPredicate> createParser() {
if (GET_TAG_REGISTRY_METHOD != null) {
obj = GET_TAG_REGISTRY_METHOD.invoke(server);
} else {
obj = RegistryReflection.registryByName("block");
obj = RegistryReflection.builtInRegistryByName("block");
}
Objects.requireNonNull(CREATE_PREDICATE_METHOD, "create on BlockPredicateArgument$Result");
final Predicate<Object> predicate = (Predicate<Object>) CREATE_PREDICATE_METHOD.invoke(result, obj);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.incendo.cloud.examples.bukkit.builder.feature.StringArrayExample;
import org.incendo.cloud.examples.bukkit.builder.feature.minecraft.BlockPredicateExample;
import org.incendo.cloud.examples.bukkit.builder.feature.minecraft.ComponentExample;
import org.incendo.cloud.examples.bukkit.builder.feature.minecraft.EnchantmentExample;
import org.incendo.cloud.examples.bukkit.builder.feature.minecraft.ItemStackExample;
import org.incendo.cloud.examples.bukkit.builder.feature.minecraft.ItemStackPredicateExample;
import org.incendo.cloud.examples.bukkit.builder.feature.minecraft.NamespacedKeyExample;
Expand All @@ -70,6 +71,7 @@ public final class BuilderExample {
new RegexExample(),
new StringArrayExample(),
// Minecraft-specific features
new EnchantmentExample(),
new ItemStackExample(),
new SelectorExample(),
new TextColorExample(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// MIT License
//
// Copyright (c) 2024 Incendo
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package org.incendo.cloud.examples.bukkit.builder.feature.minecraft;

import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.bukkit.BukkitCommandManager;
import org.incendo.cloud.examples.bukkit.ExamplePlugin;
import org.incendo.cloud.examples.bukkit.builder.BuilderFeature;

import static org.incendo.cloud.bukkit.parser.EnchantmentParser.enchantmentParser;

/**
* Example showcasing the enchantment parser.
*/
public final class EnchantmentExample implements BuilderFeature {

@Override
public void registerFeature(
final @NonNull ExamplePlugin examplePlugin,
final @NonNull BukkitCommandManager<CommandSender> manager
) {
manager.command(
manager.commandBuilder("builder")
.literal("enchantment")
.required("enchant", enchantmentParser())
.handler(ctx -> {
final Enchantment enchantment = ctx.get("enchant");
ctx.sender().sendMessage("The enchant you typed is '" + enchantment.getKey() + "'.");
})
);
}
}

0 comments on commit d1a5d25

Please sign in to comment.