Dashloader: use ASM instead of wrapping the class
This commit is contained in:
parent
649ca78d6c
commit
b336a8cb36
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.respackopts;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.integration.dashloader.DashLoaderCompat;
|
||||
import io.gitlab.jfronny.respackopts.integration.DashLoaderCompat;
|
||||
import io.gitlab.jfronny.respackopts.data.entry.ConfigBranch;
|
||||
import io.gitlab.jfronny.respackopts.data.entry.ConfigEntry;
|
||||
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.gitlab.jfronny.respackopts;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.gitlab.jfronny.libjf.data.WrappedPack;
|
||||
import io.gitlab.jfronny.respackopts.integration.dashloader.DashLoaderCompat;
|
||||
import io.gitlab.jfronny.respackopts.data.DirRpo;
|
||||
import io.gitlab.jfronny.respackopts.data.PackCapability;
|
||||
import io.gitlab.jfronny.respackopts.data.Respackmeta;
|
||||
|
@ -54,8 +53,6 @@ public class Respackopts implements ClientModInitializer {
|
|||
|
||||
public static Starscript STAR_SCRIPT;
|
||||
|
||||
public static final Boolean DASHLOADER_PRESENT = FabricLoader.getInstance().isModLoaded("dashloader");
|
||||
|
||||
public static final Gson GSON;
|
||||
public static GuiFactory factory = new GuiFactory();
|
||||
public static boolean forceRespackReload = false;
|
||||
|
@ -101,7 +98,7 @@ public class Respackopts implements ClientModInitializer {
|
|||
} catch (IOException e) {
|
||||
LOGGER.error("Could not initialize config directory", e);
|
||||
}
|
||||
if (DASHLOADER_PRESENT) DashLoaderCompat.hookDashLoader();
|
||||
//if (DASHLOADER_PRESENT) DashLoaderCompat.hookDashLoader();
|
||||
if (FabricLoader.getInstance().isDevelopmentEnvironment())
|
||||
SAVE_ACTIONS.add(() -> LOGGER.info("Save"));
|
||||
SAVE_ACTIONS.add(() -> {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package io.gitlab.jfronny.respackopts.integration;
|
||||
|
||||
import net.oskarstrom.dashloader.util.enums.DashCachePaths;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class DashLoaderCompat {
|
||||
public static boolean forceReload = false;
|
||||
public static void injection() {
|
||||
if (DashLoaderCompat.forceReload)
|
||||
for (DashCachePaths value : DashCachePaths.values()) {
|
||||
try {
|
||||
Files.deleteIfExists(value.getPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
DashLoaderCompat.forceReload = false;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package io.gitlab.jfronny.respackopts.integration;
|
|||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import io.gitlab.jfronny.respackopts.integration.dashloader.DashLoaderCompat;
|
||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package io.gitlab.jfronny.respackopts.integration.dashloader;
|
||||
|
||||
import net.oskarstrom.dashloader.DashLoader;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class DashLoaderCompat {
|
||||
public static boolean forceReload = false;
|
||||
|
||||
public static void hookDashLoader() {
|
||||
try {
|
||||
Field instance = DashLoader.class.getDeclaredField("instance");
|
||||
instance.setAccessible(true);
|
||||
instance.set(null, new HackedDashLoader((DashLoader) instance.get(null)));
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package io.gitlab.jfronny.respackopts.integration.dashloader;
|
||||
|
||||
import net.oskarstrom.dashloader.DashLoader;
|
||||
import net.oskarstrom.dashloader.util.enums.DashCachePaths;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collection;
|
||||
|
||||
public class HackedDashLoader extends DashLoader {
|
||||
public HackedDashLoader(DashLoader previous) {
|
||||
super(previous.getAssignedClassLoader().getParent());
|
||||
initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(Collection<String> resourcePacks) {
|
||||
if (DashLoaderCompat.forceReload)
|
||||
for (DashCachePaths value : DashCachePaths.values()) {
|
||||
try {
|
||||
Files.deleteIfExists(value.getPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
super.reload(resourcePacks);
|
||||
DashLoaderCompat.forceReload = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package io.gitlab.jfronny.respackopts.mixin.dashloader;
|
||||
|
||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
import org.spongepowered.asm.mixin.transformer.FabricMixinTransformerProxy;
|
||||
import org.spongepowered.asm.transformers.MixinClassWriter;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class Plugin implements IMixinConfigPlugin {
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
if (FabricLoader.getInstance().isModLoaded("dashloader")) {
|
||||
try {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
Class<?> classLoaderClass = classLoader.getClass();
|
||||
|
||||
Field delegateField = classLoaderClass.getDeclaredField("delegate");
|
||||
delegateField.setAccessible(true);
|
||||
Object delegate = delegateField.get(classLoader);
|
||||
Class<?> delegateClass = delegate.getClass();
|
||||
|
||||
Field mixinTransformerField = delegateClass.getDeclaredField("mixinTransformer");
|
||||
mixinTransformerField.setAccessible(true);
|
||||
|
||||
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
|
||||
Transformer mixinTransformer = (Transformer) unsafe.allocateInstance(Transformer.class);
|
||||
mixinTransformer.delegate = (FabricMixinTransformerProxy) mixinTransformerField.get(delegate);
|
||||
|
||||
mixinTransformerField.set(delegate, mixinTransformer);
|
||||
} catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefMapperConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixins() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
|
||||
}
|
||||
|
||||
private static class Transformer extends FabricMixinTransformerProxy {
|
||||
private FabricMixinTransformerProxy delegate;
|
||||
|
||||
@Override
|
||||
public byte[] transformClassBytes(String name, String transformedName, byte[] basicClass) {
|
||||
basicClass = delegate.transformClassBytes(name, transformedName, basicClass);
|
||||
|
||||
if (name.equals("net.oskarstrom.dashloader.DashLoader")) {
|
||||
ClassNode klass = new ClassNode();
|
||||
ClassReader reader = new ClassReader(basicClass);
|
||||
reader.accept(klass, ClassReader.EXPAND_FRAMES);
|
||||
|
||||
boolean found = false;
|
||||
for (MethodNode method : klass.methods) {
|
||||
if (method.name.equals("reload")) {
|
||||
method.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/gitlab/jfronny/respackopts/integration/dashloader/DashLoaderCompat", "injection", "()V"));
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) Respackopts.LOGGER.error("Could not hack into dashloader");
|
||||
|
||||
ClassWriter writer = new MixinClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
klass.accept(writer);
|
||||
basicClass = writer.toByteArray();
|
||||
}
|
||||
|
||||
return basicClass;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,8 @@
|
|||
]
|
||||
},
|
||||
"mixins": [
|
||||
"respackopts.mixins.json"
|
||||
"respackopts.mixins.json",
|
||||
"respackotps.dashloader.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.10.8",
|
||||
|
|
14
src/main/resources/respackotps.dashloader.mixins.json
Normal file
14
src/main/resources/respackotps.dashloader.mixins.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "io.gitlab.jfronny.respackopts.mixin.dashloader",
|
||||
"plugin": "io.gitlab.jfronny.respackopts.mixin.dashloader.Plugin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user