mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-30 20:39:10 +00:00
注入染色配方
This commit is contained in:
@@ -13,7 +13,6 @@ import net.momirealms.craftengine.core.item.ItemWrapper;
|
||||
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.StringUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
@@ -115,18 +114,7 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
|
||||
return FastNMS.INSTANCE.method$ItemStack$is(literalObject, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDyeItem(W item) {
|
||||
return CoreReflections.clazz$DyeItem.isInstance(FastNMS.INSTANCE.method$ItemStack$getItem(item.getLiteralObject()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Color> dyeColor(W item) {
|
||||
Object itemStack = item.getLiteralObject();
|
||||
Object dyeItem = FastNMS.INSTANCE.method$ItemStack$getItem(itemStack);
|
||||
if (!CoreReflections.clazz$DyeItem.isInstance(dyeItem)) return Optional.empty();
|
||||
return Optional.of(Color.fromDecimal(FastNMS.INSTANCE.method$DyeColor$getTextureDiffuseColor(FastNMS.INSTANCE.method$DyeItem$getDyeColor(dyeItem))));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setJavaComponent(W item, Object type, Object value) {
|
||||
|
||||
@@ -9,6 +9,8 @@ import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.item.CloneableConstantItem;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.injector.RecipeInjector;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||
@@ -36,25 +38,70 @@ import java.io.Reader;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
private static BukkitRecipeManager instance;
|
||||
|
||||
// TODO 需要重构整个 recipe manager
|
||||
|
||||
private static final Object MINECRAFT_RECIPE_MANAGER;
|
||||
private static final Object MINECRAFT_RECIPE_MAP;
|
||||
|
||||
static {
|
||||
try {
|
||||
MINECRAFT_RECIPE_MANAGER = CoreReflections.method$MinecraftServer$getRecipeManager.invoke(CoreReflections.method$MinecraftServer$getServer.invoke(null));
|
||||
MINECRAFT_RECIPE_MAP = VersionHelper.isOrAbove1_21_2() ? CoreReflections.field$RecipeManager$recipes.get(MINECRAFT_RECIPE_MANAGER) : null;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ReflectionInitException("Failed to initialize recipe manager", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Consumer<Key> MINECRAFT_RECIPE_REMOVER = VersionHelper.isOrAbove1_21_2() ?
|
||||
(id -> {
|
||||
Object resourceKey = toRecipeResourceKey(id);
|
||||
FastNMS.INSTANCE.method$RecipeMap$removeRecipe(MINECRAFT_RECIPE_MAP, resourceKey);
|
||||
}) :
|
||||
(id -> {
|
||||
Object resourceLocation = KeyUtils.toResourceLocation(id);
|
||||
FastNMS.INSTANCE.method$RecipeManager$removeRecipe(MINECRAFT_RECIPE_MANAGER, resourceLocation);
|
||||
});
|
||||
private static final BiConsumer<Key, Object> MINECRAFT_RECIPE_ADDER =
|
||||
VersionHelper.isOrAbove1_21_2() ?
|
||||
(id, recipe) -> {
|
||||
Object resourceKey = toRecipeResourceKey(id);
|
||||
Object recipeHolder = FastNMS.INSTANCE.constructor$RecipeHolder(resourceKey, recipe);
|
||||
FastNMS.INSTANCE.method$RecipeManager$addRecipe(MINECRAFT_RECIPE_MANAGER, recipeHolder);
|
||||
} :
|
||||
VersionHelper.isOrAbove1_20_2() ?
|
||||
(id, recipe) -> {
|
||||
Object resourceLocation = KeyUtils.toResourceLocation(id);
|
||||
Object recipeHolder = FastNMS.INSTANCE.constructor$RecipeHolder(resourceLocation, recipe);
|
||||
FastNMS.INSTANCE.method$RecipeManager$addRecipe(MINECRAFT_RECIPE_MANAGER, recipeHolder);
|
||||
} :
|
||||
(id, recipe) -> {
|
||||
FastNMS.INSTANCE.method$RecipeManager$addRecipe(MINECRAFT_RECIPE_MANAGER, recipe);
|
||||
};
|
||||
|
||||
static {
|
||||
try {
|
||||
Key dyeRecipeId = Key.from("armor_dye");
|
||||
MINECRAFT_RECIPE_REMOVER.accept(dyeRecipeId);
|
||||
MINECRAFT_RECIPE_ADDER.accept(dyeRecipeId, RecipeInjector.createCustomDyeRecipe());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ReflectionInitException("Failed to inject dye recipes", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final List<Object> injectedIngredients = new ArrayList<>();
|
||||
// 将自定义配方转为“广义”配方,接受更加宽容的输入
|
||||
// 部分过程借助bukkit完成,部分直接通过nms方法注册
|
||||
private static final Map<Key, BukkitRecipeConvertor<? extends Recipe<ItemStack>>> MIXED_RECIPE_CONVERTORS = new HashMap<>();
|
||||
private static final List<Object> injectedIngredients = new ArrayList<>();
|
||||
private static final IdentityHashMap<Recipe<ItemStack>, Object> CE_RECIPE_2_NMS_HOLDER = new IdentityHashMap<>();
|
||||
public static final CustomDyeRecipe<ItemStack> DYE_RECIPE = new CustomDyeRecipe<>();
|
||||
private static Object nmsRecipeManager;
|
||||
private static final IdentityHashMap<Recipe<ItemStack>, Object> MINECRAFT_RECIPE_HOLDER_BY_RECIPE = new IdentityHashMap<>();
|
||||
|
||||
private static void registerNMSSmithingRecipe(Object recipe) {
|
||||
try {
|
||||
CoreReflections.method$RecipeManager$addRecipe.invoke(nmsRecipeManager(), recipe);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to register smithing recipe", e);
|
||||
}
|
||||
public static Object toRecipeResourceKey(Key id) {
|
||||
return FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.RECIPE, KeyUtils.toResourceLocation(id));
|
||||
}
|
||||
|
||||
private static void registerBukkitShapedRecipe(Object recipe) {
|
||||
@@ -124,17 +171,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
MIXED_RECIPE_CONVERTORS.put(RecipeTypes.SMITHING_TRANSFORM, (BukkitRecipeConvertor<CustomSmithingTransformRecipe<ItemStack>>) (id, recipe) -> {
|
||||
try {
|
||||
Object nmsRecipe = createMinecraftSmithingTransformRecipe(recipe);
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
nmsRecipe = CoreReflections.constructor$RecipeHolder.newInstance(
|
||||
CraftBukkitReflections.method$CraftRecipe$toMinecraft.invoke(null, new NamespacedKey(id.namespace(), id.value())), nmsRecipe);
|
||||
} else if (VersionHelper.isOrAbove1_20_2()) {
|
||||
nmsRecipe = CoreReflections.constructor$RecipeHolder.newInstance(KeyUtils.toResourceLocation(id), nmsRecipe);
|
||||
} else {
|
||||
Object finalNmsRecipe0 = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe0);
|
||||
}
|
||||
Object finalNmsRecipe = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe);
|
||||
return () -> MINECRAFT_RECIPE_ADDER.accept(id, nmsRecipe);
|
||||
} catch (InvalidRecipeIngredientException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
@@ -145,17 +182,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
MIXED_RECIPE_CONVERTORS.put(RecipeTypes.SMITHING_TRIM, (BukkitRecipeConvertor<CustomSmithingTrimRecipe<ItemStack>>) (id, recipe) -> {
|
||||
try {
|
||||
Object nmsRecipe = createMinecraftSmithingTrimRecipe(recipe);
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
nmsRecipe = CoreReflections.constructor$RecipeHolder.newInstance(
|
||||
CraftBukkitReflections.method$CraftRecipe$toMinecraft.invoke(null, new NamespacedKey(id.namespace(), id.value())), nmsRecipe);
|
||||
} else if (VersionHelper.isOrAbove1_20_2()) {
|
||||
nmsRecipe = CoreReflections.constructor$RecipeHolder.newInstance(KeyUtils.toResourceLocation(id), nmsRecipe);
|
||||
} else {
|
||||
Object finalNmsRecipe0 = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe0);
|
||||
}
|
||||
Object finalNmsRecipe = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe);
|
||||
return () -> MINECRAFT_RECIPE_ADDER.accept(id, nmsRecipe);
|
||||
} catch (InvalidRecipeIngredientException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
@@ -281,20 +308,15 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
this.plugin = plugin;
|
||||
this.recipeEventListener = new RecipeEventListener(plugin, this, plugin.itemManager());
|
||||
this.crafterEventListener = VersionHelper.isOrAbove1_21() ? new CrafterEventListener(plugin, this, plugin.itemManager()) : null;
|
||||
try {
|
||||
nmsRecipeManager = CoreReflections.method$MinecraftServer$getRecipeManager.invoke(CoreReflections.method$MinecraftServer$getServer.invoke(null));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to get minecraft recipe manager", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object nmsRecipeHolderByRecipe(Recipe<ItemStack> recipe) {
|
||||
if (super.isReloading) return null;
|
||||
return CE_RECIPE_2_NMS_HOLDER.get(recipe);
|
||||
return MINECRAFT_RECIPE_HOLDER_BY_RECIPE.get(recipe);
|
||||
}
|
||||
|
||||
public static Object nmsRecipeManager() {
|
||||
return nmsRecipeManager;
|
||||
public static Object minecraftRecipeManager() {
|
||||
return MINECRAFT_RECIPE_MANAGER;
|
||||
}
|
||||
|
||||
public static BukkitRecipeManager instance() {
|
||||
@@ -315,8 +337,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
super.isReloading = true;
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
try {
|
||||
this.stolenFeatureFlagSet = CoreReflections.field$RecipeManager$featureflagset.get(nmsRecipeManager);
|
||||
CoreReflections.field$RecipeManager$featureflagset.set(nmsRecipeManager, null);
|
||||
this.stolenFeatureFlagSet = CoreReflections.field$RecipeManager$featureflagset.get(MINECRAFT_RECIPE_MANAGER);
|
||||
CoreReflections.field$RecipeManager$featureflagset.set(MINECRAFT_RECIPE_MANAGER, null);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to steal featureflagset", e);
|
||||
}
|
||||
@@ -347,7 +369,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
@Override
|
||||
public void disable() {
|
||||
unload();
|
||||
CE_RECIPE_2_NMS_HOLDER.clear();
|
||||
MINECRAFT_RECIPE_HOLDER_BY_RECIPE.clear();
|
||||
// 不是服务器关闭造成disable,那么需要把配方卸载干净
|
||||
if (!Bukkit.isStopping()) {
|
||||
for (Runnable task : this.delayedTasksOnMainThread) {
|
||||
@@ -365,7 +387,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (isBrewingRecipe) {
|
||||
Bukkit.getPotionBrewer().removePotionMix(new NamespacedKey(key.namespace(), key.value()));
|
||||
} else {
|
||||
unregisterNMSRecipe(new NamespacedKey(key.namespace(), key.value()));
|
||||
MINECRAFT_RECIPE_REMOVER.accept(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,19 +428,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
return (BukkitRecipeConvertor<T>) MIXED_RECIPE_CONVERTORS.get(recipe.type());
|
||||
}
|
||||
|
||||
private void unregisterNMSRecipe(NamespacedKey key) {
|
||||
try {
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
Object recipeMap = CoreReflections.field$RecipeManager$recipes.get(nmsRecipeManager);
|
||||
CoreReflections.method$RecipeMap$removeRecipe.invoke(recipeMap, CraftBukkitReflections.method$CraftRecipe$toMinecraft.invoke(null, key));
|
||||
} else {
|
||||
Bukkit.removeRecipe(key);
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to unregister nms recipes", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void injectDataPackRecipes() {
|
||||
try {
|
||||
@@ -501,6 +510,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
@Override
|
||||
public void runDelayedSyncTasks() {
|
||||
if (!Config.enableRecipeSystem()) return;
|
||||
|
||||
try {
|
||||
// run delayed tasks
|
||||
for (Runnable r : this.delayedTasksOnMainThread) {
|
||||
@@ -510,13 +520,13 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
|
||||
// give flags back on 1.21.2+
|
||||
if (VersionHelper.isOrAbove1_21_2() && this.stolenFeatureFlagSet != null) {
|
||||
CoreReflections.field$RecipeManager$featureflagset.set(nmsRecipeManager(), this.stolenFeatureFlagSet);
|
||||
CoreReflections.field$RecipeManager$featureflagset.set(minecraftRecipeManager(), this.stolenFeatureFlagSet);
|
||||
this.stolenFeatureFlagSet = null;
|
||||
}
|
||||
|
||||
// refresh recipes
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
CoreReflections.method$RecipeManager$finalizeRecipeLoading.invoke(nmsRecipeManager());
|
||||
CoreReflections.method$RecipeManager$finalizeRecipeLoading.invoke(minecraftRecipeManager());
|
||||
}
|
||||
|
||||
// send to players
|
||||
@@ -536,13 +546,12 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
// clear cache
|
||||
injectedIngredients.clear();
|
||||
|
||||
CE_RECIPE_2_NMS_HOLDER.clear();
|
||||
MINECRAFT_RECIPE_HOLDER_BY_RECIPE.clear();
|
||||
// create mappings
|
||||
for (Map.Entry<Key, Recipe<ItemStack>> entry : this.byId.entrySet()) {
|
||||
Optional<Object> nmsRecipe = getOptionalNMSRecipe(entry.getKey());
|
||||
nmsRecipe.ifPresent(o -> CE_RECIPE_2_NMS_HOLDER.put(entry.getValue(), o));
|
||||
nmsRecipe.ifPresent(o -> MINECRAFT_RECIPE_HOLDER_BY_RECIPE.put(entry.getValue(), o));
|
||||
}
|
||||
CE_RECIPE_2_NMS_HOLDER.put(DYE_RECIPE, getOptionalNMSRecipe(CustomDyeRecipe.ID).orElseThrow(() -> new IllegalStateException("DyeRecipe not found")));
|
||||
super.isReloading = false;
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Failed to run delayed recipe tasks", e);
|
||||
@@ -568,7 +577,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
|
||||
private void handleDataPackShapelessRecipe(Key id, VanillaShapelessRecipe recipe, Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
boolean hasCustomItemInTag = false;
|
||||
List<Ingredient<ItemStack>> ingredientList = new ArrayList<>();
|
||||
@@ -596,7 +604,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (hasCustomItemInTag) {
|
||||
Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe);
|
||||
callback.accept(() -> {
|
||||
unregisterNMSRecipe(key);
|
||||
MINECRAFT_RECIPE_REMOVER.accept(id);
|
||||
converted.run();
|
||||
});
|
||||
}
|
||||
@@ -604,7 +612,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
|
||||
private void handleDataPackShapedRecipe(Key id, VanillaShapedRecipe recipe, Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
boolean hasCustomItemInTag = false;
|
||||
Map<Character, Ingredient<ItemStack>> ingredients = new HashMap<>();
|
||||
@@ -633,7 +640,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (hasCustomItemInTag) {
|
||||
Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe);
|
||||
callback.accept(() -> {
|
||||
unregisterNMSRecipe(key);
|
||||
MINECRAFT_RECIPE_REMOVER.accept(id);
|
||||
converted.run();
|
||||
});
|
||||
}
|
||||
@@ -644,7 +651,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
VanillaCookingRecipe recipe,
|
||||
HeptaFunction<Key, CookingRecipeCategory, String, Ingredient<ItemStack>, Integer, Float, CustomRecipeResult<ItemStack>, CustomCookingRecipe<ItemStack>> constructor2,
|
||||
Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
boolean hasCustomItemInTag = readVanillaIngredients(false, recipe.ingredient(), holders::add);
|
||||
@@ -657,7 +663,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (hasCustomItemInTag) {
|
||||
Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe);
|
||||
callback.accept(() -> {
|
||||
unregisterNMSRecipe(key);
|
||||
MINECRAFT_RECIPE_REMOVER.accept(id);
|
||||
converted.run();
|
||||
});
|
||||
}
|
||||
@@ -665,7 +671,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
|
||||
private void handleDataPackSmithingTransform(Key id, VanillaSmithingTransformRecipe recipe, Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
boolean hasCustomItemInTag;
|
||||
|
||||
@@ -689,7 +694,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (hasCustomItemInTag) {
|
||||
Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe);
|
||||
callback.accept(() -> {
|
||||
unregisterNMSRecipe(key);
|
||||
MINECRAFT_RECIPE_REMOVER.accept(id);
|
||||
converted.run();
|
||||
});
|
||||
}
|
||||
@@ -697,8 +702,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
|
||||
private void handleDataPackSmithingTrim(Key id, VanillaSmithingTrimRecipe recipe, Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
|
||||
boolean hasCustomItemInTag;
|
||||
Set<UniqueKey> additionHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(false, recipe.addition(), additionHolders::add);
|
||||
@@ -718,7 +721,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (hasCustomItemInTag) {
|
||||
Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe);
|
||||
callback.accept(() -> {
|
||||
unregisterNMSRecipe(key);
|
||||
MINECRAFT_RECIPE_REMOVER.accept(id);
|
||||
converted.run();
|
||||
});
|
||||
}
|
||||
@@ -883,12 +886,12 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
Object resourceKey = FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.RECIPE, KeyUtils.toResourceLocation(id));
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceKey);
|
||||
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(MINECRAFT_RECIPE_MANAGER, resourceKey);
|
||||
return optional;
|
||||
} else {
|
||||
Object resourceLocation = KeyUtils.toResourceLocation(id);
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceLocation);
|
||||
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(MINECRAFT_RECIPE_MANAGER, resourceLocation);
|
||||
return optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ public class RecipeEventListener implements Listener {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<Object> optionalMCRecipe = FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(
|
||||
BukkitRecipeManager.nmsRecipeManager(),
|
||||
BukkitRecipeManager.minecraftRecipeManager(),
|
||||
MRecipeTypes.CAMPFIRE_COOKING,
|
||||
CoreReflections.constructor$SingleRecipeInput.newInstance(FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)),
|
||||
FastNMS.INSTANCE.field$CraftWorld$ServerLevel(event.getPlayer().getWorld()),
|
||||
@@ -699,7 +699,11 @@ public class RecipeEventListener implements Listener {
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO 全部改注入
|
||||
Object mcRecipe = CraftBukkitReflections.field$CraftComplexRecipe$recipe.get(complexRecipe);
|
||||
if (CoreReflections.clazz$ArmorDyeRecipe.isInstance(mcRecipe)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Repair recipe
|
||||
if (CoreReflections.clazz$RepairItemRecipe.isInstance(mcRecipe)) {
|
||||
@@ -745,8 +749,6 @@ public class RecipeEventListener implements Listener {
|
||||
int newItemDamage = Math.max(0, newItem.maxDamage() - remainingDurability);
|
||||
newItem.damage(newItemDamage);
|
||||
inventory.setResult(newItem.getItem());
|
||||
} else if (CoreReflections.clazz$ArmorDyeRecipe.isInstance(mcRecipe)) {
|
||||
handlePossibleDyeRecipe(event, false);
|
||||
} else if (CoreReflections.clazz$FireworkStarFadeRecipe.isInstance(mcRecipe)) {
|
||||
ItemStack[] itemStacks = inventory.getMatrix();
|
||||
for (ItemStack itemStack : itemStacks) {
|
||||
@@ -826,29 +828,6 @@ public class RecipeEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onDyeRecipe(PrepareItemCraftEvent event) {
|
||||
org.bukkit.inventory.Recipe recipe = event.getRecipe();
|
||||
if (recipe != null) {
|
||||
return;
|
||||
}
|
||||
handlePossibleDyeRecipe(event, true);
|
||||
}
|
||||
|
||||
private void handlePossibleDyeRecipe(PrepareItemCraftEvent event, boolean correct) {
|
||||
// dye recipe
|
||||
CraftingInventory inventory = event.getInventory();
|
||||
CraftingInput<ItemStack> input = getCraftingInput(inventory);
|
||||
if (input == null) return;
|
||||
if (BukkitRecipeManager.DYE_RECIPE.matches(input)) {
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
event.getInventory().setResult(BukkitRecipeManager.DYE_RECIPE.assemble(input, ItemBuildContext.of(this.plugin.adapt(player))));
|
||||
if (correct) {
|
||||
correctCraftingRecipeUsed(inventory, BukkitRecipeManager.DYE_RECIPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onCraftingRecipe(PrepareItemCraftEvent event) {
|
||||
if (!Config.enableRecipeSystem()) return;
|
||||
|
||||
@@ -17,22 +17,30 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRecipeTypes;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemTags;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.item.CustomItem;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.recipe.CustomCookingRecipe;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class RecipeInjector {
|
||||
private static Class<?> clazz$InjectedCacheChecker;
|
||||
|
||||
private static Class<?> clazz$InjectedArmorDyeRecipe;
|
||||
|
||||
public static void init() {
|
||||
ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17);
|
||||
clazz$InjectedCacheChecker = byteBuddy
|
||||
@@ -70,6 +78,35 @@ public class RecipeInjector {
|
||||
.make()
|
||||
.load(RecipeInjector.class.getClassLoader())
|
||||
.getLoaded();
|
||||
clazz$InjectedArmorDyeRecipe = byteBuddy
|
||||
.subclass(CoreReflections.clazz$ArmorDyeRecipe, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING)
|
||||
.name("net.momirealms.craftengine.bukkit.item.recipe.ArmorDyeRecipe")
|
||||
.method((VersionHelper.isOrAbove1_21() ?
|
||||
ElementMatchers.takesArguments(CoreReflections.clazz$CraftingInput, CoreReflections.clazz$Level) :
|
||||
ElementMatchers.takesArguments(CoreReflections.clazz$CraftingContainer, CoreReflections.clazz$Level)
|
||||
).and(ElementMatchers.returns(boolean.class)))
|
||||
.intercept(MethodDelegation.to(MatchesInterceptor.INSTANCE))
|
||||
.method((
|
||||
VersionHelper.isOrAbove1_21() ?
|
||||
ElementMatchers.takesArguments(CoreReflections.clazz$CraftingInput, CoreReflections.clazz$HolderLookup$Provider) :
|
||||
VersionHelper.isOrAbove1_20_5() ?
|
||||
ElementMatchers.takesArguments(CoreReflections.clazz$CraftingContainer, CoreReflections.clazz$HolderLookup$Provider) :
|
||||
ElementMatchers.takesArguments(CoreReflections.clazz$CraftingContainer, CoreReflections.clazz$RegistryAccess)
|
||||
).and(ElementMatchers.returns(CoreReflections.clazz$ItemStack)))
|
||||
.intercept(MethodDelegation.to(AssembleInterceptor.INSTANCE))
|
||||
.make()
|
||||
.load(RecipeInjector.class.getClassLoader())
|
||||
.getLoaded();
|
||||
}
|
||||
|
||||
public static Object createCustomDyeRecipe() throws ReflectiveOperationException {
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
Constructor<?> constructor = ReflectionUtils.getConstructor(clazz$InjectedArmorDyeRecipe, CoreReflections.clazz$CraftingBookCategory);
|
||||
return constructor.newInstance(CoreReflections.instance$CraftingBookCategory$MISC);
|
||||
} else {
|
||||
Constructor<?> constructor = ReflectionUtils.getConstructor(clazz$InjectedArmorDyeRecipe, CoreReflections.clazz$ResourceLocation, CoreReflections.clazz$CraftingBookCategory);
|
||||
return constructor.newInstance(KeyUtils.toResourceLocation(Key.of("armor_dye")), CoreReflections.instance$CraftingBookCategory$MISC);
|
||||
}
|
||||
}
|
||||
|
||||
public static void injectCookingBlockEntity(Object entity) throws ReflectiveOperationException {
|
||||
@@ -101,6 +138,139 @@ public class RecipeInjector {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Function<Object, Boolean> INGREDIENT_COUNT_CHECKER =
|
||||
VersionHelper.isOrAbove1_21() ?
|
||||
(input) -> FastNMS.INSTANCE.method$CraftingInput$ingredientCount(input) < 2 :
|
||||
(container) -> false;
|
||||
private static final Function<Object, Integer> INGREDIENT_COUNT_GETTER =
|
||||
VersionHelper.isOrAbove1_21() ?
|
||||
FastNMS.INSTANCE::method$CraftingInput$ingredientCount :
|
||||
FastNMS.INSTANCE::method$Container$getContainerSize;
|
||||
private static final BiFunction<Object, Integer, Object> INGREDIENT_GETTER =
|
||||
VersionHelper.isOrAbove1_21() ?
|
||||
FastNMS.INSTANCE::method$CraftingInput$getItem :
|
||||
FastNMS.INSTANCE::method$Container$getItem;
|
||||
|
||||
public static class MatchesInterceptor {
|
||||
public static final MatchesInterceptor INSTANCE = new MatchesInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@AllArguments Object[] args) {
|
||||
Object input = args[0];
|
||||
if (INGREDIENT_COUNT_CHECKER.apply(input)) {
|
||||
return false;
|
||||
}
|
||||
int size = INGREDIENT_COUNT_GETTER.apply(input);
|
||||
Item<ItemStack> itemToDye = null;
|
||||
boolean hasDye = false;
|
||||
for (int i = 0; i < size; i++) {
|
||||
Object itemStack = INGREDIENT_GETTER.apply(input, i);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(itemStack)) {
|
||||
continue;
|
||||
}
|
||||
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(itemStack));
|
||||
if (isDyeable(wrapped)) {
|
||||
if (itemToDye != null) {
|
||||
return false;
|
||||
}
|
||||
itemToDye = wrapped;
|
||||
} else {
|
||||
if (!isDye(wrapped)) {
|
||||
return false;
|
||||
}
|
||||
hasDye = true;
|
||||
}
|
||||
}
|
||||
return hasDye && itemToDye != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AssembleInterceptor {
|
||||
public static final AssembleInterceptor INSTANCE = new AssembleInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@AllArguments Object[] args) {
|
||||
List<Color> colors = new ArrayList<>();
|
||||
Item<ItemStack> itemToDye = null;
|
||||
Object input = args[0];
|
||||
int size = INGREDIENT_COUNT_GETTER.apply(input);
|
||||
for (int i = 0; i < size; i++) {
|
||||
Object itemStack = INGREDIENT_GETTER.apply(input, i);
|
||||
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(itemStack)) {
|
||||
continue;
|
||||
}
|
||||
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(itemStack));
|
||||
if (isDyeable(wrapped)) {
|
||||
itemToDye = wrapped.copyWithCount(1);
|
||||
} else {
|
||||
Color dyeColor = getDyeColor(wrapped);
|
||||
if (dyeColor != null) {
|
||||
colors.add(dyeColor);
|
||||
} else {
|
||||
return CoreReflections.instance$ItemStack$EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (itemToDye == null || itemToDye.isEmpty() || colors.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return itemToDye.applyDyedColors(colors).getLiteralObject();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Color getDyeColor(final Item<ItemStack> dyeItem) {
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = dyeItem.getCustomItem();
|
||||
if (optionalCustomItem.isPresent()) {
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
return Optional.ofNullable(customItem.settings().dyeColor()).orElseGet(() -> getVanillaDyeColor(dyeItem));
|
||||
}
|
||||
return getVanillaDyeColor(dyeItem);
|
||||
}
|
||||
|
||||
private static final Predicate<Item<ItemStack>> IS_DYEABLE =
|
||||
VersionHelper.isOrAbove1_20_5() ?
|
||||
(item -> item.is(ItemTags.DYEABLE)) :
|
||||
(item -> {
|
||||
Object itemLike = FastNMS.INSTANCE.method$ItemStack$getItem(item.getLiteralObject());
|
||||
return CoreReflections.clazz$DyeableLeatherItem.isInstance(itemLike);
|
||||
});
|
||||
|
||||
private static boolean isDyeable(final Item<ItemStack> item) {
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = item.getCustomItem();
|
||||
if (optionalCustomItem.isPresent()) {
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
if (customItem.settings().dyeable() == Tristate.FALSE) {
|
||||
return false;
|
||||
}
|
||||
if (customItem.settings().dyeable() == Tristate.TRUE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return IS_DYEABLE.test(item);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Color getVanillaDyeColor(final Item<ItemStack> item) {
|
||||
Object itemStack = item.getLiteralObject();
|
||||
Object dyeItem = FastNMS.INSTANCE.method$ItemStack$getItem(itemStack);
|
||||
if (!CoreReflections.clazz$DyeItem.isInstance(dyeItem)) return null;
|
||||
return Color.fromDecimal(FastNMS.INSTANCE.method$DyeColor$getTextureDiffuseColor(FastNMS.INSTANCE.method$DyeItem$getDyeColor(dyeItem)));
|
||||
}
|
||||
|
||||
private static boolean isDye(Item<ItemStack> dyeItem) {
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = dyeItem.getCustomItem();
|
||||
if (optionalCustomItem.isPresent()) {
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
return customItem.settings().dyeColor() != null || isVanillaDyeItem(dyeItem);
|
||||
}
|
||||
return isVanillaDyeItem(dyeItem);
|
||||
}
|
||||
|
||||
private static boolean isVanillaDyeItem(Item<ItemStack> item) {
|
||||
return CoreReflections.clazz$DyeItem.isInstance(FastNMS.INSTANCE.method$ItemStack$getItem(item.getLiteralObject()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public static class GetRecipeForMethodInterceptor1_20 {
|
||||
public static final GetRecipeForMethodInterceptor1_20 INSTANCE = new GetRecipeForMethodInterceptor1_20();
|
||||
@@ -110,7 +280,7 @@ public class RecipeInjector {
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||
Object lastRecipeResourceLocation = injectedCacheCheck.lastRecipe();
|
||||
Optional<Pair<Object, Object>> optionalRecipe = FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.nmsRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceLocation);
|
||||
Optional<Pair<Object, Object>> optionalRecipe = FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.minecraftRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceLocation);
|
||||
if (optionalRecipe.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -156,7 +326,7 @@ public class RecipeInjector {
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||
Object lastRecipeResourceLocation = injectedCacheCheck.lastRecipe();
|
||||
Optional<Object> optionalRecipe = (Optional<Object>) FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.nmsRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceLocation);
|
||||
Optional<Object> optionalRecipe = (Optional<Object>) FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.minecraftRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceLocation);
|
||||
if (optionalRecipe.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -202,7 +372,7 @@ public class RecipeInjector {
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||
Object lastRecipeResourceLocation = injectedCacheCheck.lastRecipe();
|
||||
Optional<Object> optionalRecipe = (Optional<Object>) FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.nmsRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceLocation);
|
||||
Optional<Object> optionalRecipe = (Optional<Object>) FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.minecraftRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceLocation);
|
||||
if (optionalRecipe.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -243,7 +413,7 @@ public class RecipeInjector {
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||
Object lastRecipeResourceKey = injectedCacheCheck.lastRecipe();
|
||||
Optional<Object> optionalRecipe = (Optional<Object>) FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.nmsRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceKey);
|
||||
Optional<Object> optionalRecipe = (Optional<Object>) FastNMS.INSTANCE.method$RecipeManager$getRecipeFor(BukkitRecipeManager.minecraftRecipeManager(), injectedCacheCheck.recipeType(), args[0], args[1], lastRecipeResourceKey);
|
||||
if (optionalRecipe.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -3903,4 +3903,67 @@ public final class CoreReflections {
|
||||
"world.item.DyeItem"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$Recipe$matches = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21() ?
|
||||
ReflectionUtils.getMethod(clazz$Recipe, boolean.class, clazz$RecipeInput, clazz$Level) :
|
||||
ReflectionUtils.getMethod(clazz$Recipe, boolean.class, clazz$Container, clazz$Level)
|
||||
);
|
||||
|
||||
public static final Method method$Recipe$assemble = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21() ?
|
||||
ReflectionUtils.getMethod(clazz$Recipe, clazz$ItemStack, clazz$RecipeInput, clazz$HolderLookup$Provider) :
|
||||
VersionHelper.isOrAbove1_20_5() ?
|
||||
ReflectionUtils.getMethod(clazz$Recipe, clazz$ItemStack, clazz$Container, clazz$HolderLookup$Provider) :
|
||||
ReflectionUtils.getMethod(clazz$Recipe, clazz$ItemStack, clazz$Container, clazz$RegistryAccess)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$CraftingBookCategory = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.crafting.CraftingBookCategory",
|
||||
"world.item.crafting.CraftingBookCategory"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$CraftingBookCategory$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(clazz$CraftingBookCategory, clazz$CraftingBookCategory.arrayType())
|
||||
);
|
||||
|
||||
public static final Object instance$CraftingBookCategory$BUILDING;
|
||||
public static final Object instance$CraftingBookCategory$REDSTONE;
|
||||
public static final Object instance$CraftingBookCategory$EQUIPMENT;
|
||||
public static final Object instance$CraftingBookCategory$MISC;
|
||||
|
||||
static {
|
||||
try {
|
||||
Object[] values = (Object[]) method$CraftingBookCategory$values.invoke(null);
|
||||
instance$CraftingBookCategory$BUILDING = values[0];
|
||||
instance$CraftingBookCategory$REDSTONE = values[1];
|
||||
instance$CraftingBookCategory$EQUIPMENT = values[2];
|
||||
instance$CraftingBookCategory$MISC = values[3];
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ReflectionInitException("Failed to initialize CraftingBookCategory", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$CraftingInput = MiscUtils.requireNonNullIf(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.crafting.CraftingInput",
|
||||
"world.item.crafting.CraftingInput"
|
||||
), VersionHelper.isOrAbove1_21()
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$CraftingContainer = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.inventory.InventoryCrafting",
|
||||
"world.inventory.CraftingContainer"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$DyeableLeatherItem = MiscUtils.requireNonNullIf(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.IDyeable",
|
||||
"world.item.DyeableLeatherItem"
|
||||
), !VersionHelper.isOrAbove1_20_5()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class MItems {
|
||||
private MItems() {}
|
||||
@@ -9,11 +12,17 @@ public final class MItems {
|
||||
public static final Object WATER_BUCKET;
|
||||
public static final Object BARRIER;
|
||||
|
||||
@Nullable
|
||||
private static Object getById(String id) {
|
||||
Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id);
|
||||
return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, rl);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Object getById(Key id) {
|
||||
return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(id));
|
||||
}
|
||||
|
||||
static {
|
||||
AIR = getById("air");
|
||||
WATER_BUCKET = getById("water_bucket");
|
||||
|
||||
@@ -7,7 +7,6 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries
|
||||
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.sound.AbstractSoundManager;
|
||||
import net.momirealms.craftengine.core.sound.JukeboxSong;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
@@ -12,6 +12,7 @@ public class ItemTags {
|
||||
|
||||
public static final Key AXES = Key.of("minecraft:axes");
|
||||
public static final Key SWORDS = Key.of("minecraft:swords");
|
||||
public static final Key DYEABLE = Key.of("minecraft:dyeable");
|
||||
|
||||
private ItemTags() {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user