package tterrag.tppibot.commands; import java.lang.reflect.Type; import java.util.Collection; import java.util.List; import java.util.Map; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; import org.pircbotx.Channel; import org.pircbotx.PircBotX; import org.pircbotx.User; import org.pircbotx.hooks.events.DisconnectEvent; import org.pircbotx.hooks.events.MessageEvent; import tterrag.tppibot.config.Config; import tterrag.tppibot.runnables.MessageSender; import com.google.common.base.Joiner; import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.eventbus.Subscribe; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; public class Tell extends Command { public static class MultimapJson implements JsonSerializer<Multimap<?, ?>> { @Override public JsonElement serialize(Multimap<?, ?> src, Type typeOfSrc, JsonSerializationContext context) { return context.serialize(src.asMap()); } } private Config tellsConfig; private ArrayListMultimap<String, TellMessage> tells = ArrayListMultimap.create(); @SuppressWarnings("serial") public Tell() { super("tell"); tellsConfig = new Config("tells.json"); tellsConfig.setGson(new GsonBuilder().setPrettyPrinting().registerTypeHierarchyAdapter(Multimap.class, new MultimapJson()).create()); if (Strings.isNullOrEmpty(tellsConfig.getText())) { tellsConfig.writeJsonToFile(tells); } else { Map<String, Collection<TellMessage>> temp = new Gson().fromJson(tellsConfig.getText(), new TypeToken<Map<String, Collection<TellMessage>>>() { }.getType()); temp.entrySet().forEach(e -> tells.putAll(e.getKey(), e.getValue())); } } @Override public void onCommand(PircBotX bot, User user, Channel channel, List<String> lines, String... args) { if (args.length < 2) { lines.add("This command requires at least two args."); return; } String message = Joiner.on(' ').join(args); TellMessage send = new TellMessage(args[0], message, channel.getName(), user.getNick()); if (!tells.containsValue(send)) { tells.put(send.getSendTo(), send); MessageSender.INSTANCE.enqueueNotice(bot, user.getNick(), "I'll pass that along."); } else { MessageSender.INSTANCE.enqueueNotice(bot, user.getNick(), "I can't let you do that."); } } @Override public String getDesc() { return "Stores a message to send to a user when they return."; } @Override public boolean shouldReceiveEvents() { return true; } @Subscribe public void onDisconnect(DisconnectEvent<PircBotX> event) { tellsConfig.writeJsonToFile(tells); } @Subscribe public void onMessage(MessageEvent<PircBotX> event) { if (tells.containsKey(event.getUser().getNick())) { Collection<TellMessage> messages = tells.get(event.getUser().getNick()); Collection<TellMessage> toRemove = Lists.newArrayList(); for (TellMessage toSend : messages) { if (toSend.getChannel().equals(event.getChannel().getName())) { MessageSender.INSTANCE.enqueueNotice(event.getBot(), toSend.getSendTo(), "\"" + toSend.getMessage() + "\" - " + toSend.getFrom()); toRemove.add(toSend); } } messages.removeAll(toRemove); } } @RequiredArgsConstructor @Getter @EqualsAndHashCode @ToString public static class TellMessage { private final String sendTo; private final String message; private final String channel; private final String from; } }