/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.impl.protocol.irc; import java.io.*; import java.util.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; import org.jibble.pircbot.*; /** * An implementation of the PircBot IRC stack. * * @author Stephane Remy * @author Loic Kempf * @author Yana Stamcheva */ public class IrcStack extends PircBot { private static final Logger logger = Logger.getLogger(IrcStack.class); /** * Timeout for server response. */ private int timeout = 5000; /** * A list of timers indicating when a chat room join fails. */ private Hashtable joinTimeoutTimers = new Hashtable(); /** * A list of the channels on this server */ private List serverChatRoomList = new ArrayList(); /** * A list of users that we have info about, it is used to stock "whois" * responses */ private Hashtable userInfoTable = new Hashtable(); /** * The IRC multi-user chat operation set. */ private OperationSetMultiUserChatIrcImpl ircMUCOpSet; /** * The IRC protocol provider service. */ private ProtocolProviderServiceIrcImpl parentProvider; private Object operationLock = new Object(); /** * The operation response code indicates */ private int operationResponseCode = 0; /** * Creates an instance of IrcStack. * * @param parentProvider the IRC protocol provider service * @param nickname our nickname * @param login our login * @param version the version * @param finger the finger */ public IrcStack( ProtocolProviderServiceIrcImpl parentProvider, String nickname, String login, String version, String finger) { this.parentProvider = parentProvider; this.ircMUCOpSet = (OperationSetMultiUserChatIrcImpl) parentProvider .getOperationSet(OperationSetMultiUserChat.class); this.setName(nickname); this.setLogin(login); this.setVersion(version); this.setFinger(finger); } /** * Connects to the server. * * @param serverAddress the address of the server * @param serverPort the port to connect to * @param serverPassword the password to use for connect * @param autoNickChange indicates if the nick name should be changed in * case there exist already a participant with the same nick name * * @throws OperationFailedException */ public void connect(String serverAddress, int serverPort, String serverPassword, boolean autoNickChange) throws OperationFailedException { this.setVerbose(false); this.setAutoNickChange(autoNickChange); try { if (serverPassword == null) { this.connect(serverAddress, serverPort); } else this.connect(serverAddress, serverPort, serverPassword); } catch (IOException e) { throw new OperationFailedException(e.getMessage(), OperationFailedException.INTERNAL_SERVER_ERROR); } catch (NickAlreadyInUseException e) { throw new OperationFailedException(e.getMessage(), OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS); } catch (IrcException e) { throw new OperationFailedException(e.getMessage(), OperationFailedException.GENERAL_ERROR); } } /** * Called when we're connected to the IRC server. */ protected void onConnect() { RegistrationState oldState = parentProvider.getCurrentRegistrationState(); parentProvider.setCurrentRegistrationState(RegistrationState.REGISTERED); parentProvider.fireRegistrationStateChanged( oldState, RegistrationState.REGISTERED, RegistrationStateChangeEvent.REASON_USER_REQUEST, null); // Obtain information for all channels on this server. this.listChannels(); } /** * Indicates that a message has arrived from the IRC stack. */ protected void onMessage( String channel, String sender, String login, String hostname, String messageContent) { logger.trace("MESSAGE received in chat room : " + channel + ": from " + sender + " " + login + "@" + hostname + " the message: " + messageContent); MessageIrcImpl message = new MessageIrcImpl( messageContent, MessageIrcImpl.DEFAULT_MIME_TYPE, MessageIrcImpl.DEFAULT_MIME_ENCODING, null); ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel); if (chatRoom == null) chatRoom = (ChatRoomIrcImpl) ircMUCOpSet.findSystemRoom(); if(chatRoom == null || !chatRoom.isJoined()) return; ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sender); if (sourceMember == null) return; chatRoom.fireMessageReceivedEvent( message, sourceMember, new Date(System.currentTimeMillis()), ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED); } /** * Indicates that a private message has been received. * Note that for now this method only logs the message. */ protected void onPrivateMessage(String sender, String login, String hostname, String messageContent) { logger.trace("PRIVATE MESSAGE received from " + sender + " " + login + "@" + hostname + " the message: " + messageContent); MessageIrcImpl message = new MessageIrcImpl( messageContent, MessageIrcImpl.DEFAULT_MIME_TYPE, MessageIrcImpl.DEFAULT_MIME_ENCODING, null); ChatRoomIrcImpl chatRoom = ircMUCOpSet.findPrivateChatRoom(sender); if(chatRoom == null || !chatRoom.isJoined()) return; ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sender); if (sourceMember == null) { sourceMember = new ChatRoomMemberIrcImpl(parentProvider, chatRoom, sender, login, hostname, ChatRoomMemberRole.GUEST); chatRoom.addChatRoomMember(sender, sourceMember); chatRoom.fireMemberPresenceEvent( sourceMember, null, // There's no other actors in this presence event. ChatRoomMemberPresenceChangeEvent.MEMBER_JOINED, "A message received from unknown member."); } chatRoom.fireMessageReceivedEvent( message, sourceMember, new Date(System.currentTimeMillis()), ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED); } /** * This method is called whenever an ACTION is sent from a user. E.g. * such events generated by typing "/me goes shopping" in most IRC clients. * * @param sender The nick of the user that sent the action. * @param login The login of the user that sent the action. * @param hostname The host name of the user that sent the action. * @param target The target of the action, be it a channel or our nick. * @param action The action carried out by the user. */ protected void onAction(String sender, String login, String hostname, String target, String action) { logger.trace("ACTION on " + target + " : Received from " + sender + " " + login + "@" + hostname + " the action: " + action); MessageIrcImpl actionMessage = new MessageIrcImpl( action, MessageIrcImpl.DEFAULT_MIME_TYPE, MessageIrcImpl.DEFAULT_MIME_ENCODING, null); // We presume that the target is a chat room, as we have not yet // implemented private messages. ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(target); if (chatRoom == null) chatRoom = (ChatRoomIrcImpl) ircMUCOpSet.findSystemRoom(); if(chatRoom == null || !chatRoom.isJoined()) return; ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sender); if (sourceMember == null) return; chatRoom.fireMessageReceivedEvent( actionMessage, sourceMember, new Date(System.currentTimeMillis()), ChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED); } /** * After calling the listChannels() method in PircBot, the server * will start to send us information about each channel on the * server. * * @param channel The name of the channel. * @param userCount The number of users visible in this channel. * @param topic The topic for this channel. */ protected void onChannelInfo(String channel, int userCount, String topic) { this.addServerChatRoom(channel); } /** * Called when a user (possibly us) gets operator status taken away. *
* This is a type of mode change and is also passed to the onMode * method in the PircBot class. * * @param channel The channel in which the mode change took place. * @param sourceNick The nick of the user that performed the mode change. * @param sourceLogin The login of the user that performed the mode change. * @param sourceHostname The host name of the user that performed the mode * change. * @param recipient The nick of the user that got 'de-opp-ed'. */ protected void onDeop( String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) { logger.trace("DEOP on " + channel + ": Received from " + sourceNick + " " + sourceLogin + "@" + sourceHostname + "on " + recipient); ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel); if (chatRoom == null || !chatRoom.isJoined()) return; ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sourceNick); if (sourceMember == null) return; chatRoom.fireMemberRoleEvent(sourceMember, ChatRoomMemberRole.GUEST); } /** * Called when a user (possibly us) gets voice status removed. *
* This is a type of mode change and is also passed to the onMode * method in the PircBot class. * * @param channel The channel in which the mode change took place. * @param sourceNick The nick of the user that performed the mode change. * @param sourceLogin The login of the user that performed the mode change. * @param sourceHostname The host name of the user that performed the mode * change. * @param recipient The nick of the user that got 'de-voiced'. */ protected void onDeVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) { if (logger.isDebugEnabled()) logger.debug("DEVOICE on " + channel + ": Received from " + sourceNick + " " + sourceLogin + "@" + sourceHostname + "on " + recipient); ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel); if (chatRoom == null || !chatRoom.isJoined()) return; ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sourceNick); if (sourceMember == null) return; chatRoom.fireMemberRoleEvent( sourceMember, ChatRoomMemberRole.SILENT_MEMBER); } /** * Called when we are invited to a channel by a user. * * @param targetNick The nick of the user being invited - should be us! * @param sourceNick The nick of the user that sent the invitation. * @param sourceLogin The login of the user that sent the invitation. * @param sourceHostname The host name of the user that sent the invitation. * @param channel The channel that we're being invited to. */ protected void onInvite(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String channel) { if (logger.isDebugEnabled()) logger.debug("INVITE on " + channel + ": Received from " + sourceNick + " " + sourceLogin + "@" + sourceHostname); ChatRoom targetChatRoom = ircMUCOpSet.findRoom(channel); ircMUCOpSet.fireInvitationEvent(targetChatRoom, sourceNick, "", null); } /** * This method is called whenever someone (possibly us) joins a channel * which we are on. * * @param channel The channel which somebody joined. * @param sender The nick of the user who joined the channel. * @param login The login of the user who joined the channel. * @param hostname The host name of the user who joined the channel. */ protected void onJoin( String channel, String sender, String login, String hostname) { if (logger.isDebugEnabled()) logger.debug("JOIN on " + channel + ": Received from " + sender + " " + login + "@" + hostname); ChatRoomIrcImpl chatRoom = (ChatRoomIrcImpl) ircMUCOpSet.findRoom(channel); if(chatRoom.getUserNickname().equals(sender)) ircMUCOpSet.fireLocalUserPresenceEvent( chatRoom, LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_JOINED, ""); else { ChatRoomMemberIrcImpl member = new ChatRoomMemberIrcImpl( parentProvider, chatRoom, sender, login, hostname, ChatRoomMemberRole.GUEST); chatRoom.addChatRoomMember(sender, member); //we don't specify a reason chatRoom.fireMemberPresenceEvent( member, null, ChatRoomMemberPresenceChangeEvent.MEMBER_JOINED, null); } } /** * This method is called whenever someone (possibly us) is kicked from * any of the channels that we are in. * * @param channel The channel from which the recipient was kicked. * @param kickerNick The nick of the user who performed the kick. * @param kickerLogin The login of the user who performed the kick. * @param kickerHostname The host name of the user who performed the kick. * @param recipientNick The unfortunate recipient of the kick. * @param reason The reason given by the user who performed the kick. */ protected void onKick( String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) { logger.trace("KICK on " + channel + ": Received from " + kickerNick + " " + kickerLogin + "@" + kickerHostname); ChatRoomIrcImpl chatRoom = (ChatRoomIrcImpl) ircMUCOpSet.getChatRoom(channel); if (chatRoom == null || !chatRoom.isJoined()) return; if(chatRoom.getUserNickname().equals(kickerNick)) { notifyChatRoomOperation(0); } if(chatRoom.getUserNickname().equals(recipientNick)) ircMUCOpSet.fireLocalUserPresenceEvent( chatRoom, LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_KICKED, reason); else { ChatRoomMember member = chatRoom.getChatRoomMember(recipientNick); ChatRoomMember actorMember = chatRoom.getChatRoomMember(kickerNick); chatRoom.removeChatRoomMember(recipientNick); chatRoom.fireMemberPresenceEvent( member, actorMember, ChatRoomMemberPresenceChangeEvent.MEMBER_KICKED, reason); } } /** * This method is called whenever someone (possibly us) changes nick on any * of the channels that we are on. * * @param oldNick The old nick. * @param login The login of the user. * @param hostname The host name of the user. * @param newNick The new nick. */ protected void onNickChange(String oldNick, String login, String hostname, String newNick) { logger.trace("NICK changed: from " + oldNick + " changed to " + newNick); this.notifyChatRoomOperation(0); Iterator joinedChatRoomsIter = ircMUCOpSet.getCurrentlyJoinedChatRooms().iterator(); while (joinedChatRoomsIter.hasNext()) { ChatRoomIrcImpl chatRoom = (ChatRoomIrcImpl) joinedChatRoomsIter.next(); ChatRoomMember member = chatRoom.getChatRoomMember(oldNick); if (member == null) continue; ChatRoomMemberPropertyChangeEvent evt = new ChatRoomMemberPropertyChangeEvent( member, chatRoom, ChatRoomMemberPropertyChangeEvent.MEMBER_NICKNAME, oldNick, newNick); chatRoom.fireMemberPropertyChangeEvent(evt); } } /** * This method is called whenever we receive a notice. * * @param sourceNick The nick of the user that sent the notice. * @param sourceLogin The login of the user that sent the notice. * @param sourceHostname The host name of the user that sent the notice. * @param target The target of the notice, be it our nick or a channel name. * @param notice The notice message. */ protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) { logger.trace("NOTICE on " + target + ": Received from " + sourceNick + " " + sourceLogin + "@" + sourceHostname + " the message: " + notice); MessageIrcImpl message = new MessageIrcImpl( notice, MessageIrcImpl.DEFAULT_MIME_TYPE, MessageIrcImpl.DEFAULT_MIME_ENCODING, null); // We consider that the target is always a chat room. ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(target); if(chatRoom == null || !chatRoom.isJoined()) chatRoom = (ChatRoomIrcImpl) ircMUCOpSet.findSystemRoom(); ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sourceNick); if (sourceMember == null) return; chatRoom.fireMessageReceivedEvent( message, sourceMember, new Date(System.currentTimeMillis()), ChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED); } /** * Called when a user (possibly us) gets granted operator status for a * channel. *
* This is a type of mode change and is also passed to the onMode * method in the PircBot class. * * @param channel The channel in which the mode change took place. * @param sourceNick The nick of the user that performed the mode change. * @param sourceLogin The login of the user that performed the mode change. * @param sourceHostname The host name of the user that performed the mode * change. * @param recipient The nick of the user that got 'opp-ed'. */ protected void onOp(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) { if (logger.isDebugEnabled()) logger.debug("MODE OP on " + channel + ": from " + sourceNick + " " + sourceLogin + "@" + sourceHostname + " on " + recipient); ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel); if (chatRoom == null || !chatRoom.isJoined()) return; ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sourceNick); if (sourceMember == null) return; chatRoom.fireMemberRoleEvent( sourceMember, ChatRoomMemberRole.ADMINISTRATOR); } /** * This method is called whenever someone (possibly us) leaves a channel * which we are on. * * @param channel The channel which somebody parted from. * @param sender The nick of the user who parted from the channel. * @param login The login of the user who parted from the channel. * @param hostname The host name of the user who parted from the channel. */ protected void onPart( String channel, String sender, String login, String hostname) { if (logger.isDebugEnabled()) logger.debug("LEAVE on " + channel + ": Received from " + sender + " " + login + "@" + hostname); ChatRoomIrcImpl chatRoom = (ChatRoomIrcImpl) ircMUCOpSet.findRoom(channel); if(chatRoom.getUserNickname().equals(sender)) ircMUCOpSet.fireLocalUserPresenceEvent( chatRoom, LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_LEFT, ""); else { ChatRoomMember member = chatRoom.getChatRoomMember(sender); if (member == null) return; chatRoom.removeChatRoomMember(sender); //we don't specify a reason chatRoom.fireMemberPresenceEvent( member, null, ChatRoomMemberPresenceChangeEvent.MEMBER_LEFT, null); } } /** * This method is called whenever someone (possibly us) quits from the * server. We will only observe this if the user was in one of the * channels to which we are connected. * * @param sourceNick The nick of the user that quit from the server. * @param sourceLogin The login of the user that quit from the server. * @param sourceHostname The host name of the user that quit from the server. * @param reason The reason given for quitting the server. */ protected void onQuit( String sourceNick, String sourceLogin, String sourceHostname, String reason) { if (logger.isDebugEnabled()) logger.debug("QUIT : Received from " + sourceNick + " " + sourceLogin + "@" + sourceHostname); Iterator joinedChatRooms = ircMUCOpSet.getCurrentlyJoinedChatRooms().iterator(); while (joinedChatRooms.hasNext()) { ChatRoomIrcImpl chatRoom = (ChatRoomIrcImpl) joinedChatRooms.next(); if(chatRoom.getUserNickname().equals(sourceNick)) ircMUCOpSet.fireLocalUserPresenceEvent( chatRoom, LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_DROPPED, reason); else { ChatRoomMember member = chatRoom.getChatRoomMember(sourceNick); if (member == null) return; chatRoom.removeChatRoomMember(sourceNick); chatRoom.fireMemberPresenceEvent( member, null, ChatRoomMemberPresenceChangeEvent.MEMBER_QUIT, reason); } } } /** * Called when a host mask ban is removed from a channel. *
* This is a type of mode change and is also passed to the onMode
* method in the PircBot class.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
* @param hostmask
*/
protected void onRemoveChannelBan( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname,
String hostmask)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
ChatRoom chatRoom = ircMUCOpSet.getChatRoom(channel);
if (chatRoom == null)
return;
//TODO: Implement IrcStack.onRemoveChannelBan.
}
/**
* Called when a channel key is removed.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
* @param key The key that was in use before the channel key was removed.
*/
protected void onRemoveChannelKey( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname,
String key)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
//TODO: Implement IrcStack.onRemoveChannelKey().
}
/**
* Called when the user limit is removed for a channel.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemoveChannelLimit(String channel, String sourceNick,
String sourceLogin, String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
ChatRoom chatRoom = ircMUCOpSet.getChatRoom(channel);
if (chatRoom == null)
return;
//TODO: Implement IrcStack.onRemoveChannelLimit().
}
/**
* Called when a channel has 'invite only' removed.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemoveInviteOnly( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onRemoveInviteOnly().
}
/**
* Called when a channel has moderated mode removed.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemoveModerated( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onRemoveModerated().
}
/**
* Called when a channel is set to allow messages from any user, even
* if they are not actually in the channel.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemoveNoExternalMessages( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onRemoveNoExternalMessages().
}
/**
* Called when a channel is marked as not being in private mode.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemovePrivate( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onRemovePrivate().
}
/**
* Called when a channel has 'secret' mode removed.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemoveSecret( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onRemoveSecret().
}
/**
* Called when topic protection is removed for a channel.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onRemoveTopicProtection(String channel, String sourceNick,
String sourceLogin, String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onRemoveSecret().
}
/**
*
* @param code The three-digit numerical code for the response.
* @param response The full response from the IRC server.
*
* @see ReplyConstants
*/
protected void onServerResponse (int code, String response)
{
if (code == ERR_NOSUCHCHANNEL)
{
logger.error("No such channel:" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_NOSUCHCHANNEL);
}
else if (code == ERR_BADCHANMASK)
{
logger.error("Bad channel mask :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_BADCHANMASK);
}
else if (code == ERR_BADCHANNELKEY)
{
logger.error("Bad channel key :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_BADCHANNELKEY);
}
else if (code == ERR_BANNEDFROMCHAN)
{
logger.error("Banned from channel :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_BANNEDFROMCHAN);
}
else if (code == ERR_CHANNELISFULL)
{
logger.error("Channel is full :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_CHANNELISFULL);
}
else if (code == ERR_CHANOPRIVSNEEDED)
{
logger.error("Channel operator privilages needed :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_CHANOPRIVSNEEDED);
}
else if (code == ERR_ERRONEUSNICKNAME)
{
logger.error("ERR_ERRONEUSNICKNAME :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_ERRONEUSNICKNAME);
}
else if (code == ERR_INVITEONLYCHAN)
{
logger.error("Invite only channel :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_INVITEONLYCHAN);
}
else if (code == ERR_NEEDMOREPARAMS)
{
logger.error("Need more params :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_NEEDMOREPARAMS);
}
else if (code == ERR_NICKCOLLISION)
{
logger.error("Nick collision :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_NICKCOLLISION);
}
else if (code == ERR_NICKNAMEINUSE)
{
logger.error("Nickname in use :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_NICKNAMEINUSE);
}
else if (code == ERR_NONICKNAMEGIVEN)
{
logger.error("No nickname given :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_NONICKNAMEGIVEN);
}
else if (code == ERR_NOTONCHANNEL)
{
logger.error("Not on channel :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_NOTONCHANNEL);
}
else if (code == ERR_TOOMANYCHANNELS)
{
logger.error("Too many channels :" + code
+ ": Response :" + response);
this.notifyChatRoomOperation(ERR_TOOMANYCHANNELS);
}
// reply responses
else if (code == RPL_WHOISUSER)
{
StringTokenizer tokenizer = new StringTokenizer(response);
tokenizer.nextToken();
String nickname = tokenizer.nextToken();
String login = tokenizer.nextToken();
String hostname = tokenizer.nextToken();
UserInfo userInfo = new UserInfo(nickname, login, hostname);
this.userInfoTable.put(nickname, userInfo);
}
else if (code == RPL_WHOISSERVER)
{
StringTokenizer tokenizer = new StringTokenizer(response);
tokenizer.nextToken();
String userNickName = tokenizer.nextToken();
int end = response.indexOf(':');
String serverInfo = response.substring(end + 1);
if (userInfoTable.containsKey(userNickName))
{
((UserInfo) userInfoTable.get(userNickName))
.setServerInfo(serverInfo);
}
}
else if (code == RPL_WHOISOPERATOR)
{
StringTokenizer tokenizer = new StringTokenizer(response);
tokenizer.nextToken();
String userNickName = tokenizer.nextToken();
if (userInfoTable.containsKey(userNickName))
{
((UserInfo) userInfoTable.get(userNickName)).setIrcOp(true);
}
}
else if (code == RPL_WHOISIDLE)
{
StringTokenizer tokenizer = new StringTokenizer(response);
tokenizer.nextToken();
String userNickName = tokenizer.nextToken();
long idle = Long.parseLong(tokenizer.nextToken());
if (userInfoTable.containsKey(userNickName))
{
((UserInfo) userInfoTable.get(userNickName)).setIdle(idle);
}
}
else if (code == RPL_WHOISCHANNELS)
{
StringTokenizer tokenizer = new StringTokenizer(response);
tokenizer.nextToken();
String userNickName = tokenizer.nextToken();
if (userInfoTable.containsKey(userNickName))
{
((UserInfo) userInfoTable.get(userNickName))
.clearJoinedChatRoom();
while(tokenizer.hasMoreTokens())
{
String channel = tokenizer.nextToken();
if(channel.startsWith(":"))
channel = channel.substring(1);
((UserInfo) userInfoTable.get(userNickName))
.addJoinedChatRoom(channel);
}
}
}
else if (code == RPL_ENDOFWHOIS)
{
StringTokenizer tokenizer = new StringTokenizer(response);
tokenizer.nextToken();
String userNickName = tokenizer.nextToken();
if (userInfoTable.containsKey(userNickName))
{
UserInfo userInfo
= (UserInfo) userInfoTable.get(userNickName);
this.onWhoIs(userInfo);
}
}
else if (code != RPL_LISTSTART
&& code != RPL_LIST
&& code != RPL_LISTEND)
{
logger.trace(
"Server response: Code : "
+ code
+ " Response : "
+ response);
int delimiterIndex = response.indexOf(':');
if(delimiterIndex != -1 && delimiterIndex < response.length() - 1)
response = response.substring(delimiterIndex + 1);
MessageIrcImpl message
= new MessageIrcImpl(
response,
MessageIrcImpl.DEFAULT_MIME_TYPE,
MessageIrcImpl.DEFAULT_MIME_ENCODING,
null);
ChatRoomIrcImpl serverRoom
= (ChatRoomIrcImpl) ircMUCOpSet.findSystemRoom();
ChatRoomMember serverMember = ircMUCOpSet.findSystemMember();
serverRoom.fireMessageReceivedEvent(
message,
serverMember,
new Date(System.currentTimeMillis()),
ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED);
}
}
/**
* Called when a user (possibly us) gets banned from a channel. Being
* banned from a channel prevents any user with a matching host mask from
* joining the channel. For this reason, most bans are usually directly
* followed by the user being kicked .
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
* @param hostmask The host mask of the user that has been banned.
*/
protected void onSetChannelBan( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname,
String hostmask)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetChannelBan().
}
/**
* Called when a channel key is set. When the channel key has been set,
* other users may only join that channel if they know the key. Channel
* keys are sometimes referred to as passwords.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
* @param key The new key for the channel.
*/
protected void onSetChannelKey(String channel, String sourceNick,
String sourceLogin, String sourceHostname, String key)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetChannelKey().
}
/**
* Called when a user limit is set for a channel. The number of users in
* the channel cannot exceed this limit.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
* @param limit The maximum number of users that may be in this channel at
* the same time.
*/
protected void onSetChannelLimit( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname,
int limit)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetChannelLimit().
}
/**
* Called when a channel is set to 'invite only' mode. A user may only
* join the channel if they are invited by someone who is already in the
* channel.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onSetInviteOnly( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetChannelLimit().
}
/**
* Called when a channel is set to 'moderated' mode. If a channel is
* moderated, then only users who have been 'voiced' or 'opp-ed' may speak
* or change their nicks.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onSetModerated( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetModerated().
}
/**
* Called when a channel is set to only allow messages from users that
* are in the channel.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The hostname of the user that performed the mode
* change.
*/
protected void onSetNoExternalMessages( String channel,
String sourceNick,
String sourceLogin,
String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetNoExternalMessages().
}
/**
* Called when a channel is marked as being in private mode.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onSetPrivate(String channel, String sourceNick,
String sourceLogin, String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
// TODO: Implement IrcStack.onSetPrivate().
}
/**
* Called when a channel is set to be in 'secret' mode. Such channels
* typically do not appear on a server's channel listing.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onSetSecret(String channel, String sourceNick,
String sourceLogin, String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
//TODO: Implement IrcStack.onSetPrivate().
}
/**
* Called when topic protection is enabled for a channel. Topic protection
* means that only operators in a channel may change the topic.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
*/
protected void onSetTopicProtection(String channel, String sourceNick,
String sourceLogin, String sourceHostname)
{
if (logger.isDebugEnabled())
logger.debug("MODE on " + channel + ": Received from " + sourceNick
+ " " + sourceLogin + "@" + sourceHostname);
//TODO: Implement IrcStack.onSetPrivate().
}
/**
* This method is called whenever a user sets the topic, or when
* PircBot joins a new channel and discovers its topic.
*
* @param channel The channel that the topic belongs to.
* @param topic The topic for the channel.
* @param setBy The nick of the user that set the topic.
* @param date When the topic was set (milliseconds since the epoch).
* @param changed True if the topic has just been changed, false if
* the topic was already there.
*
*/
protected void onTopic( String channel,
String topic,
String setBy,
long date,
boolean changed)
{
logger.trace("TOPIC on " + channel + ": " + topic + " setBy: "
+ setBy + " on: " + date);
this.notifyChatRoomOperation(0);
ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel);
ChatRoomPropertyChangeEvent evt
= new ChatRoomPropertyChangeEvent(
chatRoom,
ChatRoomPropertyChangeEvent.CHAT_ROOM_SUBJECT,
topic,
topic);
chatRoom.firePropertyChangeEvent(evt);
}
/**
* This method is called whenever we receive a line from the server that
* the PircBot has not been programmed to recognize.
*
* @param line The raw line that was received from the server.
*/
protected void onUnknown(String line)
{
logger.error("Unknown message received from the server : " + line);
}
/**
* This method is called when we receive a user list from the server
* after joining a channel.
*
* @param channel The name of the channel.
* @param users An array of User objects belonging to this channel.
*
* @see User
*/
protected void onUserList(String channel, User[] users)
{
if (logger.isDebugEnabled())
logger.debug("NAMES on " + channel);
ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel);
chatRoom.clearChatRoomMemberList();
for (int i = 0; i < users.length; i++)
{
User user = users[i];
ChatRoomMemberRole newMemberRole;
if (user.getPrefix().equalsIgnoreCase("@"))
{
newMemberRole = ChatRoomMemberRole.ADMINISTRATOR;
}
else if (user.getPrefix().equalsIgnoreCase("%"))
{
newMemberRole = ChatRoomMemberRole.MODERATOR;
}
else if (user.getPrefix().equalsIgnoreCase("+"))
{
newMemberRole = ChatRoomMemberRole.MEMBER;
}
else
{
newMemberRole = ChatRoomMemberRole.GUEST;
}
ChatRoomMemberIrcImpl newMember
= new ChatRoomMemberIrcImpl(parentProvider,
chatRoom,
user.getNick(),
null,
null,
newMemberRole);
chatRoom.addChatRoomMember(user.getNick(), newMember);
//we don't specify a reason
chatRoom.fireMemberPresenceEvent(
newMember,
null,
ChatRoomMemberPresenceChangeEvent.MEMBER_JOINED,
null);
}
}
/**
* Called when a user (possibly us) gets voice status granted in a channel.
*
* @param channel The channel in which the mode change took place.
* @param sourceNick The nick of the user that performed the mode change.
* @param sourceLogin The login of the user that performed the mode change.
* @param sourceHostname The host name of the user that performed the mode
* change.
* @param recipient The nick of the user that got 'voiced'.
*/
protected void onVoice(String channel, String sourceNick,
String sourceLogin, String sourceHostname, String recipient)
{
if (logger.isDebugEnabled())
logger.debug("VOICE on " + channel + ": Received from "
+ sourceNick + " " + sourceLogin + "@" + sourceHostname + "on "
+ recipient);
ChatRoomIrcImpl chatRoom = ircMUCOpSet.getChatRoom(channel);
if (chatRoom == null || !chatRoom.isJoined())
return;
ChatRoomMember sourceMember = chatRoom.getChatRoomMember(sourceNick);
if (sourceMember == null)
return;
chatRoom.fireMemberRoleEvent( sourceMember,
ChatRoomMemberRole.GUEST);
}
/**
* Returns the list of chat rooms on this server.
*
* @return the list of chat rooms on this server
*/
public List getServerChatRoomList()
{
return serverChatRoomList;
}
/**
* Tests if this chat room is joined
*
* @param chatRoom the chat room we want to test
* @return true if the chat room is joined, false otherwise
*/
protected boolean isJoined(ChatRoomIrcImpl chatRoom)
{
// If we are asked for the status of the server channel, we return true
// if the server is connected and false otherwise.
if(ircMUCOpSet.findSystemRoom().equals(chatRoom))
return isConnected();
// Private rooms are joined if they exist.
if(chatRoom.isPrivate())
return true;
// For all other channels on the server.
if (this.isConnected())
{
String[] channels = this.getChannels();
for (int i = 0; i < channels.length; i++)
{
if (chatRoom.getName().equals(channels[i]))
{
return true;
}
}
return false;
}
else
{
return false;
}
}
/**
* Join a chat room on this server.
*
* @param chatRoom the chat room to join
*/
public void join(ChatRoom chatRoom)
{
this.joinChannel(chatRoom.getName());
Timer joinTimeoutTimer = new Timer();
joinTimeoutTimers.put(chatRoom, joinTimeoutTimer);
joinTimeoutTimer.schedule(new JoinTimeoutTask(chatRoom), timeout);
}
/**
* Join a chat room on this server.
*
* @param chatRoom the chat room to join
* @param password the password of the chat room
*/
public void join(ChatRoom chatRoom, byte[] password)
{
this.joinChannel(chatRoom.getName(), new String(password));
Timer joinTimeoutTimer = new Timer();
joinTimeoutTimers.put(chatRoom, joinTimeoutTimer);
joinTimeoutTimer.schedule(new JoinTimeoutTask(chatRoom), timeout);
}
/**
* Leaves the given chat room.
*
* @param chatRoom the chat room we want to leave
*/
protected void leave(ChatRoom chatRoom)
{
this.partChannel(chatRoom.getName());
}
/**
* This method sends a command to the server which can also be an action or
* a notice.
*
* @param message The command we want to send.
*/
protected void sendCommand(ChatRoomIrcImpl chatRoom, Message message)
{
String command = message.getContent();
if (command.startsWith("/me"))
{
this.sendAction(chatRoom.getName(), command.substring(3));
}
else if (command.startsWith("/notice"))
{
this.sendNotice(chatRoom.getName(), command.substring(7));
}
else if (command.startsWith("/msg"))
{
StringTokenizer tokenizer = new StringTokenizer(command);
String target = null;
String messageContent = null;
// We don't need the /msg command text.
tokenizer.nextToken();
if(tokenizer.hasMoreTokens())
target = tokenizer.nextToken();
if(tokenizer.hasMoreTokens())
messageContent = tokenizer.nextToken();
this.sendMessage(target, messageContent);
}
else if (command.startsWith("/query"))
{
StringTokenizer tokenizer = new StringTokenizer(command);
String target = null;
tokenizer.nextToken();
if(tokenizer.hasMoreTokens())
target = tokenizer.nextToken();
ChatRoomIrcImpl privateChatRoom
= ircMUCOpSet.findPrivateChatRoom(target);
if(privateChatRoom == null)
return;
ChatRoomMember sourceMember = privateChatRoom.getChatRoomMember(
parentProvider.getAccountID().getService());
if (sourceMember == null)
sourceMember
= new ChatRoomMemberIrcImpl(
parentProvider,
privateChatRoom,
parentProvider.getAccountID().getService(),
"",
"",
ChatRoomMemberRole.GUEST);
MessageIrcImpl queryMessage
= new MessageIrcImpl( "Private conversation initiated.",
MessageIrcImpl.DEFAULT_MIME_TYPE,
MessageIrcImpl.DEFAULT_MIME_ENCODING,
null);
privateChatRoom.fireMessageReceivedEvent(
queryMessage,
sourceMember,
new Date(System.currentTimeMillis()),
ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED);
}
else
{
this.sendRawLine(command.substring(1));
}
}
/**
* Called to ban the given user from the given channel. The reason is not
* passed to the server, as it doesn't support this parameter.
*
* @param chatRoom the chat room for which the user should be banned
* @param hostmask the host mask of the user to ban
* @param reason the reason of the ban
*/
protected void banParticipant( String chatRoom,
String hostmask,
String reason)
throws OperationFailedException
{
this.ban(chatRoom, hostmask);
this.lockChatRoomOperation();
if (operationResponseCode == ERR_NEEDMOREPARAMS)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_CHANOPRIVSNEEDED)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.NOT_ENOUGH_PRIVILEGES);
else if (operationResponseCode == ERR_NOTONCHANNEL)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_USERSDONTMATCH)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_NOSUCHCHANNEL)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_NOSUCHNICK)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_KEYSET)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_UMODEUNKNOWNFLAG)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_UNKNOWNMODE)
throw new OperationFailedException(
"Need more parameters.",
OperationFailedException.GENERAL_ERROR);
}
/**
* Who is.
*
* @param userInfo
*/
private void onWhoIs(UserInfo userInfo)
{
logger.trace("WHOIS on: " + userInfo.getNickName() + "!"
+ userInfo.getLogin() + "@" + userInfo.getHostname());
String whoisMessage = "Nickname: " + userInfo.getNickName() + "
"
+ "Host name: " + userInfo.getHostname() + "
"
+ "Login: " + userInfo.getLogin() + "
"
+ "Server info: " + userInfo.getServerInfo() + "
"
+ "Joined chat rooms:";
Iterator joinedChatRooms = userInfo.getJoinedChatRooms().iterator();
while(joinedChatRooms.hasNext())
{
whoisMessage += " " + joinedChatRooms.next();
}
MessageIrcImpl message
= new MessageIrcImpl( whoisMessage,
MessageIrcImpl.DEFAULT_MIME_TYPE,
MessageIrcImpl.DEFAULT_MIME_ENCODING,
null);
ChatRoomIrcImpl chatRoom
= (ChatRoomIrcImpl) ircMUCOpSet.findSystemRoom();
if(chatRoom == null || !chatRoom.isJoined())
return;
ChatRoomMember sourceMember
= new ChatRoomMemberIrcImpl(parentProvider,
chatRoom,
"",
"",
"",
ChatRoomMemberRole.GUEST);
chatRoom.fireMessageReceivedEvent(
message,
sourceMember,
new Date(System.currentTimeMillis()),
ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED);
}
/**
* Adds a chat room to the server chat room list.
*
* @param chatRoomName the name of the chat room to add
*/
private void addServerChatRoom(String chatRoomName)
{
synchronized (serverChatRoomList)
{
if (!serverChatRoomList.contains(chatRoomName))
serverChatRoomList.add(chatRoomName);
}
}
/**
* After waiting a certain time notifies all interested listeners that a
* join has failed, because there's no response from the server.
*/
private class JoinTimeoutTask extends TimerTask
{
private ChatRoom chatRoom;
/**
* Creates an instance of JoinTimeoutTask.
*
* @param chatRoom the chat room for which the join has been timed out.
*/
public JoinTimeoutTask(ChatRoom chatRoom)
{
this.chatRoom = chatRoom;
}
/**
* Notifies all interested listeners that a join has failed, because
* there's no response from the server.
* @see java.util.TimerTask#run()
*/
public void run()
{
((OperationSetMultiUserChatIrcImpl) parentProvider
.getOperationSet(OperationSetMultiUserChat.class))
.fireLocalUserPresenceEvent(chatRoom,
LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED,
"An error occured while joining the " + chatRoom.getName()
+ " chat room.");
}
}
/**
* 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.
*/
private int parseInt(String str)
{
try
{
return Integer.parseInt(str);
}
catch (NumberFormatException exc)
{
return -1;
}
}
/**
* Locks a chat room operation.
*/
private void lockChatRoomOperation()
{
synchronized (operationLock)
{
try
{
operationLock.wait(5000);
}
catch (InterruptedException e)
{
logger.error("Chat Room operation lock thread interrupted.", e);
}
}
}
/**
* Notifies the waiting chat room operation.
*/
private void notifyChatRoomOperation(int responseCode)
{
this.operationResponseCode = responseCode;
synchronized (operationLock)
{
operationLock.notify();
}
}
/**
* Kicks the participant with the given contact address from the given
* channel.
*
* @param chatRoomName the name of the chat room
* @param contactAddress the address of the contact to kick
* @param reason the reason of the kick
*
* @throws OperationFailedException if we are not joined or we don't have
* enough privileges to kick a participant.
*/
public void kickParticipant(String chatRoomName,
String contactAddress,
String reason)
throws OperationFailedException
{
this.kick(chatRoomName, contactAddress, reason);
this.lockChatRoomOperation();
if (operationResponseCode == ERR_CHANOPRIVSNEEDED)
throw new OperationFailedException(
"You need to have operator privileges"
+ "in order to kick a contact.",
OperationFailedException.NOT_ENOUGH_PRIVILEGES);
else if (operationResponseCode == ERR_NEEDMOREPARAMS)
throw new OperationFailedException(
"The server need more parameters in order to perform"
+ "this operation.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_NOSUCHCHANNEL)
throw new OperationFailedException(
"The channel from which the contact should be kicked"
+ "was not found.",
OperationFailedException.NOT_FOUND);
else if (operationResponseCode == ERR_BADCHANMASK)
throw new OperationFailedException(
"The channel from which the contact should be kicked"
+ "was not found.",
OperationFailedException.NOT_FOUND);
else if (operationResponseCode == ERR_NOTONCHANNEL)
throw new OperationFailedException(
"You need to be joined to the chat room in order"
+ "to kick a contact from it.",
OperationFailedException.CHAT_ROOM_NOT_JOINED);
}
/**
* Changes the topic of the given channel.
*
* @param channel the channel to change
* @param topic the new topic to set
* @throws OperationFailedException thrown if the user is not joined to the
* channel or if he/she doesn't have enough privileges to change the
* topic or if the topic is null.
*/
public void setSubject(String channel, String topic)
throws OperationFailedException
{
this.setTopic(channel, topic);
this.lockChatRoomOperation();
if (operationResponseCode == ERR_NEEDMOREPARAMS)
new OperationFailedException(
"More parameters should be provided to the server.",
OperationFailedException.GENERAL_ERROR);
else if (operationResponseCode == ERR_NOTONCHANNEL)
new OperationFailedException(
"You need to be joined in order to"
+ " change the subject of the chat room.",
OperationFailedException.CHAT_ROOM_NOT_JOINED);
else if (operationResponseCode == ERR_CHANOPRIVSNEEDED)
new OperationFailedException(
"You don't have enough privileges"
+ " to change the chat room subject.",
OperationFailedException.NOT_ENOUGH_PRIVILEGES);
}
/**
* Changes the user nick name on the IRC server.
*
* @param nickname the new nickname
* @throws OperationFailedException if the nickname is already used by
* someone else
*/
public void setUserNickname(String nickname)
throws OperationFailedException
{
this.changeNick(nickname);
this.lockChatRoomOperation();
if (operationResponseCode == ERR_NICKNAMEINUSE)
throw new OperationFailedException(
"The nickname you chosed is already used by someone else.",
OperationFailedException.IDENTIFICATION_CONFLICT);
else if (operationResponseCode == ERR_NICKCOLLISION)
throw new OperationFailedException(
"The nickname you chosed is already used by someone else.",
OperationFailedException.IDENTIFICATION_CONFLICT);
else if (operationResponseCode == ERR_NONICKNAMEGIVEN)
throw new OperationFailedException(
"You need to enter a valid nickname.",
OperationFailedException.ILLEGAL_ARGUMENT);
else if (operationResponseCode == ERR_ERRONEUSNICKNAME)
throw new OperationFailedException(
"You need to enter a valid nickname.",
OperationFailedException.ILLEGAL_ARGUMENT);
}
}