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 25, 2022
1 parent ad2af47 commit c43b095
Show file tree
Hide file tree
Showing 18 changed files with 301 additions and 258 deletions.
33 changes: 20 additions & 13 deletions forge/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,26 @@ extensions.configure(LoomGradleExtension::class) {
}

// Forge extra configurations
val forgeBootstrapLibrariesConfig = configurations.register("bootstrapLibraries")
val mlTransformersConfig = configurations.register("mltransformers")
val forgeLibrariesConfig = configurations.register("spongeLibraries") {
val forgeBootstrapLibrariesConfig: NamedDomainObjectProvider<Configuration> = configurations.register("bootstrapLibraries")
val mlTransformersConfig: NamedDomainObjectProvider<Configuration> = configurations.register("mltransformers")
val forgeLibrariesConfig: NamedDomainObjectProvider<Configuration> = configurations.register("spongeLibraries") {
extendsFrom(mlTransformersConfig.get())
}
val forgeAppLaunchConfig = configurations.register("applaunch") {
val forgeAppLaunchConfig: NamedDomainObjectProvider<Configuration> = configurations.register("applaunch") {
extendsFrom(forgeBootstrapLibrariesConfig.get())
extendsFrom(mlTransformersConfig.get())
extendsFrom(configurations.getByName("minecraftNamed"))
extendsFrom(configurations.getByName("loaderLibraries"))
}

// Common source sets and configurations
val launchConfig = commonProject.configurations.named("launch")
val accessors = commonProject.sourceSets.named("accessors")
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")
val launchConfig: NamedDomainObjectProvider<Configuration> = commonProject.configurations.named("launch")
val accessors: NamedDomainObjectProvider<SourceSet> = commonProject.sourceSets.named("accessors")
val launch: NamedDomainObjectProvider<SourceSet> = commonProject.sourceSets.named("launch")
val applaunch: NamedDomainObjectProvider<SourceSet> = commonProject.sourceSets.named("applaunch")
val mixins: NamedDomainObjectProvider<SourceSet> = commonProject.sourceSets.named("mixins")
val main: NamedDomainObjectProvider<SourceSet> = commonProject.sourceSets.named("main")
val mlTransformers: NamedDomainObjectProvider<SourceSet> = transformersProject.sourceSets.named("main")

// Forge source sets
val forgeMain by sourceSets.named("main") {
Expand Down Expand Up @@ -249,8 +249,8 @@ val forgeManifest = java.manifest {
System.getenv()["GIT_BRANCH"]?.apply { attributes("Git-Branch" to this) }
}

val mixinConfigs = spongeImpl.mixinConfigurations
val mods = extensions.getByType(LoomGradleExtension::class).unmappedModCollection
val mixinConfigs: MutableSet<String> = spongeImpl.mixinConfigurations
val mods: ConfigurableFileCollection = extensions.getByType(LoomGradleExtension::class).unmappedModCollection
tasks.withType(net.fabricmc.loom.task.AbstractRunTask::class) {
setClasspath(files(mods, sourceSets.main.get().runtimeClasspath, forgeAppLaunch.runtimeClasspath))
argumentProviders += CommandLineArgumentProvider {
Expand Down Expand Up @@ -392,6 +392,7 @@ tasks {
manifest {
attributes(mapOf(
"Access-Widener" to "common.accesswidener",
"Superclass-Transformer" to "common.superclasschange,forge.superclasschange",
"Multi-Release" to true,
"MixinConfigs" to mixinConfigs.joinToString(",")
))
Expand All @@ -403,11 +404,17 @@ tasks {
from(commonProject.sourceSets.named("launch").map {it.output })
from(commonProject.sourceSets.named("applaunch").map {it.output })
from(transformersProject.sourceSets.named("main").map { it.output })

// Pull dependencies from the mlTransformers project
from(mlTransformersConfig.get().files)

from(forgeAppLaunch.output)
from(forgeLaunch.output)
from(forgeAccessors.output)
from(forgeMixins.output)

// Make sure to relocate access widener so that we don't conflict with other
// coremods also using access widener
relocate("net.fabricmc.accesswidener", "org.spongepowered.forge.libs.accesswidener")
}

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,13 @@ 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");
scc.offerResource(ForgeProductionBootstrap.class.getResource("/forge.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
3 changes: 3 additions & 0 deletions forge/src/main/resources/forge.superclasschange
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"org.spongepowered.api.entity.ai.goal.AbstractGoal": "net.minecraft.entity.ai.goal.Goal"
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public abstract class MainMixin_Forge {

@Inject(method = "<clinit>", at = @At("RETURN"))
private static void forge$initLaunch(final CallbackInfo ci) {
if (Launch.instance() != null) {
return;
}
final PluginPlatform pluginPlatform = AppLaunch.pluginPlatform();
final ForgeLaunch launch = new ForgeLaunch(pluginPlatform);
Launch.setInstance(launch);
Expand Down
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
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 c43b095

Please sign in to comment.