package pl.shockah.shocky;
import java.io.IOException;
import java.util.*;
import org.pircbotx.*;
import org.pircbotx.exception.*;
import pl.shockah.Reflection;
public class MultiChannel {
private static List<PircBotX> botList = new LinkedList<PircBotX>();
protected static String channelPrefixes = null;
public static Channel get(String name) {
name = name.toLowerCase();
synchronized (botList) {
for (PircBotX entry : botList) {
for (Channel channel : entry.getChannels()) {
if (channel.getName().equalsIgnoreCase(name))
return channel;
}
}
}
return null;
}
private static PircBotX createBot() {
PircBotX bot = Shocky.getBotManager().createBot(Data.config.getString("main-server"));
bot.setVersion(Data.config.getString("main-version"));
if (!connect(bot))
return null;
if (channelPrefixes == null)
channelPrefixes = Reflection.getPrivateValue(PircBotX.class,"channelPrefixes",bot);
botList.add(bot);
return bot;
}
public static boolean connect(PircBotX bot) {
String server = Data.config.getString("main-server");
try {
bot.connect(server.contentEquals("localhost") ? null : server);
if (!bot.isConnected())
return false;
startWebServer(bot);
if (!Data.config.getString("main-nickservpass").isEmpty())
bot.identify(Data.config.getString("main-nickservpass"));
return true;
} catch (NickAlreadyInUseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IrcException e) {
e.printStackTrace();
}
return false;
}
public static void startWebServer(PircBotX bot) {
try {
if (!WebServer.exists() && WebServer.start(bot.getInetAddress().getHostAddress(),8000))
System.out.println("--- Shocky web server is running! ---");
} catch (IOException e) {
e.printStackTrace();
}
}
public static List<String> getBotChannels(PircBotX bot) throws Exception {
Set<Channel> set = bot.getChannels();
List<String> list = new ArrayList<String>(set.size());
for (Channel channel : set)
list.add(channel.getName());
return Collections.unmodifiableList(list);
}
public static void lostChannel(String channel) throws Exception {
Data.channels.remove(channel);
}
public static void join(String... channels) throws Exception {
join(botList, channels);
}
public synchronized static void join(List<? extends PircBotX> bots, String... channels) throws Exception {
if (channels == null || channels.length == 0)
return;
List<Thread> joinThreads = new LinkedList<Thread>();
synchronized (botList) {
List<String> currentChannels = new LinkedList<String>();
for (PircBotX bot : botList)
currentChannels.addAll(getBotChannels(bot));
List<String> joinList = new LinkedList<String>(Arrays.asList(channels));
joinList.removeAll(currentChannels);
if (joinList.size() == 0)
return;
Iterator<String> joinIter = joinList.iterator();
for (PircBotX bot : bots) {
if (!joinIter.hasNext())
break;
List<String> channelList = new ArrayList<String>(getBotChannels(bot));
channelList.removeAll(joinList);
if (channelList.size() >= Data.config.getInt("main-maxchannels"))
continue;
joinThreads.add(joinChannels(bot, joinIter, channelList.size()));
}
if (bots == botList) {
while (joinIter.hasNext()) {
Thread t = joinChannels(createBot(), joinIter, 0);
if (t == null)
break;
joinThreads.add(t);
Thread.sleep(3000);
}
}
}
for (Thread t : joinThreads)
t.join();
System.out.format("Finished joining %d channel%s",channels.length,channels.length==1?"":"s").println();
}
private static Thread joinChannels(PircBotX bot, Iterator<String> iter, int start) {
if (bot == null || iter == null || !iter.hasNext())
return null;
List<String> botChannel = new ArrayList<String>();
for (int i = start; iter.hasNext() && i < Data.config.getInt("main-maxchannels"); ++i) {
String channel = iter.next().toLowerCase();
synchronized (Data.channels) {
if (!Data.channels.contains(channel))
Data.channels.add(channel);
}
botChannel.add(channel);
}
Thread t = new JoinChannelsThread(bot,botChannel.toArray(new String[0]));
t.start();
return t;
}
private static class JoinChannelsThread extends Thread {
private final PircBotX bot;
private final String[] channels;
public JoinChannelsThread(PircBotX bot, String[] channels) {
super();
this.setDaemon(true);
this.bot = bot;
this.channels = channels;
}
@Override
public void run() {
for (int i = 0; i < channels.length; ++i) {
String channel = channels[i];
if (bot.channelExists(channel))
continue;
if (i > 0 && (i % 10 == 0)) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bot.joinChannel(channel);
}
}
}
public static void part(String... channels) throws Exception {
List<String> argsList = null;
if (channels == null || channels.length == 0)
argsList = new LinkedList<String>(Data.channels);
else
argsList = Arrays.asList(channels);
if (!Data.channels.removeAll(argsList))
return;
synchronized (botList) {
for (PircBotX bot : botList) {
List<String> partList = new LinkedList<String>(getBotChannels(bot));
partList.retainAll(argsList);
for (String channel : partList)
bot.partChannel(bot.getChannel(channel));
}
}
}
}