mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 18:09:27 +00:00
重构配方匹配
This commit is contained in:
@@ -8,8 +8,8 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -21,7 +21,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
|
||||
private final Object item;
|
||||
private final Object clientItem;
|
||||
|
||||
public BukkitCustomItem(Holder<Key> id, Object item, Object clientItem, Key materialKey, Key clientBoundMaterialKey,
|
||||
public BukkitCustomItem(UniqueKey id, Object item, Object clientItem, Key materialKey, Key clientBoundMaterialKey,
|
||||
List<ItemBehavior> behaviors,
|
||||
List<ItemDataModifier<ItemStack>> modifiers, List<ItemDataModifier<ItemStack>> clientBoundModifiers,
|
||||
ItemSettings settings,
|
||||
@@ -64,7 +64,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder<ItemStack> {
|
||||
private Holder<Key> id;
|
||||
private UniqueKey id;
|
||||
private Key itemKey;
|
||||
private final Object item;
|
||||
private Key clientBoundItemKey;
|
||||
@@ -81,7 +81,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<ItemStack> id(Holder<Key> id) {
|
||||
public Builder<ItemStack> id(UniqueKey id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,6 @@ import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.plugin.logger.Debugger;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
@@ -349,7 +346,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CustomItem.Builder<ItemStack> createPlatformItemBuilder(Holder<Key> id, Key materialId, Key clientBoundMaterialId) {
|
||||
protected CustomItem.Builder<ItemStack> createPlatformItemBuilder(UniqueKey id, Key materialId, Key clientBoundMaterialId) {
|
||||
Object item = FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(materialId));
|
||||
Object clientBoundItem = materialId == clientBoundMaterialId ? item : FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(clientBoundMaterialId));
|
||||
if (item == null) {
|
||||
@@ -372,14 +369,12 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
Key itemKey = KeyUtils.resourceLocationToKey(resourceLocation);
|
||||
if (itemKey.namespace().equals("minecraft")) {
|
||||
VANILLA_ITEMS.add(itemKey);
|
||||
Holder.Reference<Key> holder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(itemKey)
|
||||
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
|
||||
.register(ResourceKey.create(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), itemKey), itemKey));
|
||||
UniqueKey uniqueKey = UniqueKey.create(itemKey);
|
||||
Object mcHolder = FastNMS.INSTANCE.method$Registry$getHolderByResourceKey(MBuiltInRegistries.ITEM, FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.ITEM, resourceLocation)).get();
|
||||
Set<Object> tags = (Set<Object>) CoreReflections.field$Holder$Reference$tags.get(mcHolder);
|
||||
for (Object tag : tags) {
|
||||
Key tagId = Key.of(CoreReflections.field$TagKey$location.get(tag).toString());
|
||||
VANILLA_ITEM_TAGS.computeIfAbsent(tagId, (key) -> new ArrayList<>()).add(holder);
|
||||
VANILLA_ITEM_TAGS.computeIfAbsent(tagId, (key) -> new ArrayList<>()).add(uniqueKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,29 +2,28 @@ package net.momirealms.craftengine.bukkit.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
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.reflection.bukkit.CraftBukkitReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.MaterialUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.RecipeUtils;
|
||||
import net.momirealms.craftengine.core.item.CustomItem;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.item.recipe.*;
|
||||
import net.momirealms.craftengine.core.item.recipe.Recipe;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.*;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.HeptaFunction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
@@ -135,6 +134,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
Object finalNmsRecipe = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe);
|
||||
} catch (InvalidRecipeIngredientException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to convert smithing transform recipe", e);
|
||||
return null;
|
||||
@@ -220,8 +221,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
});
|
||||
MIXED_RECIPE_CONVERTORS.put(RecipeTypes.STONECUTTING, (BukkitRecipeConvertor<CustomStoneCuttingRecipe<ItemStack>>) (id, recipe) -> {
|
||||
List<ItemStack> itemStacks = new ArrayList<>();
|
||||
for (Holder<Key> item : recipe.ingredient().items()) {
|
||||
itemStacks.add(BukkitItemManager.instance().buildItemStack(item.value(), null));
|
||||
for (UniqueKey item : recipe.ingredient().items()) {
|
||||
itemStacks.add(BukkitItemManager.instance().buildItemStack(item.key(), null));
|
||||
}
|
||||
StonecuttingRecipe stonecuttingRecipe = new StonecuttingRecipe(
|
||||
new NamespacedKey(id.namespace(), id.value()), recipe.result(ItemBuildContext.EMPTY),
|
||||
@@ -351,6 +352,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
if (converted != null) {
|
||||
this.delayedTasksOnMainThread.add(converted);
|
||||
}
|
||||
} catch (InvalidRecipeIngredientException e) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.invalid_ingredient", e.ingredient());
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Failed to convert recipe " + id, e);
|
||||
}
|
||||
@@ -502,13 +505,13 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
|
||||
private void handleDataPackStoneCuttingRecipe(Key id, VanillaStoneCuttingRecipe recipe) {
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : recipe.ingredient()) {
|
||||
if (item.charAt(0) == '#') {
|
||||
Key tag = Key.from(item.substring(1));
|
||||
holders.addAll(this.plugin.itemManager().tagToItems(tag));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
|
||||
holders.add(UniqueKey.create(Key.from(item)));
|
||||
}
|
||||
}
|
||||
CustomStoneCuttingRecipe<ItemStack> ceRecipe = new CustomStoneCuttingRecipe<>(
|
||||
@@ -524,7 +527,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
boolean hasCustomItemInTag = false;
|
||||
List<Ingredient<ItemStack>> ingredientList = new ArrayList<>();
|
||||
for (List<String> list : recipe.ingredients()) {
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : list) {
|
||||
if (item.charAt(0) == '#') {
|
||||
Key tag = Key.of(item.substring(1));
|
||||
@@ -535,7 +538,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
holders.addAll(plugin.itemManager().tagToItems(tag));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
|
||||
holders.add(UniqueKey.create(Key.from(item)));
|
||||
}
|
||||
}
|
||||
ingredientList.add(Ingredient.of(holders));
|
||||
@@ -560,7 +563,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
boolean hasCustomItemInTag = false;
|
||||
Map<Character, Ingredient<ItemStack>> ingredients = new HashMap<>();
|
||||
for (Map.Entry<Character, List<String>> entry : recipe.ingredients().entrySet()) {
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : entry.getValue()) {
|
||||
if (item.charAt(0) == '#') {
|
||||
Key tag = Key.from(item.substring(1));
|
||||
@@ -571,7 +574,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
}
|
||||
holders.addAll(plugin.itemManager().tagToItems(tag));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
|
||||
holders.add(UniqueKey.create(Key.from(item)));
|
||||
}
|
||||
}
|
||||
ingredients.put(entry.getKey(), Ingredient.of(holders));
|
||||
@@ -597,7 +600,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
boolean hasCustomItemInTag = readVanillaIngredients(false, recipe.ingredient(), holders::add);
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = constructor2.apply(
|
||||
id, recipe.category(), recipe.group(),
|
||||
@@ -620,11 +623,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
ItemStack result = createDataPackResultStack(recipe.result());
|
||||
boolean hasCustomItemInTag;
|
||||
|
||||
Set<Holder<Key>> additionHolders = new HashSet<>();
|
||||
Set<UniqueKey> additionHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(false, recipe.addition(), additionHolders::add);
|
||||
Set<Holder<Key>> templateHolders = new HashSet<>();
|
||||
Set<UniqueKey> templateHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.template(), templateHolders::add);
|
||||
Set<Holder<Key>> baseHolders = new HashSet<>();
|
||||
Set<UniqueKey> baseHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.base(), baseHolders::add);
|
||||
|
||||
CustomSmithingTransformRecipe<ItemStack> ceRecipe = new CustomSmithingTransformRecipe<>(
|
||||
@@ -647,7 +650,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
this.registerInternalRecipe(id, ceRecipe);
|
||||
}
|
||||
|
||||
private boolean readVanillaIngredients(boolean hasCustomItemInTag, List<String> ingredients, Consumer<Holder<Key>> holderConsumer) {
|
||||
private boolean readVanillaIngredients(boolean hasCustomItemInTag, List<String> ingredients, Consumer<UniqueKey> holderConsumer) {
|
||||
for (String item : ingredients) {
|
||||
if (item.charAt(0) == '#') {
|
||||
Key tag = Key.from(item.substring(1));
|
||||
@@ -656,11 +659,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
hasCustomItemInTag = true;
|
||||
}
|
||||
}
|
||||
for (Holder<Key> holder : this.plugin.itemManager().tagToItems(tag)) {
|
||||
for (UniqueKey holder : this.plugin.itemManager().tagToItems(tag)) {
|
||||
holderConsumer.accept(holder);
|
||||
}
|
||||
} else {
|
||||
holderConsumer.accept(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
|
||||
holderConsumer.accept(UniqueKey.create(Key.from(item)));
|
||||
}
|
||||
}
|
||||
return hasCustomItemInTag;
|
||||
@@ -703,8 +706,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
|
||||
private static RecipeChoice ingredientToBukkitRecipeChoice(Ingredient<ItemStack> ingredient) {
|
||||
Set<Material> materials = new HashSet<>();
|
||||
for (Holder<Key> holder : ingredient.items()) {
|
||||
materials.add(getMaterialById(holder.value()));
|
||||
for (UniqueKey holder : ingredient.items()) {
|
||||
materials.add(getMaterialById(holder.key()));
|
||||
}
|
||||
return new RecipeChoice.MaterialChoice(new ArrayList<>(materials));
|
||||
}
|
||||
@@ -715,15 +718,21 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
return material;
|
||||
}
|
||||
Optional<CustomItem<ItemStack>> optionalItem = BukkitItemManager.instance().getCustomItem(key);
|
||||
return optionalItem.map(itemStackCustomItem -> MaterialUtils.getMaterial(itemStackCustomItem.material())).orElse(null);
|
||||
return optionalItem.map(itemStackCustomItem -> MaterialUtils.getMaterial(itemStackCustomItem.material())).orElseThrow(() -> new InvalidRecipeIngredientException(key.asString()));
|
||||
}
|
||||
|
||||
private static List<Object> getIngredientLooks(List<Holder<Key>> holders) {
|
||||
private static List<Object> getIngredientLooks(List<UniqueKey> holders) {
|
||||
List<Object> itemStacks = new ArrayList<>();
|
||||
for (Holder<Key> holder : holders) {
|
||||
ItemStack itemStack = BukkitItemManager.instance().getBuildableItem(holder.value()).get().buildItemStack(ItemBuildContext.EMPTY, 1);
|
||||
Object nmsStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack);
|
||||
itemStacks.add(nmsStack);
|
||||
for (UniqueKey holder : holders) {
|
||||
Optional<? extends BuildableItem<ItemStack>> buildableItem = BukkitItemManager.instance().getBuildableItem(holder.key());
|
||||
if (buildableItem.isPresent()) {
|
||||
ItemStack itemStack = buildableItem.get().buildItemStack(ItemBuildContext.EMPTY, 1);
|
||||
Object nmsStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack);
|
||||
itemStacks.add(nmsStack);
|
||||
} else {
|
||||
Item<ItemStack> barrier = BukkitItemManager.instance().createWrappedItem(ItemKeys.BARRIER, null);
|
||||
barrier.customNameJson(AdventureHelper.componentToJson(Component.text(holder.key().asString()).color(NamedTextColor.RED)));
|
||||
}
|
||||
}
|
||||
return itemStacks;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ import net.momirealms.craftengine.core.item.recipe.Recipe;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.bukkit.block.Crafter;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -23,7 +22,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CrafterEventListener implements Listener {
|
||||
private static final OptimizedIDItem<ItemStack> EMPTY = new OptimizedIDItem<>(null, null);
|
||||
@@ -62,14 +60,8 @@ public class CrafterEventListener implements Listener {
|
||||
optimizedIDItems.add(EMPTY);
|
||||
} else {
|
||||
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
if (idHolder.isEmpty()) {
|
||||
// an invalid item is used in recipe, we disallow it
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
} else {
|
||||
optimizedIDItems.add(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
}
|
||||
UniqueKey uniqueId = UniqueKey.create(wrappedItem.id());
|
||||
optimizedIDItems.add(new OptimizedIDItem<>(uniqueId, itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,7 @@ import net.momirealms.craftengine.core.item.setting.AnvilRepairItem;
|
||||
import net.momirealms.craftengine.core.item.setting.ItemEquipment;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.Pair;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Campfire;
|
||||
@@ -42,6 +37,7 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.*;
|
||||
import org.bukkit.event.inventory.*;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.*;
|
||||
import org.bukkit.inventory.view.AnvilView;
|
||||
@@ -79,10 +75,9 @@ public class RecipeEventListener implements Listener {
|
||||
if (ItemStackUtils.isEmpty(item)) return;
|
||||
if (ItemStackUtils.isEmpty(fuelStack)) {
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(item);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
if (idHolder.isEmpty()) return;
|
||||
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), item));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, item));
|
||||
Key recipeType;
|
||||
if (furnaceInventory.getType() == InventoryType.FURNACE) {
|
||||
recipeType = RecipeTypes.SMELTING;
|
||||
@@ -92,7 +87,7 @@ public class RecipeEventListener implements Listener {
|
||||
recipeType = RecipeTypes.SMOKING;
|
||||
}
|
||||
|
||||
Recipe<ItemStack> ceRecipe = recipeManager.recipeByInput(recipeType, input);
|
||||
Recipe<ItemStack> ceRecipe = this.recipeManager.recipeByInput(recipeType, input);
|
||||
// The item is an ingredient, we should never consider it as fuel firstly
|
||||
if (ceRecipe != null) return;
|
||||
|
||||
@@ -360,11 +355,8 @@ public class RecipeEventListener implements Listener {
|
||||
return;
|
||||
}
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
if (idHolder.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
|
||||
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setCancelled(true);
|
||||
@@ -390,13 +382,8 @@ public class RecipeEventListener implements Listener {
|
||||
|
||||
ItemStack itemStack = event.getSource();
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
if (idHolder.isEmpty()) {
|
||||
event.setTotalCookTime(Integer.MAX_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
UniqueKey itemId = UniqueKey.create(wrappedItem.id());
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(itemId, itemStack));
|
||||
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setTotalCookTime(Integer.MAX_VALUE);
|
||||
@@ -425,13 +412,8 @@ public class RecipeEventListener implements Listener {
|
||||
|
||||
ItemStack itemStack = event.getSource();
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
if (idHolder.isEmpty()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
UniqueKey itemId = UniqueKey.create(wrappedItem.id());
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(itemId, itemStack));
|
||||
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setCancelled(true);
|
||||
@@ -893,14 +875,8 @@ public class RecipeEventListener implements Listener {
|
||||
optimizedIDItems.add(EMPTY);
|
||||
} else {
|
||||
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
if (idHolder.isEmpty()) {
|
||||
// an invalid item is used in recipe, we disallow it
|
||||
inventory.setResult(null);
|
||||
return;
|
||||
} else {
|
||||
optimizedIDItems.add(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
}
|
||||
UniqueKey itemUniqueId = UniqueKey.create(wrappedItem.id());
|
||||
optimizedIDItems.add(new OptimizedIDItem<>(itemUniqueId, itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,8 +1016,7 @@ public class RecipeEventListener implements Listener {
|
||||
return EMPTY;
|
||||
} else {
|
||||
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
|
||||
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
|
||||
return idHolder.map(keyReference -> new OptimizedIDItem<>(keyReference, itemStack)).orElse(EMPTY);
|
||||
return new OptimizedIDItem<>(UniqueKey.create(wrappedItem.id()), itemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,9 @@ import net.momirealms.craftengine.core.item.recipe.CustomCookingRecipe;
|
||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -135,12 +134,9 @@ public class RecipeInjector {
|
||||
);
|
||||
|
||||
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();
|
||||
}
|
||||
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
if (ceRecipe == null) {
|
||||
return Optional.empty();
|
||||
@@ -186,12 +182,9 @@ public class RecipeInjector {
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
if (ceRecipe == null) {
|
||||
return Optional.empty();
|
||||
@@ -232,12 +225,9 @@ public class RecipeInjector {
|
||||
|
||||
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();
|
||||
}
|
||||
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
if (ceRecipe == null) {
|
||||
return Optional.empty();
|
||||
@@ -282,12 +272,9 @@ public class RecipeInjector {
|
||||
// 获取唯一内存地址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();
|
||||
}
|
||||
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
|
||||
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
// 这个ce配方并不存在,那么应该返回空
|
||||
if (ceRecipe == null) {
|
||||
|
||||
@@ -7,6 +7,7 @@ public final class MItems {
|
||||
|
||||
public static final Object AIR;
|
||||
public static final Object WATER_BUCKET;
|
||||
public static final Object BARRIER;
|
||||
|
||||
private static Object getById(String id) {
|
||||
Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id);
|
||||
@@ -16,5 +17,6 @@ public final class MItems {
|
||||
static {
|
||||
AIR = getById("air");
|
||||
WATER_BUCKET = getById("water_bucket");
|
||||
BARRIER = getById("barrier");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,10 @@ import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
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.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
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.UniqueKey;
|
||||
import net.momirealms.craftengine.core.world.BlockHitResult;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -24,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class InteractUtils {
|
||||
private static final Map<Key, QuadFunction<Player, Item<ItemStack>, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>();
|
||||
@@ -81,17 +79,17 @@ public class InteractUtils {
|
||||
});
|
||||
registerInteraction(BlockKeys.SOUL_CAMPFIRE, (player, item, blockState, result) -> {
|
||||
if (!Config.enableRecipeSystem()) return false;
|
||||
Optional<Holder.Reference<Key>> optional = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(item.id());
|
||||
return optional.filter(keyReference -> BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
|
||||
keyReference, item.getItem()
|
||||
))) != null).isPresent();
|
||||
UniqueKey uniqueKey = UniqueKey.create(item.id());
|
||||
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
|
||||
uniqueKey, item.getItem()
|
||||
))) != null;
|
||||
});
|
||||
registerInteraction(BlockKeys.CAMPFIRE, (player, item, blockState, result) -> {
|
||||
if (!Config.enableRecipeSystem()) return false;
|
||||
Optional<Holder.Reference<Key>> optional = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(item.id());
|
||||
return optional.filter(keyReference -> BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
|
||||
keyReference, item.getItem()
|
||||
))) != null).isPresent();
|
||||
UniqueKey uniqueKey = UniqueKey.create(item.id());
|
||||
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
|
||||
uniqueKey, item.getItem()
|
||||
))) != null;
|
||||
});
|
||||
registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true);
|
||||
registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true);
|
||||
|
||||
@@ -120,7 +120,8 @@ warning.config.image.invalid_hex_value: "<yellow>Problem in Datei <arg:0> gefund
|
||||
warning.config.recipe.duplicate: "<yellow>Problem in Datei <arg:0> gefunden - Dupliziertes Rezept '<arg:1>'. Bitte überprüfen Sie, ob dieselbe Konfiguration in anderen Dateien vorhanden ist.</yellow>"
|
||||
warning.config.recipe.missing_type: "<yellow>Problem in Datei <arg:0> gefunden - Dem Rezept '<arg:1>' fehlt das erforderliche 'type'-Argument.</yellow>"
|
||||
warning.config.recipe.invalid_type: "<yellow>Problem in Datei <arg:0> gefunden - Das Rezept '<arg:1>' verwendet einen ungültigen Rezepttyp '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_item: "<yellow>Problem in Datei <arg:0> gefunden - Das Rezept '<arg:1>' verwendet einen ungültigen Gegenstand '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.missing_ingredient: "<yellow>Problem in Datei <arg:0> gefunden - Dem Kochrezept '<arg:1>' fehlt das erforderliche 'ingredient'-Argument.</yellow>"
|
||||
warning.config.recipe.missing_result: "<yellow>Problem in Datei <arg:0> gefunden - Dem Rezept '<arg:1>' fehlt das erforderliche 'result'-Argument.</yellow>"
|
||||
warning.config.recipe.result.missing_id: "<yellow>Problem in Datei <arg:0> gefunden - Dem Rezept '<arg:1>' fehlt das erforderliche Argument 'id' für das Rezeptresultat.</yellow>"
|
||||
|
||||
@@ -121,7 +121,8 @@ warning.config.image.invalid_hex_value: "<yellow>Issue found in file <arg:0> - T
|
||||
warning.config.recipe.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated recipe '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
|
||||
warning.config.recipe.missing_type: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is missing the required 'type' argument.</yellow>"
|
||||
warning.config.recipe.invalid_type: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid recipe type '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_item: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid item '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.missing_ingredient: "<yellow>Issue found in file <arg:0> - The cooking recipe '<arg:1>' is missing the required 'ingredient' argument.</yellow>"
|
||||
warning.config.recipe.missing_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is missing the required 'result' argument.</yellow>"
|
||||
warning.config.recipe.result.missing_id: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is missing the required argument 'id' for recipe result.</yellow>"
|
||||
|
||||
@@ -84,7 +84,8 @@ warning.config.image.invalid_hex_value: "<yellow>Problema encontrado en el archi
|
||||
warning.config.recipe.duplicate: "<yellow>Problema encontrado en el archivo <arg:0> - Receta duplicada '<arg:1>'. Verifica si hay la misma configuración en otros archivos.</yellow>"
|
||||
warning.config.recipe.missing_type: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' carece del argumento requerido 'type'.</yellow>"
|
||||
warning.config.recipe.invalid_type: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' está usando un tipo de receta inválido '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_item: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' está usando un objeto inválido '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.missing_ingredient: "<yellow>Problema encontrado en el archivo <arg:0> - La receta de cocción '<arg:1>' carece del argumento requerido 'ingredient'.</yellow>"
|
||||
warning.config.recipe.missing_result: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' carece del argumento requerido 'result'.</yellow>"
|
||||
warning.config.recipe.result.missing_id: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' carece del argumento requerido 'id' para el resultado de la receta.</yellow>"
|
||||
|
||||
@@ -120,7 +120,8 @@ warning.config.image.invalid_hex_value: "<yellow>Проблема найдена
|
||||
warning.config.recipe.duplicate: "<yellow>Проблема найдена в файле <arg:0> - Дублированный рецепт '<arg:1>'. Проверьте, есть ли такая же конфигурация в других файлах.</yellow>"
|
||||
warning.config.recipe.missing_type: "<yellow>Проблема найдена в файле <arg:0> - В рецепте '<arg:1>' отсутствует необходимый 'type' аргумент.</yellow>"
|
||||
warning.config.recipe.invalid_type: "<yellow>Проблема найдена в файле <arg:0> - Рецепт '<arg:1>' использует недопустимый тип рецепта '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_item: "<yellow>Проблема найдена в файле <arg:0> - Рецепт '<arg:1>' использует недопустимый предмет '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.missing_ingredient: "<yellow>Проблема найдена в файле <arg:0> - В рецепт приготовления '<arg:1>' отсутствует необходимый 'ingredient' аргумент.</yellow>"
|
||||
warning.config.recipe.missing_result: "<yellow>Проблема найдена в файле <arg:0> - В рецепте '<arg:1>' отсутствует необходимый 'result' аргумент.</yellow>"
|
||||
warning.config.recipe.result.missing_id: "<yellow>Проблема найдена в файле <arg:0> - В рецепте '<arg:1>' отсутствует необходимый аргумент 'id' для результата рецепта.</yellow>"
|
||||
|
||||
@@ -83,7 +83,8 @@ warning.config.image.invalid_hex_value: "<yellow><arg:0> dosyasında sorun bulun
|
||||
warning.config.recipe.duplicate: "<yellow><arg:0> dosyasında sorun bulundu - Yinelenen tarif '<arg:1>'. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin.</yellow>"
|
||||
warning.config.recipe.missing_type: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi gerekli 'type' argümanı eksik.</yellow>"
|
||||
warning.config.recipe.invalid_type: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi geçersiz bir tarif türü '<arg:2>' kullanıyor.</yellow>"
|
||||
warning.config.recipe.invalid_item: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi geçersiz bir eşya '<arg:2>' kullanıyor.</yellow>"
|
||||
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.missing_ingredient: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' pişirme tarifi gerekli 'ingredient' argümanı eksik.</yellow>"
|
||||
warning.config.recipe.missing_result: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi gerekli 'result' argümanı eksik.</yellow>"
|
||||
warning.config.recipe.result.missing_id: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi, tarif sonucu için gerekli 'id' argümanı eksik.</yellow>"
|
||||
|
||||
@@ -121,7 +121,8 @@ warning.config.image.invalid_hex_value: "<yellow>在文件 <arg:0> 发现问题
|
||||
warning.config.recipe.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的配方 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
|
||||
warning.config.recipe.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 缺少必需的 'type' 参数</yellow>"
|
||||
warning.config.recipe.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的配方类型 '<arg:2>'</yellow>"
|
||||
warning.config.recipe.invalid_item: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的物品 '<arg:2>'</yellow>"
|
||||
warning.config.recipe.invalid_ingredient: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的原料 '<arg:2>'</yellow>"
|
||||
warning.config.recipe.invalid_result: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的结果 '<arg:2>'</yellow>"
|
||||
warning.config.recipe.missing_ingredient: "<yellow>在文件 <arg:0> 发现问题 - 烧炼配方 '<arg:1>' 缺少必需的 'ingredient' 参数</yellow>"
|
||||
warning.config.recipe.missing_result: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 缺少必需的 'result' 参数</yellow>"
|
||||
warning.config.recipe.result.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 的结果缺少必需的 'id' 参数</yellow>"
|
||||
|
||||
@@ -5,8 +5,8 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -15,7 +15,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractCustomItem<I> implements CustomItem<I> {
|
||||
protected final Holder<Key> id;
|
||||
protected final UniqueKey id;
|
||||
protected final Key material;
|
||||
protected final Key clientBoundMaterial;
|
||||
protected final ItemDataModifier<I>[] modifiers;
|
||||
@@ -25,7 +25,7 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
|
||||
protected final Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AbstractCustomItem(Holder<Key> id, Key material, Key clientBoundMaterial,
|
||||
public AbstractCustomItem(UniqueKey id, Key material, Key clientBoundMaterial,
|
||||
List<ItemBehavior> behaviors,
|
||||
List<ItemDataModifier<I>> modifiers,
|
||||
List<ItemDataModifier<I>> clientBoundModifiers,
|
||||
@@ -52,11 +52,11 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
|
||||
|
||||
@Override
|
||||
public Key id() {
|
||||
return this.id.value();
|
||||
return this.id.key();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<Key> idHolder() {
|
||||
public UniqueKey uniqueId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,6 @@ import net.momirealms.craftengine.core.plugin.context.text.TextProvider;
|
||||
import net.momirealms.craftengine.core.plugin.context.text.TextProviders;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.type.Either;
|
||||
@@ -42,14 +39,14 @@ import java.util.stream.Stream;
|
||||
public abstract class AbstractItemManager<I> extends AbstractModelGenerator implements ItemManager<I> {
|
||||
protected static final Map<Key, List<ItemBehavior>> VANILLA_ITEM_EXTRA_BEHAVIORS = new HashMap<>();
|
||||
protected static final Set<Key> VANILLA_ITEMS = new HashSet<>(1024);
|
||||
protected static final Map<Key, List<Holder<Key>>> VANILLA_ITEM_TAGS = new HashMap<>();
|
||||
protected static final Map<Key, List<UniqueKey>> VANILLA_ITEM_TAGS = new HashMap<>();
|
||||
|
||||
private final ItemParser itemParser;
|
||||
private final EquipmentParser equipmentParser;
|
||||
protected final Map<String, ExternalItemProvider<I>> externalItemProviders = new HashMap<>();
|
||||
protected final Map<String, Function<Object, ItemDataModifier<I>>> dataFunctions = new HashMap<>();
|
||||
protected final Map<Key, CustomItem<I>> customItems = new HashMap<>();
|
||||
protected final Map<Key, List<Holder<Key>>> customItemTags = new HashMap<>();
|
||||
protected final Map<Key, List<UniqueKey>> customItemTags = new HashMap<>();
|
||||
protected final Map<Key, Map<Integer, Key>> cmdConflictChecker = new HashMap<>();
|
||||
protected final Map<Key, ModernItemModel> modernItemModels1_21_4 = new HashMap<>();
|
||||
protected final Map<Key, TreeSet<LegacyOverridesModel>> modernItemModels1_21_2 = new HashMap<>();
|
||||
@@ -157,19 +154,19 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
// tags
|
||||
Set<Key> tags = customItem.settings().tags();
|
||||
for (Key tag : tags) {
|
||||
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.idHolder());
|
||||
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.uniqueId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Holder<Key>> tagToItems(Key tag) {
|
||||
List<Holder<Key>> items = new ArrayList<>();
|
||||
List<Holder<Key>> holders = VANILLA_ITEM_TAGS.get(tag);
|
||||
public List<UniqueKey> tagToItems(Key tag) {
|
||||
List<UniqueKey> items = new ArrayList<>();
|
||||
List<UniqueKey> holders = VANILLA_ITEM_TAGS.get(tag);
|
||||
if (holders != null) {
|
||||
items.addAll(holders);
|
||||
}
|
||||
List<Holder<Key>> customItems = this.customItemTags.get(tag);
|
||||
List<UniqueKey> customItems = this.customItemTags.get(tag);
|
||||
if (customItems != null) {
|
||||
items.addAll(customItems);
|
||||
}
|
||||
@@ -177,12 +174,12 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Holder<Key>> tagToVanillaItems(Key tag) {
|
||||
public List<UniqueKey> tagToVanillaItems(Key tag) {
|
||||
return Collections.unmodifiableList(VANILLA_ITEM_TAGS.getOrDefault(tag, List.of()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Holder<Key>> tagToCustomItems(Key tag) {
|
||||
public List<UniqueKey> tagToCustomItems(Key tag) {
|
||||
return Collections.unmodifiableList(this.customItemTags.getOrDefault(tag, List.of()));
|
||||
}
|
||||
|
||||
@@ -253,7 +250,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
return VANILLA_ITEMS.contains(item);
|
||||
}
|
||||
|
||||
protected abstract CustomItem.Builder<I> createPlatformItemBuilder(Holder<Key> id, Key material, Key clientBoundMaterial);
|
||||
protected abstract CustomItem.Builder<I> createPlatformItemBuilder(UniqueKey id, Key material, Key clientBoundMaterial);
|
||||
|
||||
protected abstract void registerArmorTrimPattern(Collection<Key> equipments);
|
||||
|
||||
@@ -327,11 +324,9 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
throw new LocalizedResourceConfigException("warning.config.item.duplicate");
|
||||
}
|
||||
|
||||
// register for recipes
|
||||
Holder.Reference<Key> holder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(id)
|
||||
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
|
||||
.register(ResourceKey.create(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
|
||||
UniqueKey uniqueId = UniqueKey.create(id);
|
||||
|
||||
// register for recipes
|
||||
boolean isVanillaItem = isVanillaItem(id);
|
||||
Key material = Key.from(isVanillaItem ? id.value() : ResourceConfigUtils.requireNonEmptyStringOrThrow(section.get("material"), "warning.config.item.missing_material").toLowerCase(Locale.ENGLISH));
|
||||
Key clientBoundMaterial = section.containsKey("client-bound-material") ? Key.from(section.get("client-bound-material").toString().toLowerCase(Locale.ENGLISH)) : material;
|
||||
@@ -346,7 +341,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
|
||||
Key itemModelKey = null;
|
||||
|
||||
CustomItem.Builder<I> itemBuilder = createPlatformItemBuilder(holder, material, clientBoundMaterial);
|
||||
CustomItem.Builder<I> itemBuilder = createPlatformItemBuilder(uniqueId, material, clientBoundMaterial);
|
||||
boolean hasItemModelSection = section.containsKey("item-model");
|
||||
|
||||
// To get at least one model provider
|
||||
|
||||
@@ -6,8 +6,8 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -17,7 +17,7 @@ public interface CustomItem<I> extends BuildableItem<I> {
|
||||
|
||||
Key id();
|
||||
|
||||
Holder<Key> idHolder();
|
||||
UniqueKey uniqueId();
|
||||
|
||||
Key material();
|
||||
|
||||
@@ -47,7 +47,7 @@ public interface CustomItem<I> extends BuildableItem<I> {
|
||||
List<ItemBehavior> behaviors();
|
||||
|
||||
interface Builder<I> {
|
||||
Builder<I> id(Holder<Key> id);
|
||||
Builder<I> id(UniqueKey id);
|
||||
|
||||
Builder<I> clientBoundMaterial(Key clientBoundMaterialKey);
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ import net.momirealms.craftengine.core.pack.model.ModernItemModel;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
|
||||
import net.momirealms.craftengine.core.plugin.Manageable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -82,11 +82,11 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
|
||||
boolean addCustomItem(CustomItem<T> customItem);
|
||||
|
||||
List<Holder<Key>> tagToItems(Key tag);
|
||||
List<UniqueKey> tagToItems(Key tag);
|
||||
|
||||
List<Holder<Key>> tagToVanillaItems(Key tag);
|
||||
List<UniqueKey> tagToVanillaItems(Key tag);
|
||||
|
||||
List<Holder<Key>> tagToCustomItems(Key tag);
|
||||
List<UniqueKey> tagToCustomItems(Key tag);
|
||||
|
||||
int fuelTime(T itemStack);
|
||||
|
||||
|
||||
@@ -2,12 +2,7 @@ package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.EnumUtils;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -21,14 +16,13 @@ public abstract class AbstractRecipeFactory<T> implements RecipeFactory<T> {
|
||||
return MiscUtils.castToMap(getIngredientOrThrow(arguments), true);
|
||||
}
|
||||
|
||||
protected Set<Holder<Key>> ingredientHolders(Map<String, Object> arguments) {
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
protected Set<UniqueKey> ingredientHolders(Map<String, Object> arguments) {
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : ingredients(arguments)) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
return holders;
|
||||
|
||||
@@ -11,8 +11,8 @@ import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -140,8 +140,8 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
this.byResult.computeIfAbsent(recipe.result().item().id(), k -> new ArrayList<>()).add(recipe);
|
||||
HashSet<Key> usedKeys = new HashSet<>();
|
||||
for (Ingredient<T> ingredient : recipe.ingredientsInUse()) {
|
||||
for (Holder<Key> holder : ingredient.items()) {
|
||||
Key key = holder.value();
|
||||
for (UniqueKey holder : ingredient.items()) {
|
||||
Key key = holder.key();
|
||||
if (usedKeys.add(key)) {
|
||||
this.byIngredient.computeIfAbsent(key, k -> new ArrayList<>()).add(recipe);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -28,7 +28,7 @@ public class CustomBlastingRecipe<T> extends CustomCookingRecipe<T> {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<Holder<Key>> holders = ingredientHolders(arguments);
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomBlastingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -28,7 +28,7 @@ public class CustomCampfireRecipe<T> extends CustomCookingRecipe<T> {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<Holder<Key>> holders = ingredientHolders(arguments);
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomCampfireRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,9 @@ import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
@@ -156,13 +155,12 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
}
|
||||
char ch = key.charAt(0);
|
||||
List<String> items = MiscUtils.getAsStringList(entry.getValue());
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
ingredients.put(ch, Ingredient.of(holders));
|
||||
|
||||
@@ -3,11 +3,9 @@ package net.momirealms.craftengine.core.item.recipe;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
@@ -64,13 +62,12 @@ public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
if (ingredientsObject instanceof Map<?,?> map) {
|
||||
for (Map.Entry<String, Object> entry : (MiscUtils.castToMap(map, false)).entrySet()) {
|
||||
List<String> items = MiscUtils.getAsStringList(entry.getValue());
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
@@ -78,36 +75,33 @@ public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
} else if (ingredientsObject instanceof List<?> list) {
|
||||
for (Object obj : list) {
|
||||
if (obj instanceof List<?> inner) {
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : MiscUtils.getAsStringList(inner)) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
} else {
|
||||
String item = obj.toString();
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String item = ingredientsObject.toString();
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -28,7 +28,7 @@ public class CustomSmeltingRecipe<T> extends CustomCookingRecipe<T> {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<Holder<Key>> holders = ingredientHolders(arguments);
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomSmeltingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import net.momirealms.craftengine.core.item.recipe.input.SmithingInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.registry.Registries;
|
||||
import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
@@ -145,13 +144,12 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
||||
}
|
||||
|
||||
private Ingredient<A> toIngredient(List<String> items) {
|
||||
Set<Holder<Key>> holders = new HashSet<>();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
return holders.isEmpty() ? null : Ingredient.of(holders);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -28,7 +28,7 @@ public class CustomSmokingRecipe<T> extends CustomCookingRecipe<T> {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<Holder<Key>> holders = ingredientHolders(arguments);
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomSmokingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -45,7 +45,7 @@ public class CustomStoneCuttingRecipe<T> extends AbstractGroupedRecipe<T> {
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
Set<Holder<Key>> holders = ingredientHolders(arguments);
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomStoneCuttingRecipe<>(id, group, Ingredient.of(holders), parseResult(arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedContents.IngredientInfo<Holder<Key>> {
|
||||
private final List<Holder<Key>> items;
|
||||
public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedContents.IngredientInfo<UniqueKey> {
|
||||
private final List<UniqueKey> items;
|
||||
|
||||
public Ingredient(List<Holder<Key>> items) {
|
||||
public Ingredient(List<UniqueKey> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@@ -18,17 +17,17 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
|
||||
.orElseGet(stack::isEmpty);
|
||||
}
|
||||
|
||||
public static <T> Ingredient<T> of(List<Holder<Key>> items) {
|
||||
public static <T> Ingredient<T> of(List<UniqueKey> items) {
|
||||
return new Ingredient<>(items);
|
||||
}
|
||||
|
||||
public static <T> Ingredient<T> of(Set<Holder<Key>> items) {
|
||||
public static <T> Ingredient<T> of(Set<UniqueKey> items) {
|
||||
return new Ingredient<>(new ArrayList<>(items));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(OptimizedIDItem<T> optimizedIDItem) {
|
||||
for (Holder<Key> item : this.items()) {
|
||||
for (UniqueKey item : this.items()) {
|
||||
if (optimizedIDItem.is(item)) {
|
||||
return true;
|
||||
}
|
||||
@@ -36,14 +35,14 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<Holder<Key>> items() {
|
||||
public List<UniqueKey> items() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (Holder<Key> item : this.items()) {
|
||||
for (UniqueKey item : this.items()) {
|
||||
joiner.add(item.toString());
|
||||
}
|
||||
return "Ingredient: [" + joiner + "]";
|
||||
@@ -54,7 +53,7 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsItem(Holder<Key> entry) {
|
||||
public boolean acceptsItem(UniqueKey entry) {
|
||||
return this.items.contains(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
public class InvalidRecipeIngredientException extends RuntimeException {
|
||||
private final String ingredient;
|
||||
|
||||
public InvalidRecipeIngredientException(String ingredient) {
|
||||
this.ingredient = ingredient;
|
||||
}
|
||||
|
||||
public String ingredient() {
|
||||
return ingredient;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,36 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
|
||||
public class OptimizedIDItem<T> {
|
||||
private final T rawItem;
|
||||
private final Holder<Key> idHolder;
|
||||
private final UniqueKey uniqueId;
|
||||
|
||||
public OptimizedIDItem(Holder<Key> idHolder, T rawItem) {
|
||||
this.idHolder = idHolder;
|
||||
public OptimizedIDItem(UniqueKey uniqueId, T rawItem) {
|
||||
this.uniqueId = uniqueId;
|
||||
this.rawItem = rawItem;
|
||||
}
|
||||
|
||||
public Holder<Key> id() {
|
||||
return idHolder;
|
||||
public UniqueKey id() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
public T rawItem() {
|
||||
return rawItem;
|
||||
}
|
||||
|
||||
public boolean is(Holder<Key> id) {
|
||||
return idHolder == id;
|
||||
public boolean is(UniqueKey id) {
|
||||
return uniqueId == id;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return idHolder == null;
|
||||
return uniqueId == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OptimizedIDItem{" +
|
||||
"idHolder=" + idHolder +
|
||||
"uniqueId=" + uniqueId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public interface RecipeFactory<T> {
|
||||
int count = ResourceConfigUtils.getAsInt(resultMap.getOrDefault("count", 1), "count");
|
||||
return new CustomRecipeResult(
|
||||
CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", id)),
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id)),
|
||||
count
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RecipeFinder {
|
||||
private final StackedContents<Holder<Key>> stackedContents = new StackedContents<>();
|
||||
private final StackedContents<UniqueKey> stackedContents = new StackedContents<>();
|
||||
|
||||
public <T> void addInput(OptimizedIDItem<T> item) {
|
||||
if (!item.isEmpty()) {
|
||||
@@ -19,7 +18,7 @@ public class RecipeFinder {
|
||||
return !placementInfo.isImpossibleToPlace() && canCraft(placementInfo.ingredients());
|
||||
}
|
||||
|
||||
private boolean canCraft(List<? extends StackedContents.IngredientInfo<Holder<Key>>> rawIngredients) {
|
||||
private boolean canCraft(List<? extends StackedContents.IngredientInfo<UniqueKey>> rawIngredients) {
|
||||
return this.stackedContents.tryPick(rawIngredients);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,7 @@ import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.gui.*;
|
||||
import net.momirealms.craftengine.core.plugin.gui.Ingredient;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
@@ -506,8 +502,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
|
||||
List<Item<?>> templates = new ArrayList<>();
|
||||
Optional.ofNullable(recipe.template()).ifPresent(it -> {
|
||||
for (Holder<Key> in : it.items()) {
|
||||
templates.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : it.items()) {
|
||||
templates.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
});
|
||||
layout.addIngredient('A', templates.isEmpty() ? GuiElement.EMPTY : GuiElement.recipeIngredient(templates, (e, c) -> {
|
||||
@@ -539,8 +535,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
|
||||
List<Item<?>> bases = new ArrayList<>();
|
||||
Optional.ofNullable(recipe.base()).ifPresent(it -> {
|
||||
for (Holder<Key> in : it.items()) {
|
||||
bases.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : it.items()) {
|
||||
bases.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
});
|
||||
layout.addIngredient('B', bases.isEmpty() ? GuiElement.EMPTY : GuiElement.recipeIngredient(bases, (e, c) -> {
|
||||
@@ -572,8 +568,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
|
||||
List<Item<?>> additions = new ArrayList<>();
|
||||
Optional.ofNullable(recipe.addition()).ifPresent(it -> {
|
||||
for (Holder<Key> in : it.items()) {
|
||||
additions.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : it.items()) {
|
||||
additions.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
});
|
||||
layout.addIngredient('C', additions.isEmpty() ? GuiElement.EMPTY : GuiElement.recipeIngredient(additions, (e, c) -> {
|
||||
@@ -623,8 +619,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
|
||||
List<Item<?>> ingredients = new ArrayList<>();
|
||||
net.momirealms.craftengine.core.item.recipe.Ingredient<Object> ingredient = recipe.ingredient();
|
||||
for (Holder<Key> in : ingredient.items()) {
|
||||
ingredients.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : ingredient.items()) {
|
||||
ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
GuiLayout layout = new GuiLayout(
|
||||
" ",
|
||||
@@ -756,8 +752,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
|
||||
List<Item<?>> ingredients = new ArrayList<>();
|
||||
net.momirealms.craftengine.core.item.recipe.Ingredient<Object> ingredient = recipe.ingredient();
|
||||
for (Holder<Key> in : ingredient.items()) {
|
||||
ingredients.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : ingredient.items()) {
|
||||
ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
GuiLayout layout = new GuiLayout(
|
||||
" ",
|
||||
@@ -1001,8 +997,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
layout.addIngredient(currentChar, Ingredient.EMPTY);
|
||||
} else {
|
||||
List<Item<?>> ingredients = new ArrayList<>();
|
||||
for (Holder<Key> in : ingredient.items()) {
|
||||
ingredients.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : ingredient.items()) {
|
||||
ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
layout.addIngredient(currentChar, GuiElement.recipeIngredient(ingredients, (e, c) -> {
|
||||
c.cancel();
|
||||
@@ -1044,8 +1040,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
|
||||
char currentChar = (char) (start + x + y * 3);
|
||||
if (i < ingredients.size()) {
|
||||
List<Item<?>> ingredientItems = new ArrayList<>();
|
||||
for (Holder<Key> in : ingredients.get(i).items()) {
|
||||
ingredientItems.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
|
||||
for (UniqueKey in : ingredients.get(i).items()) {
|
||||
ingredientItems.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
|
||||
}
|
||||
layout.addIngredient(currentChar, GuiElement.recipeIngredient(ingredientItems, (e, c) -> {
|
||||
c.cancel();
|
||||
|
||||
@@ -36,12 +36,10 @@ import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory
|
||||
import net.momirealms.craftengine.core.plugin.context.function.FunctionFactory;
|
||||
import net.momirealms.craftengine.core.plugin.context.number.NumberProviderFactory;
|
||||
import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectorFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
|
||||
public class BuiltInRegistries {
|
||||
public static final Registry<CustomBlock> BLOCK = createDynamicBoundRegistry(Registries.BLOCK);
|
||||
public static final Registry<Key> OPTIMIZED_ITEM_ID = createConstantBoundRegistry(Registries.OPTIMIZED_ITEM_ID);
|
||||
public static final Registry<BlockBehaviorFactory> BLOCK_BEHAVIOR_FACTORY = createConstantBoundRegistry(Registries.BLOCK_BEHAVIOR_FACTORY);
|
||||
public static final Registry<ItemBehaviorFactory> ITEM_BEHAVIOR_FACTORY = createConstantBoundRegistry(Registries.ITEM_BEHAVIOR_FACTORY);
|
||||
public static final Registry<PropertyFactory> PROPERTY_FACTORY = createConstantBoundRegistry(Registries.PROPERTY_FACTORY);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class UniqueKey {
|
||||
private static final Map<Key, UniqueKey> CACHE = new HashMap<>(4096, 0.5f);
|
||||
private final Key key;
|
||||
|
||||
private UniqueKey(Key key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public static UniqueKey create(Key key) {
|
||||
return CACHE.computeIfAbsent(key, UniqueKey::new);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static UniqueKey getCached(Key key) {
|
||||
return CACHE.get(key);
|
||||
}
|
||||
|
||||
public Key key() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user