package heufybot.modules; import heufybot.core.Logger; import heufybot.utils.FileUtils; import heufybot.utils.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; public class Tell extends Module { private final int MESSAGE_COOLDOWN = 10; private LinkedHashMap<String, ArrayList<Message>> tellsMap; private HashMap<String, Date> tellers; private String databasePath; public Tell(String server) { super(server); this.authType = AuthType.Anyone; this.apiVersion = 60; this.triggerTypes = new TriggerType[] { TriggerType.Message, TriggerType.Action }; this.trigger = "^" + this.commandPrefix + "(tell|r(emove)?tell|s(ent)?tells)($| .*)"; this.triggerOnEveryMessage = true; this.tellsMap = new LinkedHashMap<String, ArrayList<Message>>(); this.tellers = new HashMap<String, Date>(); this.databasePath = "data/" + server + "/tells.json"; } @Override public String getHelp(String message) { return "Commands: " + this.commandPrefix + "tell <user> <message>, " + this.commandPrefix + "rtell <message>, " + this.commandPrefix + "senttells | Tells the specified user a message the next time they speak, " + "removes a message sent by you from the database or lists your pending messages."; } @Override public void processEvent(String source, String message, String triggerUser, List<String> params) { if (message.toLowerCase().matches("^" + this.commandPrefix + "tell.*")) { if (params.size() == 1) { this.bot.getServer(this.server).cmdPRIVMSG(source, "Tell what?"); return; } params.remove(0); if (params.size() == 1) { this.bot.getServer(this.server).cmdPRIVMSG(source, "What do you want me to tell them?"); return; } Date timestamp = this.tellers.get(triggerUser); if (timestamp != null) { long timeStampDifference = (new Date().getTime() - timestamp.getTime()) / 1000; System.out.println(timeStampDifference); if (timeStampDifference < this.MESSAGE_COOLDOWN) { this.bot.getServer(this.server).cmdPRIVMSG( source, "Calm down, " + triggerUser + "! You just sent a message " + timeStampDifference + " seconds ago! You have to wait " + (this.MESSAGE_COOLDOWN - timeStampDifference) + " more seconds."); return; } } String[] recepients; if (params.get(0).contains("&")) { recepients = params.get(0).split("&"); } else { recepients = new String[] { params.get(0) }; } params.remove(0); for (String recepient2 : recepients) { String recepient = this.fixRegex(recepient2.replaceAll(":", "")); if (triggerUser.toLowerCase().matches(recepient.toLowerCase())) { this.bot.getServer(this.server).cmdPRIVMSG(source, "Why are you telling yourself that?"); return; } else if (recepient2.equalsIgnoreCase(this.bot.getServer(this.server).getNickname())) { this.bot.getServer(this.server).cmdPRIVMSG(source, "Thanks for telling me that, " + triggerUser + "."); return; } String messageToSend = StringUtils.join(params, " "); Date date = new Date(); DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss (z)"); String dateString = format.format(date); String messageSource = ""; if (source.equals(triggerUser)) { messageSource = "PM"; } else { messageSource = "Channel"; } Message tellMessage = new Message(triggerUser, messageToSend, dateString, messageSource); if (!this.tellsMap.containsKey(recepient)) { this.tellsMap.put(recepient, new ArrayList<Message>()); } this.tellsMap.get(recepient).add(tellMessage); this.tellers.put(triggerUser, new Date()); this.writeMessages(); this.bot.getServer(this.server).cmdPRIVMSG(source, "Okay, I'll tell " + recepient2 + " that next time they speak."); } } else if (message.toLowerCase().matches("^" + this.commandPrefix + "r(emove)?tell.*")) { if (params.size() == 1) { this.bot.getServer(this.server).cmdPRIVMSG(source, "Remove what?"); return; } params.remove(0); String searchString = ".*" + StringUtils.join(params, " ") + ".*"; boolean matchFound = false; for (Iterator<String> iter = this.tellsMap.keySet().iterator(); iter.hasNext() && !matchFound; ) { String user = iter.next(); ArrayList<Message> sentMessages = this.tellsMap.get(user); for (Iterator<Message> iter2 = sentMessages.iterator(); iter2.hasNext() && !matchFound; ) { Message sentMessage = iter2.next(); if (sentMessage.getFrom().equalsIgnoreCase(triggerUser) && sentMessage.getText().toLowerCase() .matches(searchString.toLowerCase())) { String messageString = "Message \"" + sentMessage.getText() + "\" sent to " + user + " on " + sentMessage.getDateSent() + " was removed from the message database!"; if (sentMessage.getMessageSource().equals("PM")) { this.bot.getServer(this.server).cmdNOTICE(triggerUser, messageString); } else { this.bot.getServer(this.server).cmdPRIVMSG(source, messageString); } iter2.remove(); this.writeMessages(); matchFound = true; } } if (sentMessages.size() == 0) { this.tellsMap.remove(user); } } if (!matchFound) { this.bot.getServer(this.server).cmdPRIVMSG(source, "No message matching \"" + searchString + "\" was found."); } } else if (message.toLowerCase().matches("^" + this.commandPrefix + "s(ent)?tells.*")) { if (params.size() > 1) { return; } boolean foundMessage = false; for (String user : this.tellsMap.keySet()) { ArrayList<Message> sentMessages = this.tellsMap.get(user); for (Message sentMessage : sentMessages) { if (sentMessage.getFrom().equalsIgnoreCase(triggerUser)) { foundMessage = true; this.bot.getServer(this.server).cmdNOTICE( triggerUser, sentMessage.getText() + " < Sent to " + user + " on " + sentMessage.getDateSent()); } } } if (!foundMessage) { this.bot.getServer(this.server).cmdNOTICE(triggerUser, "There are no messages sent by you that have not been received yet."); } } // Automatic stuff int messageCount = 0; for (Iterator<String> iter = this.tellsMap.keySet().iterator(); iter.hasNext() && messageCount < 3; ) { String user = iter.next(); if (triggerUser.toLowerCase().matches(user.toLowerCase())) { ArrayList<Message> sentMessages = this.tellsMap.get(user); for (Iterator<Message> iter2 = sentMessages.iterator(); iter2.hasNext() && messageCount < 3; messageCount++) { Message sentMessage = iter2.next(); String messageString = triggerUser + ": " + sentMessage.getText() + " < From " + sentMessage.getFrom() + " on " + sentMessage.getDateSent(); if (sentMessage.getMessageSource().equals("PM")) { this.bot.getServer(this.server).cmdPRIVMSG(triggerUser, messageString); iter2.remove(); } else if (source.startsWith("#")) { this.bot.getServer(this.server).cmdPRIVMSG(source, messageString); iter2.remove(); } } if (sentMessages.size() == 0) { iter.remove(); } } } this.writeMessages(); } @Override public void onLoad() { if (FileUtils.touchFile(this.databasePath)) { FileUtils.writeFile(this.databasePath, "[]"); } this.readMessages(); } @Override public void onUnload() { this.writeMessages(); } public void readMessages() { try { JSONArray recepients = (JSONArray) new JSONParser().parse(FileUtils .readFile(this.databasePath)); for (int i = 0; i < recepients.size(); i++) { JSONObject recepient = (JSONObject) recepients.get(i); String name = recepient.get("name").toString(); JSONArray messages = (JSONArray) recepient.get("messages"); ArrayList<Message> messageList = new ArrayList<Message>(); for (int j = 0; j < messages.size(); j++) { JSONObject messageObject = (JSONObject) messages.get(j); Message message = new Message(messageObject.get("from").toString(), messageObject.get("text").toString(), messageObject.get("dateSent") .toString(), messageObject.get("messageSource").toString()); messageList.add(message); } this.tellsMap.put(name, messageList); } } catch (ParseException e) { Logger.error("Module: Tell", "The tells database could not be read."); } } @SuppressWarnings("unchecked") public void writeMessages() { JSONArray recepients = new JSONArray(); for (String recepient : this.tellsMap.keySet()) { JSONArray messages = new JSONArray(); JSONObject recepientObject = new JSONObject(); for (Message message : this.tellsMap.get(recepient)) { JSONObject messageObject = new JSONObject(); messageObject.put("from", message.getFrom()); messageObject.put("text", message.getText()); messageObject.put("dateSent", message.getDateSent()); messageObject.put("messageSource", message.getMessageSource()); messages.add(messageObject); } recepientObject.put("name", recepient); recepientObject.put("messages", messages); recepients.add(recepientObject); } FileUtils.writeFile(this.databasePath, recepients.toJSONString()); } private String fixRegex(String regex) { return "^" + StringUtils.escapeRegex(regex).replaceAll("\\*", ".*").replaceAll("\\?", ".") .replaceAll("\\(", "(").replaceAll("\\)", ")").replaceAll(",", "|") .replaceAll("/", "|") + "$"; } }