Warning: session_start(): open(/var/lib/php/sessions/sess_imu4q0ns3tmpmak5bmdr3qqj5e, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
public class main {
static String vmArgs = "-XX:+PrintGC -Xmx32m";
static int port = 80;
static String forwardServer =
//"ai1.lol";
//"google.de";
"localhost";
static Map forwardMap = litmap(
"thedevchannel.com", 3000,
"default", 8080);
public static void main(String[] args) throws Exception {
// Safety Rebooter - to hold up thedevchannel.com and ai1.lol when admin sleeps!
Thread _t_0 = new Thread("Rebooter") {
public void run() {
try {
sleepSeconds(60*60*24);
nohupJavax(programID(), vmArgs);
System.exit (0);
} catch (Exception _e) {
throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
};
_t_0.start();
// turn off memory leak
noPrintLog();
// Now for the actual server...
final ServerSocket serverSocket = new ServerSocket(port);
Thread thread = new Thread("HTTP Proxy Accept Port " + port) { public void run() {
try {
while (true) {
try {
final Socket s = serverSocket.accept();
Thread _t_1 = new Thread("Lister") {
public void run() {
try {
sleepSeconds(5);
listThreads();
} catch (Exception _e) {
throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
};
_t_1.start();
final String client = dropPrefix("/", s.getInetAddress().toString()); // Hmm... how to get the actual IP properly?
String threadName = "PROXY: Handling client " + client;
Thread t2 = new Thread(threadName) {
public void run() { try {
Socket outSocket = null;
final AtomicLong transmitted = new AtomicLong();
final AtomicLong outTransmitted = new AtomicLong();
try {
print("HTTP Proxy Incoming!");
final OutputStream out = s.getOutputStream();
final InputStream in = s.getInputStream();
// collect headers
ByteArrayOutputStream headersOut = new ByteArrayOutputStream();
BufferedReader headerReader = new BufferedReader(new InputStreamReader(in, "US-ASCII"), 1);
boolean forwardedFor = false;
String host = null;
while (true) {
String line = headerReader.readLine();
if (line == null) return;
print("Header line read: " + quote(line));
if (startsWithIgnoreCase(line, "Host:"))
host = dropPrefix("Host:", line).trim();
else {
String rewritten;
if (startsWithIgnoreCase(line, "X-Forwarded-For:")) {
forwardedFor = true;
rewritten = line + ", " + client;
} else
rewritten = empty(line) ? line : rewriteHeaderLine(line);
if (!eq(rewritten, line))
print("Rewritten as: " + quote(rewritten));
if (nempty(rewritten)) {
byte[] bytes = (rewritten + "\r\n").getBytes("US-ASCII");
//print("Sending: " + bytesToHex(bytes));
headersOut.write(bytes);
}
}
if (l(line) == 0)
break;
}
int port = getForwardPort(host);
outSocket = new Socket(forwardServer, port);
print("Connected to " + forwardServer + ":" + port);
final OutputStream outOut = outSocket.getOutputStream();
final InputStream outIn = outSocket.getInputStream();
outOut.write(headersOut.toByteArray());
if (!forwardedFor)
headerSend(outOut, "X-Forwarded-For: " + client);
headerSend(outOut, "Host: " + hostToPort(host, port));
headerSend(outOut, ""); // end of headers
outOut.flush();
// forward content in both directions
//copyStream(outIn, out);
Thread inThread = new Thread("Proxy In") {
public void run() { try {
byte[] buf = new byte[1];
while (true) {
int n = outIn.read(buf);
if (n <= 0) return;
out.write(buf, 0, n);
long t = transmitted.addAndGet(n);
if (t % 100000 == 0) print("Transmitted to client: " + t);
}
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
};
inThread.start();
Thread outThread = new Thread("Proxy Out") {
public void run() { try {
byte[] buf = new byte[1];
while (true) {
int n = in.read(buf);
if (n <= 0) return;
outOut.write(buf, 0, n);
long t = outTransmitted.addAndGet(n);
if (t % 100000 == 0) print("Transmitted to server: " + t);
}
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
};
outThread.start();
inThread.join();
//outThread.join();
} catch (IOException e) {
print("[internal] " + e);
} finally {
print("Proxy request done, got " + transmitted.get() + ", sent " + outTransmitted.get() + " + headers");
try { s.close(); } catch (Throwable __e) { printStackTrace(__e); }
try { if (outSocket != null) outSocket.close(); } catch (Throwable __e) { printStackTrace(__e); }
}
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
}; // Thread t2
t2.setDaemon(true);
t2.start();
} catch (SocketTimeoutException e) {
}
}
} catch (IOException e) {
print("[internal] " + e);
}
}};
thread.start();
print("HTTP proxy on port " + port + " started.");
}
static String rewriteHeaderLine(String line) {
/*if (startsWithIgnoreCase(line, "Host:"))
line = "Host: " + forwardServer + ":" + forwardPort;*/
return line;
}
static int getForwardPort(String host) {
int i = host.indexOf(':');
if (i >= 0)
host = host.substring(0, i);
host = host.toLowerCase();
for (String key : forwardMap.keySet())
if (eq(host, key) || host.endsWith("." + key))
return forwardMap.get(key);
return forwardMap.get("default");
}
static String hostToPort(String host, int port) {
int i = host.indexOf(':');
if (i >= 0)
host = host.substring(0, i);
return host + ":" + port;
}
static void headerSend(OutputStream out, String header) { try {
print("Sending header: " + header);
out.write((header + "\r\n").getBytes("US-ASCII"));
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static void sleepSeconds(long s) {
if (s > 0) sleep(s*1000);
}
static boolean nempty(Collection c) {
return !isEmpty(c);
}
static boolean nempty(String s) {
return !isEmpty(s);
}
static Map litmap(Object... x) {
TreeMap map = new TreeMap();
for (int i = 0; i < x.length-1; i += 2)
if (x[i+1] != null)
map.put(x[i], x[i+1]);
return map;
}
static boolean eq(Object a, Object b) {
if (a == null) return b == null;
if (a.equals(b)) return true;
if (a instanceof BigInteger) {
if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b));
if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b));
}
return false;
}
static int l(Object[] array) {
return array == null ? 0 : array.length;
}
static int l(byte[] array) {
return array == null ? 0 : array.length;
}
static int l(int[] array) {
return array == null ? 0 : array.length;
}
static int l(char[] array) {
return array == null ? 0 : array.length;
}
static int l(Collection c) {
return c == null ? 0 : c.size();
}
static int l(Map m) {
return m == null ? 0 : m.size();
}
static int l(String s) {
return s == null ? 0 : s.length();
}
static boolean empty(Collection c) {
return isEmpty(c);
}
static boolean empty(String s) {
return isEmpty(s);
}
static boolean empty(Map map) {
return map == null || map.isEmpty();
}
static void listThreads() {
print();
Map threadMap = Thread.getAllStackTraces();
for (Thread t : threadMap.keySet()) {
//print(structure(threadMap));
print(t);
}
print(threadMap.size() + " threads.");
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot
static void print() {
print("");
}
static void print(Object o) {
String s = String.valueOf(o) + "\n";
StringBuffer loc = local_log;
if (loc != null)
loc.append(s);
StringBuffer buf = print_log;
if (buf != loc && buf != null)
buf.append(s);
System.out.print(s);
}
static void print(long l) {
print(String.valueOf(l));
}
static String quote(String s) {
if (s == null) return "null";
return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
}
static String quote(long l) {
return quote("" + l);
}
static void noPrintLog() {
setOpt(mc(), "local_log", null);
setOpt(mc(), "print_log", null);
}
static void nohupJavax(String javaxargs) {
nohupJavax(javaxargs, "");
}
// vm args are ignored if pre-spun VM found...
static void nohupJavax(String javaxargs, String vmArgs) {
javaxargs = javaxargs.trim();
if (javaxargs.startsWith("#")) javaxargs = javaxargs.substring(1);
String snippetID = javaTok(javaxargs).get(1);
int idx = javaxargs.indexOf(' ');
String args = idx < 0 ? "" : javaxargs.substring(idx+1).trim();
String line;
if (args.length() != 0)
line = format3("please start program * with arguments *", snippetID, args);
else
line = format3("please start program *", snippetID);
String answer = sendToLocalBotOpt("A pre-spun VM.", line);
if (match3("ok", answer)) {
print("OK, used pre-spun VM.");
} else {
if (answer != null)
print("> " + answer);
print("Using standard nohup.");
classicNohupJavax(javaxargs, vmArgs);
}
}
static String programID() {
return getProgramID();
}
static String dropPrefix(String prefix, String s) {
return s.startsWith(prefix) ? s.substring(l(prefix)) : s;
}
static boolean startsWithIgnoreCase(String a, String b) {
return a != null && a.regionMatches(true, 0, b, 0, b.length());
}
static String format3(String pat, Object... args) {
if (args.length == 0) return pat;
List tok = javaTokPlusPeriod(pat);
int argidx = 0;
for (int i = 1; i < tok.size(); i += 2)
if (tok.get(i).equals("*"))
tok.set(i, format3_formatArg(argidx < args.length ? args[argidx++] : "null"));
return join(tok);
}
static String format3_formatArg(Object arg) {
if (arg == null) return "null";
if (arg instanceof String) {
String s = (String) arg;
return isIdentifier(s) || isNonNegativeInteger(s) ? s : quote(s);
}
if (arg instanceof Integer || arg instanceof Long) return String.valueOf(arg);
return quote(structure(arg));
}
// class Matches is added by #752
static boolean match3(String pat, String s) {
return match3(pat, s, null);
}
static boolean match3(String pat, String s, Matches matches) {
if (s == null) return false;
return match3(pat, parse3(s), matches);
}
static boolean match3(String pat, List toks, Matches matches) {
List tokpat = parse3(pat);
return match3(tokpat,toks,matches);
}
static boolean match3(List tokpat, List toks, Matches matches) {
String[] m = match2(tokpat, toks);
//print(structure(tokpat) + " on " + structure(toks) + " => " + structure(m));
if (m == null)
return false;
else {
if (matches != null) matches.m = m;
return true;
}
}
static String programID;
static String getProgramID() {
return programID;
}
// TODO: ask JavaX instead
static String getProgramID(Class c) {
return or((String) getOpt(c, "programID"), "?");
}
static String getProgramID(Object o) {
return getProgramID(getMainClass(o));
}
static boolean isEmpty(Collection c) {
return c == null || c.isEmpty();
}
static boolean isEmpty(String s) {
return s == null || s.length() == 0;
}
// replacement for class JavaTok
// maybe incomplete, might want to add floating point numbers
// todo also: extended multi-line strings
static List javaTok(String s) {
List tok = new ArrayList();
int l = s.length();
int i = 0;
while (i < l) {
int j = i;
char c; String cc;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
cc = s.substring(j, Math.min(j+2, l));
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (cc.equals("/*")) {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (cc.equals("//")) {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
tok.add(s.substring(i, j));
i = j;
if (i >= l) break;
c = s.charAt(i); // cc is not needed in rest of loop body
cc = s.substring(i, Math.min(i+2, l));
// scan for non-whitespace
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (cc.equals("[[")) {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else
++j;
tok.add(s.substring(i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
return tok;
}
static List javaTok(List tok) {
return javaTok(join(tok));
}
static void classicNohupJavax(String javaxargs) {
classicNohupJavax(javaxargs, "");
}
static void classicNohupJavax(String javaxargs, String vmArgs) { try {
int x = latestInstalledJavaX();
File xfile = new File(userHome(), ".javax/x" + Math.max(x, 30) + ".jar");
if (!xfile.isFile()) {
String url = "http://tinybrain.de/x30.jar";
byte[] data = loadBinaryPage(url);
if (data.length < 1000000)
fail("Could not load " + url);
saveBinaryFile(xfile.getPath(), data);
}
String jarPath = xfile.getPath();
if (javaxargs.startsWith("#")) javaxargs = javaxargs.substring(1);
nohup("java " + vmArgs + " -jar " + (isWindows() ? winQuote(jarPath) : bashQuote(jarPath)) + " " + javaxargs);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
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 void setOpt(Object o, String field, Object value) {
if (o instanceof Class) setOpt((Class) o, field, value);
else try {
Field f = setOpt_findField(o.getClass(), field);
if (f != null)
smartSet(f, o, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static void setOpt(Class c, String field, Object value) {
try {
Field f = setOpt_findStaticField(c, field);
if (f != null)
smartSet(f, null, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field setOpt_findField(Class> c, String field) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field))
return f;
return null;
}
static Field setOpt_findStaticField(Class> c, String field) {
for (Field f : c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
return null;
}
static Class mc() {
return getMainClass();
}
static String sendToLocalBotOpt(String bot, String text) {
if (bot == null) return null;
DialogIO channel = findBot(bot);
if (channel == null) {
print(quote(bot) + " not found, skipping send: " + quote(text));
return null;
}
try {
channel.readLine();
print(bot + "> " + text);
channel.sendLine(text);
String s = channel.readLine();
print(bot + "< " + s);
return s;
} catch (Throwable e) {
e.printStackTrace();
return null;
} finally {
channel.close();
}
}
static boolean isIdentifier(String s) {
return isJavaIdentifier(s);
}
// match2 matches multiple "*" (matches a single token) wildcards and zero or one "..." wildcards (matches multiple tokens)
static String[] match2(List pat, List tok) {
// standard case (no ...)
int i = pat.indexOf("...");
if (i < 0) return match2_match(pat, tok);
pat = new ArrayList(pat); // We're modifying it, so copy first
pat.set(i, "*");
while (pat.size() < tok.size()) {
pat.add(i, "*");
pat.add(i+1, ""); // doesn't matter
}
return match2_match(pat, tok);
}
static String[] match2_match(List pat, List tok) {
List result = new ArrayList();
if (pat.size() != tok.size()) {
/*if (debug)
print("Size mismatch: " + structure(pat) + " vs " + structure(tok));*/
return null;
}
for (int i = 1; i < pat.size(); i += 2) {
String p = pat.get(i), t = tok.get(i);
/*if (debug)
print("Checking " + p + " against " + t);*/
if (eq(p, "*"))
result.add(t);
else if (!equalsIgnoreCase(unquote(p), unquote(t))) // bold change - match quoted and unquoted now
return null;
}
return result.toArray(new String[result.size()]);
}
static List parse3(String s) {
return dropPunctuation(javaTokPlusPeriod(s));
}
static int latestInstalledJavaX() {
File[] files = new File(userHome(), ".javax").listFiles();
int v = 0;
if (files != null) for (File f : files) {
Matcher m = Pattern.compile("x(\\d\\d\\d?)\\.jar").matcher(f.getName());
if (m.matches())
v = Math.max(v, Integer.parseInt(m.group(1)));
}
return v;
}
/** writes safely (to temp file, then rename) */
public static void saveBinaryFile(String fileName, byte[] contents) throws IOException {
File file = new File(fileName);
File parentFile = file.getParentFile();
if (parentFile != null)
parentFile.mkdirs();
String tempFileName = fileName + "_temp";
FileOutputStream fileOutputStream = new FileOutputStream(tempFileName);
fileOutputStream.write(contents);
fileOutputStream.close();
if (file.exists() && !file.delete())
throw new IOException("Can't delete " + fileName);
if (!new File(tempFileName).renameTo(file))
throw new IOException("Can't rename " + tempFileName + " to " + fileName);
}
static void saveBinaryFile(File fileName, byte[] contents) {
try {
saveBinaryFile(fileName.getPath(), contents);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static String _userHome;
static String userHome() {
if (_userHome == null) {
if (isAndroid())
_userHome = "/storage/sdcard0/";
else
_userHome = System.getProperty("user.home");
//System.out.println("userHome: " + _userHome);
}
return _userHome;
}
public static boolean isWindows() {
return System.getProperty("os.name").contains("Windows");
}
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);
}
/** possibly improvable */
public static String bashQuote(String text) {
if (text == null) return null;
return "\"" + text
.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r") + "\"";
}
public static File nohup(String cmd) throws IOException {
File outFile = File.createTempFile("nohup_" + nohup_sanitize(cmd), ".out");
nohup(cmd, outFile, false);
return outFile;
}
static String nohup_sanitize(String s) {
return s.replaceAll("[^a-zA-Z0-9\\-_]", "");
}
/** outFile takes stdout and stderr. */
public static void nohup(String cmd, File outFile, boolean append) throws IOException {
String command = nohup_makeNohupCommand(cmd, outFile, append);
File scriptFile = File.createTempFile("_realnohup", isWindows() ? ".bat" : "");
System.out.println("[Nohup] " + command);
try {
//System.out.println("[RealNohup] Script file: " + scriptFile.getPath());
saveTextFile(scriptFile.getPath(), command);
String[] command2;
if (isWindows())
command2 = new String[] {"cmd", "/c", "start", "/b", scriptFile.getPath() };
else
command2 = new String[] {"/bin/bash", scriptFile.getPath() };
Process process = Runtime.getRuntime().exec(command2);
try {
process.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int value = process.exitValue();
//System.out.println("exit value: " + value);
} finally {
if (!isWindows())
scriptFile.delete();
}
}
public static String nohup_makeNohupCommand(String cmd, File outFile, boolean append) {
mkdirsForFile(outFile);
String command;
if (isWindows())
command = cmd + (append ? " >>" : " >") + winQuote(outFile.getPath()) + " 2>&1";
else
command = "nohup " + cmd + (append ? " >>" : " >") + bashQuote(outFile.getPath()) + " 2>&1 &";
return command;
}
static Class getMainClass() { try {
return Class.forName("main");
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static Class getMainClass(Object o) { try {
return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main");
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static boolean isNonNegativeInteger(String s) {
return s != null && Pattern.matches("\\d+", s);
}
static A or(A a, A b) {
return a != null ? a : b;
}
static void smartSet(Field f, Object o, Object value) throws Exception {
f.setAccessible(true);
// take care of common case (long to int)
if (f.getType() == int.class && value instanceof Long)
value = ((Long) value).intValue();
f.set(o, value);
}
static byte[] loadBinaryPage(String url) throws IOException {
return loadBinaryPage(new URL(url).openConnection());
}
public static byte[] loadBinaryPage(URLConnection con) throws IOException {
//setHeaders(con);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
InputStream inputStream = con.getInputStream();
int n = 0;
while (true) {
int ch = inputStream.read();
if (ch < 0)
break;
buf.write(ch);
if (++n % 100000 == 0)
System.err.println(" " + n + " bytes loaded.");
}
inputStream.close();
return buf.toByteArray();
}
static Map findBot_cache = new TreeMap();
static int findBot_timeout = 5000;
static DialogIO findBot(String searchPattern) {
// first split off sub-bot suffix
String subBot = null;
int i = searchPattern.indexOf('/');
if (i >= 0 && (isJavaIdentifier(searchPattern.substring(0, i)) || isInteger(searchPattern.substring(0, i)))) {
subBot = searchPattern.substring(i+1);
searchPattern = searchPattern.substring(0, i);
if (!isInteger(searchPattern))
searchPattern = "Multi-Port at " + searchPattern + ".";
}
// assume it's a port if it's an integer
if (isInteger(searchPattern))
return talkToSubBot(subBot, talkTo(parseInt(searchPattern)));
if (eq(searchPattern, "remote"))
return talkToSubBot(subBot, talkTo("second.tinybrain.de", 4999));
Integer port = findBot_cache.get(searchPattern);
if (port != null) try {
DialogIO io = talkTo("localhost", port);
io.waitForLine(/*findBot_timeout*/); // TODO: implement
String line = io.readLineNoBlock();
if (indexOfIgnoreCase(line, searchPattern) == 0) {
call(io, "pushback", line); // put hello string back in
return talkToSubBot(subBot, io);
}
} catch (Exception e) {
e.printStackTrace();
}
List bots = quickBotScan();
// find top-level bots
for (ProgramScan.Program p : bots) {
if (indexOfIgnoreCase(p.helloString, searchPattern) == 0) { // strict matching - start of hello string only, but case-insensitive
findBot_cache.put(searchPattern, p.port);
return talkToSubBot(subBot, talkTo("localhost", p.port));
}
}
// find sub-bots
for (ProgramScan.Program p : bots) {
String botName = firstPartOfHelloString(p.helloString);
boolean isVM = startsWithIgnoreCase(p.helloString, "This is a JavaX VM.");
boolean shouldRecurse = startsWithIgnoreCase(botName, "Multi-Port") || isVM;
if (shouldRecurse) try {
Map subBots = (Map) unstructure(sendToLocalBot(p.port, "list bots"));
for (Number vport : subBots.keySet()) {
String name = subBots.get(vport);
if (startsWithIgnoreCase(name, searchPattern))
return talkToSubBot(vport.longValue(), talkTo("localhost", p.port));
}
} catch (Exception e) { e.printStackTrace(); }
}
return null;
}
static String structure(Object o) {
return structure(o, 0, null /*new IdentityHashMap*/);
}
static String structure_seen(Object o) {
return structure(o, 0, new IdentityHashMap());
}
// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
static String structure(Object o, int stringSizeLimit, IdentityHashMap