Index: D:/L2J Workspace/L2_GameServer_CT1/java/config/irc.properties =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/config/irc.properties (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/config/irc.properties (revision 0) @@ -0,0 +1,41 @@ +# IRC Client Settings +# +# IRC BOT Functions +# !online - displays online player count +# !gmlist - displays the gmlist + +# Enable the Client +Enable = True + +# Server hostname/ip +Server = l2-eternal.de + +# Server Port +Port = 6667 + +# Use SSL +SSL = False + +# Password +Password = + +# Nickname +Nick = l2bot + +# User +User = l2 + +# Name +Name = l2 + +# Nickserv Support +Nickserv = False +NickservName = nickserv +NickservCommand = password + +# Optional Login Command +# example : LoginCommand : nickserv identify YourBotPassword +LoginCommand = + +# Channel +Channel = #L2Tube Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/Config.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/Config.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/Config.java (working copy) @@ -82,6 +82,8 @@ public static final String SIEGE_CONFIGURATION_FILE = "./config/siege.properties"; /** Properties file for telnet configuration */ public static final String TELNET_FILE = "./config/telnet.properties"; + /** Properties file for IRC configuration */ + public static final String IRC_FILE = "./config/irc.properties"; /******************************************************************************************************************************************************/ /** L2J Property File Definitions End Here**/ @@ -914,7 +916,30 @@ public static int NORMAL_CONNECTION_TIME; public static int FAST_CONNECTION_TIME; public static int MAX_CONNECTION_PER_IP; + + /** ************************************************** **/ + /** IRC Settings - Begin **/ + /** ************************************************** **/ + + public static boolean IRC_ENABLED; + public static boolean IRC_SSL; + public static String IRC_SERVER; + public static int IRC_PORT; + public static String IRC_PASS; + public static String IRC_NICK; + public static String IRC_USER; + public static String IRC_NAME; + public static boolean IRC_NICKSERV; + public static String IRC_NICKSERV_NAME; + public static String IRC_NICKSERV_COMMAND; + public static String IRC_LOGIN_COMMAND; + public static String IRC_CHANNEL; + + /** ************************************************** **/ + /** IRC Settings - END **/ + /** ************************************************** **/ + /** * This class initializes all global variables for configuration.
* If key doesn't appear in properties file, a default value is setting on by this class. @@ -1297,6 +1322,34 @@ e.printStackTrace(); throw new Error("Failed to Load "+ID_CONFIG_FILE+" File."); } + + // IRC + try + { + Properties ircSettings = new Properties(); + InputStream is = new FileInputStream(new File(IRC_FILE)); + ircSettings.load(is); + is.close(); + + IRC_ENABLED = Boolean.parseBoolean(ircSettings.getProperty("Enable", "false")); + IRC_SSL = Boolean.parseBoolean(ircSettings.getProperty("SSL", "false")); + IRC_SERVER = ircSettings.getProperty("Server", "localhost"); + IRC_PORT = Integer.parseInt(ircSettings.getProperty("Port", "6667")); + IRC_PASS = ircSettings.getProperty("Pass", "localhost"); + IRC_NICK = ircSettings.getProperty("Nick", "l2bot"); + IRC_USER = ircSettings.getProperty("User", "l2"); + IRC_NAME = ircSettings.getProperty("Name", "l2"); + IRC_NICKSERV = Boolean.parseBoolean(ircSettings.getProperty("NickServ", "false")); + IRC_NICKSERV_NAME = ircSettings.getProperty("NickservName", "nickserv"); + IRC_NICKSERV_COMMAND = ircSettings.getProperty("NickservCommand", ""); + IRC_LOGIN_COMMAND = ircSettings.getProperty("LoginCommand", ""); + IRC_CHANNEL = ircSettings.getProperty("Channel", "#mychan"); + } + catch (Exception e) + { + e.printStackTrace(); + throw new Error("Failed to Load "+IRC_FILE+" File."); + } // General Config File try Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/clientpackets/Say2.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/clientpackets/Say2.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/clientpackets/Say2.java (working copy) @@ -24,6 +24,7 @@ import net.sf.l2j.gameserver.datatables.MapRegionTable; import net.sf.l2j.gameserver.handler.IVoicedCommandHandler; import net.sf.l2j.gameserver.handler.VoicedCommandHandler; +import net.sf.l2j.gameserver.instancemanager.IrcManager; import net.sf.l2j.gameserver.instancemanager.PetitionManager; import net.sf.l2j.gameserver.model.BlockList; import net.sf.l2j.gameserver.model.L2World; @@ -225,6 +226,8 @@ player.sendPacket(cs); } } + if(Config.IRC_ENABLED) + IrcManager.getInstance().getConnection().sendChan("07!"+ activeChar.getName() +": " + _text); break; case TRADE: if (Config.DEFAULT_TRADE_CHAT.equalsIgnoreCase("on") || @@ -243,7 +246,9 @@ player.sendPacket(cs); } } - break; + if (Config.IRC_ENABLED) + IrcManager.getInstance().getConnection().sendChan("13+" + activeChar.getName() + ": " + _text); + break; case ALL: if (_text.startsWith(".")) { @@ -330,6 +335,10 @@ activeChar.sendMessage("Action failed. Heroes are only able to speak in the global channel once every 10 seconds."); return; } + if(Config.IRC_ENABLED) + { + IrcManager.getInstance().getConnection().sendChan("12%"+ activeChar.getName() +": " + _text); + } for (L2PcInstance player : L2World.getInstance().getAllPlayers()) if (!BlockList.isBlocked(player, activeChar)) player.sendPacket(cs); Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/network/L2IrcClient.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/network/L2IrcClient.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/network/L2IrcClient.java (revision 0) @@ -0,0 +1,382 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.network; + +import java.io.IOException; +import java.security.MessageDigest; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.StringTokenizer; +import java.util.logging.Logger; + +import javolution.util.FastMap; +import net.sf.l2j.Base64; +import net.sf.l2j.Config; +import net.sf.l2j.L2DatabaseFactory; +import net.sf.l2j.gameserver.GmListTable; +import net.sf.l2j.gameserver.LoginServerThread; +import net.sf.l2j.gameserver.handler.IIrcCommandHandler; +import net.sf.l2j.gameserver.handler.IrcCommandHandler; +import net.sf.l2j.gameserver.instancemanager.IrcManager; +import net.sf.l2j.gameserver.lib.irc.IRCConnection; +import net.sf.l2j.gameserver.lib.irc.IRCEventListener; +import net.sf.l2j.gameserver.lib.irc.IRCModeParser; +import net.sf.l2j.gameserver.lib.irc.IRCUser; +import net.sf.l2j.gameserver.model.L2World; +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; +import net.sf.l2j.gameserver.serverpackets.CreatureSay; +import net.sf.l2j.util.Rnd; + +public class L2IrcClient extends Thread +{ + protected final static Logger _log = Logger.getLogger(L2IrcClient.class.getName()); + + protected IRCConnection conn; + protected String channel; + protected String adminchan; + protected String nickname; + protected FastMap _authedGms = new FastMap(); + + public L2IrcClient(String host, int port, String pass, String nick, String user, String name, boolean ssl, String Chan) + { + conn = new IRCConnection(host, new int[] { port }, pass, nick, user, name); + channel = Chan; + nickname = nick; + adminchan = channel+"Admin"; + conn.addIRCEventListener(new Listener()); + conn.setEncoding("UTF-8"); + conn.setPong(true); + conn.setDaemon(false); + conn.setColors(false); + start(); + } + + public void connect() throws IOException + { + if (!conn.isConnected()) + { + conn.connect(); + conn.send("JOIN " + channel); + conn.send("JOIN " + adminchan); + setDaemon(true); + } + } + + public void disconnect() + { + if (conn.isConnected()) + { + //conn.close(); + //IrcManager.getInstance().removeConnection(); + conn.doQuit(); + conn.setDaemon(false); + } + } + + public void send(String Text) + { + if (checkConnection()) + conn.send(Text); + } + + public void send(String target, String Text) + { + if (checkConnection()) + conn.doPrivmsg(target, Text); + } + + public void sendChan(String Text) + { + if (checkConnection()) + { + conn.doPrivmsg(channel, Text); + } + } + + public void sendAdminChan(String Text) + { + if(checkConnection()) + { + conn.doPrivmsg(adminchan, Text); + } + } + + public boolean checkConnection() + { + if (!conn.isConnected()) + { + try + { + IrcManager.getInstance().reConnect(); + } + catch (Exception exc) + { + exc.printStackTrace(); + } + } + return conn.isConnected(); + } + + /** + * Treats IRC events. + */ + public class Listener implements IRCEventListener + { + private boolean isconnected; + + public void onRegistered() + { + _log.info("IRC: Connected"); + if (!Config.IRC_LOGIN_COMMAND.trim().equals("")) + send(Config.IRC_LOGIN_COMMAND.trim()); + if (Config.IRC_NICKSERV) + send(Config.IRC_NICKSERV_NAME, Config.IRC_NICKSERV_COMMAND); + isconnected = true; + } + + public void onDisconnected() + { + _log.info("IRC: Disconnected"); + isconnected = false; + IrcManager.getInstance().reConnect(); + } + + public void onError(String msg) + { + _log.info("IRC: Error: " + msg); + } + + public void onError(int num, String msg) + { + _log.info("IRC: Error #" + num + ": " + msg); + // nickname already in use + if (num == 433) + { + Integer random = Rnd.get(999); + send("NICK " + nickname + random); + send("JOIN " + channel); + send("JOIN " + adminchan); + } + } + + public void onInvite(String chan, IRCUser u, String nickPass) + { + } + + public void onJoin(String chan, IRCUser u) + { + } + + public void onKick(String chan, IRCUser u, String nickPass, String msg) + { + } + + public void onMode(IRCUser u, String nickPass, String mode) + { + } + + public void onMode(String chan, IRCUser u, IRCModeParser mp) + { + } + + public void onNick(IRCUser u, String nickNew) + { + removeAccount(u.getUsername(),u.getHost()); + } + + public void onNotice(String target, IRCUser u, String msg) + { + } + + public void onPart(String chan, IRCUser u, String msg) + { + removeAccount(u.getUsername(),u.getHost()); + } + + public void onPrivmsg(String chan, IRCUser u, String msg) + { + if (msg.equals("!online")) + { + double onl = L2World.getInstance().getAllPlayersCount(); + double onlshown = Math.round(((onl/100)*35)+onl); + sendChan("Online Players: " + (int)onlshown + " / " + LoginServerThread.getInstance().getMaxPlayer()); + sendAdminChan("Online Players: " + (int)onl + " / " + LoginServerThread.getInstance().getMaxPlayer()); + } + else if (msg.equals("!gmlist")) + { + if (GmListTable.getInstance().getAllGms(false).size() <= 0) + sendChan("There are not any GMs that are providing customer service currently"); + else + for (L2PcInstance gm : GmListTable.getInstance().getAllGms(false)) + sendChan(gm.getName()); + } + else if (chan.equalsIgnoreCase(channel)) + { + CreatureSay cs = new CreatureSay(0, 1, "[IRC]" + u.getNick(), msg); + for (L2PcInstance player : L2World.getInstance().getAllPlayers()) + { + player.sendPacket(cs); + } + } + else if (chan.equalsIgnoreCase(adminchan)) + { + if (msg.startsWith("!")) + { + IIrcCommandHandler ircch = IrcCommandHandler.getInstance().getIrcCommandHandler(msg); + + if (ircch != null) + ircch.useIrcCommand(msg, u.getNick(), null, _authedGms.containsKey(u.getUsername())); + } + else + { + CreatureSay cs = new CreatureSay(0, 1, "[IRC]" + u.getNick(), msg); + for (L2PcInstance player : L2World.getInstance().getAllPlayers()) + { + player.sendPacket(cs); + } + } + } + else + { + if (msg.startsWith("ident")) + { + StringTokenizer st = new StringTokenizer(msg); + st.nextToken(); + try + { + String username = st.nextToken(); + String password = st.nextToken(); + isAccountValid(username,password,u.getUsername(),u.getNick(),u.getHost()); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + } + } + + public void onQuit(IRCUser u, String msg) + { + removeAccount(u.getUsername(),u.getHost()); + } + + public void onReply(int num, String value, String msg) + { + } + + public void onTopic(String chan, IRCUser u, String topic) + { + } + + public void onPing(String p) + { + // keep connection alive + conn.doPong(p); + } + + public void unknown(String a, String b, String c, String d) + { + _log.warning("IRC UNKNOWN: " + a + " b " + c + " " + d); + } + + public boolean isConnected() + { + return isconnected; + } + } + + protected void isAccountValid(String account,String password,String ident,String nick,String ip) + { + boolean ok = false; + java.sql.Connection con = null; + try + { + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] raw = password.getBytes("UTF-8"); + byte[] hash = md.digest(raw); + byte[] expected = null; + int access = 0; + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement = con.prepareStatement("SELECT password, access_level FROM irc WHERE login=?"); + statement.setString(1, account); + ResultSet rset = statement.executeQuery(); + if (rset.next()) + { + expected = Base64.decode(rset.getString("password")); + access = rset.getInt("access_level"); + } + rset.close(); + statement.close(); + + if (expected == null) + return; + else + { + if (access <= 0) + return; + + ok = true; + for (int i = 0; i < expected.length; i++) + { + if (hash[i] != expected[i]) + { + ok = false; + break; + } + } + } + if (ok) + { + if (!_authedGms.containsKey(ident)) + { + _authedGms.put(ident, ip); + send(nick,"Successfully Authed!"); + } + else + { + send(nick,"Already Authed!"); + } + + } + else + { + send(nick,"Authentication Failed!"); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + con.close(); + } + catch (Exception e) + { + } + } + } + + protected void removeAccount(String nick,String ip) + { + if (_authedGms.containsKey(nick)) + _authedGms.remove(nick); + else if (_authedGms.containsValue(ip)) + _authedGms.remove(ip); + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Shutdown.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Shutdown.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Shutdown.java (working copy) @@ -300,11 +300,11 @@ public void startShutdown(L2PcInstance activeChar, int seconds, boolean restart) { _log.warning("GM: "+activeChar.getName()+"("+activeChar.getObjectId()+") issued shutdown command. " + MODE_TEXT[_shutdownMode] + " in "+seconds+ " seconds!"); - if (restart) { + if (restart) _shutdownMode = GM_RESTART; - } else { + else _shutdownMode = GM_SHUTDOWN; - } + if(_shutdownMode > 0) { @@ -342,12 +342,74 @@ } /** + * This functions starts a shutdown countdown + * + * @param activeChar GM who issued the shutdown command + * @param seconds seconds until shutdown + * @param restart true if the server will restart after shutdown + */ + public void startShutdown(String activeChar, int seconds, boolean restart) + { + _log.warning("GM: "+activeChar+" issued shutdown command. " + MODE_TEXT[_shutdownMode] + " in "+seconds+ " seconds!"); + + if (restart) + _shutdownMode = GM_RESTART; + else + _shutdownMode = GM_SHUTDOWN; + + if(_shutdownMode > 0) + { + switch (seconds) + { + case 540: + case 480: + case 420: + case 360: + case 300: + case 240: + case 180: + case 120: + case 60: + case 30: + case 10: + case 5: + case 4: + case 3: + case 2: + case 1: + break; + default: + SendServerQuit(seconds); + } + } + + if (_counterInstance != null) + _counterInstance._abort(); + + // the main instance should only run for shutdown hook, so we start a new instance + _counterInstance = new Shutdown(seconds, restart); + _counterInstance.start(); + } + + /** * This function aborts a running countdown * * @param activeChar GM who issued the abort command */ - public void abort(L2PcInstance activeChar) { + public void abort(L2PcInstance activeChar) + { _log.warning("GM: "+activeChar.getName()+"("+activeChar.getObjectId()+") issued shutdown ABORT. " + MODE_TEXT[_shutdownMode] + " has been stopped!"); + if (_counterInstance != null) + { + _counterInstance._abort(); + Announcements _an = Announcements.getInstance(); + _an.announceToAll("Server aborts " + MODE_TEXT[_shutdownMode] + " and continues normal operation!"); + } + } + + public void abort(String activeChar) + { + _log.warning("GM: "+activeChar+" issued shutdown ABORT. " + MODE_TEXT[_shutdownMode] + " has been stopped!"); if (_counterInstance != null) { _counterInstance._abort(); Announcements _an = Announcements.getInstance(); Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Announcements.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Announcements.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Announcements.java (working copy) @@ -30,6 +30,7 @@ import net.sf.l2j.Config; import net.sf.l2j.gameserver.cache.HtmCache; import net.sf.l2j.gameserver.clientpackets.Say2; +import net.sf.l2j.gameserver.instancemanager.IrcManager; import net.sf.l2j.gameserver.model.L2World; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; import net.sf.l2j.gameserver.network.SystemMessageId; @@ -207,15 +208,19 @@ } } - public void announceToAll(String text) { + public void announceToAll(String text) + { CreatureSay cs = new CreatureSay(0, Say2.ANNOUNCEMENT, "", text); for (L2PcInstance player : L2World.getInstance().getAllPlayers()) { player.sendPacket(cs); } + if(Config.IRC_ENABLED) + IrcManager.getInstance().getConnection().sendChan("10Announce: " + text); } - public void announceToAll(SystemMessage sm) { + public void announceToAll(SystemMessage sm) + { for (L2PcInstance player : L2World.getInstance().getAllPlayers()) { Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/model/GMAudit.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/model/GMAudit.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/model/GMAudit.java (working copy) @@ -23,6 +23,7 @@ import java.util.logging.Logger; import net.sf.l2j.Config; +import net.sf.l2j.gameserver.instancemanager.IrcManager; import net.sf.l2j.gameserver.lib.Log; public class GMAudit @@ -58,6 +59,8 @@ { _log.log(Level.SEVERE, "GMAudit for GM " + gmName +" could not be saved: ", e); } + if (Config.IRC_ENABLED) + IrcManager.getInstance().getConnection().sendAdminChan(today + ">" + gmName + ">" + action + ">" +target + ">" + params); } } } Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCModeParser.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCModeParser.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCModeParser.java (revision 0) @@ -0,0 +1,293 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCModeParser + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. ++ */ +package net.sf.l2j.gameserver.lib.irc; + +/** + * Parses channel-modes. + *

+ * An instance of this class is an argument of the {@link + * org.schwering.irc.lib.IRCEventListener#onMode(String chan, IRCUser user, + * IRCModeParser modeParser)}. + * It's intended to help the programmer to work with the modes. + *

+ * Channelmodes are: + *

    + *
  • +/- o nick
  • + *
  • +/- v nick
  • + *
  • +/- b banmask
  • + *
  • +/- l limit
  • + *
  • +/- k key
  • + *
  • +/- p
  • + *
  • +/- s
  • + *
  • +/- i
  • + *
  • +/- t
  • + *
  • +/- n
  • + *
  • +/- m
  • + *
+ *

+ * These are all channel-modes defined in RFC1459. Nevertheless, most networks + * provide more channel-modes. This class can handle all modes; it's not + * restricted to the rights defined in RFC1459. + * + * @author Christoph Schwering <schwering@gmail.com> + * @version 1.22 + * @see IRCEventListener + */ +public class IRCModeParser +{ + /** + * Represents the operators, modes and nicks as they were sent from the IRC + * server. + */ + private String _line; + + /** + * Contains pluses (+) and minuses (-) + * which show if the mode is taken or given. + */ + private char[] operatorsArr; + + /** + * This array contains the modes that are set with the operator of the + * operatorsArr-array. * + */ + private char[] modesArr; + + /** + * Represents the parsed nicks, hostnames, limits or keys in an array of + * Strings. + */ + private String[] argsArr; + + // ------------------------------ + /** + * Analyzes the modes and parses them into the parts operators (+ + * or -), modes (one character) and optional arguments (one + * word or number). + * + * @param line + * The modes and the arguments; nothing more. + */ + public IRCModeParser(String line) + { + line = line.trim(); + this._line = line; + int index = line.indexOf(' '); + if (index >= 2) + { // with arguments + String modes = line.substring(0, index); + String args = line.substring(index + 1); + parse(modes, args); // call real constructor. + } + else if (line.length() >= 2) + { // no arguments + String modes = line; + String args = ""; + parse(modes, args); + } + else + { // nothing + argsArr = new String[0]; + operatorsArr = new char[0]; + modesArr = new char[0]; + } + } + + // ------------------------------ + /** + * Analyzes the modes and parses them into the parts operators (+ + * or -), modes (one character) and optional arguments (one + * word or number). + * + * @param modes + * The modes (for example +oo+m-v). + * @param args + * The modes' arguments (for example Heinz Hans + * Thomas). + */ + public IRCModeParser(String modes, String args) + { + _line = modes + " " + args; + parse(modes, args); + } + + // ------------------------------ + /** + * Parses the modes into two char-arrays and one + * String-array.
+ * The first one contains the operator of the mode (+ or + * -) and the second one the mode (w, + * i, s, o or any other + * mode). The String[] contains the nicknames. + * + * @param modes + * The modes (for example +oo+m-v). + * @param args + * The modes' arguments (for example Heinz Hans Thomas). + */ + private void parse(String modes, String args) + { + String[] argsTmp = IRCUtil.split(args, ' '); + int modesLen = modes.length(); + int modesCount = getModesCount(modes); + char c; + char operator = '+'; // any value cause it must be initialized + operatorsArr = new char[modesCount]; + modesArr = new char[modesCount]; + argsArr = new String[modesCount]; + // parse and fill the arrays + for (int i = 0, j = 0, n = 0; i < modesLen; i++) + { + c = modes.charAt(i); + if (c == '+' || c == '-') + { + operator = c; + } + else + { + // add the operator (which was found earlier in the loop) + operatorsArr[n] = operator; + modesArr[n] = c; // add the mode + if ((c == 'o' || c == 'v' || c == 'b' || c == 'k') // come with + // arg + || (c == 'l' && operator == '+')) + { // key comes with arg if '+' + argsArr[n] = (j < argsTmp.length) ? argsTmp[j++] : ""; + } + else + { + argsArr[n] = ""; // null if mode has no argument (for + // example m, p, s) + } + n++; // increase n, not i. n is used to fill the arrays + } + } + } + + // ------------------------------ + /** + * Returns the amount of modes in the string. This is done by counting all + * chars which are not + or -. + * + * @param modes + * The modes which are to analyze. + * @return The count of modes without operators. + */ + private int getModesCount(String modes) + { + int count = 0; + for (int i = 0, c, len = modes.length(); i < len; i++) + if ((c = modes.charAt(i)) != '+' && c != '-') + count++; + return count; + } + + // ------------------------------ + /** + * Returns count of modes. + * + * @return The count of modes. + * @see #getOperatorAt(int) + * @see #getModeAt(int) + * @see #getArgAt(int) + */ + public int getCount() + { + return operatorsArr.length; + } + + // ------------------------------ + /** + * Returns the operator (+ or -) of a given + * index. + * + * @param i + * The index of the operator you want to get. The index starts + * with 1 and not with 0. + * @return The operator at the given index (+ or + * -). + * @see #getCount() + * @see #getModeAt(int) + * @see #getArgAt(int) + */ + public char getOperatorAt(int i) + { + return operatorsArr[i - 1]; + } + + // ------------------------------ + /** + * Returns the mode (for example o, v, + * m, i) of a given index. + * + * @param i + * The index of the mode you want to get. The index starts with + * 1 and not with 0. + * @return The mode of the given index (for example o, + * v, m, i) + * @see #getCount() + * @see #getOperatorAt(int) + * @see #getArgAt(int) + */ + public char getModeAt(int i) + { + return modesArr[i - 1]; + } + + // ------------------------------ + /** + * Returns the nick of a given index. + * + * @param i + * The index of the argument you want to get. The index starts + * with 1 and not with 0. + * @return The argument you requested. It's "" if there's no + * argument at this index (for example +m for + * moderated has never an argument). + * @see #getCount() + * @see #getOperatorAt(int) + * @see #getModeAt(int) + */ + public String getArgAt(int i) + { + return argsArr[i - 1]; + } + + // ------------------------------ + /** + * Returns the line as it was sent from the IRC server. The line contains + * the the operators, the modes and the nicknames, but not the channel or + * the nickname who executed the MODE command! + * + * @return The line which was set as argument when the parser was + * initialized. + */ + public String getLine() + { + return _line; + } + + // ------------------------------ + /** + * Generates a String with some information about the + * instance of IRCModeParser. Its format is: + * classname[line]. + * + * @return A String with information about the instance. + */ + @Override + public String toString() + { + return getClass().getName() + "[" + getLine() + "]"; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventAdapter.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventAdapter.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventAdapter.java (revision 0) @@ -0,0 +1,301 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCEventAdapter + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + */ + +package net.sf.l2j.gameserver.lib.irc; + +/** + * Adapts the events of the IRCEventListener interface. + *

+ * Supported events: + *

    + *
  • Connect
  • + *
  • Disconnect
  • + *
  • Error
  • + *
  • Invite
  • + *
  • Join
  • + *
  • Kick
  • + *
  • Private Message
  • + *
  • Mode (Chan)
  • + *
  • Mode (User)
  • + *
  • Nick
  • + *
  • Notice
  • + *
  • Numeric Reply
  • + *
  • Numeric Error
  • + *
  • Part
  • + *
  • Ping
  • + *
  • Quit
  • + *
  • Topic
  • + *
+ *

+ * For other, unkown events there's the unknown-method. + * @author Christoph Schwering <schwering@gmail.com> + * @version 1.63 + * @see IRCEventListener + */ +public class IRCEventAdapter implements IRCEventListener { + + /** + * The default and only constructor does nothing. + */ + public IRCEventAdapter() { + // nothing + } + +// ------------------------------ + + /** + * Fired when the own connection is successfully established. + * This is the case when the first PING? is received.
+ * This happens between the connection is opened with a socket and the + * connection is registered: The client sends his information to the server + * (nickname, username). The server says hello to you by sending you + * some NOTICEs. And if your nickname is invalid or in use or + * anything else is wrong with your nickname, it asks you for a new one. + */ + public void onRegistered() { + // nothing + } + +// ------------------------------ + + /** + * Fired when the own connection is broken. + */ + public void onDisconnected() { + // nothing + } + +// ------------------------------ + + /** + * Fired when an ERROR command is received. + * @param msg The message of the error. + */ + public void onError(String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when a numeric error is received. + * The server often sends numeric errors (wrong nickname etc.). + * The msg's format is different for every reply. All replies' + * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. + * @param num The identifier (usually a 3-digit number). + * @param msg The message of the error. + */ + public void onError(int num, String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody is invited to a channel. + * @param chan The channel the user is invited to. + * @param user The user who invites another. Contains nick, username and host. + * @param passiveNick The nickname of the user who is invited by another user + * (passive). + */ + public void onInvite(String chan, IRCUser user, String passiveNick) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody joins a channel. + * @param chan The channel the person joins. + * @param user The user who joins. Contains nick, username and host. + */ + public void onJoin(String chan, IRCUser user) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody is kicked from a channel. + * @param chan The channel somebody is kicked from. + * @param user The user who kicks another user from a channel. + * Contains nick, username and host. + * @param passiveNick The nickname of the user who is kicked from a channel + * (passive). + * @param msg The message the active user has set. This is "" if + * no message was set. + */ + public void onKick(String chan, IRCUser user, String passiveNick, + String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when an operator changes the modes of a channel. + * For example, he can set somebody as an operator, too, or take him the + * oper-status. + * Also keys, moderated and other channelmodes are fired here. + * @param chan The channel in which the modes are changed. + * @param user The user who changes the modes. + * Contains nick, username and host. + * @param modeParser The IRCModeParser object which contains the + * parsed information about the modes which are changed. + */ + public void onMode(String chan, IRCUser user, IRCModeParser modeParser) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody changes somebody's usermodes. + * Note that this event is not fired when a channel-mode is set, for example + * when someone sets another user as operator or the mode moderated. + * @param user The user who changes the modes of another user or himself. + * Contains nick, username and host. + * @param passiveNick The nickname of the person whose modes are changed by + * another user or himself. + * @param mode The changed modes which are set. + */ + public void onMode(IRCUser user, String passiveNick, String mode) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody changes his nickname successfully. + * @param user The user who changes his nickname. + * Contains nick, username and host. + * @param newNick The new nickname of the user who changes his nickname. + */ + public void onNick(IRCUser user, String newNick) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody sends a NOTICE to a user or a group. + * @param target The channel or nickname the user sent a NOTICE + * to. + * @param user The user who notices another person or a group. + * Contains nick, username and host. + * @param msg The message. + */ + public void onNotice(String target, IRCUser user, String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody parts from a channel. + * @param chan The channel somebody parts from. + * @param user The user who parts from a channel. + * Contains nick, username and host. + * @param msg The part-message which is optionally. + * If it's empty, msg is "". + */ + public void onPart(String chan, IRCUser user, String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when a PING comes in. + * The IRC server tests in different periods if the client is still there by + * sending PING <ping>. The client must response PONG <ping>. + * @param ping The ping which is received from the server. + */ + public void onPing(String ping) { + // nothing + } + +// ------------------------------ + + /** + * Fired when a user sends a PRIVMSG to a user or to a + * group. + * @param target The channel or nickname the user sent a PRIVMSG + * to. + * @param user The user who sent the PRIVMSG. + * Contains nick, username and host. + * @param msg The message the user transmits. + */ + public void onPrivmsg(String target, IRCUser user, String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when somebody quits from the network. + * @param user The user who quits. Contains nick, username and host. + * @param msg The optional message. "" if no message is set by + * the user. + */ + public void onQuit(IRCUser user, String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when a numeric reply is received. + * For example, WHOIS queries are answered by the server with + * numeric replies. + * The msg's format is different for every reply. All replies' + * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. + * The first word in the value is always your own nickname! + * @param num The numeric reply. + * @param value The first part of the message. + * @param msg The main part of the message. + */ + public void onReply(int num, String value, String msg) { + // nothing + } + +// ------------------------------ + + /** + * Fired when the topic is changed by operators. + * Note that the topic is given as a numeric reply fired in + * onReply when you join a channel. + * @param chan The channel where the topic is changed. + * @param user The user who changes the topic. + * Contains nick, username and host. + * @param topic The new topic. + */ + public void onTopic(String chan, IRCUser user, String topic) { + // nothing + } + +// ------------------------------ + + /** + * This event is fired when the incoming line can not be identified as a known + * event. + * @param prefix The prefix of the incoming line. + * @param command The command of the incoming line. + * @param middle The part until the colon (:). + * @param trailing The part behind the colon (:). + */ + public void unknown(String prefix, String command, String middle, + String trailing) { + // nothing + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventListener.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventListener.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventListener.java (revision 0) @@ -0,0 +1,264 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCEventListener + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. +*/ + +package net.sf.l2j.gameserver.lib.irc; + +import java.util.EventListener; + +/** + * Used as listener for incoming events like messages. + *

+ * The IRCEventListener is used by the + * IRCConnection.addEventListener(IRCEventListener) method to add + * a listener which listens to the connection for incoming IRC events like ++ * PRIVMSGs or numeric replies. + *

+ * Supported events: + *

    + *
  • Connect
  • + *
  • Disconnect
  • + *
  • Error
  • + *
  • Invite
  • + *
  • Join
  • + *
  • Kick
  • + *
  • Private Message
  • + *
  • Mode (Chan)
  • + *
  • Mode (User)
  • + *
  • Nick
  • + *
  • Notice
  • + *
  • Numeric Reply
  • + *
  • Numeric Error
  • + *
  • Part
  • + *
  • Ping
  • + *
  • Quit
  • + *
  • Topic
  • + *
+ *

+ * For other, unkown events there's the unknown-method. + * @author Christoph Schwering <schwering@gmail.com> + * @version 1.64 + * @see IRCEventAdapter + * @see IRCConnection + */ +public interface IRCEventListener extends EventListener, IRCConstants { + + /** + * Fired when the own connection is successfully established. + * This is the case when the first PING? is received.
+ * This happens between the connection is opened with a socket and the + * connection is registered: The client sends his information to the server + * (nickname, username). The server says hello to you by sending you + * some NOTICEs. And if your nickname is invalid or in use or + * anything else is wrong with your nickname, it asks you for a new one. + */ + public void onRegistered(); + +// ------------------------------ + + /** + * Fired when the own connection is broken. + */ + public void onDisconnected(); + +// ------------------------------ + + /** + * Fired when an ERROR command is received. + * @param msg The message of the error. + */ + public void onError(String msg); + +// ------------------------------ + + /** + * Fired when a numeric error is received. + * The server often sends numeric errors (wrong nickname etc.). + * The msg's format is different for every reply. All replies' + * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. + * @param num The identifier (usually a 3-digit number). + * @param msg The message of the error. + */ + public void onError(int num, String msg); + +// ------------------------------ + + /** + * Fired when somebody is invited to a channel. + * @param chan The channel the user is invited to. + * @param user The user who invites another. Contains nick, username and host. + * @param passiveNick The nickname of the user who is invited by another user + * (passive). + */ + public void onInvite(String chan, IRCUser user, String passiveNick); + +// ------------------------------ + + /** + * Fired when somebody joins a channel. + * @param chan The channel the person joins. + * @param user The user who joins. Contains nick, username and host. + */ + public void onJoin(String chan, IRCUser user); + +// ------------------------------ + + /** + * Fired when somebody is kicked from a channel. + * @param chan The channel somebody is kicked from. + * @param user The user who kicks another user from a channel. + * Contains nick, username and host. + * @param passiveNick The nickname of the user who is kicked from a channel + * (passive). + * @param msg The message the active user has set. This is "" if + * no message was set. + */ + public void onKick(String chan, IRCUser user, String passiveNick, String msg); + +// ------------------------------ + + /** + * Fired when an operator changes the modes of a channel. + * For example, he can set somebody as an operator, too, or take him the + * oper-status. + * Also keys, moderated and other channelmodes are fired here. + * @param chan The channel in which the modes are changed. + * @param user The user who changes the modes. + * Contains nick, username and host. + * @param modeParser The IRCModeParser object which contains the + * parsed information about the modes which are changed. + */ + public void onMode(String chan, IRCUser user, IRCModeParser modeParser); + +// ------------------------------ + + /** + * Fired when somebody changes somebody's usermodes. + * Note that this event is not fired when a channel-mode is set, for example + * when someone sets another user as operator or the mode moderated. + * @param user The user who changes the modes of another user or himself. + * Contains nick, username and host. + * @param passiveNick The nickname of the person whose modes are changed by + * another user or himself. + * @param mode The changed modes which are set. + */ + public void onMode(IRCUser user, String passiveNick, String mode); + +// ------------------------------ + + /** + * Fired when somebody changes his nickname successfully. + * @param user The user who changes his nickname. + * Contains nick, username and host. + * @param newNick The new nickname of the user who changes his nickname. + */ + public void onNick(IRCUser user, String newNick); + +// ------------------------------ + + /** + * Fired when somebody sends a NOTICE to a user or a group. + * @param target The channel or nickname the user sent a NOTICE + * to. + * @param user The user who notices another person or a group. + * Contains nick, username and host. + * @param msg The message. + */ + public void onNotice(String target, IRCUser user, String msg); + +// ------------------------------ + + /** + * Fired when somebody parts from a channel. + * @param chan The channel somebody parts from. + * @param user The user who parts from a channel. + * Contains nick, username and host. + * @param msg The part-message which is optionally. + * If it's empty, msg is "". + */ + public void onPart(String chan, IRCUser user, String msg); + +// ------------------------------ + + /** + * Fired when a PING comes in. + * The IRC server tests in different periods if the client is still there by + * sending PING <ping>. The client must response PONG <ping>. + * @param ping The ping which is received from the server. + */ + public void onPing(String ping); + +// ------------------------------ + + /** + * Fired when a user sends a PRIVMSG to a user or to a + * group. + * @param target The channel or nickname the user sent a PRIVMSG + * to. + * @param user The user who sent the PRIVMSG. + * Contains nick, username and host. + * @param msg The message the user transmits. + */ + public void onPrivmsg(String target, IRCUser user, String msg); + +// ------------------------------ + + /** + * Fired when somebody quits from the network. + * @param user The user who quits. Contains nick, username and host. + * @param msg The optional message. "" if no message is set by + * the user. + */ + public void onQuit(IRCUser user, String msg); + +// ------------------------------ + + /** + * Fired when a numeric reply is received. + * For example, WHOIS queries are answered by the server with + * numeric replies. + * The msg's format is different for every reply. All replies' + * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. + * The first word in the value is always your own nickname! + * @param num The numeric reply. + * @param value The first part of the message. + * @param msg The main part of the message. + */ + public void onReply(int num, String value, String msg); + +// ------------------------------ + + /** + * Fired when the topic is changed by operators. + * Note that the topic is given as a numeric reply fired in + * onReply when you join a channel. + * @param chan The channel where the topic is changed. + * @param user The user who changes the topic. + * Contains nick, username and host. + * @param topic The new topic. + */ + public void onTopic(String chan, IRCUser user, String topic); + +// ------------------------------ + + /** + * This event is fired when the incoming line can not be identified as a known + * event. + * @param prefix The prefix of the incoming line. + * @param command The command of the incoming line. + * @param middle The part until the colon (:). + * @param trailing The part behind the colon (:). + */ + public void unknown(String prefix, String command, String middle, + String trailing); + +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCParser.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCParser.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCParser.java (revision 0) @@ -0,0 +1,559 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCParser + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + */ + +package net.sf.l2j.gameserver.lib.irc; + +/** + * Parses a line sent from the IRC server. + *

+ * Note: Probably this class is unimportant for you. It's used by the + * IRCConnection to parse incoming lines. Nevertheless I declared + * it as public because you might want to use it to parse IRC + * command-shortcuts like MSG instead of PRIVMSG in + * your client.
+ * The following text goes on with the description of the class and what it + * does. + *

+ * According with RFC1459 it divides the line into a prefix, a command and + * its parameters. + *

+ * The prefix is only given if a line starts with a : (colon) + * and is used to indicate from where the line is send. + *

+ * The next word in the line (if no prefix exists it is the first, else the + * second word) is the command. + * The command is eiter a valid IRC command or a three-digit number which + * represents a numeric reply or a numeric error. + *

+ * The parameters are divided into a middle and a trailing part. + * In the middle part one word means one parameter while the trailing part is + * just one parameter independent from the amount of words in it. + * If there is a " :" (space+colon) in the line, this point + * means the beginning of the trailing. + * If there is no such space+colon, the trailing is just the last word. + * All words behind the space+colon mean just one parameter. + * If there is only one parameter given (the parameter is the first, the last + * and the only one), the parameter is available as trailing (with + * getTrailing), not as middle! + *

+ * One line may have up to 15 parameters. Therefore up to 14 are middle and + * one is the trailing. + *

+ * The line may have up to 510 characters plus the CR-LF (carriage return - + * line feed) which trails the incoming line. + *

+ * The following extract of the RFC1459 shows the message format in BNF: + *

+ * <message>  ::= + * [':' <prefix> <SPACE> ] <command> <params> + * <crlf>
+ * <prefix>   ::= + * <servername> | <nick> + * [ '!' <username> ] [ '@' <host> ] + *
+ * <command>  ::= + * <letter> { <letter> } | <number> <number> + * <number>
+ * <SPACE>    ::= + * ' ' { ' ' }
+ * <params>   ::= + * <SPACE> [ ':' <trailing> | <middle> <params> ]
+ * <middle>   ::= + * <Any *non-empty* sequence of octets not including SPACE or NUL or CR or + * LF, the first of which may not be ':'>
+ * <trailing> ::= + * <Any, possibly *empty*, sequence of octets not including NUL or CR or + * LF>
++ * <crlf>     ::= ++ * CR LF
++ *
++ * @author Christoph Schwering <schwering@gmail.com> ++ * @version 3.22 ++ * @see IRCConnection ++ */ +public class IRCParser { + + /** + * The StringBuffer contains the line which was analyzed. + */ + private StringBuffer buf; + + /** + * The length of the line. + */ + private int len; + + /** + * The prefix, which is parsed out in the constructor. + */ + private String prefix; + + /** + * The command, which is parsed out in the constructor. + */ + private String command; + + /** + * The middle, which is parsed out in the constructor. + */ + private String middle; + + /** + * The trailing, which is parsed out in the constructor. The trailing is the + * part behind the colon (:) or the last parameter. + */ + private String trailing; + + /** + * The parameters' array. It's not initialized in the constructor because of + * rare access. The methods which use and need this parameter-array + * (getParametersCount, getParameter, getParameterFrom etc.) initialize this + * array by calling initParameters, if the array isn't initialized yet. + */ + private String[] parameters; + +// ------------------------------ + + /** + * Parses the line after erasing all mIRC color codes. + * This constructor is a shorthand for IRCParser(line, false). + * @param line The line which will be parsed. + */ + public IRCParser(String line) { + this(line, false); + } + +// ------------------------------ + + /** + * The main constructor. + * Parses prefix, command, middle and trailing. + * @param line The line which will be parsed. + * @param colorsEnabled If false, mIRC color codes are parsed out + * by using IRCUtil.parseColors method. + */ + public IRCParser(String line, boolean colorsEnabled) { + int index = 0; + int trail; + + buf = new StringBuffer(line); + if (!colorsEnabled) + buf = IRCUtil.parseColors(buf); + len = buf.length(); + + // prefix + if (buf.charAt(0) == ':') { + prefix = buf.substring(1, (index = indexOf(' ', index))); + index++; + } + + while (buf.charAt(index) == ' ') + index++; + + // command + command = buf.substring(index, ((index = indexOf(' ', index)) != -1) + ? index : (index = len)); + + while (index < len && buf.charAt(index) == ' ') + index++; + index--; + + // middle & trailing + if ((trail = indexOf(" :", index)) != -1) + trailing = buf.substring(trail + 2, len); + else if ((trail = lastIndexOf(' ')) != -1 && trail >= index) + trailing = buf.substring(trail + 1, len); + middle = (index < trail) ? buf.substring(index + 1, trail) : ""; + + // save + prefix = (prefix != null) ? prefix : ""; + command = (command != null) ? command : ""; + middle = (middle != null) ? middle : ""; + trailing = (trailing != null) ? trailing : ""; + } + +// ------------------------------ + + /** + * Searches for a char in the StringBuffer buf from a given index + * and returns its index. + * @param c The char to search. + * @param i The index the method will start searching at. + * @return The index of the searched char. + */ + private int indexOf(int c, int i) { + while (i < len) + if (buf.charAt(i++) == c) + return --i; + return -1; + } + +// ------------------------------ + + /** + * Searches for a string in the StringBuffer buf from a given + * index and returns its beginning index. + * @param str The string to search. + * @param i The index the method will start searching at. + * @return The index of the searched string. + */ + private int indexOf(String str, int i) { + int sublen = str.length(); + int index = -1; + int j; + for ( ; i < len; i++) + for (index = i, j = 0; i < len && j < sublen; i++, j++) + if (buf.charAt(i) != str.charAt(j)) + break; + else if (j + 1 == sublen) + return index; + return -1; + } + +// ------------------------------ + + /** + * Searches for a given char in the StringBuffer buf.
+ * It starts at the end.
+ * Note: The method expects a character which is not c before + * it can return an index. Thus in a string like "nick moor   + *   " with four trailing spaces + * lastIndexOf(' ') does not return the the index of the last + * space. It first waits for characters which are not a space (r, o, o, m) and + * then returns the index of the next space: the space between + * nick and moor. By this, also in lines with ++ * trailing whitespace the trailing-part is correctly recognized. + * @param c The char to search. + * @return The last index of the searched char. + */ + private int lastIndexOf(int c) { + int i = len; + boolean ok = false; + while (i > 0) + if (buf.charAt(--i) != c) + ok = true; + else if (ok) + return i; + return -1; + } + +// ------------------------------ + + /** + * Initializes the parameters[]. + * This method is called by getParam, getParamFrom + * and getParamTo, if the parameters[] aren't + * initialized yet.
+ * The method splits the middle into all words using and appends + * the trailing as last parameter. It uses the IRCUtil.split + * method. + */ + private void initParameters() { + parameters = IRCUtil.split(middle, ' ', trailing); + } + +// ------------------------------ + + /** + * Returns the line's prefix. A prefix is the part which contains information + * about the sender of the line. If no prefix is set, "" is + * returned; but in fact there's always a prefix. + * @return The line's prefix. + */ + public String getPrefix() { + return prefix; + } + +// ------------------------------ + + /** + * Returns the line's command. + * @return The line's command. + */ + public String getCommand() { + return command; + } + +// ------------------------------ + + /** + * Returns the line's middle. + * @return The line's middle. + */ + public String getMiddle() { + return middle; + } + +// ------------------------------ + + /** + * Returns the line's trailing. + * @return The line's trailing. + */ + public String getTrailing() { + return trailing; + } + +// ------------------------------ + + /** + * Returns the unparsed line. It looks exacttly as the server sent it, but + * if colors are disabled and therefore already parsed out by + * IRCUtil.parseColors, the colors are not included in here. + * @return The line. + */ + public String getLine() { + return buf.toString(); + } + +// ------------------------------ + + /** + * Returns the line's parameters which consists of the middle and the + * trailing. + * @return The line's parameters. + */ + public String getParameters() { + return middle + + ((middle.length() != 0 && trailing.length() != 0) ? " " : "") + + trailing; + } + +// ------------------------------ + + /** + * Returns the nickname of the person who sent the line + * or the servername of the server which sent the line.
+ * It is found in the prefix which always looks like that:
+ * + * <servername> | <nick> + * [ '!' <username> ] [ '@' <host> ] + *

+ * If no prefix is given in the whole line, null is returned. + *

+ * Note: This method is totally equal to getServername! + *
+ * Note: There is also the method getUser which returns + * an IRCUser object which holds the nickname, username and host. + * By the way, the getUser uses the getNick, + * getUsername and getHost methods to create this + * object. + * @return The nickname or the servername of the line. If no prefix is given, + * null is returned. + * @see #getServername() + * @see #getUsername() + * @see #getHost() + * @see #getUser() + */ + public String getNick() { + int i = prefix.indexOf('!'); + if (i != -1 || (i = prefix.indexOf('@')) != -1) + return prefix.substring(0, i); + return (prefix.length() != 0) ? prefix : null; + } + +// ------------------------------ + + /** + * Returns the servername of the server which sent the line + * or the nickname of the person who sent the line.
+ * It is found in the prefix which always looks like that:
+ * + * <servername> | <nick> + * [ '!' <username> ] [ '@' <host> ] + *

+ * If no prefix is given in the whole line, null is returned. + *

+ * Note: This method is totally equal to getNick! + *
+ * Note: There is also the method getUser which returns + * an IRCUser object which holds the nickname, username and host. + * By the way, the getUser uses the getNick, + * getUsername and getHost methods to create this + * object. + * @return The servername or the nickname of the line. If no prefix is given, + * null is returned. + * @see #getNick() + * @see #getUser() + */ + public String getServername() { + return getNick(); + } + +// ------------------------------ + + /** + * Returns the username of the person who sent the line.
+ * It is found in the prefix which always looks like that:
+ * + * <servername> | <nick> + * [ '!' <username> ] [ '@' <host> ] + *

+ * If the username is not specified, this method returns null. + *
+ * Note: There is also the method getUser which returns + * an IRCUser object which holds the nickname, username and host. + * By the way, the getUser uses the getNick, + * getUsername and getHost methods to create this + * object. + * @return The username of the line; null if it's not given. + * @see #getNick() + * @see #getHost() + * @see #getUser() + */ + public String getUsername() { + int i = prefix.indexOf('!') + 1; + if (i != 0) { + int j = prefix.indexOf('@', i); + return prefix.substring(i, (j != -1) ? j : prefix.length()); + } + return null; + } + +// ------------------------------ + + /** + * Returns the host of the person who sent the line.
+ * It is found in the prefix which always looks like that:
+ * + * <servername> | <nick> + * [ '!' <username> ] [ '@' <host> ] + *

+ * If the host is not specified, this method returns null. + *
+ * Note: There is also the method getUser which returns + * an IRCUser object which holds the nickname, username and host. + * By the way, the getUser uses the getNick, + * getUsername and getHost methods to create this + * object. + * @return The host of the line; null if it's not given. + * @see #getNick() + * @see #getUsername() + * @see #getUser() + */ + public String getHost() { + int i = prefix.indexOf('@') + 1; + if (i != 0) + return prefix.substring(i, prefix.length()); + return null; + } + +// ------------------------------ + + /** + * Returns a new IRCUser object. + * This method is equal to new IRCUser(IRCParser.getNick(), + * IRCParser.getUsername(), IRCParser.getHost()). See those methods to + * learn which value they return if they are not set. + * @return A new IRCUser object with exactly those values which + * are returned by the getNick, getUsername + * and getHost methods. + * @see #getNick() + * @see #getUsername() + * @see #getHost() + */ + public IRCUser getUser() { + return new IRCUser(getNick(), getUsername(), getHost()); + } + +// ------------------------------ + + /** + * Gets count of parameters. + * If parameters isn't initialized yet, it calls + * initParameters to do that. + * @return The number of parameters. + */ + public int getParameterCount() { + if (parameters == null) + initParameters(); + return parameters.length; + } + +// ------------------------------ + + /** + * Get one parameter of the line. + * If parameters isn't initialized yet, it calls + * initParameters to do that. + * @param i The index of the parameter you want to get. The index starts with + * 1 and not with 0. + * @return The ith parameter. If i is out of bounds, + * "" is returned. + */ + public String getParameter(int i) { + if (parameters == null) + initParameters(); + --i; + if (i >= 0 && i < parameters.length) + return parameters[i]; + else + return ""; + } + +// ------------------------------ + + /** + * Grabs the line's parameters from the ith to the last + * parameter (including the ith). + * If parameters isn't initialized yet, it calls + * initParameters to do that. + * @param i The index of the first parameter you want to get. + * @return All parameters behind another beginning at the ith. + * If i is out of bounds, "" is returned. + */ + public String getParametersFrom(int i) { + if (parameters == null) + initParameters(); + StringBuffer params = new StringBuffer(); + for (i--; i < parameters.length; i++) + params.append(parameters[i] +" "); + return params.toString(); + } + +// ------------------------------ + + /** + * Grabs the line's parameters from the first to the ith + * parameters (including the ith). + * If parameters isn't initialized yet, it calls + * initParameters to do that. + * @param i The index of the last parameter you want to get. + * @return All parameters beginning at the first and ending at the + * ith. If i is out of bounds, + * "" is returned. + */ + public String getParametersTo(int i) { + if (parameters == null) + initParameters(); + StringBuffer params = new StringBuffer(); + int max = (i < parameters.length) ? i : parameters.length; + for (i = 0; i < max; i++) + params.append(parameters[i] +" "); + return params.toString(); + } + +// ------------------------------ + + /** + * Generates a String with some information about the instance of + * IRCParser.
+ * Its format is: classname[prefix,command,middle,trailing]. + * @return A String with information about the instance. + */ + @Override + public String toString() { + return getClass().getName() +"["+ prefix +","+ command +","+ middle +","+ + trailing +"]"; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConstants.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConstants.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConstants.java (revision 0) @@ -0,0 +1,1402 @@ +package net.sf.l2j.gameserver.lib.irc; + +/** + * Contains constants: reply codes, error codes and mIRC color codes. + * @author Christoph Schwering <schwering@gmail.com> + * @since 1.10 + * @version 1.00 + * @see IRCEventListener#onError(int, String) + * @see IRCEventListener#onReply(int, String, String) + */ +public interface IRCConstants { + + /** + * Usually the first replies when you're connected. + */ + public static final int RPL_WELCOME = 001; + + /** + * Usually the first replies when you're connected. + */ + public static final int RPL_YOURHOST = 002; + + /** + * Usually the first replies when you're connected. + */ + public static final int RPL_CREATED = 003; + + /** + * Usually the first replies when you're connected. + */ + public static final int RPL_MYINFO = 004; + + /** + * Usually the first replies when you're connected. + */ + public static final int RPL_ISUPPORT = 005; + + + /** + * Used to indicate the nickname parameter supplied to + * a command is currently unused. + */ + public static final int ERR_NOSUCHNICK = 401; + + /** + * Format: "<server name> No such server".
+ * Used to indicate the server name given currently + * doesn't exist. + */ + public static final int ERR_NOSUCHSERVER = 402; + + /** + * Format: "<channel name> No such channel".
+ * Used to indicate the given channel name is invalid. + */ + public static final int ERR_NOSUCHCHANNEL = 403; + + /** + * Format: "<channel name> Cannot send to channel".
+ * Sent to a user who is either (a) not on a channel + * which is mode +n or (b) not a chanop (or mode +v) on + * a channel which has mode +m set and is trying to send + * a PRIVMSG message to that channel. + */ + public static final int ERR_CANNOTSENDTOCHAN = 404; + + /** + * Format: "<channel name> You have joined too many + * channels".
+ * Sent to a user when they have joined the maximum + * number of allowed channels and they try to join + * another channel. + */ + public static final int ERR_TOOMANYCHANNELS = 405; + + /** + * Format: "<nickname> There was no such nickname".
+ * Returned by WHOWAS to indicate there is no history + * information for that nickname. + */ + public static final int ERR_WASNOSUCHNICK = 406; + + + /** + * Format: "<target> Duplicate recipients. No message delivered".
+ * Returned to a client which is attempting to send a PRIVMSG/NOTICE using + * the user@host destination format and for a user@host which has several + * occurrences. + */ + public static final int ERR_TOOMANYTARGETS = 407; + + /** + * Format: "No origin specified".
+ * PING or PONG message missing the originator parameter + * which is required since these commands must work + * without valid prefixes. + */ + public static final int ERR_NOORIGIN = 409; + + /** + * Format: "No recipient given (<command>)". + */ + public static final int ERR_NORECIPIENT = 411; + + /** + * Format: "No text to send".
+ * 412 - 414 are returned by PRIVMSG to indicate that + * the message wasn't delivered for some reason. + * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that + * are returned when an invalid use of + * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + */ + public static final int ERR_NOTEXTTOSEND = 412; + + /** + * Format: "<mask> No toplevel domain specified".
+ * 412 - 414 are returned by PRIVMSG to indicate that + * the message wasn't delivered for some reason. + * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that + * are returned when an invalid use of + * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + */ + public static final int ERR_NOTOPLEVEL = 413; + + /** + * Format: "<mask> Wildcard in toplevel domain".
+ * 412 - 414 are returned by PRIVMSG to indicate that + * the message wasn't delivered for some reason. + * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that + * are returned when an invalid use of + * "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted. + */ + public static final int ERR_WILDTOPLEVEL = 414; + + /** + * Format: "<command> Unknown command".
+ * Returned to a registered client to indicate that the + * command sent is unknown by the server. + */ + public static final int ERR_UNKNOWNCOMMAND = 421; + + /** + * Format: "MOTD File is missing".
+ * Server's MOTD file could not be opened by the server. + */ + public static final int ERR_NOMOTD = 422; + + /** + * Format: "<server> No administrative info available".
+ * Returned by a server in response to an ADMIN message + * when there is an error in finding the appropriate + * information. + */ + public static final int ERR_NOADMININFO = 423; + + /** + * Format: "File error doing <file op> on <file>".
+ * Generic error message used to report a failed file + * operation during the processing of a message. + */ + public static final int ERR_FILEERROR = 424; + + /** + * Format: "No nickname given".
+ * Returned when a nickname parameter expected for a + * command and isn't found. + */ + public static final int ERR_NONICKNAMEGIVEN = 431; + + /** + * Format: "<nick> Erroneus nickname".
+ * Returned after receiving a NICK message which contains + * characters which do not fall in the defined set. See + * section x.x.x for details on valid nicknames. + */ + public static final int ERR_ERRONEUSNICKNAME = 432; + + /** + * Format: "<nick> Nickname is already in use".
+ * Returned when a NICK message is processed that results + * in an attempt to change to a currently existing + * nickname. + */ + public static final int ERR_NICKNAMEINUSE = 433; + + /** + * Format: "<nick> Nickname collision KILL".
+ * Returned by a server to a client when it detects a + * nickname collision (registered of a NICK that + * already exists by another server). + */ + public static final int ERR_NICKCOLLISION = 436; + + /** + * Format: "<nick> <channel> They aren't on that channel".
+ * Returned by the server to indicate that the target + * user of the command is not on the given channel. + */ + public static final int ERR_USERNOTINCHANNEL = 441; + + /** + * Format: "<channel> You're not on that channel".
+ * Returned by the server whenever a client tries to + * perform a channel effecting command for which the + * client isn't a member. + */ + public static final int ERR_NOTONCHANNEL = 442; + + /** + * Format: "<user> <channel> is already on channel".
+ * Returned when a client tries to invite a user to a + * channel they are already on. + */ + public static final int ERR_USERONCHANNEL = 443; + + /** + * Format: "<user> User not logged in".
+ * Returned by the summon after a SUMMON command for a + * user was unable to be performed since they were not + * logged in. + */ + public static final int ERR_NOLOGIN = 444; + + /** + * Format: "SUMMON has been disabled".
+ * Returned as a response to the SUMMON command. Must be + * returned by any server which does not implement it. + */ + public static final int ERR_SUMMONDISABLED = 445; + + /** + * Format: "USERS has been disabled".
+ * Returned as a response to the USERS command. Must be + * returned by any server which does not implement it. + */ + public static final int ERR_USERSDISABLED = 446; + + /** + * Format: "You have not registered".
+ * Returned by the server to indicate that the client + * must be registered before the server will allow it + * to be parsed in detail. + */ + public static final int ERR_NOTREGISTERED = 451; + + /** + * Format: "<command> Not enough parameters".
+ * Returned by the server by numerous commands to + * indicate to the client that it didn't supply enough + * parameters. + */ + public static final int ERR_NEEDMOREPARAMS = 461; + + /** + * Format: "You may not reregister".
+ * Returned by the server to any link which tries to + * change part of the registered details (such as + * password or user details from second USER message). + */ + public static final int ERR_ALREADYREGISTRED = 462; + + /** + * Format: "Your host isn't among the privileged".
+ * Returned to a client which attempts to register with + * a server which does not been setup to allow + * connections from the host the attempted connection + * is tried. + */ + public static final int ERR_NOPERMFORHOST = 463; + + /** + * Format: "Password incorrect".
+ * Returned to indicate a failed attempt at registering + * a connection for which a password was required and + * was either not given or incorrect. + */ + public static final int ERR_PASSWDMISMATCH = 464; + + /** + * Format: "You are banned from this server".
+ * Returned after an attempt to connect and register + * yourself with a server which has been setup to + * explicitly deny connections to you. + */ + public static final int ERR_YOUREBANNEDCREEP = 465; + + /** + * Format: "<channel> Channel key already set". + */ + public static final int ERR_KEYSET = 467; + + /** + * Format: "<channel> Cannot join channel (+l)". + */ + public static final int ERR_CHANNELISFULL = 471; + + /** + * Format: "<char> is unknown mode char to me". + */ + public static final int ERR_UNKNOWNMODE = 472; + + /** + * Format: "<channel> Cannot join channel (+i)". + */ + public static final int ERR_INVITEONLYCHAN = 473; + + /** + * Format: "<channel> Cannot join channel (+b)". + */ + public static final int ERR_BANNEDFROMCHAN = 474; + + /** + * Format: "<channel> Cannot join channel (+k)". + */ + public static final int ERR_BADCHANNELKEY = 475; + + /** + * Format: "Permission Denied- You're not an IRC operator". + * Any command requiring operator privileges to operate + * must return this error to indicate the attempt was + * unsuccessful. + */ + public static final int ERR_NOPRIVILEGES = 481; + + /** + * Format: "<channel> You're not channel operator".
+ * Any command requiring 'chanop' privileges (such as + * MODE messages) must return this error if the client + * making the attempt is not a chanop on the specified + * channel. + */ + public static final int ERR_CHANOPRIVSNEEDED = 482; + + /** + * Format: "You cant kill a server!".
+ * Any attempts to use the KILL command on a server + * are to be refused and this error returned directly + * to the client. + */ + public static final int ERR_CANTKILLSERVER = 483; + + /** + * Format: "No O-lines for your host".
+ * If a client sends an OPER message and the server has + * not been configured to allow connections from the + * client's host as an operator, this error must be + * returned. + */ + public static final int ERR_NOOPERHOST = 491; + + /** + * Format: "Unknown MODE flag".
+ * Returned by the server to indicate that a MODE + * message was sent with a nickname parameter and that + * the a mode flag sent was not recognized. + */ + public static final int ERR_UMODEUNKNOWNFLAG = 501; + + /** + * Format: "Cant change mode for other users".
+ * Error sent to any user trying to view or change the + * user mode for a user other than themselves. + */ + public static final int ERR_USERSDONTMATCH = 502; + + /** + * Dummy reply number. Not used. + */ + public static final int RPL_NONE = 300; + + /** + * Format: "[<reply>{<space><reply>}]".
+ * Reply format used by USERHOST to list replies to + * the query list. The reply string is composed as + * follows:
+ * <reply> ::= <nick>['*'] '=' <'+'|'-'><hostname> + *
+ * The '*' indicates whether the client has registered + * as an Operator. The '-' or '+' characters represent + * whether the client has set an AWAY message or not + * respectively. + */ + public static final int RPL_USERHOST = 302; + + /** + * Format: "[<nick> {<space><nick>}]".
+ * Reply format used by ISON to list replies to the + * query list. + */ + public static final int RPL_ISON = 303; + + /** + * Format: "<nick> <away message>". + */ + public static final int RPL_AWAY = 301; + + /** + * Format: "You are no longer marked as being away". + */ + public static final int RPL_UNAWAY = 305; + + /** + * Format: "You have been marked as being away".
+ * These replies are used with the AWAY command (if + * allowed). RPL_AWAY is sent to any client sending a + * PRIVMSG to a client which is away. RPL_AWAY is only + * sent by the server to which the client is connected. + * Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the + * client removes and sets an AWAY message. + */ + public static final int RPL_NOWAWAY = 306; + + /** + * Format: "<nick> <user> <host> * :<real name>". + *
+ * Replies 311 - 313, 317 - 319 are all replies + * generated in response to a WHOIS message. Given that + * there are enough parameters present, the answering + * server must either formulate a reply out of the above + * numerics (if the query nick is found) or return an + * error reply. The '*' in RPL_WHOISUSER is there as + * the literal character and not as a wild card. For + * each reply set, only RPL_WHOISCHANNELS may appear + * more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name + * indicate whether a client is a channel operator or + * has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark + * the end of processing a WHOIS message. + */ + public static final int RPL_WHOISUSER = 311; + + /** + * Format: "<nick> <server> <server info>".
+ * Replies 311 - 313, 317 - 319 are all replies + * generated in response to a WHOIS message. Given that + * there are enough parameters present, the answering + * server must either formulate a reply out of the above + * numerics (if the query nick is found) or return an + * error reply. The '*' in RPL_WHOISUSER is there as + * the literal character and not as a wild card. For + * each reply set, only RPL_WHOISCHANNELS may appear + * more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name + * indicate whether a client is a channel operator or + * has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark + * the end of processing a WHOIS message. + */ + public static final int RPL_WHOISSERVER = 312; + + /** + * Format: "<nick> is an IRC operator".
+ * Replies 311 - 313, 317 - 319 are all replies + * generated in response to a WHOIS message. Given that + * there are enough parameters present, the answering + * server must either formulate a reply out of the above + * numerics (if the query nick is found) or return an + * error reply. The '*' in RPL_WHOISUSER is there as + * the literal character and not as a wild card. For + * each reply set, only RPL_WHOISCHANNELS may appear + * more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name + * indicate whether a client is a channel operator or + * has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark + * the end of processing a WHOIS message. + */ + public static final int RPL_WHOISOPERATOR = 313; + + /** + * Format: "<nick> <integer> seconds idle".
+ * Replies 311 - 313, 317 - 319 are all replies + * generated in response to a WHOIS message. Given that + * there are enough parameters present, the answering + * server must either formulate a reply out of the above + * numerics (if the query nick is found) or return an + * error reply. The '*' in RPL_WHOISUSER is there as + * the literal character and not as a wild card. For + * each reply set, only RPL_WHOISCHANNELS may appear + * more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name + * indicate whether a client is a channel operator or + * has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark + * the end of processing a WHOIS message. + */ + public static final int RPL_WHOISIDLE = 317; + + /** + * Format: "<nick> End of /WHOIS list".
+ * Replies 311 - 313, 317 - 319 are all replies + * generated in response to a WHOIS message. Given that + * there are enough parameters present, the answering + * server must either formulate a reply out of the above + * numerics (if the query nick is found) or return an + * error reply. The '*' in RPL_WHOISUSER is there as + * the literal character and not as a wild card. For + * each reply set, only RPL_WHOISCHANNELS may appear + * more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name + * indicate whether a client is a channel operator or + * has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark + * the end of processing a WHOIS message. + */ + public static final int RPL_ENDOFWHOIS = 318; + + /** + * Format: "<nick> {[@|+]<channel><space>}".
+ * Replies 311 - 313, 317 - 319 are all replies + * generated in response to a WHOIS message. Given that + * there are enough parameters present, the answering + * server must either formulate a reply out of the above + * numerics (if the query nick is found) or return an + * error reply. The '*' in RPL_WHOISUSER is there as + * the literal character and not as a wild card. For + * each reply set, only RPL_WHOISCHANNELS may appear + * more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name + * indicate whether a client is a channel operator or + * has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark + * the end of processing a WHOIS message. + */ + public static final int RPL_WHOISCHANNELS = 319; + + /** + * Format: "<nick> <user> <host> * <real name>". + */ + public static final int RPL_WHOWASUSER = 314; + + /** + * Format: "<nick> End of WHOWAS".
+ * When replying to a WHOWAS message, a server must use + * the replies RPL_WHOWASUSER, RPL_WHOISSERVER or + * ERR_WASNOSUCHNICK for each nickname in the presented + * list. At the end of all reply batches, there must + * be RPL_ENDOFWHOWAS (even if there was only one reply + * and it was an error). + */ + public static final int RPL_ENDOFWHOWAS = 369; + + /** + * Format: "Channel Users Name".
+ * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark + * the start, actual replies with data and end of the + * server's response to a LIST command. If there are + * no channels available to return, only the start + * and end reply must be sent. + */ + public static final int RPL_LISTSTART = 321; + + /** + * Format: "<channel> <# visible> <topic>".
+ * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark + * the start, actual replies with data and end of the + * server's response to a LIST command. If there are + * no channels available to return, only the start + * and end reply must be sent. + */ + public static final int RPL_LIST = 322; + + /** + * Format: "End of /LIST".
+ * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark + * the start, actual replies with data and end of the + * server's response to a LIST command. If there are + * no channels available to return, only the start + * and end reply must be sent. + */ + public static final int RPL_LISTEND = 323; + + /** + * Format: "<channel> <mode> <mode params>".
+ */ + public static final int RPL_CHANNELMODEIS = 324; + + /** + * Format: "<nick> <authname> is authed as"
+ * This is part of /WHOIS on many servers which provide bots to authenticate. + */ + public static final int RPL_AUTHNAME = 333; + + /** + * Format: "<channel> No topic is set".
+ * When sending a TOPIC message to determine the + * channel topic, one of two replies is sent. If + * the topic is set, RPL_TOPIC is sent back else + * public static final int RPL_NOTOPIC. + */ + public static final int RPL_NOTOPIC = 331; + + /** + * Format: "<channel> <topic>".
+ * When sending a TOPIC message to determine the + * channel topic, one of two replies is sent. If + * the topic is set, RPL_TOPIC is sent back else + * public static final int RPL_NOTOPIC. + */ + public static final int RPL_TOPIC = 332; + + /** + * Format: "<channel> <nick-who-set-topic> <seconds>". + * The seconds are not milliseconds; just multiply it with 1000 and then + * format a date with it. + */ + public static final int RPL_TOPICINFO = 333; + + /** + * Format: "<channel> <nick>".
+ * Returned by the server to indicate that the + * attempted INVITE message was successful and is + * being passed onto the end client. + */ + public static final int RPL_INVITING = 341; + + /** + * Format: "<user> Summoning user to IRC".
+ * Returned by a server answering a SUMMON message to + * indicate that it is summoning that user. + */ + public static final int RPL_SUMMONING = 342; + + /** + * Format: "<version>.<debuglevel> <server> + * <comments>".
+ * Reply by the server showing its version details. + * The <version> is the version of the software being + * used (including any patchlevel revisions) and the + * <debuglevel> is used to indicate if the server is + * running in "debug mode".
+ * The "comments" field may contain any comments about + * the version or further version details. + */ + public static final int RPL_VERSION = 351; + + /** + * Format: "<channel> <user> <host> <server> + * <nick> <H|G>[*][@|+] <hopcount> <real name>".
+ * The RPL_WHOREPLY and RPL_ENDOFWHO pair are used + * to answer a WHO message. The RPL_WHOREPLY is only + * sent if there is an appropriate match to the WHO + * query. If there is a list of parameters supplied + * with a WHO message, a RPL_ENDOFWHO must be sent + * after processing each list item with <name> being + * the item. + */ + public static final int RPL_WHOREPLY = 352; + + /** + * Format: "<name> End of /WHO list".
+ * The RPL_WHOREPLY and RPL_ENDOFWHO pair are used ++ * to answer a WHO message. The RPL_WHOREPLY is only + * sent if there is an appropriate match to the WHO + * query. If there is a list of parameters supplied + * with a WHO message, a RPL_ENDOFWHO must be sent + * after processing each list item with <name> being + * the item. + */ + public static final int RPL_ENDOFWHO = 315; + + /** + * Format: "<channel> [[@|+]<nick> [[@|+]<nick> + * [...]]]".
+ * To reply to a NAMES message, a reply pair consisting + * of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the + * server back to the client. If there is no channel + * found as in the query, then only RPL_ENDOFNAMES is + * returned. The exception to this is when a NAMES + * message is sent with no parameters and all visible + * channels and contents are sent back in a series of + * RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark + * the end. + */ + public static final int RPL_NAMREPLY = 353; + + /** + * Format: "<channel> End of /NAMES list".
+ * To reply to a NAMES message, a reply pair consisting + * of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the + * server back to the client. If there is no channel + * found as in the query, then only RPL_ENDOFNAMES is + * returned. The exception to this is when a NAMES + * message is sent with no parameters and all visible + * channels and contents are sent back in a series of + * RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark + * the end. + */ + public static final int RPL_ENDOFNAMES = 366; + + /** + * Format: "<mask> <server> <hopcount> <server info>". + *
+ * In replying to the LINKS message, a server must send + * replies back using the RPL_LINKS numeric and mark the + * end of the list using an RPL_ENDOFLINKS reply. + */ + public static final int RPL_LINKS = 364; + + /** + * Format: "<mask> End of /LINKS list".
+ * In replying to the LINKS message, a server must send + * replies back using the RPL_LINKS numeric and mark the + * end of the list using an RPL_ENDOFLINKS reply. + */ + public static final int RPL_ENDOFLINKS = 365; + + /** + * Format: "<channel> <banid>".
+ * When listing the active 'bans' for a given channel, + * a server is required to send the list back using the + * RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate + * RPL_BANLIST is sent for each active banid. After the + * banids have been listed (or if none present) a + * RPL_ENDOFBANLIST must be sent. + */ + public static final int RPL_BANLIST = 367; + + /** + * Format: "<channel> End of channel ban list".
+ * When listing the active 'bans' for a given channel, + * a server is required to send the list back using the + * RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate + * RPL_BANLIST is sent for each active banid. After the + * banids have been listed (or if none present) a + * RPL_ENDOFBANLIST must be sent. + */ + public static final int RPL_ENDOFBANLIST = 368; + + /** + * Format: "<string>".
+ * A server responding to an INFO message is required to + * send all its 'info' in a series of RPL_INFO messages + * with a RPL_ENDOFINFO reply to indicate the end of the + * replies. + */ + public static final int RPL_INFO = 371; + + + /** + * Format: "End of /INFO list".
+ * A server responding to an INFO message is required to + * send all its 'info' in a series of RPL_INFO messages + * with a RPL_ENDOFINFO reply to indicate the end of the + * replies. + */ + public static final int RPL_ENDOFINFO = 374; + + /** + * Format: "- <server> Message of the day - ".
+ * When responding to the MOTD message and the MOTD file + * is found, the file is displayed line by line, with + * each line no longer than 80 characters, using + * RPL_MOTD format replies. These should be surrounded + * by a RPL_MOTDSTART (before the RPL_MOTDs) and an + * RPL_ENDOFMOTD (after). + */ + public static final int RPL_MOTDSTART = 375; + + /** + * Format: "- <text>".
+ * When responding to the MOTD message and the MOTD file + * is found, the file is displayed line by line, with + * each line no longer than 80 characters, using + * RPL_MOTD format replies. These should be surrounded + * by a RPL_MOTDSTART (before the RPL_MOTDs) and an + * RPL_ENDOFMOTD (after). + */ + public static final int RPL_MOTD = 372; + + /** + * Format: "End of /MOTD command".
+ * When responding to the MOTD message and the MOTD file + * is found, the file is displayed line by line, with + * each line no longer than 80 characters, using + * RPL_MOTD format replies. These should be surrounded + * by a RPL_MOTDSTART (before the RPL_MOTDs) and an + * RPL_ENDOFMOTD (after). + */ + public static final int RPL_ENDOFMOTD = 376; + + /** + * Format: "You are now an IRC operator".
+ * RPL_YOUREOPER is sent back to a client which has + * just successfully issued an OPER message and gained + * operator status. + */ + public static final int RPL_YOUREOPER = 381; + + /** + * Format: "<config file> Rehashing".
+ * If the REHASH option is used and an operator sends + * a REHASH message, an RPL_REHASHING is sent back to + * the operator. + */ + public static final int RPL_REHASHING = 382; + + /** + * Format: "<server> <string showing server's local time>".
+ * When replying to the TIME message, a server must send + * the reply using the RPL_TIME format above. The string + * showing the time need only contain the correct day and + * time there. There is no further requirement for the + * time string. + */ + public static final int RPL_TIME = 391; + + /** + * Format: "UserID Terminal Host".
+ * If the USERS message is handled by a server, the + * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and + * RPL_NOUSERS are used. RPL_USERSSTART must be sent + * first, following by either a sequence of RPL_USERS + * or a single RPL_NOUSER. Following this is + * RPL_ENDOFUSERS. + */ + public static final int RPL_USERSSTART = 392; + + /** + * Format: "%-8s %-9s %-8s".
+ * If the USERS message is handled by a server, the + * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and + * RPL_NOUSERS are used. RPL_USERSSTART must be sent + * first, following by either a sequence of RPL_USERS + * or a single RPL_NOUSER. Following this is + * RPL_ENDOFUSERS. + */ + public static final int RPL_USERS = 393; + + /** + * Format: "End of users".
+ * If the USERS message is handled by a server, the + * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and + * RPL_NOUSERS are used. RPL_USERSSTART must be sent + * first, following by either a sequence of RPL_USERS + * or a single RPL_NOUSER. Following this is + * RPL_ENDOFUSERS. + */ + public static final int RPL_ENDOFUSERS = 394; + + /** + * Format: "Nobody logged in".
+ * If the USERS message is handled by a server, the + * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and + * RPL_NOUSERS are used. RPL_USERSSTART must be sent + * first, following by either a sequence of RPL_USERS + * or a single RPL_NOUSER. Following this is + * RPL_ENDOFUSERS. + */ + public static final int RPL_NOUSERS = 395; + + /** + * Format: "Link <version & debug level> <destination> + * <next server>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACELINK = 200; + + /** + * Format: "Try. <class> <server>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACECONNECTING = 201; + + /** + * Format: "H.S. <class> <server>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACEHANDSHAKE = 202; + + /** + * Format: "???? <class> [<client IP address in dot form>]".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACEUNKNOWN = 203; + + /** + * Format: "Oper <class> <nick>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACEOPERATOR = 204; + + /** + * Format: "User <class> <nick>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACEUSER = 205; + + /** + * Format: "Serv <class> <int>S <int>C <server> + * <nick!user|*!*>@<host|server>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACESERVER = 206; + + /** + * Format: "<newtype> 0 <client name>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACENEWTYPE = 208; + + /** + * Format: "File <logfile> <debug level>".
+ * The RPL_TRACE* are all returned by the server in + * response to the TRACE message. How many are + * returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There + * is no predefined order for which occurs first. + * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections + * which have not been fully established and are either + * unknown, still attempting to connect or in the + * process of completing the 'server handshake'. + * RPL_TRACELINK is sent by any server which handles + * a TRACE message and has to pass it on to another + * server. The list of RPL_TRACELINKs sent in + * response to a TRACE command traversing the IRC + * network should reflect the actual connectivity of + * the servers themselves along that path. + * RPL_TRACENEWTYPE is to be used for any connection + * which does not fit in the other categories but is + * being displayed anyway. + */ + public static final int RPL_TRACELOG = 261; + + /** + * Format: "<linkname> <sendq> <sent messages> + * <sent bytes> <received messages> + * <received bytes> <time open>". + */ + public static final int RPL_STATSLINKINFO = 211; + + /** + * Format: "<command> <count>". + */ + public static final int RPL_STATSCOMMANDS = 212; + + /** + * Format: "C <host> * <name> <port> <class>". + */ + public static final int RPL_STATSCLINE = 213; + + /** + * Format: "N <host> * <name> <port> <class>". + */ + public static final int RPL_STATSNLINE = 214; + + /** + * Format: "I <host> * <host> <port> <class>". + */ + public static final int RPL_STATSILINE = 215; + + /** + * Format: "K <host> * <username> <port> <class>". + */ + public static final int RPL_STATSKLINE = 216; + + /** + * Format: "Y <class> <ping frequency> <connect + * frequency> <max sendq>". + */ + public static final int RPL_STATSYLINE = 218; + + /** + * Format: "<stats letter> End of /STATS report". + */ + public static final int RPL_ENDOFSTATS = 219; + + /** + * Format: "L <hostmask> * <servername> <maxdepth>". + */ + public static final int RPL_STATSLLINE = 241; + + /** + * Format: "Server Up %d days %d:%02d:%02d". + */ + public static final int RPL_STATSUPTIME = 242; + + /** + * Format: "O <hostmask> * <name>" + */ + public static final int RPL_STATSOLINE = 243; + + /** + * Format: "H <hostmask> * <servername>". + */ + public static final int RPL_STATSHLINE = 244; + + /** + * Format: "<user mode string>".
+ * To answer a query about a client's own mode, + * RPL_UMODEIS is sent back. + */ + public static final int RPL_UMODEIS = 221; + + /** + * Format: "There are <integer> users and <integer> + * invisible on <integer> servers".
+ * In processing an LUSERS message, the server + * sends a set of replies from RPL_LUSERCLIENT, + * RPL_LUSEROP, RPL_USERUNKNOWN, + * RPL_LUSERCHANNELS and RPL_LUSERME. When + * replying, a server must send back + * RPL_LUSERCLIENT and RPL_LUSERME. The other + * replies are only sent back if a non-zero count + * is found for them. + */ + public static final int RPL_LUSERCLIENT = 251; + + /** + * Format: "<integer> operator(s) online".
+ * In processing an LUSERS message, the server + * sends a set of replies from RPL_LUSERCLIENT, + * RPL_LUSEROP, RPL_USERUNKNOWN, + * RPL_LUSERCHANNELS and RPL_LUSERME. When + * replying, a server must send back + * RPL_LUSERCLIENT and RPL_LUSERME. The other + * replies are only sent back if a non-zero count + * is found for them. + */ + public static final int RPL_LUSEROP = 252; + + /** + * Format: "<integer> unknown connection(s)".
+ * In processing an LUSERS message, the server + * sends a set of replies from RPL_LUSERCLIENT, + * RPL_LUSEROP, RPL_USERUNKNOWN, + * RPL_LUSERCHANNELS and RPL_LUSERME. When + * replying, a server must send back + * RPL_LUSERCLIENT and RPL_LUSERME. The other + * replies are only sent back if a non-zero count + * is found for them. + */ + public static final int RPL_LUSERUNKNOWN = 253; + + /** + * Format: "<integer> channels formed".
+ * In processing an LUSERS message, the server + * sends a set of replies from RPL_LUSERCLIENT, + * RPL_LUSEROP, RPL_USERUNKNOWN, + * RPL_LUSERCHANNELS and RPL_LUSERME. When + * replying, a server must send back + * RPL_LUSERCLIENT and RPL_LUSERME. The other + * replies are only sent back if a non-zero count + * is found for them. + */ + public static final int RPL_LUSERCHANNELS = 254; + + /** + * Format: "I have <integer> clients and <integer> + * servers".
+ * In processing an LUSERS message, the server + * sends a set of replies from RPL_LUSERCLIENT, + * RPL_LUSEROP, RPL_USERUNKNOWN, + * RPL_LUSERCHANNELS and RPL_LUSERME. When + * replying, a server must send back + * RPL_LUSERCLIENT and RPL_LUSERME. The other + * replies are only sent back if a non-zero count + * is found for them. + */ + public static final int RPL_LUSERME = 255; + + /** + * Format: "<server> Administrative info".
+ * When replying to an ADMIN message, a server + * is expected to use replies RLP_ADMINME + * through to RPL_ADMINEMAIL and provide a text + * message with each. For RPL_ADMINLOC1 a + * description of what city, state and country + * the server is in is expected, followed by + * details of the university and department + * (RPL_ADMINLOC2) and finally the administrative + * contact for the server (an email address here + * is required) in RPL_ADMINEMAIL. + */ + public static final int RPL_ADMINME = 256; + + /** + * Format: "<admin info>".
+ * When replying to an ADMIN message, a server + * is expected to use replies RLP_ADMINME + * through to RPL_ADMINEMAIL and provide a text + * message with each. For RPL_ADMINLOC1 a + * description of what city, state and country + * the server is in is expected, followed by + * details of the university and department + * (RPL_ADMINLOC2) and finally the administrative + * contact for the server (an email address here + * is required) in RPL_ADMINEMAIL. + */ + public static final int RPL_ADMINLOC1 = 257; + + /** + * Format: "<admin info>".
+ * When replying to an ADMIN message, a server + * is expected to use replies RLP_ADMINME + * through to RPL_ADMINEMAIL and provide a text + * message with each. For RPL_ADMINLOC1 a + * description of what city, state and country + * the server is in is expected, followed by + * details of the university and department + * (RPL_ADMINLOC2) and finally the administrative + * contact for the server (an email address here + * is required) in RPL_ADMINEMAIL. + */ + public static final int RPL_ADMINLOC2 = 258; + + /** + * Format: "<admin info>".
+ * When replying to an ADMIN message, a server + * is expected to use replies RLP_ADMINME + * through to RPL_ADMINEMAIL and provide a text + * message with each. For RPL_ADMINLOC1 a + * description of what city, state and country + * the server is in is expected, followed by + * details of the university and department + * (RPL_ADMINLOC2) and finally the administrative + * contact for the server (an email address here + * is required) in RPL_ADMINEMAIL. + */ + public static final int RPL_ADMINEMAIL = 259; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_TRACECLASS = 209; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_STATSQLINE = 217; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_SERVICEINFO = 231; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_ENDOFSERVICES = 232; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_SERVICE = 233; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_SERVLIST = 234; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_SERVLISTEND = 235; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_WHOISCHANOP = 316; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_KILLDONE = 361; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_CLOSING = 362; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_CLOSEEND = 363; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_INFOSTART = 373; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int RPL_MYPORTIS = 384; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int ERR_YOUWILLBEBANNED = 466; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int ERR_BADCHANMASK = 476; + + /** + * This numeric is no longer in use, reserved for future planned use or + * anything else. + */ + public static final int ERR_NOSERVICEHOST = 492; + + /** + * This is part of the mIRC code and shows that a color-code starts / ends. + * Here it is as the ASCII decimal int 3. + */ + public static final char COLOR_INDICATOR = 3; // ASCII code + + /** + * This is part of the mIRC code and shows that bold starts / ends. + * Here it is as the ASCII decimal int 31. + */ + public static final char BOLD_INDICATOR = 31; // ASCII code + + /** + * This is part of the mIRC code and shows that bold starts / ends. + * Here it is as the ASCII decimal int 2. + */ + public static final char UNDERLINE_INDICATOR = 2; // ASCII code + + /** + * This is part of the mIRC code and shows that bold, underline and colors + * end. + * Here it is as the ASCII decimal int 15. + */ + public static final char COLOR_END_INDICATOR = 15; // ASCII code + + /** + * This is part of the mIRC code and indicates that the client's colors are + * reversed (background -> foreground and foreground -> background). + * Here it is as the ASCII decimal int 22. + */ + public static final char COLOR_REVERSE_INDICATOR = 22; // ASCII code + + /** + * This is part of the mIRC code and shows that a PRIVMSG is an ACTION + * (/me). + * Here it is as the ASCII decimal int 1. + */ + public static final char ACTION_INDICATOR = 1; // ASCII code +} \ No newline at end of file Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUtil.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUtil.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUtil.java (revision 0) @@ -0,0 +1,253 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCUtil + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. +*/ + +package net.sf.l2j.gameserver.lib.irc; + +import java.util.Vector; +/** + * Contains some utilities like numeric error and reply numbers. + *

+ * The most description of the numeric errors and numeric replies are copied + * from RFC1459. + * @author Christoph Schwering <schwering@gmail.com> + * @author Normton <normton@latinmail.com> + * @version 2.03 + * @see IRCConnection + * @see IRCEventListener#onError(int, String) + * @see IRCEventListener#onReply(int, String, String) + */ +public class IRCUtil implements IRCConstants { + /** + * This is part of the mIRC code and shows that a color-code starts / ends. + * Here it is as the ASCII decimal int 3. + * @deprecated Moved to IRCConstants. + */ + @Deprecated + public static char colorIndicator = 3; // ASCII code + + /** + * This is part of the mIRC code and shows that bold starts / ends. + * Here it is as the ASCII decimal int 31. + * @deprecated Moved to IRCConstants. + */ + @Deprecated + public static char boldIndicator = 31; // ASCII code + + /** + * This is part of the mIRC code and shows that bold starts / ends. + * Here it is as the ASCII decimal int 2. + * @deprecated Moved to IRCConstants. + */ + @Deprecated + public static char underlinedIndicator = 2; // ASCII code + + /** + * This is part of the mIRC code and shows that bold, underline and colors + * end. + * Here it is as the ASCII decimal int 15. + * @deprecated Moved to IRCConstants. + */ + @Deprecated + public static char colorEndIndicator = 15; // ASCII code + + /** + * This is part of the mIRC code and indicates that the client's colors are + * reversed (background -> foreground and foreground -> background). + * Here it is as the ASCII decimal int 22. + * @deprecated Moved to IRCConstants. + */ + @Deprecated + public static char colorReverseIndicator = 22; // ASCII code + + /** + * This is part of the mIRC code and shows that a PRIVMSG is an ACTION + * (/me). + * Here it is as the ASCII decimal int 1. + * @deprecated Moved to IRCConstants. + */ + @Deprecated + public static char actionIndicator = 1; // ASCII code + +// ------------------------------ + + /** + * This is an empty constructor, it does nothing. Nobody may instantiate this + * class. + */ + private IRCUtil() { + // nothing + } + +// ------------------------------ + + /** + * According to RFC2812 the channel's name may and must start with one of the + * following characters. + *

    + *
  • ! == 33 (ASCII)
  • + *
  • # == 35
  • + *
  • & == 38
  • + *
  • + == 43
  • + *
. + * @param str The name to check if it's a channel. + * @return true if the argument starts with one of the characters + * mentioned above. + */ + public static boolean isChan(String str) { + int c; + return str.length() >= 2 + && ((c = str.charAt(0)) == 35 || c == 38 || c == 33 || c == 43); + } + +// ------------------------------ + + /** + * Parses a String to an int via + * Integer.parseInt but avoids the + * NumberFormatException. + * @param str The String to parse. + * @return The parsed new int. -1 if + * NumberFormatException was thrown. + */ + public static int parseInt(String str) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException exc) { + return -1; + } + } + +// ------------------------------ + + /** + * Erases the mIRC colorcodes from a String. + * The documentation of the evil color codes is available on + * http://www.mirc.co.uk/help/color.txt. + * This method links to the parseColors(StringBuffer) method. + * @param str The line which should be parsed. + * @return A line cleaned from any mIRC colorcodes. + * @see #parseColors(StringBuffer) + */ + public static String parseColors(String str) { + return parseColors(new StringBuffer(str)).toString(); + } + +// ------------------------------ + + /** + * Erases the mIRC colorcodes from a String. + * The documentation of the evil color codes is available on + * http://www.mirc.co.uk/help/color.txt. + * @param buf The line which should be parsed. + * @return A line as StringBuffer object which is cleaned from + * any mIRC colorcodes. + * @see #parseColors(String) + */ + public static StringBuffer parseColors(StringBuffer buf) { + int len = buf.length(); + + for (int i = 0, j = 0, c; i < len; i++, j = i) { + c = buf.charAt(i); + try { + // COLORS Beginning + // (format: [][[,[]] + if (c == COLOR_INDICATOR) { + c = buf.charAt(++j); + if ('0' <= c && c <= '9') { // first int + c = buf.charAt(++j); + if ('0' <= c && c <= '9') + c = buf.charAt(++j); // second int + } + if (c == ',') + c = buf.charAt(++j); // comma + if ('0' <= c && c <= '9') { // first int + c = buf.charAt(++j); + if ('0' <= c && c <= '9') + c = buf.charAt(++j); // second int + } + // ACTION / BOLD / UNDERLINE / COLOR END + // (format: / etc.) + } else if (c == ACTION_INDICATOR || c == BOLD_INDICATOR || + c == UNDERLINE_INDICATOR || c == COLOR_END_INDICATOR || + c == COLOR_REVERSE_INDICATOR) { + j++; + } + } catch(StringIndexOutOfBoundsException exc) { + // we got the end of the string with a call to charAt(++iIndexEnd) + // nothing + } + + if (j > i) { + buf = buf.delete(i, j); // remove the cars + len -= j - i; + i--; + } + } + return buf; + } + +// ------------------------------ + + /** + * Splits a string into substrings. + * @param str The string which is to split. + * @param delim The delimiter character, for example a space ' '. + * @param trailing The ending which is added as a substring though it wasn't + * in the str. This parameter is just for the + * IRCParser class which uses this method to + * split the middle part into the parameters. + * But as last parameter always the trailing is + * added. This is done here because it's the fastest way to + * do it here.
+ * If the end is null or + * "", nothing is appended. + * @return An array with all substrings. + * @see #split(String, int) + */ + public static String[] split(String str, int delim, String trailing) { + Vector items = new Vector(15); + int last = 0; + int index = 0; + int len = str.length(); + while (index < len) { + if (str.charAt(index) == delim) { + items.add(str.substring(last, index)); + last = index + 1; + } + index++; + } + if (last != len) + items.add(str.substring(last)); + if (trailing != null && trailing.length() != 0) + items.add(trailing); + String[] result = new String[items.size()]; + items.copyInto(result); + return result; + } + +// ------------------------------ + + /** + * Splits a string into substrings. This method is totally equal to + * split(str, delim, null). + * @param str The string which is to split. + * @param delim The delimiter character, for example a space ' '. + * @return An array with all substrings. + * @see #split(String, int, String) + */ + public static String[] split(String str, int delim) { + return split(str, delim, null); + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUser.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUser.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUser.java (revision 0) @@ -0,0 +1,126 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCUser + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + */ + +package net.sf.l2j.gameserver.lib.irc; + +/** + * Holds variables for the nick, username and host of a user. +

+ * It's used to pack these information in one object. + * @author Christoph Schwering <schwering@gmail.com> + * @version 1.02 + * @see IRCEventListener + * @see IRCParser +*/ +public class IRCUser { + + /** + * The user's nickname. + */ + private String _nick; + + /** + * The user's username. + */ + private String _username; + + /** + * The user's host. + */ + private String _host; + +// ------------------------------ + + /** + * Creates a new IRCUser object. + * @param nick The user's nickname. ++ * @param username The user's username. + * @param host The user's host. + */ + public IRCUser(String nick, String username, String host) { + this._nick = nick; + this._username = username; + this._host = host; + } + +// ------------------------------ + + /** + * Returns the nickname of the person who sent the line + * or the servername of the server which sent the line.
+ * If no nickname is given, null is returned. + *

+ * Note: This method is totally equal to getServername! + * @return The nickname or the servername of the line. If no nick is given, + * null is returned. + * @see #getServername() + * @see #getUsername() + * @see #getHost() + */ + public String getNick() { + return _nick; + } + +// ------------------------------ + + /** + * Returns the servername of the server which sent the line or the nickname of + * the person who sent the line.
+ * If no nickname is given, null is returned. + *

+ * Note: This method is totally equal to getNick! + * @return The servername or the nickname of the line. If no server is given, + * null is returned. + * @see #getNick() + */ + public String getServername() { + return getNick(); + } + +// ------------------------------ + + /** + * Returns the username of the person who sent the line.
+ * If the username is not specified, this method returns null. + * @return The username of the line; null if it's not given. + * @see #getNick() + * @see #getHost() + */ + public String getUsername() { + return _username; + } + +// ------------------------------ + + /** + * Returns the host of the person who sent the line.
+ * If the host is not specified, this method returns null. + * @return The host of the line; null if it's not given. + * @see #getNick() + * @see #getUsername() + */ + public String getHost() { + return _host; + } + +// ------------------------------ + + /** + * Returns the nickname. + * @return The nickname. + */ + @Override + public String toString() { + return getNick(); + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConnection.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConnection.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConnection.java (revision 0) @@ -0,0 +1,1320 @@ +/* + * IRClib -- A Java Internet Relay Chat library -- class IRCConnection + * Copyright (C) 2002 - 2006 Christoph Schwering + * + * This library and the accompanying materials are made available under the + * terms of the + * - GNU Lesser General Public License, + * - Apache License, Version 2.0 and + * - Eclipse Public License v1.0. + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + */ +package net.sf.l2j.gameserver.lib.irc; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Socket; +import java.net.SocketException; +/** + * Creates a new connection to an IRC server. It's the main class of the + * IRClib, the point everything starts. + *

+ * The following sample code tries to establish an IRC connection to an + * IRC server: + *

+ *


+ * /* 
+ *  * The following code of a class which imports org.schwering.irc.lib.*
+ *  * prepares an IRC connection and then tries to establish the connection.
+ *  * The server is "irc.somenetwork.com", the default portrange (6667 and 
+ *  * 6669) is set, no password is used (null). The nickname is "Foo" and 
+ *  * the realname is "Mr. Foobar". The username "foobar".
+ *  * Because of setDaemon(true), the JVM exits even if this thread is 
+ *  * running.
+ *  * An instance of the class MyListener which must implement 
+ *  * IRCActionListener is added as only event-listener for the connection. 
+ *  * The connection is told to parse out mIRC color codes and to enable
+ *  * automatic PING? PONG! replies.
+ *  */
+ * IRCConnection conn = new IRCConnection(
+ *                            "irc.somenetwork.com", 
+ *                            6667, 
+ *                            6669, 
+ *                            null, 
+ *                            "Foo", 
+ *                            "Mr. Foobar", 
+ *                            "foo@bar.com" 
+ *                          ); 
+ * 
+ * conn.addIRCEventListener(new MyListener()); 
+ * conn.setDaemon(true);
+ * conn.setColors(false); 
+ * conn.setPong(true); 
+ * 
+ * try {
+ *   conn.connect(); // Try to connect!!! Don't forget this!!!
+ * } catch (IOException ioexc) {
+ *   ioexc.printStackTrace(); 
+ * }
+ * 

+ *

+ * The serverpassword isn't needed in most cases. You can give + * null or "" instead as done in this example. + * @author Christoph Schwering <schwering@gmail.com> + * @version 3.05 + * @see IRCEventListener + * @see IRCParser + * @see IRCUtil + * @see SSLIRCConnection + */ + +public class IRCConnection extends Thread +{ + /** + * This Socket is a connection to the IRC server. + */ + private Socket socket; + + /** + * This is like a UNIX-runlevel. Its value indicates the level of the + * IRCConnection object. 0 means that the + * object has not yet been connected, 1 means that it's + * connected but not registered, 2 means that it's connected + * and registered but still waiting to receive the nickname the first time, + * 3 means that it's connected and registered, and + * -1 means that it was connected but is disconnected. + * Therefore the defaultvalue is 0. + */ + protected byte level = 0; + + /** + * The host of the IRC server. + */ + protected String _host; + + /** + * The int[] contains all ports to which we are going to try + * to connect. This can be a portrange from port 6667 to 6669, for example. + */ + protected int[] _ports; + + /** + * The BufferedReader receives Strings from the IRC server. + */ + private volatile BufferedReader in; + + /** + * The PrintWriter sends Strings to the IRC server. + */ + private PrintWriter out; + + /** + * The String contains the name of the character encoding + * used to talk to the server. This can be ISO-8859-1 or UTF-8 for example. + * The default is ISO-8859-1. + */ + protected String _encoding = "ISO-8859-1"; + + /** + * This array contains IRCEventListener objects. + */ + private IRCEventListener[] listeners = new IRCEventListener[0]; + + /** + * This int is the connection's timeout in milliseconds. It's + * used in the Socket.setSoTimeout method. The default is + * 1000 * 60 * 15 millis which are 15 minutes. + */ + private int timeout = 1000 * 60 * 15; + + /** + * This boolean stands for enabled (true) or + * disabled (false) ColorCodes.
+ * Default is enabled (false). + */ + private boolean colorsEnabled = false; + + /** + * This boolean stands for enabled or disabled automatic + * PING? PONG! support.
+ * It means, that if the server asks with PING for the ping, the PONG is + * automatically sent. Default is automatic PONG enabled (true). + */ + private boolean pongAutomatic = true; + + /** + * The password, which is needed to get access to the IRC server. + */ + private String _pass; + + /** + * The user's nickname, which is indispensably to connect. + */ + private String _nick; + + /** + * The user's realname, which is indispensably to connect. + */ + private String _realname; + + /** + * The user's username, which is indispensable to connect. + */ + private String _username; + + // ------------------------------ + /** + * Creates a new IRC connection.
+ * The difference to the other constructor is, that it transmits the ports + * in an int[]. Thus, also ports like 1024, 2048, 6667 and + * 6669 can be selected.
+ *
+ * The constructor prepares a new IRC connection which can be really started + * by invoking the connect method. Before invoking it, you + * should set the IRCEventListener and other settings.
+ * Note that you do not need to set a password to connect to the large + * public IRC networks like QuakeNet, EFNet etc. To use no password in your + * IRC connection, use "" or null for the + * password argument in the constructor. + * + * @param host + * The hostname of the server we want to connect to. + * @param ports + * The portrange to which we want to connect. + * @param pass + * The password of the IRC server. If your server isn't secured + * by a password (that's normal), use null or + * "". + * @param nick + * The nickname for the connection. Is used to register the + * connection. + * @param username + * The username. Is used to register the connection. + * @param realname + * The realname. Is used to register the connection. + * @throws IllegalArgumentException + * If the host or ports is + * null or ports' length is + * 0. + * @see #connect() + */ + public IRCConnection(String host, int[] ports, String pass, String nick, String username, String realname) + { + if (host == null || ports == null || ports.length == 0) + throw new IllegalArgumentException("Host and ports may not be null."); + this._host = host; + this._ports = ports; + this._pass = (pass != null && pass.length() == 0) ? null : pass; + this._nick = nick; + this._username = username; + this._realname = realname; + } + + // ------------------------------ + /** + * Creates a new IRC connection.
+ * The difference to the other constructor is, that it transmits the ports + * as two ints. Thus, only a portrange from port + * x to port y like from port 6667 to 6669 can + * be selected.
+ *
+ * The constructor prepares a new IRC connection which can be really started + * by invoking the connect method. Before invoking it, you + * should set the IRCEventListener and other settings.
+ * Note that you do not need to set a password to connect to the large + * public IRC networks like QuakeNet, EFNet etc. To use no password in your + * IRC connection, use "" or null for the + * password argument in the constructor. + * + * @param host + * The hostname of the server we want to connect to. + * @param portMin + * The beginning of the port range we are going to connect to. + * @param portMax + * The ending of the port range we are going to connect to. + * @param pass + * The password of the IRC server. If your server isn't secured + * by a password (that's normal), use null or + * "". + * @param nick + * The nickname for the connection. Is used to register the + * connection. + * @param username + * The username. Is used to register the connection. + * @param realname + * The realname. Is used to register the connection. + * @throws IllegalArgumentException + * If the host is null. + * @see #connect() + */ + public IRCConnection(String host, int portMin, int portMax, String pass, String nick, String username, String realname) + { + this(host, portRangeToArray(portMin, portMax), pass, nick, username, realname); + } + + // ------------------------------ + /** + * Converts a portrange which starts with a given int and + * ends with a given int into an array which contains all + * ints from the beginning to the ending (including + * beginning and ending).
+ * If portMin > portMax, the portrange is turned arount + * automatically. + * + * @param portMin + * The beginning port of the portrange. + * @param portMax + * The ending port of the portrange. + */ + private static int[] portRangeToArray(int portMin, int portMax) + { + if (portMin > portMax) + { + int tmp = portMin; + portMin = portMax; + portMax = tmp; + } + int[] ports = new int[portMax - portMin + 1]; + for (int i = 0; i < ports.length; i++) + ports[i] = portMin + i; + return ports; + } + + // ------------------------------ + /** + * Establish a connection to the server.
+ * This method must be invoked to start a connection; the constructor + * doesn't do that!
+ * It tries all set ports until one is open. If all ports fail it throws an + * IOException.
+ * You can invoke connect only one time. + * + * @throws IOException + * If an I/O error occurs. + * @throws SocketException + * If the connect method was already invoked. + * @see #isConnected() + * @see #doQuit() + * @see #doQuit(String) + * @see #close() + */ + public void connect() throws IOException + { + if (level != 0) // otherwise disconnected or connect + throw new SocketException("Socket closed or already open (" + level + ")"); + IOException exception = null; + Socket s = null; + for (int i = 0; i < _ports.length && s == null; i++) + { + try + { + s = new Socket(_host, _ports[i]); + exception = null; + } + catch (IOException exc) + { + if (s != null) + s.close(); + s = null; + exception = exc; + } + } + if (exception != null) + throw exception; // connection wasn't successful at any port + prepare(s); + } + + // ------------------------------ + /** + * Invoked by the connect method, this method prepares the + * connection.
+ * It initializes the class-vars for the inputstream and the outputstream of + * the socket, starts the registration of at the IRC server by calling + * register() and starts the receiving of lines from the + * server by starting the thread with the start method.
+ *
+ * This method must be protected, because it is used by extending classes, + * which override the connect method. + * + * @param s + * The socket which is used for the connection. + * @throws IOException + * If an I/O error occurs. + * @see #connect() + * @see #run() + */ + protected void prepare(Socket s) throws IOException + { + if (s == null) + throw new SocketException("Socket s is null, not connected"); + socket = s; + level = 1; + s.setSoTimeout(timeout); + in = new BufferedReader(new InputStreamReader(s.getInputStream(), _encoding)); + out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), _encoding)); + start(); + register(); + } + + // ------------------------------ + /** + * Registers the connection with the IRC server.
+ * In fact, it sends a password (if set, else nothing), the nickname and the + * user, the realname and the host which we're connecting to.
+ * The action synchronizes code> so that no important messages + * (like the first PING) come in before this registration is finished.
+ * The USER command's format is:
+ * <username> <localhost> <irchost> <realname> + * + */ + private void register() + { + if (_pass != null) + send("PASS " + _pass); + send("NICK " + _nick); + send("USER " + _username + " " + socket.getLocalAddress() + " " + _host + " :" + _realname); + } + + // ------------------------------ + /** + * The Thread is started by the connect + * method. It's task is to receive strings from the IRC server and hand them + * over to the get method. + */ + @Override + public void run() + { + try + { + String line; + while (!isInterrupted()) + { + line = in.readLine(); + if (line != null) + get(line); + else + close(); + } + } + catch (IOException exc) + { + close(); + } + } + + // ------------------------------ + /** + * Sends a String to the server. You should use this method only, if you + * must do it. For most purposes, there are do* methods (like + * doJoin). A carriage return line feed (\r\n) + * is appended automatically. + * + * @param line + * The line which should be send to the server without the + * trailing carriage return line feed (\r\n). + */ + public void send(String line) + { + try + { + out.write(line + "\r\n"); + out.flush(); + if (level == 1) + { // not registered + IRCParser p = new IRCParser(line); + if (p.getCommand().equalsIgnoreCase("NICK")) + _nick = p.getParameter(1).trim(); + } + } + catch (Exception exc) + { + exc.printStackTrace(); + } + } + + // ------------------------------ + /** + * Just parses a String given as the only argument with the help of the + * IRCParser class. Then it controls the command and fires + * events through the IRCEventListener.
+ * + * @param line + * The line which is sent from the server. + */ + private synchronized void get(String line) + { + IRCParser p; + try + { + p = new IRCParser(line, colorsEnabled); + } + catch (Exception exc) + { + return; + } + String command = p.getCommand(); + int reply; // 3-digit reply will be parsed in the later if-condition + if (command.equalsIgnoreCase("PRIVMSG")) + { // MESSAGE + IRCUser user = p.getUser(); + String middle = p.getMiddle(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onPrivmsg(middle, user, trailing); + } + else if (command.equalsIgnoreCase("MODE")) + { // MODE + String chan = p.getParameter(1); + if (IRCUtil.isChan(chan)) + { + IRCUser user = p.getUser(); + String param2 = p.getParameter(2); + String paramsFrom3 = p.getParametersFrom(3); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onMode(chan, user, new IRCModeParser(param2, paramsFrom3)); + } + else + { + IRCUser user = p.getUser(); + String paramsFrom2 = p.getParametersFrom(2); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onMode(user, chan, paramsFrom2); + } + } + else if (command.equalsIgnoreCase("PING")) + { // PING + String ping = p.getTrailing(); // no int cause sometimes it's text + if (pongAutomatic) + doPong(ping); + else + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onPing(ping); + if (level == 1) + { // not registered + level = 2; // first PING received -> connection + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onRegistered(); + } + } + else if (command.equalsIgnoreCase("JOIN")) + { // JOIN + IRCUser user = p.getUser(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onJoin(trailing, user); + } + else if (command.equalsIgnoreCase("NICK")) + { // NICK + IRCUser user = p.getUser(); + String changingNick = p.getNick(); + String newNick = p.getTrailing(); + if (changingNick.equalsIgnoreCase(_nick)) + _nick = newNick; + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onNick(user, newNick); + } + else if (command.equalsIgnoreCase("QUIT")) + { // QUIT + IRCUser user = p.getUser(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onQuit(user, trailing); + } + else if (command.equalsIgnoreCase("PART")) + { // PART + IRCUser user = p.getUser(); + String chan = p.getParameter(1); + String msg = p.getParameterCount() > 1 ? p.getTrailing() : ""; + // not logic: "PART :#zentrum" is without msg, "PART #zentrum :cjo + // all" + // is with msg. so we cannot use getMiddle and getTrailing :-/ + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onPart(chan, user, msg); + } + else if (command.equalsIgnoreCase("NOTICE")) + { // NOTICE + IRCUser user = p.getUser(); + String middle = p.getMiddle(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onNotice(middle, user, trailing); + } + else if ((reply = IRCUtil.parseInt(command)) >= 1 && reply < 400) + { // RPL + String potNick = p.getParameter(1); + if ((level == 1 || level == 2) && _nick.length() > potNick.length() && _nick.substring(0, potNick.length()).equalsIgnoreCase(potNick)) + { + _nick = potNick; + if (level == 2) + level = 3; + } + if (level == 1) + { // not registered + level = 2; // if first PING wasn't received, we're + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onRegistered(); // connected now for sure + } + String middle = p.getMiddle(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onReply(reply, middle, trailing); + } + else if (reply >= 400 && reply < 600) + { // ERROR + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onError(reply, trailing); + } + else if (command.equalsIgnoreCase("KICK")) + { // KICK + IRCUser user = p.getUser(); + String param1 = p.getParameter(1); + String param2 = p.getParameter(2); + String msg = (p.getParameterCount() > 2) ? p.getTrailing() : ""; + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onKick(param1, user, param2, msg); + } + else if (command.equalsIgnoreCase("INVITE")) + { // INVITE + IRCUser user = p.getUser(); + String middle = p.getMiddle(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onInvite(trailing, user, middle); + } + else if (command.equalsIgnoreCase("TOPIC")) + { // TOPIC + IRCUser user = p.getUser(); + String middle = p.getMiddle(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onTopic(middle, user, trailing); + } + else if (command.equalsIgnoreCase("ERROR")) + { // ERROR + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onError(trailing); + } + else + { // OTHER + String prefix = p.getPrefix(); + String middle = p.getMiddle(); + String trailing = p.getTrailing(); + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].unknown(prefix, command, middle, trailing); + } + } + + // ------------------------------ + /** + * Close down the connection brutally.
+ * It does *NOT* send the proper IRC command QUIT. You + * should always use the doQuit methods or + * send("QUIT") instead of this method.
+ * You should use this method to close down the connection only when the IRC + * server doesn't react to the QUIT command. + * + * @see #connect() + * @see #doQuit + * @see #doQuit(String) + */ + public synchronized void close() + { + try + { + if (!isInterrupted()) + interrupt(); + } + catch (Exception exc) + { + exc.printStackTrace(); + } + try + { + if (socket != null) + socket.close(); + } + catch (Exception exc) + { + exc.printStackTrace(); + } + try + { + if (out != null) + out.close(); + } + catch (Exception exc) + { + exc.printStackTrace(); + } + try + { + if (in != null) + in.close(); + } + catch (Exception exc) + { + exc.printStackTrace(); + } + if (level != -1) + { + level = -1; + for (int i = listeners.length - 1; i >= 0; i--) + listeners[i].onDisconnected(); + } + socket = null; + in = null; + out = null; + listeners = new IRCEventListener[0]; + } + + // ------------------------------ + /** + * Adds a new {@link org.schwering.irc.lib.IRCEventListener} which listens + * for actions coming from the IRC server. + * + * @param l + * An instance of the + * {@link org.schwering.irc.lib.IRCEventListener} interface. + * @throws IllegalArgumentException + * If listener is null. + */ + public synchronized void addIRCEventListener(IRCEventListener l) + { + if (l == null) + throw new IllegalArgumentException("Listener is null."); + int len = listeners.length; + IRCEventListener[] oldListeners = listeners; + listeners = new IRCEventListener[len + 1]; + System.arraycopy(oldListeners, 0, listeners, 0, len); + listeners[len] = l; + } + + // ------------------------------ + /** + * Removes the first occurence of the given + * {@link org.schwering.irc.lib.IRCEventListener} from the listener-vector. + * + * @param l + * An instance of the + * {@link org.schwering.irc.lib.IRCEventListener} interface. + * @return true if the listener was successfully removed; + * false if it was not found. + */ + public synchronized boolean removeIRCEventListener(IRCEventListener l) + { + if (l == null) + return false; + int index = -1; + for (int i = 0; i < listeners.length; i++) + if (listeners[i].equals(l)) + { + index = i; + break; + } + if (index == -1) + return false; + listeners[index] = null; + int len = listeners.length - 1; + IRCEventListener[] newListeners = new IRCEventListener[len]; + for (int i = 0, j = 0; i < len; j++) + if (listeners[j] != null) + newListeners[i++] = listeners[j]; + listeners = newListeners; + return true; + } + + // ------------------------------ + /** + * Enables or disables the mIRC colorcodes. + * + * @param colors + * true to enable, false to disable + * colors. + */ + public void setColors(boolean colors) + { + colorsEnabled = colors; + } + + // ------------------------------ + /** + * Enables or disables the automatic PING? PONG! support. + * + * @param pong + * true to enable automatic PONG + * reply, false makes the class fire + * onPing events. + */ + public void setPong(boolean pong) + { + pongAutomatic = pong; + } + + // ------------------------------ + /** + * Changes the character encoding used to talk to the server. This can be + * ISO-8859-1 or UTF-8 for example. This property must be set before a call + * to the connect() method. + * + * @param encoding + */ + public void setEncoding(String encoding) + { + this._encoding = encoding; + } + + // ------------------------------ + /** + * Sets the connection's timeout in milliseconds.
+ * The default is 1000 * 60 15 millis which are 15 minutes. + */ + public void setTimeout(int millis) + { + if (socket != null) + try + { + socket.setSoTimeout(millis); + } + catch (IOException exc) + { + exc.printStackTrace(); + } + timeout = millis; + } + + // ------------------------------ + /** + * Tells whether there's a connection to the IRC network or not.
+ * If connect wasn't called yet, it returns + * false. + * + * @return The status of the connection; true if it's + * connected. + * @see #connect() + * @see #doQuit() + * @see #doQuit(String) + * @see #close() + */ + public boolean isConnected() + { + return level >= 1; + } + + // ------------------------------ + /** + * Returns the nickname of this instance. + * + * @return The nickname. + */ + public String getNick() + { + return _nick; + } + + // ------------------------------ + /** + * Returns the realname of this instance. + * + * @return The realname. + */ + public String getRealname() + { + return _realname; + } + + // ------------------------------ + /** + * Returns the username of this instance. + * + * @return The username. + */ + public String getUsername() + { + return _username; + } + + // ------------------------------ + /** + * Returns the server of this instance. + * + * @return The server's hostname. + */ + public String getHost() + { + return _host; + } + + // ------------------------------ + /** + * Returns the password of this instance. If no password is set, + * null is returned. + * + * @return The password. If no password is set, null is + * returned. + */ + public String getPassword() + { + return _pass; + } + + // ------------------------------ + /** + * Returns all ports to which the IRCConnection is going to + * try or has tried to connect to. + * + * @return The ports in an int[] array. + */ + public int[] getPorts() + { + return _ports; + } + + // ------------------------------ + /** + * Returns the port to which the IRCConnection connected, or + * 0 if the connection failed or wasn't tried yet. + * + * @return The port to which the IRCConnection, or + * 0 if the connection failed or wasn't tried yet. + */ + public int getPort() + { + return (socket != null) ? socket.getPort() : 0; + } + // ------------------------------ + /** + * Indicates whether colors are stripped out or not. + * + * @return true if colors are disabled. + */ + public boolean getColors() + { + return colorsEnabled; + } + + // ------------------------------ + /** + * Indicates whether automatic PING? PONG! is enabled or not. + * + * @return true if PING? PONG! is done automatically. + */ + public boolean getPong() + { + return pongAutomatic; + } + // ------------------------------ + /** + * Returns the encoding of the socket. + * + * @return The socket's encoding. + */ + public String getEncoding() + { + return _encoding; + } + + // ------------------------------ + /** + * Returns the timeout of the socket.
+ * If an error occurs, which is never the case, -1 is + * returned. + * + * @return The timeout. + */ + public int getTimeout() + { + if (socket != null) + try + { + return socket.getSoTimeout(); + } + catch (IOException exc) + { + exc.printStackTrace(); + return -1; + } + else + return timeout; + } + + // ------------------------------ + /** + * Generates a String with some information about the + * instance of IRCConnection. Its format is: + * classname[host,portMin,portMax,username,nick,realname,pass,connected] + * . + * + * @return A String with information about the instance. + */ + @Override + public String toString() + { + return getClass().getName() + "[" + _host + "," + getPort() + "," + _username + "," + _nick + "," + _realname + "," + _pass + "," + isConnected() + "]"; + } + // ------------------------------ + /** + * Removes away message. + */ + public void doAway() + { + send("AWAY"); + } + + // ------------------------------ + /** + * Sets away message. + * + * @param msg + * The away message. + */ + public void doAway(String msg) + { + send("AWAY :" + msg); + } + + // ------------------------------ + /** + * Invites a user to a channel. + * + * @param nick + * The nickname of the user who should be invited. + * @param chan + * The channel the user should be invited to. + */ + public void doInvite(String nick, String chan) + { + send("INVITE " + nick + " " + chan); + } + + // ------------------------------ + /** + * Checks if one or more nicks are used on the server. + * + * @param nick + * The nickname of the user we search for. + */ + public void doIson(String nick) + { + send("ISON " + nick); + } + + // ------------------------------ + /** + * Joins a channel without a key. + * + * @param chan + * The channel which is to join. + */ + public void doJoin(String chan) + { + send("JOIN " + chan); + } + + // ------------------------------ + /** + * Joins a channel with a key. + * + * @param chan + * The channel which is to join. + * @param key + * The key of the channel. + */ + public void doJoin(String chan, String key) + { + send("JOIN " + chan + " " + key); + } + + // ------------------------------ + /** + * Kicks a user from a channel. + * + * @param chan + * The channel somebody should be kicked from. + * @param nick + * The nickname of the user who should be kicked. + */ + public void doKick(String chan, String nick) + { + send("KICK " + chan + " " + nick); + } + + // ------------------------------ + /** + * Kicks a user from a channel with a comment. + * + * @param chan + * The channel somebody should be kicked from. + * @param nick + * The nickname of the user who should be kicked. + * @param msg + * The optional kickmessage. + */ + public void doKick(String chan, String nick, String msg) + { + send("KICK " + chan + " " + nick + " :" + msg); + } + + // ------------------------------ + /** + * Lists all channels with their topic and status. + */ + public void doList() + { + send("LIST"); + } + + // ------------------------------ + /** + * Lists channel(s) with their topic and status. + * + * @param chan + * The channel the LIST refers to. + */ + public void doList(String chan) + { + send("LIST " + chan); + } + // ------------------------------ + /** + * Lists all visible users. + */ + public void doNames() + { + send("NAMES"); + } + + // ------------------------------ + /** + * Lists all visible users of (a) channel(s). + * + * @param chan + * The channel the NAMES command is refering to. + */ + public void doNames(String chan) + { + send("NAMES " + chan); + } + // ------------------------------ + /** + * Sends a message to a person or a channel. + * + * @param target + * The nickname or channel the message should be sent to. + * @param msg + * The message which should be transmitted. + */ + public void doPrivmsg(String target, String msg) + { + send("PRIVMSG " + target + " :" + msg); + } + + // ------------------------------ + /** + * Requests a Reply 324 for the modes of a given channel. + * + * @param chan + * The channel the MODE request is refering to. + */ + public void doMode(String chan) + { + send("MODE " + chan); + } + + // ------------------------------ + /** + * Sends a mode to the server.
+ * The first argument is a nickname (user-mode) or a channel (channel-mode). + * String mode must contain the operators (+/-), the modes + * (o/v/i/k/l/p/s/w) and the possibly values (nicks/banmask/limit/key). + * + * @param target + * The nickname or channel of the user whose modes will be + * changed. + * @param mode + * The new modes. + */ + public void doMode(String target, String mode) + { + send("MODE " + target + " " + mode); + } + + // ------------------------------ + /** + * Changes the nickname. + * + * @param nick + * The new nickname. + */ + public void doNick(String nick) + { + send("NICK " + nick); + } + + // ------------------------------ + /** + * Notices a message to a person or a channel. + * + * @param target + * The nickname or channel (group) the message should be sent to. + * @param msg + * The message which should be transmitted. + */ + public void doNotice(String target, String msg) + { + send("NOTICE " + target + " :" + msg); + } + + // ------------------------------ + /** + * Parts from a given channel. + * + * @param chan + * The channel you want to part from. + */ + public void doPart(String chan) + { + send("PART " + chan); + } + // ------------------------------ + /** + * Parts from a given channel with a given parg-msg. + * + * @param chan + * The channel you want to part from. + * @param msg + * The optional partmessage. + */ + public void doPart(String chan, String msg) + { + send("PART " + chan + " :" + msg); + } + + // ------------------------------ + /** + * Quits from the IRC server with a quit-msg. + * + * @param ping + * The ping which was received in onPing. It's a + * String, because sometimes on some networks the + * server-hostname (for example splatterworld.quakenet.org) is + * given as parameter which would throw an Exception if we gave + * the ping as long. + */ + public void doPong(String ping) + { + send("PONG :" + ping); + } + + // ------------------------------ + /** + * Quits from the IRC server. Calls the disconnect-method + * which does the work actually. + * + * @see #isConnected() + * @see #connect() + * @see #doQuit(String) + * @see #close() + */ + public void doQuit() + { + send("QUIT"); + } + + // ------------------------------ + /** + * Quits from the IRC server with a quit-msg. Calls the + * disconnect-method which does the work actually. + * + * @param msg + * The optional quitmessage. + * @see #isConnected() + * @see #connect() + * @see #doQuit() + * @see #close() + */ + public void doQuit(String msg) + { + send("QUIT :" + msg); + } + // ------------------------------ + /** + * Requests the topic of a chan. The topic is given in a numeric reply. + * + * @param chan + * The channel which topic should be requested. + */ + public void doTopic(String chan) + { + send("TOPIC " + chan); + } + + // ------------------------------ + /** + * Changes the topic of a chan. + * + * @param chan + * The channel which topic is changed. + * @param topic + * The new topic. + */ + public void doTopic(String chan, String topic) + { + send("TOPIC " + chan + " :" + topic); + } + + // ------------------------------ + /** + * Requests information about users matching the given criteric, for example + * a channel they are on. + * + * @param criteric + * The criterics of the WHO query. + */ + public void doWho(String criteric) + { + send("WHO " + criteric); + } + + // ------------------------------ + /** + * Requires information about an existing user. + * + * @param nick + * The nickname of the user the query is refering to. + */ + public void doWhois(String nick) + { + send("WHOIS " + nick); + } + + // ------------------------------ + /** + * Requires host-information about a user, who is not connected anymore. + * + * @param nick + * The nickname of the user the query is refering to. + */ + public void doWhowas(String nick) + { + send("WHOWAS " + nick); + } + + // ------------------------------ + /** + * Requires host-information about up to 5 users which must be listed and + * divided by spaces. + * + * @param nick + * The nickname of the user the query is refering to. + */ + public void doUserhost(String nick) + { + send("USERHOST " + nick); + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IrcCommandHandler.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IrcCommandHandler.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IrcCommandHandler.java (revision 0) @@ -0,0 +1,93 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler; + +import java.util.Map; +import java.util.logging.Logger; + +import javolution.util.FastMap; +import net.sf.l2j.Config; +import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcAnnounce; +import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcJail; +import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcKick; +import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcShutdown; +import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcStatus; + +/** + * @author nBd + */ + +public class IrcCommandHandler +{ + private static Logger _log = Logger.getLogger(IrcCommandHandler.class.getName()); + + private static IrcCommandHandler _instance; + + private Map _datatable; + + public static IrcCommandHandler getInstance() + { + if (_instance == null) + { + _instance = new IrcCommandHandler(); + } + return _instance; + } + + private IrcCommandHandler() + { + _datatable = new FastMap(); + registerIrcCommandHandler(new IrcAnnounce()); + registerIrcCommandHandler(new IrcShutdown()); + registerIrcCommandHandler(new IrcStatus()); + registerIrcCommandHandler(new IrcKick()); + registerIrcCommandHandler(new IrcJail()); + _log.config("BypassCommandHandler: Loaded " + _datatable.size() + " handlers."); + } + + public void registerIrcCommandHandler(IIrcCommandHandler handler) + { + String[] ids = handler.getIrcCommandList(); + + for (String element : ids) + { + if (Config.DEBUG) _log.fine("Adding handler for command "+element); + _datatable.put(element, handler); + } + } + + public IIrcCommandHandler getIrcCommandHandler(String BypassCommand) + { + String command = BypassCommand; + + if (BypassCommand.indexOf(" ") != -1) + { + command = BypassCommand.substring(0, BypassCommand.indexOf(" ")); + } + + if (Config.DEBUG) + _log.fine("getting handler for command: "+command+ " -> "+(_datatable.get(command) != null)); + + return _datatable.get(command); + } + + /** + * @return + */ + public int size() + { + return _datatable.size(); + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcKick.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcKick.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcKick.java (revision 0) @@ -0,0 +1,90 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler.irccommandhandlers; + +import java.util.NoSuchElementException; +import java.util.StringTokenizer; +import net.sf.l2j.gameserver.handler.IIrcCommandHandler; +import net.sf.l2j.gameserver.instancemanager.IrcManager; +import net.sf.l2j.gameserver.model.L2World; +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; +import net.sf.l2j.gameserver.serverpackets.LeaveWorld; + +/** + * @author Daedalus + */ +public class IrcKick implements IIrcCommandHandler +{ + private static final String[] IRC_COMMANDS = + { + "!kick","!kick_nongm" + }; + + public boolean useIrcCommand(String command, String gm, String target, boolean authed) + { + if (!authed) + return false; + + StringTokenizer st = new StringTokenizer(command); + st.nextToken(); + String player = ""; + + if (command.startsWith("!kick_nongm")) + { + int counter = 0; + for (L2PcInstance plyr : L2World.getInstance().getAllPlayers()) + { + if(!plyr.isGM()) + { + counter++; + plyr.sendPacket(new LeaveWorld()); + plyr.logout(); + } + } + IrcManager.getInstance().getConnection().sendAdminChan("Kicked "+counter+" players"); + } + else if (command.startsWith("!kick")) + { + try + { + player = st.nextToken(); + L2PcInstance plyr = L2World.getInstance().getPlayer(player); + if (plyr != null) + { + plyr.logout(); + IrcManager.getInstance().getConnection().sendAdminChan("You kicked " + plyr.getName() + " from the game."); + } + } + catch (NoSuchElementException nsee) + { + IrcManager.getInstance().getConnection().sendAdminChan("Specify a character name."); + } + catch (NumberFormatException nfe) + { + IrcManager.getInstance().getConnection().sendAdminChan("Usage: !kick "); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + return true; + } + + public String[] getIrcCommandList() + { + return IRC_COMMANDS; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcStatus.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcStatus.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcStatus.java (revision 0) @@ -0,0 +1,152 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler.irccommandhandlers; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import net.sf.l2j.gameserver.GameServer; +import net.sf.l2j.gameserver.GameTimeController; +import net.sf.l2j.gameserver.GmListTable; +import net.sf.l2j.gameserver.LoginServerThread; +import net.sf.l2j.gameserver.handler.IIrcCommandHandler; +import net.sf.l2j.gameserver.instancemanager.IrcManager; +import net.sf.l2j.gameserver.model.L2Character; +import net.sf.l2j.gameserver.model.L2ItemInstance; +import net.sf.l2j.gameserver.model.L2Object; +import net.sf.l2j.gameserver.model.L2Summon; +import net.sf.l2j.gameserver.model.L2World; +import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance; +import net.sf.l2j.gameserver.model.actor.instance.L2MonsterInstance; +import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance; +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; + +/** + * @author nBd + */ + +public class IrcStatus implements IIrcCommandHandler +{ + private static final String[] IRC_COMMANDS = + { + "!status" + }; + + @SuppressWarnings("deprecation") + public boolean useIrcCommand(String command, String gm, String target, boolean authed) + { + if (!authed) + return false; + + if (command.equalsIgnoreCase("!status")) + { + int playerCount = 0, objectCount = 0; + int max = LoginServerThread.getInstance().getMaxPlayer(); + playerCount = L2World.getInstance().getAllPlayersCount(); + objectCount = L2World.getInstance().getAllVisibleObjectsCount(); + int itemCount = 0; + int itemVoidCount = 0; + int monsterCount = 0; + int minionCount = 0; + int minionsGroupCount = 0; + int npcCount = 0; + int charCount = 0; + int pcCount = 0; + int doorCount = 0; + int summonCount = 0; + int AICount = 0; + for (L2Object obj : L2World.getInstance().getAllVisibleObjects()) + { + if (obj == null) + continue; + if (obj instanceof L2Character) + if (((L2Character) obj).hasAI()) + AICount++; + if (obj instanceof L2ItemInstance) + if (((L2ItemInstance) obj).getLocation() == L2ItemInstance.ItemLocation.VOID) + itemVoidCount++; + else + itemCount++; + else if (obj instanceof L2MonsterInstance) + { + monsterCount++; + minionCount += ((L2MonsterInstance) obj).getTotalSpawnedMinionsInstances(); + minionsGroupCount += ((L2MonsterInstance) obj).getTotalSpawnedMinionsGroups(); + } + else if (obj instanceof L2NpcInstance) + npcCount++; + else if (obj instanceof L2PcInstance) + pcCount++; + else if (obj instanceof L2Summon) + summonCount++; + else if (obj instanceof L2DoorInstance) + doorCount++; + else if (obj instanceof L2Character) + charCount++; + } + IrcManager.getInstance().getConnection().sendAdminChan("Server Status: "); + IrcManager.getInstance().getConnection().sendAdminChan(" ---> Player Count: " + playerCount + "/" + max); + IrcManager.getInstance().getConnection().sendAdminChan(" +--> Object Count: " + objectCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +--> AI Count: " + AICount); + IrcManager.getInstance().getConnection().sendAdminChan(" +.... L2Item(Void): " + itemVoidCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +.......... L2Item: " + itemCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +....... L2Monster: " + monsterCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +......... Minions: " + minionCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +.. Minions Groups: " + minionsGroupCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +........... L2Npc: " + npcCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +............ L2Pc: " + pcCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +........ L2Summon: " + summonCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +.......... L2Door: " + doorCount); + IrcManager.getInstance().getConnection().sendAdminChan(" +.......... L2Char: " + charCount); + IrcManager.getInstance().getConnection().sendAdminChan(" ---> Ingame Time: " + gameTime()); + IrcManager.getInstance().getConnection().sendAdminChan(" ---> Server Uptime: " + getUptime(GameServer.dateTimeServerStarted.getTimeInMillis())); + IrcManager.getInstance().getConnection().sendAdminChan(" ---> GM Count: " + getOnlineGMS()); + IrcManager.getInstance().getConnection().sendAdminChan(" ---> Threads: " + Thread.activeCount()); + IrcManager.getInstance().getConnection().sendAdminChan(" RAM Used: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576)); + } + return true; + } + + private String gameTime() + { + int t = GameTimeController.getInstance().getGameTime(); + int h = t / 60; + int m = t % 60; + SimpleDateFormat format = new SimpleDateFormat("H:mm"); + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, h); + cal.set(Calendar.MINUTE, m); + return format.format(cal.getTime()); + } + + private String getUptime(long time) + { + long uptime = (System.currentTimeMillis() - time); + uptime = uptime / 1000; + long h = uptime / 3600; + long m = (uptime-(h*3600))/60; + long s = ((uptime-(h*3600))-(m*60)); + return h + "hrs " + m + "mins " + s + "secs"; + } + + private int getOnlineGMS() + { + return GmListTable.getInstance().getAllGms(true).size(); + } + + public String[] getIrcCommandList() + { + return IRC_COMMANDS; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcAnnounce.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcAnnounce.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcAnnounce.java (revision 0) @@ -0,0 +1,46 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler.irccommandhandlers; + +import net.sf.l2j.gameserver.Announcements; +import net.sf.l2j.gameserver.handler.IIrcCommandHandler; + +/** + * @author nBd + */ +public class IrcAnnounce implements IIrcCommandHandler +{ + private static final String[] IRC_COMMANDS = + { + "!announce" + }; + + public boolean useIrcCommand(String command, String gm, String target, boolean authed) + { + if (!authed) + return false; + + if (command.startsWith("!announce ")) + { + Announcements.getInstance().handleAnnounce(command, 10); + } + return true; + } + + public String[] getIrcCommandList() + { + return IRC_COMMANDS; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcShutdown.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcShutdown.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcShutdown.java (revision 0) @@ -0,0 +1,57 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler.irccommandhandlers; + +import net.sf.l2j.gameserver.Shutdown; +import net.sf.l2j.gameserver.handler.IIrcCommandHandler; + +/** + * @author nBd + */ + +public class IrcShutdown implements IIrcCommandHandler +{ + private static final String[] IRC_COMMANDS = + { + "!shutdown", "!restart", "!abort" + }; + + public boolean useIrcCommand(String command, String gm, String target, boolean authed) + { + if (!authed) + return false; + + if (command.startsWith("!shutdown ")) + { + int val = Integer.parseInt(command.substring(10)); + Shutdown.getInstance().startShutdown(gm, val, false); + } + else if (command.startsWith("!restart ")) + { + int val = Integer.parseInt(command.substring(9)); + Shutdown.getInstance().startShutdown(gm, val, true); + } + else if (command.equalsIgnoreCase("!abort")) + { + Shutdown.getInstance().abort(gm); + } + return true; + } + + public String[] getIrcCommandList() + { + return IRC_COMMANDS; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcJail.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcJail.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcJail.java (revision 0) @@ -0,0 +1,188 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler.irccommandhandlers; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; +import net.sf.l2j.Config; +import net.sf.l2j.L2DatabaseFactory; +import net.sf.l2j.gameserver.handler.IIrcCommandHandler; +import net.sf.l2j.gameserver.instancemanager.IrcManager; +import net.sf.l2j.gameserver.model.L2World; +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; + +/** + * @author Daedalus + */ +public class IrcJail implements IIrcCommandHandler +{ + private static final String[] IRC_COMMANDS = + { + "!jail", "!unjail" + }; + + public boolean useIrcCommand(String command, String gm, String target, boolean authed) + { + if (!authed) + return false; + + StringTokenizer st = new StringTokenizer(command); + st.nextToken(); + String player = ""; + + if (command.startsWith("!jail")) + { + try + { + player = st.nextToken(); + int delay = 0; + try + { + delay = Integer.parseInt(st.nextToken()); + } + catch (NumberFormatException nfe) + { + IrcManager.getInstance().getConnection().sendAdminChan("Usage: !jail [penalty_minutes]"); + } + catch (NoSuchElementException nsee) + { + } + L2PcInstance playerObj = L2World.getInstance().getPlayer(player); + if (playerObj != null) + { + playerObj.setInJail(true, delay); + IrcManager.getInstance().getConnection().sendAdminChan("Character " + player + " has been jailed for " + (delay > 0 ? delay + " minutes!" : "ever!")); + } + else + IRCjailOfflinePlayer(player, delay); + } + catch (NoSuchElementException nsee) + { + IrcManager.getInstance().getConnection().sendAdminChan("Usage: !jail [penalty_minutes]"); + } + catch (Exception e) + { + if (Config.DEBUG) + e.printStackTrace(); + } + } + else if (command.startsWith("!unjail")) + { + try + { + player = st.nextToken(); + L2PcInstance playerObj = L2World.getInstance().getPlayer(player); + if (playerObj != null) + { + playerObj.setInJail(false, 0); + IrcManager.getInstance().getConnection().sendAdminChan("Character "+player+" removed from jail"); + } + else + IRCunjailOfflinePlayer(player); + } + catch (NoSuchElementException nsee) + { + IrcManager.getInstance().getConnection().sendAdminChan("Specify a character name."); + } + catch (Exception e) + { + if (Config.DEBUG) + e.printStackTrace(); + } + } + return true; + } + private void IRCjailOfflinePlayer(String name, int delay) + { + Connection con = null; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + + PreparedStatement statement = con.prepareStatement("UPDATE characters SET x=?, y=?, z=?, in_jail=?, jail_timer=? WHERE char_name=?"); + statement.setInt(1, -114356); + statement.setInt(2, -249645); + statement.setInt(3, -2984); + statement.setInt(4, 1); + statement.setLong(5, delay * 60000L); + statement.setString(6, name); + + statement.execute(); + int count = statement.getUpdateCount(); + statement.close(); + + if (count == 0) + IrcManager.getInstance().getConnection().sendAdminChan("Character not found!"); + else + IrcManager.getInstance().getConnection().sendAdminChan("Character "+name+" jailed for "+(delay>0 ? delay+" minutes." : "ever!")); + } catch (SQLException se) + { + IrcManager.getInstance().getConnection().sendAdminChan("SQLException while jailing player"); + if (Config.DEBUG) se.printStackTrace(); + } finally + { + try { con.close(); } catch (Exception e) + { + if (Config.DEBUG) + e.printStackTrace(); + } + } + } + + private void IRCunjailOfflinePlayer(String name) + { + Connection con = null; + try + { + con = L2DatabaseFactory.getInstance().getConnection(); + PreparedStatement statement = con.prepareStatement("UPDATE characters SET x=?, y=?, z=?, in_jail=?, jail_timer=? WHERE char_name=?"); + statement.setInt(1, 17836); + statement.setInt(2, 170178); + statement.setInt(3, -3507); + statement.setInt(4, 0); + statement.setLong(5, 0); + statement.setString(6, name); + statement.execute(); + int count = statement.getUpdateCount(); + statement.close(); + if (count == 0) + IrcManager.getInstance().getConnection().sendAdminChan("Character not found!"); + else + IrcManager.getInstance().getConnection().sendAdminChan("Character "+name+" removed from jail"); + } catch (SQLException se) + { + IrcManager.getInstance().getConnection().sendAdminChan("SQLException while jailing player"); + if (Config.DEBUG) se.printStackTrace(); + } finally + { + try + { + con.close(); + } + catch (Exception e) + { + if (Config.DEBUG) + e.printStackTrace(); + } + } + } + public String[] getIrcCommandList() + { + return IRC_COMMANDS; + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IIrcCommandHandler.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IIrcCommandHandler.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IIrcCommandHandler.java (revision 0) @@ -0,0 +1,36 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.handler; + +/** + * + * @author nBd + */ +public interface IIrcCommandHandler +{ + /** + * this is the worker method that is called when someone uses an bypass command. + * @param activeChar + * @param command + * @return command success + */ + public boolean useIrcCommand(String command, String gm, String target, boolean authed); + + /** + * this method is called at initialization to register all the item ids automatically + * @return all known itemIds + */ + public String[] getIrcCommandList(); +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/GameServer.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/GameServer.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/GameServer.java (working copy) @@ -60,6 +60,7 @@ import net.sf.l2j.gameserver.geoeditorcon.GeoEditorListener; import net.sf.l2j.gameserver.handler.AdminCommandHandler; import net.sf.l2j.gameserver.handler.ItemHandler; +import net.sf.l2j.gameserver.handler.IrcCommandHandler; import net.sf.l2j.gameserver.handler.SkillHandler; import net.sf.l2j.gameserver.handler.UserCommandHandler; import net.sf.l2j.gameserver.handler.VoicedCommandHandler; @@ -216,6 +217,7 @@ import net.sf.l2j.gameserver.instancemanager.FortManager; import net.sf.l2j.gameserver.instancemanager.FortSiegeManager; import net.sf.l2j.gameserver.instancemanager.GrandBossManager; +import net.sf.l2j.gameserver.instancemanager.IrcManager; import net.sf.l2j.gameserver.instancemanager.ItemsOnGroundManager; import net.sf.l2j.gameserver.instancemanager.MercTicketManager; import net.sf.l2j.gameserver.instancemanager.PetitionManager; @@ -637,6 +639,8 @@ if(Config.L2JMOD_ALLOW_WEDDING) CoupleManager.getInstance(); + + IrcCommandHandler.getInstance(); TaskManager.getInstance(); @@ -733,8 +737,11 @@ _statusServer = new Status(Server.serverMode); _statusServer.start(); } - else { + else + { _log.info("Telnet server is currently disabled."); } + if (Config.IRC_ENABLED) + IrcManager.getInstance().getConnection().sendChan("GameServer Started"); } } Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/instancemanager/IrcManager.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/instancemanager/IrcManager.java (revision 0) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/instancemanager/IrcManager.java (revision 0) @@ -0,0 +1,102 @@ +/* + * 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 3 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, see . + */ +package net.sf.l2j.gameserver.instancemanager; +import java.util.logging.Logger; + +import net.sf.l2j.Config; +import net.sf.l2j.gameserver.network.L2IrcClient; +/** + * @author evill33t + * + */ +public class IrcManager +{ + private static final Logger _log = Logger.getLogger(IrcManager.class.getName()); + + // ========================================================= + private static IrcManager _Instance; + + private static L2IrcClient _IrcConnection; + + public static final IrcManager getInstance() + { + if (_Instance == null) + { + _log.info("Initializing IrcManager"); + _Instance = new IrcManager(); + _Instance.load(); + } + return _Instance; + } + + // ========================================================= + // ========================================================= + // Method - Public + public void reload() + { + _IrcConnection.disconnect(); + try + { + _IrcConnection.connect(); + } + catch (Exception e) + { + _log.warning(e.toString()); + } + } + + public void reConnect() + { + _IrcConnection = null; + _IrcConnection = new L2IrcClient(Config.IRC_SERVER, Config.IRC_PORT, Config.IRC_PASS, Config.IRC_NICK, Config.IRC_USER, + Config.IRC_NAME, Config.IRC_SSL, Config.IRC_CHANNEL); + try + { + _IrcConnection.connect(); + } + catch (Exception e) + { + _log.warning(e.toString()); + } + } + + public L2IrcClient getConnection() + { + return _IrcConnection; + } + + public void removeConnection() + { + _IrcConnection.disconnect(); + _IrcConnection = null; + load(); + } + + // ========================================================= + // Method - Private + private final void load() + { + _IrcConnection = new L2IrcClient(Config.IRC_SERVER, Config.IRC_PORT, Config.IRC_PASS, Config.IRC_NICK, Config.IRC_USER, + Config.IRC_NAME, Config.IRC_SSL, Config.IRC_CHANNEL); + try + { + _IrcConnection.connect(); + } + catch (Exception e) + { + _log.warning(e.toString()); + } + } +} Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/util/IllegalPlayerAction.java =================================================================== --- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/util/IllegalPlayerAction.java (revision 62) +++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/util/IllegalPlayerAction.java (working copy) @@ -30,6 +30,7 @@ import net.sf.l2j.Config; import net.sf.l2j.gameserver.GmListTable; +import net.sf.l2j.gameserver.instancemanager.IrcManager; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; /** @@ -77,6 +78,9 @@ record.setLoggerName("audit"); record.setParameters(new Object[]{_actor, _punishment}); _logAudit.log(record); + + if (Config.IRC_ENABLED) + IrcManager.getInstance().getConnection().sendAdminChan("4Warning: " + _message); GmListTable.broadcastMessageToGMs(_message);