package com.laytonsmith.tools;
import com.laytonsmith.PureUtilities.Common.FileUtil;
import com.laytonsmith.PureUtilities.Common.MutableObject;
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.PureUtilities.LimitedQueue;
import com.laytonsmith.PureUtilities.RunnableQueue;
import com.laytonsmith.PureUtilities.SignalHandler;
import com.laytonsmith.PureUtilities.SignalType;
import com.laytonsmith.PureUtilities.Signals;
import com.laytonsmith.PureUtilities.TermColors;
import com.laytonsmith.abstraction.AbstractConvertor;
import com.laytonsmith.abstraction.Implementation;
import com.laytonsmith.abstraction.MCColor;
import com.laytonsmith.abstraction.MCEnchantment;
import com.laytonsmith.abstraction.MCEntity;
import com.laytonsmith.abstraction.MCFireworkBuilder;
import com.laytonsmith.abstraction.MCInventory;
import com.laytonsmith.abstraction.MCItemMeta;
import com.laytonsmith.abstraction.MCItemStack;
import com.laytonsmith.abstraction.MCLocation;
import com.laytonsmith.abstraction.MCMetadataValue;
import com.laytonsmith.abstraction.MCNote;
import com.laytonsmith.abstraction.MCPattern;
import com.laytonsmith.abstraction.MCPlugin;
import com.laytonsmith.abstraction.MCPluginMeta;
import com.laytonsmith.abstraction.MCPotionData;
import com.laytonsmith.abstraction.MCRecipe;
import com.laytonsmith.abstraction.MCServer;
import com.laytonsmith.abstraction.MCWorld;
import com.laytonsmith.abstraction.blocks.MCMaterial;
import com.laytonsmith.abstraction.enums.MCDyeColor;
import com.laytonsmith.abstraction.enums.MCPatternShape;
import com.laytonsmith.abstraction.enums.MCPotionType;
import com.laytonsmith.abstraction.enums.MCRecipeType;
import com.laytonsmith.abstraction.enums.MCTone;
import com.laytonsmith.annotations.api;
import com.laytonsmith.annotations.convert;
import com.laytonsmith.commandhelper.CommandHelperPlugin;
import com.laytonsmith.core.Installer;
import com.laytonsmith.core.LogLevel;
import com.laytonsmith.core.Main;
import com.laytonsmith.core.MethodScriptCompiler;
import com.laytonsmith.core.MethodScriptComplete;
import com.laytonsmith.core.MethodScriptFileLocations;
import com.laytonsmith.core.ParseTree;
import com.laytonsmith.core.Prefs;
import com.laytonsmith.core.Profiles;
import com.laytonsmith.core.Static;
import com.laytonsmith.core.constructs.CArray;
import com.laytonsmith.core.constructs.CClassType;
import com.laytonsmith.core.constructs.CClosure;
import com.laytonsmith.core.constructs.CString;
import com.laytonsmith.core.constructs.IVariable;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.constructs.Token;
import com.laytonsmith.core.constructs.Variable;
import com.laytonsmith.core.environments.Environment;
import com.laytonsmith.core.environments.GlobalEnv;
import com.laytonsmith.core.environments.InvalidEnvironmentException;
import com.laytonsmith.core.events.Driver;
import com.laytonsmith.core.events.EventUtils;
import com.laytonsmith.core.events.drivers.CmdlineEvents;
import com.laytonsmith.core.exceptions.CRE.CREFormatException;
import com.laytonsmith.core.exceptions.CancelCommandException;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.core.exceptions.FunctionReturnException;
import com.laytonsmith.core.functions.FunctionBase;
import com.laytonsmith.core.functions.FunctionList;
import com.laytonsmith.core.profiler.ProfilePoint;
import com.laytonsmith.persistence.DataSourceException;
import com.laytonsmith.tools.docgen.DocGenTemplates;
import jline.console.ConsoleReader;
import jline.console.completer.ArgumentCompleter;
import jline.console.completer.StringsCompleter;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import static com.laytonsmith.PureUtilities.TermColors.BLUE;
import static com.laytonsmith.PureUtilities.TermColors.RED;
import static com.laytonsmith.PureUtilities.TermColors.YELLOW;
import static com.laytonsmith.PureUtilities.TermColors.p;
import static com.laytonsmith.PureUtilities.TermColors.pl;
import static com.laytonsmith.PureUtilities.TermColors.reset;
/**
* This is a command line implementation of the in game interpreter mode. This
* should only be run while the server is stopped, as it has full access to
* filesystem resources. Many things won't work as intended, but pure abstract
* functions should still work fine.
*/
public final class Interpreter {
/**
* THIS MUST NEVER EVER EVER EVER EVER EVER EVER CHANGE. EVER.
*
* BAD THINGS WILL HAPPEN TO EVERYBODY YOU LOVE IF THIS IS CHANGED!
*/
private static final String INTERPRETER_INSTALLATION_LOCATION = "/usr/local/bin/mscript";
private boolean inTTYMode = false;
private boolean multilineMode = false;
private String script = "";
private Environment env;
private Thread scriptThread = null;
private volatile boolean isExecuting = false;
private final Queue<String> commandHistory = new LimitedQueue<>(MAX_COMMAND_HISTORY);
/**
* If they mash ctrlC a bunch, they probably really want to quit, so we'll
* keep track of this, and reset it only if they then run an actual command.
*/
private volatile int ctrlCcount = 0;
/**
* After this many mashes of Ctrl+C, clearly they want to exit, so we'll
* exit the shell.
*/
private static final int MAX_CTRL_C_MASHES = 5;
/**
* Max commands that are tracked.
*/
private static final int MAX_COMMAND_HISTORY = 100;
public static void startWithTTY(String file, List<String> args) throws IOException, DataSourceException, URISyntaxException, Profiles.InvalidProfileException {
File fromFile = new File(file).getCanonicalFile();
Interpreter interpreter = new Interpreter(args, fromFile.getParentFile().getPath(), true);
try {
interpreter.execute(FileUtil.read(fromFile), args, fromFile);
} catch (ConfigCompileException ex) {
ConfigRuntimeException.HandleUncaughtException(ex, null, null);
StreamUtils.GetSystemOut().println(TermColors.reset());
System.exit(1);
} catch(ConfigCompileGroupException ex){
ConfigRuntimeException.HandleUncaughtException(ex, null);
StreamUtils.GetSystemOut().println(TermColors.reset());
System.exit(1);
}
}
private String getHelpMsg(){
String msg = YELLOW + "You are now in cmdline interpreter mode. Use exit() to exit, and >>> to enter"
+ " multiline mode.";
try {
msg += "\nYour current working directory is: " + env.getEnv(GlobalEnv.class).GetRootFolder().getCanonicalPath();
} catch (IOException ex) {
//
}
return msg;
}
/**
* Creates a new Interpreter object. This object can then be manipulated via
* the cmdline interactively, or standalone, via the execute method.
*
* @param args Any arguments passed in to the script. They are set as $vars
* @param cwd The initial working directory.
* @throws IOException
* @throws DataSourceException
* @throws URISyntaxException
*/
public Interpreter(List<String> args, String cwd) throws IOException, DataSourceException, URISyntaxException, Profiles.InvalidProfileException {
this(args, cwd, false);
}
private Interpreter(List<String> args, String cwd, boolean inTTYMode) throws IOException, DataSourceException, URISyntaxException, Profiles.InvalidProfileException {
doStartup();
env.getEnv(GlobalEnv.class).SetRootFolder(new File(cwd));
if(inTTYMode){
//Ok, done. They'll have to execute from here.
return;
}
//We have two modes here, piped input, or interactive console.
if (System.console() == null) {
Scanner scanner = new Scanner(System.in);
//We need to read in everything, it's basically in multiline mode
StringBuilder script = new StringBuilder();
String line;
try {
while ((line = scanner.nextLine()) != null) {
script.append(line).append("\n");
}
} catch (NoSuchElementException e) {
//Done
}
try {
execute(script.toString(), args);
StreamUtils.GetSystemOut().print(TermColors.reset());
System.exit(0);
} catch (ConfigCompileException ex) {
ConfigRuntimeException.HandleUncaughtException(ex, null, null);
StreamUtils.GetSystemOut().print(TermColors.reset());
System.exit(1);
} catch(ConfigCompileGroupException ex){
ConfigRuntimeException.HandleUncaughtException(ex, null);
StreamUtils.GetSystemOut().println(TermColors.reset());
System.exit(1);
}
} else {
final ConsoleReader reader = new ConsoleReader();
reader.setExpandEvents(false);
//Get a list of all the function names. This will be provided to the auto completer.
Set<FunctionBase> functions = FunctionList.getFunctionList(api.Platforms.INTERPRETER_JAVA);
List<String> names = new ArrayList<>();
for(FunctionBase f : functions){
if(f.appearInDocumentation()){
names.add(f.getName());
}
}
reader.addCompleter(new ArgumentCompleter(new ArgumentCompleter.AbstractArgumentDelimiter() {
@Override
public boolean isDelimiterChar(CharSequence buffer, int pos) {
char c = buffer.charAt(pos);
return !Character.isLetter(c) && c != '_';
}
}, new StringsCompleter(names){
@Override
public int complete(String buffer, int cursor, List<CharSequence> candidates) {
//The autocomplete can be improved a bit, instead of putting a space after it,
//let's put a parenthesis.
int ret = super.complete(buffer, cursor, candidates);
if(candidates.size() == 1){
String functionName = candidates.get(0).toString().trim();
candidates.set(0, functionName + "()");
}
return ret;
}
}));
while(true){
String prompt;
if(multilineMode){
prompt = TermColors.WHITE + ">" + reset();
} else {
prompt = getPrompt();
}
String line = reader.readLine(prompt);
if(!textLine(line)){
break;
}
}
//Perhaps this code will be revisited in the future, so that more things
//can be done, like syntax highlighting, function keys, etc, but in order
//to do that, history, command completion, etc, will all have to be re-implemented,
//and implemented around readCharacter, which is a lot of work.
// p(getPrompt());
// boolean exit = false;
// while(true){
// jline.console.ConsoleReader reader = new jline.console.ConsoleReader();
// StringBuilder line = new StringBuilder();
// while(true){
// int c = reader.readCharacter();
// if(c == 27){
// //Escape sequence
// int c2 = reader.readCharacter();
// if(c2 == 79){
// //F1-F4
// int c3 = reader.readCharacter();
// if(c3 == 80){
// //F1
// StreamUtils.GetSystemOut().println("F1");
// continue;
// } else if(c3 == 81){
// //F2
// StreamUtils.GetSystemOut().println("F2");
// continue;
// } else if(c3 == 82){
// //F3
// StreamUtils.GetSystemOut().println("F3");
// continue;
// } else if(c3 == 83){
// //F4
// StreamUtils.GetSystemOut().println("F4");
// continue;
// }
// } else if(c2 == 91){
// //At least 3 characters
// int c3 = reader.readCharacter();
// if(c3 == 68){
// //Left arrow
// StreamUtils.GetSystemOut().println("Left Arrow");
// continue;
// } else if(c3 == 65){
// //Up Arrow
// StreamUtils.GetSystemOut().println("Up Arrow");
// continue;
// } else if(c3 == 66){
// //Down Arrow
// StreamUtils.GetSystemOut().println("Down Arrow");
// continue;
// } else if(c3 == 67){
// //Right Arrow
// StreamUtils.GetSystemOut().println("Right Arrow");
// continue;
// } else if(c3 == 72){
// //Home
// StreamUtils.GetSystemOut().println("Home");
// continue;
// } else if(c3 == 70){
// //End
// StreamUtils.GetSystemOut().println("End");
// continue;
// } else {
// //At least 4 characters
// int c4 = reader.readCharacter();
// if(c4 == 126){
// if(c3 == 50){
// //Insert
// StreamUtils.GetSystemOut().println("Insert");
// continue;
// } else if(c3 == 51){
// //Delete
// StreamUtils.GetSystemOut().println("Delete");
// continue;
// } else if(c3 == 53){
// //Page Up
// StreamUtils.GetSystemOut().println("Page Up");
// continue;
// } else if(c3 == 54){
// //Page Down
// StreamUtils.GetSystemOut().println("Page Down");
// continue;
// }
// } else {
// //At least 5 characters
// int c5 = reader.readCharacter();
// if(c5 == 126){
// if(c3 == 49){
// if(c4 == 53){
// //F5
// StreamUtils.GetSystemOut().println("F5");
// continue;
// } else if(c4 == 55){
// //F6
// StreamUtils.GetSystemOut().println("F6");
// continue;
// } else if(c4 == 56){
// //F7
// StreamUtils.GetSystemOut().println("F7");
// continue;
// } else if(c4 == 57){
// //F8
// StreamUtils.GetSystemOut().println("F8");
// continue;
// }
// } else if(c3 == 50){
// if(c4 == 48){
// //F9
// StreamUtils.GetSystemOut().println("F9");
// continue;
// } else if(c4 == 49){
// //F10
// StreamUtils.GetSystemOut().println("F10");
// continue;
// } else if(c4 == 51){
// //F11
// StreamUtils.GetSystemOut().println("F11");
// continue;
// } else if(c4 == 52){
// //F12
// StreamUtils.GetSystemOut().println("F12");
// continue;
// }
// } else {
// //Unknown
// continue;
// }
// } else {
// //Unknown. This hopefully won't ever happen.
// continue;
// }
// }
// }
// } else {
// continue; //Unrecognized. Hopefully this will be fine?
// }
// }
// if(c == 13){ //"Enter" character
// //done, send the line in for processing
// StreamUtils.GetSystemOut().println();
// break;
// }
// if(c == 127){
// reader.moveCursor(-1);
// }
// line.append((char)c);
// reader.putString(Character.toString((char)c));
// }
// if(!textLine(line.toString())){
// exit = true;
// }
// if(multilineMode){
// p(">");
// } else {
// p(getPrompt());
// }
// }
}
}
private String getPrompt(){
CClosure c = (CClosure) env.getEnv(GlobalEnv.class).GetCustom("cmdline_prompt");
if(c != null){
try {
c.execute();
} catch(FunctionReturnException ex){
String val = ex.getReturn().val();
return Static.MCToANSIColors(val) + TermColors.RESET;
} catch(ConfigRuntimeException ex){
ConfigRuntimeException.HandleUncaughtException(ex, env);
}
}
return BLUE + ":" + TermColors.RESET;
}
private void doStartup() throws IOException, DataSourceException, URISyntaxException, Profiles.InvalidProfileException {
Installer.Install(MethodScriptFileLocations.getDefault().getConfigDirectory());
Installer.InstallCmdlineInterpreter();
env = Static.GenerateStandaloneEnvironment();
env.getEnv(GlobalEnv.class).SetCustom("cmdline", true);
if (Prefs.UseColors()) {
TermColors.EnableColors();
} else {
TermColors.DisableColors();
}
String auto_include = FileUtil.read(MethodScriptFileLocations.getDefault().getCmdlineInterpreterAutoIncludeFile());
try {
MethodScriptCompiler.execute(auto_include, MethodScriptFileLocations.getDefault().getCmdlineInterpreterAutoIncludeFile(), true, env, null, null, null);
} catch (ConfigCompileException ex) {
ConfigRuntimeException.HandleUncaughtException(ex, "Interpreter will continue to run, however.", null);
} catch (ConfigCompileGroupException ex){
ConfigRuntimeException.HandleUncaughtException(ex, null);
}
//Install our signal handlers.
SignalHandler.SignalCallback signalHandler = new SignalHandler.SignalCallback() {
@Override
public boolean handle(SignalType type) {
if(isExecuting){
env.getEnv(GlobalEnv.class).SetInterrupt(true);
if(scriptThread != null){
scriptThread.interrupt();
}
for(Thread t : env.getEnv(GlobalEnv.class).GetDaemonManager().getActiveThreads()){
t.interrupt();
}
} else {
ctrlCcount++;
if(ctrlCcount > MAX_CTRL_C_MASHES){
//Ok, ok, we get the hint.
StreamUtils.GetSystemOut().println();
StreamUtils.GetSystemOut().flush();
System.exit(130); //Standard Ctrl+C exit code
}
pl(YELLOW + "\nUse exit() to exit the shell." + reset());
p(getPrompt());
}
return true;
}
};
try {
SignalHandler.addHandler(Signals.SIGTERM, signalHandler);
} catch(IllegalArgumentException ex){
// Oh well.
}
try {
SignalHandler.addHandler(Signals.SIGINT, signalHandler);
} catch (IllegalArgumentException ex){
// Oh well again.
}
}
/**
* This evaluates each line of text
* @param line
* @return
* @throws IOException
*/
private boolean textLine(String line) throws IOException {
switch (line) {
case "-":
//Exit interpreter mode
return false;
case ">>>":
//Start multiline mode
if (multilineMode) {
pl(RED + "You are already in multiline mode!");
} else {
multilineMode = true;
pl(YELLOW + "You are now in multiline mode. Type <<< on a line by itself to execute.");
} break;
case "<<<":
//Execute multiline
multilineMode = false;
try {
execute(script, null);
script = "";
} catch (ConfigCompileException e) {
ConfigRuntimeException.HandleUncaughtException(e, null, null);
} catch(ConfigCompileGroupException e){
ConfigRuntimeException.HandleUncaughtException(e, null);
}
break;
default:
if (multilineMode) {
//Queue multiline
script = script + line + "\n";
} else {
try {
//Execute single line
execute(line, null);
} catch (ConfigCompileException ex) {
ConfigRuntimeException.HandleUncaughtException(ex, null, null);
} catch(ConfigCompileGroupException ex){
ConfigRuntimeException.HandleUncaughtException(ex, null);
}
} break;
}
return true;
}
/**
* This executes a script
* @param script
* @param args
* @throws ConfigCompileException
* @throws IOException
*/
public void execute(String script, List<String> args) throws ConfigCompileException, IOException, ConfigCompileGroupException {
execute(script, args, null);
}
/**
* This executes an entire script. The cmdline_prompt_event is first triggered (if used) and
* if the event is cancelled, nothing happens.
* @param script
* @param args
* @param fromFile
* @throws ConfigCompileException
* @throws IOException
*/
public void execute(String script, List<String> args, File fromFile) throws ConfigCompileException, IOException, ConfigCompileGroupException {
CmdlineEvents.cmdline_prompt_input.CmdlinePromptInput input = new CmdlineEvents.cmdline_prompt_input.CmdlinePromptInput(script);
EventUtils.TriggerListener(Driver.CMDLINE_PROMPT_INPUT, "cmdline_prompt_input", input);
if(input.isCancelled()){
return;
}
ctrlCcount = 0;
if("exit".equals(script)){
pl(YELLOW + "Use exit() if you wish to exit.");
return;
}
if("help".equals(script)){
pl(getHelpMsg());
return;
}
if (fromFile == null) {
fromFile = new File("Interpreter");
}
isExecuting = true;
ProfilePoint compile = env.getEnv(GlobalEnv.class).GetProfiler().start("Compilation", LogLevel.VERBOSE);
final ParseTree tree;
try {
List<Token> stream = MethodScriptCompiler.lex(script, fromFile, true);
tree = MethodScriptCompiler.compile(stream);
} finally {
compile.stop();
}
//Environment env = Environment.createEnvironment(this.env.getEnv(GlobalEnv.class));
final List<Variable> vars = new ArrayList<>();
if (args != null) {
//Build the @arguments variable, the $ vars, and $ itself. Note that
//we have special handling for $0, that is the script name, like bash.
//However, it doesn't get added to either $ or @arguments, due to the
//uncommon use of it.
StringBuilder finalArgument = new StringBuilder();
CArray arguments = new CArray(Target.UNKNOWN);
{
//Set the $0 argument
Variable v = new Variable("$0", "", Target.UNKNOWN);
v.setVal(fromFile.toString());
v.setDefault(fromFile.toString());
vars.add(v);
}
for (int i = 0; i < args.size(); i++) {
String arg = args.get(i);
if (i > 0) {
finalArgument.append(" ");
}
Variable v = new Variable("$" + Integer.toString(i + 1), "", Target.UNKNOWN);
v.setVal(new CString(arg, Target.UNKNOWN));
v.setDefault(arg);
vars.add(v);
finalArgument.append(arg);
arguments.push(new CString(arg, Target.UNKNOWN), Target.UNKNOWN);
}
Variable v = new Variable("$", "", false, true, Target.UNKNOWN);
v.setVal(new CString(finalArgument.toString(), Target.UNKNOWN));
v.setDefault(finalArgument.toString());
vars.add(v);
env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(new CClassType("array", Target.UNKNOWN), "@arguments", arguments, Target.UNKNOWN));
}
try {
ProfilePoint p = this.env.getEnv(GlobalEnv.class).GetProfiler().start("Interpreter Script", LogLevel.ERROR);
try {
final MutableObject<Throwable> wasThrown = new MutableObject<>();
scriptThread = new Thread(new Runnable() {
@Override
public void run() {
try {
MethodScriptCompiler.execute(tree, env, new MethodScriptComplete() {
@Override
public void done(String output) {
if(System.console() != null && !"".equals(output.trim())){
StreamUtils.GetSystemOut().println(output);
}
}
}, null, vars);
} catch (CancelCommandException e) {
//Nothing, though we could have been Ctrl+C cancelled, so we need to reset
//the interrupt flag. But we do that unconditionally below, in the finally,
//in the other thread.
} catch (ConfigRuntimeException e) {
ConfigRuntimeException.HandleUncaughtException(e, env);
//No need for the full stack trace
if (System.console() == null) {
System.exit(1);
}
} catch (NoClassDefFoundError e) {
StreamUtils.GetSystemErr().println(RED + Main.getNoClassDefFoundErrorMessage(e) + reset());
StreamUtils.GetSystemErr().println("Since you're running from standalone interpreter mode, this is not a fatal error, but one of the functions you just used required"
+ " an actual backing engine that isn't currently loaded. (It still might fail even if you load the engine though.) You simply won't be"
+ " able to use that function here.");
if (System.console() == null) {
System.exit(1);
}
} catch (InvalidEnvironmentException ex) {
StreamUtils.GetSystemErr().println(RED + ex.getMessage() + " " + ex.getData() + "() cannot be used in this context.");
if (System.console() == null) {
System.exit(1);
}
} catch (RuntimeException e) {
pl(RED + e.toString());
e.printStackTrace(StreamUtils.GetSystemErr());
if (System.console() == null) {
System.exit(1);
}
}
}
}, "MethodScript-Main");
scriptThread.start();
try {
scriptThread.join();
} catch (InterruptedException ex) {
//
}
try {
env.getEnv(GlobalEnv.class).GetDaemonManager().waitForThreads();
} catch (InterruptedException ex) {
//
}
} finally {
p.stop();
}
} finally {
env.getEnv(GlobalEnv.class).SetInterrupt(false);
isExecuting = false;
}
}
public static void install() {
if (TermColors.SYSTEM == TermColors.SYS.UNIX) {
try {
URL jar = Interpreter.class.getProtectionDomain().getCodeSource().getLocation();
File exe = new File(INTERPRETER_INSTALLATION_LOCATION);
String bashScript = Static.GetStringResource("/interpreter-helpers/bash.sh");
try {
bashScript = bashScript.replaceAll("%%LOCATION%%", jar.toURI().getPath());
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
exe.createNewFile();
if (!exe.canWrite()) {
throw new IOException();
}
FileUtil.write(bashScript, exe);
exe.setExecutable(true, false);
File manDir = new File("/usr/local/man/man1");
if (manDir.exists()) {
//Don't do this installation if the man pages aren't already there.
String manPage = Static.GetStringResource("/interpreter-helpers/manpage");
manPage = DocGenTemplates.DoTemplateReplacement(manPage, DocGenTemplates.GetGenerators());
File manPageFile = new File(manDir, "mscript.1");
FileUtil.write(manPage, manPageFile);
}
} catch (IOException e) {
StreamUtils.GetSystemErr().println("Cannot install. You must run the command with sudo for it to succeed, however, did you do that?");
return;
}
} else {
StreamUtils.GetSystemErr().println("Sorry, cmdline functionality is currently only supported on unix systems! Check back soon though!");
return;
}
StreamUtils.GetSystemOut().println("MethodScript has successfully been installed on your system. Note that you may need to rerun the install command"
+ " if you change locations of the jar, or rename it. Be sure to put \"#!" + INTERPRETER_INSTALLATION_LOCATION + "\" at the top of all your scripts,"
+ " if you wish them to be executable on unix systems, and set the execution bit with chmod +x <script name> on unix systems.");
StreamUtils.GetSystemOut().println("Try this script to test out the basic features of the scripting system:\n");
StreamUtils.GetSystemOut().println(Static.GetStringResource("/interpreter-helpers/sample.ms"));
}
public static void uninstall() {
if (TermColors.SYSTEM == TermColors.SYS.UNIX) {
try {
File exe = new File(INTERPRETER_INSTALLATION_LOCATION);
if (!exe.delete()) {
throw new IOException();
}
} catch (IOException e) {
StreamUtils.GetSystemErr().println("Cannot uninstall. You must run the command with sudo for it to succeed, however, did you do that?");
return;
}
} else {
StreamUtils.GetSystemErr().println("Sorry, cmdline functionality is currently only supported on unix systems! Check back soon though!");
return;
}
StreamUtils.GetSystemOut().println("MethodScript has been uninstalled from this system.");
}
@convert(type = Implementation.Type.SHELL)
public static class ShellConvertor extends AbstractConvertor {
RunnableQueue queue = new RunnableQueue("ShellInterpreter-userland");
@Override
public MCLocation GetLocation(MCWorld w, double x, double y, double z, float yaw, float pitch) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public Class GetServerEventMixin() {
return ShellEventMixin.class;
}
@Override
public MCEnchantment[] GetEnchantmentValues() {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCEnchantment GetEnchantmentByName(String name) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCServer GetServer() {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemStack GetItemStack(int type, int qty) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemStack GetItemStack(int type, int data, int qty) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemStack GetItemStack(MCMaterial type, int qty) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemStack GetItemStack(MCMaterial type, int data, int qty) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemStack GetItemStack(String type, int qty) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemStack GetItemStack(String type, int data, int qty) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCPotionData GetPotionData(MCPotionType type, boolean extended, boolean upgraded) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public void Startup(CommandHelperPlugin chp) {
}
@Override
public int LookupItemId(String materialName) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public String LookupMaterialName(int id) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCEntity GetCorrectEntity(MCEntity e) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCInventory GetEntityInventory(MCEntity entity) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCInventory GetLocationInventory(MCLocation location) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCNote GetNote(int octave, MCTone tone, boolean sharp) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCColor GetColor(int red, int green, int blue) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCPattern GetPattern(MCDyeColor color, MCPatternShape shape) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCFireworkBuilder GetFireworkBuilder() {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCPluginMeta GetPluginMeta() {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCMaterial getMaterial(int id) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCItemMeta GetCorrectMeta(MCItemMeta im) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public List<MCEntity> GetEntitiesAt(MCLocation loc, double radius) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCRecipe GetNewRecipe(MCRecipeType type, MCItemStack result) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCRecipe GetRecipe(MCRecipe unspecific) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCMaterial GetMaterial(String name) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCMetadataValue GetMetadataValue(Object value, MCPlugin plugin) {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public String GetPluginName() {
return "MethodScript";
}
@Override
public MCPlugin GetPlugin() {
throw new UnsupportedOperationException("This method is not supported from a shell.");
}
@Override
public MCColor GetColor(String colorName, Target t) throws CREFormatException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String GetUser(Environment env) {
return System.getProperty("user.name");
}
}
}