From 06bfd71d0758dd9f3469102e08a9b63c4070f50f Mon Sep 17 00:00:00 2001 From: Fury_Phoenix <64714532+Phoenix-Starlight@users.noreply.github.com> Date: Thu, 28 Dec 2023 06:36:49 -0800 Subject: [PATCH] Generate mixin configs automatically using custom AP (#305) --- annotation-processor/build.gradle | 60 ++++++ .../annotation/ClientMixinValidator.java | 189 ++++++++++++++++++ .../mixinAp/annotation/MixinProcessor.java | 115 +++++++++++ .../mixinAp/config/MixinConfig.java | 65 ++++++ .../mixinAp/util/TypedAccessorMap.java | 37 ++++ annotations/build.gradle | 6 + .../modernfix/annotation/ClientOnlyMixin.java | 0 .../modernfix/annotation/IgnoreMixin.java | 11 + .../annotation/IgnoreOutsideDev.java | 0 .../modernfix/annotation/RequiresMod.java | 0 build.gradle | 2 +- buildSrc/build.gradle | 2 +- .../modernfix.common-conventions.gradle | 2 +- .../modernfix.mod-common-conventions.gradle | 43 ++-- .../ItemModelShaperMixin.java | 2 + .../GameRendererMixin.java | 2 + .../ItemRendererMixin.java | 2 + .../resources/modernfix-common.mixins.json | 16 -- fabric/build.gradle | 4 +- .../resources/modernfix-fabric.mixins.json | 16 -- forge/build.gradle | 4 +- .../perf/async_jei/InputConstantsMixin.java | 2 + .../perf/async_locator/EyeOfEnderAccess.java | 6 +- .../perf/async_locator/EyeOfEnderMixin.java | 48 ++--- .../resources/modernfix-forge.mixins.json | 16 -- gradle.properties | 4 +- settings.gradle | 9 + 27 files changed, 555 insertions(+), 108 deletions(-) create mode 100644 annotation-processor/build.gradle create mode 100644 annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/ClientMixinValidator.java create mode 100644 annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/MixinProcessor.java create mode 100644 annotation-processor/src/main/java/org/fury_phoenix/mixinAp/config/MixinConfig.java create mode 100644 annotation-processor/src/main/java/org/fury_phoenix/mixinAp/util/TypedAccessorMap.java create mode 100644 annotations/build.gradle rename {common => annotations}/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java (100%) create mode 100644 annotations/src/main/java/org/embeddedt/modernfix/annotation/IgnoreMixin.java rename {common => annotations}/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java (100%) rename {common => annotations}/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java (100%) delete mode 100644 common/src/main/resources/modernfix-common.mixins.json delete mode 100644 fabric/src/main/resources/modernfix-fabric.mixins.json delete mode 100644 forge/src/main/resources/modernfix-forge.mixins.json diff --git a/annotation-processor/build.gradle b/annotation-processor/build.gradle new file mode 100644 index 000000000..223d94bc7 --- /dev/null +++ b/annotation-processor/build.gradle @@ -0,0 +1,60 @@ +plugins { + id 'com.github.johnrengelman.shadow' + id 'java-library' + id 'com.diffplug.spotless' +} + +repositories { + mavenCentral() + maven { url uri("https://maven.fabricmc.net") } + maven { url "https://maven.neoforged.net/releases" } +} + +dependencies { + annotationProcessor 'com.google.auto.service:auto-service:1.1.1' + compileOnly 'com.google.auto.service:auto-service:1.1.1' + + implementation 'com.google.code.gson:gson:2.10.1' + shadow 'com.google.code.gson:gson:2.10.1' + implementation 'com.google.auto:auto-common:1.2.1' + shadow 'com.google.auto:auto-common:1.2.1' + implementation 'com.google.guava:guava:21.0' + shadow 'com.google.guava:guava:21.0' + + implementation project(":annotations") + shadow project(":annotations") + // Shadow annotations + implementation 'net.fabricmc:sponge-mixin:0.12.5+' + implementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + implementation 'net.minecraftforge:mergetool:1.1.7' + implementation 'net.neoforged:mergetool:2.0.2' +} + +tasks.withType(JavaCompile) { + options.compilerArgs += '--enable-preview' + options.release = 17 +} + +shadowJar { + dependencies { + include(dependency('net.fabricmc:sponge-mixin:')) + include(dependency('net.fabricmc:fabric-loader:')) + include(dependency(':mergetool:')) + } + // shadowJar bug + include '*.jar' + include 'META-INF/services/javax.annotation.processing.Processor' + include 'org/spongepowered/asm/mixin/Mixin.class' + include 'org/fury_phoenix/**/*' + include {it.getName() == 'OnlyIn.class'} + include {it.getName() == 'Dist.class'} + include {it.getName() == 'Environment.class'} + include {it.getName() == 'EnvType.class'} +} + +spotless { + java { + removeUnusedImports() + } +} +version = '1.1.4' diff --git a/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/ClientMixinValidator.java b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/ClientMixinValidator.java new file mode 100644 index 000000000..139c6b20e --- /dev/null +++ b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/ClientMixinValidator.java @@ -0,0 +1,189 @@ +package org.fury_phoenix.mixinAp.annotation; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic; + +import net.fabricmc.api.Environment; + +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.annotation.IgnoreMixin; +import org.fury_phoenix.mixinAp.util.TypedAccessorMap; +import org.spongepowered.asm.mixin.Mixin; + +import static com.google.auto.common.AnnotationMirrors.getAnnotationValue; +import static java.util.AbstractMap.SimpleImmutableEntry; + +public class ClientMixinValidator { + + private final Messager messager; + + private final Elements elemUtils; + + private final Types types; + + private final boolean debug; + + private static final TypedAccessorMap markers = new TypedAccessorMap<>(); + + private static final Map.Entry, Function> + FabricAccessor = new SimpleImmutableEntry<>(Environment.class, Environment::value); + + private static final Map.Entry< + Class, + Function> + ForgeAccessor = new SimpleImmutableEntry<>( + net.minecraftforge.api.distmarker.OnlyIn.class, + net.minecraftforge.api.distmarker.OnlyIn::value + ); + + private static final Map.Entry< + Class, + Function> + NeoForgeAccessor = new SimpleImmutableEntry<>( + net.neoforged.api.distmarker.OnlyIn.class, + net.neoforged.api.distmarker.OnlyIn::value + ); + + static { + markers.put(FabricAccessor); + markers.put(ForgeAccessor); + markers.put(NeoForgeAccessor); + } + + private static final Collection unannotatedClasses = new HashSet<>(); + + public ClientMixinValidator(ProcessingEnvironment env) { + debug = Boolean.valueOf(env.getOptions().get("org.fury_phoenix.mixinAp.validator.debug")); + messager = env.getMessager(); + elemUtils = env.getElementUtils(); + types = env.getTypeUtils(); + } + + public boolean validateMixin(TypeElement annotatedMixinClass) { + return targetsClient(annotatedMixinClass) && + (annotatedMixinClass.getAnnotation(ClientOnlyMixin.class) == null); + } + + public boolean targetsClient(TypeElement annotatedMixinClass) { + return targetsClient(getTargets(annotatedMixinClass)) && + !isIgnored(annotatedMixinClass); + } + + private boolean targetsClient(Collection classTargets) { + return classTargets.stream().anyMatch(this::targetsClient); + } + + private boolean targetsClient(Object classTarget) { + return switch (classTarget) { + case TypeElement te -> + isClientMarked(te); + case TypeMirror tm -> { + var el = types.asElement(tm); + yield el != null ? targetsClient(el) : warn("TypeMirror of " + tm); + } + // If you're using a dollar sign in class names you are insane + case String s -> { + var te = + elemUtils.getTypeElement(toSourceString(s.split("\\$")[0])); + yield te != null ? targetsClient(te) : warn(s); + } + default -> + throw new IllegalArgumentException("Unhandled type: " + + classTarget.getClass() + "\n" + "Stringified contents: " + + classTarget.toString()); + }; + } + + private boolean isClientMarked(TypeElement te) { + for (var entry : markers.entrySet()) { + var marker = te.getAnnotation(entry.getKey()); + if(marker == null) continue; + + return entry.getValue().apply(marker).toString().equals("CLIENT"); + } + if(debug && unannotatedClasses.add(te.toString())) { + messager.printMessage(Diagnostic.Kind.WARNING, + "No marker annotations present on " + te + "!"); + } + return false; + } + + private boolean isIgnored(TypeElement te) { + if(te.getAnnotation(IgnoreMixin.class) != null) { + messager.printMessage(Diagnostic.Kind.WARNING, + toSourceString(te.toString()) + " is ignored!"); + return true; + } + return false; + } + + private boolean warn(Object o) { + messager.printMessage(Diagnostic.Kind.WARNING, + toSourceString(o.toString()) + " can't be loaded, so it is skipped!"); + return false; + } + + public Map.Entry + getClientMixinEntry(TypeElement annotatedMixinClass) { + return new SimpleImmutableEntry<>( + annotatedMixinClass.getQualifiedName(), + getTargets(annotatedMixinClass) + .stream() + .filter(this::targetsClient) + .map(Object::toString) + .map(ClientMixinValidator::toSourceString) + .collect(Collectors.joining(", ")) + ); + } + + private Collection getTargets(TypeElement annotatedMixinClass) { + Collection clzsses = Set.of(); + Collection imaginaries = Set.of(); + TypeMirror MixinElement = elemUtils.getTypeElement(Mixin.class.getName()).asType(); + for (var mirror : annotatedMixinClass.getAnnotationMirrors()) { + if(!types.isSameType(mirror.getAnnotationType(), MixinElement)) + continue; + + @SuppressWarnings("unchecked") + var wrappedClzss = (List) + getAnnotationValue(mirror, "value").getValue(); + + clzsses = wrappedClzss.stream() + .map(AnnotationValue::getValue) + .map(TypeMirror.class::cast) + .collect(Collectors.toSet()); + + @SuppressWarnings("unchecked") + var wrappedStrings = (List) + getAnnotationValue(mirror, "targets").getValue(); + + imaginaries = wrappedStrings.stream() + .map(AnnotationValue::getValue) + .map(String.class::cast) + .collect(Collectors.toSet()); + } + return Stream.of(clzsses, imaginaries) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + } + + public static String toSourceString(String bytecodeName) { + return bytecodeName.replaceAll("\\/", "."); + } +} diff --git a/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/MixinProcessor.java b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/MixinProcessor.java new file mode 100644 index 000000000..747f8865f --- /dev/null +++ b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/MixinProcessor.java @@ -0,0 +1,115 @@ +package org.fury_phoenix.mixinAp.annotation; + +import com.google.auto.service.AutoService; +import com.google.common.base.Throwables; + +import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedOptions; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; + +import org.fury_phoenix.mixinAp.config.MixinConfig; + +@SupportedAnnotationTypes({"org.spongepowered.asm.mixin.Mixin", "org.embeddedt.modernfix.annotation.ClientOnlyMixin"}) +@SupportedOptions({"rootProject.name", "project.name", "org.fury_phoenix.mixinAp.validator.debug"}) +@SupportedSourceVersion(SourceVersion.RELEASE_17) +@AutoService(Processor.class) +public class MixinProcessor extends AbstractProcessor { + + // Remember to call toString when using aliases + private static final Map aliases = Map.of( + "Mixin", "mixins", + "ClientOnlyMixin", "client" + ); + + private final Map> mixinConfigList = new HashMap<>(); + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + try { + if(roundEnv.processingOver()){ + filterMixinSets(); + // create record for serialization, compute package name + String packageName = Optional.ofNullable(mixinConfigList.get("mixins")) + .orElse(mixinConfigList.get("client")) + .get(0).split("(?<=mixin)")[0]; + finalizeMixinConfig(); + new MixinConfig(packageName, + mixinConfigList.get("mixins"), + mixinConfigList.get("client") + ).generateMixinConfig(processingEnv); + } else { + processMixins(annotations, roundEnv); + } + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Fatal error:" + + Throwables.getStackTraceAsString(e)); + throw new RuntimeException(e); + // Halt the AP to prevent nonsense errors + } + return false; + } + + private void processMixins(Set annotations, RoundEnvironment roundEnv) { + for (TypeElement annotation : annotations) { + Set annotatedMixins = roundEnv.getElementsAnnotatedWith(annotation); + + Stream mixinStream = + annotatedMixins.stream() + .map(TypeElement.class::cast); + + validateCommonMixins(annotation, mixinStream); + + List mixins = + annotatedMixins.stream() + .map(TypeElement.class::cast) + .map(TypeElement::toString) + .collect(Collectors.toList()); + + mixinConfigList.putIfAbsent(aliases.get(annotation.getSimpleName().toString()), mixins); + } + } + + private void filterMixinSets() { + List commonSet = mixinConfigList.get("mixins"); + if(commonSet == null) return; + commonSet.removeAll(mixinConfigList.get("client")); + } + + private void validateCommonMixins(TypeElement annotation, Stream mixins) { + if(!annotation.getSimpleName().toString().equals("Mixin")) + return; + ClientMixinValidator validator = new ClientMixinValidator(processingEnv); + // The implementation may throw a CME + mixins.sequential() + .filter(validator::validateMixin) + .map(validator::getClientMixinEntry) + .forEach(this::logClientClassTarget); + } + + private void logClientClassTarget(Map.Entry mixin) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, + "Mixin " + mixin.getKey() + " targets client-side classes: " + mixin.getValue()); + } + + private void finalizeMixinConfig() { + // relativize class names + for(var list : mixinConfigList.values()) { + list.replaceAll(className -> className.split("(?<=mixin.)")[1]); + } + } +} diff --git a/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/config/MixinConfig.java b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/config/MixinConfig.java new file mode 100644 index 000000000..9d1e6c918 --- /dev/null +++ b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/config/MixinConfig.java @@ -0,0 +1,65 @@ +package org.fury_phoenix.mixinAp.config; + +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; + +import java.io.IOException; +import java.io.Writer; +import java.util.List; +import java.util.Optional; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.tools.StandardLocation; + +public record MixinConfig( + boolean required, + String minVersion, + @SerializedName("package") + String packageName, + String plugin, + String compatabilityLevel, + @SerializedName("mixins") + List commonMixins, + @SerializedName("client") + List clientMixins, + InjectorOptions injectors, OverwriteOptions overwrites + ) { + public MixinConfig(String packageName, List commonMixins, List clientMixins) { + this(true, "0.8", packageName, "org.embeddedt.modernfix.core.ModernFixMixinPlugin", "JAVA_8", + commonMixins, clientMixins, InjectorOptions.DEFAULT, OverwriteOptions.DEFAULT); + } + public record InjectorOptions(int defaultRequire) { + public static final InjectorOptions DEFAULT = new InjectorOptions(1); + } + public record OverwriteOptions(boolean conformVisibility) { + public static final OverwriteOptions DEFAULT = new OverwriteOptions(true); + } + + public void generateMixinConfig(ProcessingEnvironment env) throws IOException { + try ( + Writer mixinConfigWriter = env.getFiler() + .createResource(StandardLocation.SOURCE_OUTPUT, "", + MixinConfig.computeMixinConfigPath( + Optional.of(env.getOptions().get("rootProject.name")), + Optional.ofNullable(env.getOptions().get("project.name")) + ) + ).openWriter() + ) { + String mixinConfig = new GsonBuilder() + .setPrettyPrinting() + .create() + .toJson(this); + + mixinConfigWriter.write(mixinConfig); + mixinConfigWriter.write("\n"); + } catch (IOException e) { throw e; } + } + + private static String computeMixinConfigPath(Optional rootProjectName, Optional projectName) { + return "resources/" + + rootProjectName.get() + + (projectName.isPresent() ? "-" : "") + + projectName.orElse("") + + ".mixins.json"; + } +} diff --git a/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/util/TypedAccessorMap.java b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/util/TypedAccessorMap.java new file mode 100644 index 000000000..5632a9175 --- /dev/null +++ b/annotation-processor/src/main/java/org/fury_phoenix/mixinAp/util/TypedAccessorMap.java @@ -0,0 +1,37 @@ +package org.fury_phoenix.mixinAp.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; + +import static java.util.Map.Entry; + +/** + * Type-safe heterogenous map of accessors + * @author Fury_Phoenix + * @reason Type-safety since K, V of Map are non-identical + * @param The supertype of desired types. + * This is useful in cases such as . + */ +public class TypedAccessorMap { + private final Map, Function> typedAccessors = new HashMap<>(); + + public void put(Class key, Function func) { + Objects.requireNonNull(func); + typedAccessors.put(Objects.requireNonNull(key), o -> func.apply(key.cast(o))); + } + + public void put(Entry, Function> entry) { + put(entry.getKey(), entry.getValue()); + } + + public Function get(Class key) { + return typedAccessors.get(key); + } + + public Set, Function>> entrySet() { + return typedAccessors.entrySet(); + } +} diff --git a/annotations/build.gradle b/annotations/build.gradle new file mode 100644 index 000000000..5271e5b3d --- /dev/null +++ b/annotations/build.gradle @@ -0,0 +1,6 @@ +plugins { + id 'modernfix.common-conventions' + id 'java-library' +} + +version = '1.1.0' diff --git a/common/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java b/annotations/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java similarity index 100% rename from common/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java rename to annotations/src/main/java/org/embeddedt/modernfix/annotation/ClientOnlyMixin.java diff --git a/annotations/src/main/java/org/embeddedt/modernfix/annotation/IgnoreMixin.java b/annotations/src/main/java/org/embeddedt/modernfix/annotation/IgnoreMixin.java new file mode 100644 index 000000000..00ae1fb7a --- /dev/null +++ b/annotations/src/main/java/org/embeddedt/modernfix/annotation/IgnoreMixin.java @@ -0,0 +1,11 @@ +package org.embeddedt.modernfix.annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface IgnoreMixin { +} + diff --git a/common/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java b/annotations/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java similarity index 100% rename from common/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java rename to annotations/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java diff --git a/common/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java b/annotations/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java similarity index 100% rename from common/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java rename to annotations/src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java diff --git a/build.gradle b/build.gradle index f943a7a36..0390ec975 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { id 'org.ajoberstar.grgit' version '5.2.0' id 'se.bjurr.gitchangelog.git-changelog-gradle-plugin' version '1.79.0' id "com.modrinth.minotaur" version "2.+" apply false - id("com.diffplug.spotless") version "6.18.0" apply false + id("com.diffplug.spotless") version "6.18.0" apply false id 'modernfix.common-conventions' apply false } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 1957c3393..678405245 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,3 +1,3 @@ plugins { id 'groovy-gradle-plugin' -} \ No newline at end of file +} diff --git a/buildSrc/src/main/groovy/modernfix.common-conventions.gradle b/buildSrc/src/main/groovy/modernfix.common-conventions.gradle index ebce0241e..ecf68ba0c 100644 --- a/buildSrc/src/main/groovy/modernfix.common-conventions.gradle +++ b/buildSrc/src/main/groovy/modernfix.common-conventions.gradle @@ -78,4 +78,4 @@ repositories { url 'https://maven.terraformersmc.com/releases' } maven { url = "https://jitpack.io" } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/groovy/modernfix.mod-common-conventions.gradle b/buildSrc/src/main/groovy/modernfix.mod-common-conventions.gradle index 3362ce37e..2997c5cd5 100644 --- a/buildSrc/src/main/groovy/modernfix.mod-common-conventions.gradle +++ b/buildSrc/src/main/groovy/modernfix.mod-common-conventions.gradle @@ -16,37 +16,26 @@ dependencies { parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip") } } + implementation project(":annotations") + annotationProcessor project(path: ":annotation-processor", configuration: 'shadow') } +project.sourceSets { + main.resources.srcDirs += [layout.buildDirectory.dir("generated/sources/annotationProcessor/java/main/resources")] +} +// hack to shut up gradle about the hack to include generated resources tasks { processResources { - def mixinFileList = [] - def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/" + project.name + "/mixin") - fileTree(mixinDirectory).visit { FileVisitDetails details -> - if(details.file.isFile()) { - def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.') - mixinFileList << fileName - } - } - - def mixinClassesStringB = new StringBuilder() - for(int i = 0; i < mixinFileList.size(); i++) { - mixinClassesStringB.append(" \"") - mixinClassesStringB.append(mixinFileList.get(i)) - mixinClassesStringB.append('"') - if(i < (mixinFileList.size() - 1)) - mixinClassesStringB.append(',') - mixinClassesStringB.append('\n') - } - - def replacements = [ - mixin_classes: mixinClassesStringB.toString() - ] + dependsOn compileJava + } +} - inputs.properties replacements - def filePattern = "modernfix-" + project.name + ".mixins.json" - filesMatching(filePattern) { - expand replacements +tasks.withType(JavaCompile) { + options.fork = true + options.forkOptions.jvmArgs << '--enable-preview' + configure(options) { + if (!name.toLowerCase().contains('test')) { + options.compilerArgs << "-ArootProject.name=${rootProject.name}" << "-Aproject.name=${project.name}" } } -} \ No newline at end of file +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java index 9e31ecd75..dfe8c84d3 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java @@ -6,6 +6,7 @@ import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.world.item.Item; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.dynamicresources.DynamicModelCache; import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; import org.embeddedt.modernfix.util.DynamicInt2ObjectMap; @@ -18,6 +19,7 @@ import java.util.Map; @Mixin(ItemModelShaper.class) +@ClientOnlyMixin public abstract class ItemModelShaperMixin { @Shadow public abstract ModelManager getModelManager(); diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/GameRendererMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/GameRendererMixin.java index ee3a0f9d9..d457b5d40 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/GameRendererMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/GameRendererMixin.java @@ -1,6 +1,7 @@ package org.embeddedt.modernfix.common.mixin.perf.faster_item_rendering; import net.minecraft.client.renderer.GameRenderer; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.render.RenderState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -8,6 +9,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(GameRenderer.class) +@ClientOnlyMixin public class GameRendererMixin { @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GameRenderer;renderLevel(FJLcom/mojang/blaze3d/vertex/PoseStack;)V", shift = At.Shift.BEFORE)) private void markRenderingLevel(CallbackInfo ci) { diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java index 7e2ddd69b..972014579 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java @@ -11,6 +11,7 @@ import net.minecraft.client.resources.model.SimpleBakedModel; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.render.FastItemRenderType; import org.embeddedt.modernfix.render.RenderState; import org.embeddedt.modernfix.render.SimpleItemModelView; @@ -21,6 +22,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(value = ItemRenderer.class, priority = 600) +@ClientOnlyMixin public abstract class ItemRendererMixin { private ItemTransforms.TransformType transformType; private final SimpleItemModelView modelView = new SimpleItemModelView(); diff --git a/common/src/main/resources/modernfix-common.mixins.json b/common/src/main/resources/modernfix-common.mixins.json deleted file mode 100644 index 94a4e091e..000000000 --- a/common/src/main/resources/modernfix-common.mixins.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.embeddedt.modernfix.common.mixin", - "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", - "compatibilityLevel": "JAVA_8", - "mixins": [ -${mixin_classes} - ], - "injectors": { - "defaultRequire": 1 - }, - "overwrites": { - "conformVisibility": true - } -} diff --git a/fabric/build.gradle b/fabric/build.gradle index 6eefad324..c20477319 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "7.1.2" + id "com.github.johnrengelman.shadow" id 'com.adarshr.test-logger' version '3.2.0' id "modernfix.mod-common-conventions" id "modernfix.platform-conventions" @@ -122,4 +122,4 @@ publishing { repositories { // Add repositories to publish to here. } -} \ No newline at end of file +} diff --git a/fabric/src/main/resources/modernfix-fabric.mixins.json b/fabric/src/main/resources/modernfix-fabric.mixins.json deleted file mode 100644 index 3d94ea0d8..000000000 --- a/fabric/src/main/resources/modernfix-fabric.mixins.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "required": true, - "package": "org.embeddedt.modernfix.fabric.mixin", - "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", - "compatibilityLevel": "JAVA_8", - "minVersion": "0.8", - "mixins": [ -${mixin_classes} - ], - "injectors": { - "defaultRequire": 1 - }, - "overwrites": { - "conformVisibility": true - } -} \ No newline at end of file diff --git a/forge/build.gradle b/forge/build.gradle index 5d783901a..ea515fab5 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "7.1.2" + id "com.github.johnrengelman.shadow" id "modernfix.mod-common-conventions" id "modernfix.platform-conventions" } @@ -141,4 +141,4 @@ publishing { repositories { // Add repositories to publish to here. } -} \ No newline at end of file +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_jei/InputConstantsMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_jei/InputConstantsMixin.java index e5b49c662..5b632f72a 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_jei/InputConstantsMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_jei/InputConstantsMixin.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.systems.RenderSystem; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.RequiresMod; import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Mixin; @@ -9,6 +10,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(InputConstants.class) +@ClientOnlyMixin @RequiresMod("jei") public class InputConstantsMixin { @Redirect(method = "isKeyDown", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwGetKey(JI)I", remap = false)) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderAccess.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderAccess.java index c35be48b0..5f24fa1cd 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderAccess.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderAccess.java @@ -1,11 +1,13 @@ package org.embeddedt.modernfix.forge.mixin.perf.async_locator; import net.minecraft.world.entity.projectile.EyeOfEnder; +import org.embeddedt.modernfix.annotation.IgnoreMixin; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(EyeOfEnder.class) +@IgnoreMixin public interface EyeOfEnderAccess { - @Accessor - void setLife(int life); + @Accessor + void setLife(int life); } diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderMixin.java index 74205bf34..7b1463f88 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/async_locator/EyeOfEnderMixin.java @@ -1,6 +1,7 @@ package org.embeddedt.modernfix.forge.mixin.perf.async_locator; import net.minecraft.world.entity.projectile.EyeOfEnder; +import org.embeddedt.modernfix.annotation.IgnoreMixin; import org.embeddedt.modernfix.forge.structure.logic.EyeOfEnderData; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -8,30 +9,31 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(EyeOfEnder.class) +@IgnoreMixin public class EyeOfEnderMixin implements EyeOfEnderData { - private boolean locateTaskOngoing = false; + private boolean locateTaskOngoing = false; - @Override - public void setLocateTaskOngoing(boolean locateTaskOngoing) { - this.locateTaskOngoing = locateTaskOngoing; - } + @Override + public void setLocateTaskOngoing(boolean locateTaskOngoing) { + this.locateTaskOngoing = locateTaskOngoing; + } - /* - Intercept EyeOfEnder#tick call and return after the super call if there's an ongoing locate task. This is to - prevent the entity from moving or dying until we have a location result. - */ - @Inject( - method = "tick", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/Entity;tick()V", - shift = At.Shift.AFTER - ), - cancellable = true - ) - public void skipTick(CallbackInfo ci) { - if (locateTaskOngoing) { - ci.cancel(); - } - } + /* + Intercept EyeOfEnder#tick call and return after the super call if there's an ongoing locate task. This is to + prevent the entity from moving or dying until we have a location result. + */ + @Inject( + method = "tick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/Entity;tick()V", + shift = At.Shift.AFTER + ), + cancellable = true + ) + public void skipTick(CallbackInfo ci) { + if (locateTaskOngoing) { + ci.cancel(); + } + } } diff --git a/forge/src/main/resources/modernfix-forge.mixins.json b/forge/src/main/resources/modernfix-forge.mixins.json deleted file mode 100644 index f63f1dfc3..000000000 --- a/forge/src/main/resources/modernfix-forge.mixins.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "required": true, - "package": "org.embeddedt.modernfix.forge.mixin", - "plugin": "org.embeddedt.modernfix.core.ModernFixMixinPlugin", - "compatibilityLevel": "JAVA_8", - "minVersion": "0.8", - "mixins": [ -${mixin_classes} - ], - "injectors": { - "defaultRequire": 1 - }, - "overwrites": { - "conformVisibility": true - } -} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 1cb73b923..a66571673 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,8 @@ refined_storage_version=3807951 kubejs_version=1605.3.19-build.299 ctm_version=MC1.16.1-1.1.2.6 supported_minecraft_versions=1.16.4,1.16.5 +// Look up maven coordinates when changing shadow_version +shadow_version=7.1.2 fabric_loader_version=0.14.21 fabric_api_version=0.42.0+1.16 @@ -25,4 +27,4 @@ modmenu_version=1.16.23 spark_forge_version=3767277 spark_fabric_version=3337642 -use_fabric_api_at_runtime=true \ No newline at end of file +use_fabric_api_at_runtime=true diff --git a/settings.gradle b/settings.gradle index 514910c15..dbf3afdd6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,8 +5,17 @@ pluginManagement { maven { url "https://maven.architectury.dev/" } maven { url "https://maven.minecraftforge.net/" } } + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.github.johnrengelman.shadow") { + useModule("gradle.plugin.com.github.johnrengelman:shadow:${shadow_version}") + } + } + } } +include("annotation-processor") +include("annotations") include("test_agent") include("common")