Skip to content

Commit

Permalink
Reintroduce Superclass Transformations
Browse files Browse the repository at this point in the history
Properly reintroduces superclass transformers with
ModLauncher's ITransformer api. There are some quirks with
needing to accept transforming classes multiple times based
on voting contexts. This functions as expected in both
development and production cases from limited testing.

Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
  • Loading branch information
gabizou committed Feb 17, 2022
1 parent ee6029f commit ba81410
Show file tree
Hide file tree
Showing 19 changed files with 381 additions and 257 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.gradle.api.logging.Logger;
import org.gradle.api.tasks.SourceSet;

import javax.annotation.Nullable;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
Expand All @@ -12,9 +14,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Nullable;
import javax.inject.Inject;

public abstract class SpongeImplementationExtension {

public static final String MIXIN_CONFIGS_PROPERTY = "mixinConfigs";
Expand Down Expand Up @@ -100,17 +99,21 @@ public String generatePlatformBuildVersionString(final String apiVersion, final
* @return the mixin configuration files that should be applied to this project
*/
public Set<String> getMixinConfigurations() {
return this.getNamedConfigurations(SpongeImplementationExtension.MIXIN_CONFIGS_PROPERTY);
}

public Set<String> getNamedConfigurations(final String name) {
final Set<String> configs = new HashSet<>();

// if we have a parent
final Project parentProject = this.project.getParent();
if (parentProject != null) {
SpongeImplementationExtension
.splitAndAddIfNonNull(configs, (String) parentProject.findProperty(SpongeImplementationExtension.MIXIN_CONFIGS_PROPERTY));
.splitAndAddIfNonNull(configs, (String) parentProject.findProperty(name));
}

// own project
SpongeImplementationExtension.splitAndAddIfNonNull(configs, (String) this.project.findProperty("mixinConfigs"));
SpongeImplementationExtension.splitAndAddIfNonNull(configs, (String) this.project.findProperty(name));
return configs;
}

Expand Down
11 changes: 11 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,17 @@ license {
newLine(false)
}

idea {
if (project != null) {
(project as ExtensionAware).extensions["settings"].run {
(this as ExtensionAware).extensions.getByType(org.jetbrains.gradle.ext.TaskTriggersConfig::class).run {
afterSync(":modlauncher-transformers:build")
}
}
}
}


allprojects {
configurations.configureEach {
resolutionStrategy.dependencySubstitution {
Expand Down
20 changes: 17 additions & 3 deletions forge/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ plugins {
apply(plugin = "dev.architectury.loom") // we can't use the plugins block because we have to declare the dep in buildscript

val commonProject = parent!!
val transformersProject = parent!!.project(":modlauncher-transformers")
val apiVersion: String by project
val minecraftVersion: String by project
val forgeVersion: String by project
Expand Down Expand Up @@ -79,9 +80,13 @@ extensions.configure(LoomGradleExtension::class) {

// Forge extra configurations
val forgeBootstrapLibrariesConfig = configurations.register("bootstrapLibraries")
val forgeLibrariesConfig = configurations.register("spongeLibraries")
val mlTransformersConfig = configurations.register("mltransformers")
val forgeLibrariesConfig = configurations.register("spongeLibraries") {
extendsFrom(mlTransformersConfig.get())
}
val forgeAppLaunchConfig = configurations.register("applaunch") {
extendsFrom(forgeBootstrapLibrariesConfig.get())
extendsFrom(mlTransformersConfig.get())
extendsFrom(configurations.getByName("minecraftNamed"))
extendsFrom(configurations.getByName("loaderLibraries"))
}
Expand All @@ -93,6 +98,7 @@ val launch = commonProject.sourceSets.named("launch")
val applaunch = commonProject.sourceSets.named("applaunch")
val mixins = commonProject.sourceSets.named("mixins")
val main = commonProject.sourceSets.named("main")
val mlTransformers = transformersProject.sourceSets.named("main")

// Forge source sets
val forgeMain by sourceSets.named("main") {
Expand All @@ -115,6 +121,9 @@ val forgeLaunch by sourceSets.register("launch") {
extendsFrom(forgeAppLaunchConfig.get())
extendsFrom(forgeLibrariesConfig.get())
}
configurations.named(runtimeClasspathConfigurationName) {
extendsFrom(mlTransformersConfig.get())
}
}
val forgeAccessors by sourceSets.register("accessors") {
spongeImpl.applyNamedDependencyOnOutput(commonProject, mixins.get(), this, project, this.implementationConfigurationName)
Expand Down Expand Up @@ -149,6 +158,7 @@ val forgeAppLaunch by sourceSets.register("applaunch") {
spongeImpl.applyNamedDependencyOnOutput(commonProject, main.get(), this, project, this.runtimeOnlyConfigurationName)
spongeImpl.applyNamedDependencyOnOutput(commonProject, accessors.get(), this, project, this.runtimeOnlyConfigurationName)
spongeImpl.applyNamedDependencyOnOutput(project, forgeMain, this, project, this.runtimeOnlyConfigurationName)
spongeImpl.applyNamedDependencyOnOutput(transformersProject, mlTransformers.get(), this, project, this.runtimeOnlyConfigurationName)
}
val forgeMixinsImplementation by configurations.named(forgeMixins.implementationConfigurationName) {
extendsFrom(forgeLibrariesConfig.get())
Expand All @@ -157,6 +167,7 @@ val forgeMixinsImplementation by configurations.named(forgeMixins.implementation
configurations.named(forgeAppLaunch.implementationConfigurationName) {
extendsFrom(forgeAppLaunchConfig.get())
extendsFrom(launchConfig.get())
extendsFrom(mlTransformersConfig.get())
}
val forgeAppLaunchRuntime by configurations.named(forgeAppLaunch.runtimeOnlyConfigurationName)

Expand Down Expand Up @@ -201,9 +212,11 @@ dependencies {
exclude(group = "org.spongepowered", module = "configurate-core")
exclude(group = "org.checkerframework", module = "checker-qual")
}
appLaunch("net.fabricmc:access-widener:1.0.2") {
exclude(group = "org.apache.logging.log4j")
appLaunch("org.spongepowered:configurate-jackson") {
exclude(group = "org.spongepowered", module = "configurate-core")
exclude(group = "org.checkerframework", module = "checker-qual")
}
mlTransformersConfig.name(project(transformersProject.path))

val libraries = forgeLibrariesConfig.name
libraries("org.spongepowered:timings:$timingsVersion")
Expand Down Expand Up @@ -389,6 +402,7 @@ tasks {
from(commonProject.sourceSets.named("accessors").map {it.output })
from(commonProject.sourceSets.named("launch").map {it.output })
from(commonProject.sourceSets.named("applaunch").map {it.output })
from(transformersProject.sourceSets.named("main").map { it.output })
from(forgeAppLaunch.output)
from(forgeLaunch.output)
from(forgeAccessors.output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.loading.ModDirTransformerDiscoverer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.spongepowered.transformers.modlauncher.AccessWidenerTransformationService;
import org.spongepowered.transformers.modlauncher.SuperclassChanger;

import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Supplier;
Expand Down Expand Up @@ -90,11 +91,12 @@ public void initialize(final IEnvironment environment) {
throw new RuntimeException("Failed to register SpongeForge", ex);
}
// Register SF as an AW
final Optional<AccessWidenerTransformationService> aw = environment.getProperty(AccessWidenerTransformationService.INSTANCE.get());
if (aw.isPresent()) {
// todo: actually read this from the jar manifest
aw.get().offerResource(ForgeProductionBootstrap.class.getResource("/common.accesswidener"), "SpongeForge injected");
}
// todo: actually read this from the jar manifest
environment.getProperty(AccessWidenerTransformationService.INSTANCE.get()).ifPresent(aWTS ->
aWTS.offerResource(ForgeProductionBootstrap.class.getResource("/common.accesswidener"), "SpongeForge injected"));
environment.getProperty(SuperclassChanger.INSTANCE.get()).ifPresent(scc -> {
scc.offerResource(ForgeProductionBootstrap.class.getResource("/common.superclasschange"), "SpongeForge injected");
});
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
org.spongepowered.forge.applaunch.service.AccessWidenerTransformationService
org.spongepowered.forge.applaunch.service.ForgeProductionBootstrap
org.spongepowered.forge.applaunch.service.ForgeProductionBootstrap
4 changes: 3 additions & 1 deletion forge/src/mixins/resources/mixins.spongeforge.core.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"minecraftforge.fml.ModContainerMixin_Forge",
"minecraftforge.util.ITeleporterMixin_Forge",
"server.BootstrapMixin_Forge",
"server.MainMixin_Forge",
"server.MinecraftServerMixin_Forge",
"server.level.ServerLevelMixin_Timings_Forge",
"server.level.ServerPlayerMixin_Forge",
Expand All @@ -40,5 +39,8 @@
"client": [
"client.MinecraftMixin_Forge",
"client.main.MainMixin_Forge"
],
"server": [
"server.MainMixin_Forge"
]
}
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ projectDescription=The SpongeAPI implementation targeting vanilla Minecraft and
mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.concurrent.json,mixins.sponge.core.json,\
mixins.sponge.entityactivation.json,mixins.sponge.exploit.json,mixins.sponge.inventory.json,mixins.sponge.movementcheck.json,\
mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json
superClassChanges=common.superclasschange

minecraftVersion=1.16.5
recommendedVersion=0-SNAPSHOT
Expand Down
54 changes: 54 additions & 0 deletions modlauncher-transformers/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
plugins {
eclipse
idea
}
//// Make sure jar is present for other projects
eclipse {
synchronizationTasks(tasks.jar)
}


val organization: String by project
val projectUrl: String by project

license {
properties {
this["name"] = "Sponge"
this["organization"] = organization
this["url"] = projectUrl
}
header(rootProject.file("HEADER.txt"))

include("**/*.java")
newLine(false)
}

val log4jVersion: String by project
val modlauncherVersion: String by project
val apiConfigurateVersion: String by project
val asmVersion: String by project

dependencies {
implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
implementation("cpw.mods:modlauncher:$modlauncherVersion") {
exclude(group = "org.apache.logging.log4j")
exclude(group = "net.sf.jopt-simple") // uses a newer version than MC
}
implementation(platform("org.spongepowered:configurate-bom:$apiConfigurateVersion"))
implementation("org.spongepowered:configurate-core") {
exclude(group = "org.checkerframework", module="checker-qual") // We use our own version
}
implementation("org.spongepowered:configurate-jackson") {
exclude(group="org.spongepowered", module="configurate-core")
exclude(group="org.checkerframework", module="checker-qual") // We use our own version
}
implementation("net.sf.jopt-simple:jopt-simple:5.0.3")
implementation("org.ow2.asm:asm-commons:$asmVersion")
implementation("cpw.mods:grossjava9hacks:1.3.3") {
exclude(group="org.apache.logging.log4j")
}
implementation("net.fabricmc:access-widener:1.0.2") {
exclude(group="org.apache.logging.log4j")
}
compileOnly("org.checkerframework:checker-qual:3.13.0")
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.forge.applaunch.service;
package org.spongepowered.transformers.modlauncher;

import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformationService;
Expand All @@ -38,7 +38,9 @@
import net.fabricmc.accesswidener.AccessWidenerVisitor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
Expand All @@ -55,17 +57,18 @@
import java.util.function.BiFunction;
import java.util.function.Supplier;

@DefaultQualifier(NonNull.class)
public class AccessWidenerTransformationService implements ITransformationService {

public static final String NAME = "access_widener";
public static final String ACCESS_WIDENER_EXTENSION = "accesswidener";
public static final Supplier<TypesafeMap.Key<AccessWidenerTransformationService>>
INSTANCE = IEnvironment.buildKey("sponge:aw", AccessWidenerTransformationService.class);
private static final Logger LOGGER = LogManager.getLogger();
static final Logger LOGGER = LogManager.getLogger();

private final AccessWidener widener = new AccessWidener();
private final AccessWidenerReader reader = new AccessWidenerReader(this.widener);
private OptionSpec<String> configSpec;
private @MonotonicNonNull OptionSpec<String> configSpec;

@NonNull
@Override
Expand Down
Loading

0 comments on commit ba81410

Please sign in to comment.