2013-10-03 50 views
1

我的目标是以编程方式编译称为Minecraft的游戏的Java代码。我正在开发一个修改,允许用户编写Java文件并进行编译,以便它们可以安装到游戏中(游戏是用Java编写的),我使用JavaCompiler类并且工作正常,问题是当游戏是反编译的,所有的目录和名称都会改变,但是使用JavaCompiler它并不如预期的那样。我徘徊,如果有一种方法来编译java文件,然后用一段代码来编辑类,它将用其他字符串代替set字符串,我试图让它在java文件中更改,然后编译,只有编译不起作用,因为导入和类名称无效。这里是我当前的代码:使用JavaCompiler编译Minecraft

package com.marko5049.TechRev.GUI; 

import java.awt.Dimension; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.InputStream; 
import java.io.Writer; 
import java.util.Scanner; 

import javax.swing.JTextArea; 
import javax.tools.Diagnostic; 
import javax.tools.DiagnosticListener; 
import javax.tools.JavaCompiler; 
import javax.tools.JavaFileManager; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 

import net.minecraft.client.Minecraft; 
import net.minecraft.client.gui.GuiButton; 
import net.minecraft.client.gui.GuiTextField; 
import net.minecraft.entity.player.EntityPlayer; 
import net.minecraft.util.ResourceLocation; 
import net.minecraft.world.World; 

import org.lwjgl.input.Keyboard; 
import org.lwjgl.opengl.GL11; 

import com.marko5049.TechRev.TileEntityComputer; 

import cpw.mods.fml.common.FMLCommonHandler; 

public class GuiProgramIDE extends GuiScreenMod 
{ 
    private World world; 
    private EntityPlayer entityplayer; 
    private Minecraft mc; 
    private final TileEntityComputer tile; 
    private GuiTextField txtBox; 
    private GuiTextField txtName; 

    public GuiProgramIDE(World world1, EntityPlayer entityplayer1, Minecraft minecraft, TileEntityComputer compTile) 
    { 
     world = world1; 
     entityplayer = entityplayer1; 
     mc = minecraft; 
     tile = compTile; 
    } 

    public void updateScreen() 
    { 
     this.txtBox.updateCursorCounter(); 
     this.txtName.updateCursorCounter(); 
    } 

    public void initGui() 
    { 
     Keyboard.enableRepeatEvents(true); 
     buttonList.clear(); 
     this.txtBox = new GuiTextField(this.fontRenderer, this.width/2 - 150, 80, 300, 40); 
     this.txtBox.setMaxStringLength(999999999); 
     this.txtBox.setFocused(true); 
     this.txtBox.setText("Text goes here!"); 
     this.txtName = new GuiTextField(this.fontRenderer, this.width/2 - 100, 40, 200, 20); 
     this.txtName.setMaxStringLength(32); 
     this.txtName.setFocused(false); 
     this.txtName.setText("Title goes here!"); 
     buttonList.add(new GuiButton(1, width/2 - 105, height/2 + 40, 100, 20, "Save")); 
     buttonList.add(new GuiButton(2, width/2 + 5, height/2 + 40, 100, 20, "Open")); 
     buttonList.add(new GuiButton(3, width/2 - 105, height/2 + 60, 210, 20, "Compile")); 
    } 

    public void onGuiClosed() 
    { 
     Keyboard.enableRepeatEvents(false); 
    } 

    protected void actionRPerformed(GuiButton guibutton) 
    { 

    } 

    protected void actionPerformed(GuiButton guibutton) 
    { 
     if(guibutton.id == 1) { 
      BufferedWriter write; 
      String text = txtBox.getText(); 
      String title = txtName.getText(); 
      String name = txtName.getText() + ".java"; 
      String path = Minecraft.getMinecraft().mcDataDir.getParent().toString() + "/saves/" + world.getWorldInfo().getWorldName().toString() + "/TechRev/Compiler/"; 
      File destFolder = new File(path); 
      if (!destFolder.exists()) 
      { 
       destFolder.mkdir(); 
       if(!path.endsWith(name)) path += name; 
       try { 
        write = new BufferedWriter(new FileWriter(path)); 
        write.write(text); 
        write.close(); 
        txtBox.setText(text); 
        txtName.setText(title); 
       } catch(Exception e) {} 
      } else { 
       if(!path.endsWith(name)) path += name; 
       try { 
        write = new BufferedWriter(new FileWriter(path)); 
        write.write(text); 
        write.close(); 
        txtBox.setText(text); 
        txtName.setText(title); 
       } catch(Exception e) {} 
      } 
     } 
     if(guibutton.id == 2) { 
      String title = txtName.getText(); 
      String name = title + ".java"; 
      String path = Minecraft.getMinecraft().mcDataDir.getParent().toString() + "/saves/" + world.getWorldInfo().getWorldName().toString() + "/TechRev/Compiler/"; 
      File file = new File(path + name); 
      if(file.canRead()) { 
       String FileTxt = ""; 
       if((path + name).endsWith(".java")) { 
        try { 
         Scanner read = new Scanner(new FileInputStream(file)); 
         while (read.hasNextLine()) { 
          FileTxt += read.nextLine(); 
         } 
         read.close(); 
        } catch(FileNotFoundException e) {} 
        txtBox.setText(FileTxt); 
        txtName.setText(title); 
       } 

      } else { 
       System.out.print("Cannot Open File!"); 
      } 
     } 
     if(guibutton.id == 3) { 
      String title = txtName.getText(); 
      String name = title + ".java"; 
      String src = Minecraft.getMinecraft().mcDataDir.getParent().toString() + "/saves/" + world.getWorldInfo().getWorldName().toString() + "/TechRev/Compiler/"; 
      File java = new File(src + name); 
      File srcFolder = new File(src); 
      if (!srcFolder.exists()) { 
       srcFolder.mkdir(); 
       compile(src + name); 
      } else { 
       compile(src + name); 
      } 
     } 
    } 

    public void compile(String file) { 
     String fileToCompile = file; 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     int compilationResult = compiler.run(null, null, null, fileToCompile); 
     if (compilationResult == 0) { 
      System.out.println("Compilation is successful"); 
      entityplayer.addChatMessage("Compilation is successful"); 
     } else { 
      System.out.println("Compilation failed"); 
      entityplayer.addChatMessage("Compilation failed"); 
     } 
    } 

    public boolean doesGuiPauseGame() 
    { 
      return true; 
    } 

    protected void keyTyped(char par1, int par2) 
    { 
     super.keyTyped(par1, par2); 
     this.txtBox.textboxKeyTyped(par1, par2); 
     this.txtName.textboxKeyTyped(par1, par2); 
    } 

    protected void mouseClicked(int par1, int par2, int par3) 
    { 
     super.mouseClicked(par1, par2, par3); 
     this.txtName.mouseClicked(par1, par2, par3); 
     this.txtBox.mouseClicked(par1, par2, par3); 
    } 

    public void drawScreen(int i, int j, float f) 
    { 
      drawDefaultBackground(); 
      int x = width/3 - 128; 
      int y = height/3 - 128; 
      try{ 
        GL11.glPushMatrix(); 
        GL11.glScalef(1.5F, 1.5F, 1.5F); 
        GL11.glColor4f(2.0F, 2.0F, 2.0F, 2.0F); 
        mc.renderEngine.bindTexture(new ResourceLocation("TechRev:App.png")); 
        drawTexturedModalRect(x, y, 0, 0, 256, 256); 
        GL11.glPopMatrix(); 
      } 
      finally{ 
      } 
      this.txtBox.drawTextBox(); 
      this.txtName.drawTextBox(); 
      super.drawScreen(i, j, f); 
    } 
} 

正如你所看到的,这是对编辑的文本框的GUI,它保存在目录中,为.java文件的文本。下面是写在这个界面我测试的java文件:

import cpw.mods.fml.common.Mod; import net.minecraft.src.ModLoader; import net.minecraft.item.Item; 
@Mod(modid = "TechRev", name = "Technological Revolution", version = "V0.1") 
public class TechRev { 
public static Item ChickenLegs = new Item(3000).setUnlocalizedName("chicken"); 
public TechRev() { init(); } 
public void init(){ ModLoader.addName(ChickenLegs, "Chicken Drumsticks");}} 

正如我所说的JavaCompiler进行做什么它应该只是我需要它重命名在从产生的类文件的目录和类名编译器。

回答

0

听起来你需要做一些类似于immibis的Bearded-Octo-Nemesis工具的工作。 BON允许您使用已用于反编译Minecraft的MCP目录中的配置,对Minecraft mod档案进行反混淆处理。输入是一个生产模型归档文件(引用混淆的Minecraft类/方法/字段名称)以及MCP目录的路径。输出是一个mod档案,应该可以在反混淆的环境中使用,例如MCP Eclipse工作区(您可以将反混淆的mod档案放在mcp/jars/mods文件夹中)。

这里是BON源代码的链接; immibis使用相当宽松的许可证,因此您可能可以调整其代码以使用Forge的一部分的运行时反混淆数据。 https://github.com/immibis/bearded-octo-nemesis