summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modules.h8
-rw-r--r--src/channels.cpp12
-rw-r--r--src/modules.cpp1
-rw-r--r--src/modules/m_namesx.cpp56
4 files changed, 26 insertions, 51 deletions
diff --git a/include/modules.h b/include/modules.h
index 35c439a10..af36b7023 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -401,7 +401,7 @@ enum Implementation
I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead, I_OnChangeLocalUserGECOS, I_OnUserRegister,
I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList,
I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed,
- I_OnText, I_OnReadConfig, I_OnDownloadFile, I_OnPassCompare, I_OnRunTestSuite,
+ I_OnText, I_OnReadConfig, I_OnDownloadFile, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem,
I_END
};
@@ -1357,6 +1357,12 @@ class CoreExport Module : public Extensible
* via the --testsuite debugging parameter.
*/
virtual void OnRunTestSuite();
+
+ /** Called for every item in a NAMES list, so that modules may reformat portions of it as they see fit.
+ * For example NAMESX, channel mode +u and +I, and UHNAMES. If the nick is set to an empty string by any
+ * module, then this will cause the nickname not to be displayed at all.
+ */
+ virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick);
};
diff --git a/src/channels.cpp b/src/channels.cpp
index c90a8f4e5..a0c9a0304 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -881,9 +881,15 @@ void Channel::UserList(User *user, CUList *ulist)
if (i->first->Visibility && !i->first->Visibility->VisibleTo(user))
continue;
- size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", this->GetPrefixChar(i->first), i->second.c_str());
- /* OnUserList can change this - reset it back to normal */
- i->second = i->first->nick;
+ std::string prefixlist = this->GetPrefixChar(i->first);
+ std::string nick = i->first->nick;
+ FOREACH_MOD(I_OnNamesListItem, OnNamesListItem(user, i->first, this, prefixlist, nick));
+
+ /* Nick was nuked, a module wants us to skip it */
+ if (nick.empty())
+ continue;
+
+ size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", prefixlist.c_str(), nick.c_str());
curlen += ptrlen;
ptr += ptrlen;
diff --git a/src/modules.cpp b/src/modules.cpp
index 8a769ceb1..4bfa16eca 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -193,6 +193,7 @@ void Module::OnGarbageCollect() { }
void Module::OnBufferFlushed(User*) { }
void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { }
void Module::OnRunTestSuite() { }
+void Module::OnNamesListItem(User*, User*, Channel*, std::string&, std::string&) { }
ModuleManager::ModuleManager(InspIRCd* Ins) : ModCount(0), Instance(Ins)
diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp
index 2e79d6a06..3ce1b00eb 100644
--- a/src/modules/m_namesx.cpp
+++ b/src/modules/m_namesx.cpp
@@ -25,7 +25,7 @@ class ModuleNamesX : public Module
ModuleNamesX(InspIRCd* Me)
: Module(Me)
{
- Implementation eventlist[] = { I_OnSyncUserMetaData, I_OnPreCommand, I_OnUserList, I_On005Numeric, I_OnEvent };
+ Implementation eventlist[] = { I_OnSyncUserMetaData, I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent };
ServerInstance->Modules->Attach(eventlist, this, 5);
}
@@ -69,55 +69,17 @@ class ModuleNamesX : public Module
return 0;
}
- virtual int OnUserList(User* user, Channel* Ptr, CUList* &ulist)
+ virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
{
- if (user->GetExt("NAMESX"))
- {
- char list[MAXBUF];
- size_t dlen, curlen;
- dlen = curlen = snprintf(list,MAXBUF,"353 %s %c %s :", user->nick, Ptr->IsModeSet('s') ? '@' : Ptr->IsModeSet('p') ? '*' : '=', Ptr->name);
- int numusers = 0;
- char* ptr = list + dlen;
+ if (!issuer->GetExt("NAMESX"))
+ return;
- if (!ulist)
- ulist = Ptr->GetUsers();
+ /* Some module hid this from being displayed, dont bother */
+ if (nick.empty())
+ return;
- bool has_user = Ptr->HasUser(user);
- for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
- {
- if ((!has_user) && (i->first->IsModeSet('i')))
- continue;
-
- if (i->first->Visibility && !i->first->Visibility->VisibleTo(user))
- continue;
-
- size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", Ptr->GetAllPrefixChars(i->first), i->second.c_str());
- /* OnUserList can change this - reset it back to normal */
- i->second = i->first->nick;
- curlen += ptrlen;
- ptr += ptrlen;
- numusers++;
- if (curlen > (480-NICKMAX))
- {
- /* list overflowed into multiple numerics */
- user->WriteServ(std::string(list));
- /* reset our lengths */
- dlen = curlen = snprintf(list,MAXBUF,"353 %s %c %s :", user->nick, Ptr->IsModeSet('s') ? '@' : Ptr->IsModeSet('p') ? '*' : '=', Ptr->name);
- ptr = list + dlen;
- ptrlen = 0;
- numusers = 0;
- }
- }
- /* if whats left in the list isnt empty, send it */
- if (numusers)
- {
- user->WriteServ(std::string(list));
- }
- user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, Ptr->name);
- return 1;
- }
- return 0;
- }
+ prefixes = channel->GetAllPrefixChars(user);
+ }
virtual void OnEvent(Event *ev)
{