From b10f1308f5359ce73a9f4b899cf9516c4ad5388f Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 19 Nov 2023 03:04:21 +0800 Subject: Support NeoForge --- .../me/shedaniel/rei/forge/AnnotationUtils.java | 119 +++++++++++ .../me/shedaniel/rei/forge/PluginDetectorImpl.java | 237 +++++++++++++++++++++ .../rei/forge/PrimitivePlatformAdapterImpl.java | 69 ++++++ .../java/me/shedaniel/rei/forge/REIPlugin.java | 38 ++++ .../me/shedaniel/rei/forge/REIPluginClient.java | 34 +++ .../me/shedaniel/rei/forge/REIPluginCommon.java | 34 +++ .../rei/forge/REIPluginDedicatedServer.java | 34 +++ .../me/shedaniel/rei/forge/REIPluginLoader.java | 38 ++++ .../shedaniel/rei/forge/REIPluginLoaderClient.java | 34 +++ .../shedaniel/rei/forge/REIPluginLoaderCommon.java | 34 +++ .../rei/forge/REIPluginLoaderDedicatedServer.java | 34 +++ .../rei/forge/RoughlyEnoughItemsForge.java | 45 ++++ .../rei/impl/client/CodepointMapWrapper.java | 92 ++++++++ .../client/forge/CreativeModeTabCollectorImpl.java | 67 ++++++ .../rei/impl/client/forge/ErrorDisplayerImpl.java | 55 +++++ .../gui/credits/forge/CreditsScreenImpl.java | 34 +++ .../client/gui/forge/ScreenOverlayImplForge.java | 76 +++++++ .../rei/mixin/forge/MixinClientPacketListener.java | 51 +++++ .../forge/MixinEffectRenderingInventoryScreen.java | 66 ++++++ .../me/shedaniel/rei/mixin/forge/MixinFontSet.java | 62 ++++++ .../rei/mixin/forge/MixinInputConstants.java | 52 +++++ .../rei/mixin/forge/MixinInputConstantsKey.java | 57 +++++ .../rei/mixin/forge/MixinPacketEncoder.java | 57 +++++ .../rei/mixin/forge/MixinRecipeToast.java | 47 ++++ .../shedaniel/rei/mixin/forge/MixinTagLoader.java | 134 ++++++++++++ .../shedaniel/rei/mixin/forge/MixinTagManager.java | 47 ++++ .../client/forge/DefaultClientPluginImpl.java | 88 ++++++++ .../crafting/forge/DefaultCraftingDisplayImpl.java | 40 ++++ .../rei/plugin/common/forge/DefaultPluginImpl.java | 61 ++++++ 29 files changed, 1836 insertions(+) create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/AnnotationUtils.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/PrimitivePlatformAdapterImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPlugin.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginClient.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginCommon.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginDedicatedServer.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoader.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderClient.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderCommon.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderDedicatedServer.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/forge/RoughlyEnoughItemsForge.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/impl/client/CodepointMapWrapper.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/CreativeModeTabCollectorImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/ErrorDisplayerImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/credits/forge/CreditsScreenImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplForge.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinClientPacketListener.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinEffectRenderingInventoryScreen.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinFontSet.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinInputConstants.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinInputConstantsKey.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinPacketEncoder.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinRecipeToast.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinTagLoader.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinTagManager.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/plugin/client/forge/DefaultClientPluginImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/forge/DefaultCraftingDisplayImpl.java create mode 100644 neoforge/src/main/java/me/shedaniel/rei/plugin/common/forge/DefaultPluginImpl.java (limited to 'neoforge/src/main/java') diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/AnnotationUtils.java b/neoforge/src/main/java/me/shedaniel/rei/forge/AnnotationUtils.java new file mode 100644 index 000000000..9a13e0cdc --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/AnnotationUtils.java @@ -0,0 +1,119 @@ +/* + * 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.forge; + +import com.google.common.collect.Lists; +import me.shedaniel.rei.impl.init.PrimitivePlatformAdapter; +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.neoforgespi.language.IModInfo; +import net.neoforged.neoforgespi.language.ModFileScanData; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Triple; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.util.TriConsumer; +import org.objectweb.asm.Type; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class AnnotationUtils { + public static final Logger LOGGER = LogManager.getFormatterLogger("REI"); + + public static void scanAnnotation(Class clazz, Predicate> predicate, TriConsumer, Supplier, Class> consumer) { + scanAnnotation(Type.getType(clazz), predicate, consumer); + } + + public static void scanAnnotation(Type annotationType, Predicate> predicate, TriConsumer, Supplier, Class> consumer) { + List, Supplier, Class>> instances = Lists.newArrayList(); + for (ModFileScanData data : ModList.get().getAllScanData()) { + List modIds = data.getIModInfoData().stream() + .flatMap(info -> info.getMods().stream()) + .map(IModInfo::getModId) + .collect(Collectors.toList()); + out: + for (ModFileScanData.AnnotationData annotation : data.getAnnotations()) { + if (annotationType.equals(annotation.annotationType())) { + Object value = annotation.annotationData().get("value"); + boolean enabled; + + 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()); + } else if (value instanceof List) { + List 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())); + } else { + enabled = true; + } + } else { + enabled = true; + } + + if (!enabled) continue; + + try { + Class clazz = (Class) Class.forName(annotation.memberName()); + if (predicate.test(clazz)) { + instances.add(new ImmutableTriple<>(modIds, () -> { + try { + return clazz.getDeclaredConstructor().newInstance(); + } catch (Throwable throwable) { + LOGGER.error("Failed to load plugin: " + annotation.memberName(), throwable); + return null; + } + }, clazz)); + } + } catch (Throwable throwable) { + Throwable t = throwable; + while (t != null) { + if (t.getMessage() != null && t.getMessage().contains("invalid dist DEDICATED_SERVER") && !PrimitivePlatformAdapter.get().isClient()) { + LOGGER.warn("Plugin " + annotation.memberName() + " is attempting to load on the server, but is not compatible with the server. " + + "The mod should declare the environments it is compatible with in the @" + annotationType.getClassName() + " annotation."); + continue out; + } + t = t.getCause(); + } + LOGGER.error("Failed to load plugin: " + annotation.memberName(), throwable); + } + } + } + } + + for (Triple, Supplier, Class> pair : instances) { + consumer.accept(pair.getLeft(), pair.getMiddle(), pair.getRight()); + } + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java b/neoforge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java new file mode 100644 index 000000000..f96f0b409 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java @@ -0,0 +1,237 @@ +/* + * 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.forge; + +import com.google.common.base.Suppliers; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.common.plugins.PluginManager; +import me.shedaniel.rei.api.common.plugins.PluginView; +import me.shedaniel.rei.api.common.plugins.REIPluginProvider; +import me.shedaniel.rei.api.common.plugins.REIServerPlugin; +import me.shedaniel.rei.impl.init.PluginDetector; +import me.shedaniel.rei.plugin.client.forge.DefaultClientPluginImpl; +import me.shedaniel.rei.plugin.client.runtime.DefaultClientRuntimePlugin; +import me.shedaniel.rei.plugin.client.runtime.HideIngredientsFromTagsPlugin; +import me.shedaniel.rei.plugin.common.forge.DefaultPluginImpl; +import me.shedaniel.rei.plugin.common.runtime.DefaultRuntimePlugin; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext; +import net.neoforged.fml.loading.FMLEnvironment; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.Supplier; + +public class PluginDetectorImpl implements PluginDetector { + private static

> REIPluginProvider

wrapPlugin(List modId, REIPluginProvider

plugin) { + return new REIPluginProvider

() { + final String nameSuffix = " [" + String.join(", ", modId) + "]"; + + @Override + public Collection

provide() { + return plugin.provide(); + } + + @Override + public Class

getPluginProviderClass() { + return plugin.getPluginProviderClass(); + } + + @Override + public String getPluginProviderName() { + return plugin.getPluginProviderName() + nameSuffix; + } + }; + } + + private static final Supplier>, List>>> loaderProvided = + Suppliers.memoize(() -> getPluginsLoader(REIPluginLoader.class)); + private static final Supplier>, List>>> loaderProvidedCommon = + Suppliers.memoize(() -> getPluginsLoader(REIPluginLoaderCommon.class)); + private static final Supplier>, List>>> loaderProvidedDist; + + static { + Supplier>, List>>> dist; + if (FMLEnvironment.dist == Dist.CLIENT) { + dist = Suppliers.memoize(() -> getPluginsLoader(REIPluginLoaderClient.class)); + } else if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) { + dist = Suppliers.memoize(() -> getPluginsLoader(REIPluginLoaderDedicatedServer.class)); + } else throw new IllegalStateException("Unknown environment: " + FMLEnvironment.dist); + loaderProvidedDist = dist; + } + + @NotNull + private static > List, List>> getPluginsLoader(Class annotation) { + List, List>> list = new ArrayList<>(); + AnnotationUtils.>scanAnnotation(annotation, REIPluginProvider.class::isAssignableFrom, (modId, provider, clazz) -> { + try { + list.add(new AbstractMap.SimpleEntry<>(provider.get(), modId)); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + }); + return list; + } + + @Override + public void detectServerPlugins() { + PluginView.getServerInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new DefaultPluginImpl())); + PluginView.getServerInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new DefaultRuntimePlugin())); + + // Legacy Annotation + AnnotationUtils.scanAnnotation(REIPlugin.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Common plugins + AnnotationUtils.scanAnnotation(REIPluginCommon.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Dist plugins + if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) { + AnnotationUtils.scanAnnotation(REIPluginDedicatedServer.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + } else { + AnnotationUtils.scanAnnotation(REIPluginClient.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + } + + // Loaders + for (Map.Entry>, List> entry : loaderProvided.get()) { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIServerPlugin.class))); + } + for (Map.Entry>, List> entry : loaderProvidedCommon.get()) { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIServerPlugin.class))); + } + for (Map.Entry>, List> entry : loaderProvidedDist.get()) { + ((PluginView) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIServerPlugin.class))); + } + } + + @Override + public void detectCommonPlugins() { + // Legacy Annotation + AnnotationUtils.>scanAnnotation(REIPlugin.class, me.shedaniel.rei.api.common.plugins.REIPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Common plugins + AnnotationUtils.>scanAnnotation(REIPluginCommon.class, me.shedaniel.rei.api.common.plugins.REIPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Dist plugins + if (FMLEnvironment.dist == Dist.CLIENT) { + AnnotationUtils.scanAnnotation(REIPluginClient.class, me.shedaniel.rei.api.common.plugins.REIPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + } else if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) { + AnnotationUtils.scanAnnotation(REIPluginDedicatedServer.class, me.shedaniel.rei.api.common.plugins.REIPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + } + + // Loaders + for (Map.Entry>, List> entry : loaderProvided.get()) { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(entry.getValue(), entry.getKey())); + } + for (Map.Entry>, List> entry : loaderProvidedCommon.get()) { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(entry.getValue(), entry.getKey())); + } + for (Map.Entry>, List> entry : loaderProvidedDist.get()) { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(entry.getValue(), entry.getKey())); + } + } + + @OnlyIn(Dist.CLIENT) + @Override + public Supplier detectClientPlugins() { + return () -> () -> { + PluginView.getClientInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new DefaultClientPluginImpl())); + PluginView.getClientInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new DefaultClientRuntimePlugin())); + PluginView.getClientInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new HideIngredientsFromTagsPlugin())); + + // Legacy Annotation + AnnotationUtils.scanAnnotation(REIPlugin.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Common plugins + AnnotationUtils.scanAnnotation(REIPluginCommon.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Dist plugins + AnnotationUtils.scanAnnotation(REIPluginClient.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Loaders + for (Map.Entry>, List> entry : loaderProvided.get()) { + ((PluginView) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIClientPlugin.class))); + } + for (Map.Entry>, List> entry : loaderProvidedCommon.get()) { + ((PluginView) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIClientPlugin.class))); + } + for (Map.Entry>, List> entry : loaderProvidedDist.get()) { + ((PluginView) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIClientPlugin.class))); + } + }; + } + + private static

> REIPluginProvider

wrapAndFilter(REIPluginProvider provider, Class

clazz) { + return new REIPluginProvider<>() { + @Override + public Collection

provide() { + return new AbstractCollection<>() { + @Override + public Iterator

iterator() { + return Iterables.filter(provider.provide(), clazz).iterator(); + } + + @Override + public int size() { + return Iterators.size(iterator()); + } + }; + } + + @Override + public Class

getPluginProviderClass() { + return clazz; + } + + @Override + public String getPluginProviderName() { + return provider.getPluginProviderName(); + } + }; + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/PrimitivePlatformAdapterImpl.java b/neoforge/src/main/java/me/shedaniel/rei/forge/PrimitivePlatformAdapterImpl.java new file mode 100644 index 000000000..01491ecb5 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/PrimitivePlatformAdapterImpl.java @@ -0,0 +1,69 @@ +/* + * 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.forge; + +import me.shedaniel.rei.RoughlyEnoughItemsState; +import me.shedaniel.rei.impl.init.PrimitivePlatformAdapter; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.fml.loading.FMLLoader; +import org.apache.maven.artifact.versioning.ComparableVersion; + +public class PrimitivePlatformAdapterImpl implements PrimitivePlatformAdapter { + @Override + public boolean isClient() { + return FMLEnvironment.dist == Dist.CLIENT; + } + + @Override + public void checkMods() { + if (ModList.get().isLoaded("moreoverlays")) { + RoughlyEnoughItemsState.error("REI is not compatible with MoreOverlays, and actually contains Builtin Inventory Highlighting, other features can be installed via different mods!"); + } + } + + @Override + public boolean isDev() { + return !FMLLoader.isProduction(); + } + + @Override + public String getMinecraftVersion() { + return ModList.get().getModContainerById("minecraft").get().getModInfo().getVersion().toString(); + } + + @Override + public int compareVersions(String version1, String version2) { + ComparableVersion v1 = new ComparableVersion(version1); + ComparableVersion v2 = new ComparableVersion(version2); + + try { + return v1.compareTo(v2); + } catch (IllegalStateException e) { + new IllegalStateException("Failed to compare versions: " + version1 + " and " + version2, e).printStackTrace(); + return 0; + } + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPlugin.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPlugin.java new file mode 100644 index 000000000..c89748640 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPlugin.java @@ -0,0 +1,38 @@ +/* + * 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.forge; + +import net.neoforged.api.distmarker.Dist; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Deprecated(forRemoval = true) +public @interface REIPlugin { + Dist[] value() default {Dist.CLIENT, Dist.DEDICATED_SERVER}; +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginClient.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginClient.java new file mode 100644 index 000000000..0ae0ad4a4 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginClient.java @@ -0,0 +1,34 @@ +/* + * 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.forge; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface REIPluginClient { +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginCommon.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginCommon.java new file mode 100644 index 000000000..7e60faad4 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginCommon.java @@ -0,0 +1,34 @@ +/* + * 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.forge; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface REIPluginCommon { +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginDedicatedServer.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginDedicatedServer.java new file mode 100644 index 000000000..e984ba93c --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginDedicatedServer.java @@ -0,0 +1,34 @@ +/* + * 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.forge; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface REIPluginDedicatedServer { +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoader.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoader.java new file mode 100644 index 000000000..e338c4419 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoader.java @@ -0,0 +1,38 @@ +/* + * 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.forge; + +import net.neoforged.api.distmarker.Dist; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Deprecated(forRemoval = true) +public @interface REIPluginLoader { + Dist[] value() default {Dist.CLIENT, Dist.DEDICATED_SERVER}; +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderClient.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderClient.java new file mode 100644 index 000000000..267d175c4 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderClient.java @@ -0,0 +1,34 @@ +/* + * 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.forge; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface REIPluginLoaderClient { +} \ No newline at end of file diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderCommon.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderCommon.java new file mode 100644 index 000000000..230d19524 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderCommon.java @@ -0,0 +1,34 @@ +/* + * 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.forge; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface REIPluginLoaderCommon { +} \ No newline at end of file diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderDedicatedServer.java b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderDedicatedServer.java new file mode 100644 index 000000000..eee703048 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/REIPluginLoaderDedicatedServer.java @@ -0,0 +1,34 @@ +/* + * 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.forge; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface REIPluginLoaderDedicatedServer { +} \ No newline at end of file diff --git a/neoforge/src/main/java/me/shedaniel/rei/forge/RoughlyEnoughItemsForge.java b/neoforge/src/main/java/me/shedaniel/rei/forge/RoughlyEnoughItemsForge.java new file mode 100644 index 000000000..ae7c88c96 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/forge/RoughlyEnoughItemsForge.java @@ -0,0 +1,45 @@ +/* + * 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.forge; + +import me.shedaniel.rei.impl.init.RoughlyEnoughItemsInitializer; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.DistExecutor; +import net.neoforged.fml.IExtensionPoint; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.data.loading.DatagenModLoader; +import org.jetbrains.annotations.ApiStatus; + +@Mod("roughlyenoughitems") +@ApiStatus.Internal +public class RoughlyEnoughItemsForge { + public RoughlyEnoughItemsForge() { + ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> "", (a, b) -> true)); + if (!DatagenModLoader.isRunningDataGen()) { + RoughlyEnoughItemsInitializer.onInitialize(); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> RoughlyEnoughItemsInitializer::onInitializeClient); + } + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/impl/client/CodepointMapWrapper.java b/neoforge/src/main/java/me/shedaniel/rei/impl/client/CodepointMapWrapper.java new file mode 100644 index 000000000..fcc396b9c --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/impl/client/CodepointMapWrapper.java @@ -0,0 +1,92 @@ +/* + * 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.client; + +import it.unimi.dsi.fastutil.ints.IntSet; +import net.minecraft.client.gui.font.CodepointMap; +import org.jetbrains.annotations.Nullable; + +import java.util.function.IntFunction; + +public class CodepointMapWrapper extends CodepointMap { + private final CodepointMap delegate; + protected transient IntSet keys; + + public CodepointMapWrapper(CodepointMap delegate) { + super(delegate.blockConstructor, i -> delegate.blockMap); + this.empty = delegate.empty; + this.blockMap = delegate.blockMap; + this.delegate = delegate; + } + + @Override + public void clear() { + synchronized (this) { + delegate.clear(); + } + } + + @Nullable + @Override + public T put(int i, T object) { + synchronized (this) { + return delegate.put(i, object); + } + } + + @Nullable + @Override + public T get(int i) { + synchronized (this) { + return delegate.get(i); + } + } + + @Override + public T computeIfAbsent(int i, IntFunction intFunction) { + synchronized (this) { + return delegate.computeIfAbsent(i, intFunction); + } + } + + @Nullable + @Override + public T remove(int i) { + synchronized (this) { + return delegate.remove(i); + } + } + + @Override + public void forEach(Output arg) { + synchronized (this) { + delegate.forEach(arg); + } + } + + @Override + public IntSet keySet() { + return delegate.keySet(); + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/CreativeModeTabCollectorImpl.java b/neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/CreativeModeTabCollectorImpl.java new file mode 100644 index 000000000..752631dcb --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/CreativeModeTabCollectorImpl.java @@ -0,0 +1,67 @@ +/* + * 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.client.forge; + +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; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.client.ClientHooks; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +public class CreativeModeTabCollectorImpl { + public static Map> collectTabs() { + Map> map = new LinkedHashMap<>(); + FeatureFlagSet featureFlags = FeatureFlags.REGISTRY.allFlags(); + CreativeModeTab.ItemDisplayParameters parameters = new CreativeModeTab.ItemDisplayParameters(featureFlags, true, RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)); + + for (CreativeModeTab tab : CreativeModeTabs.allTabs()) { + if (tab.getType() != CreativeModeTab.Type.HOTBAR && tab.getType() != CreativeModeTab.Type.INVENTORY) { + try { + CreativeModeTab.ItemDisplayBuilder builder = new CreativeModeTab.ItemDisplayBuilder(tab, featureFlags); + ResourceKey resourceKey = BuiltInRegistries.CREATIVE_MODE_TAB + .getResourceKey(tab) + .orElseThrow(() -> new IllegalStateException("Unregistered creative tab: " + tab)); + ClientHooks.onCreativeModeTabBuildContents(tab, resourceKey, tab.displayItemsGenerator, parameters, (stack, visibility) -> { + if (visibility == CreativeModeTab.TabVisibility.SEARCH_TAB_ONLY) return; + builder.accept(stack, visibility); + }); + map.put(tab, builder.tabContents); + } catch (Throwable throwable) { + InternalLogger.getInstance().error("Failed to collect creative tab: " + tab, throwable); + } + } + } + + return map; + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/ErrorDisplayerImpl.java b/neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/ErrorDisplayerImpl.java new file mode 100644 index 000000000..53d92272e --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/impl/client/forge/ErrorDisplayerImpl.java @@ -0,0 +1,55 @@ +/* + * 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.client.forge; + +import me.shedaniel.rei.impl.client.ErrorDisplayer; +import net.minecraft.client.gui.screens.Screen; +import net.neoforged.neoforge.client.event.ScreenEvent; +import net.neoforged.neoforge.common.NeoForge; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.UnaryOperator; + +public class ErrorDisplayerImpl implements ErrorDisplayer.ErrorGuiInitializer { + private static final List> CONSUMERS = new ArrayList<>(); + + static { + NeoForge.EVENT_BUS.addListener(ErrorDisplayerImpl::onGuiOpen); + } + + @Override + public void registerGuiInit(UnaryOperator consumer) { + CONSUMERS.add(consumer); + } + + public static void onGuiOpen(ScreenEvent.Opening event) { + for (UnaryOperator consumer : CONSUMERS) { + Screen screen = consumer.apply(event.getScreen()); + if (screen != null) { + event.setNewScreen(screen); + } + } + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/credits/forge/CreditsScreenImpl.java b/neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/credits/forge/CreditsScreenImpl.java new file mode 100644 index 000000000..5996b50be --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/credits/forge/CreditsScreenImpl.java @@ -0,0 +1,34 @@ +/* + * 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.client.gui.credits.forge; + +import me.shedaniel.rei.impl.client.gui.credits.CreditsScreen; +import net.minecraft.util.Tuple; + +import java.util.List; + +public class CreditsScreenImpl { + public static void fillTranslators(Exception[] exception, List>> translators) { + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplForge.java b/neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplForge.java new file mode 100644 index 000000000..9e29d9501 --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplForge.java @@ -0,0 +1,76 @@ +/* + * 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.client.gui.forge; + +import me.shedaniel.rei.api.client.gui.widgets.Tooltip; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner; +import net.minecraft.network.chat.Component; +import net.minecraft.world.inventory.tooltip.TooltipComponent; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.client.ClientHooks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class ScreenOverlayImplForge extends ScreenOverlayImpl { + @Override + public void renderTooltipInner(Screen screen, GuiGraphics graphics, Tooltip tooltip, int mouseX, int mouseY) { + graphics.pose().pushPose(); + EntryStack stack = tooltip.getContextStack(); + ItemStack itemStack = stack.getType() == VanillaEntryTypes.ITEM ? stack.castValue() : ItemStack.EMPTY; + List texts = CollectionUtils.filterAndMap(tooltip.entries(), Tooltip.Entry::isText, Tooltip.Entry::getAsText); + List components = ClientHooks.gatherTooltipComponents(itemStack, texts, Optional.empty(), mouseX, screen.width, screen.height, screen.getMinecraft().font); + components = new ArrayList<>(components); + for (Tooltip.Entry entry : tooltip.entries()) { + if (!entry.isText()) { + TooltipComponent component = entry.getAsTooltipComponent(); + + if (component instanceof ClientTooltipComponent client) { + components.add(client); + continue; + } + + components.add(1, ClientTooltipComponent.create(component)); + } + } + Font font = Minecraft.getInstance().font; + if (!itemStack.isEmpty()) { + font = ClientHooks.getTooltipFont(itemStack, font); + } + graphics.tooltipStack = itemStack; + graphics.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE); + graphics.tooltipStack = ItemStack.EMPTY; + graphics.pose().popPose(); + } +} diff --git a/neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinClientPacketListener.java b/neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinClientPacketListener.java new file mode 100644 index 000000000..333f8fdbc --- /dev/null +++ b/neoforge/src/main/java/me/shedaniel/rei/mixin/forge/MixinClientPacketListener.java @@ -0,0 +1,51 @@ +/* + * 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.