package jelectrum; import org.jibble.pircbot.PircBot; import org.jibble.pircbot.IrcException; import java.util.Scanner; import java.net.URL; import java.util.Random; public class IrcBot extends PircBot { private Jelectrum jelly; private Object connection_lock = new Object(); private Config config; private volatile long kickWaitTime=0; private boolean shouldRun = false; private String advert_host = null; private String nick = null; private String chatChannel; private boolean gossip=false; public IrcBot(Jelectrum jelly, String mode) { config = jelly.getConfig(); this.jelly = jelly; if (mode == null) { if (config.isSet("irc_enabled") && config.getBoolean("irc_enabled")) { config.require("irc_nick"); config.require("irc_advertise_host"); advert_host = config.get("irc_advertise_host"); String config_nick = config.get("irc_nick"); if (config_nick.equals("auto")) { String seed = getHostSeed(advert_host); config_nick = WordList.getWords(2, "_", seed); } nick = "E_j_" + config_nick; setName(nick); setLogin(nick); shouldRun=true; } } else { if (config.isSet("irc_enabled_" + mode) && config.getBoolean("irc_enabled_" + mode)) { config.require("irc_nick_"+mode); config.require("irc_advertise_host_"+mode); advert_host = config.get("irc_advertise_host_"+mode); String config_nick = config.get("irc_nick_"+mode); if (config_nick.equals("auto")) { String seed = getHostSeed(advert_host); config_nick = WordList.getWords(2, "_", seed); } nick = "E_j_" + config_nick; setName(nick); setLogin(nick); shouldRun=true; } } new GossipThread().start(); } public String getHostSeed(String h) { try { if (h.equals("auto")) { h = lookupMyIp(); } } catch(java.io.IOException e) { return null; } return h; } public String getAdvertString() throws java.io.IOException { //hostmame v1.0 p10000 t s //hostname v1.0 p10000 t50003 s50004 String host = advert_host; if (advert_host.equals("auto")) { host = lookupMyIp(); } StringBuilder sb=new StringBuilder(); sb.append(host); sb.append(" v"); sb.append(StratumConnection.PROTO_VERSION); sb.append(" p10000"); if (config.isSet("tcp_port")) { sb.append(" t"); int port = jelly.getStratumServer().getTcpPort(); if (port != 50001) sb.append("" + port); } if (config.isSet("ssl_port")) { sb.append(" s"); int port = jelly.getStratumServer().getSslPort(); if (port != 50002) sb.append("" + port); } return sb.toString(); } public void start() { if (shouldRun) { new IrcThread().start(); } } @Override protected void onDisconnect() { synchronized(connection_lock) { connection_lock.notifyAll(); } } @Override protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) { if (nick.equals(recipientNick)) { jelly.getEventLog().log("Kicked from " + channel + " by " + kickerNick + " for " + reason); jelly.getEventLog().log("Waiting one hour before trying again"); kickWaitTime = System.currentTimeMillis() + 3600L * 1000L; synchronized(connection_lock) { connection_lock.notifyAll(); } } } public class IrcThread extends Thread { public IrcThread() { setName("IrcThread"); setDaemon(true); } public void run() { while(shouldRun) { try { ircRun(); } catch(Throwable t) { t.printStackTrace(); } gossip=false; try { sleep(600000);} catch(Throwable t){} } } public void ircRun() throws java.io.IOException, IrcException, InterruptedException { //setVerbose(true); while (System.currentTimeMillis() < kickWaitTime) { Thread.sleep(15000); } setVersion(getAdvertString()); connect("irc.freenode.net"); if (config.getBoolean("testnet")) { joinChannel("#electrum-testnet"); joinChannel("#jelectrum-testnet"); chatChannel="#jelectrum-testnet"; } else { joinChannel("#electrum"); joinChannel("#jelectrum"); chatChannel="#jelectrum"; } gossip=true; synchronized(connection_lock) { connection_lock.wait(); } gossip=false; while (System.currentTimeMillis() < kickWaitTime) { Thread.sleep(15000); } disconnect(); } } public static String lookupMyIp() throws java.io.IOException { String url = "https://jelectrum-1022.appspot.com/myip"; URL u = new URL(url); Scanner scan =new Scanner(u.openStream()); String line = scan.nextLine(); scan.close(); return line.trim(); } public class GossipThread extends Thread { public GossipThread() { setName("IrcBot/Gossip"); setDaemon(false); } public void run() { Random rnd = new Random(); while(true) { int sleep_max = 6 * 3600 * 1000; try { sleep(rnd.nextInt(sleep_max)); if (gossip) { int word_count = 1 + rnd.nextInt(5); sendMessage(chatChannel, WordList.getWords(word_count, " ", null)); } } catch(Throwable t) { t.printStackTrace(); } } } } }