Replace sound manager CT with mixin magic
This commit is contained in:
@@ -41,8 +41,7 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
|
|||||||
public String[] getASMTransformerClass() {
|
public String[] getASMTransformerClass() {
|
||||||
return new String[]{
|
return new String[]{
|
||||||
ForceChunkLoadingCT.class.getName(),
|
ForceChunkLoadingCT.class.getName(),
|
||||||
NoNameTagCT.class.getName(),
|
NoNameTagCT.class.getName()
|
||||||
SoundManagerCT.class.getName()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
package eu.crushedpixel.replaymod.coremod;
|
|
||||||
|
|
||||||
import net.minecraft.launchwrapper.IClassTransformer;
|
|
||||||
import org.objectweb.asm.ClassReader;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.tree.*;
|
|
||||||
|
|
||||||
import java.util.ListIterator;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
|
||||||
|
|
||||||
public class SoundManagerCT implements IClassTransformer {
|
|
||||||
|
|
||||||
private static final String REPLAY_HANDLER = "eu/crushedpixel/replaymod/replay/ReplayHandler";
|
|
||||||
private static final String CAMERA_ENTITY = "eu/crushedpixel/replaymod/entities/CameraEntity";
|
|
||||||
private static final String CLASS_NAME = "net.minecraft.client.audio.SoundManager";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] transform(String name, String transformedName, byte[] bytes) {
|
|
||||||
if (CLASS_NAME.equals(transformedName)) {
|
|
||||||
if (name.equals(transformedName)) {
|
|
||||||
return transform(bytes, "setListener", "(Lnet/minecraft/entity/player/EntityPlayer;F)V");
|
|
||||||
} else {
|
|
||||||
return transform(bytes, "a", "(Lahd;F)V");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] transform(byte[] bytes, String name_setListener, String desc_setListener) {
|
|
||||||
ClassReader classReader = new ClassReader(bytes);
|
|
||||||
ClassNode classNode = new ClassNode();
|
|
||||||
classReader.accept(classNode, 0);
|
|
||||||
|
|
||||||
boolean success = false;
|
|
||||||
for (MethodNode m : classNode.methods) {
|
|
||||||
if (desc_setListener.equals(m.desc) && name_setListener.equals(m.name)) {
|
|
||||||
ListIterator<AbstractInsnNode> iter = m.instructions.iterator();
|
|
||||||
inject(iter);
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!success) {
|
|
||||||
throw new NoSuchMethodError();
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
|
||||||
classNode.accept(classWriter);
|
|
||||||
return classWriter.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* public void setListener(EntityPlayer player, float partialTicks) {
|
|
||||||
* ...
|
|
||||||
* if (ReplayHandler.isInReplay()) {
|
|
||||||
* player = ReplayHandler.getCameraEntity();
|
|
||||||
* }
|
|
||||||
* ...
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
private void inject(ListIterator<AbstractInsnNode> iter) {
|
|
||||||
LabelNode l = new LabelNode();
|
|
||||||
iter.add(new MethodInsnNode(INVOKESTATIC, REPLAY_HANDLER, "isInReplay", "()Z", false));
|
|
||||||
iter.add(new JumpInsnNode(IFEQ, l));
|
|
||||||
iter.add(new MethodInsnNode(INVOKESTATIC, REPLAY_HANDLER, "getCameraEntity", "()L" + CAMERA_ENTITY + ";", false));
|
|
||||||
iter.add(new VarInsnNode(ASTORE, 1));
|
|
||||||
iter.add(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package eu.crushedpixel.replaymod.mixin;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.audio.SoundHandler;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(Minecraft.class)
|
||||||
|
public class MixinMinecraft {
|
||||||
|
@Redirect(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/audio/SoundHandler;setListener(Lnet/minecraft/entity/player/EntityPlayer;F)V"))
|
||||||
|
public void setSoundSystemListener(SoundHandler soundHandler, EntityPlayer listener, float renderPartialTicks) {
|
||||||
|
soundHandler.setListener(ReplayHandler.isInReplay() ? ReplayHandler.getCameraEntity() : listener, renderPartialTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinEffectRenderer",
|
"MixinEffectRenderer",
|
||||||
"MixinEntityRenderer",
|
"MixinEntityRenderer",
|
||||||
|
"MixinMinecraft",
|
||||||
"MixinRenderItem",
|
"MixinRenderItem",
|
||||||
"MixinRenderManager"
|
"MixinRenderManager"
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user