Advertisement
Nokiyen

ASMClassTransformer

Oct 8th, 2016
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.36 KB | None | 0 0
  1. package noki.almagest.asm;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import org.lwjgl.opengl.GL11;
  7. import org.objectweb.asm.ClassReader;
  8. import org.objectweb.asm.ClassVisitor;
  9. import org.objectweb.asm.ClassWriter;
  10. import org.objectweb.asm.MethodVisitor;
  11. import org.objectweb.asm.Opcodes;
  12. import org.objectweb.asm.commons.AnalyzerAdapter;
  13.  
  14. import net.minecraft.client.Minecraft;
  15. import net.minecraft.client.renderer.GLAllocation;
  16. import net.minecraft.client.renderer.GlStateManager;
  17. import net.minecraft.client.renderer.RenderGlobal;
  18. import net.minecraft.client.renderer.Tessellator;
  19. import net.minecraft.client.renderer.VertexBuffer;
  20. import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
  21. import net.minecraft.client.renderer.vertex.VertexFormat;
  22. import net.minecraft.launchwrapper.IClassTransformer;
  23. import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
  24. import net.minecraftforge.fml.relauncher.ReflectionHelper;
  25. import noki.almagest.AlmagestCore;
  26. import noki.almagest.helper.HelperConstellation;
  27. import noki.almagest.helper.HelperConstellation.LineData;
  28. import noki.almagest.helper.HelperConstellation.StarData;
  29.  
  30.  
  31. /**********
  32.  * @class ASMClassTransformer
  33.  *
  34.  * @description 実際にASMによるバイトコード改変を行うクラスです。
  35.  */
  36. public class ASMClassTransformer implements IClassTransformer, Opcodes {
  37.    
  38.     //******************************//
  39.     // define member variables.
  40.     //******************************//
  41.     private static final String TARGET_CLASS_NAME = "net.minecraft.client.renderer.RenderGlobal";
  42.    
  43.    
  44.     private static net.minecraft.client.renderer.vertex.VertexBuffer lineVBO;
  45.     private static int lineGLCallList;
  46.    
  47.    
  48.     //******************************//
  49.     // define member methods.
  50.     //******************************//
  51.     @Override
  52.     public byte[] transform(String name, String transformedName, byte[] basicClass) {
  53.        
  54.         ASMLoadingPlugin.LOGGER.fine("enter ASMClassTransformer.");
  55.        
  56.         if (!transformedName.equals(TARGET_CLASS_NAME)) {
  57.             return basicClass;
  58.         }
  59.        
  60.         try {
  61.             ASMLoadingPlugin.LOGGER.fine("enter transforming.");
  62.            
  63.             //**この辺りから、ASMの書き方ができます。**//
  64.            
  65.             //ClassReader, ClassWriter, ClassVisitorで3すくみになるように引数を与えることで処理を早める。
  66.             ClassReader classReader = new ClassReader(basicClass);
  67.             ClassWriter classWriter = new ClassWriter(classReader, 0);
  68.             CustomClassVisitor customVisitor = new CustomClassVisitor(name, classWriter);
  69.             classReader.accept(customVisitor, ClassReader.EXPAND_FRAMES);
  70.             return classWriter.toByteArray();
  71.            
  72.             //**ここまで**//
  73.         } catch (Exception e) {
  74.             throw new RuntimeException("asm, class transforming failed.", e);
  75.         }
  76.        
  77.     }
  78.    
  79.    
  80.     //--------------------
  81.     // Inner Class.
  82.     //--------------------
  83.     class CustomClassVisitor extends ClassVisitor {
  84.        
  85.         //*****define member variables.*//
  86.         private String owner;
  87.        
  88.         private static final String TARGET_METHOD_NAME_OBF = "func_174968_a";
  89.         private static final String TARGET_METHOD_DESC = "(Lnet/minecraft/client/renderer/VertexBuffer;FZ)V";
  90.         @SuppressWarnings("unused")
  91.         private static final String TARGET_METHOD_NAME = "renderSky";
  92.        
  93.         private static final String TARGET_METHOD_NAME_OBF2 = "func_174963_q";
  94.         private static final String TARGET_METHOD_DESC2 = "()V";
  95.         @SuppressWarnings("unused")
  96.         private static final String TARGET_METHOD_NAME2 = "generateStars";
  97.        
  98.         private static final String TARGET_METHOD_NAME_OBF3 = "func_180444_a";
  99.         private static final String TARGET_METHOD_DESC3 = "(Lnet/minecraft/client/renderer/VertexBuffer;)V";
  100.         @SuppressWarnings("unused")
  101.         private static final String TARGET_METHOD_NAME3 = "generateStars";
  102.        
  103.        
  104.         //*****define member methods.***//
  105.         public CustomClassVisitor(String owner, ClassVisitor cv) {
  106.             super(Opcodes.ASM4, cv);
  107.             this.owner = owner;
  108.         }
  109.        
  110.         @Override
  111.         public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
  112.             boolean flag1 = TARGET_METHOD_NAME_OBF.equals(FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(this.owner, name, desc));
  113.             boolean flag2 = TARGET_METHOD_DESC.equals(FMLDeobfuscatingRemapper.INSTANCE.mapMethodDesc(desc));
  114.             if(flag1 && flag2) {
  115.                 ASMLoadingPlugin.LOGGER.fine("enter method.");
  116.                 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
  117.                 return new CustomMethodVisitor(this.api, this.owner, access, name, desc, mv);
  118.             }
  119.            
  120.             boolean flag3 = TARGET_METHOD_NAME_OBF2.equals(FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(this.owner, name, desc));
  121.             boolean flag4 = TARGET_METHOD_DESC2.equals(FMLDeobfuscatingRemapper.INSTANCE.mapMethodDesc(desc));
  122.             if(flag3 && flag4) {
  123.                 ASMLoadingPlugin.LOGGER.fine("enter method 2.");
  124.                 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
  125.                 return new CustomMethodVisitor2(this.api, this.owner, access, name, desc, mv);
  126.             }
  127.            
  128.             boolean flag5 = TARGET_METHOD_NAME_OBF3.equals(FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(this.owner, name, desc));
  129.             boolean flag6 = TARGET_METHOD_DESC3.equals(FMLDeobfuscatingRemapper.INSTANCE.mapMethodDesc(desc));
  130.             if(flag5 && flag6) {
  131.                 ASMLoadingPlugin.LOGGER.fine("enter method 3.");
  132.                 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
  133.                 return new CustomMethodVisitor3(this.api, this.owner, access, name, desc, mv);
  134.             }
  135.            
  136.             return super.visitMethod(access, name, desc, signature, exceptions);
  137.         }
  138.        
  139.     }
  140.    
  141.     //MethodVisitorの代わりにAnalyzerAdapterを使うことで、
  142.     //visitMax()やvisitFrame()の処理をしなくてよくなる。
  143.     //その代わり、各種superメソッドを呼び出す必要がある。
  144.     //COMPUTE_MAXでもそんなに速度落ちないという噂も。
  145.     class CustomMethodVisitor extends AnalyzerAdapter {
  146.        
  147.         private static final String TARGET_FIELD_NAME_OBF = "field_175013_s";
  148.         @SuppressWarnings("unused")
  149.         private static final String TARGET_FIELD_NAME = "starVBO";
  150.         private boolean starVBOFlag = false;
  151.        
  152.         private static final String TARGET_FIELD_NAME_OBF2 = "field_72772_v";
  153.         @SuppressWarnings("unused")
  154.         private static final String TARGET_FIELD_NAME2 = "starGLCallList";
  155.         private boolean callListFlag = false;
  156.        
  157.         protected CustomMethodVisitor(int api, String owner, int access, String name, String desc, MethodVisitor mv) {
  158.             super(api, owner, access, name, desc, mv);
  159.             starVBOFlag = false;
  160.             callListFlag = false;
  161.         }
  162.        
  163.         @Override
  164.         public void visitCode() {
  165.             starVBOFlag = false;
  166.             callListFlag = false;
  167.             super.visitCode();
  168.         }
  169.        
  170.         @Override
  171.         public void visitFieldInsn(int opcode, String owner, String name, String desc) {
  172.            
  173.             if(opcode == GETFIELD
  174.                     && TARGET_FIELD_NAME_OBF.equals(FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(owner, name, desc))
  175.                     && starVBOFlag == false) {
  176.                 starVBOFlag = true;
  177.                 super.visitMethodInsn(INVOKESTATIC, "noki/almagest/asm/ASMClassTransformer", "renderLinesForVBO", "()V", false);
  178.             }
  179.             else if(opcode == GETFIELD
  180.                     && TARGET_FIELD_NAME_OBF2.equals(FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(owner, name, desc))
  181.                     && callListFlag == false) {
  182.                 callListFlag = true;
  183.                 super.visitMethodInsn(INVOKESTATIC, "noki/almagest/asm/ASMClassTransformer", "renderLinesForCallList", "()V", false);
  184.             }
  185.             super.visitFieldInsn(opcode, owner, name, desc);
  186.            
  187.         }
  188.        
  189.     }
  190.    
  191.     class CustomMethodVisitor2 extends AnalyzerAdapter {
  192.        
  193.         //*****define member variables.*//
  194.         private String owner2;
  195.        
  196.         protected CustomMethodVisitor2(int api, String owner, int access, String name, String desc, MethodVisitor mv) {
  197.             super(api, owner, access, name, desc, mv);
  198.             this.owner2 = owner;
  199.         }
  200.  
  201.         //*****define member methods.***//
  202.         @Override
  203.         public void visitCode() {
  204.             ASMLoadingPlugin.LOGGER.fine("enter visitCode().");
  205.             super.visitCode();
  206. //          super.visitFieldInsn(GETFIELD, this.owner2, "field_175005_X", "Z");
  207.             super.visitMethodInsn(INVOKESTATIC, "noki/almagest/asm/ASMClassTransformer", "generateStarsAlt", "()V", false);
  208. //          super.visitInsn(RETURN);
  209. //          super.visitEnd();
  210.         }
  211.        
  212.     }
  213.    
  214.     class CustomMethodVisitor3 extends AnalyzerAdapter {
  215.        
  216.         //*****define member variables.*//
  217.        
  218.         //*****define member methods.***//
  219.         protected CustomMethodVisitor3(int api, String owner, int access, String name, String desc, MethodVisitor mv) {
  220.             super(api, owner, access, name, desc, mv);
  221.         }
  222.  
  223.         @Override
  224.         public void visitCode() {
  225.             ASMLoadingPlugin.LOGGER.fine("enter visitCode().");
  226.             super.visitCode();
  227.             super.visitMethodInsn(INVOKESTATIC, "noki/almagest/asm/ASMClassTransformer", "renderStarsAlt", "()V", false);
  228.             super.visitInsn(RETURN);
  229.             super.visitEnd();
  230.         }
  231.        
  232.     }
  233.    
  234.     public static void renderLinesForVBO() {
  235.        
  236.         AlmagestCore.log("enter renderLinesForVBO().");
  237.         lineVBO.bindBuffer();
  238.         GlStateManager.glEnableClientState(32884);
  239.         GlStateManager.glVertexPointer(3, 5126, 12, 0);
  240.         lineVBO.drawArrays(GL11.GL_LINES);
  241.         lineVBO.unbindBuffer();
  242.         GlStateManager.glDisableClientState(32884);
  243.        
  244.     }
  245.    
  246.     public static void renderLinesForCallList() {
  247.        
  248.         AlmagestCore.log("enter renderLinesForCallList().");
  249.         GlStateManager.callList(lineGLCallList);
  250.        
  251.     }
  252.    
  253.     public static void renderStarsAlt() {
  254.        
  255.         Tessellator tessellator = Tessellator.getInstance();
  256.         VertexBuffer renderer = tessellator.getBuffer();
  257.        
  258.         renderer.begin(7, DefaultVertexFormats.POSITION);
  259.         for(int i=1; i<=88; i++) {
  260.             ArrayList<StarData> targetStars = HelperConstellation.getStars(i);
  261.            
  262.             for(StarData each: targetStars) {
  263.                 double radius = 200;
  264.                 double lat = Math.toRadians(each.getCalculatedLat());
  265.                 double lon = Math.toRadians(each.getCalculatedLong());
  266.                 double starY = radius * Math.sin(lat);
  267.                 double starX = radius * Math.cos(lat) * Math.sin(lon);
  268.                 double starZ = radius * Math.cos(lat) * Math.cos(lon);             
  269.                 renderer.pos(starX, starY, starZ).endVertex();
  270.                 renderer.pos(starX, starY, starZ+1).endVertex();
  271.                 renderer.pos(starX+1, starY, starZ+1).endVertex();
  272.                 renderer.pos(starX+1, starY, starZ).endVertex();
  273.             }
  274.         }
  275.        
  276.     }
  277.    
  278.     public static void renderLines(VertexBuffer renderer) {
  279.        
  280. /*      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);   // alpha blend.
  281.         GL11.glEnable(GL11.GL_BLEND);
  282.         GlStateManager.color(1F, 1F, 1F, 200F/255F);*/
  283.        
  284.         renderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION);
  285.         GL11.glLineWidth(1);
  286.        
  287.         for(int i=1; i<=88; i++) {
  288.             List<LineData> targetLines = HelperConstellation.getLines(i);
  289.            
  290.             for(LineData each: targetLines) {
  291.                 double radius = 200;
  292.                 double star1Y = radius * Math.sin(Math.toRadians(each.star1.getCalculatedLat()));
  293.                 double star1X = radius * Math.cos(Math.toRadians(each.star1.getCalculatedLat())) * Math.sin(Math.toRadians(each.star1.getCalculatedLong()));
  294.                 double star1Z = radius * Math.cos(Math.toRadians(each.star1.getCalculatedLat())) * Math.cos(Math.toRadians(each.star1.getCalculatedLong()));
  295.                 double star2Y = radius * Math.sin(Math.toRadians(each.star2.getCalculatedLat()));
  296.                 double star2X = radius * Math.cos(Math.toRadians(each.star2.getCalculatedLat())) * Math.sin(Math.toRadians(each.star2.getCalculatedLong()));
  297.                 double star2Z = radius * Math.cos(Math.toRadians(each.star2.getCalculatedLat())) * Math.cos(Math.toRadians(each.star2.getCalculatedLong()));
  298.                 renderer.pos(star1X, star1Y, star1Z).endVertex();
  299.                 renderer.pos(star2X, star2Y, star2Z).endVertex();
  300.             }
  301.         }
  302.        
  303. /*      GL11.glDisable(GL11.GL_BLEND);
  304.         GlStateManager.resetColor();*/
  305.        
  306.     }
  307.    
  308.     public static void generateStarsAlt() {
  309.        
  310.         AlmagestCore.log("enter generateStarsAlt().");
  311.        
  312.         //keep renderer.
  313.         Tessellator tessellator = Tessellator.getInstance();
  314.         VertexBuffer vertexBuffer = tessellator.getBuffer();
  315.        
  316.         //stars.
  317.         RenderGlobal renderGlobal = Minecraft.getMinecraft().renderGlobal;
  318.         if(renderGlobal == null) {
  319.             return;
  320.         }
  321.        
  322.         /*net.minecraft.client.renderer.vertex.VertexBuffer starVBO =
  323.                 ReflectionHelper.getPrivateValue(RenderGlobal.class, renderGlobal, "field_175013_s", "starVBO");
  324.         if(starVBO != null) {
  325.             starVBO.deleteGlBuffers();
  326.         }
  327.        
  328.         int starGLCallList =
  329.                 ReflectionHelper.getPrivateValue(RenderGlobal.class, renderGlobal, "field_72772_v", "starGLCallList");
  330.         if(starGLCallList >= 0) {
  331.             GLAllocation.deleteDisplayLists(starGLCallList);
  332.             ReflectionHelper.setPrivateValue(RenderGlobal.class, renderGlobal, -1, "field_72772_v", "starGLCallList");
  333.         }*/
  334.        
  335.         boolean vboEnabled =
  336.                 ReflectionHelper.getPrivateValue(RenderGlobal.class, renderGlobal, "field_175005_X", "vboEnabled");
  337. /*      if(vboEnabled) {
  338.             VertexFormat vertexBufferFormat =
  339.                     ReflectionHelper.getPrivateValue(RenderGlobal.class, renderGlobal, "field_175014_r", "vertexBufferFormat");
  340.             starVBO = new net.minecraft.client.renderer.vertex.VertexBuffer(vertexBufferFormat);
  341.             renderStarsAlt(vertexBuffer);
  342.             vertexBuffer.finishDrawing();
  343.             vertexBuffer.reset();
  344.             starVBO.bufferData(vertexBuffer.getByteBuffer());
  345.             ReflectionHelper.setPrivateValue(RenderGlobal.class, renderGlobal, starVBO, "field_175013_s", "starVBO");
  346.         }
  347.         else {
  348.             starGLCallList = GLAllocation.generateDisplayLists(1);
  349.             ReflectionHelper.setPrivateValue(RenderGlobal.class, renderGlobal, starGLCallList, "field_72772_v", "starGLCallList");
  350.             GlStateManager.pushMatrix();
  351.             GlStateManager.glNewList(starGLCallList, 4864);
  352.             renderStarsAlt(vertexBuffer);
  353.             tessellator.draw();
  354.             GlStateManager.glEndList();
  355.             GlStateManager.popMatrix();
  356.         }*/
  357.        
  358.        
  359.         //lines.
  360.         if(lineVBO != null) {
  361.             lineVBO.deleteGlBuffers();
  362.         }
  363.        
  364.         if(lineGLCallList >= 0) {
  365.             GLAllocation.deleteDisplayLists(lineGLCallList);
  366.             lineGLCallList = -1;
  367.         }
  368.        
  369.         if(vboEnabled) {
  370.             VertexFormat vertexBufferFormat =
  371.                     ReflectionHelper.getPrivateValue(RenderGlobal.class, Minecraft.getMinecraft().renderGlobal, "field_175014_r");
  372.             lineVBO = new net.minecraft.client.renderer.vertex.VertexBuffer(vertexBufferFormat);
  373.             renderLines(vertexBuffer);
  374.             vertexBuffer.finishDrawing();
  375.             vertexBuffer.reset();
  376.             lineVBO.bufferData(vertexBuffer.getByteBuffer());
  377.         }
  378.         else {
  379.             lineGLCallList = GLAllocation.generateDisplayLists(1);
  380.             GlStateManager.pushMatrix();
  381.             GlStateManager.glNewList(lineGLCallList, 4864);
  382.             renderLines(vertexBuffer);
  383.             tessellator.draw();
  384.             GlStateManager.glEndList();
  385.             GlStateManager.popMatrix();
  386.         }
  387.        
  388.     }
  389.  
  390. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement