static L pinging = synchroList(); // who we ping static volatile L scannedBots; static double pingLoopInterval = 30; sbool allowDangerousCommands; // eval from any machine on the subnet concept MachineInfo { S ip; bool me, aware; S computerID, os; L bots; long lastChecked; } sclass GeneralInfo { S computerID, os; L bots; } static S awarenessBot(S s) { new Matches m; if "get computer id" ret ok(computerID()); if "who are you pinging" ret structure(pinging); if "list bots" ret structure(or(scannedBots, fullBotScan())); if "general info" { new GeneralInfo gi; gi.computerID = computerID(); //gi.isAndroid = isAndroid(); gi.os = System.getProperty("os.name"); gi.bots = asList(collectTreeSet(or(scannedBots, fullBotScan()), "helloString")); ret structure(gi); } if (allowDangerousCommands) { if "please run snippet *" { final Class c = hotwire($1); thread { callMain(c); } ret "ok, running main in new thread"; // TODO: return injection ID } if "please hotwire snippet *" { hotwire($1); ret "ok"; // TODO: return injection ID } if "please forward to machine *: *" ret sendToPublicCommBot($1, $2); } null; } static void getClientsFrom(S ip) { pcall { MachineInfo info = uniq(MachineInfo, +ip); info.lastChecked = now(); info.change(); try { O gi = safeUnstructure(sendToAwareness(ip, "general info")); info.aware = true; copyFields(gi, info, "os", "computerID", "bots"); info.me = eq(info.computerID, computerID()); info.change(); } catch e { info.aware = false; info.bots = null; throw(asRuntimeException(e)); } } pcall { addPeers(getClientsListFrom(ip)); } pcall { addPeers(getPeersListFrom(ip)); } } static S sendToLocalBotOpt(S bot, S text, O... args) { if (bot == null) return null; text = format(text, args); if (swic("Awareness Bot.", bot)) ret callStaticAnswerMethod(text); DialogIO channel = findBot(bot); if (channel == null) { print(quote(bot) + " not found, skipping send: " + quote(text)); return null; } try { channel.readLine(); print(shorten(bot + "> " + text, 200)); channel.sendLine(text); S s = channel.readLine(); print(shorten(bot + "< " + s, 200)); return s; } catch (Throwable e) { e.printStackTrace(); return null; } finally { channel.close(); } } static S sendToLocalBotOpt_original(S bot, S text, O... args) { if (bot == null) return null; text = format(text, args); DialogIO channel = findBot(bot); if (channel == null) { print(quote(bot) + " not found, skipping send: " + quote(text)); return null; } try { channel.readLine(); print(shorten(bot + "> " + text, 200)); channel.sendLine(text); S s = channel.readLine(); print(shorten(bot + "< " + s, 200)); return s; } catch (Throwable e) { e.printStackTrace(); return null; } finally { channel.close(); } } svoid pingThread(fO extraCode) { thread "Ping Loop" { addPeers(getMyIPs()); int pingingIdx = 0; new L pinging; while licensed { try { pinging = cloneList(main.pinging); // ping the gateway S gateway = gateway(); if (gateway != null && !pinging.contains(gateway)) { print("Pinging gateway " + gateway); addPeers(ll(gateway)); } setAddAll(pinging, keys(phonePublicCommBot_clients)); // ping one known party if (nempty(pinging)) { S ip = get(pinging, pingingIdx++ % l(pinging)); print("Pinging peer " + ip); getClientsFrom(ip); } } catch e { logQuoted("pingloop.log", chatTime() + " " + e); } pcall { scannedBots = fullBotScan(); } pcallF(extraCode); sleepSeconds(pingLoopInterval); } } } svoid addPeers(L peers) { for (S peer : unnull(peers)) if (isIPv4(peer) && !isLoopbackIP(peer) && !pinging.contains(peer)) { pinging.add(peer); getClientsFrom(peer); } }