+ * This annotation class represents a valid dependency check where you can + * quickly use a semantic versioning expression to check for the presence of + * a specified dependency. + *
+ * + *+ * Incompatible type settings are also preset, and additionally we support + * custom predicates to help verify that the runtime environment is valid + * for the annotated class. + *
+ */ +@Target({ /* No targets allowed */}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Dependency { + /** + * Preset simple compatibility options + */ + enum DependencyType { + /** + * Default behaviour, no interference with inspection content. + */ + NORMAL, + /** + * If this item is used, the decorated class is not executed when the + * {@link Dependency#modid}, {@link Dependency#version} and + * {@link Dependency#predicate} (if present) checks pass. + */ + CONFLICT + } + + /** + * Dependency mod id. + * + * @return mod id. + */ + String modid(); + + /** + * Dependency mod version expressions. + * + * @return Dependency version expressions list. + */ + String[] version(); + + /** + * Dependency mod type. + * + * @return Dependency type. + */ + DependencyType dependencyType() default DependencyType.NORMAL; + + /** + * Dependency custom predicate. + * + * @return Custom Predicate Classes. + */ + @Nullable + Class extends CustomDependencyPredicate>[] predicate() default {}; +} diff --git a/src/main/java/top/hendrixshen/magiclib/untils/dependency/DependencyValidator.java b/src/main/java/top/hendrixshen/magiclib/untils/dependency/DependencyValidator.java new file mode 100644 index 00000000..062c173b --- /dev/null +++ b/src/main/java/top/hendrixshen/magiclib/untils/dependency/DependencyValidator.java @@ -0,0 +1,44 @@ +package top.hendrixshen.magiclib.untils.dependency; + +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.api.Version; +import net.fabricmc.loader.api.VersionParsingException; +import net.fabricmc.loader.impl.util.version.VersionPredicateParser; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Optional; + +public class DependencyValidator { + private static Method oldMatchesMethod; + + static { + try { + oldMatchesMethod = Class.forName("net.fabricmc.loader.util.version.VersionPredicateParser").getMethod("matches", Version.class, String.class); + } catch (ClassNotFoundException | NoSuchMethodException ignored) { + // Ignored + } + } + + public static boolean checkDependency(Version version, String versionExpr) { + try { + if (oldMatchesMethod != null) { + return (boolean) oldMatchesMethod.invoke(null, version, versionExpr); + } + return VersionPredicateParser.parse(versionExpr).test(version); + } catch (VersionParsingException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean checkDependency(String modId, String version, Dependency.DependencyType type) { + Optional