diff options
| author | shedaniel <daniel@shedaniel.me> | 2023-11-19 03:04:21 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-11-19 03:04:21 +0800 |
| commit | b10f1308f5359ce73a9f4b899cf9516c4ad5388f (patch) | |
| tree | 5b5700934ae88681918a620edc39754dbf82d496 /neoforge/src/main/java/me | |
| parent | 11b87fdd96f5542d646aa8f5136095917f207564 (diff) | |
| download | RoughlyEnoughItems-b10f1308f5359ce73a9f4b899cf9516c4ad5388f.tar.gz RoughlyEnoughItems-b10f1308f5359ce73a9f4b899cf9516c4ad5388f.tar.bz2 RoughlyEnoughItems-b10f1308f5359ce73a9f4b899cf9516c4ad5388f.zip | |
Support NeoForge
Diffstat (limited to 'neoforge/src/main/java/me')
29 files changed, 1836 insertions, 0 deletions
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 <A, T> void scanAnnotation(Class<A> clazz, Predicate<Class<T>> predicate, TriConsumer<List<String>, Supplier<T>, Class<T>> consumer) { + scanAnnotation(Type.getType(clazz), predicate, consumer); + } + + public static <T> void scanAnnotation(Type annotationType, Predicate<Class<T>> predicate, TriConsumer<List<String>, Supplier<T>, Class<T>> consumer) { + List<Triple<List<String>, Supplier<T>, Class<T>>> instances = Lists.newArrayList(); + for (ModFileScanData data : ModList.get().getAllScanData()) { + List<String> 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<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())); + } else { + enabled = true; + } + } else { + enabled = true; + } + + if (!enabled) continue; + + try { + Class<T> clazz = (Class<T>) 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<List<String>, Supplier<T>, Class<T>> 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 <P extends me.shedaniel.rei.api.common.plugins.REIPlugin<?>> REIPluginProvider<P> wrapPlugin(List<String> modId, REIPluginProvider<P> plugin) { + return new REIPluginProvider<P>() { + final String nameSuffix = " [" + String.join(", ", modId) + "]"; + + @Override + public Collection<P> provide() { + return plugin.provide(); + } + + @Override + public Class<P> getPluginProviderClass() { + return plugin.getPluginProviderClass(); + } + + @Override + public String getPluginProviderName() { + return plugin.getPluginProviderName() + nameSuffix; + } + }; + } + + private static final Supplier<List<Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>>>> loaderProvided = + Suppliers.memoize(() -> getPluginsLoader(REIPluginLoader.class)); + private static final Supplier<List<Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>>>> loaderProvidedCommon = + Suppliers.memoize(() -> getPluginsLoader(REIPluginLoaderCommon.class)); + private static final Supplier<List<Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>>>> loaderProvidedDist; + + static { + Supplier<List<Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>>>> 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 <T, P extends me.shedaniel.rei.api.common.plugins.REIPlugin<?>> List<Map.Entry<REIPluginProvider<P>, List<String>>> getPluginsLoader(Class<T> annotation) { + List<Map.Entry<REIPluginProvider<P>, List<String>>> list = new ArrayList<>(); + AnnotationUtils.<T, REIPluginProvider<P>>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.<REIPlugin, REIServerPlugin>scanAnnotation(REIPlugin.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Common plugins + AnnotationUtils.<REIPluginCommon, REIServerPlugin>scanAnnotation(REIPluginCommon.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Dist plugins + if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) { + AnnotationUtils.<REIPluginDedicatedServer, REIServerPlugin>scanAnnotation(REIPluginDedicatedServer.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + } else { + AnnotationUtils.<REIPluginClient, REIServerPlugin>scanAnnotation(REIPluginClient.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + } + + // Loaders + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvided.get()) { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIServerPlugin.class))); + } + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvidedCommon.get()) { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIServerPlugin.class))); + } + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvidedDist.get()) { + ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIServerPlugin.class))); + } + } + + @Override + public void detectCommonPlugins() { + // Legacy Annotation + AnnotationUtils.<REIPlugin, me.shedaniel.rei.api.common.plugins.REIPlugin<?>>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.<REIPluginCommon, me.shedaniel.rei.api.common.plugins.REIPlugin<?>>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.<REIPluginClient, me.shedaniel.rei.api.common.plugins.REIPlugin>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.<REIPluginDedicatedServer, me.shedaniel.rei.api.common.plugins.REIPlugin>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<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvided.get()) { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(entry.getValue(), entry.getKey())); + } + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvidedCommon.get()) { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(entry.getValue(), entry.getKey())); + } + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvidedDist.get()) { + ((PluginView) PluginManager.getInstance()).registerPlugin(wrapPlugin(entry.getValue(), entry.getKey())); + } + } + + @OnlyIn(Dist.CLIENT) + @Override + public Supplier<Runnable> 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.<REIPlugin, REIClientPlugin>scanAnnotation(REIPlugin.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Common plugins + AnnotationUtils.<REIPluginCommon, REIClientPlugin>scanAnnotation(REIPluginCommon.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Dist plugins + AnnotationUtils.<REIPluginClient, REIClientPlugin>scanAnnotation(REIPluginClient.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin, clazz) -> { + ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); + }); + + // Loaders + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvided.get()) { + ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIClientPlugin.class))); + } + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvidedCommon.get()) { + ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIClientPlugin.class))); + } + for (Map.Entry<REIPluginProvider<me.shedaniel.rei.api.common.plugins.REIPlugin<?>>, List<String>> entry : loaderProvidedDist.get()) { + ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(wrapPlugin(entry.getValue(), wrapAndFilter(entry.getKey(), REIClientPlugin.class))); + } + }; + } + + private static <P extends me.shedaniel.rei.api.common.plugins.REIPlugin<P>> REIPluginProvider<P> wrapAndFilter(REIPluginProvider<?> provider, Class<P> clazz) { + return new REIPluginProvider<>() { + @Override + public Collection<P> provide() { + return new AbstractCollection<>() { + @Override + public Iterator<P> iterator() { + return Iterables.filter(provider.provide(), clazz).iterator(); + } + + @Override + public int size() { + return Iterators.size(iterator()); + } + }; + } + + @Override + public Class<P> 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 |
