Skip to content

Commit

Permalink
Fix #1666
Browse files Browse the repository at this point in the history
  • Loading branch information
shedaniel committed Aug 14, 2024
1 parent a0e666f commit 90af6e0
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 31 deletions.
4 changes: 4 additions & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import net.fabricmc.loom.task.RemapJarTask

archivesBaseName = rootProject.name + "-" + project.name

loom {
accessWidenerPath = gradle.rootProject.project("fabric").file("src/main/resources/roughlyenoughitems.accessWidener")
}

dependencies {
modCompileOnly("net.fabricmc:fabric-loader:${project.fabricloader_version}")
modApi("me.shedaniel.cloth:cloth-config:${cloth_config_version}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@

package me.shedaniel.rei.api.common.display.basic;

import dev.architectury.utils.EnvExecutor;
import dev.architectury.utils.GameInstance;
import me.shedaniel.rei.api.common.display.Display;
import me.shedaniel.rei.api.common.display.SimpleDisplaySerializer;
import me.shedaniel.rei.api.common.entry.EntryIngredient;
import me.shedaniel.rei.api.common.util.EntryIngredients;
import me.shedaniel.rei.impl.common.InternalRegistryAccess;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
Expand All @@ -38,16 +37,12 @@

import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/**
* A basic implementation of a display, consisting of a list of inputs, a list of outputs
* and a possible display location.
*/
public abstract class BasicDisplay implements Display {
protected static final Supplier<RegistryAccess> REGISTRY_ACCESS =
EnvExecutor.getEnvSpecific(() -> () -> () -> GameInstance.getClient().player.level().registryAccess(),
() -> () -> () -> GameInstance.getServer().registryAccess());
protected List<EntryIngredient> inputs;
protected List<EntryIngredient> outputs;
protected Optional<ResourceLocation> location;
Expand All @@ -64,7 +59,7 @@ public BasicDisplay(List<EntryIngredient> inputs, List<EntryIngredient> outputs,

@ApiStatus.Experimental
public static RegistryAccess registryAccess() {
return REGISTRY_ACCESS.get();
return InternalRegistryAccess.getInstance().get();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* This file is licensed under the MIT License, part of Roughly Enough Items.
* Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 shedaniel
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package me.shedaniel.rei.impl.common;

import dev.architectury.platform.Platform;
import dev.architectury.utils.Env;
import dev.architectury.utils.GameInstance;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import org.jetbrains.annotations.ApiStatus;

import java.lang.ref.WeakReference;
import java.util.function.Supplier;

@ApiStatus.Internal
public final class InternalRegistryAccess implements Supplier<RegistryAccess> {
private static final InternalRegistryAccess INSTANCE = new InternalRegistryAccess();
private WeakReference<RegistryAccess> registryAccess;
private boolean warned;

public static InternalRegistryAccess getInstance() {
return INSTANCE;
}

@Override
public RegistryAccess get() {
RegistryAccess access = this.registryAccess == null ? null : this.registryAccess.get();
if (access != null) {
return access;
}

if (Platform.getEnvironment() == Env.CLIENT) {
access = getFromClient();
} else if (GameInstance.getServer() != null) {
access = GameInstance.getServer().registryAccess();
}

if (access == null && !this.warned) {
this.warned = true;

new NullPointerException("Cannot get registry access!").printStackTrace();
InternalLogger.getInstance().warn("Cannot get registry access!");
return RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
}

return access;
}

@Environment(EnvType.CLIENT)
private static RegistryAccess getFromClient() {
if (Minecraft.getInstance().level != null) {
return Minecraft.getInstance().level.registryAccess();
} else if (Minecraft.getInstance().getConnection() != null) {
return Minecraft.getInstance().getConnection().registryAccess();
} else if (Minecraft.getInstance().gameMode != null) {
// Sometimes the packet is sent way too fast and is between the connection and the level, better safe than sorry
return Minecraft.getInstance().gameMode.connection.registryAccess();
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,8 @@ public class DefaultPlugin implements BuiltinPlugin, REIServerPlugin {
@Override
public void registerItemComparators(ItemComparatorRegistry registry) {
Function<ItemStack, ItemEnchantments> enchantmentTag = stack -> {
if (!stack.has(DataComponents.ENCHANTMENTS)) {
if (stack.has(DataComponents.STORED_ENCHANTMENTS)) {
return stack.get(DataComponents.STORED_ENCHANTMENTS);
}
return null;
if (stack.has(DataComponents.STORED_ENCHANTMENTS)) {
return stack.get(DataComponents.STORED_ENCHANTMENTS);
}
return stack.get(DataComponents.ENCHANTMENTS);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import me.shedaniel.rei.impl.common.InternalLogger;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.flag.FeatureFlagSet;
Expand All @@ -42,7 +41,7 @@ public class CreativeModeTabCollectorImpl {
public static Map<CreativeModeTab, Collection<ItemStack>> collectTabs() {
Map<CreativeModeTab, Collection<ItemStack>> map = new LinkedHashMap<>();
FeatureFlagSet featureFlags = FeatureFlags.REGISTRY.allFlags();
CreativeModeTab.ItemDisplayParameters parameters = new CreativeModeTab.ItemDisplayParameters(featureFlags, true, Objects.requireNonNullElseGet(BasicDisplay.registryAccess(), () -> RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)));
CreativeModeTab.ItemDisplayParameters parameters = new CreativeModeTab.ItemDisplayParameters(featureFlags, true, BasicDisplay.registryAccess());

for (CreativeModeTab tab : CreativeModeTabs.allTabs()) {
if (tab.getType() != CreativeModeTab.Type.HOTBAR && tab.getType() != CreativeModeTab.Type.INVENTORY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import me.shedaniel.rei.RoughlyEnoughItemsCoreClient;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.protocol.common.ClientboundUpdateTagsPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
import net.minecraft.world.item.crafting.RecipeManager;
Expand All @@ -36,12 +37,14 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPacketListener.class)
public class MixinClientPacketListener {
public abstract class MixinClientPacketListener {
@Shadow @Final private RecipeManager recipeManager;

@Shadow public abstract RegistryAccess.Frozen registryAccess();

@Inject(method = "handleUpdateRecipes", at = @At("HEAD"))
private void handleUpdateRecipes(ClientboundUpdateRecipesPacket clientboundUpdateRecipesPacket, CallbackInfo ci) {
RoughlyEnoughItemsCoreClient.PRE_UPDATE_RECIPES.invoker().update(recipeManager);
RoughlyEnoughItemsCoreClient.PRE_UPDATE_RECIPES.invoker().accept(recipeManager, registryAccess());
}

@Inject(method = "handleUpdateTags", at = @At("HEAD"))
Expand Down
1 change: 1 addition & 0 deletions fabric/src/main/resources/roughlyenoughitems.accessWidener
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ accessible field net/minecraft/world/item/crafting/SmithingTrimRecipe base Lnet/
accessible field net/minecraft/world/item/crafting/SmithingTrimRecipe addition Lnet/minecraft/world/item/crafting/Ingredient;
accessible field net/minecraft/world/item/CreativeModeTab displayItemsGenerator Lnet/minecraft/world/item/CreativeModeTab$DisplayItemsGenerator;
accessible class net/minecraft/world/item/CreativeModeTab$ItemDisplayBuilder
accessible field net/minecraft/client/multiplayer/MultiPlayerGameMode connection Lnet/minecraft/client/multiplayer/ClientPacketListener;
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.ModList;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.fml.loading.moddiscovery.ModAnnotation;
import net.neoforged.fml.loading.modscan.ModAnnotation;
import net.neoforged.neoforgespi.language.IModInfo;
import net.neoforged.neoforgespi.language.ModFileScanData;
import org.apache.commons.lang3.tuple.ImmutableTriple;
Expand Down Expand Up @@ -68,13 +68,13 @@ public static <T> void scanAnnotation(Type annotationType, Predicate<Class<T>> p
if (value instanceof Dist[]) {
enabled = Arrays.asList((Dist[]) value).contains(FMLEnvironment.dist);
} else if (value instanceof ModAnnotation.EnumHolder) {
enabled = Objects.equals(((ModAnnotation.EnumHolder) value).getValue(), FMLEnvironment.dist.name());
enabled = Objects.equals(((ModAnnotation.EnumHolder) value).value(), FMLEnvironment.dist.name());
} else if (value instanceof List) {
List<ModAnnotation.EnumHolder> holders = ((List<?>) value).stream().filter(o -> o instanceof ModAnnotation.EnumHolder)
.map(o -> (ModAnnotation.EnumHolder) o).toList();
if (!holders.isEmpty()) {
enabled = holders.stream()
.anyMatch(o -> Objects.equals(o.getValue(), FMLEnvironment.dist.name()));
.anyMatch(o -> Objects.equals(o.value(), FMLEnvironment.dist.name()));
} else {
enabled = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

import me.shedaniel.rei.api.common.display.basic.BasicDisplay;
import me.shedaniel.rei.impl.common.InternalLogger;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.flag.FeatureFlagSet;
Expand All @@ -38,13 +37,12 @@
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

public class CreativeModeTabCollectorImpl {
public static Map<CreativeModeTab, Collection<ItemStack>> collectTabs() {
Map<CreativeModeTab, Collection<ItemStack>> map = new LinkedHashMap<>();
FeatureFlagSet featureFlags = FeatureFlags.REGISTRY.allFlags();
CreativeModeTab.ItemDisplayParameters parameters = new CreativeModeTab.ItemDisplayParameters(featureFlags, true, Objects.requireNonNullElseGet(BasicDisplay.registryAccess(), () -> RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)));
CreativeModeTab.ItemDisplayParameters parameters = new CreativeModeTab.ItemDisplayParameters(featureFlags, true, BasicDisplay.registryAccess());

for (CreativeModeTab tab : CreativeModeTabs.allTabs()) {
if (tab.getType() != CreativeModeTab.Type.HOTBAR && tab.getType() != CreativeModeTab.Type.INVENTORY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import me.shedaniel.rei.RoughlyEnoughItemsCoreClient;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.protocol.common.ClientboundUpdateTagsPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
import net.minecraft.world.item.crafting.RecipeManager;
Expand All @@ -36,12 +37,14 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPacketListener.class)
public class MixinClientPacketListener {
public abstract class MixinClientPacketListener {
@Shadow @Final private RecipeManager recipeManager;

@Shadow public abstract RegistryAccess.Frozen registryAccess();

@Inject(method = "handleUpdateRecipes", at = @At("HEAD"))
private void handleUpdateRecipes(ClientboundUpdateRecipesPacket clientboundUpdateRecipesPacket, CallbackInfo ci) {
RoughlyEnoughItemsCoreClient.PRE_UPDATE_RECIPES.invoker().update(recipeManager);
RoughlyEnoughItemsCoreClient.PRE_UPDATE_RECIPES.invoker().accept(recipeManager, registryAccess());
}

@Inject(method = "handleUpdateTags", at = @At("HEAD"))
Expand Down
1 change: 1 addition & 0 deletions neoforge/src/main/resources/META-INF/accesstransformer.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ public-f net.minecraft.client.gui.font.CodepointMap blockMap # blockMap
public-f net.minecraft.client.gui.font.CodepointMap blockConstructor # blockConstructor
public net.minecraft.world.item.CreativeModeTab displayItemsGenerator # displayItemsGenerator
public net.minecraft.world.item.CreativeModeTab$ItemDisplayBuilder
public net.minecraft.client.multiplayer.MultiPlayerGameMode connection # connection
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
import net.minecraft.client.gui.screens.recipebook.GhostRecipe;
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.models.blockstates.PropertyDispatch;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
Expand All @@ -112,6 +113,7 @@
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeManager;
import org.apache.commons.lang3.mutable.MutableLong;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
Expand All @@ -120,15 +122,12 @@
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.*;
import java.util.stream.Stream;

@Environment(EnvType.CLIENT)
public class RoughlyEnoughItemsCoreClient {
public static final Event<ClientRecipeUpdateEvent> PRE_UPDATE_RECIPES = EventFactory.createLoop();
public static final Event<BiConsumer<RecipeManager, RegistryAccess>> PRE_UPDATE_RECIPES = EventFactory.createLoop();
public static final Event<Runnable> POST_UPDATE_TAGS = EventFactory.createLoop();
public static boolean isLeftMousePressed = false;
private static final ExecutorService RELOAD_PLUGINS = Executors.newSingleThreadScheduledExecutor(task -> {
Expand Down Expand Up @@ -317,9 +316,9 @@ private void registerEvents() {
final ResourceLocation recipeButtonTex = new ResourceLocation("textures/gui/recipe_button.png");
MutableLong startReload = new MutableLong(-1);
MutableLong endReload = new MutableLong(-1);
PRE_UPDATE_RECIPES.register(recipeManager -> {
PRE_UPDATE_RECIPES.register((recipeManager, registryAccess) -> {
RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.clear();
reloadPlugins(startReload, ReloadStage.START);
reloadPlugins(startReload, ReloadStage.START, registryAccess);
});
ClientRecipeUpdateEvent.EVENT.register(recipeManager -> {
reloadPlugins(endReload, ReloadStage.END);
Expand Down Expand Up @@ -469,6 +468,11 @@ public static boolean resetFocused(Screen screen) {

@ApiStatus.Internal
public static void reloadPlugins(MutableLong lastReload, @Nullable ReloadStage start) {
reloadPlugins(lastReload, start, null);
}

@ApiStatus.Internal
public static void reloadPlugins(MutableLong lastReload, @Nullable ReloadStage start, @Nullable RegistryAccess registryAccess) {
if (Minecraft.getInstance().level == null) return;
if (lastReload != null) {
if (lastReload.getValue() > 0 && System.currentTimeMillis() - lastReload.getValue() <= 5000) {
Expand Down

0 comments on commit 90af6e0

Please sign in to comment.