diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-08-27 05:26:06 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-08-27 05:26:31 +0800 |
| commit | 113fe8f692f4f9bb113d28f6a1b3375bd8f0eec8 (patch) | |
| tree | da371c2c28ec95167aea4ebc91a6ff4a9f5f59b3 | |
| parent | a4776b33fd86731249cf9b02c2ea6fff1bce9350 (diff) | |
| download | RoughlyEnoughItems-113fe8f692f4f9bb113d28f6a1b3375bd8f0eec8.tar.gz RoughlyEnoughItems-113fe8f692f4f9bb113d28f6a1b3375bd8f0eec8.tar.bz2 RoughlyEnoughItems-113fe8f692f4f9bb113d28f6a1b3375bd8f0eec8.zip | |
Add hints for if REI does not initialize properly
51 files changed, 679 insertions, 95 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java index a5928679c..de413d6ab 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java @@ -63,7 +63,7 @@ public interface EntryTypeRegistry extends Reloadable<REIPlugin<?>> { } /** - * Registers a entry type, with its entry definition. + * Registers an entry type, with its entry definition. * * @param id the identifier of the entry type * @param definition the definition of the entry diff --git a/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java b/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java index 48cce495e..0a3a8e185 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java @@ -34,15 +34,29 @@ public interface ParentReloadable<P extends REIPlugin<?>> extends Reloadable<P> @Override default void startReload() { - for (Reloadable<P> reloadable : getReloadables()) { - reloadable.startReload(); + for (ReloadStage stage : ReloadStage.values()) { + startReload(stage); } } @Override default void endReload() { + for (ReloadStage stage : ReloadStage.values()) { + endReload(stage); + } + } + + @Override + default void startReload(ReloadStage stage) { + for (Reloadable<P> reloadable : getReloadables()) { + reloadable.startReload(stage); + } + } + + @Override + default void endReload(ReloadStage stage) { for (Reloadable<P> reloadable : getReloadables()) { - reloadable.endReload(); + reloadable.endReload(stage); } } } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/registry/ReloadStage.java b/api/src/main/java/me/shedaniel/rei/api/common/registry/ReloadStage.java new file mode 100644 index 000000000..cb1deff3c --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/common/registry/ReloadStage.java @@ -0,0 +1,29 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021 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.api.common.registry; + +public enum ReloadStage { + START, + END, +} diff --git a/api/src/main/java/me/shedaniel/rei/api/common/registry/Reloadable.java b/api/src/main/java/me/shedaniel/rei/api/common/registry/Reloadable.java index d472ad72d..67b7174a5 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/registry/Reloadable.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/registry/Reloadable.java @@ -27,10 +27,26 @@ import me.shedaniel.rei.api.common.plugins.REIPlugin; @FunctionalInterface public interface Reloadable<P extends REIPlugin<?>> { + default ReloadStage getStage() { + return ReloadStage.END; + } + void startReload(); + default void startReload(ReloadStage stage) { + if (stage == getStage()) { + startReload(); + } + } + default void endReload() {} + default void endReload(ReloadStage stage) { + if (stage == getStage()) { + endReload(); + } + } + /** * Accepts a {@link REIPlugin} * @@ -38,6 +54,12 @@ public interface Reloadable<P extends REIPlugin<?>> { */ default void acceptPlugin(P plugin) {} + default void acceptPlugin(P plugin, ReloadStage stage) { + if (stage == getStage()) { + acceptPlugin(plugin); + } + } + /** * Returns whether {@link Reloadable#acceptPlugin(REIPlugin)} should be done in parallel. * diff --git a/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinClientPacketListener.java b/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinClientPacketListener.java new file mode 100644 index 000000000..d23118c3a --- /dev/null +++ b/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinClientPacketListener.java @@ -0,0 +1,45 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021 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.mixin.fabric; + +import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket; +import net.minecraft.world.item.crafting.RecipeManager; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientPacketListener.class) +public class MixinClientPacketListener { + @Shadow @Final private RecipeManager recipeManager; + + @Inject(method = "handleUpdateRecipes", at = @At("HEAD")) + private void handleUpdateRecipes(ClientboundUpdateRecipesPacket clientboundUpdateRecipesPacket, CallbackInfo ci) { + RoughlyEnoughItemsCoreClient.PRE_UPDATE_RECIPES.invoker().update(recipeManager); + } +}
\ No newline at end of file diff --git a/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinPacketEncoder.java b/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinPacketEncoder.java new file mode 100644 index 000000000..30e2f1a6d --- /dev/null +++ b/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinPacketEncoder.java @@ -0,0 +1,58 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021 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.mixin.fabric; + +import dev.architectury.utils.GameInstance; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.ChatFormatting; +import net.minecraft.Util; +import net.minecraft.network.PacketEncoder; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PacketEncoder.class) +public class MixinPacketEncoder { + @Inject(method = "encode", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/Packet;isSkippable()Z")) + private void failedToEncode(ChannelHandlerContext channelHandlerContext, Packet<?> packet, ByteBuf byteBuf, CallbackInfo ci) { + if (packet instanceof ClientboundUpdateRecipesPacket) { + MinecraftServer server = GameInstance.getServer(); + String issue = "REI: Server failed to synchronize recipe data with the client! " + + "Please check the server console log for errors, this breaks REI and vanilla recipe books!"; + server.execute(() -> { + for (ServerPlayer player : server.getPlayerList().getPlayers()) { + player.sendMessage(new TextComponent(issue).withStyle(ChatFormatting.RED), Util.NIL_UUID); + } + }); + System.out.println(issue); + } + } +} diff --git a/fabric/src/main/resources/rei.mixins.json b/fabric/src/main/resources/rei.mixins.json index b7d1e7c81..7897b4049 100644 --- a/fabric/src/main/resources/rei.mixins.json +++ b/fabric/src/main/resources/rei.mixins.json @@ -3,9 +3,11 @@ "package": "me.shedaniel.rei.mixin.fabric", "compatibilityLevel": "JAVA_8", "client": [ + "MixinClientPacketListener", "MixinScreen" ], "mixins": [ + "MixinPacketEncoder" ], "injectors": { "maxShiftBy": 5, diff --git a/gradle.properties b/gradle.properties index dacf56056..8570b003f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ forge_version=37.0.18 fabricloader_version=0.11.6 cloth_config_version=5.0.37 modmenu_version=2.0.2 -fabric_api=0.35.2+1.17 +fabric_api=0.39.2+1.17 architectury_version=2.3.22 api_exculde= #api_include=me.shedaniel.cloth:cloth-events,me.shedaniel.cloth:config-2,me.sargunvohra.mcmods:autoconfig1u,org.jetbrains:annotations,net.fabricmc.fabric-api:fabric diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java index fe495d876..d6f6ac5a1 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java @@ -27,6 +27,7 @@ import dev.architectury.platform.Platform; import dev.architectury.registry.ReloadListenerRegistry; import dev.architectury.utils.Env; import dev.architectury.utils.EnvExecutor; +import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.annotation.Nullable; import me.shedaniel.rei.api.common.entry.comparison.FluidComparatorRegistry; import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry; import me.shedaniel.rei.api.common.entry.type.EntryType; @@ -36,6 +37,7 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.plugins.PluginView; import me.shedaniel.rei.api.common.plugins.REIPlugin; import me.shedaniel.rei.api.common.plugins.REIServerPlugin; +import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry; import me.shedaniel.rei.impl.Internals; import me.shedaniel.rei.impl.common.category.CategoryIdentifierImpl; @@ -112,10 +114,16 @@ public class RoughlyEnoughItemsCore { new MenuInfoRegistryImpl()), "serverPluginManager"); } - public static void _reloadPlugins() { + public static void _reloadPlugins(@Nullable ReloadStage stage) { + if (stage == null) { + for (ReloadStage reloadStage : ReloadStage.values()) { + _reloadPlugins(reloadStage); + } + return; + } try { for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { - instance.startReload(); + instance.startReload(stage); } } catch (Throwable throwable) { throwable.printStackTrace(); @@ -130,7 +138,7 @@ public class RoughlyEnoughItemsCore { if (Platform.getEnvironment() == Env.SERVER) { MutableLong lastReload = new MutableLong(-1); ReloadListenerRegistry.register(PackType.SERVER_DATA, (preparationBarrier, resourceManager, profilerFiller, profilerFiller2, executor, executor2) -> { - return preparationBarrier.wait(Unit.INSTANCE).thenRunAsync(RoughlyEnoughItemsCore::_reloadPlugins, executor2); + return preparationBarrier.wait(Unit.INSTANCE).thenRunAsync(() -> RoughlyEnoughItemsCore._reloadPlugins(null), executor2); }); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index 2f09e6a22..2b3a9aef4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -25,11 +25,14 @@ package me.shedaniel.rei; import com.google.common.collect.Lists; import com.mojang.serialization.DataResult; +import dev.architectury.event.Event; +import dev.architectury.event.EventFactory; import dev.architectury.event.EventResult; import dev.architectury.event.events.client.ClientGuiEvent; import dev.architectury.event.events.client.ClientRecipeUpdateEvent; import dev.architectury.event.events.client.ClientScreenInputEvent; import dev.architectury.networking.NetworkManager; +import dev.architectury.platform.Platform; import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; @@ -48,6 +51,7 @@ import me.shedaniel.rei.api.client.registry.screen.OverlayDecider; import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.plugins.PluginView; +import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.util.EntryStacks; import me.shedaniel.rei.impl.ClientInternals; import me.shedaniel.rei.impl.client.REIRuntimeImpl; @@ -108,6 +112,7 @@ import java.util.stream.Stream; @Environment(EnvType.CLIENT) public class RoughlyEnoughItemsCoreClient { + public static final Event<ClientRecipeUpdateEvent> PRE_UPDATE_RECIPES = EventFactory.createLoop(); @ApiStatus.Experimental public static boolean isLeftMousePressed = false; private static final ExecutorService RELOAD_PLUGINS = Executors.newSingleThreadScheduledExecutor(task -> { @@ -262,8 +267,10 @@ public class RoughlyEnoughItemsCoreClient { private void registerEvents() { Minecraft client = Minecraft.getInstance(); final ResourceLocation recipeButtonTex = new ResourceLocation("textures/gui/recipe_button.png"); - MutableLong lastReload = new MutableLong(-1); - ClientRecipeUpdateEvent.EVENT.register(recipeManager -> reloadPlugins(lastReload)); + MutableLong startReload = new MutableLong(-1); + MutableLong endReload = new MutableLong(-1); + PRE_UPDATE_RECIPES.register(recipeManager -> reloadPlugins(endReload, ReloadStage.START)); + ClientRecipeUpdateEvent.EVENT.register(recipeManager -> reloadPlugins(endReload, Platform.isFabric() ? ReloadStage.END : null)); ClientGuiEvent.INIT_POST.register((screen, access) -> { REIRuntimeImpl.getInstance().setPreviousScreen(screen); if (ConfigObject.getInstance().doesDisableRecipeBook() && screen instanceof AbstractContainerScreen) { @@ -359,7 +366,7 @@ public class RoughlyEnoughItemsCoreClient { } @ApiStatus.Internal - public static void reloadPlugins(MutableLong lastReload) { + public static void reloadPlugins(MutableLong lastReload, @Nullable ReloadStage start) { if (lastReload != null) { if (lastReload.getValue() > 0 && System.currentTimeMillis() - lastReload.getValue() <= 5000) { RoughlyEnoughItemsCore.LOGGER.warn("Suppressing Reload Plugins!"); @@ -368,9 +375,9 @@ public class RoughlyEnoughItemsCoreClient { lastReload.setValue(System.currentTimeMillis()); } if (ConfigObject.getInstance().doesRegisterRecipesInAnotherThread()) { - CompletableFuture.runAsync(RoughlyEnoughItemsCore::_reloadPlugins, RELOAD_PLUGINS); + CompletableFuture.runAsync(() -> RoughlyEnoughItemsCore._reloadPlugins(start), RELOAD_PLUGINS); } else { - RoughlyEnoughItemsCore._reloadPlugins(); + RoughlyEnoughItemsCore._reloadPlugins(start); } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java index 956bfd62a..07a94a0b3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java @@ -39,7 +39,9 @@ import me.shedaniel.rei.api.client.gui.widgets.TextField; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.overlay.ScreenOverlay; import me.shedaniel.rei.api.client.regis |
