package net.hexid.hexbot.bot;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import net.hexid.Utils;

public abstract class BotProcess extends Thread {
	private Process process;
	private Scanner in;
	protected Bot bot;

	public BotProcess(Bot bot) throws IOException {
		super();
		this.bot = bot;
		this.process = startProcess();
		this.in = new Scanner(this.process.getInputStream());
	}

	protected abstract void processInput(final String in);

	protected Process startProcess() throws IOException {
		List<String> botExecuteData = bot.getBotExecuteData();
		botExecuteData.add(0, "casperjs"); // program (will be added to PATH)
		botExecuteData.add(1, Bots.getBotFile(bot));

		String processData = Utils.join(" ", botExecuteData);
		String pathName;
		if(File.pathSeparator.equals(";")) { // if windows
			pathName = "Path";
			botExecuteData = Arrays.asList(new String[]{"cmd.exe", "/C", processData});
		} else { // if unix-based
			pathName = "PATH";
			botExecuteData = Arrays.asList(new String[]{"/usr/bin/env","bash", "-c", processData});
		}

		// create a processbuilder with the bot's commands and combined input and error streams
		ProcessBuilder pb = new ProcessBuilder(botExecuteData).redirectErrorStream(true);

		// append phantomjs and casperjs to the path (runs local installs first)
		pb.environment().put(pathName, Bots.getBotEnvPath(pb.environment().get(pathName)));

		return pb.start(); // execute the process
	}

	@Override public void run() {
		while(in.hasNext())
			processInput(in.nextLine());

		in.close();

		try {
			process.waitFor();
			bot.processExitCode(process.exitValue());
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void killProcess() {
		process.destroy();
	}
}
package net.hexid.hexbot.bot;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import net.hexid.Utils;

public abstract class BotProcess extends Thread {
	private Process process;
	private Scanner in;
	protected Bot bot;

	public BotProcess(Bot bot) throws IOException {
		super();
		this.bot = bot;
		this.process = startProcess();
		this.in = new Scanner(this.process.getInputStream());
	}

	protected abstract void processInput(final String in);

	protected Process startProcess() throws IOException {
		List<String> processData;
		String botExecuteData = Utils.join(" ", "casperjs", Bots.getBotFile(bot),
				Utils.join(" ", bot.getBotExecuteData()));
		String pathName;
		if(File.pathSeparator.equals(";")) { // if windows
			pathName = "Path";
			processData = Arrays.asList(new String[]{"cmd.exe", "/C", botExecuteData});
		} else { // if unix-based
			pathName = "PATH";
			processData = Arrays.asList(new String[]{"/usr/bin/env","bash", "-c", botExecuteData});
		}

		// create a processbuilder with the bot's commands and combined input and error streams
		ProcessBuilder pb = new ProcessBuilder(processData).redirectErrorStream(true);

		// append phantomjs and casperjs to the path (runs local installs first)
		pb.environment().put(pathName, Bots.getBotEnvPath(pb.environment().get(pathName)));

		return pb.start(); // execute the process
	}

	@Override public void run() {
		while(in.hasNext())
			processInput(in.nextLine());

		in.close();

		try {
			process.waitFor();
			bot.processExitCode(process.exitValue());
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void killProcess() {
		process.destroy();
	}
}
Allow for the use of bot.getBotExecuteData() returning String[] instead of ArrayList<String>