import java.math.*;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.*;
import java.security.spec.*;
import java.security.*;
import java.lang.management.*;
import java.lang.ref.*;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import javax.swing.table.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.*;
import java.util.regex.*;
import java.util.List;
import java.util.zip.*;
import java.util.*;
public class main {
static class MultiMap {
Map> data = new HashMap>();
public void put(A key, B value) {
List list = data.get(key);
if (list == null)
data.put(key, list = new ArrayList());
list.add(value);
}
public void putAll(A key, Collection values) {
for (B value : values)
put(key, value);
}
public List get(A key) {
List list = data.get(key);
return list == null ? Collections. emptyList() : list;
}
public Set keySet() {
return data.keySet();
}
public void remove(A key) {
data.remove(key);
}
public void remove(A key, B value) {
List list = data.get(key);
if (list != null) {
list.remove(value);
if (list.isEmpty())
data.remove(key);
}
}
public void clear() {
data.clear();
}
public boolean containsKey(A key) {
return data.containsKey(key);
}
public B getFirst(A key) {
List list = get(key);
return list.isEmpty() ? null : list.get(0);
}
}
static MultiMap map = new MultiMap();
static String name = "Multi Assoc Bot";
static boolean chatEnabled = true;
public static void main(String[] args) throws Exception {
readLocally("map");
makeAndroid3(name + " at " + getComputerID() + ".");
if (chatEnabled)
toChat();
}
static void toChat() {
while (true) {
try {
for (ChatLine l : suckHumans(name))
sayInWebChat(name, answer(l.text));
} catch (Throwable __e) { __e.printStackTrace(); }
sleep(1000);
}
}
static List lookup(String s) {
return map.get(simplify(s));
}
// should simplify a sentence neatly
static String simplify(String s) {
// TODO: probably leave case of quoted strings intact
String result = join(" ", codeTokensOnly(tokensToLowerCase(nlTok(s))));
print(s);
print("=> " + result);
return result;
}
static synchronized String answer(String input) {
List tok = nlTok(input);
int idx = tok.indexOf("=");
if (idx >= 0) {
String l = join(tok.subList(0, idx)).trim();
String r = join(tok.subList(idx+1, l(tok))).trim();
l = simplify(l);
List values = map.get(l);
int i = indexOfSentence(values, r);
// standard case (new value())
if (i < 0) {
map.put(l, r);
saveLocally("map");
return "ok, added";
}
// already latest value
if (i == values.size()-1)
return "yup, i know :)";
// reordering case
values.add(r);
values.remove(i);
saveLocally("map");
return "ok, moving value to end";
}
List values = lookup(input);
if (values.isEmpty()) return null;
return input + "=" + join(", ", values);
}
static int indexOfSentence(List l, String sentence) {
sentence = simplify(sentence);
for (int i = 0; i < l(l); i++)
if (eq(simplify(l.get(i)), sentence))
return i;
return -1;
}
static List nlTok(String s) {
return javaTokPlusPeriod(s);
}
// Suck only human postings of web chat
static List suckHumans(String myName) {
List lines = new ArrayList();
for (ChatLine l : suckWebChat(myName))
if (!l.isBot)
lines.add(l);
return lines;
}
static void sayInWebChat(String botName, String line) {
if (botName == null || line == null) return;
loadPage("tinybrain.de:8080/tb-int/groupchat.json.botsay.php?name=" + urlencode(botName) + "&line=" + urlencode(line));
}
static int l(Object[] array) {
return array == null ? 0 : array.length;
}
static int l(List list) {
return list == null ? 0 : list.size();
}
static int l(String s) {
return s == null ? 0 : s.length();
}
static abstract class DialogIO {
String line;
boolean eos;
abstract String readLineImpl();
abstract boolean isStillConnected();
abstract void sendLine(String line);
abstract boolean isLocalConnection();
abstract Socket getSocket();
abstract void close();
int getPort() { return getSocket().getPort(); }
boolean helloRead;
String readLineNoBlock() {
String l = line;
line = null;
return l;
}
boolean waitForLine() { try {
if (line != null) return true;
//print("Readline");
line = readLineImpl();
//print("Readline done: " + line);
if (line == null) eos = true;
return line != null;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
String readLine() {
waitForLine();
helloRead = true;
return readLineNoBlock();
}
String ask(String s, Object... args) {
if (!helloRead) readLine();
if (args.length != 0) s = format3(s, args);
sendLine(s);
return readLine();
}
String askLoudly(String s, Object... args) {
if (!helloRead) readLine();
if (args.length != 0) s = format3(s, args);
print("> " + s);
sendLine(s);
String answer = readLine();
print("< " + answer);
return answer;
}
void pushback(String l) {
if (line != null)
fail();
line = l;
helloRead = false;
}
}
static abstract class DialogHandler {
abstract void run(DialogIO io);
} // Dialog classes
static class Android3 {
String greeting;
boolean publicOverride; // optionally set this in client
int startPort = 5000; // optionally set this in client
Responder responder;
boolean console = true;
boolean daemon = false;
boolean incomingSilent = false;
boolean useMultiPort = true;
// set by system
int port;
long vport;
DialogHandler handler;
ServerSocket server;
Android3(String greeting) {
this.greeting = greeting;}
Android3() {}
synchronized void dispose() {
if (server == null) return;
try {
server.close();
} catch (IOException e) {
print("[internal] " + e);
}
server = null;
}
}
static abstract class Responder {
abstract String answer(String s, List history);
}
static Android3 makeAndroid3(final String greeting) {
return makeAndroid3(new Android3(greeting));
}
static Android3 makeAndroid3(final String greeting, Responder responder) {
Android3 android = new Android3(greeting);
android.responder = responder;
return makeAndroid3(android);
}
static Android3 makeAndroid3(final Android3 a) {
if (a.responder == null)
a.responder = new Responder() {
String answer(String s, List history) {
return callStaticAnswerMethod(s, history);
}
};
if (a.useMultiPort) {
a.vport = addToMultiPort(a.greeting, a.responder);
if (a.vport == 1)
makeAndroid3_handleConsole(a);
return a;
}
print(a.greeting);
a.handler = makeAndroid3_makeDialogHandler(a);
a.port = a.daemon
? startDialogServerOnPortAboveDaemon(a.startPort, a.handler)
: startDialogServerOnPortAbove(a.startPort, a.handler);
a.server = startDialogServer_serverSocket;
if (a.console && makeAndroid3_consoleInUse()) a.console = false;
if (a.console)
makeAndroid3_handleConsole(a);
record(a);
return a;
}
static void makeAndroid3_handleConsole(final Android3 a) {
// Console handling stuff
print("You may also type on this console.");
Thread _t_0 = new Thread() {
public void run() {
try {
List history = new ArrayList();
String line;
while ((line = readLine()) != null) {
if ("bye".equals(line)) {
print("> bye stranger");
history = new ArrayList();
} else {
history.add(line);
history.add(makeAndroid3_getAnswer(line, history, a)); // prints answer on console too
}
}
} catch (Exception _e) {
throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
};
_t_0.start();
}
static DialogHandler makeAndroid3_makeDialogHandler(final Android3 a) {
return new DialogHandler() {
public void run(final DialogIO io) {
if (!a.publicOverride && !(publicCommOn() || io.isLocalConnection())) {
io.sendLine("Sorry, not allowed");
return;
}
String dialogID = randomID(8);
io.sendLine(a.greeting + " / Your ID: " + dialogID);
List history = new ArrayList();
while (io.isStillConnected()) {
if (io.waitForLine()) {
final String line = io.readLineNoBlock();
String s = dialogID + " at " + now() + ": " + quote(line);
if (!a.incomingSilent)
print(s);
if ("bye".equals(line)) {
io.sendLine("bye stranger");
return;
}
Matches m = new Matches();
history.add(line);
String answer;
if (match3("this is a continuation of talk *", s, m)
|| match3("hello bot! this is a continuation of talk *", s, m)) {
dialogID = unquote(m.m[0]);
answer = "ok";
} else
answer = makeAndroid3_getAnswer(line, history, a);
history.add(answer);
io.sendLine(answer);
//appendToLog(logFile, s);
}
}
}};
}
static String makeAndroid3_getAnswer(String line, List history, Android3 a) {
String answer;
try {
answer = makeAndroid3_fallback(line, history, a.responder.answer(line, history));
} catch (Throwable e) {
e = getInnerException(e);
e.printStackTrace();
answer = e.toString();
}
if (!a.incomingSilent)
print("> " + shorten(answer, 500));
return answer;
}
static String makeAndroid3_fallback(String s, List history, String answer) {
// Now we only do the safe thing instead of VM inspection - give out our process ID
if (answer == null && match3("what is your pid", s))
return getPID();
if (answer == null && match3("what is your program id", s)) // should be fairly safe, right?
return getProgramID();
if (match3("get injection id", s))
return getInjectionID();
if (answer == null) answer = "?";
if (answer.indexOf('\n') >= 0 || answer.indexOf('\r') >= 0)
answer = quote(answer);
return answer;
}
static boolean makeAndroid3_consoleInUse() {
for (Object o : record_list)
if (o instanceof Android3 && ((Android3) o).console)
return true;
return false;
}
static String getComputerID() { try {
return computerID();
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static List codeTokensOnly(List tok) {
List l = new ArrayList();
for (int i = 1; i < tok.size(); i += 2)
l.add(tok.get(i));
return l;
}
//1001045 // double var remover
static synchronized void saveLocally(String variableName) {
File textFile = new File(programDir(programID()), variableName + ".text");
File structureFile = new File(programDir(programID()), variableName + ".structure");
Object x = get(main.class, variableName);
if (x == null) {
textFile.delete();
structureFile.delete();
} else if (x instanceof String) {
structureFile.delete();
saveTextFile(textFile, (String) x);
} else {
textFile.delete();
saveTextFile(structureFile, structure(x));
}
}
// read a string variable from standard storage
// does not overwrite variable contents if there is no file
static synchronized void readLocally(String varNames) {
for (String variableName : codeTokensOnly(javaTok(varNames))) {
File textFile = new File(programDir(programID()), variableName + ".text");
File structureFile = new File(programDir(programID()), variableName + ".structure");
String value = loadTextFile(textFile);
if (value != null)
set(main.class, variableName, value);
else {
value = loadTextFile(structureFile);
if (value != null)
readLocally_set(main.class, variableName, unstructure(value));
}
}
}
static void readLocally_set(Class c, String varName, Object value) {
Object oldValue = get(c, varName);
if (oldValue instanceof List && !(oldValue instanceof ArrayList) && value != null) {
// Assume it's a synchroList.
value = synchroList((List) value);
}
set(c, varName, value);
}
static boolean eq(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
static List tokensToLowerCase(List tok) {
tok = new ArrayList(tok);
for (int i = 1; i < tok.size(); i += 2)
tok.set(i, tok.get(i).toLowerCase());
return tok;
}
static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (Exception e) { throw new RuntimeException(e); }
}
static void sleep() { try {
print("Sleeping.");
synchronized(main.class) { main.class.wait(); }
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static StringBuffer print_log;
static void print() {
print("");
}
static void print(Object o) {
String s = String.valueOf(o) + "\n";
synchronized(StringBuffer.class) {
if (print_log == null) print_log = new StringBuffer();
}
print_log.append(s);
System.out.print(s);
}
static void print(long l) {
print(String.valueOf(l));
}
public static String join(String glue, Iterable strings) {
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String[] strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(Iterable strings) {
return join("", strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String callStaticAnswerMethod(List bots, String s) {
for (Class c : bots) try {
String answer = callStaticAnswerMethod(c, s);
if (answer != null) return answer;
} catch (Throwable e) {
print("Error calling " + getProgramID(c));
e.printStackTrace();
}
return null;
}
static String callStaticAnswerMethod(Class c, String s) {
String answer = (String) callOpt(c, "answer", s, litlist(s));
if (answer == null)
answer = (String) callOpt(c, "answer", s);
return answer;
}
static String callStaticAnswerMethod(String s, List history) {
String answer = (String) callOpt(getMainClass(), "answer", s, history);
if (answer == null)
answer = (String) callOpt(getMainClass(), "answer", s);
return answer;
}
static String getInjectionID() {
return (String) call(getJavaX(), "getInjectionID", getMainClass());
}
static Object addToMultiPort_responder;
static long addToMultiPort(final String botName) {
return addToMultiPort(botName, new Object() {
public String answer(String s, List history) {
String answer = (String) ( callOpt(getMainClass(), "answer", s, history));
if (answer != null) return answer;
answer = (String) callOpt(getMainClass(), "answer", s);
if (answer != null) return answer;
if (match3("get injection id", s))
return getInjectionID();
return null;
}
});
}
static long addToMultiPort(final String botName, final Object responder) {
print(botName);
addToMultiPort_responder = responder;
startMultiPort();
List ports = getMultiPorts();
if (ports.isEmpty())
fail("No multiports!");
if (ports.size() > 1)
print("Multiple multi-ports. Using last one.");
Object port = last(ports);
Object responder2 = new Object() {
public String answer(String s, List history) {
if (match3("get injection id", s))
return getInjectionID();
if (match3("your name", s))
return botName;
return (String) call(responder, "answer", s, history);
}
};
record(responder2);
return (Long) call(port, "addResponder", botName, responder2);
}
static class ChatLine {
String who, text;
boolean isBot;
}
static int suckWebChat_lastID;
static long suckWebChat_lastSuck;
static List suckWebChat(String myName) {
if (now() < suckWebChat_lastSuck + 500)
print("Warning: Sucking a lot :)");
suckWebChat_lastSuck = now();
int n = suckWebChat_lastID == 0 ? 1 : 1000;
Map data = (Map) jsonDecode(loadPageSilently("tinybrain.de:8080/tb-int/groupchat.json.lines.php?fromID=" + suckWebChat_lastID + "&n=" + n
+ "&who=" + urlencode(myName)));
List