Skip to content

Instantly share code, notes, and snippets.

@aadnk
Last active December 17, 2015 00:38
Show Gist options
  • Save aadnk/5522005 to your computer and use it in GitHub Desktop.
Save aadnk/5522005 to your computer and use it in GitHub Desktop.
Read-eval-print loop in CraftBukkit.
package com.comphenix.example;
import java.util.concurrent.TimeUnit;
import javax.script.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.*;
import org.bukkit.conversations.*;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.util.concurrent.Uninterruptibles;
public class REPLBukkit extends JavaPlugin implements Listener {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
public synchronized boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (command.getName().equals("js") && sender instanceof Conversable) {
((Conversable) sender).beginConversation(new Conversation(this, (Conversable) sender, new StringPrompt() {
private String lastLine = "", lines = "";
private volatile int state;
private int lineCount = 0;
public String getPromptText(ConversationContext context) { return lastLine; }
public Prompt acceptInput(final ConversationContext context, String line) {
lines += (lastLine = line) + "\n";
lineCount++;
Thread t = new Thread(new Runnable() {
public void run() {
try {
state = 0; // State.INTERRUPTED
context.getForWhom().sendRawMessage("> " + engine.eval(lines));
state = 1; // State.DONE
} catch (Exception e) {
if (!(e instanceof ScriptException) || ((ScriptException) e).getLineNumber() != lineCount) {
for (String errorLine : ExceptionUtils.getMessage(e).split("/n"))
context.getForWhom().sendRawMessage(ChatColor.RED + errorLine);
state = 1; // State.DONE
} else
state = 2; // State.MORE_LINES
}
}
});
t.start();
Uninterruptibles.joinUninterruptibly(t, 5, TimeUnit.SECONDS);
if (state == 0) t.stop();
return state == 2 ? this : Prompt.END_OF_CONVERSATION;
}
}) {{ localEchoEnabled = false; }});
((Conversable) sender).acceptConversationInput(StringUtils.join(args, " "));
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment