1 /***
2 * Jetrix TetriNET Server
3 * Copyright (C) 2001-2004 Emmanuel Bourg
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 package net.jetrix.protocols;
21
22 import java.util.*;
23 import net.jetrix.*;
24 import net.jetrix.messages.*;
25 import net.jetrix.messages.channel.*;
26 import net.jetrix.messages.channel.specials.*;
27 import org.apache.commons.lang.*;
28
29 /***
30 * Protocol to communicate with IRC clients.
31 *
32 * @author Emmanuel Bourg
33 * @version $Revision: 799 $, $Date: 2009-02-18 17:28:08 +0100 (Wed, 18 Feb 2009) $
34 */
35 public class IRCProtocol extends AbstractProtocol
36 {
37 private static Map<String, String> styles = new HashMap<String, String>();
38
39 static
40 {
41 styles.put("red", "\u000304");
42 styles.put("black", "\u000301");
43 styles.put("green", "\u000303");
44 styles.put("lightGreen", "\u000309");
45 styles.put("darkBlue", "\u000302");
46 styles.put("blue", "\u000312");
47 styles.put("cyan", "\u000310");
48 styles.put("aqua", "\u000311");
49 styles.put("yellow", "\u000308");
50 styles.put("kaki", "\u000307");
51 styles.put("brown", "\u000305");
52 styles.put("lightGray", "\u000315");
53 styles.put("gray", "\u000314");
54 styles.put("magenta", "\u000313");
55 styles.put("purple", "\u000306");
56 styles.put("b", "\u0002");
57 styles.put("i", "\u0016");
58 styles.put("u", "\u0037");
59 styles.put("white", "\u000300");
60 }
61
62 /***
63 * Return the name of this protocol
64 */
65 public String getName()
66 {
67 return "IRC";
68 }
69
70 /***
71 * Parse the specified string and return the corresponding server
72 * message for this protocol.
73 */
74 public Message getMessage(String line)
75 {
76 IRCMessage msg = IRCMessage.parse(line);
77
78 if (msg.isCommand(IRCCommand.JOIN))
79 {
80 AddPlayerMessage message = new AddPlayerMessage();
81 message.setDestination(ChannelManager.getInstance().getChannel(msg.getParameter(0)));
82
83 return message;
84 }
85 else if (msg.isCommand(IRCCommand.PART))
86 {
87 LeaveMessage message = new LeaveMessage();
88 message.setDestination(ChannelManager.getInstance().getChannel(msg.getParameter(0)));
89
90 return message;
91 }
92 else if (msg.isCommand(IRCCommand.PRIVMSG))
93 {
94
95
96 SmsgMessage message = new SmsgMessage();
97 message.setDestination(ChannelManager.getInstance().getChannel(msg.getParameter(0)));
98 message.setText(msg.getParameter(1));
99 message.setPrivate(false);
100
101 return message;
102 }
103 else
104 {
105 return null;
106 }
107 }
108
109 /***
110 * Translate the specified message into a string that will be sent
111 * to a client using this protocol.
112 */
113 public String translate(Message m, Locale locale)
114 {
115 if (m instanceof PlineMessage) { return translate((PlineMessage) m, locale); }
116 else if (m instanceof PlayerLostMessage) { return translate((PlayerLostMessage) m); }
117 else if (m instanceof PlineActMessage) { return translate((PlineActMessage) m, locale); }
118 else if (m instanceof TeamMessage) { return translate((TeamMessage) m, locale); }
119 else if (m instanceof JoinMessage) { return translate((JoinMessage) m, locale); }
120 else if (m instanceof LeaveMessage) { return translate((LeaveMessage) m, locale); }
121 else if (m instanceof NewGameMessage) { return translate((NewGameMessage) m, locale); }
122 else if (m instanceof EndGameMessage) { return translate((EndGameMessage) m, locale); }
123 else if (m instanceof IngameMessage) { return translate((IngameMessage) m, locale); }
124 else if (m instanceof PauseMessage) { return translate((PauseMessage) m); }
125 else if (m instanceof ResumeMessage) { return translate((ResumeMessage) m); }
126 else if (m instanceof GmsgMessage) { return translate((GmsgMessage) m, locale); }
127 else if (m instanceof SpectatorListMessage) { return translate((SpectatorListMessage) m, locale); }
128
129 else
130 {
131 return null;
132 }
133 }
134
135 public String translate(PlineMessage m, Locale locale)
136 {
137 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
138
139 Destination source = m.getSource();
140 if (source != null && source instanceof Client)
141 {
142 message.setNick(((Client) source).getUser().getName());
143 }
144 else
145 {
146 message.setNick("jetrix");
147 }
148
149 String name = m.getChannelName() == null ? "#jetrix" : "#" + m.getChannelName();
150
151 message.addParameter(name);
152 message.addParameter(applyStyle(m.getText(locale)));
153
154 return message.toString();
155 }
156
157 public String translate(PlineActMessage m, Locale locale)
158 {
159 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
160
161 Destination source = m.getSource();
162 if (source != null && source instanceof Client)
163 {
164 message.setNick(((Client) source).getUser().getName());
165 }
166 else
167 {
168 message.setNick("jetrix");
169 }
170
171 String name = m.getChannelName() == null ? "#jetrix" : "#" + m.getChannelName();
172
173 message.addParameter(name);
174 message.addParameter(applyStyle("\u0001ACTION " + m.getText(locale) + "\u0001"));
175
176 return message.toString();
177 }
178
179 public String translate(GmsgMessage m, Locale locale)
180 {
181 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
182
183 Destination source = m.getSource();
184 if (source != null && source instanceof Client)
185 {
186 message.setNick(((Client) source).getUser().getName());
187 }
188 else
189 {
190 message.setNick("jetrix");
191 }
192
193 String name = m.getChannelName() == null ? "#jetrix" : "#" + m.getChannelName();
194
195
196
197 message.addParameter(name);
198 message.addParameter(applyStyle("<gray>" + m.getText(locale)));
199
200 return message.toString();
201 }
202
203 public String translate(SpectatorListMessage m, Locale locale)
204 {
205 IRCMessage message1 = new IRCMessage(IRCReply.RPL_NAMREPLY);
206 message1.setNick("jetrix");
207 message1.addParameter(((Client) m.getDestination()).getUser().getName());
208 message1.addParameter("=");
209 message1.addParameter("#" + m.getChannel());
210
211 Collection<String> spectators = m.getSpectators();
212 message1.addParameter(StringUtils.join(spectators.iterator(), " "));
213
214 IRCMessage message2 = new IRCMessage(IRCReply.RPL_ENDOFNAMES);
215 message2.setNick("jetrix");
216 message2.addParameter(((Client) m.getDestination()).getUser().getName());
217 message2.addParameter("#" + m.getChannel());
218 message2.addParameter("End of /NAMES list");
219
220 return message1.toString() + getEOL() + message2;
221 }
222
223 public String translate(TeamMessage m, Locale locale)
224 {
225 Client client = (Client) m.getSource();
226
227 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
228 message.setNick("jetrix");
229 message.addParameter("#" + m.getChannelName());
230
231 String messageKey = m.getName() == null ? "channel.team.none" : "channel.team.new";
232 Object[] params = new Object[] { client.getUser().getName(), m.getName() };
233 message.addParameter(applyStyle(Language.getText(messageKey, locale, params)));
234
235 return message.toString();
236 }
237
238 public String translate(JoinMessage m, Locale locale)
239 {
240 IRCMessage message = new IRCMessage(IRCCommand.JOIN);
241 message.setNick(m.getName());
242 message.addParameter("#" + m.getChannelName());
243
244 return message.toString();
245 }
246
247 public String translate(LeaveMessage m, Locale locale)
248 {
249 IRCMessage message = new IRCMessage(IRCCommand.PART);
250 message.setNick(m.getName());
251 message.addParameter("#" + m.getChannelName());
252
253 return message.toString();
254 }
255
256 public String translate(NewGameMessage m, Locale locale)
257 {
258 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
259 message.setNick("jetrix");
260 message.addParameter("#" + m.getChannelName());
261 message.addParameter(applyStyle(Language.getText("channel.game.start", locale)));
262
263 return message.toString();
264 }
265
266 public String translate(EndGameMessage m, Locale locale)
267 {
268 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
269 message.setNick("jetrix");
270 message.addParameter("#" + m.getChannelName());
271 message.addParameter(applyStyle(Language.getText("channel.game.stop", locale)));
272
273 return message.toString();
274 }
275
276 public String translate(IngameMessage m, Locale locale)
277 {
278 IRCMessage message = new IRCMessage(IRCCommand.PRIVMSG);
279 message.setNick("jetrix");
280 message.addParameter("#" + m.getChannelName());
281 message.addParameter(applyStyle(Language.getText("channel.game.running", locale)));
282
283 return message.toString();
284 }
285
286 public String translate(PauseMessage m)
287 {
288 return null;
289 }
290
291 public String translate(ResumeMessage m)
292 {
293 return null;
294 }
295
296 public String translate(LevelMessage m)
297 {
298 return null;
299 }
300
301 public String translate(FieldMessage m)
302 {
303 return null;
304 }
305
306 public String translate(PlayerLostMessage m)
307 {
308 return null;
309 }
310
311 public String translate(DisconnectedMessage m)
312 {
313 return null;
314 }
315
316 public String translate(CommandMessage m)
317 {
318 return null;
319 }
320
321 public String translate(LinesAddedMessage m)
322 {
323 return null;
324 }
325
326 public String translate(AddLineMessage m)
327 {
328 return null;
329 }
330
331 public String translate(ClearLineMessage m)
332 {
333 return null;
334 }
335
336 public String translate(NukeFieldMessage m)
337 {
338 return null;
339 }
340
341 public String translate(RandomClearMessage m)
342 {
343 return null;
344 }
345
346 public String translate(SwitchFieldsMessage m)
347 {
348 return null;
349 }
350
351 public String translate(ClearSpecialsMessage m)
352 {
353 return null;
354 }
355
356 public String translate(GravityMessage m)
357 {
358 return null;
359 }
360
361 public String translate(BlockQuakeMessage m)
362 {
363 return null;
364 }
365
366 public String translate(BlockBombMessage m)
367 {
368 return null;
369 }
370
371 public Map<String,String> getStyles()
372 {
373 return styles;
374 }
375
376 public String applyStyle(String text)
377 {
378
379 Map<String,String> styles = getStyles();
380 if (styles == null) return text;
381
382 for (String key : styles.keySet())
383 {
384 String value = styles.get(key);
385 if (value == null) { value = ""; }
386 text = text.replaceAll("<" + key + ">", value);
387 text = text.replaceAll("</" + key + ">", value);
388 }
389 return text;
390 }
391
392 public char getEOL()
393 {
394 return '\n';
395 }
396
397 }