/*
Eteria IRC Client, an RFC 1459 compliant client program written in Java.
Copyright (C) 2000-2001 Javier Kohen <jkohen at tough.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.applet.AudioClip;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.text.*;
import java.util.*;
import ar.com.jkohen.applet.*;
import ar.com.jkohen.awt.*;
import ar.com.jkohen.awt.event.*;
import ar.com.jkohen.irc.*;
import ar.com.jkohen.net.*;
import ar.com.jkohen.util.*;
import com.splendid.awtchat.*;
/**
* This is Eteria IRC Client's core class. It contains the main control loop, some high level communication methods and topmost-GUI code.
*
* @author Javier Kohen
*/
public class EIRC extends Applet implements ClientProcess, Observer, ActionListener, ItemListener, MouseListener, ChatPanelListener, WindowListener, Runnable
{
/**
* Program's name.
* Used as part of "About" info.
*/
public final static String PACKAGE = "Eteria IRC Client beta";
/**
* Program's release version.
* Used as part of "About" info.
* Should be either a "YYYYMMDD" date or a "X.Y.Z" version number.
*/
public final static String VERSION = "20120410.12.55";
/**
* Program's release extra version.
* Used as part of "About" info.
* Should be a String describing in-site's modifications.
*/
public final static String VERSION_EXTRA = "version www.coolsmile.net + avatars";
/**
* Author's name.
* Used as part of "About" info.
*/
public final static String AUTHOR = "Javier Kohen";
private static Hashtable commands;
private static ResourceBundle user_commands;
private static Resources res;
private Collator collator;
private Vector channels;
private CollatedHashtable channel_windows;
private CollatedHashtable privates;
private Vector ignore_list;
private Vector names;
// private boolean missing_default_channel_in_list;
// Used to build the users list from the server replies to the WHO command.
private Vector who_reply;
// Store a channel's +b/e/I list
private Vector list;
private Properties server_support;
private ConfigurationProperties properties;
private static String defaultfont = "SansSerif";
private static Font mainfont = new Font(defaultfont, Font.PLAIN, 12);
private static Color mainbg = SystemColor.control ;
private static Color mainfg = SystemColor.controlText;
private static Color textbg = SystemColor.window;
private static Color textfg = SystemColor.textText;
private static Color selbg = SystemColor.textHighlight;
private static Color selfg = SystemColor.textHighlightText;
/* GUI. */
private Image main_icon;
private TextField nick_entry;
private Label label;
private Label away;
private PopupMenu menu;
private ControlPanel control_panel;
private ChatPanelContainer chat_panel;
private StatusWindow status;
private ChanListWindow chan_list;
private WhoListWindow who_list;
private OutputWindow debug_window;
private Frame f;
private boolean application = false;
private Hashtable color_list;
private String current_server;
private String status_tag;
private String current_nick, username, realname;
private String new_nick;
private String original_nick;
private ServerProcess server;
private IRCServices irc_services;
private boolean is_away;
private String away_str;
/* Configuration properties. */
private boolean special_services;
private int debug_traffic;
private String nicksrv_pass;
private String irc_pass;
private String quit_message;
private boolean request_motd;
private boolean see_everything_from_server;
private boolean see_join;
private boolean see_invite;
private boolean on_dcc_notify_peer;
private String service_bots;
private boolean hideip;
private boolean focus_opening_privates;
private boolean no_privates;
private boolean auto_list;
private String user_modes;
private int write_color;
private int scroll_speed;
private int silent;
private AudioClip event_sounds[];
private String decoding, encoding;
private String cfg_name;
private String network_name = "";
private String default_join;
private int restrict_join;
private int ping;
private boolean connected;
private boolean logged_in;
private boolean send_quit;
private boolean server_admin;
private boolean ircop_override;
private boolean who_invisible;
private boolean login_time;
// Dialogs.
private static Configurator configurator;
private static ModeList mode_list;
private static TextAreaCopy tac;
private static ASLBox asl;
private static HelpBox help;
private MessageFormat chan_title, private_title, chanlist_title, wholist_title;
static
{
commands = new Hashtable(100);
commands.put("PING", new Integer(-1));
commands.put("NICK", new Integer(-2));
commands.put("JOIN", new Integer(-3));
commands.put("MODE", new Integer(-4));
commands.put("PART", new Integer(-5));
commands.put("QUIT", new Integer(-6));
commands.put("KICK", new Integer(-7));
commands.put("TOPIC", new Integer(-8));
commands.put("PRIVMSG", new Integer(-9));
commands.put("NOTICE", new Integer(-10));
commands.put("ERROR", new Integer(-11));
commands.put("WALLOPS", new Integer(-12));
commands.put("INVITE", new Integer(-13));
commands.put("PONG", new Integer(-14));
commands.put("001", new Integer(001));
commands.put("005", new Integer(005));
commands.put("232", new Integer(232));
commands.put("251", new Integer(251));
commands.put("301", new Integer(301));
commands.put("303", new Integer(303));
commands.put("302", new Integer(302));
commands.put("305", new Integer(305));
commands.put("306", new Integer(306));
commands.put("307", new Integer(307));
commands.put("310", new Integer(310));
commands.put("311", new Integer(311));
commands.put("312", new Integer(312));
commands.put("313", new Integer(313));
commands.put("314", new Integer(314));
commands.put("315", new Integer(315));
commands.put("317", new Integer(317));
commands.put("318", new Integer(318)); // No action needed.
commands.put("319", new Integer(319));
commands.put("320", new Integer(320));
commands.put("321", new Integer(321));
commands.put("322", new Integer(322));
commands.put("323", new Integer(323));
commands.put("324", new Integer(324));
commands.put("329", new Integer(329)); // No action needed.
commands.put("331", new Integer(331));
commands.put("332", new Integer(332));
commands.put("333", new Integer(333));
commands.put("335", new Integer(335));
commands.put("346", new Integer(346));
commands.put("347", new Integer(347));
commands.put("348", new Integer(348));
commands.put("349", new Integer(349));
commands.put("352", new Integer(352));
commands.put("353", new Integer(353));
commands.put("366", new Integer(366));
commands.put("367", new Integer(367));
commands.put("368", new Integer(368));
commands.put("371", new Integer(371));
commands.put("372", new Integer(372));
commands.put("375", new Integer(375));
commands.put("376", new Integer(376));
commands.put("378", new Integer(378));
commands.put("381", new Integer(381));
commands.put("391", new Integer(391));
commands.put("401", new Integer(401));
commands.put("403", new Integer(403));
commands.put("404", new Integer(404));
commands.put("406", new Integer(406));
commands.put("421", new Integer(421));
commands.put("422", new Integer(422));
commands.put("432", new Integer(432));
commands.put("433", new Integer(433));
commands.put("437", new Integer(437));
commands.put("438", new Integer(438));
commands.put("447", new Integer(447));
commands.put("461", new Integer(461));
commands.put("464", new Integer(464));
commands.put("465", new Integer(465));
commands.put("471", new Integer(471));
commands.put("473", new Integer(473));
commands.put("474", new Integer(474));
commands.put("475", new Integer(475));
commands.put("477", new Integer(477));
commands.put("478", new Integer(478));
commands.put("481", new Integer(481));
commands.put("482", new Integer(482));
commands.put("489", new Integer(489));
commands.put("491", new Integer(491));
commands.put("536", new Integer(536));
commands.put("600", new Integer(600));
commands.put("601", new Integer(601));
commands.put("604", new Integer(604));
commands.put("605", new Integer(605));
commands.put("671", new Integer(671));
}
/**
* Constructor for Applet instances.
* Must be present, even if empty.
*/
public EIRC()
{
}
/**
* Execution starts here when the program is run out of Applet context.
* This method supplies a simple substitute for the Applet viewer.
*
* @param args a String[] containing command-line arguments.
*/
public static void main(String args[])
{
EIRC eirc = new EIRC();
eirc.application = true;
eirc.setStub(new SimpleAppletStub(args));
eirc.init();
eirc.start();
new Thread(eirc).start();
}
public void init()
{
this.collator = RFC1459.getCollator();
this.channels = new Vector();
this.channel_windows = new CollatedHashtable(collator);
this.privates = new CollatedHashtable(collator);
this.ignore_list = new Vector();
this.names = new Vector();
this.server_support = new Properties();
this.event_sounds = new AudioClip[res.EVENTS];
res = new Resources(this, getParameter("language"));
/* Initialize with the default configuration */
Properties default_props = new Properties();
try
{
default_props.load(Resources.getResourceAsStream("configuration.properties"));
}
catch (IOException ex)
{
System.err.println(ex);
}
/* Get saved configuration */
cfg_name = getParameter("configuration");
if (application)
properties = new LocalConfiguration(cfg_name, default_props);
else
properties = new NetworkConfiguration(this, cfg_name, default_props);
properties.addObserver(this);
/* Default quit */
this.quit_message = res.getString("eirc.default_quit");
if(properties.getString("quit_message") == null || properties.getString("quit_message").equals(""))
properties.setString("quit_message", quit_message);
/* Read user's colors and sounds configurations */
Vector sound_list = new Vector();
color_list = new Hashtable();
for (Enumeration e = properties.keys(); e.hasMoreElements() ;)
{
String key = (String)e.nextElement();
try
{
if (key.indexOf("sound.") == 0 && Integer.parseInt(key.substring(6)) > 0)
sound_list.addElement(properties.getProperty(key));
if (key.indexOf("color.") == 0)
color_list.put(key.substring(6), Color.decode(properties.getProperty(key)));
}
catch(NumberFormatException ex) {}
}
/* Load sounds in background */
if (properties.getBoolean("load_sounds"))
{
res.addObserver(this);
res.cacheSounds(sound_list, properties.getProperty("sound.path"));
}
/* Force an update to initialize some variables to their defaults. */
update(properties, null);
// EIRC.user_commands = ResourceBundle.getBundle("Commands");
EIRC.user_commands = new Commands();
/* Read text colors */
Color fixedColors[] = new Color[16]; // 16 colors + 2 (fg/bg) internal.
for (int i = 0; i < fixedColors.length; i++)
{
try
{
fixedColors[i] = Color.decode(properties.getString("n" + i));
}
catch (Exception ex)
{
fixedColors[i] = Color.black;
System.err.println(ex);
}
}
SmileyTextArea.setColors(fixedColors);
TextAttributePicker.setColors(fixedColors);
int order[] = new int[16];
try
{
for (int i = 0; i < order.length; i++)
order[i] = Integer.parseInt(properties.getString("c" + i));
}
catch (Exception ex)
{
for (int i = 0; i < order.length; i++)
order[i] = i;
}
TextAttributePicker.setOrder(order);
for (Enumeration e = Resources.lang_resource.propertyNames(); e.hasMoreElements() ;)
{
String key = (String)e.nextElement();
if (key.indexOf("tld.") == 0)
NickInfo.addTLD(key.substring(key.indexOf(".") + 1), res.getString(key));
}
try
{
NickInfo.setParseASLType(Integer.parseInt(properties.getString("default_asl")));
} catch (NumberFormatException e) {}
chan_title = new MessageFormat(res.getString("top_panel.chan"));
private_title = new MessageFormat(res.getString("top_panel.private"));
chanlist_title = new MessageFormat(res.getString("top_panel.chanlist"));
wholist_title = new MessageFormat(res.getString("top_panel.wholist"));
main_icon = res.getImage("icon");
irc_services = new IRCServices(this);
String mySys = System.getProperty("os.name").replace(' ', '_');
if (mySys.indexOf("Windows") == 0)
mySys = "Windows";
SimpleAppletContext.setPath(properties.getProperty("navigator." + mySys));
this.default_join = getParameter("join");
String t;
int s = 12;
if ((t = getParameter("font_name")) != null)
defaultfont = t;
try
{
if ((t = getParameter("font_size")) != null)
s = Integer.parseInt(t);
}
catch (NumberFormatException e) {}
this.mainfont = new Font(defaultfont, Font.PLAIN, s);
try
{
if ((t = getParameter("mainbg")) != null)
this.mainbg = Color.decode(t);
}
catch (NumberFormatException e) {}
try
{
if ((t = getParameter("mainfg")) != null)
this.mainfg = Color.decode(t);
}
catch (NumberFormatException e) {}
try
{
if ((t = getParameter("textbg")) != null)
this.textbg = Color.decode(t);
}
catch (NumberFormatException e) {}
try
{
if ((t = getParameter("textfg")) != null)
this.textfg = Color.decode(t);
}
catch (NumberFormatException e) {}
try
{
if ((t = getParameter("selbg")) != null)
this.selbg = Color.decode(t);
}
catch (NumberFormatException e) {}
try
{
if ((t = getParameter("selfg")) != null)
this.selfg = Color.decode(t);
}
catch (NumberFormatException e) {}
// Send traffic to stderr.
// Turn off for production setups!
debug_traffic = 0;
if ((t = getParameter("debug_traffic")) != null)
{
try
{
debug_traffic = Integer.parseInt(t);
} catch (NumberFormatException e) {}
}
write_color = 1;
if ((t = getParameter("write_color")) != null)
{
try
{
write_color = Integer.parseInt(t);
if (write_color < 0 || write_color > 15)
write_color = 1;
} catch (NumberFormatException e) {}
properties.setInt("write_color", write_color);
}
if ((t = getParameter("nicksrv_pass")) == null)
t = "";
properties.setString("nicksrv_pass", t);
if ((t = getParameter("user_modes")) != null)
{
user_modes = "";
for (int i = 0; i < t.length(); i++)
{
char c = t.charAt(i);
if (Character.isLetter(c) || c == '+' || c == '-')
user_modes += c;
}
}
if (debug_traffic > 0)
{
String propertyNames[] = { "file.separator", "line.separator", "path.separator", "java.class.version", "java.vendor", "java.vendor.url", "java.version", "os.name", "os.arch", "os.version" };
debug(getAppletInfo());
debug("\n");
for (int i = 0; i < propertyNames.length; i++)
debug(propertyNames[i] + " = " + System.getProperty(propertyNames[i]));
debug("\n");
Locale l = Locale.getDefault();
debug("country = " + l.getCountry() + " (" + l.getDisplayCountry() + ")");
debug("language = " + l.getLanguage() + " (" + l.getDisplayLanguage() + ")");
debug("encoding = " + new OutputStreamWriter(System.out).getEncoding());
debug("\n");
}
/* Platform depend security */
askPermissions();
/* Create main GUI. */
// Check some supports which may not be available on all virtual machines
NewMouseWheelEvent.checkMouseWheelSupport();
NewGraphics2D.checkRenderSupport();
LinkProcess.init();
t = getParameter("spawn_frame");
if ((t != null && !t.equals("0")) || application)
{
f = new Frame();
f.setIconImage(main_icon);
f.addWindowListener(this);
int width = 800;
int height = 600;
try
{
width = Integer.parseInt(getParameter("width"));
height = Integer.parseInt(getParameter("height"));
}
catch (Exception ex) {}
initGUI(f);
f.pack();
f.setSize(width, height);
Toolkit tkit = getToolkit();
f.setLocation((tkit.getScreenSize().width - f.getSize().width) / 2, (tkit.getScreenSize().height - f.getSize().height) / 2);
f.setVisible(true);
f.addWindowListener(this);
f.setName("main");
}
else
{
f = null;
initGUI(this);
}
setBackground(mainbg);
setForeground(mainfg);
setSelectedBackground(selbg);
setFont(mainfont);
updateWindowTitle();
/* Event listeners and observers. */
nick_entry.addActionListener(this);
away.addMouseListener(this);
properties.addObserver(chan_list);
properties.addObserver(who_list);
properties.addObserver(status);
properties.addObserver(irc_services);
chan_list.update(properties, null);
who_list.update(properties, null);
status.update(properties, null);
irc_services.update(properties, null);
/* Misc. GUI init. */
if ((t = getParameter("nickname")) != null)
{
char [] str = t.toCharArray();
// Replace every '?' occurrence by a random decimal digit.
for (int i = 0; i < str.length; i++)
if ('?' == str[i])
str[i] = Character.forDigit((int) Math.floor(Math.random() * 10.0), 10);
nick_entry.setText(String.valueOf(str));
original_nick = String.valueOf(str);
}
if ((t = getParameter("irc_pass")) != null && t.length() > 0)
properties.setString("irc_pass", t);
username = "CS" + Calendar.getInstance().get(Calendar.WEEK_OF_YEAR);
realname = "www.coolsmile.net";
if ((t = getParameter("username")) != null && t.length() > 0)
username = t;
if ((t = getParameter("realname")) != null && t.length() > 0)
realname = t;
}
public void askPermissions()
{
/* Platform-dependent security checks
** see : http://support.microsoft.com/kb/175622
** or http://support.microsoft.com/kb/193877
** http://java.sun.com/j2se/1.5.0/docs/guide/deployment/deployment-guide/upgrade-guide/article-05.html
*/
try
{
if (System.getProperty("java.vendor").indexOf("Microsoft") >= 0)
{
/*
** com.ms.security.PolicyEngine.assertPermission(com.ms.security.PermissionID.NETIO);
*/
Class PolicyClass = Class.forName("com.ms.security.PolicyEngine");
Class IdClass = Class.forName("com.ms.security.PermissionID");
Method assertMethod = PolicyClass.getMethod("assertPermission", new Class[] { IdClass });
Field permission = IdClass.getField("NETIO");
Object permObj = permission.get(null);
Object none = assertMethod.invoke(null, new Object[] { permObj });
/*
** com.ms.security.PolicyEngine.assertPermission(com.ms.security.PermissionID.UI);
*/
permission = IdClass.getField("UI");
permObj = permission.get(null);
none = assertMethod.invoke(null, new Object[] { permObj });
}
}
catch (Exception ex) { System.err.println("Permission error : " + ex); }
}
public void openASL()
{
String t = getParameter("asl");
if((t != null && !t.equals("0")) || t == null)
{
if (asl == null)
{
asl = new ASLBox(this, res.getString("asl.connection"));
asl.addWindowListener(this);
asl.setName("asl");
}
else
{
asl.toFront();
}
asl.init(nick_entry.getText(), nicksrv_pass, realname);
}
}
public void start()
{
String t = getParameter("login");
// See if auto-login was requested.
if (t != null && !t.equals("0"))
{
// Can't login if no nickname was provided.
if ((t = getParameter("nickname")) == null || t.length() == 0)
status.printError(res.getString("eirc.s26"));
else
connect();
}
else
{
openASL();
}
}
public void run()
{
while (ping > 0)
{
if (server != null && connected && server.timedOut())
{
String a[] = { network_name };
sendMessage("PING", a);
}
try
{
Thread.sleep(ping * 1000);
} catch (InterruptedException ex) {}
}
}
public void stop()
{
disconnect();
}
public void destroy()
{
// Remove all components from container.
removeAll();
}
private void initGUI(Container cont)
{
String t;
GridBagLayout gb = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
cont.setLayout(gb);
label = new Label(res.getString("eirc.enter_nick"), Label.RIGHT);
gbc.anchor = GridBagConstraints.EAST;
gb.setConstraints(label, gbc);
label.setBackground(mainbg);
t = getParameter("gui_nick");
if (t == null || !t.equals("0"))
cont.add(label);
/* Textfield(int) and Textfield(String) look buggy on Linux */
this.nick_entry = new TextField();
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.WEST;
gb.setConstraints(nick_entry, gbc);
nick_entry.setBackground(textbg);
if (t == null || !t.equals("0"))
cont.add(nick_entry);
this.menu = new PopupMenu();
CheckboxMenuItem cbm = new CheckboxMenuItem(res.getString("eirc.away_custom"));
cbm.addItemListener(this);
menu.add(cbm);
menu.addSeparator();
StringTokenizer tk = new StringTokenizer(res.getString("eirc.away_list"), "/");
while (tk.hasMoreTokens())
{
cbm = new CheckboxMenuItem(tk.nextToken());
cbm.addItemListener(this);
menu.add(cbm);
}
away = new Label(res.getString("eirc.away"));
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.WEST;
gb.setConstraints(away, gbc);
t = getParameter("gui_away");
if (t == null || !t.equals("0"))
cont.add(away);
away.add(menu);
away.setBackground(mainbg);
away.setForeground(Color.blue);
/*
** Check if we can add some buttons.
*/
boolean enabled[] = new boolean[ControlPanel.COMPONENTS];
for (int i = 0; i < ControlPanel.COMPONENTS; i++)
enabled[i] = true;
t = getParameter("gui_chanlist");
if (t != null && t.equals("0"))
enabled[ControlPanel.CHANNELS] = false;
t = getParameter("gui_userlist");
if (t != null && t.equals("0"))
enabled[ControlPanel.WHO] = false;
t = getParameter("gui_options");
if (t != null && t.equals("0"))
enabled[ControlPanel.SETUP] = false;
t = getParameter("gui_help");
if (t != null && t.equals("0"))
enabled[ControlPanel.HELP] = false;
t = getParameter("gui_connect");
if (t != null && t.equals("0"))
enabled[ControlPanel.CONNECT] = false;
this.control_panel = new ControlPanel(this, enabled);
gbc.anchor = GridBagConstraints.EAST;
gb.setConstraints(control_panel, gbc);
cont.add(control_panel);
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridy = 1;
this.chat_panel = new ChatPanelContainer(this);
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.BOTH;
gb.setConstraints(chat_panel, gbc);
cont.add(chat_panel);
/* Create and add Channel list window. */
String tag = "*Chans*";
this.chan_list = new ChanListWindow(this, tag);
chan_list.setForeground(mainfg);
chan_list.setBackground(mainbg);
chan_list.setTextBackground(textbg);
chan_list.setTextForeground(textfg);
// chan_list.setSelectedForeground(selfg);
chan_list.setSelectedBackground(selbg);
chat_panel.addPanel(chan_list, tag);
/* Create and add Who list window. */
tag = "*Who*";
this.who_list = new WhoListWindow(this, tag);
who_list.setForeground(mainfg);
who_list.setBackground(mainbg);
who_list.setTextBackground(textbg);
// who_list.setTextForeground(textfg);
who_list.setSelectedForeground(selfg);
who_list.setSelectedBackground(selbg);
chat_panel.addPanel(who_list, tag);
/* Create and add StatusWindow. */
status_tag = Resources.getString("eirc.status");
String title = Resources.getString("status_panel");
this.status = new StatusWindow(this, status_tag);
status.setBackground(mainbg);
status.setForeground(mainfg);
status.setTextBackground(textbg);
status.setTextForeground(textfg);
status.setSelectedBackground(selbg);
status.requestFocus();
chat_panel.add(status, status_tag, true);
chat_panel.setTitle(status_tag, title);
chat_panel.show(status_tag);
cont.setBackground(mainbg);
cont.setForeground(mainfg);
cont.setFont(mainfont);
}
public String getAppletInfo()
{
return (PACKAGE + " " + VERSION + "\n" + VERSION_EXTRA + ", an RFC 1459 compliant client program written in Java.\n" + "Copyright (C) 2000-2001 Javier Kohen <jkohen at tough.com>");
}
public String[][] getParameterInfo()
{
return param_info;
}
void connect()
{
String host = null;
if (current_server != null)
host = current_server;
else
host = getParameter("server");
if (host == null || host.length() == 0)
{
host = getDocumentBase().getHost();
if (host.length() == 0)
host = "localhost";
}
boolean ssl = false;
try
{
ssl = (Integer.parseInt(getParameter("ssl")) == 1 ? true : false);
}
catch (Exception e) {}
connect(host, ssl);
}
void connect(String host, boolean ssl)
{
int port = 6667; // Set default port.
if (ssl)
port = 6697;
try
{
port = Integer.parseInt(getParameter("port"));
} catch (Exception e) {}
connect(host, port, ssl);
}
synchronized void connect(String host, int port, boolean ssl)
{
if (nick_entry.getText().length() == 0)
{
status.printError(res.getString("eirc.s1"));
return;
}
status.printInfo(res.getString("eirc.login"));
/* See if this Applet can connect promiscuously.
* No Exceptions will be thrown out of Applet context.
*/
InetAddress server_addr = null;
Socket s = null;
ServerThread st = null;
try
{
/* Resolve server's address. */
InetAddress [] addresses = InetAddress.getAllByName(host);
server_addr = addresses[(int) Math.floor(Math.random() * addresses.length)];
server_addr = InetAddress.getByName(host);
/* Establish a connection to the server. */
s = createSocket(server_addr, port, ssl);
/* Spawn a new thread to handle the connection. */
st = new ServerThread(this, s, decoding, encoding, ping);
}
catch (UnknownHostException e)
{
Object a[] = { host };
String ptn = res.getString("eirc.s2");
status.printError(MessageFormat.format(ptn, a));
return;
}
catch (IOException e)
{
Object a[] = { server_addr.getHostName(), (new Integer(port)).toString() };
String ptn = res.getString("eirc.s3");
status.printError(MessageFormat.format(ptn, a));
status.printInfo(e.toString());
return;
}
catch (SecurityException e)
{
status.printError(res.getString("eirc.not_in_applet"));
return;
}
catch (ClassNotFoundException e)
{
status.printError(res.getString("eirc.nossl"));
return;
}
catch (Exception e)
{
reportException(e);
return;
}
if (connected)
disconnect();
properties.addObserver(st);
this.server = st;
st.start();
this.connected = true;
this.send_quit = true;
/* Login into server. */
login();
this.current_server = host;
/* Enable controls that depend on being connected. */
control_panel.setConnected(true);
/*
** Enable previously opened windows.
*/
/* Enable opened channels and re-join */
String c;
String p[] = { "", "" };
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow w = (ChannelWindow)e.nextElement();
if (w != null)
{
if (p[0].length() > 0)
{
p[0] += ",";
p[1] += ",";
}
c = w.getChannel().getTag();
if (c != null)
{
p[0] += c;
c = w.getChannel().getKey();
if (c.length() == 0) c = " ";
p[1] += c;
}
w.setEnabled(true);
}
}
if (p[0].length() > 0)
sendMessage("JOIN", p);
/* Enable privates */
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.setEnabled(true);
}
status.clear();
chan_list.clear();
who_list.clear();
}
public Socket createSocket(InetAddress addr, int port, boolean sec) throws Exception
{
Socket s = null;
if (sec)
{
Class SSLClass = Class.forName("javax.net.ssl.SSLSocket");
if(SSLClass == null)
throw new ClassNotFoundException();
/*
** SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
** SSLSocket ssl = (SSLSocket)factory.createSocket(server_addr, port);
*/
Class FactoryCLass = Class.forName("javax.net.ssl.SSLSocketFactory");
Method getdefault = FactoryCLass.getMethod("getDefault", new Class[] {});
Object factory = getdefault.invoke(null, new Object[] {});
Method createsocket = FactoryCLass.getMethod("createSocket", new Class[] { InetAddress.class, int.class });
Object ssl = createsocket.invoke(factory, new Object[] { addr, new Integer(port) } );
s = (Socket)ssl;
}
else
{
s = new Socket(addr, port);
}
return(s);
}
public void connect(String nick, String pass, String real)
{
nick_entry.setText(nick);
nicksrv_pass = pass;
realname = real;
properties.setString("nickname", nick);
properties.setString("realname", realname);
connect();
}
private synchronized void login()
{
if (!connected)
return;
if (irc_pass != null && irc_pass.length() > 0)
{
String p[] = { irc_pass };
sendMessage("PASS", p);
}
this.new_nick = nick_entry.getText();
String n[] = { new_nick };
sendMessage("NICK", n);
String u[] = { username, "0", "0", realname };
sendMessage("USER", u);
}
public synchronized void disconnect()
{
/* Disable controls that depend on being connected. */
control_panel.setConnected(false);
if (!connected)
return;
/* Logout from server */
logout();
/* Kill the connection */
server.disconnect();
server = null;
this.connected = false;
status.printError(res.getString("eirc.disconnected"));
chat_panel.show(status_tag);
/* Close what should be closed on disconnection. */
// closePrivates();
// closeChannels();
/* Disable opened channels */
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow w = (ChannelWindow)e.nextElement();
w.setEnabled(false);
w.clearUsers();
}
/* Disable opened privates */
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.setEnabled(false);
}
/*
** Reset away
*/
away.setForeground(Color.blue);
for (int i = 0; i < menu.getItemCount(); i++)
{
MenuItem mi = menu.getItem(i);
if (mi instanceof CheckboxMenuItem)
((CheckboxMenuItem)mi).setState(false);
}
is_away = false;
/*
** Clear modes
*/
setGlobalModes("-*");
}
private synchronized void logout()
{
// if (!logged_in)
// return;
if (send_quit)
{
String p[] = { quit_message };
sendMessage("QUIT", p);
this.send_quit = false;
}
this.logged_in = false;
}
private synchronized void pos_login()
{
if (!connected)
return;
current_nick = new_nick;
status.requestFocus();
chan_list.setEnabled(true);
who_list.setEnabled(true);
if (request_motd)
{
String p[] = { };
sendMessage("MOTD", p);
}
if (user_modes != null && user_modes.length() > 0)
{
String p[] = { this.current_nick, user_modes };
sendMessage("MODE", p);
}
if (default_join != null && default_join.length() > 0)
{
String p[] = null;
default_join = default_join.trim();
int space = default_join.indexOf(" ");
if (space > 0)
{
// Keyed channels
p = new String[2];
p[0] = default_join.substring(0, space);
p[1] = default_join.substring(space + 1);
}
else
{
p = new String[1];
p[0] = default_join;
}
sendMessage("JOIN", p);
default_join = null;
}
if (chan_list != null && auto_list)
chan_list.listChannels();
}
public void printMode(ChannelWindow cw, String prefix, String param, String msg_tag, int sound)
{
if (msg_tag != null && cw != null)
{
Object a[] = { prefix, param };
String ptn = res.getString(msg_tag);
cw.printInfo(MessageFormat.format(ptn, a));
}
/*
** Play an event sound only if user is focused on the channel
*/
if (sound > -1 && cw == getCurrentPanel())
playSound(sound);
}
public void reportException(Exception ex)
{
report("err", ex.toString());
}
public void reportIOException(IOException ex)
{
report("eirc.errnet", ex.toString());
}
public void report(String key, String details)
{
/* Report verbose error on status window */
status.printError(res.getString(key));
status.printInfo(details);
}
public void debug(String s)
{
if (debug_traffic == 1 || debug_window == null)
System.err.println(s);
if (debug_traffic == 2 && debug_window != null)
debug_window.printServerNotice(s, "Debug");
}
public void processMessage(Message m)
{
String command_key = m.getCommand();
String mask = m.getPrefix();
String params[] = m.getParameters();
Integer t_cmd = (Integer)commands.get(command_key);
String prefix = mask;
int endOff = mask.indexOf('!');
int atHost = mask.indexOf('@');
if (endOff != -1)
{
prefix = mask.substring(0, endOff);
if (atHost > endOff)
{
String user = mask.substring(endOff + 1, atHost);
String host = mask.substring(atHost + 1);
if (!NickInfo.hasInfos(prefix) && !isService(prefix))
{
NickInfo.add(prefix, "", user, host);
// Retrieve user's info.
String p[] = { prefix };
sendMessage("WHO", p);
}
}
}
if (debug_traffic > 0 || t_cmd == null)
{
// Strip CRLF from the end of the message.
String t = m.toString();
t = t.substring(0, t.length() - 2);
if (debug_traffic > 0)
debug("<< " + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(new Date()) + " " + t);
if (t_cmd == null)
{
if (see_everything_from_server)
{
try
{
// We don't care about the result, we just want to know if it's a number.
Integer.parseInt(command_key);
// Numeric command, take the crud out of it.
StringBuffer buf = new StringBuffer(params[1]);
for (int i = 2; i < params.length; i++)
{
buf.append(' ');
buf.append(params[i]);
}
status.printUnmangled(buf.toString());
}
catch (NumberFormatException e)
{
// Not numeric command.
status.printUnmangled(t);
}
}
return;
}
}
// This flag is checked by NOTICE and PRIVMSG handlers.
boolean is_prefix_ignored = false;
String addr = NickInfo.getInetAddr(prefix);
if (addr != null)
is_prefix_ignored = ignore_list.contains(addr);
int command = t_cmd.intValue();
switch (command)
{
case -1: // PING
{
String p[] = { params[0] };
sendMessage("PONG", p);
break;
}
case -2: // NICK
{
if (prefix.equals(current_nick))
{
// Self nick change
current_nick = params[0];
nick_entry.setText(current_nick);
Object a[] = { current_nick };
String ptn = res.getString("eirc.s4");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
updateWindowTitle();
}
else
{
// Other's nick change
Object a[] = { prefix, params[0] };
String ptn = res.getString("eirc.s5");
String msg_text = MessageFormat.format(ptn, a);
OutputWindow [] ow = getUserPanels(prefix);
for (int i = 0; i < ow.length; i++)
ow[i].printInfo(msg_text);
}
// Update nick from nick info entries
NickInfo.changeNick(prefix, params[0]);
// Update private window (if there's one) accordingly
if (privates.containsKey(prefix) && !privates.containsKey(params[0]))
{
PrivateWindow pw = (PrivateWindow) privates.get(prefix);
pw.setUser(params[0]);
chat_panel.rename(prefix, params[0]);
Object o[] = { params[0] };
chat_panel.setTitle(params[0], private_title.format(o));
privates.remove(prefix);
privates.put(params[0], pw);
}
// Update channel window accordingly
for (Enumeration e = channels.elements(); e.hasMoreElements(); )
{
Channel channel = (Channel) e.nextElement();
if (channel.contains(prefix))
{
channel.rename(prefix, params[0]);
channel.update();
}
}
break;
}
case -3: // JOIN
{
// If it's me, just open the channel window.
if (current_nick.equals(prefix))
{
openChannel(params[0]);
// Retrieve users' info.
String p[] = { params[0] };
sendMessage("WHO", p);
}
else
{
Channel channel = getChannel(params[0]);
if (channel != null)
{
channel.add(prefix);
channel.update();
if (see_join)
{
ChannelWindow cw = getChannelWindow(params[0]);
if (cw != null)
{
Object a[] = { prefix };
String ptn = res.getString("eirc.s6");
cw.printInfo(MessageFormat.format(ptn, a));
if (cw == getCurrentPanel())
playSound(res.EVENT_JOIN);
}
}
updateChanTitle(getChannel(params[0]));
}
}
break;
}
case -4: // MODE
{
String [] modes_params;
if (params.length > 2)
{
modes_params = new String [params.length - 2];
for (int i = 0; i < modes_params.length; i++)
modes_params[i] = params[i + 2];
}
else
{
modes_params = new String[1];
modes_params[0] = params[0];
}
// Process server wide user modes.
if (!Channel.isChannel(params[0]))
{
setGlobalModes(params[1]);
// Refresh all channels' popup menus.
for (Enumeration e = channels.elements(); e.hasMoreElements(); )
{
Channel channel = (Channel) e.nextElement();
channel.setModes();
}
break;
}
Channel channel = getChannel(params[0]);
if (channel != null)
{
channel.setModes(params[1], modes_params);
channel.update();
}
ChannelWindow cw = getChannelWindow(params[0]);
boolean sign = false;
char modes[] = params[1].toCharArray();
int j = 0;
for (int i = 0; i < modes.length; i++)
{
String msg_tag = null;
int sound = -1;
switch (modes[i])
{
case '+':
sign = true;
break;
case '-':
sign = false;
break;
case 'v':
msg_tag = sign ? "eirc.+v" : "eirc.-v";
sound = sign ? res.EVENT_OP : res.EVENT_DEOP;
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'o':
msg_tag = sign ? "eirc.+o" : "eirc.-o";
sound = sign ? res.EVENT_OP: res.EVENT_DEOP;
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'h':
msg_tag = sign ? "eirc.+h" : "eirc.-h";
sound = sign ? res.EVENT_OP: res.EVENT_DEOP;
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'b':
msg_tag = sign ? "eirc.+b" : "eirc.-b";
sound = sign ? res.EVENT_BAN : -1;
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'e':
msg_tag = sign ? "eirc.+e" : "eirc.-e";
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'I':
msg_tag = sign ? "eirc.+I" : "eirc.-I";
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
// Channel modes
case 'm':
msg_tag = sign ? "eirc.+m" : "eirc.-m";
printMode(cw, prefix, modes_params[0], msg_tag, sound);
break;
case 's':
msg_tag = sign ? "eirc.+s" : "eirc.-s";
printMode(cw, prefix, modes_params[0], msg_tag, sound);
break;
case 'i':
msg_tag = sign ? "eirc.+i" : "eirc.-i";
printMode(cw, prefix, modes_params[0], msg_tag, sound);
break;
case 'k':
msg_tag = sign ? "eirc.+k" : "eirc.-k";
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'l':
msg_tag = sign ? "eirc.+l" : "eirc.-l";
printMode(cw, prefix, sign ? modes_params[j++] : "", msg_tag, sound);
break;
// User modes not RFC compliant. //////////////////////////
case 'a':
msg_tag = sign ? "eirc.+a" : "eirc.-a";
sound = sign ? res.EVENT_OP: res.EVENT_DEOP;
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
case 'q':
msg_tag = sign ? "eirc.+q" : "eirc.-q";
sound = sign ? res.EVENT_OP: res.EVENT_DEOP;
printMode(cw, prefix, modes_params[j++], msg_tag, sound);
break;
// Channel modes not RFC compliant. //////////////////////////
case 'r':
msg_tag = sign ? "eirc.+r" : "eirc.-r";
printMode(cw, prefix, modes_params[0], msg_tag, sound);
break;
case 'N':
msg_tag = sign ? "eirc.+N" : "eirc.-N";
printMode(cw, prefix, modes_params[0], msg_tag, sound);
break;
/////////////////////////////////////////////////////////////
}
}
break;
}
case -5: // PART
{
if (current_nick.equals(prefix))
{
closeChannel(params[0]);
}
else
{
Channel channel = getChannel(params[0]);
channel.remove(prefix);
channel.update();
if (see_join)
{
ChannelWindow cw = getChannelWindow(params[0]);
String part_msg = "";
if (params.length >= 2)
part_msg = params[1];
Object a[] = { prefix, part_msg };
String ptn = res.getString("eirc.s8");
cw.printInfo(MessageFormat.format(ptn, a));
if (cw == getCurrentPanel())
playSound(res.EVENT_PART);
}
updateChanTitle(getChannel(params[0]));
}
break;
}
case -6: // QUIT
{
Object a[] = { prefix, params[0] };
String ptn = res.getString("eirc.s9");
String msg_text = MessageFormat.format(ptn, a);
OutputWindow [] ow = getUserPanels(prefix);
for (int i = 0; i < ow.length; i++)
{
ow[i].printInfo(msg_text);
if(ow[i] == (OutputWindow)getCurrentPanel())
playSound(res.EVENT_QUIT);
}
// Remove the user from the channels he was in.
for (Enumeration e = channels.elements(); e.hasMoreElements(); )
{
Channel channel = (Channel) e.nextElement();
channel.remove(prefix);
channel.update();
}
updateChanTitle(getChannel(params[0]));
NickInfo.remove(prefix);
break;
}
case -7: // KICK
{
String reason = (params[2] != null ? params[2] : "");
if (current_nick.equals(params[1]))
{
closeChannel(params[0]);
Object a[] = { params[0], prefix, reason };
String ptn = res.getString("eirc.s10");
status.printInfo(MessageFormat.format(ptn, a));
playSound(res.EVENT_KICK);
}
else
{
Channel channel = getChannel(params[0]);
channel.remove(params[1]);
channel.update();
ChannelWindow cw = getChannelWindow(params[0]);
Object a[] = { params[1], prefix, reason };
String ptn = res.getString("eirc.s11");
cw.printInfo(MessageFormat.format(ptn, a));
updateChanTitle(getChannel(params[0]));
if(cw == getCurrentPanel())
playSound(res.EVENT_KICK);
}
break;
}
case -8: // TOPIC
{
Channel channel = getChannel(params[0]);
channel.setTopic(MircMessage.filterMircAttributes(params[1]));
ChannelWindow cw = getChannelWindow(params[0]);
Object a[] = { prefix, params[1] };
String ptn = res.getString("eirc.s36");
cw.printInfo(MessageFormat.format(ptn, a));
break;
}
case -9: // PRIVMSG
{
// If the source of this message is in the ignore list, ignore this message. This flag is set at the top of the switch block.
if (is_prefix_ignored)
break;
boolean isChannel = Channel.isChannel(params[0]);
if (CTCPMessage.isCTCPMessage(params[1]))
{
CTCPMessage ctcp = new CTCPMessage(params[1]);
{
Object [] a = { ctcp.getCommandString(), prefix };
String ptn = res.getString("eirc.ctcp_received");
// status.printWarning(MessageFormat.format(ptn, a));
}
switch (ctcp.getCommand())
{
case CTCPMessage.ACTION:
{
if (!ctcp.hasParameter())
break;
ChatWindow target = (isChannel ? (ChatWindow)getChannelWindow(params[0]) : (ChatWindow)openPrivate(prefix, no_privates));
if (target != null)
target.printAction(ctcp.getParameter(), prefix);
break;
}
case CTCPMessage.PING:
{
String param = ctcp.hasParameter() ? ctcp.getParameter() : "";
CTCPMessage reply = new CTCPMessage("PING", param);
String p[] = { prefix, reply.toString() };
// sendMessage("NOTICE", p);
break;
}
case CTCPMessage.DCC:
{
Object a[] = { prefix };
String ptn = res.getString("eirc.dcc_not_supported");
OutputWindow target = getCurrentPanel();
target.printInfo(MessageFormat.format(ptn, a));
if (on_dcc_notify_peer)
{
String p[] = { prefix, res.getString("eirc.dcc_notify.remote") };
sendMessage("NOTICE", p);
ptn = res.getString("eirc.dcc_notify.local");
target.printInfo(MessageFormat.format(ptn, a));
}
break;
}
case CTCPMessage.VERSION:
{
CTCPMessage reply = new CTCPMessage("VERSION", PACKAGE.concat("-").concat(VERSION).concat(VERSION_EXTRA).concat(" ").concat(AUTHOR));
String p[] = { prefix, reply.toString() };
// sendMessage("NOTICE", p);
break;
}
}
}
else
{
if (isChannel)
{
ChannelWindow target = (ChannelWindow) getChannelWindow(params[0]);
if (target != null)
{
User user = target.getChannel().get(prefix);
target.printPrivmsg(params[1], prefix, user);
}
}
else
{
PrivateWindow target = openPrivate(prefix, no_privates);
if (target != null)
{
target.printPrivmsg(params[1], prefix);
playSound(res.EVENT_PRVMSG);
}
}
}
break;
}
case -10: // NOTICE
{
// If the source of this message is in the ignore list, ignore this message. This flag is set at the top of the switch block.
if (is_prefix_ignored)
break;
// if (prefix.length() > 0)
// {
// endOff = prefix.indexOf('!');
// if (endOff != -1)
// prefix = prefix.substring(0, endOff);
// }
// NickServ checking user's password
if (irc_services.isPassOk(prefix, params[1]))
login_time = false;
if (irc_services.isIdPrompt(prefix, params[1]) && !login_time)
{
if (current_nick.equalsIgnoreCase(original_nick) && !(nicksrv_pass != null || nicksrv_pass.equals("")))
identify(nicksrv_pass);
else
openIDWin();
}
if (irc_services.isPassBad(prefix, params[1]))
badIDWin();
if (Channel.isChannel(params[0]))
{
getChannelWindow(params[0]).printNotice(params[1], prefix);
}
else if (prefix.length() > 0 && prefix.toLowerCase().endsWith(network_name.toLowerCase()))
{
// Output notices from servers to status window.
status.printServerNotice(params[1], res.getString("eirc.server"));
}
else if (special_services && prefix.length() > 0 && isService(prefix) && !Channel.isChannel(prefix))
{
// Output notices from service bots to a dedicated (per bot) window.
PrivateWindow target = openPrivate(prefix, false);
if (target != null)
target.printNotice(params[1], prefix);
}
else if (params[0].equals(current_nick))
{
if (!CTCPMessage.isCTCPMessage(params[1]))
{
// Personal notice.
OutputWindow ow = getCurrentPanel();
if (ow != null && ow != status)
ow.printNotice(params[1], prefix);
else
status.printNotice(params[1], prefix);
}
else
{
CTCPMessage ctcp = new CTCPMessage(params[1]);
switch (ctcp.getCommand())
{
case CTCPMessage.PING:
{
double diff = Double.NEGATIVE_INFINITY;
if (ctcp.hasParameter())
{
try
{
long launch = Long.parseLong(ctcp.getParameter());
long arrive = (new Date()).getTime();
diff = (arrive - launch) / 1000.0;
}
catch (NumberFormatException e) {}
}
Object a[] = { prefix, new Double(diff) };
MessageFormat mf = new MessageFormat(res.getString("eirc.s12"));
double limits[] = { ChoiceFormat.previousDouble(0.0), 0.0, 1.0, ChoiceFormat.nextDouble(2.0) };
String times[] = { res.getString("eirc.s12.0"), res.getString("eirc.s12.1"), res.getString("eirc.s12.2"), res.getString("eirc.s12.3")};
mf.setFormat(1, new ChoiceFormat(limits, times));
getCurrentPanel().printInfo(mf.format(a));
break;
}
default:
{
Object a[] = { ctcp.getCommandString(), ctcp.getParameter() };
String ptn = res.getString("eirc.ctcp_reply");
getCurrentPanel().printNotice(MessageFormat.format(ptn, a), prefix);
break;
}
}
}
}
else
{
// These can only be originated on a server.
status.printNotice(params[0] + " " + params[1], prefix);
}
break;
}
case -11: // ERROR
{
status.printError(params[0]);
if (params[0].startsWith("Closing Link"))
{
send_quit = false;
disconnect();
}
break;
}
case -12: // WALLOPS
{
status.printServerNotice(params[0], prefix);
break;
}
case -13: // INVITE
{
if (see_invite)
{
Object a[] = { params[1], prefix };
String ptn = res.getString("eirc.invite");
status.printInfo(MessageFormat.format(ptn, a));
}
break;
}
case -14: // PONG
{
if (params.length >= 1)
{
Object a[] = { params[1] };
String ptn = res.getString("eirc.pong");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
}
break;
}
case 001: // RPL_WELCOME
{
if (m.isFromServer())
{
if (prefix.indexOf(".") == -1)
{
network_name = prefix;
}
else
{
StringTokenizer st = new StringTokenizer(prefix, ".");
String token = "";
while (st.countTokens() > 2)
token = st.nextToken();
network_name = st.nextToken() + "." + st.nextToken();
}
}
if (nicksrv_pass != null && nicksrv_pass.length() > 0)
{
identify(nicksrv_pass);
login_time = true;
}
break;
}
case 005: // RPL_ISUPPORT
{
if (m.isFromServer() && params.length >= 3)
{
/* The first and last parameters are ignored */
for (int i = 1; i < params.length - 1; i++)
{
int n = params[i].indexOf('=');
if (n > 1 && n < params[i].length() + 1)
{
String name = params[i].substring(0, n);
String val = params[i].substring(n + 1);
server_support.put(name, val);
}
else
{
/* No value but it means server actually support that */
server_support.put(params[i], "1");
}
}
}
break;
}
case 251: // RPL_LUSERCLIENT
{
MessageFormat mf = new MessageFormat("There are {0} users and {1} invisible on {2} servers");
try
{
Object o[] = mf.parse(params[1]);
int visibles = 0, invisibles = 0, total = 0;
try
{
visibles = Integer.parseInt((String)o[0]);
invisibles = Integer.parseInt((String)o[1]);
total = visibles + invisibles;
}
catch (NumberFormatException e) {}
Object s[] = { new Integer(total), new Integer(invisibles) };
String tag = "*Who*";
chat_panel.setTitle(tag, wholist_title.format(s));
}
catch (ParseException ex) {}
break;
}
case 301: // RPL_AWAY
case 391: // RPL_TIME
{
Object a[] = { params[1], params[2] };
String ptn = res.getString("eirc." + command);
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 302: // RPL_USERHOST
{
String list = params[1];
if (list.length() > 0)
{
StringTokenizer st = new StringTokenizer(list, " ");
while (st.hasMoreTokens())
{
String s = st.nextToken();
int i = s.indexOf("=");
String nick = s.substring(0, i);
if (nick.endsWith("*"))
{
nick = nick.substring(0, nick.length() - 1);
Object a[] = { nick };
String ptn = res.getString("eirc.s16");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
}
if (s.charAt(i + 1) == '-')
{
Object a[] = { nick };
String ptn = res.getString("eirc.302.away");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
}
String hostmask = s.substring(i + 2);
Object a[] = { nick, hostmask };
String ptn = res.getString("eirc.302.host");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
}
}
break;
}
case 303: // RPL_ISON
{
String list = params[1];
if (list.length() == 0)
{
getCurrentPanel().printInfo(res.getString("eirc.isoff"));
}
else
{
StringTokenizer st = new StringTokenizer(list, " ");
while (st.hasMoreTokens())
{
Object a[] = { st.nextToken() };
String ptn = res.getString("eirc.ison");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
}
}
break;
}
case 305: // RPL_UNAWAY
case 306: // RPL_NOWAWAY
{
is_away = (command == 306);
away.setForeground(is_away ? Color.red : Color.blue);
away.repaint(); // For Macintosh MRJ
break;
}
case 310: // RPL_WHOISOPSTATUS
{
Object a[] = { params[1], params[2] };
String ptn = res.getString("eirc.310");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 311: // RPL_WHOISUSER
{
if (hideip)
params[3] = "?";
Object a[] = { params[1], params[2], params[3] };
String ptn = res.getString("eirc.s13");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
// Real name is used to pass extra information about the user.
break;
}
case 312: // RPL_WHOISSERVER
{
Object a[] = { params[1], params[2], params[3] };
String ptn = res.getString("eirc.s15");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 313: // RPL_WHOISOPERATOR
{
Object a[] = { params[1] };
String ptn = res.getString("eirc.s16");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 314: // RPL_WHOWASUSER
{
if (hideip)
params[3] = "?";
Object a[] = { params[1], params[2], params[3], params[5] };
String ptn = res.getString("eirc.314");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 315: // RPL_ENDOFWHO
{
ChannelWindow cw = getChannelWindow(params[1]);
updateChanTitle(getChannel(params[1]));
if (params[1].indexOf("*") >= 0)
replyWhoEnd();
else
who_reply = null;
for (Enumeration e = channels.elements(); e.hasMoreElements(); )
{
Channel channel = (Channel) e.nextElement();
channel.update();
}
break;
}
case 317: // RPL_WHOISIDLE
{
int hrs = 0, mins = 0, secs = 0;
try
{
hrs = Integer.parseInt(params[2]) / 3600;
mins = (Integer.parseInt(params[2]) % 3600) / 60;
secs = (Integer.parseInt(params[2]) % 3600) % 60;
} catch (NumberFormatException e) {}
Object a[] = { params[1], new Integer(hrs), new Integer(mins), new Integer(secs) };
getCurrentPanel().printInfo(MessageFormat.format(res.getString("eirc.317"), a));
if (params.length >= 4)
{
Object b[] = { params[1], new Date(Long.parseLong(params[3]) * 1000) };
getCurrentPanel().printInfo(MessageFormat.format(res.getString("eirc.317.signon"), b));
}
break;
}
case 319: // RPL_WHOISCHANNELS
{
Object a[] = { params[1], params[2] };
String ptn = res.getString("eirc.s18");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 321: // RPL_LISTSTART
{
replyListStart();
break;
}
case 322: // RPL_LIST
{
// Some servers (ie. Bahamut) report a channel named '*' under some circumstances. Ignore those channels.
if (params[1].equals("*"))
break;
int users = 0;
try
{
users = Integer.parseInt(params[2]);
}
catch (NumberFormatException ex) {}
replyListAdd(params[1], users, params[3]);
break;
}
case 323: // RPL_LISTEND
{
replyListEnd();
break;
}
case 324: // RPL_CHANNELMODEIS
{
String [] modes_params = new String [params.length - 3];
for (int i = 0; i < modes_params.length; i++)
modes_params[i] = params[i + 3];
Channel channel = getChannel(params[1]);
if (channel != null)
channel.setModes(params[2], modes_params);
break;
}
case 331: // RPL_NOTOPIC
{
Channel channel = getChannel(params[1]);
if (channel != null)
channel.setTopic("");
OutputWindow cw = getChannelWindow(params[1]);
if (cw == null)
cw = getCurrentPanel();
Object a[] = { params[1] };
String ptn = res.getString("eirc.s37");
cw.printInfo(MessageFormat.format(ptn, a));
break;
}
case 332: // RPL_TOPIC
{
Channel channel = getChannel(params[1]);
if (channel != null)
channel.setTopic(MircMessage.filterMircAttributes(params[2]));
OutputWindow cw = getChannelWindow(params[1]);
if (cw == null)
cw = getCurrentPanel();
Object a[] = { params[1], params[2] };
String ptn = res.getString("eirc.s38");
cw.printInfo(MessageFormat.format(ptn, a));
break;
}
case 333: // RPL_TOPICINFO
{
// We're sent the time in seconds, but Date expects millis.
Date topic_date = new Date(Long.parseLong(params[3]) * 1000);
OutputWindow cw = getChannelWindow(params[1]);
if (cw == null)
cw = getCurrentPanel();
Object a[] = { params[2], topic_date, topic_date };
String ptn = res.getString("eirc.s35");
cw.printInfo(MessageFormat.format(ptn, a));
break;
}
case 336: // RPL_INVITELIST
{
listAdd(params[2], params[3], new Date(Long.parseLong(params[4]) * 1000));
break;
}
case 337: // RPL_ENDOFINVITELIST
{
listEnd(params[1], 'I');
break;
}
case 348: // RPL_EXCEPTLIST
{
listAdd(params[2], params[3], new Date(Long.parseLong(params[4]) * 1000));
break;
}
case 349: // RPL_ENDOFEXCEPTLIST
{
listEnd(params[1], 'e');
break;
}
case 352: // RPL_WHOREPLY
{
if (params.length >= 6)
{
NickInfo.add(params[5], params[params.length - 1], params[2], params[3]);
replyWhoAdd(params[5]);
for (Enumeration e = channels.elements(); e.hasMoreElements(); )
{
Channel channel = (Channel) e.nextElement();
channel.update(params[5]);
}
}
break;
}
case 353: // RPL_NAMREPLY
{
Channel channel = getChannel(params[2]);
StringTokenizer st = new StringTokenizer(params[3], " ");
int tokens = st.countTokens();
for (int i = 0; i < tokens; i++)
{
if (channel != null)
channel.add(st.nextToken());
else
names.addElement(st.nextToken());
}
break;
}
case 366: // RPL_ENDOFNAMES
{
if (getChannel(params[1]) == null)
{
Object a[] = { params[1] };
String s = res.getString("eirc.366");
getCurrentPanel().printInfo(MessageFormat.format(s, a));
s = "";
for (Enumeration e = names.elements() ; e.hasMoreElements() ;)
s += (String)e.nextElement() + " ";
getCurrentPanel().printInfo(s);
}
names.removeAllElements();
break;
}
case 367: // RPL_BANLIST
{
listAdd(params[2], params[3], new Date(Long.parseLong(params[4]) * 1000));
break;
}
case 368: // RPL_ENDOFBANLIST
{
listEnd(params[1], 'b');
break;
}
case 6: // RPL_ADMINME
case 7: // RPL_ADMINLOC1
case 8: // RPL_ADMINLOC2
case 9: // RPL_ADMINEMAIL
case 371: // RPL_INFO
case 372: // RPL_MOTD
{
status.printInfo(params[1]);
break;
}
case 381: // RPL_YOUREOPER
{
getCurrentPanel().printInfo(res.getString("eirc." + command));
break;
}
case 376: // RPL_ENDOFMOTD
case 422: // ERR_NOMOTD
{
// If this point was reached, login has been successful.
if (!logged_in)
{
this.logged_in = true;
// See what the server thinks our nick is from the message it sent. Servers trim nicks to fit an n-char limit.
if (!new_nick.equals(params[0]))
{
this.new_nick = params[0];
nick_entry.setText(new_nick);
Object a[] = { new_nick };
String ptn = res.getString("eirc.s4");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
}
pos_login();
updateWindowTitle();
}
setServerSupport();
break;
}
case 404: // ERR_CANNOTSENDTOCHAN
{
Object a[] = { params[2] };
String ptn = res.getString("eirc." + command);
getCurrentPanel().printError(MessageFormat.format(ptn, a));
break;
}
case 432: // ERR_ERRONEUSNICKNAME
case 433: // ERR_NICKNAMEINUSE
{
getCurrentPanel().printError(res.getString("eirc." + command));
break;
}
case 401: // ERR_NOSUCHNICK
case 403: // ERR_NOSUCHCHANNEL
case 406: // ERR_WASNOSUCHNICK
case 421: // ERR_UNKNOWNCOMMAND
case 461: // ERR_NEEDMOREPARAMS
case 464: // ERR_PASSWDMISMATCH
case 491: // ERR_NOOPERHOST
{
Object a[] = { params[1] };
String ptn = res.getString("eirc." + command);
getCurrentPanel().printError(MessageFormat.format(ptn, a));
break;
}
case 437: // ERR_UNAVAILRESOURCE
case 465: // ERR_YOUREBANNEDCREEP
case 471: // ERR_CHANNELISFULL
case 473: // ERR_INVITEONLYCHAN
case 474: // ERR_BANNEDFROMCHAN
case 478: // ERR_BANLISTFULL
case 482: // ERR_CHANOPRIVSNEEDED
{
Object a[] = { params[1] };
String ptn = res.getString("eirc." + command);
status.printError(MessageFormat.format(ptn, a));
status.requestFocus();
break;
}
case 475: // ERR_BADCHANNELKEY
{
openKeyWin(params[1]);
break;
}
/* ----------------- RFC not compliant special messages ---------------- */
case 232: // RPL_RULES (Unreal)
case 536: // RPL_RULES (IrcDreams)
{
status.printInfo(params[1]);
break;
}
case 307: // RPL_WHOISREGISTERED (Unreal, Bahamut)
{
Object a[] = { params[1] };
String ptn = res.getString("eirc.s27");
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 320: // RPL_WHOISSPECIAL (Unreal)
case 378: // RPL_WHOISHOST (Unreal)
{
Object a[] = { params[1], params[2] };
String ptn = res.getString("eirc." + command);
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 335: // RPL_WHOISBOT (Unreal)
case 671: // RPL_WHOISSECURE
{
Object a[] = { params[1] };
String ptn = res.getString("eirc." + command);
getCurrentPanel().printInfo(MessageFormat.format(ptn, a));
break;
}
case 346: // RPL_INVEXLIST (Unreal)
{
listAdd(params[2], params[3], new Date(Long.parseLong(params[4]) * 1000));
break;
}
case 347: // RPL_ENDOFINVEXLIST (Unreal)
{
listEnd(params[1], 'I');
break;
}
case 438: // ERR_NICKCHANGETOOFAST (Unreal)
case 447: // ERR_NONICKCHANGE (Unreal)
{
Object a[] = { params[params.length - 1] };
String ptn = res.getString("eirc.nickchange");
getCurrentPanel().printError(MessageFormat.format(ptn, a));
break;
}
case 498: // Reserved nick Voila.fr
{
getCurrentPanel().printError(res.getString("eirc.433"));
break;
}
case 477: // ERR_NEEDREGGEDNICK (Unreal, Bahamut)
case 489: // ERR_SECUREONLYCHAN (Unreal)
{
Object a[] = { params[1] };
String ptn = res.getString("eirc." + command);
status.printError(MessageFormat.format(ptn, a));
status.requestFocus();
break;
}
case 600: // RPL_LOGON (Unreal, Bahamut)
case 601: // RPL_LOGOFF (Unreal, Bahamut)
{
Date log = new Date(Long.parseLong(params[4]) * 1000);
Object a[] = { params[1], log };
String ptn = res.getString("eirc." + command);
status.printInfo(MessageFormat.format(ptn, a));
break;
}
case 604: // RPL_NOWON (Unreal, Bahamut)
case 605: // RPL_NOWOFF (Unreal, Bahamut)
{
Object a[] = { params[1] };
String ptn = res.getString("eirc." + command);
status.printInfo(MessageFormat.format(ptn, a));
break;
}
/* ----------------- End of RFC not compliant messages ---------------- */
}
}
private void setServerSupport()
{
// IRC RPL_ISUPPORT still draft but widely supported
try
{
String prefixes = (String)server_support.get("PREFIX");
if (prefixes != null && prefixes.length() > 2)
Modes.parseSupportedPrefixes(prefixes);
} catch (ParseException ex) { System.err.println(ex); }
try
{
String modes = (String)server_support.get("MODES");
if (modes != null && modes.length() > 0)
ModeList.setMaximumNumber(Integer.parseInt(modes));
} catch (NumberFormatException ex) { System.err.println(ex); }
}
private void replyListStart()
{
chan_list.clear();
}
private void replyListAdd(String tag, int users, String topic)
{
// Some buggy IRCd's don't send RPL_LISTSTART.
// if (!chan_list.initialized())
// replyListStart();
chan_list.add(new ChannelItem(tag, users, topic));
if (chan_list.number() % 100 == 0);
updateChanListTitle();
}
private void replyListEnd()
{
// Some buggy IRCd's don't send RPL_LISTSTART.
// if (!chan_list.initialized())
// replyListStart();
if (chan_list.number() == 0)
status.printInfo(res.getString("eirc.s19"));
chan_list.stop();
updateChanListTitle();
}
private void replyWhoAdd(String tag)
{
if (who_reply == null)
who_reply = new Vector();
who_reply.addElement(tag);
}
private void replyWhoEnd()
{
if (who_reply == null)
who_reply = new Vector();
who_list.loadUsers(who_reply);
this.who_reply = null;
/*
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow cw = (ChannelWindow)e.nextElement();
if (cw != null)
cw.refreshUsers();
}
*/
}
private void listStart()
{
this.list = new Vector(1);
}
private void listAdd(String mask, String op, Date date)
{
if (list == null)
listStart();
list.addElement(new ListItem(mask, op, date));
}
private void listEnd(String channel, char param)
{
if (list == null)
listStart();
String supported_modes = "beI";
if (supported_modes.indexOf(param) >= 0)
openList(channel, param);
this.list = null;
}
public void sendCommand(String text, OutputWindow target)
{
if (text.trim().length() <= 0)
throw new IllegalArgumentException("empty command");
String [] result = null;
try
{
result = Commands.parseCommand(user_commands, text);
}
catch (MissingResourceException ex)
{
// Let the server decide whether the command is correct.
String [] a = new String [0];
sendMessage(text, a);
return;
}
catch (IllegalArgumentException ex)
{
// Peek command. Text won't be neither empty nor have only white space (checked above).
String name = new StringTokenizer(text).nextToken();
// If excution gets here, command "name" does exist, otherwise the previous catch statement would have came into action.
Command c = Commands.getCommand(user_commands, name);
String action = c.getTag();
int required = c.getRequiredParameters();
// Show help.
String help = res.getString(action.concat(".short").toLowerCase());
if (help != null)
{
Object [] a = { help };
String ptn = res.getString("eirc.s22");
target.printError(MessageFormat.format(ptn, a));
}
else
{
// No help for this command. Warn the user.
MessageFormat mf = new MessageFormat(res.getString("eirc.bad_invocation"));
Object [] a = { action, new Integer(required) };
double [] limits = { 1.0, ChoiceFormat.nextDouble(1.0) };
String [] fragments =
{
res.getString("eirc.bad_invocation.0"),
res.getString("eirc.bad_invocation.1"),
};
mf.setFormat(1, new ChoiceFormat(limits, fragments));
target.printError(mf.format(a));
}
return;
}
/* Invoke the command. */
String name = result[0];
Vector parameters = new Vector(result.length - 1);
for (int i = 1; i < result.length; i++)
parameters.addElement(result[i]);
invokeCommand(name, parameters, target);
}
void invokeCommand(String name, Vector parameters, OutputWindow target)
{
// Command disabled in config ?
if (isDisabledCmd(name))
{
Object [] a = { name };
String ptn = res.getString("eirc.forbid");
target.printError(MessageFormat.format(ptn, a));
return;
}
// Only add commands here, DON'T add aliases.
if (name.equalsIgnoreCase("HELP"))
cmd_help(parameters, target);
else if (name.equalsIgnoreCase("CHARSET"))
cmd_charset(parameters, target);
else if (name.equalsIgnoreCase("CLEAR"))
cmd_clear(parameters, target);
else if (name.equalsIgnoreCase("QUOTE"))
cmd_quote(parameters, target);
else if (name.equalsIgnoreCase("JOIN"))
cmd_join(parameters, target);
else if (name.equalsIgnoreCase("PART"))
cmd_part(parameters, target);
else if (name.equalsIgnoreCase("PRIVMSG"))
cmd_msg(parameters, target);
else if (name.equalsIgnoreCase("NOTICE"))
cmd_notice(parameters, target);
else if (name.equalsIgnoreCase("PINGTIME"))
cmd_pingtime(parameters, target);
else if (name.equalsIgnoreCase("QUIT"))
cmd_quit(parameters, target);
else if (name.equalsIgnoreCase("NICK"))
cmd_nick(parameters, target);
else if (name.equalsIgnoreCase("ME"))
cmd_me(parameters, target);
else if (name.equalsIgnoreCase("QUERY"))
cmd_query(parameters, target);
else if (name.equalsIgnoreCase("CTCP"))
cmd_ctcp(parameters, target);
else if (name.equalsIgnoreCase("EIRC"))
cmd_eirc(parameters, target);
else if (name.equalsIgnoreCase("KBAN"))
cmd_kban(parameters, target);
else if (name.equalsIgnoreCase("IGNORE"))
cmd_ignore(parameters, target);
else if (name.equalsIgnoreCase("UNIGNORE"))
cmd_unignore(parameters, target);
else if (name.equalsIgnoreCase("SAVE"))
cmd_save(parameters, target);
else if (name.equalsIgnoreCase("SERVER"))
cmd_server(parameters, target, false);
else if (name.equalsIgnoreCase("SERVERSSL"))
cmd_server(parameters, target, true);
else if (name.equalsIgnoreCase("GHOST"))
cmd_ghost(parameters, target);
else if (name.equalsIgnoreCase("DEBUG"))
cmd_debug(parameters, target);
else
{
// Let the server decide whether the command is correct.
String [] a = new String [parameters.size()];
parameters.copyInto(a);
sendMessage(name, a);
}
}
boolean isDisabledCmd(String cmd)
{
String list = getParameter("disabled_cmds");
if (list != null && cmd != null && list.length() > 0 && cmd.length() > 0)
{
StringTokenizer tk = new StringTokenizer(list, ", ");
while (tk.hasMoreTokens())
{
if (tk.nextToken().equalsIgnoreCase(cmd))
return(true);
}
}
return(false);
}
void cmd_help(Vector params, OutputWindow target)
{
// If no command has been specified.
if (params.size() == 0)
{
// List internal commands.
for (Enumeration e= user_commands.getKeys();e.hasMoreElements();)
target.printInfo((String) e.nextElement());
return;
}
String action = (String)params.elementAt(0);
try
{
// Resolve aliases.
action = Commands.getCommand(user_commands, action).getTag();
}
catch (MissingResourceException e)
{
}
String help_on = action.toLowerCase();
// See if there's help locally provided for this command.
String h1 = res.getString(help_on.concat(".short"));
String h2 = res.getString(help_on.concat(".long"));
if (h1 != null && h2 != null)
{
target.printInfo(h1);
target.printInfo(h2);
}
else
{
// No help for this command.
Object a[] = { action };
String ptn = res.getString("eirc.no_help");
target.printError(MessageFormat.format(ptn, a));
}
}
void cmd_quote(Vector params, OutputWindow target)
{
String a[] = new String [0];
sendMessage((String) params.elementAt(0), a);
}
void cmd_nick(Vector params, OutputWindow target)
{
String a[] = new String [params.size()];
params.copyInto(a);
a[0] = RFC1459.filterString(a[0]);
sendMessage("NICK", a);
}
void cmd_me(Vector params, OutputWindow target)
{
if (!(target instanceof ChatWindow))
{
target.printError(res.getString("eirc.s23"));
return;
}
String to = ((ChatWindow) target).getPanelTag();
params.insertElementAt(to, 0);
String a[] = new String [params.size()];
params.copyInto(a);
((ChatWindow) target).printMyAction(a[1]);
a[1] = "\001ACTION " + a[1] + "\001";
sendMessage("PRIVMSG", a);
}
void cmd_query(Vector params, OutputWindow target)
{
String a[] = new String [params.size()];
params.copyInto(a);
PrivateWindow pw = openPrivate(a[0]);
chat_panel.show(a[0]);
pw.requestFocus();
if (params.size() == 2)
{
sendMessage("PRIVMSG", a);
pw.printMyPrivmsg(a[1]);
}
}
void cmd_msg(Vector params, OutputWindow target)
{
cmd_query(params, target);
}
void cmd_notice(Vector params, OutputWindow target)
{
if (!(target instanceof ChatWindow))
{
target.printError(res.getString("eirc.s23"));
return;
}
if (params.size() == 2)
{
String a[] = new String [2];
a[0] = (String)params.elementAt(0);
a[1] = (String)params.elementAt(1);
sendMessage("NOTICE", a);
((ChatWindow)target).printMyNotice(a[1]);
}
}
void cmd_join(Vector params, OutputWindow target)
{
if (!canJoin())
return;
String a[] = new String [params.size()];
params.copyInto(a);
if (!Channel.isChannel(a[0]))
{
a[0] = '#' + a[0];
}
sendMessage("JOIN", a);
}
void cmd_part(Vector params, OutputWindow target)
{
if (0 == params.size())
{
if (!(target instanceof ChannelWindow))
{
target.printError(res.getString("eirc.s24"));
return;
}
params.insertElementAt(((ChannelWindow) target).getPanelTag(), 0);
}
String a[] = new String [params.size()];
params.copyInto(a);
if (!Channel.isChannel(a[0]))
{
a[0] = '#' + a[0];
}
// The Listener for the event takes care of sending the message.
sendMessage("PART", a);
}
void cmd_pingtime(Vector params, OutputWindow target)
{
params.addElement("\001PING " + (new Date()).getTime() + "\001");
String a[] = new String [params.size()];
params.copyInto(a);
sendMessage("PRIVMSG", a);
}
void cmd_quit(Vector params, OutputWindow target)
{
String a[] = new String [1];
a[0] = 0 == params.size() ? quit_message : (String) params.elementAt(0);
this.send_quit = false;
sendMessage("QUIT", a);
}
void cmd_ctcp(Vector params, OutputWindow target)
{
String a[] = new String [params.size()];
params.copyInto(a);
a[1] = "\001" + a[1] + "\001";
sendMessage("PRIVMSG", a);
}
void cmd_eirc(Vector params, OutputWindow target)
{
Object a[] = { PACKAGE, VERSION.concat(" ").concat(VERSION_EXTRA), res.getString("author"), res.getString("update") };
String ptn = res.getString("info");
target.printInfo(MessageFormat.format(ptn, a));
}
void cmd_charset(Vector params, OutputWindow target)
{
String charset = encoding;
if (params.size() > 0)
{
charset = (String)params.elementAt(0);
try
{
CharsConverter conv = new CharsConverter(charset, charset);
if (server != null)
server.setCharsConverter(conv);
encoding = charset;
decoding = charset;
properties.setString("decoding", charset);
properties.setString("encoding", charset);
}
catch(UnsupportedEncodingException e)
{
target.printError(e.toString());
return;
}
}
target.printInfo("Charset : " + charset);
}
void cmd_clear(Vector params, OutputWindow target)
{
target.clear();
}
void cmd_kban(Vector params, OutputWindow target)
{
int i = 0;
String channel = "";
if (target instanceof ChannelWindow)
channel = ((ChannelWindow)target).getPanelTag();
if (params.size() > 2)
channel = (String)params.elementAt(i++);
String nick = (String)params.elementAt(i++);
String why = "";
if (i == params.size() - 1)
why = (String)params.elementAt(i);
if (getChannel(channel) == null)
{
target.printError(res.getString("eirc.s24"));
return;
}
String mask = nick;
String addr = NickInfo.getInetAddr(nick);
String user = NickInfo.getUser(nick);
if (addr == null)
{
if (user != null)
mask = "*!" + user + "@*";
}
else
{
mask = "*!*@" + addr;
}
sendCommand("MODE " + channel + " +b " + mask, target);
sendCommand("KICK " + channel + " " + nick + " " + why, target);
}
void cmd_ignore(Vector params, OutputWindow target)
{
if (params.size() == 0)
{
if (ignore_list.size() == 0)
{
target.printWarning(res.getString("eirc.no_ignored_users"));
return;
}
StringBuffer line = new StringBuffer();
for (Enumeration e = NickInfo.getList().elements(); e.hasMoreElements();)
{
String nick = (String) e.nextElement();
if (ignore_list.contains(NickInfo.getInetAddr(nick)))
line.append(' ').append(nick);
}
Object a[] = { line.toString() };
String ptn = res.getString("eirc.ignored_users");
target.printInfo(MessageFormat.format(ptn, a));
return;
}
String nick = (String) params.elementAt(0);
String addr = NickInfo.getInetAddr(nick);
if (addr != null && !ignore_list.contains(addr))
{
ignore_list.addElement(addr);
Object a[] = { nick };
String ptn = res.getString("eirc.ignore");
target.printInfo(MessageFormat.format(ptn, a));
String p[] = { nick, res.getString("eirc.ignore_notice") };
sendMessage("NOTICE", p);
}
}
void cmd_unignore(Vector params, OutputWindow target)
{
String nick = (String) params.elementAt(0);
String addr = NickInfo.getInetAddr(nick);
if (addr != null && ignore_list.removeElement(addr))
{
Object a[] = { nick };
String ptn = res.getString("eirc.unignore");
target.printInfo(MessageFormat.format(ptn, a));
String p[] = { nick, res.getString("eirc.unignore_notice") };
sendMessage("NOTICE", p);
}
}
void cmd_save(Vector params, OutputWindow target)
{
String name = null;
if (params.size() > 0)
{
saveTo((String)params.elementAt(0));
return;
}
if (isConfDefined())
{
save();
return;
}
target.printError(res.getString("eirc.errsav"));
}
void cmd_server(Vector params, OutputWindow target, boolean ssl)
{
String server_name = (String)params.elementAt(0);
if (params.size() > 2)
this.irc_pass = (String)params.elementAt(2);
// If user passed a port number.
if (params.size() > 1)
{
try
{
connect(server_name, Integer.parseInt((String)params.elementAt(1)), ssl);
return;
}
catch (NumberFormatException e) {}
}
connect(server_name, ssl);
}
void cmd_ghost(Vector params, OutputWindow target)
{
String a[] = new String [params.size()];
params.copyInto(a);
irc_services.killGhost(a[0], a[1]);
}
void cmd_debug(Vector params, OutputWindow target)
{
String a[] = new String [params.size()];
params.copyInto(a);
if (a[0].equalsIgnoreCase("OFF"))
debug_traffic = 0;
if (a[0].equalsIgnoreCase("CONSOLE"))
debug_traffic = 1;
if (a[0].equalsIgnoreCase("ON"))
{
debug_window = getCurrentPanel();
debug_traffic = 2;
}
}
public void sendMessage(String command, String parameters[])
{
if (connected)
{
Message m = new MircMessage(command, parameters);
if (debug_traffic > 0)
{
String t = m.toString();
// Strip CRLF.
t = t.substring(0, t.length() - 2);
debug(">> " + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(new Date()) + " " + t);
}
try
{
server.enqueueMessage(m);
}
catch (IOException e)
{
System.err.println(e);
}
}
else
{
// FIXME: it can't distinguish user and program issued messages.
status.printError(res.getString("eirc.disconnected"));
}
}
public void joinChannel(String name)
{
if (getChannel(name) == null)
{
if (canJoin())
{
String p[] = { name };
sendMessage("JOIN", p);
}
}
else
{
showPanel(name);
}
}
public boolean canJoin()
{
// Permission ?
if (restrict_join == 0)
return(true);
return(false);
}
public OutputWindow getCurrentPanel()
{
ChatPanel cp = chat_panel.getVisible();
return (cp != null && cp instanceof OutputWindow ? (OutputWindow)cp : status);
}
public OutputWindow getUserPanel(String user)
{
OutputWindow ow = getPrivate(user);
return (ow != null ? ow : status);
}
public OutputWindow [] getUserPanels(String user)
{
Vector v = new Vector();
for (Enumeration e = channel_windows.elements(); e.hasMoreElements();)
{
ChannelWindow cw = (ChannelWindow) e.nextElement();
Channel c = cw.getChannel();
if (c.contains(user))
v.addElement(cw);
}
OutputWindow pw = getPrivate(user);
if (pw != null)
v.addElement(pw);
OutputWindow [] a = new OutputWindow [v.size()];
v.copyInto(a);
return(a);
}
public String[] getChans()
{
Vector v = new Vector();
for (Enumeration e = channel_windows.elements(); e.hasMoreElements();)
{
ChannelWindow cw = (ChannelWindow) e.nextElement();
Channel ch = cw.getChannel();
v.addElement(ch.getTag());
}
String[] a = new String[v.size()];
v.copyInto(a);
return(a);
}
public String getNick()
{
return(current_nick);
}
public Channel getChannel(String tag)
{
ChannelWindow cw = getChannelWindow(tag);
return (cw != null ? cw.getChannel() : null);
}
public ChannelWindow getChannelWindow(String tag)
{
return (ChannelWindow)channel_windows.get(tag);
}
public Channel openChannel(String tag)
{
Channel channel = getChannel(tag);
if (channel != null)
{
chat_panel.show(tag);
return(channel);
}
channel = new Channel(tag);
channels.addElement(channel);
String [] p = { tag };
sendMessage("MODE", p);
/* Create GUI object.
*/
ChannelWindow cw = new ChannelWindow(this, channel);
properties.addObserver(cw);
cw.update(properties, null);
cw.setFont(getFont());
cw.setForeground(mainfg);
cw.setBackground(mainbg);
cw.setTextForeground(textfg);
cw.setTextBackground(textbg);
cw.setSelectedForeground(selfg);
cw.setSelectedBackground(selbg);
channel_windows.put(tag, cw);
chat_panel.add(cw, tag);
cw.validate();
chat_panel.show(tag);
cw.requestFocus();
cw.addChatPanelListener(this);
return channel;
}
public void close(String name)
{
if (Channel.isChannel(name))
{
String p[] = { name };
sendMessage("PART", p);
closeChannel(name);
}
else
{
closePrivate(name);
}
}
public void closeAllChannels()
{
/* Close all open channel panels */
String chans[] = getChans();
String param[] = new String[1];
if (connected && chans.length > 0)
{
int i = chans.length - 1;
param[0] = chans[i--];
for (; i >= 0; i--)
param[0] += "," + chans[i];
sendMessage("PART", param);
}
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow w = (ChannelWindow)e.nextElement();
w.dispose();
}
channel_windows.clear();
channels.removeAllElements();
}
public void closeChannel(String s)
{
for (Enumeration e = channels.elements(); e.hasMoreElements(); )
{
Channel channel = (Channel) e.nextElement();
if (channel.getTag().equals(s))
channels.removeElement(channel);
}
ChannelWindow cw = getChannelWindow(s);
if (cw != null)
cw.dispose();
}
public void closePrivate(String name)
{
/* Close a private */
for (Enumeration e = privates.elements(); e.hasMoreElements();)
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
if (pw.getUser().equals(name))
{
privates.remove(name);
pw.dispose();
}
}
}
public void closeUnreadPrivates()
{
for (Enumeration e = privates.elements(); e.hasMoreElements();)
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
if (!pw.isRead())
{
privates.remove(pw.getPanelTag());
pw.dispose();
}
}
}
public void closeAllPrivates()
{
/* Close privates panels */
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.dispose();
}
privates.clear();
}
public void updateChanTitle(Channel ch)
{
if (ch != null)
{
String tag = ch.getTag();
Object o[] = { tag, new Integer(ch.number()) };
chat_panel.setTitle(tag, chan_title.format(o));
}
}
public void updateChanListTitle()
{
String tag = "*Chans*";
Object o[] = { new Integer(chan_list.number()) };
chat_panel.setTitle(tag, chanlist_title.format(o));
}
public PrivateWindow getPrivate(String target)
{
return (PrivateWindow) privates.get(target);
}
public PrivateWindow openPrivate(String target, boolean no_more)
{
PrivateWindow pw = getPrivate(target);
if (pw != null)
return pw;
if (no_more)
return(null);
else
return(openPrivate(target));
}
public PrivateWindow openPrivate(String target)
{
PrivateWindow pw = getPrivate(target);
if (pw != null)
return pw;
pw = new PrivateWindow(this, target, target);
properties.addObserver(pw);
pw.update(properties, null);
pw.setFont(getFont());
pw.setForeground(mainfg);
pw.setBackground(mainbg);
pw.setTextForeground(textfg);
pw.setTextBackground(textbg);
pw.setSelectedBackground(selbg);
privates.put(target, pw);
chat_panel.add(pw, target);
Object o[] = { target };
chat_panel.setTitle(target, private_title.format(o));
pw.validate();
if (focus_opening_privates)
{
chat_panel.show(target);
pw.requestFocus();
}
pw.addChatPanelListener(this);
return pw;
}
public void showPanel(String name)
{
chat_panel.show(name);
}
public void openChannelList()
{
chat_panel.showPanel("*Chans*");
}
public void openWhoList()
{
// String p[] = { };
// sendMessage("LUSERS", p);
chat_panel.showPanel("*Who*");
}
public void openConfigurator()
{
if (configurator == null)
{
configurator = new Configurator(this, this.properties);
configurator.addWindowListener(this);
configurator.setName("configurator");
}
else
{
configurator.toFront();
}
}
public void openList(String tag, char mode)
{
if (list != null)
{
Channel chan = getChannel(tag);
boolean is_op = false;
if (chan != null)
{
User me = chan.get(getNick());
is_op = me.isOwner() || me.isAdmin() || me.isOp() || me.isHalfOp() || canOverride();
}
MessageFormat mf = new MessageFormat(res.getString(mode + "_list.title"));
Object o[] = { tag };
String title = mf.format(o);
mf = new MessageFormat(Resources.getString("eirc." + mode + "_list"));
String button = res.getString(mode + "_list.delete");
if (mode_list == null)
{
mode_list = new ModeList(this);
mode_list.addWindowListener(this);
mode_list.setName("mode_list");
}
else
{
mode_list.toFront();
}
mode_list.initList(tag, is_op, list, title, mf, button, mode);
}
}
public String openAwayWin()
{
Box b = new Box(this, res.getString("away.title"), res.getString("away.prompt"), res.getString("away.label"), away_str, false);
if (b.getResult() == 1)
{
away_str = b.getString();
return(away_str != null ? away_str : "");
}
return("");
}
public Box openWin(String cmd, String nick)
{
String key = cmd.toLowerCase(Locale.US);
MessageFormat mf = new MessageFormat(res.getString(key + ".prompt"));
Object o[] = { nick };
String prompt = mf.format(o);
return(new Box(this, res.getString(key + ".title"), prompt, res.getString(key + ".label"), null, false));
}
public void openKill(String cmd, String nick, OutputWindow target)
{
Box b = openWin(cmd, nick);
String why = b.getString();
if (b.getResult() == 1 && why.length() > 0)
sendCommand(cmd + " " + nick + " " + why, target);
}
public void openKick(String cmd, String channel, String nick, OutputWindow target)
{
Box b = openWin(cmd, nick);
String why = b.getString();
if (b.getResult() == 1 && why.length() > 0)
sendCommand(cmd + " " + channel + " " + nick + " " + why, target);
}
public void openKeyWin(String chan)
{
MessageFormat mf = new MessageFormat(res.getString("join.title"));
Object o[] = { chan };
String title = mf.format(o);
Box b = new Box(this, title, res.getString("join.prompt"), res.getString("join.label"), null, true);
if (b.getResult() == 1)
{
String p[] = { chan, b.getString() };
sendMessage("JOIN", p);
}
}
public void openGhostWin(String cmd, String nick, OutputWindow target)
{
Box b = new Box(this, res.getString("ghost.title"), res.getString("ghost.prompt"), res.getString("ghost.label"), null, true);
String pw = b.getString();
if (b.getResult() == 1 && pw.length() > 0)
sendCommand(cmd + " " + nick + " " + pw, target);
}
public void openIDWin()
{
Box b = new Box(this, res.getString("services.id.title"), res.getString("services.prompt"), res.getString("services.label"), null, true);
String pw = b.getString();
if (b.getResult() == 1 && pw.length() > 0)
{
identify(pw);
}
else
{
String p[] = { original_nick };
sendMessage("NICK", p);
}
}
public void badIDWin()
{
new Box(this, res.getString("services.id.title"), res.getString("services.ns.loginbad"), null);
String p[] = { original_nick };
sendMessage("NICK", p);
}
public boolean isNickCorrect(String nick)
{
int i = 0;
boolean compliant = true;
char c = '?';
while (i < nick.length() && compliant)
{
c = nick.charAt(i);
compliant = RFC1459.isDeclaredChar(c);
i++;
}
if (!compliant)
{
Object o[] = { new Character(c) };
MessageFormat mf = new MessageFormat(res.getString("nick.message"));
new Box(this, res.getString("nick.title"), mf.format(o), null, null, false);
return(false);
}
return(true);
}
public void openHelp()
{
if (help == null)
{
help = new HelpBox(this);
help.addWindowListener(this);
help.setName("help");
}
else
{
help.toFront();
}
}
public void updateWindowTitle()
{
String p = getParameter("spawn_frame");
if ((p == null || p.equals("0")) && !application)
return;
String title = "";
if (current_nick != null)
title = current_nick;
if (current_server != null && current_server.length() > 0)
title += " - " + current_server;
String te;
if ((te = res.getString("title")) != null)
{
// Force a space char at the beginning, browsers trim PARAMs.
if (te.charAt(0) != ' ')
te = ' ' + te;
title = title.concat(te);
}
f.setTitle(title);
}
public void update(Observable o, Object argument)
{
if (o instanceof ConfigurationProperties)
{
ConfigurationProperties props = (ConfigurationProperties)o;
String arg = null;
if (argument != null)
arg = (String)argument;
if (arg == null || arg.equals("special_services"))
this.special_services = props.getBoolean("special_services");
if (arg == null || arg.equals("nicksrv_pass"))
this.nicksrv_pass = props.getString("nicksrv_pass");
if (arg == null || arg.equals("irc_pass"))
this.irc_pass = props.getString("irc_pass");
if (arg == null || arg.equals("request_motd"))
this.request_motd = props.getBoolean("request_motd");
if (arg == null || arg.equals("see_everything_from_server"))
this.see_everything_from_server = props.getBoolean("see_everything_from_server");
if (arg == null || arg.equals("see_join"))
this.see_join = props.getBoolean("see_join");
if (arg == null || arg.equals("see_invite"))
this.see_invite = props.getBoolean("see_invite");
if (arg == null || arg.equals("on_dcc_notify_peer"))
this.on_dcc_notify_peer = props.getBoolean("on_dcc_notify_peer");
if (arg == null || arg.equals("service_bots"))
this.service_bots = props.getString("service_bots");
if (arg == null || arg.equals("hideip"))
this.hideip = props.getBoolean("hideip");
if (arg == null || arg.equals("focus_opening_privates"))
this.focus_opening_privates = props.getBoolean("focus_opening_privates");
if (arg == null || arg.equals("no_privates"))
this.no_privates = props.getBoolean("no_privates");
if (arg == null || arg.equals("write_color"))
this.write_color = props.getInt("write_color");
if (arg == null || arg.equals("scroll_speed"))
this.scroll_speed = props.getInt("scroll_speed");
if (arg == null || arg.equals("silent"))
this.silent = props.getInt("silent");
if (arg == null || arg.equals("auto_list"))
this.auto_list = props.getBoolean("auto_list");
if (arg == null || arg.equals("decoding"))
this.decoding = props.getString("decoding");
if (arg == null || arg.equals("encoding"))
this.encoding = props.getString("encoding");
if (arg == null || arg.equals("quit_message"))
this.quit_message = props.getString("quit_message");
if (arg == null || arg.startsWith("event_"))
{
for (int i = 1; i <= res.EVENTS; i++)
this.event_sounds[i - 1] = (AudioClip)res.SOUNDS.get(props.getString("event_" + i));
}
if (arg == null || arg.equals("restrict_join"))
this.restrict_join = props.getInt("restrict_join");
if (arg == null || arg.equals("ping"))
this.ping = props.getInt("ping");
}
}
public void requestFocus()
{
if (connected && status != null)
status.requestFocus();
if (!connected && nick_entry != null)
nick_entry.requestFocus();
}
public boolean isService(String tag)
{
return (status_tag.equals(tag) || irc_services.isService(tag));
}
public void setGlobalModes(String modes)
{
char [] mode_ary = modes.toCharArray();
boolean sign = false;
int j = 0;
for (int i = 0; i < mode_ary.length; i++)
{
switch (mode_ary[i])
{
case '+':
sign = true;
break;
case '-':
sign = false;
break;
case 'o':
server_admin = sign;
break;
case 'i':
who_invisible = sign;
who_list.invisible.setState(sign);
break;
case 'N':
ircop_override = sign;
break;
case '*':
server_admin = sign;
who_invisible = sign;
who_list.invisible.setState(sign);
ircop_override = sign;
}
}
}
public boolean isIRCop()
{
return(server_admin);
}
public boolean canOverride()
{
// If true, ircops can override a channel's modes without beeing opped. (Unreal global mode)
return(ircop_override);
}
public boolean isInvisible()
{
return(who_invisible);
}
public void identify(String passwd)
{
irc_services.identifyNick(current_nick, username, passwd);
}
public void register(String passwd, String email)
{
irc_services.registerNick(passwd, email);
}
public int scrollSpeed()
{
return(scroll_speed);
}
public boolean isConfDefined()
{
return(cfg_name != null && cfg_name.length() > 0);
}
public void save()
{
saveTo(cfg_name);
}
public void saveTo(String dest)
{
try
{
properties.write(dest);
}
catch(IOException e)
{
report("eirc.errsav", e.toString());
}
}
public String[] getUserColors()
{
String c[] = new String[color_list.size()];
int i = 0;
for (Enumeration e = color_list.keys(); e.hasMoreElements(); )
c[i++] = (String)e.nextElement();
return(c);
}
public Color getUserColor(String s)
{
return((Color)color_list.get(s));
}
public void paint(Graphics g)
{
getFrame().setBackground(getBackground());
super.paint(g);
}
public Frame getFrame()
{
if (f != null)
return(f);
Container c = this;
while(c != null && !(c instanceof Frame))
c = c.getParent();
if (c == null)
return(new Frame());
else
return((Frame)c);
}
public void setFont(Font ft)
{
Frame ff = getFrame();
mainfont = ft;
ff.setFont(ft);
ff.validate();
status.setFont(ft);
status.validate();
chan_list.setFont(ft);
chan_list.validate();
who_list.setFont(ft);
who_list.validate();
// Propagate changes to other windows.
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow cw = (ChannelWindow) e.nextElement();
cw.setFont(ft);
cw.validate();
}
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.setFont(ft);
pw.validate();
}
// Popup menu font
for (int i = 0; i < menu.getItemCount(); i++)
menu.getItem(i).setFont(ft);
label.setFont(ft);
nick_entry.setFont(ft);
away.setFont(ft);
control_panel.setFont(ft);
control_panel.repaint();
chat_panel.setFont(ft);
chat_panel.validate();
}
public Font getFont()
{
return(mainfont);
}
public void setBackground(Color c)
{
mainbg = c;
getFrame().setBackground(c);
super.setBackground(c);
status.setBackground(c);
chan_list.setBackground(c);
who_list.setBackground(c);
/* Propagate changes to other windows */
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow cw = (ChannelWindow) e.nextElement();
cw.setBackground(c);
}
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.setBackground(c);
}
label.setBackground(c);
away.setBackground(c);
control_panel.setBackground(c);
chat_panel.setBackground(c);
repaint();
}
public void setForeground(Color c)
{
mainfg = c;
getFrame().setForeground(c);
control_panel.setForeground(c);
chat_panel.setForeground(c);
}
public void setTextBackground(Color c)
{
textbg = c;
nick_entry.setBackground(c);
status.setTextBackground(c);
chan_list.setTextBackground(c);
who_list.setTextBackground(c);
// Propagate changes to other windows.
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow cw = (ChannelWindow) e.nextElement();
cw.setTextBackground(c);
}
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.setTextBackground(c);
}
}
public void setTextForeground(Color c)
{
textfg = c;
nick_entry.setForeground(c);
}
public void setSelectedBackground(Color c)
{
// Propagate changes to other windows.
for (Enumeration e = channel_windows.elements(); e.hasMoreElements(); )
{
ChannelWindow cw = (ChannelWindow) e.nextElement();
cw.setSelectedBackground(c);
}
for (Enumeration e = privates.elements(); e.hasMoreElements(); )
{
PrivateWindow pw = (PrivateWindow) e.nextElement();
pw.setSelectedBackground(c);
}
}
public Color getBackground()
{
return(mainbg);
}
public Color getTextBackground()
{
return(textbg);
}
public Color getTextForeground()
{
return(textfg);
}
public void cutPaste(String s)
{
if (tac == null)
{
tac = new TextAreaCopy(this, s);
tac.setName("tac");
tac.addWindowListener(this);
}
else
{
tac.toFront();
}
tac.setText(s);
}
public void visitURL(URL url)
{
visitURL(url, "_blank");
}
public void visitURL(URL url, String target)
{
getAppletContext().showDocument(url, target);
}
public void actionPerformed(ActionEvent ev)
{
this.new_nick = nick_entry.getText();
if (new_nick.length() == 0)
return;
if (!isNickCorrect(new_nick))
return;
if (!connected)
{
connect();
}
else
{
String p[] = { new_nick };
sendMessage("NICK", p);
}
}
public void mouseClicked(MouseEvent ev)
{
}
public void mouseEntered(MouseEvent ev)
{
getFrame().setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent ev)
{
getFrame().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
public void mousePressed(MouseEvent ev)
{
menu.show(away, ev.getPoint().x, ev.getPoint().y);
}
public void mouseReleased(MouseEvent ev)
{
}
public void itemStateChanged(ItemEvent ev)
{
String p[] = { "" };
for (int i = 0; i < menu.getItemCount(); i++)
{
MenuItem item = menu.getItem(i);
if (item instanceof CheckboxMenuItem)
{
if(menu.getItem(i) == ev.getSource() && ((CheckboxMenuItem)item).getState())
{
if (i == 0)
{
p[0] = openAwayWin();
if (p[0].equals(""))
((CheckboxMenuItem)item).setState(false);
}
else
{
p[0] = item.getLabel();
}
}
else
{
((CheckboxMenuItem)item).setState(false);
}
}
}
sendMessage("AWAY", p);
}
public void playSound(int i)
{
if (silent == res.SND_OFF || (silent == res.SND_OFFAWAY && is_away))
return;
if (event_sounds[i] != null)
event_sounds[i].play();
}
public void chatPanelClosing(ChatPanelEvent ev)
{
ChatPanel source = ev.getChatPanel();
String name = source.getPanelTag();
chat_panel.remove(name);
if (source instanceof PrivateWindow)
{
properties.deleteObserver((PrivateWindow) source);
privates.remove(name);
}
else if (source instanceof ChannelWindow)
{
properties.deleteObserver((ChannelWindow) source);
channel_windows.remove(name);
}
}
public void windowOpened(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
String name = e.getWindow().getName();
if (name.equals("main"))
{
if (f != null)
f.dispose();
stop();
destroy();
System.exit(0);
}
if (name.equals("tac") && tac != null)
{
tac.dispose();
tac = null;
}
if (name.equals("configurator") && configurator != null)
{
configurator.dispose();
configurator = null;
}
if (name.equals("asl") && asl != null)
{
asl.dispose();
asl = null;
}
if (name.equals("mode_list") && mode_list != null)
{
mode_list.dispose();
mode_list = null;
}
if (name.equals("help") && help != null)
{
help.dispose();
help = null;
}
}
public void windowClosed(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowActivated(WindowEvent e)
{
ImageButton.setWindowFocus(true);
SmileyTextAreaArea.setWindowFocus(true);
NickList.setWindowFocus(true);
}
public void windowDeactivated(WindowEvent e)
{
if (!(e.getSource() instanceof NewDialog))
{
ImageButton.setWindowFocus(false);
SmileyTextAreaArea.setWindowFocus(false);
NickList.setWindowFocus(false);
}
}
public String getParameter(String param)
{
String s = super.getParameter(param);
if (s != null && s.length() > 0)
return(s);
if (properties != null)
return(properties.getString(param));
return(null);
}
private final static String [][] param_info =
{
{ "server", "string", "IRC server's address" },
{ "port", "0-65535", "IRC server's port" },
{ "ssl", "0/1", "Plain or SSL connection" },
{ "irc_pass", "string", "clients' password to server" },
{ "mainbg", "color", "general background color" },
{ "mainfg", "color", "general foreground color" },
{ "textbg", "color", "text background color" },
{ "textfg", "color", "text foreground color" },
{ "selbg", "color", "selected background color" },
{ "selfg", "color", "selected foreground color" },
{ "join", "string", "channel(s) to auto-join" },
{ "username", "string", "username part of hostmask" },
{ "realname", "string", "user's real name" },
{ "nickname", "RFC 1459 string", "user's nick name" },
{ "nicksrv_pass", "string", "nickserv user's password" },
{ "login", "0/1", "whether to try auto-login" },
{ "disable_cmds", "string", "list of commands to disable" },
{ "user_modes", "string", "set or unset user modes after connection" },
{ "spawn_frame", "0/1", "spawn separate frame" },
{ "gui_nick", "0/1", "remove or add nick change field" },
{ "gui_away", "0/1", "remove or add away menu" },
{ "gui_chanlist", "0/1", "remove or add channels list" },
{ "gui_userlist", "0/1", "remove or add users list" },
{ "gui_options", "0/1", "remove or add options" },
{ "gui_help", "0/1", "remove or add help" },
{ "gui_connect", "0/1", "remove or add connect button" },
{ "width", "int", "frame width" },
{ "height", "int", "frame height" },
{ "debug_traffic", "0-2", "disable, enable debugging to console or to applet" },
{ "write_color", "0-15", "messages color" },
{ "font_name", "string", "font name" },
{ "font_size", "integer", "font size" },
{ "language", "string", "preferred language, or leave empty for auto-detect" },
{ "userid", "string", "some data to identify a web user server-side" },
{ "configuration", "string", "path/name of configuration file" }
};
public class COMClassObject
{
/* Documented bug at :
// http://support.microsoft.com/default.aspx?scid=kb;en-us;243771
//
// Empty class prevent MS's JVM
// to load a non-existant "<applet>$COMClassObject.class".
// Could save www errors log...
*/
}
}