mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 17:09:19 +00:00
优化熔炉性能,保证线程安全
This commit is contained in:
@@ -160,7 +160,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
for (Map.Entry<Integer, List<String>> entry : this.clientBoundTags.entrySet()) {
|
for (Map.Entry<Integer, List<String>> entry : this.clientBoundTags.entrySet()) {
|
||||||
list.add(new TagUtils.TagEntry(entry.getKey(), entry.getValue()));
|
list.add(new TagUtils.TagEntry(entry.getKey(), entry.getValue()));
|
||||||
}
|
}
|
||||||
Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.instance$Registries$BLOCK, list));
|
Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, list));
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
this.plugin.networkManager().sendPacket(this.plugin.adapt(player), packet);
|
this.plugin.networkManager().sendPacket(this.plugin.adapt(player), packet);
|
||||||
}
|
}
|
||||||
@@ -762,7 +762,7 @@ public class BukkitBlockManager extends AbstractBlockManager {
|
|||||||
private Object createBlockProperties(Key realBlockKey) throws Exception {
|
private Object createBlockProperties(Key realBlockKey) throws Exception {
|
||||||
Object blockProperties = CoreReflections.method$BlockBehaviour$Properties$of.invoke(null);
|
Object blockProperties = CoreReflections.method$BlockBehaviour$Properties$of.invoke(null);
|
||||||
Object realBlockResourceLocation = createResourceLocation(realBlockKey);
|
Object realBlockResourceLocation = createResourceLocation(realBlockKey);
|
||||||
Object realBlockResourceKey = CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.instance$Registries$BLOCK, realBlockResourceLocation);
|
Object realBlockResourceKey = CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.BLOCK, realBlockResourceLocation);
|
||||||
if (CoreReflections.field$BlockBehaviour$Properties$id != null) {
|
if (CoreReflections.field$BlockBehaviour$Properties$id != null) {
|
||||||
CoreReflections.field$BlockBehaviour$Properties$id.set(blockProperties, realBlockResourceKey);
|
CoreReflections.field$BlockBehaviour$Properties$id.set(blockProperties, realBlockResourceKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
|
|||||||
Object holder = BukkitCraftEngine.instance().blockManager().getMinecraftBlockHolder(state.customBlockState().registryId());
|
Object holder = BukkitCraftEngine.instance().blockManager().getMinecraftBlockHolder(state.customBlockState().registryId());
|
||||||
Set<Object> tags = new HashSet<>();
|
Set<Object> tags = new HashSet<>();
|
||||||
for (Key tag : settings.tags()) {
|
for (Key tag : settings.tags()) {
|
||||||
tags.add(CoreReflections.method$TagKey$create.invoke(null, MRegistries.instance$Registries$BLOCK, KeyUtils.toResourceLocation(tag)));
|
tags.add(CoreReflections.method$TagKey$create.invoke(null, MRegistries.BLOCK, KeyUtils.toResourceLocation(tag)));
|
||||||
}
|
}
|
||||||
CoreReflections.field$Holder$Reference$tags.set(holder, tags);
|
CoreReflections.field$Holder$Reference$tags.set(holder, tags);
|
||||||
// set burning properties
|
// set burning properties
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class SaplingBlockBehavior extends BukkitBlockBehavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateTree(Object world, Object blockPos, Object blockState, Object randomSource) throws Exception {
|
private void generateTree(Object world, Object blockPos, Object blockState, Object randomSource) throws Exception {
|
||||||
Object registry = CoreReflections.method$RegistryAccess$registryOrThrow.invoke(FastNMS.INSTANCE.registryAccess(), MRegistries.instance$Registries$CONFIGURED_FEATURE);
|
Object registry = CoreReflections.method$RegistryAccess$registryOrThrow.invoke(FastNMS.INSTANCE.registryAccess(), MRegistries.CONFIGURED_FEATURE);
|
||||||
if (registry == null) return;
|
if (registry == null) return;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Optional<Object> holder = (Optional<Object>) CoreReflections.method$Registry$getHolder1.invoke(registry, FeatureUtils.createFeatureKey(treeFeature()));
|
Optional<Object> holder = (Optional<Object>) CoreReflections.method$Registry$getHolder1.invoke(registry, FeatureUtils.createFeatureKey(treeFeature()));
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
|
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
|
||||||
.register(new ResourceKey<>(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
|
.register(new ResourceKey<>(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
|
||||||
Object resourceLocation = KeyUtils.toResourceLocation(id.namespace(), id.value());
|
Object resourceLocation = KeyUtils.toResourceLocation(id.namespace(), id.value());
|
||||||
Object mcHolder = ((Optional<Object>) CoreReflections.method$Registry$getHolder1.invoke(MBuiltInRegistries.ITEM, CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.instance$Registries$ITEM, resourceLocation))).get();
|
Object mcHolder = ((Optional<Object>) CoreReflections.method$Registry$getHolder1.invoke(MBuiltInRegistries.ITEM, CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.ITEM, resourceLocation))).get();
|
||||||
Set<Object> tags = (Set<Object>) CoreReflections.field$Holder$Reference$tags.get(mcHolder);
|
Set<Object> tags = (Set<Object>) CoreReflections.field$Holder$Reference$tags.get(mcHolder);
|
||||||
for (Object tag : tags) {
|
for (Object tag : tags) {
|
||||||
Key tagId = Key.of(CoreReflections.field$TagKey$location.get(tag).toString());
|
Key tagId = Key.of(CoreReflections.field$TagKey$location.get(tag).toString());
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
|||||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
|
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.CoreReflections;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||||
import net.momirealms.craftengine.bukkit.util.MaterialUtils;
|
import net.momirealms.craftengine.bukkit.util.MaterialUtils;
|
||||||
import net.momirealms.craftengine.bukkit.util.RecipeUtils;
|
import net.momirealms.craftengine.bukkit.util.RecipeUtils;
|
||||||
@@ -45,9 +46,9 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
// 将自定义配方转为“广义”配方,接受更加宽容的输入
|
// 将自定义配方转为“广义”配方,接受更加宽容的输入
|
||||||
// 部分过程借助bukkit完成,部分直接通过nms方法注册
|
// 部分过程借助bukkit完成,部分直接通过nms方法注册
|
||||||
private static final Map<Key, BukkitRecipeConvertor<? extends Recipe<ItemStack>>> MIXED_RECIPE_CONVERTORS = new HashMap<>();
|
private static final Map<Key, BukkitRecipeConvertor<? extends Recipe<ItemStack>>> MIXED_RECIPE_CONVERTORS = new HashMap<>();
|
||||||
private static Object nmsRecipeManager;
|
|
||||||
private static final List<Object> injectedIngredients = new ArrayList<>();
|
private static final List<Object> injectedIngredients = new ArrayList<>();
|
||||||
private static final IdentityHashMap<Recipe<ItemStack>, Object> recipeToMcRecipeHolder = new IdentityHashMap<>();
|
private static final IdentityHashMap<Recipe<ItemStack>, Object> CE_RECIPE_2_NMS_HOLDER = new IdentityHashMap<>();
|
||||||
|
private static Object nmsRecipeManager;
|
||||||
|
|
||||||
private static void registerNMSSmithingRecipe(Object recipe) {
|
private static void registerNMSSmithingRecipe(Object recipe) {
|
||||||
try {
|
try {
|
||||||
@@ -265,7 +266,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object nmsRecipeHolderByRecipe(Recipe<ItemStack> recipe) {
|
public Object nmsRecipeHolderByRecipe(Recipe<ItemStack> recipe) {
|
||||||
return recipeToMcRecipeHolder.get(recipe);
|
if (super.isReloading) return null;
|
||||||
|
return CE_RECIPE_2_NMS_HOLDER.get(recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object nmsRecipeManager() {
|
public static Object nmsRecipeManager() {
|
||||||
@@ -287,6 +289,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
if (!Config.enableRecipeSystem()) return;
|
if (!Config.enableRecipeSystem()) return;
|
||||||
|
super.isReloading = true;
|
||||||
if (VersionHelper.isOrAbove1_21_2()) {
|
if (VersionHelper.isOrAbove1_21_2()) {
|
||||||
try {
|
try {
|
||||||
this.stolenFeatureFlagSet = CoreReflections.field$RecipeManager$featureflagset.get(nmsRecipeManager);
|
this.stolenFeatureFlagSet = CoreReflections.field$RecipeManager$featureflagset.get(nmsRecipeManager);
|
||||||
@@ -308,7 +311,6 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
this.plugin.logger().warn("Failed to unregister recipes", e);
|
this.plugin.logger().warn("Failed to unregister recipes", e);
|
||||||
}
|
}
|
||||||
recipeToMcRecipeHolder.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -320,6 +322,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
unload();
|
unload();
|
||||||
|
CE_RECIPE_2_NMS_HOLDER.clear();
|
||||||
HandlerList.unregisterAll(this.recipeEventListener);
|
HandlerList.unregisterAll(this.recipeEventListener);
|
||||||
if (this.crafterEventListener != null) {
|
if (this.crafterEventListener != null) {
|
||||||
HandlerList.unregisterAll(this.crafterEventListener);
|
HandlerList.unregisterAll(this.crafterEventListener);
|
||||||
@@ -473,6 +476,15 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
|
|
||||||
// clear cache
|
// clear cache
|
||||||
injectedIngredients.clear();
|
injectedIngredients.clear();
|
||||||
|
|
||||||
|
CE_RECIPE_2_NMS_HOLDER.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
super.isReloading = false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.plugin.logger().warn("Failed to run delayed recipe tasks", e);
|
this.plugin.logger().warn("Failed to run delayed recipe tasks", e);
|
||||||
}
|
}
|
||||||
@@ -691,7 +703,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
return optionalItem.map(itemStackCustomItem -> MaterialUtils.getMaterial(itemStackCustomItem.material())).orElse(null);
|
return optionalItem.map(itemStackCustomItem -> MaterialUtils.getMaterial(itemStackCustomItem.material())).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Object> getIngredientLooks(List<Holder<Key>> holders) throws ReflectiveOperationException {
|
private static List<Object> getIngredientLooks(List<Holder<Key>> holders) {
|
||||||
List<Object> itemStacks = new ArrayList<>();
|
List<Object> itemStacks = new ArrayList<>();
|
||||||
for (Holder<Key> holder : holders) {
|
for (Holder<Key> holder : holders) {
|
||||||
ItemStack itemStack = BukkitItemManager.instance().getBuildableItem(holder.value()).get().buildItemStack(ItemBuildContext.EMPTY, 1);
|
ItemStack itemStack = BukkitItemManager.instance().getBuildableItem(holder.value()).get().buildItemStack(ItemBuildContext.EMPTY, 1);
|
||||||
@@ -710,8 +722,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
.map(Optional::get)
|
.map(Optional::get)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
Object shapedRecipe = getNMSRecipe(id);
|
Object shapedRecipe = getOptionalNMSRecipe(id).get();
|
||||||
recipeToMcRecipeHolder.put(recipe, shapedRecipe);
|
|
||||||
if (VersionHelper.isOrAbove1_20_2()) {
|
if (VersionHelper.isOrAbove1_20_2()) {
|
||||||
shapedRecipe = CoreReflections.field$RecipeHolder$recipe.get(shapedRecipe);
|
shapedRecipe = CoreReflections.field$RecipeHolder$recipe.get(shapedRecipe);
|
||||||
}
|
}
|
||||||
@@ -731,8 +742,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
try {
|
try {
|
||||||
List<Ingredient<ItemStack>> actualIngredients = recipe.ingredientsInUse();
|
List<Ingredient<ItemStack>> actualIngredients = recipe.ingredientsInUse();
|
||||||
|
|
||||||
Object shapelessRecipe = getNMSRecipe(id);
|
Object shapelessRecipe = getOptionalNMSRecipe(id).get();
|
||||||
recipeToMcRecipeHolder.put(recipe, shapelessRecipe);
|
|
||||||
if (VersionHelper.isOrAbove1_20_2()) {
|
if (VersionHelper.isOrAbove1_20_2()) {
|
||||||
shapelessRecipe = CoreReflections.field$RecipeHolder$recipe.get(shapelessRecipe);
|
shapelessRecipe = CoreReflections.field$RecipeHolder$recipe.get(shapelessRecipe);
|
||||||
}
|
}
|
||||||
@@ -751,8 +761,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
private static void injectCookingRecipe(Key id, CustomCookingRecipe<ItemStack> recipe) {
|
private static void injectCookingRecipe(Key id, CustomCookingRecipe<ItemStack> recipe) {
|
||||||
try {
|
try {
|
||||||
Ingredient<ItemStack> actualIngredient = recipe.ingredient();
|
Ingredient<ItemStack> actualIngredient = recipe.ingredient();
|
||||||
Object smeltingRecipe = getNMSRecipe(id);
|
Object smeltingRecipe = getOptionalNMSRecipe(id).get();
|
||||||
recipeToMcRecipeHolder.put(recipe, smeltingRecipe);
|
|
||||||
if (VersionHelper.isOrAbove1_20_2()) {
|
if (VersionHelper.isOrAbove1_20_2()) {
|
||||||
smeltingRecipe = CoreReflections.field$RecipeHolder$recipe.get(smeltingRecipe);
|
smeltingRecipe = CoreReflections.field$RecipeHolder$recipe.get(smeltingRecipe);
|
||||||
}
|
}
|
||||||
@@ -771,23 +780,17 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
|||||||
|
|
||||||
// 获取nms配方,请注意1.20.1获取配方本身,而1.20.2+获取的是配方的holder
|
// 获取nms配方,请注意1.20.1获取配方本身,而1.20.2+获取的是配方的holder
|
||||||
// recipe on 1.20.1 and holder on 1.20.2+
|
// recipe on 1.20.1 and holder on 1.20.2+
|
||||||
private static Object getNMSRecipe(Key id) throws ReflectiveOperationException {
|
private static Optional<Object> getOptionalNMSRecipe(Key id) throws ReflectiveOperationException {
|
||||||
if (VersionHelper.isOrAbove1_21_2()) {
|
if (VersionHelper.isOrAbove1_21_2()) {
|
||||||
Object resourceKey = CraftBukkitReflections.method$CraftRecipe$toMinecraft.invoke(null, new NamespacedKey(id.namespace(), id.value()));
|
Object resourceKey = FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.RECIPE, KeyUtils.toResourceLocation(id));
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceKey);
|
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceKey);
|
||||||
if (optional.isEmpty()) {
|
return optional;
|
||||||
throw new IllegalArgumentException("Recipe " + id + " not found");
|
|
||||||
}
|
|
||||||
return optional.get();
|
|
||||||
} else {
|
} else {
|
||||||
Object resourceLocation = KeyUtils.toResourceLocation(id);
|
Object resourceLocation = KeyUtils.toResourceLocation(id);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceLocation);
|
Optional<Object> optional = (Optional<Object>) CoreReflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceLocation);
|
||||||
if (optional.isEmpty()) {
|
return optional;
|
||||||
throw new IllegalArgumentException("Recipe " + id + " not found");
|
|
||||||
}
|
|
||||||
return optional.get();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -843,7 +843,7 @@ public class RecipeEventListener implements Listener {
|
|||||||
try {
|
try {
|
||||||
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(event.getView());
|
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(event.getView());
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
plugin.logger().warn("Failed to get inventory viewer", e);
|
this.plugin.logger().warn("Failed to get inventory viewer", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,14 +854,18 @@ public class RecipeEventListener implements Listener {
|
|||||||
if (ceRecipe != null) {
|
if (ceRecipe != null) {
|
||||||
inventory.setResult(ceRecipe.result(new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
inventory.setResult(ceRecipe.result(new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
||||||
serverPlayer.setLastUsedRecipe(ceRecipe.id());
|
serverPlayer.setLastUsedRecipe(ceRecipe.id());
|
||||||
correctCraftingRecipeUsed(inventory, ceRecipe);
|
if (!ceRecipe.id().equals(recipeId)) {
|
||||||
|
correctCraftingRecipeUsed(inventory, ceRecipe);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SHAPED, input, lastRecipe);
|
ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SHAPED, input, lastRecipe);
|
||||||
if (ceRecipe != null) {
|
if (ceRecipe != null) {
|
||||||
inventory.setResult(ceRecipe.result(new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
inventory.setResult(ceRecipe.result(new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
||||||
serverPlayer.setLastUsedRecipe(ceRecipe.id());
|
serverPlayer.setLastUsedRecipe(ceRecipe.id());
|
||||||
correctCraftingRecipeUsed(inventory, ceRecipe);
|
if (!ceRecipe.id().equals(recipeId)) {
|
||||||
|
correctCraftingRecipeUsed(inventory, ceRecipe);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// clear result if not met
|
// clear result if not met
|
||||||
@@ -869,9 +873,8 @@ public class RecipeEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void correctCraftingRecipeUsed(CraftingInventory inventory, Recipe<ItemStack> recipe) {
|
private void correctCraftingRecipeUsed(CraftingInventory inventory, Recipe<ItemStack> recipe) {
|
||||||
Object holderOrRecipe = recipeManager.nmsRecipeHolderByRecipe(recipe);
|
Object holderOrRecipe = this.recipeManager.nmsRecipeHolderByRecipe(recipe);
|
||||||
if (holderOrRecipe == null) {
|
if (holderOrRecipe == null) {
|
||||||
// it's a vanilla recipe but not injected
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -922,20 +925,21 @@ public class RecipeEventListener implements Listener {
|
|||||||
CustomSmithingTransformRecipe<ItemStack> transformRecipe = (CustomSmithingTransformRecipe<ItemStack>) ceRecipe;
|
CustomSmithingTransformRecipe<ItemStack> transformRecipe = (CustomSmithingTransformRecipe<ItemStack>) ceRecipe;
|
||||||
ItemStack processed = transformRecipe.assemble(new ItemBuildContext(this.plugin.adapt(player), ContextHolder.EMPTY), this.itemManager.wrap(base));
|
ItemStack processed = transformRecipe.assemble(new ItemBuildContext(this.plugin.adapt(player), ContextHolder.EMPTY), this.itemManager.wrap(base));
|
||||||
event.setResult(processed);
|
event.setResult(processed);
|
||||||
correctSmithingRecipeUsed(inventory, ceRecipe);
|
if (!ceRecipe.id().equals(recipeId)) {
|
||||||
|
correctSmithingRecipeUsed(inventory, ceRecipe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void correctSmithingRecipeUsed(SmithingInventory inventory, Recipe<ItemStack> recipe) {
|
private void correctSmithingRecipeUsed(SmithingInventory inventory, Recipe<ItemStack> recipe) {
|
||||||
Object holderOrRecipe = recipeManager.nmsRecipeHolderByRecipe(recipe);
|
Object holderOrRecipe = this.recipeManager.nmsRecipeHolderByRecipe(recipe);
|
||||||
if (holderOrRecipe == null) {
|
if (holderOrRecipe == null) {
|
||||||
// it's a vanilla recipe but not injected
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Object resultInventory = CraftBukkitReflections.field$CraftResultInventory$resultInventory.get(inventory);
|
Object resultInventory = CraftBukkitReflections.field$CraftResultInventory$resultInventory.get(inventory);
|
||||||
CoreReflections.field$ResultContainer$recipeUsed.set(resultInventory, holderOrRecipe);
|
CoreReflections.field$ResultContainer$recipeUsed.set(resultInventory, holderOrRecipe);
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
plugin.logger().warn("Failed to correct used recipe", e);
|
this.plugin.logger().warn("Failed to correct used recipe", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ public interface InjectedCacheCheck {
|
|||||||
|
|
||||||
void recipeType(Object recipeType);
|
void recipeType(Object recipeType);
|
||||||
|
|
||||||
|
Key customRecipeType();
|
||||||
|
|
||||||
|
void customRecipeType(Key customRecipeType);
|
||||||
|
|
||||||
Object lastRecipe();
|
Object lastRecipe();
|
||||||
|
|
||||||
void lastRecipe(Object lastRecipe);
|
void lastRecipe(Object lastRecipe);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager;
|
|||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
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.MRecipeTypes;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.item.recipe.CustomCookingRecipe;
|
import net.momirealms.craftengine.core.item.recipe.CustomCookingRecipe;
|
||||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||||
@@ -28,7 +30,6 @@ import net.momirealms.craftengine.core.util.ReflectionUtils;
|
|||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class RecipeInjector {
|
public class RecipeInjector {
|
||||||
@@ -41,17 +42,23 @@ public class RecipeInjector {
|
|||||||
.name("net.momirealms.craftengine.bukkit.entity.InjectedCacheChecker")
|
.name("net.momirealms.craftengine.bukkit.entity.InjectedCacheChecker")
|
||||||
.implement(CoreReflections.clazz$RecipeManager$CachedCheck)
|
.implement(CoreReflections.clazz$RecipeManager$CachedCheck)
|
||||||
.implement(InjectedCacheCheck.class)
|
.implement(InjectedCacheCheck.class)
|
||||||
|
|
||||||
.defineField("recipeType", Object.class, Visibility.PUBLIC)
|
.defineField("recipeType", Object.class, Visibility.PUBLIC)
|
||||||
.method(ElementMatchers.named("recipeType"))
|
.method(ElementMatchers.named("recipeType"))
|
||||||
.intercept(FieldAccessor.ofField("recipeType"))
|
.intercept(FieldAccessor.ofField("recipeType"))
|
||||||
|
|
||||||
|
.defineField("customRecipeType", Key.class, Visibility.PUBLIC)
|
||||||
|
.method(ElementMatchers.named("customRecipeType"))
|
||||||
|
.intercept(FieldAccessor.ofField("customRecipeType"))
|
||||||
|
|
||||||
.defineField("lastRecipe", Object.class, Visibility.PUBLIC)
|
.defineField("lastRecipe", Object.class, Visibility.PUBLIC)
|
||||||
.method(ElementMatchers.named("lastRecipe"))
|
.method(ElementMatchers.named("lastRecipe"))
|
||||||
.intercept(FieldAccessor.ofField("lastRecipe"))
|
.intercept(FieldAccessor.ofField("lastRecipe"))
|
||||||
.method(ElementMatchers.named("setLastRecipe"))
|
|
||||||
.intercept(FieldAccessor.ofField("lastRecipe"))
|
|
||||||
.defineField("lastCustomRecipe", Key.class, Visibility.PUBLIC)
|
.defineField("lastCustomRecipe", Key.class, Visibility.PUBLIC)
|
||||||
.method(ElementMatchers.named("lastCustomRecipe"))
|
.method(ElementMatchers.named("lastCustomRecipe"))
|
||||||
.intercept(FieldAccessor.ofField("lastCustomRecipe"))
|
.intercept(FieldAccessor.ofField("lastCustomRecipe"))
|
||||||
|
|
||||||
.method(ElementMatchers.named("getRecipeFor").or(ElementMatchers.named("a")))
|
.method(ElementMatchers.named("getRecipeFor").or(ElementMatchers.named("a")))
|
||||||
.intercept(MethodDelegation.to(
|
.intercept(MethodDelegation.to(
|
||||||
VersionHelper.isOrAbove1_21_2() ?
|
VersionHelper.isOrAbove1_21_2() ?
|
||||||
@@ -73,269 +80,227 @@ public class RecipeInjector {
|
|||||||
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
|
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
|
||||||
Object recipeType = FastNMS.INSTANCE.field$AbstractFurnaceBlockEntity$recipeType(entity);
|
Object recipeType = FastNMS.INSTANCE.field$AbstractFurnaceBlockEntity$recipeType(entity);
|
||||||
InjectedCacheCheck injectedChecker = (InjectedCacheCheck) ReflectionUtils.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
|
InjectedCacheCheck injectedChecker = (InjectedCacheCheck) ReflectionUtils.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
|
||||||
injectedChecker.recipeType(recipeType);
|
if (recipeType == MRecipeTypes.SMELTING) {
|
||||||
|
injectedChecker.customRecipeType(RecipeTypes.SMELTING);
|
||||||
|
injectedChecker.recipeType(MRecipeTypes.SMELTING);
|
||||||
|
} else if (recipeType == MRecipeTypes.BLASTING) {
|
||||||
|
injectedChecker.customRecipeType(RecipeTypes.BLASTING);
|
||||||
|
injectedChecker.recipeType(MRecipeTypes.BLASTING);
|
||||||
|
} else if (recipeType == MRecipeTypes.SMOKING) {
|
||||||
|
injectedChecker.customRecipeType(RecipeTypes.SMOKING);
|
||||||
|
injectedChecker.recipeType(MRecipeTypes.SMOKING);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("RecipeType " + recipeType + " not supported");
|
||||||
|
}
|
||||||
CoreReflections.field$AbstractFurnaceBlockEntity$quickCheck.set(entity, injectedChecker);
|
CoreReflections.field$AbstractFurnaceBlockEntity$quickCheck.set(entity, injectedChecker);
|
||||||
} else if (!VersionHelper.isOrAbove1_21_2() && CoreReflections.clazz$CampfireBlockEntity.isInstance(entity)) {
|
} else if (!VersionHelper.isOrAbove1_21_2() && CoreReflections.clazz$CampfireBlockEntity.isInstance(entity)) {
|
||||||
Object quickCheck = CoreReflections.field$CampfireBlockEntity$quickCheck.get(entity);
|
Object quickCheck = CoreReflections.field$CampfireBlockEntity$quickCheck.get(entity);
|
||||||
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
|
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
|
||||||
InjectedCacheCheck injectedChecker = (InjectedCacheCheck) ReflectionUtils.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
|
InjectedCacheCheck injectedChecker = (InjectedCacheCheck) ReflectionUtils.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
|
||||||
|
injectedChecker.customRecipeType(RecipeTypes.CAMPFIRE_COOKING);
|
||||||
injectedChecker.recipeType(MRecipeTypes.CAMPFIRE_COOKING);
|
injectedChecker.recipeType(MRecipeTypes.CAMPFIRE_COOKING);
|
||||||
CoreReflections.field$CampfireBlockEntity$quickCheck.set(entity, injectedChecker);
|
CoreReflections.field$CampfireBlockEntity$quickCheck.set(entity, injectedChecker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
public static class GetRecipeForMethodInterceptor1_20 {
|
public static class GetRecipeForMethodInterceptor1_20 {
|
||||||
public static final GetRecipeForMethodInterceptor1_20 INSTANCE = new GetRecipeForMethodInterceptor1_20();
|
public static final GetRecipeForMethodInterceptor1_20 INSTANCE = new GetRecipeForMethodInterceptor1_20();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@RuntimeType
|
@RuntimeType
|
||||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) throws Exception {
|
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||||
Object mcRecipeManager = BukkitRecipeManager.nmsRecipeManager();
|
|
||||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||||
Object type = injectedCacheCheck.recipeType();
|
Object lastRecipeResourceLocation = injectedCacheCheck.lastRecipe();
|
||||||
Object lastRecipe = 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(mcRecipeManager, type, args[0], args[1], lastRecipe);
|
if (optionalRecipe.isEmpty()) {
|
||||||
if (optionalRecipe.isPresent()) {
|
|
||||||
Pair<Object, Object> pair = optionalRecipe.get();
|
|
||||||
Object resourceLocation = pair.getFirst();
|
|
||||||
Key recipeId = Key.of(resourceLocation.toString());
|
|
||||||
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
|
||||||
|
|
||||||
ItemStack itemStack;
|
|
||||||
List<Object> items;
|
|
||||||
if (type == MRecipeTypes.CAMPFIRE_COOKING) {
|
|
||||||
items = (List<Object>) CoreReflections.field$SimpleContainer$items.get(args[0]);
|
|
||||||
} else {
|
|
||||||
items = (List<Object>) CoreReflections.field$AbstractFurnaceBlockEntity$items.get(args[0]);
|
|
||||||
}
|
|
||||||
itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(items.get(0));
|
|
||||||
|
|
||||||
// it's a recipe from other plugins
|
|
||||||
boolean isCustom = recipeManager.isCustomRecipe(recipeId);
|
|
||||||
if (!isCustom) {
|
|
||||||
injectedCacheCheck.lastRecipe(resourceLocation);
|
|
||||||
return Optional.of(pair.getSecond());
|
|
||||||
}
|
|
||||||
|
|
||||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
|
||||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
|
||||||
if (idHolder.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
|
||||||
CustomCookingRecipe<ItemStack> ceRecipe;
|
|
||||||
Key lastCustomRecipe = injectedCacheCheck.lastCustomRecipe();
|
|
||||||
if (type == MRecipeTypes.SMELTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMELTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.BLASTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.BLASTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.SMOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMOKING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.CAMPFIRE_COOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input, lastCustomRecipe);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (ceRecipe == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache recipes, it might be incorrect on reloading
|
|
||||||
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
|
||||||
// It doesn't matter at all
|
|
||||||
injectedCacheCheck.lastRecipe(resourceLocation);
|
|
||||||
return Optional.of(Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe)).orElse(pair.getSecond()));
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair<Object, Object> resourceLocationAndRecipe = optionalRecipe.get();
|
||||||
|
Object rawRecipeResourceLocation = resourceLocationAndRecipe.getFirst();
|
||||||
|
Key rawRecipeKey = Key.of(rawRecipeResourceLocation.toString());
|
||||||
|
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
||||||
|
|
||||||
|
boolean isCustom = recipeManager.isCustomRecipe(rawRecipeKey);
|
||||||
|
if (!isCustom) {
|
||||||
|
injectedCacheCheck.lastRecipe(rawRecipeResourceLocation);
|
||||||
|
return Optional.of(resourceLocationAndRecipe.getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(
|
||||||
|
injectedCacheCheck.recipeType() == MRecipeTypes.CAMPFIRE_COOKING ?
|
||||||
|
FastNMS.INSTANCE.field$SimpleContainer$items(args[0]).getFirst() :
|
||||||
|
FastNMS.INSTANCE.field$AbstractFurnaceBlockEntity$getItem(args[0], 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||||
|
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||||
|
if (idHolder.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||||
|
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||||
|
if (ceRecipe == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
||||||
|
if (!ceRecipe.id().equals(rawRecipeKey)) {
|
||||||
|
injectedCacheCheck.lastRecipe(KeyUtils.toResourceLocation(ceRecipe.id()));
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe)).orElse(resourceLocationAndRecipe.getSecond());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
public static class GetRecipeForMethodInterceptor1_20_5 {
|
public static class GetRecipeForMethodInterceptor1_20_5 {
|
||||||
public static final GetRecipeForMethodInterceptor1_20_5 INSTANCE = new GetRecipeForMethodInterceptor1_20_5();
|
public static final GetRecipeForMethodInterceptor1_20_5 INSTANCE = new GetRecipeForMethodInterceptor1_20_5();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@RuntimeType
|
@RuntimeType
|
||||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) throws Exception {
|
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||||
Object mcRecipeManager = BukkitRecipeManager.nmsRecipeManager();
|
|
||||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||||
Object type = injectedCacheCheck.recipeType();
|
Object lastRecipeResourceLocation = injectedCacheCheck.lastRecipe();
|
||||||
Object lastRecipe = 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(mcRecipeManager, type, args[0], args[1], lastRecipe);
|
if (optionalRecipe.isEmpty()) {
|
||||||
if (optionalRecipe.isPresent()) {
|
|
||||||
Object holder = optionalRecipe.get();
|
|
||||||
Object id = FastNMS.INSTANCE.field$RecipeHolder$id(holder);
|
|
||||||
Key recipeId = Key.of(id.toString());
|
|
||||||
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
|
||||||
|
|
||||||
ItemStack itemStack;
|
|
||||||
List<Object> items;
|
|
||||||
if (type == MRecipeTypes.CAMPFIRE_COOKING) {
|
|
||||||
items = (List<Object>) CoreReflections.field$SimpleContainer$items.get(args[0]);
|
|
||||||
} else {
|
|
||||||
items = (List<Object>) CoreReflections.field$AbstractFurnaceBlockEntity$items.get(args[0]);
|
|
||||||
}
|
|
||||||
itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(items.get(0));
|
|
||||||
|
|
||||||
// it's a recipe from other plugins
|
|
||||||
boolean isCustom = recipeManager.isCustomRecipe(recipeId);
|
|
||||||
if (!isCustom) {
|
|
||||||
injectedCacheCheck.lastRecipe(id);
|
|
||||||
return optionalRecipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
|
||||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
|
||||||
if (idHolder.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
|
||||||
CustomCookingRecipe<ItemStack> ceRecipe;
|
|
||||||
Key lastCustomRecipe = injectedCacheCheck.lastCustomRecipe();
|
|
||||||
if (type == MRecipeTypes.SMELTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMELTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.BLASTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.BLASTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.SMOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMOKING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.CAMPFIRE_COOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input, lastCustomRecipe);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (ceRecipe == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache recipes, it might be incorrect on reloading
|
|
||||||
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
|
||||||
// It doesn't matter at all
|
|
||||||
injectedCacheCheck.lastRecipe(id);
|
|
||||||
return Optional.of(Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe)).orElse(holder));
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object rawRecipeHolder = optionalRecipe.get();
|
||||||
|
Object rawRecipeResourceLocation = FastNMS.INSTANCE.field$RecipeHolder$id(rawRecipeHolder);
|
||||||
|
Key rawRecipeKey = Key.of(rawRecipeResourceLocation.toString());
|
||||||
|
|
||||||
|
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
||||||
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(
|
||||||
|
injectedCacheCheck.recipeType() == MRecipeTypes.CAMPFIRE_COOKING ?
|
||||||
|
FastNMS.INSTANCE.field$SimpleContainer$items(args[0]).getFirst() :
|
||||||
|
FastNMS.INSTANCE.field$AbstractFurnaceBlockEntity$getItem(args[0], 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean isCustom = recipeManager.isCustomRecipe(rawRecipeKey);
|
||||||
|
if (!isCustom) {
|
||||||
|
injectedCacheCheck.lastRecipe(rawRecipeResourceLocation);
|
||||||
|
return optionalRecipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||||
|
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||||
|
if (idHolder.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||||
|
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||||
|
if (ceRecipe == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
||||||
|
if (!ceRecipe.id().equals(rawRecipeKey)) {
|
||||||
|
injectedCacheCheck.lastRecipe(KeyUtils.toResourceLocation(ceRecipe.id()));
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
public static class GetRecipeForMethodInterceptor1_21 {
|
public static class GetRecipeForMethodInterceptor1_21 {
|
||||||
public static final GetRecipeForMethodInterceptor1_21 INSTANCE = new GetRecipeForMethodInterceptor1_21();
|
public static final GetRecipeForMethodInterceptor1_21 INSTANCE = new GetRecipeForMethodInterceptor1_21();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@RuntimeType
|
@RuntimeType
|
||||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) throws Exception {
|
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||||
Object mcRecipeManager = BukkitRecipeManager.nmsRecipeManager();
|
|
||||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||||
Object type = injectedCacheCheck.recipeType();
|
Object lastRecipeResourceLocation = injectedCacheCheck.lastRecipe();
|
||||||
Object lastRecipe = 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(mcRecipeManager, type, args[0], args[1], lastRecipe);
|
if (optionalRecipe.isEmpty()) {
|
||||||
if (optionalRecipe.isPresent()) {
|
|
||||||
Object holder = optionalRecipe.get();
|
|
||||||
Object id = FastNMS.INSTANCE.field$RecipeHolder$id(holder);
|
|
||||||
Key recipeId = Key.of(id.toString());
|
|
||||||
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
|
||||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(CoreReflections.field$SingleRecipeInput$item.get(args[0]));
|
|
||||||
|
|
||||||
// it's a recipe from other plugins
|
|
||||||
boolean isCustom = recipeManager.isCustomRecipe(recipeId);
|
|
||||||
if (!isCustom) {
|
|
||||||
injectedCacheCheck.lastRecipe(id);
|
|
||||||
return optionalRecipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
|
||||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
|
||||||
if (idHolder.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
|
||||||
CustomCookingRecipe<ItemStack> ceRecipe;
|
|
||||||
Key lastCustomRecipe = injectedCacheCheck.lastCustomRecipe();
|
|
||||||
if (type == MRecipeTypes.SMELTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMELTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.BLASTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.BLASTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.SMOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMOKING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.CAMPFIRE_COOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input, lastCustomRecipe);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (ceRecipe == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache recipes, it might be incorrect on reloading
|
|
||||||
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
|
||||||
// It doesn't matter at all
|
|
||||||
injectedCacheCheck.lastRecipe(id);
|
|
||||||
return Optional.of(Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe)).orElse(holder));
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object rawRecipeHolder = optionalRecipe.get();
|
||||||
|
Object rawRecipeResourceLocation = FastNMS.INSTANCE.field$RecipeHolder$id(rawRecipeHolder);
|
||||||
|
Key rawRecipeKey = Key.of(rawRecipeResourceLocation.toString());
|
||||||
|
|
||||||
|
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
||||||
|
boolean isCustom = recipeManager.isCustomRecipe(rawRecipeKey);
|
||||||
|
if (!isCustom) {
|
||||||
|
injectedCacheCheck.lastRecipe(rawRecipeResourceLocation);
|
||||||
|
return optionalRecipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.field$SingleRecipeInput$item(args[0]));
|
||||||
|
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||||
|
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||||
|
if (idHolder.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||||
|
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||||
|
if (ceRecipe == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
||||||
|
if (!ceRecipe.id().equals(rawRecipeKey)) {
|
||||||
|
injectedCacheCheck.lastRecipe(KeyUtils.toResourceLocation(ceRecipe.id()));
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
public static class GetRecipeForMethodInterceptor1_21_2 {
|
public static class GetRecipeForMethodInterceptor1_21_2 {
|
||||||
public static final GetRecipeForMethodInterceptor1_21_2 INSTANCE = new GetRecipeForMethodInterceptor1_21_2();
|
public static final GetRecipeForMethodInterceptor1_21_2 INSTANCE = new GetRecipeForMethodInterceptor1_21_2();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@RuntimeType
|
@RuntimeType
|
||||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) throws Exception {
|
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||||
Object mcRecipeManager = BukkitRecipeManager.nmsRecipeManager();
|
|
||||||
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
InjectedCacheCheck injectedCacheCheck = (InjectedCacheCheck) thisObj;
|
||||||
Object type = injectedCacheCheck.recipeType();
|
Object lastRecipeResourceKey = injectedCacheCheck.lastRecipe();
|
||||||
Object lastRecipe = 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(mcRecipeManager, type, args[0], args[1], lastRecipe);
|
if (optionalRecipe.isEmpty()) {
|
||||||
if (optionalRecipe.isPresent()) {
|
|
||||||
Object holder = optionalRecipe.get();
|
|
||||||
Object id = FastNMS.INSTANCE.field$RecipeHolder$id(holder);
|
|
||||||
Object resourceLocation = FastNMS.INSTANCE.field$ResourceKey$location(id);
|
|
||||||
Key recipeId = Key.of(resourceLocation.toString());
|
|
||||||
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
|
||||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(CoreReflections.field$SingleRecipeInput$item.get(args[0]));
|
|
||||||
|
|
||||||
// it's a recipe from other plugins
|
|
||||||
boolean isCustom = recipeManager.isCustomRecipe(recipeId);
|
|
||||||
if (!isCustom) {
|
|
||||||
injectedCacheCheck.lastRecipe(id);
|
|
||||||
return optionalRecipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
|
||||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
|
||||||
if (idHolder.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
|
||||||
CustomCookingRecipe<ItemStack> ceRecipe;
|
|
||||||
Key lastCustomRecipe = injectedCacheCheck.lastCustomRecipe();
|
|
||||||
if (type == MRecipeTypes.SMELTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMELTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.BLASTING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.BLASTING, input, lastCustomRecipe);
|
|
||||||
} else if (type == MRecipeTypes.SMOKING) {
|
|
||||||
ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(RecipeTypes.SMOKING, input, lastCustomRecipe);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (ceRecipe == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache recipes, it might be incorrect on reloading
|
|
||||||
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
|
||||||
// It doesn't matter at all
|
|
||||||
injectedCacheCheck.lastRecipe(id);
|
|
||||||
return Optional.of(Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe)).orElse(holder));
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取配方的基础信息
|
||||||
|
Object recipeHolder = optionalRecipe.get();
|
||||||
|
Object rawRecipeResourceKey = FastNMS.INSTANCE.field$RecipeHolder$id(recipeHolder);
|
||||||
|
Object rawRecipeResourceLocation = FastNMS.INSTANCE.field$ResourceKey$location(rawRecipeResourceKey);
|
||||||
|
Key rawRecipeKey = Key.of(rawRecipeResourceLocation.toString());
|
||||||
|
|
||||||
|
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
|
||||||
|
// 来自其他插件注册的自定义配方
|
||||||
|
boolean isCustom = recipeManager.isCustomRecipe(rawRecipeKey);
|
||||||
|
if (!isCustom) {
|
||||||
|
injectedCacheCheck.lastRecipe(rawRecipeResourceKey);
|
||||||
|
return optionalRecipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取唯一内存地址id
|
||||||
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.field$SingleRecipeInput$item(args[0]));
|
||||||
|
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||||
|
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||||
|
if (idHolder.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||||
|
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||||
|
// 这个ce配方并不存在,那么应该返回空
|
||||||
|
if (ceRecipe == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录上一次使用的配方(ce)
|
||||||
|
injectedCacheCheck.lastCustomRecipe(ceRecipe.id());
|
||||||
|
// 更新上一次使用的配方(nms)
|
||||||
|
if (!ceRecipe.id().equals(rawRecipeKey)) {
|
||||||
|
injectedCacheCheck.lastRecipe(FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.RECIPE, KeyUtils.toResourceLocation(ceRecipe.id())));
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(recipeManager.nmsRecipeHolderByRecipe(ceRecipe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,21 +10,23 @@ import java.lang.reflect.Type;
|
|||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
public final class MRegistries {
|
public final class MRegistries {
|
||||||
public static final Object instance$Registries$BLOCK;
|
public static final Object BLOCK;
|
||||||
public static final Object instance$Registries$ITEM;
|
public static final Object ITEM;
|
||||||
public static final Object instance$Registries$ATTRIBUTE;
|
public static final Object ATTRIBUTE;
|
||||||
public static final Object instance$Registries$BIOME;
|
public static final Object BIOME;
|
||||||
public static final Object instance$Registries$MOB_EFFECT;
|
public static final Object MOB_EFFECT;
|
||||||
public static final Object instance$Registries$SOUND_EVENT;
|
public static final Object SOUND_EVENT;
|
||||||
public static final Object instance$Registries$PARTICLE_TYPE;
|
public static final Object PARTICLE_TYPE;
|
||||||
public static final Object instance$Registries$ENTITY_TYPE;
|
public static final Object ENTITY_TYPE;
|
||||||
public static final Object instance$Registries$FLUID;
|
public static final Object FLUID;
|
||||||
public static final Object instance$Registries$RECIPE_TYPE;
|
public static final Object RECIPE_TYPE;
|
||||||
public static final Object instance$Registries$DIMENSION_TYPE;
|
public static final Object DIMENSION_TYPE;
|
||||||
public static final Object instance$Registries$CONFIGURED_FEATURE;
|
public static final Object CONFIGURED_FEATURE;
|
||||||
public static final Object instance$Registries$PLACED_FEATURE;
|
public static final Object PLACED_FEATURE;
|
||||||
@Nullable // 1.21+
|
@Nullable // 1.21+
|
||||||
public static final Object instance$Registries$JUKEBOX_SONG;
|
public static final Object JUKEBOX_SONG;
|
||||||
|
@Nullable // 1.21+
|
||||||
|
public static final Object RECIPE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Field[] fields = CoreReflections.clazz$Registries.getDeclaredFields();
|
Field[] fields = CoreReflections.clazz$Registries.getDeclaredFields();
|
||||||
@@ -43,6 +45,7 @@ public final class MRegistries {
|
|||||||
Object registries$ConfiguredFeature = null;
|
Object registries$ConfiguredFeature = null;
|
||||||
Object registries$PlacedFeature = null;
|
Object registries$PlacedFeature = null;
|
||||||
Object registries$JukeboxSong = null;
|
Object registries$JukeboxSong = null;
|
||||||
|
Object registries$Recipe = null;
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
Type fieldType = field.getGenericType();
|
Type fieldType = field.getGenericType();
|
||||||
if (fieldType instanceof ParameterizedType paramType) {
|
if (fieldType instanceof ParameterizedType paramType) {
|
||||||
@@ -60,6 +63,8 @@ public final class MRegistries {
|
|||||||
registries$RecipeType = field.get(null);
|
registries$RecipeType = field.get(null);
|
||||||
} else if (rawType == CoreReflections.clazz$ConfiguredFeature) {
|
} else if (rawType == CoreReflections.clazz$ConfiguredFeature) {
|
||||||
registries$ConfiguredFeature = field.get(null);
|
registries$ConfiguredFeature = field.get(null);
|
||||||
|
} else if (rawType == CoreReflections.clazz$Recipe) {
|
||||||
|
registries$Recipe = field.get(null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (type == CoreReflections.clazz$Block) {
|
if (type == CoreReflections.clazz$Block) {
|
||||||
@@ -88,20 +93,21 @@ public final class MRegistries {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
instance$Registries$BLOCK = requireNonNull(registries$Block);
|
BLOCK = requireNonNull(registries$Block);
|
||||||
instance$Registries$ITEM = requireNonNull(registries$Item);
|
ITEM = requireNonNull(registries$Item);
|
||||||
instance$Registries$ATTRIBUTE = requireNonNull(registries$Attribute);
|
ATTRIBUTE = requireNonNull(registries$Attribute);
|
||||||
instance$Registries$BIOME = requireNonNull(registries$Biome);
|
BIOME = requireNonNull(registries$Biome);
|
||||||
instance$Registries$MOB_EFFECT = requireNonNull(registries$MobEffect);
|
MOB_EFFECT = requireNonNull(registries$MobEffect);
|
||||||
instance$Registries$SOUND_EVENT = requireNonNull(registries$SoundEvent);
|
SOUND_EVENT = requireNonNull(registries$SoundEvent);
|
||||||
instance$Registries$DIMENSION_TYPE = requireNonNull(registries$DimensionType);
|
DIMENSION_TYPE = requireNonNull(registries$DimensionType);
|
||||||
instance$Registries$PARTICLE_TYPE = requireNonNull(registries$ParticleType);
|
PARTICLE_TYPE = requireNonNull(registries$ParticleType);
|
||||||
instance$Registries$ENTITY_TYPE = requireNonNull(registries$EntityType);
|
ENTITY_TYPE = requireNonNull(registries$EntityType);
|
||||||
instance$Registries$FLUID = requireNonNull(registries$Fluid);
|
FLUID = requireNonNull(registries$Fluid);
|
||||||
instance$Registries$RECIPE_TYPE = requireNonNull(registries$RecipeType);
|
RECIPE_TYPE = requireNonNull(registries$RecipeType);
|
||||||
instance$Registries$CONFIGURED_FEATURE = requireNonNull(registries$ConfiguredFeature);
|
CONFIGURED_FEATURE = requireNonNull(registries$ConfiguredFeature);
|
||||||
instance$Registries$PLACED_FEATURE = requireNonNull(registries$PlacedFeature);
|
PLACED_FEATURE = requireNonNull(registries$PlacedFeature);
|
||||||
instance$Registries$JUKEBOX_SONG = registries$JukeboxSong;
|
JUKEBOX_SONG = registries$JukeboxSong;
|
||||||
|
RECIPE = registries$Recipe;
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class BukkitSoundManager extends AbstractSoundManager {
|
|||||||
protected void registerSongs(Map<Key, JukeboxSong> songs) {
|
protected void registerSongs(Map<Key, JukeboxSong> songs) {
|
||||||
if (songs.isEmpty()) return;
|
if (songs.isEmpty()) return;
|
||||||
try {
|
try {
|
||||||
Object registry = CoreReflections.method$RegistryAccess$registryOrThrow.invoke(FastNMS.INSTANCE.registryAccess(), MRegistries.instance$Registries$JUKEBOX_SONG);;
|
Object registry = CoreReflections.method$RegistryAccess$registryOrThrow.invoke(FastNMS.INSTANCE.registryAccess(), MRegistries.JUKEBOX_SONG);;
|
||||||
unfreezeRegistry(registry);
|
unfreezeRegistry(registry);
|
||||||
for (Map.Entry<Key, JukeboxSong> entry : songs.entrySet()) {
|
for (Map.Entry<Key, JukeboxSong> entry : songs.entrySet()) {
|
||||||
Key id = entry.getKey();
|
Key id = entry.getKey();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class BlockTags {
|
|||||||
Object value = CACHE.get(key);
|
Object value = CACHE.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
try {
|
try {
|
||||||
value = CoreReflections.method$TagKey$create.invoke(null, MRegistries.instance$Registries$BLOCK, KeyUtils.toResourceLocation(key));
|
value = CoreReflections.method$TagKey$create.invoke(null, MRegistries.BLOCK, KeyUtils.toResourceLocation(key));
|
||||||
CACHE.put(key, value);
|
CACHE.put(key, value);
|
||||||
return value;
|
return value;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class FeatureUtils {
|
|||||||
|
|
||||||
public static Object createFeatureKey(Key id) {
|
public static Object createFeatureKey(Key id) {
|
||||||
try {
|
try {
|
||||||
return CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.instance$Registries$CONFIGURED_FEATURE, KeyUtils.toResourceLocation(id));
|
return CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.CONFIGURED_FEATURE, KeyUtils.toResourceLocation(id));
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ItemTags {
|
|||||||
Object value = CACHE.get(key);
|
Object value = CACHE.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
try {
|
try {
|
||||||
value = CoreReflections.method$TagKey$create.invoke(null, MRegistries.instance$Registries$ITEM, KeyUtils.toResourceLocation(key));
|
value = CoreReflections.method$TagKey$create.invoke(null, MRegistries.ITEM, KeyUtils.toResourceLocation(key));
|
||||||
CACHE.put(key, value);
|
CACHE.put(key, value);
|
||||||
return value;
|
return value;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class RegistryUtils {
|
|||||||
|
|
||||||
public static int currentBiomeRegistrySize() {
|
public static int currentBiomeRegistrySize() {
|
||||||
try {
|
try {
|
||||||
Object idMap = CoreReflections.method$Registry$asHolderIdMap.invoke(CoreReflections.method$RegistryAccess$registryOrThrow.invoke(FastNMS.INSTANCE.registryAccess(), MRegistries.instance$Registries$BIOME));
|
Object idMap = CoreReflections.method$Registry$asHolderIdMap.invoke(CoreReflections.method$RegistryAccess$registryOrThrow.invoke(FastNMS.INSTANCE.registryAccess(), MRegistries.BIOME));
|
||||||
return (int) CoreReflections.method$IdMap$size.invoke(idMap);
|
return (int) CoreReflections.method$IdMap$size.invoke(idMap);
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
|||||||
protected final Set<Key> dataPackRecipes = new HashSet<>();
|
protected final Set<Key> dataPackRecipes = new HashSet<>();
|
||||||
protected final Set<Key> customRecipes = new HashSet<>();
|
protected final Set<Key> customRecipes = new HashSet<>();
|
||||||
private final RecipeParser recipeParser;
|
private final RecipeParser recipeParser;
|
||||||
|
protected boolean isReloading;
|
||||||
|
|
||||||
public AbstractRecipeManager() {
|
public AbstractRecipeManager() {
|
||||||
this.recipeReader = initVanillaRecipeReader();
|
this.recipeReader = initVanillaRecipeReader();
|
||||||
@@ -72,37 +73,44 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDataPackRecipe(Key key) {
|
public boolean isDataPackRecipe(Key key) {
|
||||||
|
if (this.isReloading) return false;
|
||||||
return this.dataPackRecipes.contains(key);
|
return this.dataPackRecipes.contains(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCustomRecipe(Key key) {
|
public boolean isCustomRecipe(Key key) {
|
||||||
|
if (this.isReloading) return false;
|
||||||
return this.byId.containsKey(key);
|
return this.byId.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Recipe<T>> recipeById(Key key) {
|
public Optional<Recipe<T>> recipeById(Key key) {
|
||||||
|
if (this.isReloading) return Optional.empty();
|
||||||
return Optional.ofNullable(this.byId.get(key));
|
return Optional.ofNullable(this.byId.get(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Recipe<T>> recipesByType(Key type) {
|
public List<Recipe<T>> recipesByType(Key type) {
|
||||||
|
if (this.isReloading) return List.of();
|
||||||
return this.byType.getOrDefault(type, List.of());
|
return this.byType.getOrDefault(type, List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Recipe<T>> recipeByResult(Key result) {
|
public List<Recipe<T>> recipeByResult(Key result) {
|
||||||
|
if (this.isReloading) return List.of();
|
||||||
return this.byResult.getOrDefault(result, List.of());
|
return this.byResult.getOrDefault(result, List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Recipe<T>> recipeByIngredient(Key ingredient) {
|
public List<Recipe<T>> recipeByIngredient(Key ingredient) {
|
||||||
|
if (this.isReloading) return List.of();
|
||||||
return this.byIngredient.getOrDefault(ingredient, List.of());
|
return this.byIngredient.getOrDefault(ingredient, List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Recipe<T> recipeByInput(Key type, RecipeInput input) {
|
public Recipe<T> recipeByInput(Key type, RecipeInput input) {
|
||||||
|
if (this.isReloading) return null;
|
||||||
List<Recipe<T>> recipes = this.byType.get(type);
|
List<Recipe<T>> recipes = this.byType.get(type);
|
||||||
if (recipes == null) return null;
|
if (recipes == null) return null;
|
||||||
for (Recipe<T> recipe : recipes) {
|
for (Recipe<T> recipe : recipes) {
|
||||||
@@ -116,8 +124,9 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Recipe<T> recipeByInput(Key type, RecipeInput input, Key lastRecipe) {
|
public Recipe<T> recipeByInput(Key type, RecipeInput input, Key lastRecipe) {
|
||||||
|
if (this.isReloading) return null;
|
||||||
if (lastRecipe != null) {
|
if (lastRecipe != null) {
|
||||||
Recipe<T> last = byId.get(lastRecipe);
|
Recipe<T> last = this.byId.get(lastRecipe);
|
||||||
if (last != null && last.matches(input)) {
|
if (last != null && last.matches(input)) {
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
|
|||||||
ahocorasick_version=0.6.3
|
ahocorasick_version=0.6.3
|
||||||
snake_yaml_version=2.4
|
snake_yaml_version=2.4
|
||||||
anti_grief_version=0.17
|
anti_grief_version=0.17
|
||||||
nms_helper_version=0.66.12
|
nms_helper_version=0.66.15
|
||||||
evalex_version=3.5.0
|
evalex_version=3.5.0
|
||||||
reactive_streams_version=1.0.4
|
reactive_streams_version=1.0.4
|
||||||
amazon_awssdk_version=2.31.23
|
amazon_awssdk_version=2.31.23
|
||||||
|
|||||||
Reference in New Issue
Block a user