Updates
Check diffs. Basically, all code is now compiled and executed on the server side
This commit is contained in:
parent
b05a04b659
commit
5bea0f3e28
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +1,6 @@
|
||||
package org.teamavion.pcomp;
|
||||
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.nbt.NBTException;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldProvider;
|
||||
@ -12,6 +10,7 @@ import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import org.teamavion.pcomp.blocks.Computer;
|
||||
import org.teamavion.pcomp.gui.GUIHandler;
|
||||
import org.teamavion.pcomp.tile.TileEntityComputer;
|
||||
@ -20,9 +19,6 @@ import org.teamavion.util.automation.SetupHelper;
|
||||
import org.teamavion.util.support.NetworkChannel;
|
||||
import org.teamavion.util.support.Reflection;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Mod(modid = PComp.MODID, version = PComp.VERSION)
|
||||
public class PComp
|
||||
{
|
||||
@ -42,23 +38,18 @@ public class PComp
|
||||
SetupHelper.registerRenders(PComp.class);
|
||||
channel = new NetworkChannel(MODID);
|
||||
channel.registerWorldHandler((side, worldEvent) -> {
|
||||
World w = (World) Reflection.getValue("world", DimensionManager.getProvider((Integer) Reflection.getValue("id", worldEvent, worldEvent.getClass())), WorldProvider.class); // Get World
|
||||
World w = (World) (side==Side.SERVER?
|
||||
Reflection.getValue("world", DimensionManager.getProvider((Integer) Reflection.getValue("id", worldEvent, worldEvent.getClass())), WorldProvider.class):
|
||||
Reflection.getValue("world", Minecraft.getMinecraft(), Minecraft.class)); // Get World
|
||||
TileEntity t = w.getTileEntity(worldEvent.getPos());
|
||||
try {
|
||||
if (t != null) {
|
||||
Matcher m = Pattern.compile("(\\d+):(\\d+):(\\d+);(\\d+);(.+)").matcher(worldEvent.getData());
|
||||
if(!m.matches()) throw new RuntimeException();
|
||||
String s1;
|
||||
NBTTagCompound n = JsonToNBT.getTagFromJson((s1=m.group(5)).substring(8, s1.length()-1)
|
||||
.replace("&rbr;", "}")
|
||||
.replace("&lbr;", "{")
|
||||
.replace(""", "\"")
|
||||
.replace("&", "&"));
|
||||
t.readFromNBT(n);
|
||||
}
|
||||
} catch (NBTException e) {
|
||||
e.printStackTrace();
|
||||
if (t == null){
|
||||
System.err.println("A referenced TileEntity ("+worldEvent.getPos().toString()+") was null!");
|
||||
return null;
|
||||
}
|
||||
t.readFromNBT(worldEvent.getEvent());
|
||||
t.markDirty();
|
||||
if(worldEvent.getEvent().hasKey("update")) return new NetworkChannel.WorldEvent(t.getPos(), t.getWorld().provider.getDimension(), t.serializeNBT());
|
||||
if(worldEvent.getEvent().hasKey("exec")) if(t instanceof TileEntityComputer) ((TileEntityComputer) t).exec();
|
||||
return null;
|
||||
});
|
||||
NetworkRegistry.INSTANCE.registerGuiHandler(this, new GUIHandler());
|
||||
|
@ -23,6 +23,8 @@ public class Computer extends Block {
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||
TileEntity t = worldIn.getTileEntity(pos);
|
||||
if(t!=null) t.setPos(pos);
|
||||
playerIn.openGui(PComp.instance, ID_COMPUTER, worldIn, pos.getX(), pos.getY(), pos.getZ());
|
||||
return true;
|
||||
}
|
||||
@ -30,7 +32,9 @@ public class Computer extends Block {
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createTileEntity(World world, IBlockState state) {
|
||||
return new TileEntityComputer();
|
||||
TileEntityComputer t = new TileEntityComputer();
|
||||
t.setWorld(world);
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -8,7 +8,11 @@ public class ContainerComputer extends Container{
|
||||
|
||||
protected final TileEntityComputer computer;
|
||||
|
||||
public ContainerComputer(TileEntityComputer computer){ this.computer = computer; }
|
||||
public ContainerComputer(TileEntityComputer computer){
|
||||
this.computer = computer;
|
||||
computer.getWorld().scheduleBlockUpdate(computer.getPos(), computer.getBlockType(), 0, 0);
|
||||
computer.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer playerIn) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.teamavion.pcomp.gui;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@ -11,17 +10,9 @@ import org.teamavion.pcomp.PComp;
|
||||
import org.teamavion.pcomp.net.DataListener;
|
||||
import org.teamavion.pcomp.tile.TileEntityComputer;
|
||||
import org.teamavion.util.support.NetworkChannel;
|
||||
import org.teamavion.util.support.Reflection;
|
||||
import org.teamavion.util.support.Result;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
@SuppressWarnings({"unchecked", "WeakerAccess"})
|
||||
@ -37,7 +28,12 @@ public class GUIComputer extends GuiScreen implements DataListener<HashMap<Integ
|
||||
protected GuiTextField[] inputLines;
|
||||
protected GuiButton button;
|
||||
|
||||
public GUIComputer(TileEntityComputer computer){ this.computer = computer; }
|
||||
public GUIComputer(TileEntityComputer computer){
|
||||
this.computer = computer;
|
||||
NBTTagCompound n = new NBTTagCompound();
|
||||
n.setString("update", "");
|
||||
PComp.instance.channel.sendToServer(new NetworkChannel.WorldEvent(computer.getPos(), computer.getWorld().provider.getDimension(), n));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(int tint) {
|
||||
@ -188,73 +184,26 @@ public class GUIComputer extends GuiScreen implements DataListener<HashMap<Integ
|
||||
break;
|
||||
}
|
||||
if(button.mousePressed(Minecraft.getMinecraft(), mouseX, mouseY)){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
File f = File.createTempFile("exec", ".java");
|
||||
ArrayList<GuiTextField> skip = new ArrayList<>();
|
||||
for(GuiTextField t : inputLines) if(t.getText().startsWith("import ") && t.getText().endsWith(";")){ skip.add(t); sb.append(t.getText()); }
|
||||
sb.append("public class ").append(f.getName().substring(0, f.getName().length() - 5)).append("{public static void main(String[] args){");
|
||||
for(GuiTextField t : inputLines) if(!skip.contains(t)) sb.append(t.getText());
|
||||
sb.append("}}");
|
||||
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
|
||||
try (OutputStream out = new FileOutputStream(f)) { out.write(sb.toString().getBytes()); }
|
||||
int result = jc.run(null, null, null, f.getAbsolutePath());
|
||||
if(result==0){
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
f.delete();
|
||||
f = new File(f.getAbsolutePath().substring(0, f.getAbsolutePath().length()-5)+".class");
|
||||
byte[] b;
|
||||
try{
|
||||
InputStream i = new FileInputStream(f);
|
||||
ArrayList<Byte> a = new ArrayList<>();
|
||||
byte[] b1 = new byte[4096];
|
||||
int i1;
|
||||
while(i.available()>0){
|
||||
i1 = i.read(b1);
|
||||
for(int j = 0; j<i1; ++j) a.add(b1[j]);
|
||||
}
|
||||
i.close();
|
||||
b = new byte[a.size()];
|
||||
for(int j = 0; j<a.size(); ++j) b[j] = a.get(j);
|
||||
}catch(Exception e){ return; }
|
||||
finally {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
f.delete();
|
||||
}
|
||||
Result<Class<?>> compiled = (Result<Class<?>>) Reflection.invokeMethod(
|
||||
Reflection.getMethod(ClassLoader.class, "defineClass", byte[].class, int.class, int.class),
|
||||
GUIComputer.class.getClassLoader(),
|
||||
b,
|
||||
0,
|
||||
b.length);
|
||||
if(compiled.success){
|
||||
for(Method m : compiled.value.getDeclaredMethods())
|
||||
if(m.getName().equals("main") && Modifier.isStatic(m.getModifiers()) && Arrays.equals(m.getParameterTypes(), new Class<?>[]{String[].class}))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
try {
|
||||
m.invoke(null, (Object) new String[]{});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NBTTagCompound n = new NBTTagCompound();
|
||||
n.setString("exec", "");
|
||||
sync(n);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
computer.unregisterDataListener(this);
|
||||
for(int i = 0; i<inputLines.length; ++i) computer.writeLine(i, inputLines[i].getText());
|
||||
NBTTagCompound n = new NBTTagCompound();
|
||||
computer.writeToNBT(n);
|
||||
JsonObject j = new JsonObject();
|
||||
j.addProperty("tag", n.toString().replace("&", "&").replace("\"", """).replace("{", "&lbr;").replace("}", "&rbr;"));
|
||||
PComp.instance.channel.sendToServer(new NetworkChannel.WorldEvent(computer.getPos(), computer.getWorld().provider.getDimension(), j));
|
||||
computer.markDirty();
|
||||
sync(new NBTTagCompound());
|
||||
super.onGuiClosed();
|
||||
}
|
||||
|
||||
protected void sync(NBTTagCompound n){
|
||||
for(int i = 0; i<inputLines.length; ++i) computer.writeLine(i, inputLines[i].getText());
|
||||
computer.writeToNBT(n);
|
||||
PComp.instance.channel.sendToServer(new NetworkChannel.WorldEvent(computer.getPos(), computer.getWorld().provider.getDimension(), n));
|
||||
computer.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseReleased(int mouseX, int mouseY, int state) {
|
||||
super.mouseReleased(mouseX, mouseY, state);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.teamavion.pcomp.gui;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@ -26,9 +25,8 @@ public class GUIHandler implements IGuiHandler{
|
||||
TileEntity t = world.getTileEntity(new BlockPos(x, y, z));
|
||||
if(!(t instanceof TileEntityComputer)) return null; // Something went wrong. ID-clash maybe?
|
||||
NBTTagCompound n = new NBTTagCompound();
|
||||
t.writeToNBT(n);JsonObject j = new JsonObject();
|
||||
j.addProperty("tag", n.toString().replace("&", "&").replace("\"", """).replace("{", "&lbr;").replace("}", "&rbr;"));
|
||||
PComp.instance.channel.sendTo(new NetworkChannel.WorldEvent(new BlockPos(x, y, z), world.provider.getDimension(), j), (EntityPlayerMP) player);
|
||||
t.writeToNBT(n);
|
||||
PComp.instance.channel.sendTo(new NetworkChannel.WorldEvent(new BlockPos(x, y, z), world.provider.getDimension(), n), (EntityPlayerMP) player);
|
||||
return new ContainerComputer((TileEntityComputer) t);
|
||||
}
|
||||
return null;
|
||||
|
@ -2,13 +2,26 @@ package org.teamavion.pcomp.tile;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import org.teamavion.pcomp.net.DataListener;
|
||||
import org.teamavion.util.support.Reflection;
|
||||
import org.teamavion.util.support.Result;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class TileEntityComputer extends TileEntity{
|
||||
@SuppressWarnings("unchecked")
|
||||
public class TileEntityComputer extends TileEntity {
|
||||
|
||||
protected final HashMap<Integer, String> lines = new HashMap<>();
|
||||
protected final ArrayList<DataListener<HashMap<Integer, String>>> dataListeners = new ArrayList<>();
|
||||
@ -20,6 +33,20 @@ public class TileEntityComputer extends TileEntity{
|
||||
public String readLine(int line){ return lines.keySet().contains(line)?lines.get(line):""; }
|
||||
public void writeLine(int line, String data){ lines.put(line, data); }
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SPacketUpdateTileEntity getUpdatePacket() {
|
||||
NBTTagCompound t = new NBTTagCompound();
|
||||
t = writeToNBT(t);
|
||||
return new SPacketUpdateTileEntity(pos, 0, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
|
||||
readFromNBT(pkt.getNbtCompound());
|
||||
super.onDataPacket(net, pkt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
|
||||
int j = 0, k = 0;
|
||||
@ -32,6 +59,18 @@ public class TileEntityComputer extends TileEntity{
|
||||
return super.writeToNBT(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound serializeNBT() {
|
||||
NBTTagCompound n = new NBTTagCompound();
|
||||
writeToNBT(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(NBTTagCompound nbt) {
|
||||
readFromNBT(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
super.readFromNBT(compound);
|
||||
@ -42,6 +81,68 @@ public class TileEntityComputer extends TileEntity{
|
||||
for(DataListener<HashMap<Integer, String>> d : dataListeners) d.getData(lines);
|
||||
}
|
||||
|
||||
public void exec(){
|
||||
try{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
File f = File.createTempFile("exec", ".java");
|
||||
ArrayList<Integer> skip = new ArrayList<>();
|
||||
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
|
||||
for(Integer key : lines.keySet()){
|
||||
if(min>key) min = key;
|
||||
if(max<key) max = key;
|
||||
}
|
||||
String s;
|
||||
for(int i = min; i<max+1; ++i) if(lines.containsKey(i) && (s=lines.get(i)).startsWith("import ") && s.endsWith(";")) { skip.add(i); sb.append(s); }
|
||||
sb.append("public class ").append(f.getName().substring(0, f.getName().length() - 5)).append("{public static void main(String[] args){");
|
||||
for(int i = min; i<max+1; ++i) if(!skip.contains(i) && (s=lines.get(i))!=null) sb.append(s);
|
||||
sb.append("}}");
|
||||
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
|
||||
try (OutputStream out = new FileOutputStream(f)) { out.write(sb.toString().getBytes()); }
|
||||
int result = jc.run(null, null, null, f.getAbsolutePath());
|
||||
if(result==0){
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
f.delete();
|
||||
f = new File(f.getAbsolutePath().substring(0, f.getAbsolutePath().length()-5)+".class");
|
||||
byte[] b;
|
||||
try{
|
||||
InputStream i = new FileInputStream(f);
|
||||
ArrayList<Byte> a = new ArrayList<>();
|
||||
byte[] b1 = new byte[4096];
|
||||
int i1;
|
||||
while(i.available()>0){
|
||||
i1 = i.read(b1);
|
||||
for(int j = 0; j<i1; ++j) a.add(b1[j]);
|
||||
}
|
||||
i.close();
|
||||
b = new byte[a.size()];
|
||||
for(int j = 0; j<a.size(); ++j) b[j] = a.get(j);
|
||||
}catch(Exception e){ return; }
|
||||
finally {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
f.delete();
|
||||
}
|
||||
Result<Class<?>> compiled = (Result<Class<?>>) Reflection.invokeMethod(
|
||||
Reflection.getMethod(ClassLoader.class, "defineClass", byte[].class, int.class, int.class),
|
||||
TileEntityComputer.class.getClassLoader(),
|
||||
b,
|
||||
0,
|
||||
b.length);
|
||||
if(compiled.success){
|
||||
for(Method m : compiled.value.getDeclaredMethods())
|
||||
if(m.getName().equals("main") && Modifier.isStatic(m.getModifiers()) && Arrays.equals(m.getParameterTypes(), new Class<?>[]{String[].class}))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
try {
|
||||
m.invoke(null, new Object[]{new String[]{}});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){ e.printStackTrace(); }
|
||||
}
|
||||
|
||||
public void registerDataListener(DataListener<HashMap<Integer, String>> listener){ dataListeners.add(listener); listener.getData(lines); }
|
||||
public void unregisterDataListener(DataListener<HashMap<Integer, String>> listener){ dataListeners.remove(listener); }
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user