Skip to content

Commit

Permalink
Develop beta 40 (#908)
Browse files Browse the repository at this point in the history
  • Loading branch information
Su5eD authored Mar 23, 2024
2 parents fc0a4c2 + 1e3aa59 commit e40dcef
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 86 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v3
with:
dependency-graph: generate-and-submit
gradle-home-cache-cleanup: true
gradle-home-cache-excludes: |
gradle.properties
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,23 @@ jobs:
matrix:
include:
- name: Maven
environment: maven
task: publish
url: https://maven.su5ed.dev/releases/dev/su5ed/sinytra/Connector
- name: GitHub
environment: github
task: publishGithub
url: https://github.com/Sinytra/Connector/releases
- name: CurseForge
environment: curseforge
task: publishCurseforge
url: https://www.curseforge.com/minecraft/mc-mods/sinytra-connector
- name: Modrinth
environment: modrinth
task: publishModrinth
url: https://modrinth.com/mod/connector
name: Publish ${{ matrix.name }}
needs: build
runs-on: ubuntu-22.04
environment: ${{ matrix.environment }}
environment:
name: ${{ matrix.name }}
url: ${{ matrix.url }}
steps:
- uses: actions/checkout@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ dependencies {
shade(group = "org.ow2.sat4j", name = "org.ow2.sat4j.pb", version = "2.3.6")
shade(group = "net.minecraftforge", name = "srgutils", version = "0.5.4")
shade(group = "net.fabricmc", name = "access-widener", version = versionAccessWidener)
shade(group = "dev.su5ed.sinytra", name = "ForgeAutoRenamingTool", version = versionForgeAutoRenamingTool)
shade(group = "org.sinytra", name = "ForgeAutoRenamingTool", version = versionForgeAutoRenamingTool)
shade(group = "org.sinytra.adapter", name = "definition", version = versionAdapterDefinition) { isTransitive = false }
shade(group = "io.github.steelwoolmc", name = "mixin-transmogrifier", version = versionMixinTransmog)
adapterData(group = "org.sinytra.adapter", name = "adapter", version = versionAdapter)
Expand Down
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=true

# Versions
versionConnector=1.0.0-beta.39
versionAdapter=1.11.30-1.20.1-20240308.152751
versionAdapterDefinition=1.11.30
versionConnector=1.0.0-beta.40
versionAdapter=1.11.32-1.20.1-20240314.234555
versionAdapterDefinition=1.11.34

versionMc=1.20.1
versionForge=47.1.3
versionForgeAutoRenamingTool=1.0.9
versionFabricLoader=2.7.1+0.15.3+1.20.1
versionForgeAutoRenamingTool=1.0.11
versionFabricLoader=2.7.2+0.15.3+1.20.1
versionAccessWidener=2.1.0
versionFabricApi=0.92.0+1.11.2+1.20.1
versionMixin=0.12.5+mixin.0.8.5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public static void removeAliasedModDependencyConstraints(LoaderModMetadata metad
.map(dep -> {
// Aliased mods typically don't follow the same version convention as the original,
// therefore we must widen all dependency constraints to wildcards
if (aliases.values().contains(dep.getModId())) {
if (aliases.keys().contains(dep.getModId()) || aliases.values().contains(dep.getModId())) {
return dep.getKind() == ModDependency.Kind.BREAKS ? null : uncheck(() -> new ModDependencyImpl(dep.getKind(), dep.getModId(), List.of("*")));
}
return dep;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.sinytra.adapter.patch.api.MixinClassGenerator;
import org.sinytra.adapter.patch.api.MixinConstants;
import org.sinytra.adapter.patch.api.Patch;
import org.sinytra.adapter.patch.api.PatchContext;
import org.sinytra.adapter.patch.api.PatchEnvironment;
import org.sinytra.adapter.patch.fixes.FieldTypePatchTransformer;
import org.sinytra.adapter.patch.fixes.FieldTypeUsageTransformer;
Expand Down Expand Up @@ -224,6 +225,11 @@ public ClassEntry process(ClassEntry entry) {
patchResult = patchResult.or(patch.apply(node, this.environment));
}
}
else {
for (ClassTransform transform : CLASS_TRANSFORMS) {
patchResult = patchResult.or(transform.apply(node, null, PatchContext.create(node, List.of(), this.environment)));
}
}

// TODO if a mixin method is extracted, roll back the status from compute frames to apply,
// Alternatively, change the order of patches so that extractmixin comes first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ public static List<Patch> getPatches() {
.modifyMethodAccess(new ModifyMethodAccess.AccessChange(false, Opcodes.ACC_STATIC))
.extractMixin("net/minecraftforge/common/extensions/IForgeBlockState")
.build(),
Patch.builder()
.targetClass("net/minecraft/client/multiplayer/MultiPlayerGameMode")
.targetMethod("m_105267_")
.targetInjectionPoint("Lnet/minecraft/world/level/block/Block;m_5707_(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/player/Player;)V")
.modifyInjectionPoint("Lnet/minecraft/world/level/block/state/BlockState;onDestroyedByPlayer(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;ZLnet/minecraft/world/level/material/FluidState;)Z")
.build(),
Patch.builder()
.targetClass("net/minecraft/world/level/block/FarmBlock")
.targetMethod("m_53258_(Lnet/minecraft/world/level/LevelReader;Lnet/minecraft/core/BlockPos;)Z")
.targetInjectionPoint("Lnet/minecraft/world/level/material/FluidState;m_205070_(Lnet/minecraft/tags/TagKey;)Z")
.modifyInjectionPoint("Lnet/minecraft/world/level/block/state/BlockState;canBeHydrated(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/material/FluidState;Lnet/minecraft/core/BlockPos;)Z")
.build(),
Patch.builder()
.targetClass("net/minecraft/world/entity/LivingEntity")
.targetMethod("m_6075_")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.SourceInterpreter;
import org.objectweb.asm.tree.analysis.SourceValue;
import org.sinytra.adapter.patch.analysis.MethodCallAnalyzer;
import org.sinytra.adapter.patch.selector.AnnotationHandle;
import org.sinytra.adapter.patch.util.MethodQualifier;

Expand All @@ -47,19 +43,14 @@ public final class OptimizedRenamingTransformer extends RenamingTransformer {
private static final String CLASS_DESC_PATTERN = "^L[a-zA-Z0-9/$_]+;$";
private static final String FQN_CLASS_NAME_PATTERN = "^([a-zA-Z0-9$_]+\\.)*[a-zA-Z0-9$_]+$";

private final SourceInterpreter reflectionRemapper;

public static Transformer create(ClassProvider classProvider, Consumer<String> log, IMappingFile mappingFile, IntermediateMapping flatMappings) {
IntermediaryClassProvider reverseProvider = new IntermediaryClassProvider(classProvider, mappingFile, mappingFile.reverse(), log);
EnhancedRemapper enhancedRemapper = new MixinAwareEnhancedRemapper(reverseProvider, mappingFile, flatMappings, log);
SourceInterpreter reflectionRemapper = new ReflectionRemapperInterpreter(Opcodes.ASM9, mappingFile, flatMappings);
return new OptimizedRenamingTransformer(enhancedRemapper, false, reflectionRemapper);
return new OptimizedRenamingTransformer(enhancedRemapper, false);
}

public OptimizedRenamingTransformer(EnhancedRemapper remapper, boolean collectAbstractParams, SourceInterpreter reflectionRemapper) {
public OptimizedRenamingTransformer(EnhancedRemapper remapper, boolean collectAbstractParams) {
super(remapper, collectAbstractParams);

this.reflectionRemapper = reflectionRemapper;
}

@Override
Expand Down Expand Up @@ -95,8 +86,6 @@ protected void postProcess(ClassNode node) {
}
}
}

MethodCallAnalyzer.analyzeInterpretMethod(method, this.reflectionRemapper);
}
for (FieldNode field : node.fields) {
field.value = postProcessRemapper.mapValue(field.value);
Expand Down Expand Up @@ -270,62 +259,6 @@ public String mapPackageName(String name) {
}
}

private static class ReflectionRemapperInterpreter extends SourceInterpreter {
private static final Type STR_TYPE = Type.getType(String.class);

private final Collection<MethodInsnNode> seen = new HashSet<>();
private final IMappingFile mappings;
private final IntermediateMapping fastMappings;

public ReflectionRemapperInterpreter(int api, IMappingFile mappings, IntermediateMapping fastMappings) {
super(api);
this.mappings = mappings;
this.fastMappings = fastMappings;
}

@Override
public SourceValue naryOperation(AbstractInsnNode insn, List<? extends SourceValue> values) {
if (insn instanceof MethodInsnNode methodInsn && !this.seen.contains(methodInsn)) {
this.seen.add(methodInsn);
// Try to remap reflection method call args
Type[] args = Type.getArgumentTypes(methodInsn.desc);
if (args.length >= 3 && STR_TYPE.equals(args[0]) && STR_TYPE.equals(args[1]) && STR_TYPE.equals(args[2]) && values.size() >= 3) {
LdcInsnNode ownerInsn = getSingleLDCString(values.get(0));
LdcInsnNode nameInsn = getSingleLDCString(values.get(1));
LdcInsnNode descInsn = getSingleLDCString(values.get(2));
if (ownerInsn != null && nameInsn != null && descInsn != null) {
String owner = (String) ownerInsn.cst;
IMappingFile.IClass cls = this.mappings.getClass(owner.replace('.', '/'));
if (cls != null) {
String name = (String) nameInsn.cst;
String desc = (String) descInsn.cst;
IMappingFile.IMethod mtd = cls.getMethod(name, desc);
if (mtd != null) {
ownerInsn.cst = owner.contains(".") ? cls.getMapped().replace('/', '.') : cls.getMapped();
nameInsn.cst = mtd.getMapped();
descInsn.cst = mtd.getMappedDescriptor();
}
else {
String mappedName = this.fastMappings.mapMethod(name, desc);
if (mappedName != null) {
ownerInsn.cst = owner.contains(".") ? cls.getMapped().replace('/', '.') : cls.getMapped();
nameInsn.cst = mappedName;
descInsn.cst = this.mappings.remapDescriptor(desc);
}
}
}
}
}
}
return super.naryOperation(insn, values);
}

@Nullable
private static LdcInsnNode getSingleLDCString(SourceValue value) {
return value.insns.size() == 1 && value.insns.iterator().next() instanceof LdcInsnNode ldc && ldc.cst instanceof String ? ldc : null;
}
}

private static class MixinTargetAnalyzer extends ClassVisitor {
private final Set<String> targets = new HashSet<>();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package dev.su5ed.sinytra.connector.transformer.jar;

import com.mojang.logging.LogUtils;
import cpw.mods.modlauncher.ClassTransformer;
import cpw.mods.modlauncher.LaunchPluginHandler;
import cpw.mods.modlauncher.TransformStore;
import cpw.mods.modlauncher.TransformationServiceDecorator;
import cpw.mods.modlauncher.TransformingClassLoader;
import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformationService;
import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.ITransformerActivity;
import net.minecraftforge.coremod.CoreModProvider;
import net.minecraftforge.fart.api.ClassProvider;
import net.minecraftforge.fml.loading.moddiscovery.CoreModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileParser;
import net.minecraftforge.fml.unsafe.UnsafeHacks;
import net.minecraftforge.forgespi.locating.IModFile;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck;

public class EarlyJSCoremodTransformer implements ClassProvider {
private static final MethodHandle GET_CORE_MODS = uncheck(() -> MethodHandles.privateLookupIn(ModFileParser.class, MethodHandles.lookup()).findStatic(ModFileParser.class, "getCoreMods", MethodType.methodType(List.class, ModFile.class)));
private static final MethodHandle TRANSFORM = uncheck(() -> MethodHandles.privateLookupIn(ClassTransformer.class, MethodHandles.lookup()).findVirtual(ClassTransformer.class, "transform", MethodType.methodType(byte[].class, byte[].class, String.class, String.class)));
private static final Logger LOGGER = LogUtils.getLogger();

private final ClassProvider provider;
private final ClassTransformer transformer;

public static EarlyJSCoremodTransformer create(ClassProvider classProvider, Iterable<IModFile> loadedMods) {
try {
CoreModProvider provider = new CoreModProvider();
for (IModFile mf : loadedMods) {
List<CoreModFile> list = (List<CoreModFile>) GET_CORE_MODS.invoke((ModFile) mf);
if (!list.isEmpty()) {
for (CoreModFile f : list) {
provider.addCoreMod(f);
}
}
}
List<ITransformer<?>> transformers = provider.getCoreModTransformers();

TransformStore transformStore = new TransformStore();
ITransformationService service = new DummyService(transformers);

Constructor<TransformationServiceDecorator> cst = TransformationServiceDecorator.class.getDeclaredConstructor(ITransformationService.class);
cst.setAccessible(true);
TransformationServiceDecorator decorator = cst.newInstance(service);
decorator.gatherTransformers(transformStore);

LaunchPluginHandler plugins = UnsafeHacks.newInstance(LaunchPluginHandler.class);
Field pluginsField = LaunchPluginHandler.class.getDeclaredField("plugins");
pluginsField.setAccessible(true);
pluginsField.set(plugins, new HashMap<>());

Constructor<ClassTransformer> xformCst = ClassTransformer.class.getDeclaredConstructor(TransformStore.class, LaunchPluginHandler.class, TransformingClassLoader.class);
xformCst.setAccessible(true);
ClassTransformer classTransformer = xformCst.newInstance(transformStore, plugins, null);
return new EarlyJSCoremodTransformer(classProvider, classTransformer);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}

public EarlyJSCoremodTransformer(ClassProvider provider, ClassTransformer transformer) {
this.provider = provider;
this.transformer = transformer;
}

@Override
public Optional<? extends IClassInfo> getClass(String s) {
return this.provider.getClass(s);
}

@Override
public Optional<byte[]> getClassBytes(String s) {
return this.provider.getClassBytes(s)
.map(bytes -> {
try {
return (byte[]) TRANSFORM.invoke(this.transformer, bytes, s, ITransformerActivity.COMPUTING_FRAMES_REASON);
} catch (Throwable t) {
LOGGER.error("Error transforming class " + s, t);
return bytes;
}
});
}

@Override
public void close() throws IOException {
this.provider.close();
}

@SuppressWarnings("rawtypes")
private record DummyService(List transformers) implements ITransformationService {
@Override
@NotNull
public String name() {
return "connector_early_js_coremods";
}

@Override
public void initialize(IEnvironment environment) {}

@Override
public void onLoad(IEnvironment env, Set<String> otherServices) {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.gson.JsonElement;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.JsonOps;
import dev.su5ed.sinytra.connector.transformer.patch.ReflectionRenamingTransformer;
import org.sinytra.adapter.patch.LVTOffsets;
import org.sinytra.adapter.patch.api.GlobalReferenceMapper;
import org.sinytra.adapter.patch.api.Patch;
Expand Down Expand Up @@ -120,6 +121,7 @@ public void transformJar(File input, Path output, FabricModFileMetadata metadata
MappingResolverImpl resolver = FabricLoaderImpl.INSTANCE.getMappingResolver();
RefmapRemapper.RefmapFiles refmap = RefmapRemapper.processRefmaps(input.toPath(), metadata.refmaps(), this.remapper, this.libs);
IMappingFile srgToIntermediary = resolver.getMap(OBF_NAMESPACE, SOURCE_NAMESPACE);
IMappingFile intermediaryToSrg = resolver.getCurrentMap(SOURCE_NAMESPACE);
AccessorRedirectTransformer accessorRedirectTransformer = new AccessorRedirectTransformer(srgToIntermediary);

List<Patch> extraPatches = Stream.concat(this.adapterPatches.stream(), AccessorRedirectTransformer.PATCHES.stream()).toList();
Expand All @@ -132,15 +134,17 @@ public void transformJar(File input, Path output, FabricModFileMetadata metadata
.add(new JarSignatureStripper())
.add(new ClassNodeTransformer(
new FieldToMethodTransformer(metadata.modMetadata().getAccessWidener(), srgToIntermediary),
accessorRedirectTransformer
accessorRedirectTransformer,
new ReflectionRenamingTransformer(intermediaryToSrg, IntermediateMapping.get(SOURCE_NAMESPACE))
))
.add(this.remappingTransformer)
.add(new ClassNodeTransformer(new ClassAnalysingTransformer()))
.add(patchTransformer)
.add(refmapRemapper)
.add(new ModMetadataGenerator(metadata.modMetadata().getId()))
.logger(s -> LOGGER.trace(TRANSFORM_MARKER, s))
.debug(s -> LOGGER.trace(TRANSFORM_MARKER, s));
.debug(s -> LOGGER.trace(TRANSFORM_MARKER, s))
.ignoreJarPathPrefix("assets/", "data/");
if (!metadata.containsAT()) {
builder.add(new AccessWidenerTransformer(metadata.modMetadata().getAccessWidener(), resolver, IntermediateMapping.get(SOURCE_NAMESPACE)));
}
Expand Down
Loading

0 comments on commit e40dcef

Please sign in to comment.