9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 20:39:10 +00:00

重构配方前

This commit is contained in:
XiaoMoMi
2025-07-30 15:51:45 +08:00
parent 29b5d48809
commit 4947b47310
22 changed files with 416 additions and 96 deletions

View File

@@ -13,6 +13,7 @@ import net.momirealms.craftengine.core.entity.furniture.Furniture;
import net.momirealms.craftengine.core.entity.furniture.FurnitureElement;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
import net.momirealms.craftengine.core.util.Color;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.WorldPosition;
import org.bukkit.Material;
@@ -65,7 +66,7 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
}
}
private synchronized List<Object> getCachedValues(@Nullable Integer color, int @Nullable [] colors) {
private synchronized List<Object> getCachedValues(@Nullable Color color, int @Nullable [] colors) {
List<Object> cachedValues = new ArrayList<>(this.commonValues);
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(item(), null);
if (item == null) {

View File

@@ -13,6 +13,7 @@ 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;
@@ -111,11 +112,20 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
protected boolean is(W item, Key itemTag) {
Object literalObject = item.getLiteralObject();
Object tag = ItemTags.getOrCreate(itemTag);
try {
return (boolean) CoreReflections.method$ItemStack$isTag.invoke(literalObject, tag);
} catch (ReflectiveOperationException e) {
return false;
}
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

View File

@@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.item.data.Enchantment;
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
import net.momirealms.craftengine.core.item.data.Trim;
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.MiscUtils;
import net.momirealms.sparrow.nbt.CompoundTag;
@@ -386,23 +387,23 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
}
@Override
protected Optional<Integer> dyedColor(ComponentItemWrapper item) {
protected Optional<Color> dyedColor(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.DYED_COLOR)) return Optional.empty();
Object javaObj = getJavaComponent(item, ComponentTypes.DYED_COLOR);
if (javaObj instanceof Integer integer) {
return Optional.of(integer);
return Optional.of(Color.fromDecimal(integer));
} else if (javaObj instanceof Map<?, ?> map) {
return Optional.of((int) map.get("rgb"));
return Optional.of(Color.fromDecimal((int) map.get("rgb")));
}
return Optional.empty();
}
@Override
protected void dyedColor(ComponentItemWrapper item, Integer color) {
protected void dyedColor(ComponentItemWrapper item, Color color) {
if (color == null) {
item.resetComponent(ComponentTypes.DYED_COLOR);
} else {
item.setJavaComponent(ComponentTypes.DYED_COLOR, color);
item.setJavaComponent(ComponentTypes.DYED_COLOR, color.color());
}
}

View File

@@ -10,6 +10,7 @@ import net.momirealms.craftengine.core.item.data.FireworkExplosion;
import net.momirealms.craftengine.core.item.data.Trim;
import net.momirealms.craftengine.core.item.modifier.IdModifier;
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.SkullUtils;
import net.momirealms.sparrow.nbt.Tag;
@@ -169,17 +170,17 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
}
@Override
protected Optional<Integer> dyedColor(LegacyItemWrapper item) {
protected Optional<Color> dyedColor(LegacyItemWrapper item) {
if (!item.hasTag("display", "color")) return Optional.empty();
return Optional.of(item.getJavaTag("display", "color"));
return Optional.of(Color.fromDecimal(item.getJavaTag("display", "color")));
}
@Override
protected void dyedColor(LegacyItemWrapper item, Integer color) {
protected void dyedColor(LegacyItemWrapper item, Color color) {
if (color == null) {
item.remove("display", "color");
} else {
item.setTag(color, "display", "color");
item.setTag(color.color(), "display", "color");
}
}

View File

@@ -46,6 +46,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
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 void registerNMSSmithingRecipe(Object recipe) {
@@ -541,7 +542,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
Optional<Object> nmsRecipe = getOptionalNMSRecipe(entry.getKey());
nmsRecipe.ifPresent(o -> CE_RECIPE_2_NMS_HOLDER.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);

View File

@@ -745,13 +745,15 @@ 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) || CoreReflections.clazz$FireworkStarFadeRecipe.isInstance(mcRecipe)) {
} 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) {
if (itemStack == null) continue;
Item<ItemStack> item = plugin.itemManager().wrap(itemStack);
Optional<CustomItem<ItemStack>> optionalCustomItem = item.getCustomItem();
if (optionalCustomItem.isPresent() && !optionalCustomItem.get().settings().dyeable()) {
if (optionalCustomItem.isPresent() && optionalCustomItem.get().settings().dyeable() == Tristate.FALSE) {
inventory.setResult(null);
return;
}
@@ -824,16 +826,37 @@ 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;
org.bukkit.inventory.Recipe recipe = event.getRecipe();
if (recipe == null)
return;
// we only handle shaped and shapeless recipes
boolean shapeless = event.getRecipe() instanceof ShapelessRecipe;
boolean shaped = event.getRecipe() instanceof ShapedRecipe;
boolean shapeless = recipe instanceof ShapelessRecipe;
boolean shaped = recipe instanceof ShapedRecipe;
if (!shaped && !shapeless) return;
CraftingRecipe craftingRecipe = (CraftingRecipe) recipe;
@@ -846,24 +869,10 @@ public class RecipeEventListener implements Listener {
}
CraftingInventory inventory = event.getInventory();
ItemStack[] ingredients = inventory.getMatrix();
List<UniqueIdItem<ItemStack>> uniqueIdItems = new ArrayList<>();
for (ItemStack itemStack : ingredients) {
uniqueIdItems.add(getUniqueIdItem(itemStack));
}
CraftingInput<ItemStack> input;
if (ingredients.length == 9) {
input = CraftingInput.of(3, 3, uniqueIdItems);
} else if (ingredients.length == 4) {
input = CraftingInput.of(2, 2, uniqueIdItems);
} else {
return;
}
CraftingInput<ItemStack> input = getCraftingInput(inventory);
if (input == null) return;
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
Key lastRecipe = serverPlayer.lastUsedRecipe();
@@ -889,17 +898,34 @@ public class RecipeEventListener implements Listener {
inventory.setResult(null);
}
private CraftingInput<ItemStack> getCraftingInput(CraftingInventory inventory) {
ItemStack[] ingredients = inventory.getMatrix();
List<UniqueIdItem<ItemStack>> uniqueIdItems = new ArrayList<>();
for (ItemStack itemStack : ingredients) {
uniqueIdItems.add(getUniqueIdItem(itemStack));
}
CraftingInput<ItemStack> input;
if (ingredients.length == 9) {
input = CraftingInput.of(3, 3, uniqueIdItems);
} else if (ingredients.length == 4) {
input = CraftingInput.of(2, 2, uniqueIdItems);
} else {
return null;
}
return input;
}
private void correctCraftingRecipeUsed(CraftingInventory inventory, Recipe<ItemStack> recipe) {
Object holderOrRecipe = this.recipeManager.nmsRecipeHolderByRecipe(recipe);
if (holderOrRecipe == null) {
return;
}
try {
Object resultInventory = CraftBukkitReflections.field$CraftInventoryCrafting$resultInventory.get(inventory);
CoreReflections.field$ResultContainer$recipeUsed.set(resultInventory, holderOrRecipe);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to correct used recipe", e);
}
Object resultInventory = FastNMS.INSTANCE.method$CraftInventoryCrafting$getResultInventory(inventory);
FastNMS.INSTANCE.method$ResultContainer$setRecipeUsed(resultInventory, holderOrRecipe);
Object matrixInventory = FastNMS.INSTANCE.method$CraftInventoryCrafting$getMatrixInventory(inventory);
FastNMS.INSTANCE.method$CraftingContainer$setCurrentRecipe(matrixInventory, holderOrRecipe);
}
@EventHandler(ignoreCancelled = true)

View File

@@ -3896,4 +3896,11 @@ public final class CoreReflections {
throw new ReflectionInitException("Failed to initialize SnowLayerBlock$LAYERS", e);
}
}
public static final Class<?> clazz$DyeItem = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.item.ItemDye",
"world.item.DyeItem"
)
);
}

View File

@@ -14,7 +14,10 @@ import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.*;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.QuadFunction;
import net.momirealms.craftengine.core.util.TriFunction;
import net.momirealms.craftengine.core.world.BlockHitResult;
import net.momirealms.craftengine.core.world.BlockPos;
import org.bukkit.GameMode;