del: Remove unused variable
[cacert-votebot.git] / src / org / cacert / votebot / IRCClient.java
1 package org.cacert.votebot;
2
3 import java.io.BufferedReader;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.io.PrintWriter;
8 import java.net.Socket;
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.concurrent.Semaphore;
12
13 import javax.net.ssl.SSLSocketFactory;
14
15 public class IRCClient {
16
17 private Semaphore loggedin = new Semaphore(0);
18
19 private PrintWriter out;
20
21 private Socket s;
22
23 class ServerReader implements Runnable {
24
25 private BufferedReader br;
26
27 public ServerReader(BufferedReader br) {
28 this.br = br;
29
30 new Thread(this).start();
31 }
32
33 @Override
34 public void run() {
35 String l;
36
37 try {
38 while ((l = br.readLine()) != null) {
39 String fullline = l;
40 // System.out.println(l);
41
42 if (l.startsWith("PING ")) {
43 System.out.println("PONG");
44 out.println("PONG " + l.substring(5));
45 }
46
47 String referent = "";
48
49 if (l.startsWith(":")) {
50 String[] parts = l.split(" ", 2);
51 referent = parts[0];
52 l = parts[1];
53 }
54
55 String[] command = l.split(" ", 3);
56
57 if (command[0].equals("001")) {
58 loggedin.release();
59 }
60
61 if (command[0].equals("PRIVMSG")) {
62 String msg = command[2].substring(1);
63 String chnl = command[1];
64
65 if ( !chnl.startsWith("#")) {
66 handlePrivMsg(referent, msg);
67 } else {
68 handleMsg(referent, chnl, msg);
69 }
70
71 log(chnl, fullline);
72 } else if (command[0].equals("JOIN")) {
73 String chn = command[1].substring(1);
74 targetBot.join(cleanReferent(referent), chn.substring(1));
75 log(chn, fullline);
76 } else if (command[0].equals("PART")) {
77 String chn = command[1];
78 targetBot.part(cleanReferent(referent), chn);
79 log(chn, fullline);
80 } else {
81 System.out.println("unknown line: ");
82 System.out.println(l);
83 }
84 }
85 } catch (IOException e) {
86 e.printStackTrace();
87 }
88
89 }
90
91 private String cleanReferent(String referent) {
92 String[] parts = referent.split("!");
93
94 if ( !parts[0].startsWith(":")) {
95 System.err.println("invalid public message");
96 return "unknown";
97 }
98
99 return parts[0];
100 }
101
102 HashMap<String, PrintWriter> logs = new HashMap<String, PrintWriter>();
103
104 private void log(String chn, String l) throws IOException {
105 if ( true ) {
106 return;
107 }
108
109 PrintWriter log = logs.get(chn);
110
111 if (log == null) {
112 log = new PrintWriter(new FileOutputStream("irc/log_" + chn), true);
113 logs.put(chn, log);
114 }
115
116 log.println(l);
117 }
118
119 private void handlePrivMsg(String referent, String msg) {
120 String[] parts = referent.split("!");
121
122 if ( !parts[0].startsWith(":")) {
123 System.err.println("invalid private message");
124 return;
125 }
126
127 if (targetBot == null) {
128 System.out.println("dropping message");
129 return;
130 }
131
132 targetBot.privateMessage(parts[0].substring(1), msg);
133 }
134
135 private void handleMsg(String referent, String chnl, String msg) {
136 String[] parts = referent.split("!");
137
138 if ( !parts[0].startsWith(":")) {
139 System.err.println("invalid public message");
140 return;
141 }
142
143 if (targetBot == null) {
144 System.out.println("dropping message");
145 return;
146 }
147
148 if ( !chnl.startsWith("#")) {
149 System.err.println("invalid public message (chnl)");
150 return;
151 }
152
153 targetBot.publicMessage(parts[0].substring(1), chnl.substring(1), msg);
154 }
155
156 }
157
158 public IRCClient(String nick, String server, int port, boolean ssl) throws IOException, InterruptedException {
159 if ( !nick.matches("[a-zA-Z0-9_-]+")) {
160 throw new Error("malformed");
161 }
162
163 if (ssl) {
164 s = SSLSocketFactory.getDefault().createSocket(server, port);//default-ssl = 7000
165 // default-ssl = 7000
166 } else {
167 s = new Socket(server, port);
168 // default-plain = 6667
169 }
170
171 out = new PrintWriter(s.getOutputStream(), true);
172 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
173
174 new ServerReader(in);
175
176 out.println("USER " + nick + " 0 * :unknown");
177 out.println("NICK " + nick);
178
179 loggedin.acquire();
180 }
181
182 HashSet<String> joined = new HashSet<String>();
183
184 private IRCBot targetBot;
185
186 public void join(String channel) {
187 if ( !channel.matches("[a-zA-Z0-9_-]+")) {
188 return;
189 }
190
191 if (joined.add(channel)) {
192 out.println("JOIN #" + channel);
193 }
194 }
195
196 public void leave(String channel) {
197 if ( !channel.matches("[a-zA-Z0-9_-]+")) {
198 return;
199 }
200
201 if (joined.remove(channel)) {
202 out.println("PART #" + channel);
203 }
204 }
205
206 public void send(String msg, String channel) {
207 if ( !channel.matches("[a-zA-Z0-9_-]+")) {
208 return;
209 }
210
211 out.println("PRIVMSG #" + channel + " :" + msg);
212 }
213
214 public void sendPrivate(String msg, String to) {
215 if ( !to.matches("[a-zA-Z0-9_-]+")) {
216 return;
217 }
218
219 out.println("PRIVMSG " + to + " :" + msg);
220 }
221
222 public void setBot(IRCBot bot) {
223 this.targetBot = bot;
224 }
225
226 public static IRCClient parseCommandLine(String[] commandLine, String nick) throws IOException, InterruptedException {
227 String host = null;
228 int port = 7000;
229 boolean ssl = true;
230
231 for (int i = 0; i < commandLine.length; i++) {
232 String cmd = commandLine[i];
233
234 if (cmd.equals("--no-ssl") || cmd.equals("-u")) {
235 ssl = false;
236 } else if (cmd.equals("--ssl") || cmd.equals("-s")) {
237 ssl = true;
238 } else if (cmd.equals("--host") || cmd.equals("-h")) {
239 host = commandLine[++i];
240 } else if (cmd.equals("--port") || cmd.equals("-p")) {
241 port = Integer.parseInt(commandLine[++i]);
242 } else if (cmd.equals("--nick") || cmd.equals("-n")) {
243 nick = commandLine[++i];
244 } else if (cmd.equals("--help") || cmd.equals("-h")) {
245 System.out.println("Options: [--no-ssl|-u|--ssl|-s|[--host|-h] <host>|[--port|-p] <port>|[--nick|-n] <nick>]*");
246 System.out.println("Requires the -host argument, --ssl is default, last argument of a kind is significant.");
247 throw new Error("Operation caneled");
248 } else {
249 throw new Error("Invalid option (usage with --help): " + cmd);
250 }
251 }
252
253 if (host == null) {
254 throw new Error("--host <host> is missing");
255 }
256
257 return new IRCClient(nick, host, port, ssl);
258 }
259
260 }