aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-spigotflower/net/minecraft/world/item/crafting/RecipeManager.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-spigotflower/net/minecraft/world/item/crafting/RecipeManager.java.patch')
-rw-r--r--patch-remap/mache-spigotflower/net/minecraft/world/item/crafting/RecipeManager.java.patch274
1 files changed, 274 insertions, 0 deletions
diff --git a/patch-remap/mache-spigotflower/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patch-remap/mache-spigotflower/net/minecraft/world/item/crafting/RecipeManager.java.patch
new file mode 100644
index 0000000000..ae8c6942ab
--- /dev/null
+++ b/patch-remap/mache-spigotflower/net/minecraft/world/item/crafting/RecipeManager.java.patch
@@ -0,0 +1,274 @@
+--- a/net/minecraft/world/item/crafting/RecipeManager.java
++++ b/net/minecraft/world/item/crafting/RecipeManager.java
+@@ -24,21 +24,26 @@
+ import javax.annotation.Nullable;
+ import net.minecraft.Util;
+ import net.minecraft.core.NonNullList;
++import net.minecraft.world.Container;
++import net.minecraft.world.item.ItemStack;
++import net.minecraft.world.level.Level;
++import org.slf4j.Logger;
++
++// CraftBukkit start
++import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
++import net.minecraft.core.registries.BuiltInRegistries;
++// CraftBukkit end
+ import net.minecraft.resources.ResourceLocation;
+ import net.minecraft.server.packs.resources.ResourceManager;
+ import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
+ import net.minecraft.util.GsonHelper;
+ import net.minecraft.util.profiling.ProfilerFiller;
+-import net.minecraft.world.Container;
+-import net.minecraft.world.item.ItemStack;
+-import net.minecraft.world.level.Level;
+-import org.slf4j.Logger;
+
+ public class RecipeManager extends SimpleJsonResourceReloadListener {
+
+ private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create();
+ private static final Logger LOGGER = LogUtils.getLogger();
+- private Map<RecipeType<?>, Map<ResourceLocation, RecipeHolder<?>>> recipes = ImmutableMap.of();
++ public Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>> recipes = ImmutableMap.of(); // CraftBukkit
+ private Map<ResourceLocation, RecipeHolder<?>> byName = ImmutableMap.of();
+ private boolean hasErrors;
+
+@@ -46,98 +51,121 @@
+ super(RecipeManager.GSON, "recipes");
+ }
+
+- @Override
+- protected void apply(Map<ResourceLocation, JsonElement> map, ResourceManager resourcemanager, ProfilerFiller profilerfiller) {
++ protected void apply(Map<ResourceLocation, JsonElement> object, ResourceManager resourceManager, ProfilerFiller profiler) {
+ this.hasErrors = false;
+- Map<RecipeType<?>, Builder<ResourceLocation, RecipeHolder<?>>> map1 = Maps.newHashMap();
++ // CraftBukkit start - SPIGOT-5667 make sure all types are populated and mutable
++ Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>> map1 = Maps.newHashMap();
++ for (RecipeType<?> recipeType : BuiltInRegistries.RECIPE_TYPE) {
++ map1.put(recipeType, new Object2ObjectLinkedOpenHashMap<>());
++ }
++ // CraftBukkit end
+ Builder<ResourceLocation, RecipeHolder<?>> builder = ImmutableMap.builder();
+- Iterator iterator = map.entrySet().iterator();
++ Iterator iterator = object.entrySet().iterator();
+
+ while (iterator.hasNext()) {
+ Entry<ResourceLocation, JsonElement> entry = (Entry) iterator.next();
+- ResourceLocation resourcelocation = (ResourceLocation) entry.getKey();
++ ResourceLocation minecraftkey = (ResourceLocation) entry.getKey();
+
+ try {
+- RecipeHolder<?> recipeholder = fromJson(resourcelocation, GsonHelper.convertToJsonObject((JsonElement) entry.getValue(), "top element"));
++ RecipeHolder<?> recipeholder = fromJson(minecraftkey, GsonHelper.convertToJsonObject((JsonElement) entry.getValue(), "top element"));
+
+- ((Builder) map1.computeIfAbsent(recipeholder.value().getType(), (recipetype) -> {
+- return ImmutableMap.builder();
+- })).put(resourcelocation, recipeholder);
+- builder.put(resourcelocation, recipeholder);
++ // CraftBukkit start
++ (map1.computeIfAbsent(recipeholder.value().getType(), (recipes) -> {
++ return new Object2ObjectLinkedOpenHashMap<>();
++ // CraftBukkit end
++ })).put(minecraftkey, recipeholder);
++ builder.put(minecraftkey, recipeholder);
+ } catch (IllegalArgumentException | JsonParseException jsonparseexception) {
+- RecipeManager.LOGGER.error("Parsing error loading recipe {}", resourcelocation, jsonparseexception);
++ RecipeManager.LOGGER.error("Parsing error loading recipe {}", minecraftkey, jsonparseexception);
+ }
+ }
+
+ this.recipes = (Map) map1.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry1) -> {
+- return ((Builder) entry1.getValue()).build();
++ return (entry1.getValue()); // CraftBukkit
+ }));
+- this.byName = builder.build();
++ this.byName = Maps.newHashMap(builder.build()); // CraftBukkit
+ RecipeManager.LOGGER.info("Loaded {} recipes", map1.size());
+ }
+
++ // CraftBukkit start
++ public void addRecipe(RecipeHolder<?> irecipe) {
++ Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>> map = this.recipes.get(irecipe.value().getType()); // CraftBukkit
++
++ if (byName.containsKey(irecipe.id()) || map.containsKey(irecipe.id())) {
++ throw new IllegalStateException("Duplicate recipe ignored with ID " + irecipe.id());
++ } else {
++ map.putAndMoveToFirst(irecipe.id(), irecipe); // CraftBukkit - SPIGOT-4638: last recipe gets priority
++ byName.put(irecipe.id(), irecipe);
++ }
++ }
++ // CraftBukkit end
++
+ public boolean hadErrorsLoading() {
+ return this.hasErrors;
+ }
+
+- public <C extends Container, T extends Recipe<C>> Optional<RecipeHolder<T>> getRecipeFor(RecipeType<T> recipetype, C c0, Level level) {
+- return this.byType(recipetype).values().stream().filter((recipeholder) -> {
+- return recipeholder.value().matches(c0, level);
++ public <C extends Container, T extends Recipe<C>> Optional<RecipeHolder<T>> getRecipeFor(RecipeType<T> recipeType, C inventory, Level level) {
++ // CraftBukkit start
++ Optional<RecipeHolder<T>> recipe = this.byType(recipeType).values().stream().filter((recipeholder) -> {
++ return recipeholder.value().matches(inventory, level);
+ }).findFirst();
++ inventory.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found
++ return recipe;
++ // CraftBukkit end
+ }
+
+- public <C extends Container, T extends Recipe<C>> Optional<Pair<ResourceLocation, RecipeHolder<T>>> getRecipeFor(RecipeType<T> recipetype, C c0, Level level, @Nullable ResourceLocation resourcelocation) {
+- Map<ResourceLocation, RecipeHolder<T>> map = this.byType(recipetype);
++ public <C extends Container, T extends Recipe<C>> Optional<Pair<ResourceLocation, RecipeHolder<T>>> getRecipeFor(RecipeType<T> recipeType, C inventory, Level level, @Nullable ResourceLocation lastRecipe) {
++ Map<ResourceLocation, RecipeHolder<T>> map = this.byType(recipeType);
+
+- if (resourcelocation != null) {
+- RecipeHolder<T> recipeholder = (RecipeHolder) map.get(resourcelocation);
++ if (lastRecipe != null) {
++ RecipeHolder<T> recipeholder = (RecipeHolder) map.get(lastRecipe);
+
+- if (recipeholder != null && recipeholder.value().matches(c0, level)) {
+- return Optional.of(Pair.of(resourcelocation, recipeholder));
++ if (recipeholder != null && recipeholder.value().matches(inventory, level)) {
++ return Optional.of(Pair.of(lastRecipe, recipeholder));
+ }
+ }
+
+ return map.entrySet().stream().filter((entry) -> {
+- return ((RecipeHolder) entry.getValue()).value().matches(c0, level);
++ return ((RecipeHolder) entry.getValue()).value().matches(inventory, level);
+ }).findFirst().map((entry) -> {
+ return Pair.of((ResourceLocation) entry.getKey(), (RecipeHolder) entry.getValue());
+ });
+ }
+
+- public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getAllRecipesFor(RecipeType<T> recipetype) {
+- return List.copyOf(this.byType(recipetype).values());
++ public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getAllRecipesFor(RecipeType<T> recipeType) {
++ return List.copyOf(this.byType(recipeType).values());
+ }
+
+- public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getRecipesFor(RecipeType<T> recipetype, C c0, Level level) {
+- return (List) this.byType(recipetype).values().stream().filter((recipeholder) -> {
+- return recipeholder.value().matches(c0, level);
++ public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getRecipesFor(RecipeType<T> recipeType, C inventory, Level level) {
++ return (List) this.byType(recipeType).values().stream().filter((recipeholder) -> {
++ return recipeholder.value().matches(inventory, level);
+ }).sorted(Comparator.comparing((recipeholder) -> {
+ return recipeholder.value().getResultItem(level.registryAccess()).getDescriptionId();
+ })).collect(Collectors.toList());
+ }
+
+- private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, RecipeHolder<T>> byType(RecipeType<T> recipetype) {
+- return (Map) this.recipes.getOrDefault(recipetype, Collections.emptyMap());
++ private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, RecipeHolder<T>> byType(RecipeType<T> recipeType) {
++ return (Map) this.recipes.getOrDefault(recipeType, new Object2ObjectLinkedOpenHashMap<>()); // CraftBukkit
+ }
+
+- public <C extends Container, T extends Recipe<C>> NonNullList<ItemStack> getRemainingItemsFor(RecipeType<T> recipetype, C c0, Level level) {
+- Optional<RecipeHolder<T>> optional = this.getRecipeFor(recipetype, c0, level);
++ public <C extends Container, T extends Recipe<C>> NonNullList<ItemStack> getRemainingItemsFor(RecipeType<T> recipeType, C inventory, Level level) {
++ Optional<RecipeHolder<T>> optional = this.getRecipeFor(recipeType, inventory, level);
+
+ if (optional.isPresent()) {
+- return ((RecipeHolder) optional.get()).value().getRemainingItems(c0);
++ return ((RecipeHolder) optional.get()).value().getRemainingItems(inventory);
+ } else {
+- NonNullList<ItemStack> nonnulllist = NonNullList.withSize(c0.getContainerSize(), ItemStack.EMPTY);
++ NonNullList<ItemStack> nonnulllist = NonNullList.withSize(inventory.getContainerSize(), ItemStack.EMPTY);
+
+ for (int i = 0; i < nonnulllist.size(); ++i) {
+- nonnulllist.set(i, c0.getItem(i));
++ nonnulllist.set(i, inventory.getItem(i));
+ }
+
+ return nonnulllist;
+ }
+ }
+
+- public Optional<RecipeHolder<?>> byKey(ResourceLocation resourcelocation) {
+- return Optional.ofNullable((RecipeHolder) this.byName.get(resourcelocation));
++ public Optional<RecipeHolder<?>> byKey(ResourceLocation recipeId) {
++ return Optional.ofNullable((RecipeHolder) this.byName.get(recipeId));
+ }
+
+ public Collection<RecipeHolder<?>> getRecipes() {
+@@ -152,43 +180,62 @@
+ });
+ }
+
+- protected static RecipeHolder<?> fromJson(ResourceLocation resourcelocation, JsonObject jsonobject) {
+- Recipe<?> recipe = (Recipe) Util.getOrThrow(Recipe.CODEC.parse(JsonOps.INSTANCE, jsonobject), JsonParseException::new);
++ protected static RecipeHolder<?> fromJson(ResourceLocation minecraftkey, JsonObject jsonobject) {
++ Recipe<?> irecipe = (Recipe) Util.getOrThrow(Recipe.CODEC.parse(JsonOps.INSTANCE, jsonobject), JsonParseException::new);
+
+- return new RecipeHolder<>(resourcelocation, recipe);
++ return new RecipeHolder<>(minecraftkey, irecipe);
+ }
+
+- public void replaceRecipes(Iterable<RecipeHolder<?>> iterable) {
++ public void replaceRecipes(Iterable<RecipeHolder<?>> recipes) {
+ this.hasErrors = false;
+- Map<RecipeType<?>, Map<ResourceLocation, RecipeHolder<?>>> map = Maps.newHashMap();
++ Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>> map = Maps.newHashMap(); // CraftBukkit
+ Builder<ResourceLocation, RecipeHolder<?>> builder = ImmutableMap.builder();
+
+- iterable.forEach((recipeholder) -> {
+- Map<ResourceLocation, RecipeHolder<?>> map1 = (Map) map.computeIfAbsent(recipeholder.value().getType(), (recipetype) -> {
+- return Maps.newHashMap();
++ recipes.forEach((recipeholder) -> {
++ Map<ResourceLocation, RecipeHolder<?>> map1 = (Map) map.computeIfAbsent(recipeholder.value().getType(), (recipes) -> {
++ return new Object2ObjectLinkedOpenHashMap<>(); // CraftBukkit
+ });
+- ResourceLocation resourcelocation = recipeholder.id();
+- RecipeHolder<?> recipeholder1 = (RecipeHolder) map1.put(resourcelocation, recipeholder);
++ ResourceLocation minecraftkey = recipeholder.id();
++ RecipeHolder<?> recipeholder1 = (RecipeHolder) map1.put(minecraftkey, recipeholder);
+
+- builder.put(resourcelocation, recipeholder);
++ builder.put(minecraftkey, recipeholder);
+ if (recipeholder1 != null) {
+- throw new IllegalStateException("Duplicate recipe ignored with ID " + resourcelocation);
++ throw new IllegalStateException("Duplicate recipe ignored with ID " + minecraftkey);
+ }
+ });
+ this.recipes = ImmutableMap.copyOf(map);
+- this.byName = builder.build();
++ this.byName = Maps.newHashMap(builder.build()); // CraftBukkit
+ }
+
+- public static <C extends Container, T extends Recipe<C>> RecipeManager.CachedCheck<C, T> createCheck(final RecipeType<T> recipetype) {
++ // CraftBukkit start
++ public boolean removeRecipe(ResourceLocation mcKey) {
++ for (Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>> recipes : recipes.values()) {
++ recipes.remove(mcKey);
++ }
++
++ return byName.remove(mcKey) != null;
++ }
++
++ public void clearRecipes() {
++ this.recipes = Maps.newHashMap();
++
++ for (RecipeType<?> recipeType : BuiltInRegistries.RECIPE_TYPE) {
++ this.recipes.put(recipeType, new Object2ObjectLinkedOpenHashMap<>());
++ }
++
++ this.byName = Maps.newHashMap();
++ }
++ // CraftBukkit end
++
++ public static <C extends Container, T extends Recipe<C>> RecipeManager.CachedCheck<C, T> createCheck(final RecipeType<T> recipeType) {
+ return new RecipeManager.CachedCheck<C, T>() {
+ @Nullable
+ private ResourceLocation lastRecipe;
+
+ @Override
+- @Override
+- public Optional<RecipeHolder<T>> getRecipeFor(C c0, Level level) {
+- RecipeManager recipemanager = level.getRecipeManager();
+- Optional<Pair<ResourceLocation, RecipeHolder<T>>> optional = recipemanager.getRecipeFor(recipetype, c0, level, this.lastRecipe);
++ public Optional<RecipeHolder<T>> getRecipeFor(C container, Level level) {
++ RecipeManager craftingmanager = level.getRecipeManager();
++ Optional<Pair<ResourceLocation, RecipeHolder<T>>> optional = craftingmanager.getRecipeFor(recipeType, container, level, this.lastRecipe);
+
+ if (optional.isPresent()) {
+ Pair<ResourceLocation, RecipeHolder<T>> pair = (Pair) optional.get();