Моя цель — программно скомпилировать Java-код для игры под названием Minecraft. Я разрабатываю модификацию, которая позволяет пользователю писать 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);
}
}
Как видите, это графический интерфейс с текстовым полем для редактирования, он сохраняет текст в каталоге и в виде файлов .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 делает то, что должен, только мне нужно, чтобы он переименовывал каталоги и имена классов в файле класса, созданном компилятором.