!752 !1002672 // pircbot library import org.jibble.pircbot.*; !include #1002680 // modified PircBot static boolean useBouncer = true; static S server = useBouncer ? "second.tinybrain.de" : "irc.freenode.net"; static S channel = /*"##linux"*/"#pircbot"; static S name = "Lookie"; static int reconnectTimeout1 = 60; // seconds after which to send a ping to server static int reconnectTimeout2 = 80; // seconds after which we try to reconnect static Map> bulk = new TreeMap; // key = channel (with "#") static MyBot bot; p { thread "IRC Log-In" { bot = new MyBot; bot.setVerbose(true); print("PircBot connecting to " + server); bot.connect(server); print("PircBot connect issued"); autoReconnect(bot); } } static class MyBot extends PircBot { long lastReceived; MyBot() { setName(name); //setRealName(name); // newer version of PircBot only setLogin(name); setVersion(name); setFinger(""); setAutoNickChange(true); } public void handleLine(String line) { getLog(channel).add(litmap("time", smartNow(), "line", line)); super.handleLine(line); lastReceived = now(); } public void onConnect() { print("PircBot onConnect useBouncer=" + useBouncer); if (useBouncer) { S bouncerLogin = loadSecretTextFileMandatory("bouncer-login").trim(); print("Logging in to bouncer"); bot.sendMessage("root", bouncerLogin.trim()); // session should already be there, so resume it print("Resuming bouncer session"); bot.sendMessage("root", "connect freenode"); } bot.joinChannel(channel); } } static void autoReconnect(final MyBot bot) { thread "PircBot Auto-Reconnect" { while (licensed()) { sleepSeconds(10); if (now() >= bot.lastReceived + reconnectTimeout2*1000) try { print("PircBot: Trying to reconnect..."); hardClose(bot); sleepSeconds(1); // allow for input thread to halt bot.reconnect(); } catch (Exception e) { print("Reconnect fail: " + e); // Couldn't reconnect! } else if (now() >= bot.lastReceived + reconnectTimeout1*1000) bot.sendRawLine("TIME"); // send something } } } static Socket getSocket(PircBot bot) { ret (Socket) get(get(bot, "_inputThread"), "_socket"); } answer { if "irc log size *" exceptionToUser { ret lstr(getLog(m.unq(0))); } } static synchronized PersistentLog getLog(S channelName) { checkChannelName(channelName); PersistentLog log = bulk.get(channelName); if (log == null) bulk.put(channelName, log = new PersistentLog(channelName + ".log")); ret log; } static S checkChannelName(S s) { assertTrue(nempty(s)); for (int i = 0; i < l(s); i++) if (!( "#!".indexOf(s.charAt(i)) >= 0 || Character.isLetterOrDigit(s.charAt(i)))) fail(s); ret s; } static void hardClose(PircBot bot) { if (bot == null) ret; try { //bot.disconnect(); getSocket(bot).close(); } catch (Exception e) { print(str(e)); } } static void cleanMeUp() { hardClose(bot); } static long smartNow_last; static long smartNow() { ret smartNow_last = max(smartNow_last + 1, now()); }