mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-08-10 17:55:44 +00:00
Merge branch 'HbmMods:master' into rulang121
This commit is contained in:
commit
b003a154ae
@ -16,6 +16,9 @@
|
||||
* Successor to the BAT9k
|
||||
* Larger footprint, way more storage space
|
||||
* Needs to be placed on a proper foundation or else it'll sink into the ground
|
||||
* AUTOCAL Automatic Calculator
|
||||
* Highly advanced programmable RoR device
|
||||
* Can send and receive signals and do calculations with the same system as NTM's calculator
|
||||
|
||||
## Changed
|
||||
* RoR graphs can now have their min and max bounds set to a fixed number
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package com.hbm.inventory.gui;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@ -59,11 +63,6 @@ public class GUIScreenRadioAUTOCAL extends GuiScreen {
|
||||
if(checkClick(x, y, 28, 36, 18, 18)) { data = new NBTTagCompound(); data.setBoolean("ignore", true); }
|
||||
if(checkClick(x, y, 48, 36, 18, 18)) { data = new NBTTagCompound(); data.setBoolean("auto", true); }
|
||||
|
||||
if(data != null) {
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, autocal.xCoord, autocal.yCoord, autocal.zCoord));
|
||||
}
|
||||
|
||||
// open folder and generate new script file
|
||||
if(checkClick(x, y, 104, 36, 18, 18)) {
|
||||
try {
|
||||
@ -74,8 +73,38 @@ public class GUIScreenRadioAUTOCAL extends GuiScreen {
|
||||
script.setExecutable(false);
|
||||
Class oclass = Class.forName("java.awt.Desktop");
|
||||
Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]);
|
||||
oclass.getMethod("browse", new Class[] { URI.class }).invoke(object, new Object[] { uploadFolder.toURI() });
|
||||
} catch(Throwable ex) { MainRegistry.logger.error("Couldn\'t open link", ex); }
|
||||
oclass.getMethod("browse", new Class[] { URI.class }).invoke(object, new Object[] { script.toURI() });
|
||||
//oclass.getMethod("edit", File.class).invoke(object, new Object[] { script });
|
||||
} catch(Throwable ex) { MainRegistry.logger.error("Couldn't open link", ex); }
|
||||
}
|
||||
|
||||
if(checkClick(x, y, 84, 36, 18, 18)) {
|
||||
try {
|
||||
File uploadFolder = new File(MainRegistry.configDir.getParentFile(), "hbmComputerUpload");
|
||||
File script = new File(uploadFolder, "script.txt");
|
||||
if(!uploadFolder.exists()) uploadFolder.mkdir();
|
||||
if(!script.exists()) {
|
||||
script.createNewFile();
|
||||
script.setExecutable(false);
|
||||
return;
|
||||
}
|
||||
/*FileReader reader = new FileReader(script);
|
||||
BufferedReader buffer = new BufferedReader(reader);
|
||||
String[] lines = buffer.lines().toArray(String[]::new);
|
||||
buffer.close();
|
||||
// this is going to blow the fuck up once we hit the max packet size, but let's ignore that for now
|
||||
data = new NBTTagCompound();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(int l = 0; l < lines.length; l++) {
|
||||
builder.append(lines[i]);
|
||||
if(l < lines.length - 1) builder.append("\n"); // yeah why the fuck not
|
||||
}
|
||||
data.setString("payload", builder.toString());*/
|
||||
byte[] bytes = Files.readAllBytes(Paths.get(script.toURI()));
|
||||
data = new NBTTagCompound();
|
||||
data.setString("payload", new String(bytes, StandardCharsets.UTF_8));
|
||||
|
||||
} catch(Throwable ex) { }
|
||||
}
|
||||
|
||||
// this thing can both upload and download files so let's be careful about this
|
||||
@ -87,6 +116,11 @@ public class GUIScreenRadioAUTOCAL extends GuiScreen {
|
||||
// but we can add some extra crap that would either halt common scripting langs entirely or at least disrupt them into not functioning
|
||||
// option 3: enforce validation so only MS-ES1 script can be received by the client. this means that info such as comments or incorrectly written commands
|
||||
// are lost, however this is the safest way because it becomes impossible to send malicious code, but it also interferes with regular user operation more
|
||||
|
||||
if(data != null) {
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, autocal.xCoord, autocal.yCoord, autocal.zCoord));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean checkClick(int x, int y, int left, int top, int sizeX, int sizeY) {
|
||||
@ -100,8 +134,8 @@ public class GUIScreenRadioAUTOCAL extends GuiScreen {
|
||||
if(checkClick(x, y, 48, 36, 18, 18)) this.func_146283_a(Arrays.asList(new String[] {EnumChatFormatting.RED + "Automatic Reboot", "Restarts the computer automatically when", "the program stops due to an error", "or after finishing."}), x, y);
|
||||
|
||||
if(checkClick(x, y, 84, 36, 18, 18)) this.func_146283_a(Arrays.asList(new String[] {EnumChatFormatting.BLUE + "Upload Program"}), x, y);
|
||||
if(checkClick(x, y, 104, 36, 18, 18)) this.func_146283_a(Arrays.asList(new String[] {EnumChatFormatting.BLUE + "Open Program Folder"}), x, y);
|
||||
if(checkClick(x, y, 124, 36, 18, 18)) this.func_146283_a(Arrays.asList(new String[] {EnumChatFormatting.BLUE + "Download Program"}), x, y);
|
||||
if(checkClick(x, y, 104, 36, 18, 18)) this.func_146283_a(Arrays.asList(new String[] {EnumChatFormatting.BLUE + "Open Program File"}), x, y);
|
||||
if(checkClick(x, y, 124, 36, 18, 18)) this.func_146283_a(Arrays.asList(new String[] {EnumChatFormatting.BLUE + "Download Program", EnumChatFormatting.RED + "Currently unsupported!"}), x, y);
|
||||
}
|
||||
|
||||
private void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
|
||||
@ -110,8 +144,8 @@ public class GUIScreenRadioAUTOCAL extends GuiScreen {
|
||||
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
|
||||
|
||||
if(autocal.isOn) drawTexturedModalRect(guiLeft + 8, guiTop + 36, 150, 0, 18, 18);
|
||||
if(autocal.ignoreError) drawTexturedModalRect(guiLeft + 28, guiTop + 36, 150, 18, 18, 18);
|
||||
if(autocal.autoReboot) drawTexturedModalRect(guiLeft + 48, guiTop + 36, 150, 36, 18, 18);
|
||||
if(!autocal.ignoreError) drawTexturedModalRect(guiLeft + 28, guiTop + 36, 150, 18, 18, 18);
|
||||
if(!autocal.autoReboot) drawTexturedModalRect(guiLeft + 48, guiTop + 36, 150, 36, 18, 18);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -8,27 +8,43 @@ import net.minecraft.world.World;
|
||||
public interface IParse {
|
||||
|
||||
public EnumStatementReturn eval(ParseContext ctx, String line);
|
||||
public void generateJumpPoints(ParseContext ctx, String line, int index);
|
||||
|
||||
public static class ParseContext {
|
||||
public World world;
|
||||
public NBTTagCompound variables;
|
||||
public HashMap<String, Integer> jmp;
|
||||
public NBTTagCompound variables = new NBTTagCompound();
|
||||
public HashMap<String, Integer> jmp = new HashMap();
|
||||
|
||||
public Object buffer;
|
||||
public int clockSpeed;
|
||||
public String buffer = "";
|
||||
public int clockSpeed = 1;
|
||||
public int current = 0;
|
||||
|
||||
public ParseContext(World world, NBTTagCompound variables, HashMap<String, Integer> jmp) {
|
||||
public ParseContext(World world) {
|
||||
this.world = world;
|
||||
this.variables = variables;
|
||||
this.jmp = jmp;
|
||||
}
|
||||
|
||||
public void turnOff() {
|
||||
this.clockSpeed = 1;
|
||||
this.current = 0;
|
||||
this.buffer = "";
|
||||
if(!this.variables.hasNoTags()) this.variables = new NBTTagCompound();
|
||||
}
|
||||
}
|
||||
|
||||
public static enum EnumStatementReturn {
|
||||
/** The command executed correctly (more or less) */
|
||||
OK,
|
||||
/** The command hasn't been recognized */
|
||||
UNRECOGNIZED_COMMAND,
|
||||
/** The expected parameters aren't present, or the parameters couldn't be parsed (i.e. using an undefined jump point) */
|
||||
PARAMETER_ERROR,
|
||||
/** Requests the AUTOCAL unit to end the tick, regardless of how many clock cycles are left */
|
||||
END_TICK,
|
||||
/** Requests an AUTOCAL shutdown */
|
||||
SHUTDOWN,
|
||||
/** Skips the instruction, doesn't use up a clock cycle */
|
||||
SKIP,
|
||||
/** General undefined behavior */
|
||||
UNDEFINED
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,271 @@
|
||||
package com.hbm.module;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.hbm.tileentity.network.RTTYSystem;
|
||||
import com.hbm.tileentity.network.RTTYSystem.RTTYChannel;
|
||||
import com.hbm.tileentity.network.TileEntityRadioAUTOCAL;
|
||||
import com.hbm.util.Calculator;
|
||||
|
||||
public class ParseMSES1 implements IParse {
|
||||
|
||||
@Override
|
||||
public EnumStatementReturn eval(ParseContext ctx, String line) {
|
||||
return EnumStatementReturn.OK;
|
||||
String lower = line.toLowerCase(Locale.US);
|
||||
|
||||
// jump point destination, skip
|
||||
if(lower.startsWith("dest ") || lower.startsWith("# ")) {
|
||||
return EnumStatementReturn.SKIP;
|
||||
}
|
||||
|
||||
// no operation, still eats up a clock cycle
|
||||
if(lower.equals("nop")) {
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// sets the desired clock speed, then skips the operation
|
||||
if(lower.startsWith("clockspeed ")) {
|
||||
if(line.length() <= 11) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
int speed = Integer.parseInt(line.substring(11));
|
||||
if(speed < 1 || speed > TileEntityRadioAUTOCAL.MAX_CLOCK_SPEED) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
ctx.clockSpeed = speed;
|
||||
} catch(Throwable ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.SKIP;
|
||||
}
|
||||
|
||||
// sets the script index to the jump point
|
||||
if(lower.startsWith("jmp ")) {
|
||||
if(line.length() <= 4) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
String jmpKey = line.substring(4);
|
||||
if(ctx.jmp.containsKey(jmpKey)) {
|
||||
ctx.current = ctx.jmp.get(jmpKey);
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
return EnumStatementReturn.PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
// sets the script index to the jump point, if the buffer is the string 'true'
|
||||
if(lower.startsWith("jmpif ")) {
|
||||
if(line.length() <= 6) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
if(!ctx.buffer.equals("true")) return EnumStatementReturn.OK;
|
||||
String jmpKey = line.substring(6);
|
||||
if(ctx.jmp.containsKey(jmpKey)) {
|
||||
ctx.current = ctx.jmp.get(jmpKey);
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
return EnumStatementReturn.PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
// sets the script index to the jump point, if the buffer is the NOT 'true'
|
||||
if(lower.startsWith("jmpnot ")) {
|
||||
if(line.length() <= 7) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
if(ctx.buffer.equals("true")) return EnumStatementReturn.OK;
|
||||
String jmpKey = line.substring(7);
|
||||
if(ctx.jmp.containsKey(jmpKey)) {
|
||||
ctx.current = ctx.jmp.get(jmpKey);
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
return EnumStatementReturn.PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
// ends the tick regardless of remaining clock cycles
|
||||
if(lower.equals("endtick")) {
|
||||
return EnumStatementReturn.END_TICK;
|
||||
}
|
||||
|
||||
// requests unit to shut down
|
||||
if(lower.equals("shutdown")) {
|
||||
return EnumStatementReturn.SHUTDOWN;
|
||||
}
|
||||
|
||||
// loads the requested variable into the buffer
|
||||
if(lower.startsWith("load ")) {
|
||||
if(line.length() <= 5) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
ctx.buffer = ctx.variables.getString(line.substring(5));
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// saves the buffer with the specified name
|
||||
if(lower.startsWith("save ")) {
|
||||
if(line.length() <= 5 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
ctx.variables.setString(line.substring(5), ctx.buffer);
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// stores the specified value in the buffer
|
||||
if(lower.startsWith("buffer ")) {
|
||||
if(line.length() <= 7) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
ctx.buffer = line.substring(7);
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// runs the calculation, allows string substitution, saves result to buffer
|
||||
if(lower.startsWith("eval ")) {
|
||||
if(line.length() <= 5) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
String statement = substitute(ctx, line.substring(5));
|
||||
try {
|
||||
double result = Calculator.evaluateExpression(statement);
|
||||
ctx.buffer = "" + result;
|
||||
} catch(Throwable ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// runs the calculation, allows string substitution, rounds, saves result to buffer,
|
||||
if(lower.startsWith("evalr ")) {
|
||||
if(line.length() <= 6) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
String statement = substitute(ctx, line.substring(6));
|
||||
try {
|
||||
double result = Calculator.evaluateExpression(statement);
|
||||
ctx.buffer = "" + (int) Math.round(result);
|
||||
} catch(Throwable ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// runs the calculation from the buffer, allows string substitution, saves result to buffer
|
||||
if(lower.equals("evalr")) {
|
||||
if(ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
String statement = substitute(ctx, ctx.buffer);
|
||||
try {
|
||||
double result = Calculator.evaluateExpression(statement);
|
||||
ctx.buffer = "" + (int) Math.round(result);
|
||||
} catch(Throwable ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// rounds the buffer down to the nearest integer
|
||||
if(lower.equals("rounddown") || lower.equals("floor")) {
|
||||
if(ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double d = Double.parseDouble(ctx.buffer);
|
||||
ctx.buffer = "" + (int) Math.floor(d);
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// rounds the buffer up to the nearest integer
|
||||
if(lower.equals("roundup") || lower.equals("ceil")) {
|
||||
if(ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double d = Double.parseDouble(ctx.buffer);
|
||||
ctx.buffer = "" + (int) Math.ceil(d);
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// rounds the buffer to the nearest integer (.5 cutoff rule)
|
||||
if(lower.equals("round") || lower.equals("nearest")) {
|
||||
if(ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double d = Double.parseDouble(ctx.buffer);
|
||||
ctx.buffer = "" + (int) Math.round(d);
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// concatenate, same as buffer but evaluates $var$ substitutions
|
||||
if(lower.startsWith("concat ")) {
|
||||
if(line.length() <= 7 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
String concat = substitute(ctx, line.substring(5));
|
||||
ctx.buffer = concat;
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// compares the buffer with a value, allows substitutions
|
||||
if(lower.startsWith("eq ")) {
|
||||
if(line.length() <= 3 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
ctx.buffer = ctx.buffer.equals(substitute(ctx, line.substring(3))) ? "true" : "false";
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// greater than buffer
|
||||
if(lower.startsWith("gtb ")) {
|
||||
if(line.length() <= 3 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double buffer = Double.parseDouble(ctx.buffer);
|
||||
double val = Double.parseDouble(line.substring(3));
|
||||
ctx.buffer = val > buffer ? "true" : "false";
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// lower than buffer
|
||||
if(lower.startsWith("ltb ")) {
|
||||
if(line.length() <= 3 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double buffer = Double.parseDouble(ctx.buffer);
|
||||
double val = Double.parseDouble(line.substring(3));
|
||||
ctx.buffer = val < buffer ? "true" : "false";
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// greater than or equal buffer
|
||||
if(lower.startsWith("geb ")) {
|
||||
if(line.length() <= 3 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double buffer = Double.parseDouble(ctx.buffer);
|
||||
double val = Double.parseDouble(line.substring(3));
|
||||
ctx.buffer = val >= buffer ? "true" : "false";
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// lower than or equal buffer
|
||||
if(lower.startsWith("leb ")) {
|
||||
if(line.length() <= 3 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
try {
|
||||
double buffer = Double.parseDouble(ctx.buffer);
|
||||
double val = Double.parseDouble(line.substring(3));
|
||||
ctx.buffer = val <= buffer ? "true" : "false";
|
||||
} catch(Exception ex) { return EnumStatementReturn.PARAMETER_ERROR; }
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// sends an RoR signal using the buffer's contents as the message over the supplied channel
|
||||
if(lower.startsWith("send ")) {
|
||||
if(line.length() <= 5 || ctx.buffer.isEmpty()) return EnumStatementReturn.PARAMETER_ERROR;
|
||||
RTTYSystem.broadcast(ctx.world, line.substring(5), ctx.buffer);
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
// listnes to an RoR signal using the buffer as the channel, then saves the signal to the buffer
|
||||
if(lower.equals("listen")) {
|
||||
// this picks up expired signals too, so polling has to be implemented by the user
|
||||
RTTYChannel chan = RTTYSystem.listen(ctx.world, ctx.buffer);
|
||||
if(chan != null) ctx.buffer = chan.signal + "";
|
||||
return EnumStatementReturn.OK;
|
||||
}
|
||||
|
||||
return EnumStatementReturn.UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
|
||||
public String substitute(ParseContext ctx, String statement) {
|
||||
if(!statement.contains("$")) return statement;
|
||||
|
||||
String[] frags = statement.split("\\$");
|
||||
if(frags.length % 2 == 0 || frags.length < 3) return statement;
|
||||
|
||||
// since var names are enclosed with $ signs, we assume that every evenly numbered fragment is a var name
|
||||
// example: 5 + $val1$ * $val2$ / (-$val3$)
|
||||
// equals "5 + ", "val1", "* ", "val2", "/ (-", "val3", ")"
|
||||
// 1 2 3 4 5 6 7
|
||||
for(int i = 1; i < frags.length; i += 2) {
|
||||
// special case, if we try to substitute $buffer$ then read the literal buffer
|
||||
if(frags[i].equals("buffer")) {
|
||||
frags[i] = ctx.buffer;
|
||||
} else {
|
||||
frags[i] = ctx.variables.getString(frags[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return String.join("", frags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateJumpPoints(ParseContext ctx, String line, int index) {
|
||||
if(line.startsWith("dest ") && line.length() > 5) {
|
||||
ctx.jmp.put(line.substring(5), index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package com.hbm.tileentity.network;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.hbm.interfaces.IControlReceiver;
|
||||
import com.hbm.inventory.gui.GUIScreenRadioAUTOCAL;
|
||||
import com.hbm.module.IParse;
|
||||
import com.hbm.module.IParse.EnumStatementReturn;
|
||||
import com.hbm.module.IParse.ParseContext;
|
||||
import com.hbm.module.ParseMSES1;
|
||||
import com.hbm.tileentity.IGUIProvider;
|
||||
import com.hbm.tileentity.TileEntityTickingBase;
|
||||
|
||||
@ -11,6 +13,8 @@ import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.nbt.NBTTagString;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class TileEntityRadioAUTOCAL extends TileEntityTickingBase implements IControlReceiver, IGUIProvider {
|
||||
@ -19,10 +23,11 @@ public class TileEntityRadioAUTOCAL extends TileEntityTickingBase implements ICo
|
||||
public boolean ignoreError = false;
|
||||
public boolean autoReboot = false;
|
||||
|
||||
public Object buffer;
|
||||
public NBTTagCompound variables;
|
||||
public String[] script;
|
||||
public HashMap<String, Integer> jmp = new HashMap();
|
||||
public static final int MAX_CLOCK_SPEED = 5;
|
||||
|
||||
public String[] script = new String[0];
|
||||
public IParse msesv1 = new ParseMSES1();
|
||||
public ParseContext ctx;
|
||||
|
||||
@Override
|
||||
public String getInventoryName() {
|
||||
@ -33,9 +38,53 @@ public class TileEntityRadioAUTOCAL extends TileEntityTickingBase implements ICo
|
||||
public void updateEntity() {
|
||||
|
||||
if(!worldObj.isRemote) {
|
||||
|
||||
if(this.worldObj.getTotalWorldTime() % 60 == 0) this.markChanged(); // ensure we're always saved to disk
|
||||
|
||||
if(this.ctx == null) {
|
||||
this.ctx = new ParseContext(worldObj);
|
||||
}
|
||||
if(this.ctx.world != this.worldObj) this.ctx.world = this.worldObj;
|
||||
|
||||
if(!this.isOn && this.autoReboot) {
|
||||
this.isOn = true;
|
||||
}
|
||||
|
||||
if(this.isOn) {
|
||||
|
||||
int emergencyBrake = 100;
|
||||
for(int i = 0; i < this.ctx.clockSpeed && emergencyBrake > 0; i++) {
|
||||
emergencyBrake--;
|
||||
|
||||
if(this.ctx.current == this.script.length) { this.stop("Program has terminated"); break; }
|
||||
if(this.ctx.current < 0 || this.ctx.current >= this.script.length) { this.stop("Program index is out of bounds"); break; }
|
||||
|
||||
try {
|
||||
int index = this.ctx.current;
|
||||
this.ctx.current ++;
|
||||
EnumStatementReturn ret = msesv1.eval(ctx, this.script[index]);
|
||||
if(ret == EnumStatementReturn.END_TICK) break;
|
||||
if(ret == EnumStatementReturn.SHUTDOWN) this.stop("Program requested shutdown");
|
||||
if(!this.ignoreError) {
|
||||
if(ret == EnumStatementReturn.UNRECOGNIZED_COMMAND) this.stop("Unrecognized command");
|
||||
if(ret == EnumStatementReturn.PARAMETER_ERROR) this.stop("Parameter error");
|
||||
if(ret == EnumStatementReturn.UNDEFINED) this.stop("Undefined behavior");
|
||||
}
|
||||
if(ret == EnumStatementReturn.SKIP) i--;
|
||||
} catch(Exception ex) {
|
||||
this.stop("Evaluation unsuccessful");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.networkPackNT(15);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(String reason) {
|
||||
this.isOn = false;
|
||||
this.ctx.turnOff();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ByteBuf buf) {
|
||||
@ -53,6 +102,49 @@ public class TileEntityRadioAUTOCAL extends TileEntityTickingBase implements ICo
|
||||
this.autoReboot = buf.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
super.readFromNBT(nbt);
|
||||
|
||||
this.isOn = nbt.getBoolean("isOn");
|
||||
this.ignoreError = nbt.getBoolean("ignoreError");
|
||||
this.autoReboot = nbt.getBoolean("autoReboot");
|
||||
|
||||
this.ctx = new ParseContext(null);
|
||||
this.ctx.current = nbt.getInteger("current");
|
||||
this.ctx.clockSpeed = nbt.getInteger("clockSpeed");
|
||||
this.ctx.buffer = nbt.getString("buffer");
|
||||
|
||||
NBTTagList lineList = nbt.getTagList("script", 8);
|
||||
this.script = new String[lineList.tagList.size()];
|
||||
for(int i = 0; i < script.length; i++) {
|
||||
this.script[i] = lineList.getStringTagAt(i);
|
||||
this.msesv1.generateJumpPoints(ctx, script[i], i);
|
||||
}
|
||||
|
||||
this.ctx.variables = nbt.getCompoundTag("variables");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound nbt) {
|
||||
super.writeToNBT(nbt);
|
||||
|
||||
nbt.setBoolean("isOn", isOn);
|
||||
nbt.setBoolean("ignoreError", ignoreError);
|
||||
nbt.setBoolean("autoReboot", autoReboot);
|
||||
|
||||
nbt.setInteger("current", ctx.current);
|
||||
nbt.setInteger("clockSpeed", ctx.clockSpeed);
|
||||
nbt.setString("buffer", ctx.buffer);
|
||||
|
||||
NBTTagList lineList = new NBTTagList();
|
||||
for(String line : this.script) {
|
||||
lineList.appendTag(new NBTTagString(line));
|
||||
}
|
||||
nbt.setTag("script", lineList);
|
||||
nbt.setTag("variables", this.ctx.variables);
|
||||
}
|
||||
|
||||
@Override public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { return null; }
|
||||
@Override public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { return new GUIScreenRadioAUTOCAL(this); }
|
||||
|
||||
@ -63,10 +155,23 @@ public class TileEntityRadioAUTOCAL extends TileEntityTickingBase implements ICo
|
||||
|
||||
@Override
|
||||
public void receiveControl(NBTTagCompound data) {
|
||||
if(data.hasKey("on")) this.isOn = !this.isOn;
|
||||
if(data.hasKey("on")) {
|
||||
if(this.isOn) stop("User requested shutdown");
|
||||
else this.isOn = true;
|
||||
}
|
||||
if(data.hasKey("ignore")) this.ignoreError = !this.ignoreError;
|
||||
if(data.hasKey("auto")) this.autoReboot = !this.autoReboot;
|
||||
|
||||
if(data.hasKey("payload")) {
|
||||
this.ctx.jmp.clear();
|
||||
this.script = data.getString("payload").split("\n");
|
||||
for(int i = 0; i < script.length; i++) {
|
||||
script[i] = script[i].trim();
|
||||
this.msesv1.generateJumpPoints(ctx, script[i], i);
|
||||
}
|
||||
if(this.isOn) stop("Script has changed");
|
||||
}
|
||||
|
||||
this.markChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user