diff options
Diffstat (limited to 'src/main/java')
14 files changed, 528 insertions, 145 deletions
| diff --git a/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java b/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java index 8158b97..75a0a5e 100644 --- a/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java +++ b/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java @@ -8,6 +8,7 @@ import net.minecraft.client.settings.KeyBinding;  import net.minecraftforge.client.ClientCommandHandler;  import net.minecraftforge.client.event.GuiOpenEvent;  import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.WorldEvent;  import net.minecraftforge.fml.client.registry.ClientRegistry;  import net.minecraftforge.fml.common.Mod;  import net.minecraftforge.fml.common.event.FMLInitializationEvent; @@ -23,7 +24,7 @@ import org.lwjgl.opengl.Display;  import java.io.File; -@Mod(modid = "djperspectivemod", name = "Perspective Mod v4", version = "4.0", acceptedMinecraftVersions = "[1.8.9]", clientSideOnly = true) +@Mod(modid = "djperspectivemod", name = "Perspective Mod v4", version = "4.1", acceptedMinecraftVersions = "[1.8.9]", clientSideOnly = true)  public class PerspectiveMod {      private static final Minecraft mc = Minecraft.getMinecraft(); @@ -68,7 +69,14 @@ public class PerspectiveMod {      @SubscribeEvent      public void onGuiOpen(GuiOpenEvent event) { -        if(event.gui != null) { +        if (event.gui != null && perspectiveToggled && config.holdMode) { +            resetPerspective(); +        } +    } + +    @SubscribeEvent +    public void onWorldLoad(WorldEvent.Load event) { +        if (perspectiveToggled) {              resetPerspective();          }      } diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java new file mode 100644 index 0000000..63f693e --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java @@ -0,0 +1,116 @@ +package me.djtheredstoner.perspectivemod.asm; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import me.djtheredstoner.perspectivemod.asm.transformers.EntityRendererTransformer; +import me.djtheredstoner.perspectivemod.asm.transformers.MinecraftTransformer; +import me.djtheredstoner.perspectivemod.asm.transformers.RenderManagerTransformer; +import net.minecraft.launchwrapper.IClassTransformer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collection; + +public class ClassTransformer implements IClassTransformer { + +    // create a logger to distinguish our errors from a normal error +    private static final Logger LOGGER = LogManager.getLogger("Perspective Mod v4 Transformer"); + +    // create a map of transformers +    private final Multimap<String, ITransformer> transformerMap = ArrayListMultimap.create(); + +    // make a jvm flag that could be used to dump transformed classes +    // usable by adding -DdebugBytecode=true to the jvm arguments +    public static final boolean outputBytecode = Boolean.parseBoolean(System.getProperty("debugBytecode", "false")); + +    public ClassTransformer() { +        // any transformer will be registered here +        registerTransformer(new EntityRendererTransformer()); +        registerTransformer(new RenderManagerTransformer()); +        registerTransformer(new MinecraftTransformer()); +    } + +    private void registerTransformer(ITransformer transformer) { +        // loop through names of classes +        for (String cls : transformer.getClassName()) { +            // put the classes into the transformer map +            transformerMap.put(cls, transformer); +        } +    } + +    @SuppressWarnings("ResultOfMethodCallIgnored") +    @Override +    public byte[] transform(String name, String transformedName, byte[] bytes) { +        if (bytes == null) return null; + +        // get the list of transformers +        Collection<ITransformer> transformers = transformerMap.get(transformedName); +        // if empty, don't bother trying to run through transformation +        if (transformers.isEmpty()) return bytes; + +        // wjat +        ClassReader reader = new ClassReader(bytes); +        ClassNode node = new ClassNode(); +        reader.accept(node, ClassReader.EXPAND_FRAMES); + +        // for every transformer, perform the transformations +        for (ITransformer transformer : transformers) { +            transformer.transform(node, transformedName); +        } + +        // what????? +        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + +        try { +            // write™ +            node.accept(writer); +        } catch (Throwable t) { +            LOGGER.error("Exception when transforming " + transformedName + " : " + t.getClass().getSimpleName()); +            t.printStackTrace(); +        } + +        if (outputBytecode) { +            File bytecodeDirectory = new File("bytecode"); +            String transformedClassName; + +            // anonymous classes +            if (transformedName.contains("$")) { +                transformedClassName = transformedName.replace('$', '.') + ".class"; +            } else { +                transformedClassName = transformedName + ".class"; +            } + +            if (!bytecodeDirectory.exists()) { +                bytecodeDirectory.mkdirs(); +            } + +            File bytecodeOutput = new File(bytecodeDirectory, transformedClassName); + +            try { +                if (!bytecodeOutput.exists()) { +                    bytecodeOutput.createNewFile(); +                } +            } catch (Exception e) { +                e.printStackTrace(); +            } + +            try (FileOutputStream os = new FileOutputStream(bytecodeOutput)) { +                // write to the generated class to /run/bytecode/classfile.class +                // with the class bytes from transforming +                os.write(writer.toByteArray()); +            } catch (IOException e) { +                e.printStackTrace(); +            } +        } + +        // return the written bytes and finalize transform +        return writer.toByteArray(); +    } + +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/ITransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/ITransformer.java new file mode 100644 index 0000000..9ef82be --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/ITransformer.java @@ -0,0 +1,98 @@ +package me.djtheredstoner.perspectivemod.asm; + +import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; +import org.objectweb.asm.tree.*; + +public interface ITransformer { + +    /** +     * The class name that's being transformed +     * +     * @return the class name +     */ +    String[] getClassName(); + +    /** +     * Perform any asm in order to transform code +     * +     * @param classNode the transformed class node +     * @param name      the transformed class name +     */ +    void transform(ClassNode classNode, String name); + +    /** +     * Map the method name from notch names +     * +     * @param classNode  the transformed class node +     * @param methodNode the transformed classes method node +     * @return a mapped method name +     */ +    default String mapMethodName(ClassNode classNode, MethodNode methodNode) { +        return FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(classNode.name, methodNode.name, methodNode.desc); +    } + +    /** +     * Map the field name from notch names +     * +     * @param classNode the transformed class node +     * @param fieldNode the transformed classes field node +     * @return a mapped field name +     */ +    default String mapFieldName(ClassNode classNode, FieldNode fieldNode) { +        return FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(classNode.name, fieldNode.name, fieldNode.desc); +    } + +    /** +     * Map the method desc from notch names +     * +     * @param methodNode the transformed method node +     * @return a mapped method desc +     */ +    default String mapMethodDesc(MethodNode methodNode) { +        return FMLDeobfuscatingRemapper.INSTANCE.mapMethodDesc(methodNode.desc); +    } + +    /** +     * Map the method name from notch names +     * +     * @param methodInsnNode the transformed method insn node +     * @return a mapped insn method +     */ +    default String mapMethodNameFromNode(MethodInsnNode methodInsnNode) { +        return FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(methodInsnNode.owner, methodInsnNode.name, methodInsnNode.desc); +    } + +    /** +     * Map the field name from notch names +     * +     * @param fieldInsnNode the transformed field insn node +     * @return a mapped insn field +     */ +    default String mapFieldNameFromNode(FieldInsnNode fieldInsnNode) { +        return FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(fieldInsnNode.owner, fieldInsnNode.name, fieldInsnNode.desc); +    } + +    default String mapClassName(String name) { +        return FMLDeobfuscatingRemapper.INSTANCE.mapType(name); +    } + +    /** +     * Remove instructions to this method +     * +     * @param methodNode the method being cleared +     */ +    default void clearInstructions(MethodNode methodNode) { +        methodNode.instructions.clear(); + +        // dont waste time clearing local variables if they're empty +        if (!methodNode.localVariables.isEmpty()) { +            methodNode.localVariables.clear(); +        } + +        // dont waste time clearing try-catches if they're empty +        if (!methodNode.tryCatchBlocks.isEmpty()) { +            methodNode.tryCatchBlocks.clear(); +        } +    } + +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java new file mode 100644 index 0000000..3ee3c9e --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java @@ -0,0 +1,29 @@ +package me.djtheredstoner.perspectivemod.asm.hooks; + +import me.djtheredstoner.perspectivemod.PerspectiveMod; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; + +public class EntityRendererHook { + +    public static float rotationYawHook(Entity entity) { +        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : entity.rotationYaw; +    } + +    public static float prevRotationYawHook(Entity entity) { +        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : entity.prevRotationYaw; +    } + +    public static float rotationPitchHook(Entity entity) { +        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : entity.rotationPitch; +    } + +    public static float prevRotationPitchHook(Entity entity) { +        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : entity.prevRotationPitch; +    } + +    public static boolean mouseHook(Minecraft minecraft) { +        return PerspectiveMod.overrideMouse(); +    } + +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/MinecraftHook.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/MinecraftHook.java new file mode 100644 index 0000000..e502232 --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/MinecraftHook.java @@ -0,0 +1,16 @@ +package me.djtheredstoner.perspectivemod.asm.hooks; + +import me.djtheredstoner.perspectivemod.PerspectiveMod; +import net.minecraft.client.settings.GameSettings; + +public class MinecraftHook { + +    public static void thirdPersonHook(GameSettings gameSettings, int value) { +        if(PerspectiveMod.perspectiveToggled) { +            PerspectiveMod.resetPerspective(); +        } else { +            gameSettings.thirdPersonView = value; +        } +    } + +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/RenderManagerHook.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/RenderManagerHook.java new file mode 100644 index 0000000..3373378 --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/RenderManagerHook.java @@ -0,0 +1,15 @@ +package me.djtheredstoner.perspectivemod.asm.hooks; + +import me.djtheredstoner.perspectivemod.PerspectiveMod; +import net.minecraft.client.renderer.entity.RenderManager; + +public class RenderManagerHook { + +    public static void playerViewXHook(RenderManager renderManager, float value) { +        renderManager.playerViewX = PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : value; +    } + +    public static void playerViewYHook(RenderManager renderManager, float value) { +        renderManager.playerViewY = PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : value; +    } +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java new file mode 100644 index 0000000..dadb1e0 --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java @@ -0,0 +1,110 @@ +package me.djtheredstoner.perspectivemod.asm.transformers; + +import me.djtheredstoner.perspectivemod.asm.ITransformer; +import org.objectweb.asm.tree.*; + +import java.util.Iterator; + +import static org.objectweb.asm.Opcodes.*; + +/** + * @see net.minecraft.client.renderer.EntityRenderer + */ +public class EntityRendererTransformer implements ITransformer { + +    private static final String HOOK_CLASS = "me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook"; + +    @Override +    public String[] getClassName() { +        return new String[]{"net.minecraft.client.renderer.EntityRenderer"}; +    } + +    @Override +    public void transform(ClassNode classNode, String name) { +        for (MethodNode method : classNode.methods) { +            String methodName = mapMethodName(classNode, method); + +            if (methodName.equals("orientCamera") || methodName.equals("func_78467_g")) { + +                Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); + +                while (iterator.hasNext()) { +                    AbstractInsnNode next = iterator.next(); + +                    if(next.getOpcode() == GETFIELD) { +                        FieldInsnNode insn = (FieldInsnNode)next; + +                        String ownerName = mapClassName(insn.owner); +                        String fieldName = mapFieldNameFromNode(insn); + +                        if(ownerName.equals("net/minecraft/entity/Entity" )&& insn.desc.equals("F")) { + +                            InsnList insnList = null; + +                            switch (fieldName) { +                                case "rotationYaw": +                                case "field_70177_z": +                                    insnList = insertRotationHook("rotationYaw"); +                                    break; +                                case "prevRotationYaw": +                                case "field_70126_B": +                                    insnList = insertRotationHook("prevRotationYaw"); +                                    break; +                                case "rotationPitch": +                                case "field_70125_A": +                                    insnList = insertRotationHook("rotationPitch"); +                                    break; +                                case "prevRotationPitch": +                                case "field_70127_C": +                                    insnList = insertRotationHook("prevRotationPitch"); +                                    break; +                            } + +                            if(insnList != null) { +                                method.instructions.insertBefore(insn, insnList); +                                method.instructions.remove(insn); +                            } +                        } +                    } +                } + +            } else if (methodName.equals("updateCameraAndRender") || methodName.equals("func_181560_a")) { + +                Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); + +                while (iterator.hasNext()) { +                    AbstractInsnNode next = iterator.next(); + +                    if(next.getOpcode() == GETFIELD) { +                        FieldInsnNode insn = (FieldInsnNode)next; + +                        String ownerName = mapClassName(insn.owner); +                        String fieldName = mapFieldNameFromNode(insn); + +                        if(ownerName.equals("net/minecraft/client/Minecraft") && (fieldName.equals("inGameHasFocus") || fieldName.equals("field_71415_G")) && insn.desc.equals("Z") +                                && insn.getNext().getNext().getNext().getOpcode() == IFEQ) { +                            method.instructions.insertBefore(insn, insertMouseHook()); +                            method.instructions.remove(insn); +                        } +                    } +                } +            } +        } +    } + +    public InsnList insertRotationHook(String field) { +        InsnList list = new InsnList(); + +        list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, field + "Hook", "(Lnet/minecraft/entity/Entity;)F", false)); + +        return list; +    } + +    public InsnList insertMouseHook() { +        InsnList list = new InsnList(); + +        list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "mouseHook", "(Lnet/minecraft/client/Minecraft;)Z", false)); + +        return list; +    } +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/MinecraftTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/MinecraftTransformer.java new file mode 100644 index 0000000..2a98619 --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/MinecraftTransformer.java @@ -0,0 +1,56 @@ +package me.djtheredstoner.perspectivemod.asm.transformers; + +import me.djtheredstoner.perspectivemod.asm.ITransformer; +import org.objectweb.asm.tree.*; + +import java.util.Iterator; + +import static org.objectweb.asm.Opcodes.*; + +/** + * @see net.minecraft.client.Minecraft + */ +public class MinecraftTransformer implements ITransformer { + +    private static final String HOOK_CLASS = "me/djtheredstoner/perspectivemod/asm/hooks/MinecraftHook"; + +    @Override +    public String[] getClassName() { +        return new String[]{"net.minecraft.client.Minecraft"}; +    } + +    @Override +    public void transform(ClassNode classNode, String name) { +        for (MethodNode method : classNode.methods) { +            String methodName = mapMethodName(classNode, method); + +            if (methodName.equals("runTick") || methodName.equals("func_71407_l")) { +                Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); + +                while (iterator.hasNext()) { +                    AbstractInsnNode next = iterator.next(); + +                    if (next.getOpcode() == PUTFIELD) { +                        FieldInsnNode insn = (FieldInsnNode) next; + +                        String ownerName = mapClassName(insn.owner); +                        String fieldName = mapFieldNameFromNode(insn); + +                        if (ownerName.equals("net/minecraft/client/settings/GameSettings") && (fieldName.equals("thirdPersonView") || fieldName.equals("field_74320_O")) && insn.desc.equals("I")) { +                            method.instructions.insertBefore(insn, insertThirdPersonHook()); +                            method.instructions.remove(insn); +                        } +                    } +                } +            } +        } +    } + +    public InsnList insertThirdPersonHook() { +        InsnList list = new InsnList(); + +        list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "thirdPersonHook", "(Lnet/minecraft/client/settings/GameSettings;I)V", false)); + +        return list; +    } +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/RenderManagerTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/RenderManagerTransformer.java new file mode 100644 index 0000000..fee214a --- /dev/null +++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/RenderManagerTransformer.java @@ -0,0 +1,72 @@ +package me.djtheredstoner.perspectivemod.asm.transformers; + +import me.djtheredstoner.perspectivemod.asm.ITransformer; +import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; +import org.objectweb.asm.tree.*; + +import java.util.Iterator; + +import static org.objectweb.asm.Opcodes.*; + +/** + * @see net.minecraft.client.renderer.entity.RenderManager + */ +public class RenderManagerTransformer implements ITransformer { +    private static final String HOOK_CLASS = "me/djtheredstoner/perspectivemod/asm/hooks/RenderManagerHook"; + +    @Override +    public String[] getClassName() { +        return new String[]{"net.minecraft.client.renderer.entity.RenderManager"}; +    } + +    @Override +    public void transform(ClassNode classNode, String name) { +        for (MethodNode method : classNode.methods) { +            String methodName = mapMethodName(classNode, method); + +            if (methodName.equals("cacheActiveRenderInfo") || methodName.equals("func_180597_a")) { +                Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); + +                while (iterator.hasNext()) { +                    AbstractInsnNode next = iterator.next(); + +                    if (next.getOpcode() == PUTFIELD) { +                        FieldInsnNode insn = (FieldInsnNode)next; + +                        String ownerName = mapClassName(insn.owner); +                        String fieldName = mapFieldNameFromNode(insn); + +                        if (ownerName.equals("net/minecraft/client/renderer/entity/RenderManager") && insn.desc.equals("F")) { + +                            InsnList insnList = null; + +                            switch (fieldName) { +                                case "playerViewX": +                                case "field_78732_j": +                                    insnList = insertRotationHook("playerViewX"); +                                    break; +                                case "playerViewY": +                                case "field_78735_i": +                                    insnList = insertRotationHook("playerViewY"); +                                    break; +                            } + +                            if(insnList != null) { +                                method.instructions.insertBefore(insn, insnList); +                                method.instructions.remove(insn); +                            } +                        } +                    } +                } +            } +        } +    } + +    public InsnList insertRotationHook(String field) { +        InsnList list = new InsnList(); + +        list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, field + "Hook", "(Lnet/minecraft/client/renderer/entity/RenderManager;F)V", false)); + +        return list; +    } +} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModLoadingPlugin.java b/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModLoadingPlugin.java deleted file mode 100644 index 1242671..0000000 --- a/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModLoadingPlugin.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.djtheredstoner.perspectivemod.forge; - -import net.minecraftforge.common.ForgeVersion; -import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; -import org.spongepowered.asm.launch.MixinBootstrap; -import org.spongepowered.asm.mixin.Mixins; - -import java.util.Map; - -// ONLY needed in development environment, the mixin tweaker handles this in prod. -@IFMLLoadingPlugin.MCVersion(ForgeVersion.mcVersion) -public class PerspectiveModLoadingPlugin implements IFMLLoadingPlugin { - -    public PerspectiveModLoadingPlugin() { -        MixinBootstrap.init(); - -        Mixins.addConfiguration("mixins.djperspectivemod.json"); -    } - -    @Override -    public String[] getASMTransformerClass() { -        return new String[0]; -    } - -    @Override -    public String getModContainerClass() { -        return null; -    } - -    @Override -    public String getSetupClass() { -        return null; -    } - -    @Override -    public void injectData(Map<String, Object> data) { - -    } - -    @Override -    public String getAccessTransformerClass() { -        return null; -    } -} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveTweaker.java b/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java index f22ba05..695f7a2 100644 --- a/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveTweaker.java +++ b/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java @@ -1,25 +1,22 @@  package me.djtheredstoner.perspectivemod.forge; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import me.djtheredstoner.perspectivemod.asm.ClassTransformer;  import net.minecraft.launchwrapper.Launch;  import net.minecraftforge.common.ForgeVersion;  import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; -import javax.swing.JOptionPane; +import javax.swing.*;  import java.io.File; -import java.io.InputStream;  import java.lang.reflect.InvocationTargetException;  import java.lang.reflect.Method;  import java.util.Map; -import java.util.zip.ZipEntry;  import java.util.zip.ZipFile; -// this one will be loaded in prod, used to detect Canelex's perspective mod +  @IFMLLoadingPlugin.MCVersion(ForgeVersion.mcVersion) -public class PerspectiveTweaker implements IFMLLoadingPlugin { +public class PerspectiveModTweaker implements IFMLLoadingPlugin { -    public PerspectiveTweaker() { +    public PerspectiveModTweaker() {          File mods = new File(Launch.minecraftHome, "mods");          if (!mods.exists()) { @@ -55,7 +52,7 @@ public class PerspectiveTweaker implements IFMLLoadingPlugin {      @Override      public String[] getASMTransformerClass() { -        return new String[0]; +        return new String[]{ClassTransformer.class.getName()};      }      @Override diff --git a/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinEntityRenderer.java b/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinEntityRenderer.java deleted file mode 100644 index 3290aff..0000000 --- a/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinEntityRenderer.java +++ /dev/null @@ -1,41 +0,0 @@ -package me.djtheredstoner.perspectivemod.mixins; - -import me.djtheredstoner.perspectivemod.PerspectiveMod; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.EntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import static org.objectweb.asm.Opcodes.*; - -@Mixin(EntityRenderer.class) -public class MixinEntityRenderer { - -    @Redirect(method = "updateCameraAndRender", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;inGameHasFocus:Z", opcode = GETFIELD)) -    public boolean updateCameraAndRender(Minecraft minecraft) { -        return PerspectiveMod.overrideMouse(); -    } - -    @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;rotationYaw:F", opcode = GETFIELD)) -    public float getRotationYaw(Entity entity) { -        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : entity.rotationYaw; -    } - -    @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevRotationYaw:F", opcode = GETFIELD)) -    public float getPrevRotationYaw(Entity entity) { -        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : entity.prevRotationYaw; -    } - -    @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;rotationPitch:F", opcode = GETFIELD)) -    public float getRotationPitch(Entity entity) { -        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : entity.rotationPitch; -    } - -    @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevRotationPitch:F")) -    public float getPrevRotationPitch(Entity entity) { -        return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : entity.prevRotationPitch; -    } - -} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinMinecraft.java b/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinMinecraft.java deleted file mode 100644 index 3083599..0000000 --- a/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinMinecraft.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.djtheredstoner.perspectivemod.mixins; - -import me.djtheredstoner.perspectivemod.PerspectiveMod; -import net.minecraft.client.Minecraft; -import net.minecraft.client.settings.GameSettings; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import static org.objectweb.asm.Opcodes.*; - -@Mixin(Minecraft.class) -public class MixinMinecraft { - -    @Redirect(method = "runTick", at = @At(value = "FIELD", target = "Lnet/minecraft/client/settings/GameSettings;thirdPersonView:I", opcode = PUTFIELD)) -    public void setThirdPersonView(GameSettings gameSettings, int value) { -        if(PerspectiveMod.perspectiveToggled) { -            PerspectiveMod.resetPerspective(); -        } else { -            gameSettings.thirdPersonView = value; -        } -    } - -} diff --git a/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinRenderManager.java b/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinRenderManager.java deleted file mode 100644 index 469d7fa..0000000 --- a/src/main/java/me/djtheredstoner/perspectivemod/mixins/MixinRenderManager.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.djtheredstoner.perspectivemod.mixins; - -import me.djtheredstoner.perspectivemod.PerspectiveMod; -import net.minecraft.client.renderer.entity.RenderManager; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import static org.objectweb.asm.Opcodes.*; - -@Mixin(RenderManager.class) -public class MixinRenderManager { - -    @Redirect(method = "cacheActiveRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/RenderManager;playerViewX:F", opcode = PUTFIELD)) -    public void getPlayerViewX(RenderManager renderManager, float value) { -        renderManager.playerViewX = PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : value; -    } - -    @Redirect(method = "cacheActiveRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/RenderManager;playerViewY:F", opcode = PUTFIELD)) -    public void getPlayerViewY(RenderManager renderManager, float value) { -        renderManager.playerViewY = PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : value; -    } - -} | 
