使用JavaCompiler编译Minecraft

使用JavaCompiler编译Minecraft,java,string,compilation,rename,minecraft,Java,String,Compilation,Rename,Minecraft,我的目标是以编程方式为名为Minecraft的游戏编译java代码。我正在开发一个修改,允许用户编写java文件并进行编译,以便安装到游戏中(游戏是用java制作的),我使用JavaCompiler类,它工作正常,问题是当游戏被反编译时,所有目录和名称都会发生变化,但对于JavaCompiler,它并不像预期的那样。我想知道是否有一种方法可以编译java文件,然后用一段代码来编辑类,用其他同样设置的字符串替换设置字符串,我尝试在java文件中更改它,然后进行编译,但编译不起作用,因为导入和类名无

我的目标是以编程方式为名为Minecraft的游戏编译java代码。我正在开发一个修改,允许用户编写java文件并进行编译,以便安装到游戏中(游戏是用java制作的),我使用JavaCompiler类,它工作正常,问题是当游戏被反编译时,所有目录和名称都会发生变化,但对于JavaCompiler,它并不像预期的那样。我想知道是否有一种方法可以编译java文件,然后用一段代码来编辑类,用其他同样设置的字符串替换设置字符串,我尝试在java文件中更改它,然后进行编译,但编译不起作用,因为导入和类名无效。这是我目前的代码:

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文件。这是我在这个GUI中编写的测试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做了它应该做的,只是我需要它来重命名编译器生成的类文件中的目录和类名。

听起来你需要做一些类似于immibis在Beard Octo Nemesis工具中所做的事情。BON允许您使用用于反编译Minecraft的MCP目录中的配置来消除Minecraft mod归档文件的混淆。输入是一个production mod archive(参考模糊的Minecraft类/方法/字段名)和MCP目录的路径。输出是一个mod归档,应该可以在一个deobfouscated环境中使用,比如MCP Eclipse工作区(您可以将deobfouscated mod归档放在MCP/jars/mods文件夹中)

这里是一个链接到苯教的源代码;immibis使用一个相当许可的许可证,因此您可以修改他的代码,以使用Forge中的运行时deobfousation数据。