]> Pileus Git - ~andy/spades/blob - src/org/pileus/spades/Message.java
Add cards display from IRC messages
[~andy/spades] / src / org / pileus / spades / Message.java
1 package org.pileus.spades;
2
3 import java.util.Date;
4 import java.util.regex.Pattern;
5 import java.util.regex.Matcher;
6
7 public class Message
8 {
9         /* Enumerations */
10         enum Type {
11                 OTHER,    // Unknown message type
12                 JOIN,     // Join channel
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
22         };
23
24         enum How {
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
31         };
32
33         /* Constants */
34         private final  String  reMsg  = "(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+)[= ]+)?(([^: ]+) *)?(:(.*))?";
35         private final  String  reFrom = "([^! ]+)!.*";
36         private final  String  reTo   = "(([^ :,]*)[:,] *)?(.*)";
37         private final  String  reCmd  = "/([a-z]+)( +(.*))?";
38
39         private static Pattern ptMsg  = null;
40         private static Pattern ptFrom = null;
41         private static Pattern ptTo   = null;
42         private static Pattern ptCmd  = null;
43
44         /* Public data */
45         public Date    time = null;
46
47         public String  line = "";
48
49         public String  src  = "";
50         public String  cmd  = "";
51         public String  dst  = "";
52         public String  arg  = "";
53         public String  msg  = "";
54
55         public Type    type = Type.OTHER;
56         public How     how  = How.OTHER;
57         public String  from = "";
58         public String  to   = "";
59         public String  txt  = "";
60
61         /* Static methods */
62         public static String clean(String msg)
63         {
64                 String num = "0?[0-9]|1[0-5]";
65                 return msg.replaceAll("[\\002\\011\\017\\025]", "")
66                           .replaceAll("[\\003\\013]("+num+")(,"+num+")?", "");
67         }
68
69         /* Private methods */
70         private String notnull(String string)
71         {
72                 return string == null ? "" : string;
73         }
74
75         /* Public Methods */
76         public Message(String dst, String from, String msg)
77         {
78                 this.time = new Date();
79                 this.how  = How.SENT;
80                 this.from = from;
81
82                 if (msg.charAt(0) == '/') {
83                         if (ptCmd == null)
84                                 ptCmd = Pattern.compile(reCmd);
85                         Matcher mr = ptCmd.matcher(msg);
86                         if (!mr.matches())
87                                 return;
88
89                         String cmd = notnull(mr.group(1));
90                         String arg = notnull(mr.group(3));
91
92                         if (cmd.matches("join")) {
93                                 Os.debug("Message: /join");
94                                 this.type = Type.JOIN;
95                                 this.cmd  = "JOIN";
96                                 this.msg  = arg;
97                                 this.line = this.cmd + " :" + arg;
98                         }
99                         if (cmd.matches("part")) {
100                                 Os.debug("Message: /part");
101                                 this.type = Type.PART;
102                                 this.cmd  = "PART";
103                                 this.msg  = arg;
104                                 this.line = this.cmd + " :" + arg;
105                         }
106                         if (this.line == null) {
107                                 Os.debug("Message: unknown command");
108                         }
109                 } else {
110                         this.type = Type.PRIVMSG;
111                         this.cmd  = "PRIVMSG";
112                         this.dst  = dst;
113                         this.msg  = msg;
114                         this.line = this.cmd + " " + this.dst + " :" + this.msg;
115                 }
116         }
117
118         public Message(String line, String name)
119         {
120                 // Initialize regexes
121                 if (ptMsg  == null) ptMsg  = Pattern.compile(reMsg);
122                 if (ptFrom == null) ptFrom = Pattern.compile(reFrom);
123                 if (ptTo   == null) ptTo   = Pattern.compile(reTo);
124
125                 // Set time stamp
126                 this.time = new Date();
127
128                 // Cleanup line
129                 line = line.replaceAll("\\s+",       " ");
130                 line = line.replaceAll("^ | $",      "");
131                 this.line = line;
132
133                 // Split line into parts
134                 Matcher mrMsg = ptMsg.matcher(line);
135                 if (mrMsg.matches()) {
136                         this.src  = notnull(mrMsg.group(2));
137                         this.cmd  = notnull(mrMsg.group(4));
138                         this.dst  = notnull(mrMsg.group(6));
139                         this.arg  = notnull(mrMsg.group(8));
140                         this.msg  = notnull(mrMsg.group(10));
141                 }
142
143                 // Determine friendly parts
144                 Matcher mrFrom = ptFrom.matcher(this.src);
145                 if (mrFrom.matches())
146                         this.from = notnull(mrFrom.group(1));
147
148                 Matcher mrTo = ptTo.matcher(this.msg);
149                 if (mrTo.matches())
150                         this.to   = notnull(mrTo.group(2));
151
152                 if (this.to.equals(""))
153                         this.txt  = notnull(this.msg);
154                 else
155                         this.txt  = notnull(mrTo.group(3));
156
157                 // Parse commands names
158                 if      (this.cmd.equals("PRIVMSG"))       this.type = Type.PRIVMSG;
159                 else if (this.cmd.equals("332"))           this.type = Type.TOPIC;
160                 else if (this.cmd.equals("353"))           this.type = Type.NAMES;
161                 else if (this.cmd.equals("ERROR"))         this.type = Type.ERROR;
162                 else if (this.cmd.equals("CAP"))           this.type = Type.CAP;
163                 else if (this.cmd.equals("AUTHENTICATE"))  this.type = Type.AUTH;
164                 else if (this.cmd.equals("903"))           this.type = Type.AUTHOK;
165                 else if (this.cmd.equals("904"))           this.type = Type.AUTHFAIL;
166                 else if (this.cmd.equals("905"))           this.type = Type.AUTHFAIL;
167                 else if (this.cmd.equals("906"))           this.type = Type.AUTHFAIL;
168                 else if (this.cmd.equals("907"))           this.type = Type.AUTHFAIL;
169
170                 // Set directed
171                 if      (this.dst.equals(name))            this.how  = How.PRIVMSG;
172                 else if (this.to.equals(name))             this.how  = How.DIRECT;
173                 else if (this.msg.contains(name))          this.how  = How.MENTION;
174                 else if (this.type == Type.PRIVMSG)        this.how  = How.CHANNEL;
175         }
176
177         public void debug()
178         {
179                 Os.debug("---------------------");
180                 Os.debug("line = [" + line + "]");
181                 Os.debug("src  = " + this.src);
182                 Os.debug("cmd  = " + this.cmd);
183                 Os.debug("dst  = " + this.dst);
184                 Os.debug("arg  = " + this.arg);
185                 Os.debug("msg  = " + this.msg);
186                 Os.debug("from = " + this.from);
187                 Os.debug("to   = " + this.to);
188                 Os.debug("txt  = " + this.txt);
189                 Os.debug("---------------------");
190         }
191
192         public String toString()
193         {
194                 return this.from + ": " + this.txt;
195         }
196 }