sclass MultiPort { sclass Resp { long virtualPort; S botName; O responder; } new List responders; Android3 android; long nextVirtualPort = 1; *() { synchronized(getJavaX()) { if (!getMultiPorts().isEmpty()) return; if (!(Boolean) call(getJavaX(), "addMultiPort", this)) { // XXX - hope this still works Android3 android = new Android3("Multi-Port at " + getVMID() + "."); android.useMultiPort = false; android.incomingSilent = true; android.console = false; android.daemon = true; makeAndroid3(android); } } //print("Dynamic Multi-Port registered with VM. Now " + l(getMultiPorts()) + " multi-port(s)."); } S answer(S s) { new Matches m; if (match3("list bots", s, m)) { ret structure(listBotsWithPort()); } if (match3("has bot *", s, m)) { S name = m.unq(0); ret findResponder(name) != null ? "yes" : "no"; } if (match3("silent", s, m)) { android.incomingSilent = true; ret "OK."; } if (match3("unsilent", s, m)) { android.incomingSilent = false; ret "OK."; } if (match3("please forward to bot *: *", s, m)) { S bot = unquote(m.m[0]); S line = unquote(m.m[1]); O responder = findResponder(bot); if (responder == null) ret "Error: bot not found"; else ret (S) call(responder, "answer", line, litlist(s)); } ret null; } synchronized L listBots() { new L list; for (Resp r : responders) list.add(r.botName); ret list; } synchronized Map listBotsWithPort() { new Map map; for (Resp r : responders) map.put(r.virtualPort, r.botName); ret map; } synchronized O findResponder(S botName) { if (isInteger(botName)) { long vport = parseLong(botName); for (Resp r : responders) if (r.virtualPort == vport) ret r.responder; } else { for (Resp r : responders) if (startsWithIgnoreCase(r.botName, botName)) ret r.responder; } ret null; } synchronized long addResponder(S botName, O responder) { new Resp r; r.virtualPort = nextVirtualPort++; r.botName = botName; r.responder = responder; responders.add(r); ret r.virtualPort; } synchronized void removeResponder(O responder) { for (int i = 0; i < l(responders); i++) if (responders.get(i).responder == responder) { //print("Responder removed."); responders.remove(i); ret; } } synchronized void removePort(long virtualPort) { for (int i = 0; i < l(responders); i++) if (responders.get(i).virtualPort == virtualPort) { //print("Virtual port " + virtualPort + " removed."); responders.remove(i); ret; } } }