Skip to content

Commit

Permalink
fix: šŸ› Fix compression upgrade to properly update contents of compresā€¦
Browse files Browse the repository at this point in the history
ā€¦sion slots after recipe updates supporting proper addition / removal of recipes, updating items shown on barrel and proper updates after reload command
  • Loading branch information
P3pp3rF1y committed Apr 5, 2024
1 parent 49f2bc9 commit b10158d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 64 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
112 changes: 68 additions & 44 deletions src/main/java/net/p3pp3rf1y/sophisticatedcore/util/RecipeHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -39,14 +41,25 @@ public Set<CompactingShape> load(Item item) {
}
});
private static final int MAX_FOLLOW_UP_COMPACTING_RECIPES = 30;
private static WeakReference<Level> world;
private static WeakReference<Level> clientLevel;
private static WeakReference<Level> serverLevel;
private static final Map<CompactedItem, CompactingResult> COMPACTING_RESULTS = new HashMap<>();
private static final Map<Item, UncompactingResult> 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() {
Expand All @@ -55,27 +68,28 @@ public static void clearCache() {
ITEM_COMPACTING_SHAPES.invalidateAll();
}

public static void onReload(final AddReloadListenerEvent evt) {
evt.addListener(new SimplePreparableReloadListener<Void>() {
@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<Level> getWorld() {
return world != null ? Optional.ofNullable(world.get()) : Optional.empty();
private static Optional<Level> 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<CompactingShape> getCompactingShapes(Item item) {
return getWorld().map(w -> {
return getLevel().map(w -> {
Set<CompactingShape> 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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -256,26 +267,21 @@ public boolean stillValid(Player playerIn) {
}

public static <T extends AbstractCookingRecipe> Optional<T> getCookingRecipe(ItemStack stack, RecipeType<T> 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<CompactingShape> getItemCompactingShapes(Item item) {
return ITEM_COMPACTING_SHAPES.getUnchecked(item);
}

public static List<StonecutterRecipe> getStonecuttingRecipes(Container inventory) {
return getRecipesOfType(RecipeType.STONECUTTING, inventory);
}

public static <T extends Recipe<Container>> List<T> getRecipesOfType(RecipeType<T> 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 <C extends Container, T extends Recipe<C>> Optional<T> safeGetRecipeFor(RecipeType<T> 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();
}
Expand All @@ -284,8 +290,7 @@ public static <C extends Container, T extends Recipe<C>> Optional<T> safeGetReci
public static <C extends Container, T extends Recipe<C>> List<T> safeGetRecipesFor(RecipeType<T> 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();
}
Expand Down Expand Up @@ -387,4 +392,23 @@ public int hashCode() {
return Objects.hash(item, width, height);
}
}

private static class RecipeChangeListenerList {
private final List<WeakReference<Runnable>> 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;
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,15 @@
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;
import org.junit.jupiter.params.ParameterizedTest;
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;
Expand Down Expand Up @@ -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);

Expand All @@ -158,7 +148,7 @@ static Stream<Arguments> testGetCompatingResult() {
@ParameterizedTest
@MethodSource
void testGetUncompactingResult(Level level, Item item, RecipeHelper.UncompactingResult expectedResult) {
RecipeHelper.setWorld(level);
RecipeHelper.setLevel(level);

RecipeHelper.UncompactingResult actualResult = RecipeHelper.getUncompactingResult(item);

Expand All @@ -179,7 +169,7 @@ static Stream<Arguments> testGetUncompactingResult() {
@ParameterizedTest
@MethodSource
void testGetItemCompactingShapes(Level level, Item item, Set<RecipeHelper.CompactingShape> shapes) {
RecipeHelper.setWorld(level);
RecipeHelper.setLevel(level);

Set<RecipeHelper.CompactingShape> actualShapes = RecipeHelper.getItemCompactingShapes(item);

Expand Down

0 comments on commit b10158d

Please sign in to comment.