From b10158d726976da6b533e2c29bdc1295059c9614 Mon Sep 17 00:00:00 2001 From: P3pp3rF1y Date: Fri, 5 Apr 2024 11:52:10 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20compression=20upgra?= =?UTF-8?q?de=20to=20properly=20update=20contents=20of=20compression=20slo?= =?UTF-8?q?ts=20after=20recipe=20updates=20supporting=20proper=20addition?= =?UTF-8?q?=20/=20removal=20of=20recipes,=20updating=20items=20shown=20on?= =?UTF-8?q?=20barrel=20and=20proper=20updates=20after=20reload=20command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- .../sophisticatedcore/SophisticatedCore.java | 3 +- .../client/ClientEventHandler.java | 2 +- .../common/CommonEventHandler.java | 3 +- .../sophisticatedcore/util/RecipeHelper.java | 112 +++++++++++------- .../util/RecipeHelperTest.java | 20 +--- 6 files changed, 78 insertions(+), 64 deletions(-) diff --git a/gradle.properties b/gradle.properties index b38edb3d..00e2602d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.daemon=false mod_id=sophisticatedcore mod_group_id=sophisticatedcore -mod_version=0.6.14 +mod_version=0.6.15 sonar_project_key=sophisticatedcore:SophisticatedCore github_package_url=https://maven.pkg.github.com/P3pp3rF1y/SophisticatedCore diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedcore/SophisticatedCore.java b/src/main/java/net/p3pp3rf1y/sophisticatedcore/SophisticatedCore.java index de662797..8248b51a 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedcore/SophisticatedCore.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedcore/SophisticatedCore.java @@ -16,7 +16,6 @@ import net.minecraftforge.fml.loading.FMLEnvironment; import net.p3pp3rf1y.sophisticatedcore.client.ClientEventHandler; import net.p3pp3rf1y.sophisticatedcore.common.CommonEventHandler; -import net.p3pp3rf1y.sophisticatedcore.crafting.UpgradeNextTierRecipe; import net.p3pp3rf1y.sophisticatedcore.data.DataGenerators; import net.p3pp3rf1y.sophisticatedcore.init.ModCompat; import net.p3pp3rf1y.sophisticatedcore.network.PacketHandler; @@ -52,7 +51,7 @@ public SophisticatedCore() { private static void serverStarted(ServerStartedEvent event) { ServerLevel world = event.getServer().getLevel(Level.OVERWORLD); if (world != null) { - RecipeHelper.setWorld(world); + RecipeHelper.setLevel(world); } } diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedcore/client/ClientEventHandler.java b/src/main/java/net/p3pp3rf1y/sophisticatedcore/client/ClientEventHandler.java index 17312c31..ad4d816a 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedcore/client/ClientEventHandler.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedcore/client/ClientEventHandler.java @@ -125,6 +125,6 @@ private record StashResultAndTooltip(IStashStorageItem.StashResult stashResult, private static void onPlayerJoinServer(ClientPlayerNetworkEvent.LoggingIn evt) { //noinspection ConstantConditions - by the time player is joining the world is not null - RecipeHelper.setWorld(Minecraft.getInstance().level); + RecipeHelper.setLevel(Minecraft.getInstance().level); } } diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedcore/common/CommonEventHandler.java b/src/main/java/net/p3pp3rf1y/sophisticatedcore/common/CommonEventHandler.java index 7660c625..c2aa3c11 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedcore/common/CommonEventHandler.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedcore/common/CommonEventHandler.java @@ -16,6 +16,7 @@ public void registerHandlers() { ModParticles.registerParticles(modBus); ModRecipes.registerHandlers(modBus); MinecraftForge.EVENT_BUS.addListener(ItemStackKey::clearCacheOnTickEnd); - MinecraftForge.EVENT_BUS.addListener(RecipeHelper::onReload); + MinecraftForge.EVENT_BUS.addListener(RecipeHelper::onDataPackSync); + MinecraftForge.EVENT_BUS.addListener(RecipeHelper::onRecipesUpdated); } } diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelper.java b/src/main/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelper.java index 37c15dc0..eecf5501 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelper.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelper.java @@ -4,9 +4,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import net.minecraft.core.NonNullList; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.server.packs.resources.SimplePreparableReloadListener; -import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -15,15 +13,19 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.*; +import net.minecraft.world.item.crafting.AbstractCookingRecipe; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.Level; -import net.minecraftforge.event.AddReloadListenerEvent; +import net.minecraftforge.client.event.RecipesUpdatedEvent; +import net.minecraftforge.event.OnDatapackSyncEvent; +import net.minecraftforge.fml.util.thread.SidedThreadGroups; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.RecipeWrapper; import net.minecraftforge.registries.ForgeRegistries; import net.p3pp3rf1y.sophisticatedcore.SophisticatedCore; -import javax.annotation.Nonnull; import java.lang.ref.WeakReference; import java.util.*; import java.util.concurrent.TimeUnit; @@ -39,14 +41,25 @@ public Set load(Item item) { } }); private static final int MAX_FOLLOW_UP_COMPACTING_RECIPES = 30; - private static WeakReference world; + private static WeakReference clientLevel; + private static WeakReference serverLevel; private static final Map COMPACTING_RESULTS = new HashMap<>(); private static final Map UNCOMPACTING_RESULTS = new HashMap<>(); + private static final RecipeChangeListenerList RECIPE_CHANGE_LISTENERS = new RecipeChangeListenerList(); - private RecipeHelper() {} + private RecipeHelper() { + } + + public static void setLevel(Level l) { + if (l instanceof ServerLevel) { + serverLevel = new WeakReference<>(l); + } else { + clientLevel = new WeakReference<>(l); + } + } - public static void setWorld(Level w) { - world = new WeakReference<>(w); + public static void addRecipeChangeListener(Runnable runnable) { + RECIPE_CHANGE_LISTENERS.add(runnable); } public static void clearCache() { @@ -55,27 +68,28 @@ public static void clearCache() { ITEM_COMPACTING_SHAPES.invalidateAll(); } - public static void onReload(final AddReloadListenerEvent evt) { - evt.addListener(new SimplePreparableReloadListener() { - @Nonnull - @Override - protected Void prepare(ResourceManager resourceManager, ProfilerFiller profilerFiller) { - return null; - } + @SuppressWarnings("unused") //event parameter used to identify which event this listener is for + public static void onRecipesUpdated(RecipesUpdatedEvent event) { + clearCache(); + RECIPE_CHANGE_LISTENERS.notifyAllListeners(); + } - @Override - protected void apply(Void object, ResourceManager resourceManager, ProfilerFiller profilerFiller) { - clearCache(); - } - }); + @SuppressWarnings("unused") //event parameter used to identify which event this listener is for + public static void onDataPackSync(OnDatapackSyncEvent event) { + clearCache(); + RECIPE_CHANGE_LISTENERS.notifyAllListeners(); } - private static Optional getWorld() { - return world != null ? Optional.ofNullable(world.get()) : Optional.empty(); + private static Optional getLevel() { + if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER) { + return serverLevel != null ? Optional.ofNullable(serverLevel.get()) : Optional.empty(); + } else { + return clientLevel != null ? Optional.ofNullable(clientLevel.get()) : Optional.empty(); + } } private static Set getCompactingShapes(Item item) { - return getWorld().map(w -> { + return getLevel().map(w -> { Set compactingShapes = new HashSet<>(); getCompactingShape(item, w, 2, 2, TWO_BY_TWO_UNCRAFTABLE, TWO_BY_TWO).ifPresent(compactingShapes::add); getCompactingShape(item, w, 3, 3, THREE_BY_THREE_UNCRAFTABLE, THREE_BY_THREE).ifPresent(compactingShapes::add); @@ -144,7 +158,7 @@ private static boolean isPartOfCompactingLoop(Item firstCompacted, Item firstCom private static boolean uncompactMatchesItem(ItemStack result, Level w, Item item, int count) { Item itemToUncompact = result.getItem(); - for(ItemStack uncompactResult : getUncompactResultItems(w, itemToUncompact)) { + for (ItemStack uncompactResult : getUncompactResultItems(w, itemToUncompact)) { if (uncompactResult.getItem() == item && uncompactResult.getCount() == count) { return true; } @@ -153,7 +167,7 @@ private static boolean uncompactMatchesItem(ItemStack result, Level w, Item item } public static UncompactingResult getUncompactingResult(Item resultItem) { - return UNCOMPACTING_RESULTS.computeIfAbsent(resultItem, k -> getWorld().map(w -> { + return UNCOMPACTING_RESULTS.computeIfAbsent(resultItem, k -> getLevel().map(w -> { for (ItemStack uncompactResultItem : getUncompactResultItems(w, resultItem)) { if (uncompactResultItem.getCount() == 9) { if (getCompactingResult(uncompactResultItem.getItem(), 3, 3).getResult().getItem() == resultItem) { @@ -182,7 +196,7 @@ public static CompactingResult getCompactingResult(Item item, CompactingShape sh } public static CompactingResult getCompactingResult(Item item, int width, int height) { - return getWorld().map(w -> getCompactingResult(item, w, width, height)).orElse(CompactingResult.EMPTY); + return getLevel().map(w -> getCompactingResult(item, w, width, height)).orElse(CompactingResult.EMPTY); } private static CompactingResult getCompactingResult(Item item, Level level, int width, int height) { @@ -214,12 +228,9 @@ private static CompactingResult getCompactingResult(Item item, Level level, int } private static CompactingResult cacheAndGetCompactingResult(CompactedItem compactedItem, CraftingRecipe recipe, CraftingContainer craftingInventory) { - Level level = world.get(); - if (level == null) { - return CompactingResult.EMPTY; - } - - return cacheAndGetCompactingResult(compactedItem, recipe, craftingInventory, recipe.assemble(craftingInventory, level.registryAccess())); + return getLevel().map(level -> + cacheAndGetCompactingResult(compactedItem, recipe, craftingInventory, recipe.assemble(craftingInventory, level.registryAccess())) + ).orElse(CompactingResult.EMPTY); } private static CompactingResult cacheAndGetCompactingResult(CompactedItem compactedItem, CraftingRecipe recipe, CraftingContainer craftingInventory, ItemStack result) { @@ -256,26 +267,21 @@ public boolean stillValid(Player playerIn) { } public static Optional getCookingRecipe(ItemStack stack, RecipeType recipeType) { - return getWorld().flatMap(w -> safeGetRecipeFor(recipeType, new RecipeWrapper(new ItemStackHandler(NonNullList.of(ItemStack.EMPTY, stack))), w)); + return getLevel().flatMap(w -> safeGetRecipeFor(recipeType, new RecipeWrapper(new ItemStackHandler(NonNullList.of(ItemStack.EMPTY, stack))), w)); } public static Set getItemCompactingShapes(Item item) { return ITEM_COMPACTING_SHAPES.getUnchecked(item); } - public static List getStonecuttingRecipes(Container inventory) { - return getRecipesOfType(RecipeType.STONECUTTING, inventory); - } - public static > List getRecipesOfType(RecipeType recipeType, Container inventory) { - return getWorld().map(w -> w.getRecipeManager().getRecipesFor(recipeType, inventory, w)).orElse(Collections.emptyList()); + return getLevel().map(w -> w.getRecipeManager().getRecipesFor(recipeType, inventory, w)).orElse(Collections.emptyList()); } public static > Optional safeGetRecipeFor(RecipeType recipeType, C inventory, Level level) { try { return level.getRecipeManager().getRecipeFor(recipeType, inventory, level); - } - catch (Exception e) { + } catch (Exception e) { SophisticatedCore.LOGGER.error("Error while getting recipe ", e); return Optional.empty(); } @@ -284,8 +290,7 @@ public static > Optional safeGetReci public static > List safeGetRecipesFor(RecipeType recipeType, C inventory, Level level) { try { return level.getRecipeManager().getRecipesFor(recipeType, inventory, level); - } - catch (Exception e) { + } catch (Exception e) { SophisticatedCore.LOGGER.error("Error while getting recipe ", e); return Collections.emptyList(); } @@ -387,4 +392,23 @@ public int hashCode() { return Objects.hash(item, width, height); } } + + private static class RecipeChangeListenerList { + private final List> list = new ArrayList<>(); + + public void add(Runnable runnable) { + list.add(new WeakReference<>(runnable)); + } + + public void notifyAllListeners() { + list.removeIf(ref -> { + Runnable runnable = ref.get(); + if (runnable != null) { + runnable.run(); + return false; + } + return true; + }); + } + } } diff --git a/src/test/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelperTest.java b/src/test/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelperTest.java index 4fd0c9a6..cf7f99d5 100644 --- a/src/test/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelperTest.java +++ b/src/test/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelperTest.java @@ -8,13 +8,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.CraftingBookCategory; -import net.minecraft.world.item.crafting.CraftingRecipe; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.RecipeManager; -import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.item.crafting.ShapedRecipe; -import net.minecraft.world.item.crafting.ShapelessRecipe; +import net.minecraft.world.item.crafting.*; import net.minecraft.world.level.Level; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -22,11 +16,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Stream; import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure; @@ -136,7 +126,7 @@ void clearCache() { @ParameterizedTest @MethodSource void testGetCompatingResult(Level level, Item item, RecipeHelper.CompactingResult expectedResult) { - RecipeHelper.setWorld(level); + RecipeHelper.setLevel(level); RecipeHelper.CompactingResult actualResult = RecipeHelper.getCompactingResult(item, RecipeHelper.CompactingShape.THREE_BY_THREE_UNCRAFTABLE); @@ -158,7 +148,7 @@ static Stream testGetCompatingResult() { @ParameterizedTest @MethodSource void testGetUncompactingResult(Level level, Item item, RecipeHelper.UncompactingResult expectedResult) { - RecipeHelper.setWorld(level); + RecipeHelper.setLevel(level); RecipeHelper.UncompactingResult actualResult = RecipeHelper.getUncompactingResult(item); @@ -179,7 +169,7 @@ static Stream testGetUncompactingResult() { @ParameterizedTest @MethodSource void testGetItemCompactingShapes(Level level, Item item, Set shapes) { - RecipeHelper.setWorld(level); + RecipeHelper.setLevel(level); Set actualShapes = RecipeHelper.getItemCompactingShapes(item);