Replace enchantment timer CT with mixin magic
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
package eu.crushedpixel.replaymod.coremod;
|
||||
|
||||
import akka.japi.Pair;
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class EnchantmentTimerCT implements IClassTransformer {
|
||||
|
||||
@Override
|
||||
public byte[] transform(String name, String transformedName,
|
||||
byte[] basicClass) {
|
||||
if(name.equals("cqh")) {
|
||||
return patchRenderEffectMethod(basicClass, true);
|
||||
}
|
||||
|
||||
if(name.equals("net.minecraft.client.renderer.entity.RenderItem")) {
|
||||
return patchRenderEffectMethod(basicClass, false);
|
||||
}
|
||||
|
||||
return basicClass;
|
||||
}
|
||||
|
||||
public byte[] patchRenderEffectMethod(byte[] bytes, boolean obfuscated) {
|
||||
System.out.println("REPLAY MOD CORE PATCHER: Inside RenderItem class");
|
||||
|
||||
String methodName = obfuscated ? "a" : "renderEffect";
|
||||
String classDescriptor = obfuscated ? "(Lcxe;)V" : "(Lnet/minecraft/client/resources/model/IBakedModel;)V";
|
||||
|
||||
String minecraftClass = obfuscated ? "bsu" : "net/minecraft/client/Minecraft";
|
||||
String getSystemTime = obfuscated ? "I" : "getSystemTime";
|
||||
String sysTimeDesc = "()J";
|
||||
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
List<Pair<AbstractInsnNode, AbstractInsnNode>> toInsert = new ArrayList<Pair<AbstractInsnNode, AbstractInsnNode>>();
|
||||
|
||||
for (MethodNode m : classNode.methods) {
|
||||
if (m.name.equals(methodName) && m.desc.equals(classDescriptor)) {
|
||||
System.out.println("REPLAY MOD CORE PATCHER: Inside renderEffect method");
|
||||
|
||||
Iterator<AbstractInsnNode> nodeIterator = m.instructions.iterator();
|
||||
while (nodeIterator.hasNext()) {
|
||||
AbstractInsnNode node = nodeIterator.next();
|
||||
if (node instanceof MethodInsnNode) {
|
||||
MethodInsnNode min = (MethodInsnNode) node;
|
||||
if (min.getOpcode() == Opcodes.INVOKESTATIC && min.name.equals(getSystemTime) &&
|
||||
min.owner.equals(minecraftClass) && min.desc.equals(sysTimeDesc)) {
|
||||
MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
"eu/crushedpixel/replaymod/timer/EnchantmentTimer", "getEnchantmentTime",
|
||||
min.desc, min.itf);
|
||||
toInsert.add(new Pair<AbstractInsnNode, AbstractInsnNode>(min, n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<AbstractInsnNode, AbstractInsnNode> pair : toInsert) {
|
||||
m.instructions.insertBefore(pair.first(), pair.second());
|
||||
m.instructions.remove(pair.first());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
// net.minecraft.client.renderer.entity.RenderItem -> cqh
|
||||
// private void renderEffect(IBakedModel model) -> private void a(cxe paramcxe)
|
||||
// float f = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F; -> float f1 = (float)(bsu.I() % 3000L) / 3000.0F / 8.0F;
|
||||
}
|
||||
@@ -42,8 +42,7 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
|
||||
return new String[]{
|
||||
ForceChunkLoadingCT.class.getName(),
|
||||
NoNameTagCT.class.getName(),
|
||||
SoundManagerCT.class.getName(),
|
||||
EnchantmentTimerCT.class.getName()
|
||||
SoundManagerCT.class.getName()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.timer.EnchantmentTimer;
|
||||
import net.minecraft.client.renderer.entity.RenderItem;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(RenderItem.class)
|
||||
public class MixinRenderItem {
|
||||
@Redirect(method = "renderEffect", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;getSystemTime()J"))
|
||||
private long getEnchantmentTime() {
|
||||
return EnchantmentTimer.getEnchantmentTime();
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ public class EnchantmentTimer {
|
||||
recordingTime += amount;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // Called by ASM
|
||||
public static long getEnchantmentTime() {
|
||||
if(!(ReplayHandler.isInPath() && ReplayProcess.isVideoRecording())) {
|
||||
if(ReplayHandler.isInReplay()) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"mixins": [
|
||||
"MixinEffectRenderer",
|
||||
"MixinEntityRenderer",
|
||||
"MixinRenderItem",
|
||||
"MixinRenderManager"
|
||||
],
|
||||
"server": [],
|
||||
|
||||
Reference in New Issue
Block a user