import javax.imageio.*; import java.awt.image.*; import java.awt.event.*; import java.awt.*; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import java.lang.management.*; import java.lang.reflect.*; import java.net.*; import java.io.*; 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 String botToZip = "#1001325"; // Heart (loud) static int compressionLevel = 9; // highest! public static void main(String[] args) throws Exception { botToZip = formatSnippetID(botToZip); print("Killing bot to zip first.."); killProgramID(botToZip); print("OK, proceeding with zipping."); File zipPath = new File(getProgramDir(), "the.zip"); zipBot(botToZip, zipPath); } static void zipBot(String botToZip, File destZip) { try { File dir = getProgramDir(botToZip); mkdirsForFile(destZip); FileOutputStream fout = new FileOutputStream(destZip); ZipOutputStream zout = new ZipOutputStream(fout); zout.setLevel(compressionLevel); int count = 0; if (dir.isDirectory()) count += dir2zip(dir, zout, "JavaX-Data/" + botToZip + "/"); if (count == 0) { print("Nothing to zip for bot " + botToZip); fout.close(); } else { zout.close(); print("Zipped " + botToZip + " (" + count + " entries) to " + destZip.getAbsolutePath() + " (" + destZip.length() + " bytes)"); } } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static boolean killProgramID(String idToKill) { print("Killing program " + idToKill); for (ProgramScan.Program p : quickBotScan()) { if (p.helloString.startsWith("This is a JavaX VM") && sameSnippetID(idToKill, sendToLocalBot(p.port, "what is your program id?"))) { print("Killing port " + p.port + " (program id: " + idToKill + ")"); killPortAndWait(p.port); return true; } } return false; } static File getProgramDir() { return programDir(); } static File getProgramDir(String snippetID) { return programDir(snippetID); } static void print() { System.out.println(); } static void print(Object o) { System.out.println(o); } static void print(long i) { System.out.println(i); } static String formatSnippetID(String id) { return "#" + parseSnippetID(id); } static String formatSnippetID(long id) { return "#" + id; } static boolean sameSnippetID(String a, String b) { return parseSnippetID(a) == parseSnippetID(b); } static void killPortAndWait(int port) { killPortAndWait("localhost", port); } static void killPortAndWait(String ip, int port) { print("Sending kill switch to " + ip + ":" + port); DialogIO io = talkTo(ip, port); io.sendLine("kill!"); try { // wait until it is closed from other side String s; while ((s = io.readLine()) != null) print(port + "< " + s); } catch (Exception e) {} io.close(); // never throws exceptions } static String sendToLocalBot(String bot, String text) { try { DialogIO channel = findBot(bot); if (channel == null) { fail(quote(bot) + " not found"); } channel.readLine(); print(bot + "> " + text); channel.sendLine(text); String s = channel.readLine(); print(bot + "< " + s); channel.close(); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } static String sendToLocalBot(int port, String text) { try { DialogIO channel = talkTo(port); channel.readLine(); print(port + "> " + text); channel.sendLine(text); String s = channel.readLine(); print(port + "< " + s); channel.close(); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } // TODO: subdirectories static int dir2zip(File inDir, ZipOutputStream outZip, String outPrefix) { try { int count = 0; for (File f : inDir.listFiles()) { if (f.isFile()) { System.out.println("Copying " + f.getName()); ++count; outZip.putNextEntry(new ZipEntry(outPrefix + f.getName())); InputStream fin = new FileInputStream(f); copyStream(fin, outZip); fin.close(); } } return count; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static int dir2zip(File inDir, ZipOutputStream outZip) { return dir2zip(inDir, outZip, ""); } static int dir2zip(String inDir, ZipOutputStream outZip) { return dir2zip(new File(inDir), outZip, ""); } static class ProgramScan { static int threads = 10; static int timeout = 5000; // hmm... static String ip = "127.0.0.1"; static int quickScanFrom = 10000, quickScanTo = 10999; static class Program { int port; String helloString; Program(int port, String helloString) { this.helloString = helloString; this.port = port;} } static List scan() { try { return scan(1, 65535); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static List scan(int fromPort, int toPort) { return scan(fromPort, toPort, new int[0]); } static List scan(int fromPort, int toPort, int[] preferredPorts) { try { Set preferredPortsSet = new HashSet(asList(preferredPorts)); String name = toPort < 10000 ? "bot" : "program"; final ExecutorService es = Executors.newFixedThreadPool(threads); print(firstToUpper(name) + "-scanning " + ip + " with timeout " + timeout + " ms in " + threads + " threads."); startTiming(); List> futures = new ArrayList>(); for (int port : preferredPorts) futures.add(checkPort(es, ip, port, timeout)); for (int port = fromPort; port <= toPort; port++) if (!preferredPortsSet.contains(port)) futures.add(checkPort(es, ip, port, timeout)); es.shutdown(); List programs = new ArrayList(); for (final Future f : futures) { Program p = f.get(); if (p != null) programs.add(p); } stopTiming(); print("Found " + programs.size() + " " + name + "(s) on " + ip); return programs; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static Future checkPort(final ExecutorService es, final String ip, final int port, final int timeout) { return es.submit(new Callable() { @Override public Program call() { try { Socket socket = new Socket(); socket.setSoTimeout(timeout); socket.connect(new InetSocketAddress(ip, port), timeout); print("Connected to " + ip + ":" + port); BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream(), "UTF-8")); String hello = in.readLine(); socket.close(); return new Program(port, hello); } catch (Exception ex) { return null; } } }); } static List quickScan() { return scan(quickScanFrom, quickScanTo); } static List quickBotScan() { return quickBotScan(new int[0]); } static List quickBotScan(int[] preferredPorts) { return scan(5000, 5999, preferredPorts); } } // ProgramScan static List quickBotScan() { return ProgramScan.quickBotScan(); } static List quickBotScan(int[] preferredPorts) { return ProgramScan.quickBotScan(preferredPorts); } static File programDir() { return programDir(getProgramID()); } static File programDir(String snippetID) { return new File(userHome(), "JavaX-Data/" + formatSnippetID(snippetID)); } public static void mkdirsForFile(File file) { File dir = file.getParentFile(); if (dir != null) // is null if file is in current dir dir.mkdirs(); } public static long parseSnippetID(String snippetID) { return Long.parseLong(shortenSnippetID(snippetID)); } 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 Map findBot_cache = new TreeMap(); static int findBot_timeout = 5000; static DialogIO findBot(String searchPattern) { 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 io; } } catch (Exception e) { e.printStackTrace(); } for (ProgramScan.Program p : quickBotScan()) if (indexOfIgnoreCase(p.helloString, searchPattern) == 0) { // strict matching - start of hello string only, but case-insensitive findBot_cache.put(searchPattern, p.port); return talkTo("localhost", p.port); } return null; } static String programID; static String getProgramID() { return programID; } static abstract class DialogIO { abstract boolean isStillConnected(); abstract String readLineNoBlock(); abstract boolean waitForLine(); abstract void sendLine(String line); abstract boolean isLocalConnection(); abstract Socket getSocket(); abstract void close(); String readLine() { waitForLine(); return readLineNoBlock(); } } static abstract class DialogHandler { abstract void run(DialogIO io); } // DialogIO static DialogIO talkTo(int port) { return talkTo("localhost", port); } static DialogIO talkTo(String ip, int port) { try { print("Talking to " + ip + ":" + port); final Socket s = new Socket(ip, port); final Writer w = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); final BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8")); return new DialogIO() { String line; boolean buff; boolean isLocalConnection() { return s.getInetAddress().isLoopbackAddress(); } boolean isStillConnected() { return !(buff || s.isClosed()); } String readLineNoBlock() { String l = line; line = null; return l; } boolean waitForLine() { try { if (line != null) return true; //print("Readline"); line = in.readLine(); //print("Readline done: " + line); if (line == null) buff = true; return line != null; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} void sendLine(String line) { try { w.write(line + "\n"); w.flush(); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} void close() { try { s.close(); } catch (IOException e) { // whatever } } Socket getSocket() { return s; } void pushback(String l) { if (line != null) fail(); line = l; } }; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} public static void copyStream(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[65536]; while (true) { int n = in.read(buf); if (n <= 0) return; out.write(buf, 0, n); } } static RuntimeException fail() { throw new RuntimeException("fail"); } static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); } 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; } static String shortenSnippetID(String snippetID) { if (snippetID.startsWith("#")) snippetID = snippetID.substring(1); String httpBlaBla = "http://tinybrain.de/"; if (snippetID.startsWith(httpBlaBla)) snippetID = snippetID.substring(httpBlaBla.length()); return snippetID; } static String programID() { return getProgramID(); } static boolean isAndroid() { return System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0; } static Object call(Object o, String method, Object... args) { try { if (o instanceof Class) { Method m = call_findStaticMethod((Class) o, method, args, false); m.setAccessible(true); return m.invoke(null, args); } else { Method m = call_findMethod(o, method, args, false); m.setAccessible(true); return m.invoke(o, args); } } catch (Exception e) { throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); } } static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) { Class _c = c; while (c != null) { for (Method m : c.getDeclaredMethods()) { if (debug) System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; if (!m.getName().equals(method)) { if (debug) System.out.println("Method name mismatch: " + method); continue; } if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug)) continue; return m; } c = c.getSuperclass(); } throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName()); } static Method call_findMethod(Object o, String method, Object[] args, boolean debug) { Class c = o.getClass(); while (c != null) { for (Method m : c.getDeclaredMethods()) { if (debug) System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; if (m.getName().equals(method) && call_checkArgs(m, args, debug)) return m; } c = c.getSuperclass(); } throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName()); } private static boolean call_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } // works on lists and strings static int indexOfIgnoreCase(Object a, Object b) { if (a instanceof String) { Matcher m = Pattern.compile((String) b, Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher((String) a); if (m.find()) return m.start(); else return -1; } if (a instanceof List) { for (int i = 0; i < ((List) a).size(); i++) { Object o = ((List) a).get(i); if (o != null && ((String) o).equalsIgnoreCase((String) b)) return i; } return -1; } throw fail("Unknown type: " + a); } // extended over Class.isInstance() to handle primitive types static boolean isInstanceX(Class type, Object arg) { if (type == boolean.class) return arg instanceof Boolean; if (type == int.class) return arg instanceof Integer; if (type == long.class) return arg instanceof Long; if (type == float.class) return arg instanceof Float; if (type == short.class) return arg instanceof Short; if (type == char.class) return arg instanceof Character; if (type == byte.class) return arg instanceof Byte; return type.isInstance(arg); } static String firstToUpper(String s) { if (s.length() == 0) return s; return Character.toUpperCase(s.charAt(0)) + s.substring(1); } static BufferedReader readLine_reader; static String readLine() { try { if (readLine_reader == null) readLine_reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); String s = readLine_reader.readLine(); if (s != null) print(s); return s; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static ArrayList asList(A[] a) { return new ArrayList(Arrays.asList(a)); } static ArrayList asList(int[] a) { ArrayList l = new ArrayList(); for (int i : a) l.add(i); return l; } static ArrayList asList(Set s) { return new ArrayList(s); } static long startTiming_startTime; static void startTiming() { startTiming_startTime = now(); } static void stopTiming() { long end = now(); print("Time: " + (end-startTiming_startTime) + " ms"); } static long now_virtualTime; static long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } }