diff --git a/protocols/irc/IrcProtocol.cpp b/protocols/irc/IrcProtocol.cpp index e372d95..15a2abf 100644 --- a/protocols/irc/IrcProtocol.cpp +++ b/protocols/irc/IrcProtocol.cpp @@ -161,9 +161,10 @@ IrcProtocol::Process(BMessage* msg) _SendMsg(&created); break; } + // If it's not a known user, we need to get their ID/nick somehow + // … that is, through the WHO. fWhoIm = user_id; - - BString cmd("WHO "); + BString cmd("WHOIS "); cmd << user_id << "\n"; _SendIrc(cmd); break; @@ -212,6 +213,22 @@ IrcProtocol::Process(BMessage* msg) } break; } + case IM_GET_ROOM_PARTICIPANTS: + { + BString chat_id; + if (msg->FindString("chat_id", &chat_id) != B_OK) + break; + + // Rooms are populated with RPL_WHOREPLY, chats RPL_WHOISUSER + BString cmd; + if (_IsChannelName(chat_id) == true) + cmd = "WHO "; + else + cmd = "WHOIS "; + cmd << chat_id << "\n"; + _SendIrc(cmd); + break; + } case IM_ROOM_SEND_INVITE: { BString chat_id = msg->FindString("chat_id"); @@ -289,6 +306,8 @@ IrcProtocol::Connect() status_t IrcProtocol::Loop() { + fWhoIsRequested = false; + fWhoRequested = false; while (fSocket != NULL && fSocket->IsConnected() == true) _ProcessLine(_ReadUntilNewline(fSocket, &fRemainingBuf)); return B_OK; @@ -327,11 +346,50 @@ IrcProtocol::_ProcessNumeric(int32 numeric, BString sender, BStringList params, { if (params.CountStrings() == 2) fNick = params.First(); - BString cmd("WHO "); + BString cmd("WHOIS "); cmd << fNick << "\n"; _SendIrc(cmd); break; } + case RPL_WHOISUSER: + { + BString nick = params.StringAt(1); + BString user = params.StringAt(2); + BString host = params.StringAt(3); + BString ident = user; + ident << "@" << host; + + fIdentNicks.RemoveItemFor(ident); + fIdentNicks.AddItem(ident, nick); + + // Contains the own user's contact info― protocol ready! + if (fReady == false && nick == fNick) { + fUser = user.String(); + _MakeReady(nick, ident); + } + // Used in the creation of a one-on-one chat + else if (fWhoIm == user || fWhoIm == nick) { + fWhoIm = ""; + BMessage created(IM_MESSAGE); + created.AddInt32("im_what", IM_CHAT_CREATED); + created.AddString("chat_id", nick); + created.AddString("user_id", ident); + _SendMsg(&created); + } + // Used to populate a one-on-one chat's userlist… lol, I know. + else if (fWhoIsRequested == false && nick != fNick) { + BMessage user(IM_MESSAGE); + user.AddInt32("im_what", IM_ROOM_PARTICIPANTS); + user.AddString("chat_id", nick); + user.AddString("user_id", ident); + user.AddString("user_name", nick); + _SendMsg(&user); + } + break; + } + case RPL_ENDOFWHOIS: + fWhoIsRequested = false; + break; case RPL_WHOREPLY: { BString channel = params.StringAt(1); @@ -341,32 +399,18 @@ IrcProtocol::_ProcessNumeric(int32 numeric, BString sender, BStringList params, BString ident = user; ident << "@" << host; - // Contains the user's contact info― protocol ready! - if (fReady == false && nick == fNick) { - fUser = user.String(); - _MakeReady(nick, ident); - } + fIdentNicks.RemoveItemFor(ident); + fIdentNicks.AddItem(ident, nick); - // Used to populate a room's userlist - if (fWhoRequested == false && channel != "*") { + // Used to populate a room's userlist (one-by-one… :p) + if (fWhoRequested == false && _IsChannelName(channel)) { BMessage user(IM_MESSAGE); user.AddInt32("im_what", IM_ROOM_PARTICIPANTS); user.AddString("chat_id", channel); user.AddString("user_id", ident); user.AddString("user_name", nick); - fIdentNicks.AddItem(ident, nick); _SendMsg(&user); } - // Here, used in the creation of a one-on-one chat - else if (fWhoIm == user || fWhoIm == nick) { - fWhoIm = ""; - BMessage created(IM_MESSAGE); - created.AddInt32("im_what", IM_CHAT_CREATED); - created.AddString("chat_id", nick); - created.AddString("user_id", ident); - fIdentNicks.AddItem(ident, nick); - _SendMsg(&created); - } break; } case RPL_ENDOFWHO: @@ -495,11 +539,6 @@ IrcProtocol::_ProcessCommand(BString command, BString sender, joined.AddString("chat_id", chat_id); if (_SenderIdent(sender) == fIdent) { joined.AddInt32("im_what", IM_ROOM_JOINED); - // Populate the userlist - BString cmd("WHO "); - cmd << chat_id << "\n"; - _SendIrc(cmd); - fChannels.Add(chat_id); } else { diff --git a/protocols/irc/IrcProtocol.h b/protocols/irc/IrcProtocol.h index e5ed0ba..a6af74a 100644 --- a/protocols/irc/IrcProtocol.h +++ b/protocols/irc/IrcProtocol.h @@ -114,6 +114,7 @@ private: // WHOREPLY is requested by the add-on to populate the user-list, but the // user might also use the /who command― if the user does, this is true bool fWhoRequested; + bool fWhoIsRequested; BString fWhoIm; bool fWriteLocked; diff --git a/protocols/irc/Numerics.h b/protocols/irc/Numerics.h index 8b5d7a5..e924d7d 100644 --- a/protocols/irc/Numerics.h +++ b/protocols/irc/Numerics.h @@ -2,7 +2,9 @@ #define _RESPONSE_NUMERICS_H #define RPL_WELCOME 1 +#define RPL_WHOISUSER 311 #define RPL_ENDOFWHO 315 +#define RPL_ENDOFWHOIS 318 #define RPL_TOPIC 332 #define RPL_WHOREPLY 352 #define RPL_NAMREPLY 353