1 package org.pileus.spades;
4 import java.util.regex.Pattern;
5 import java.util.regex.Matcher;
11 OTHER, // Unknown message type
13 PART, // Leave channel
14 PRIVMSG, // Private message
15 TOPIC, // Display current topic
16 NAMES, // Display user names
17 ERROR, // Error message from server
18 CAP, // Server capabilities
19 AUTH, // Authentication message
20 AUTHOK, // Authentication succeeded
21 AUTHFAIL, // Authentication failed
25 OTHER, // Unknown message type
26 CHANNEL, // Normal message to a channel
27 MENTION, // User was mentioned in message text
28 DIRECT, // Message directed towards user
29 PRIVMSG, // Private message to user only
30 SENT // Message was sent by the user
34 private static final String reMsg = "(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+)[= ]+)?(([^: ]+) *)?(:(.*))?";
35 private static final String reFrom = "([^! ]+)!.*";
36 private static final String reTo = "(([^ :,]*)[:,] *)?(.*)";
37 private static final String reCmd = "/([a-z]+)( +(.*))?";
39 private static final Pattern ptMsg = Pattern.compile(reMsg);
40 private static final Pattern ptFrom = Pattern.compile(reFrom);
41 private static final Pattern ptTo = Pattern.compile(reTo);
42 private static final Pattern ptCmd = Pattern.compile(reCmd);
45 public Date time = null;
47 public String line = "";
49 public String src = "";
50 public String cmd = "";
51 public String dst = "";
52 public String arg = "";
53 public String msg = "";
55 public Type type = Type.OTHER;
56 public How how = How.OTHER;
57 public String from = "";
58 public String to = "";
59 public String txt = "";
62 public static String clean(String msg)
64 String num = "0?[0-9]|1[0-5]";
65 return msg.replaceAll("[\\002\\011\\017\\025]", "")
66 .replaceAll("[\\003\\013]("+num+")(,"+num+")?", "");
70 public Message(String dst, String from, String msg)
72 this.time = new Date();
76 if (this.parseSlash(msg))
79 this.type = Type.PRIVMSG;
83 this.line = this.cmd + " " + this.dst + " :" + this.msg;
86 public Message(String line, String name)
88 this.time = new Date();
91 this.parseTypes(name);
96 Os.debug("---------------------");
97 Os.debug("line = [" + line + "]");
98 Os.debug("src = " + this.src);
99 Os.debug("cmd = " + this.cmd);
100 Os.debug("dst = " + this.dst);
101 Os.debug("arg = " + this.arg);
102 Os.debug("msg = " + this.msg);
103 Os.debug("from = " + this.from);
104 Os.debug("to = " + this.to);
105 Os.debug("txt = " + this.txt);
106 Os.debug("---------------------");
109 public String toString()
111 return this.from + ": " + this.txt;
114 /* Private methods */
115 private String notnull(String string)
117 return string == null ? "" : string;
120 private boolean parseSlash(String msg)
122 if (msg.charAt(0) != '/')
126 Matcher mr = ptCmd.matcher(msg);
130 String cmd = notnull(mr.group(1));
131 String arg = notnull(mr.group(3));
134 if (cmd.matches("join")) {
135 Os.debug("Message: /join");
136 this.type = Type.JOIN;
139 this.line = this.cmd + " :" + arg;
142 if (cmd.matches("part")) {
143 Os.debug("Message: /part");
144 this.type = Type.PART;
147 this.line = this.cmd + " :" + arg;
150 // Print warning if command is not recognized
151 if (this.line == null)
152 Os.debug("Message: unknown command");
157 private void parseText(String line)
160 line = line.replaceAll("\\s+", " ");
161 line = line.replaceAll("^ | $", "");
164 // Split line into parts
165 Matcher mrMsg = ptMsg.matcher(line);
166 if (mrMsg.matches()) {
167 this.src = notnull(mrMsg.group(2));
168 this.cmd = notnull(mrMsg.group(4));
169 this.dst = notnull(mrMsg.group(6));
170 this.arg = notnull(mrMsg.group(8));
171 this.msg = notnull(mrMsg.group(10));
174 // Determine friendly parts
175 Matcher mrFrom = ptFrom.matcher(this.src);
176 if (mrFrom.matches())
177 this.from = notnull(mrFrom.group(1));
179 Matcher mrTo = ptTo.matcher(this.msg);
181 this.to = notnull(mrTo.group(2));
183 if (this.to.equals(""))
184 this.txt = notnull(this.msg);
186 this.txt = notnull(mrTo.group(3));
189 private void parseTypes(String name)
191 // Parse commands names
192 if (this.cmd.equals("PRIVMSG")) this.type = Type.PRIVMSG;
193 else if (this.cmd.equals("332")) this.type = Type.TOPIC;
194 else if (this.cmd.equals("353")) this.type = Type.NAMES;
195 else if (this.cmd.equals("ERROR")) this.type = Type.ERROR;
196 else if (this.cmd.equals("CAP")) this.type = Type.CAP;
197 else if (this.cmd.equals("AUTHENTICATE")) this.type = Type.AUTH;
198 else if (this.cmd.equals("903")) this.type = Type.AUTHOK;
199 else if (this.cmd.equals("904")) this.type = Type.AUTHFAIL;
200 else if (this.cmd.equals("905")) this.type = Type.AUTHFAIL;
201 else if (this.cmd.equals("906")) this.type = Type.AUTHFAIL;
202 else if (this.cmd.equals("907")) this.type = Type.AUTHFAIL;
205 if (this.dst.equals(name)) this.how = How.PRIVMSG;
206 else if (this.to.equals(name)) this.how = How.DIRECT;
207 else if (this.msg.contains(name)) this.how = How.MENTION;
208 else if (this.type == Type.PRIVMSG) this.how = How.CHANNEL;