*/
class CoreExport Channel : public Extensible
{
- private:
-
- /** Pointer to creator object
- */
- InspIRCd* ServerInstance;
-
/** Connect a Channel to a User
*/
static Channel* ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const std::string &privs, bool bursting, bool created);
int maxbans;
public:
+ /** Pointer to creator object
+ */
+ InspIRCd* ServerInstance;
+
/** Creates a channel record and initialises it with default values
* @throw Nothing at present.
*/
{
return modes.find(m) != std::string::npos;
}
+ unsigned int getRank();
};
typedef std::map<User*, Membership*> UserMembList;
/** Called when a user joins a channel.
* The details of the joining user are available to you in the parameter User *user,
* and the details of the channel they have joined is available in the variable Channel *channel
- * @param user The user who is joining
- * @param channel The channel being joined
- * @param silent Change this to true if you want to conceal the JOIN command from the other users
- * of the channel (useful for modules such as auditorium)
+ * @param memb The channel membership being created
* @param sync This is set to true if the JOIN is the result of a network sync and the remote user is being introduced
* to a channel due to the network sync.
* @param created This is true if the join created the channel
*/
- virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created);
+ virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
/** Called after a user joins a channel
* Identical to OnUserJoin, but called immediately afterwards, when any linking module has
* seen the join.
- * @param user The user who is joining
- * @param channel The channel being joined
+ * @param memb The channel membership created
*/
- virtual void OnPostJoin(User* user, Channel* channel);
+ virtual void OnPostJoin(Membership*);
/** Called when a user parts a channel.
* The details of the leaving user are available to you in the parameter User *user,
* and the details of the channel they have left is available in the variable Channel *channel
- * @param user The user who is parting
- * @param channel The channel being parted
+ * @param memb The channel membership being destroyed
* @param partmessage The part message, or an empty string (may be modified)
- * @param silent Change this to true if you want to conceal the PART command from the other users
- * of the channel (useful for modules such as auditorium)
*/
- virtual void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent);
+ virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
/** Called on rehash.
* This method is called prior to a /REHASH or when a SIGHUP is received from the operating
* @param reason The kick reason
* @return 1 to prevent the kick, 0 to continue normally, -1 to explicitly allow the kick regardless of normal operation
*/
- virtual ModResult OnUserPreKick(User* source, User* user, Channel* chan, const std::string &reason);
+ virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
/** Called whenever a user is kicked.
* If this method is called, the kick is already underway and cannot be prevented, so
* @param user The user being kicked
* @param chan The channel the user is being kicked from
* @param reason The kick reason
- * @param silent Change this to true if you want to conceal the PART command from the other users
- * of the channel (useful for modules such as auditorium)
*/
- virtual void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent);
+ virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
/** Called whenever a user opers locally.
* The User will contain the oper mode 'o' as this function is called after any modifications
* 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);
+ virtual void OnNamesListItem(User* issuer, Membership* item, std::string &prefixes, std::string &nick);
virtual ModResult OnNumeric(User* user, unsigned int numeric, const std::string &text);
Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const std::string &privs, bool bursting, bool created)
{
std::string nick = user->nick;
- bool silent = false;
- Ptr->AddUser(user);
+ Membership* memb = Ptr->AddUser(user);
user->chans.insert(Ptr);
for (std::string::const_iterator x = privs.begin(); x != privs.end(); x++)
}
}
- FOREACH_MOD_I(Instance,I_OnUserJoin,OnUserJoin(user, Ptr, bursting, silent, created));
+ CUList except_list;
+ FOREACH_MOD_I(Instance,I_OnUserJoin,OnUserJoin(memb, bursting, created, except_list));
- if (!silent)
- Ptr->WriteChannel(user,"JOIN :%s",Ptr->name.c_str());
+ Ptr->WriteAllExcept(user, false, 0, except_list, "JOIN :%s", Ptr->name.c_str());
/* Theyre not the first ones in here, make sure everyone else sees the modes we gave the user */
std::string ms = Instance->Modes->ModeString(user, Ptr);
}
Ptr->UserList(user);
}
- FOREACH_MOD_I(Instance,I_OnPostJoin,OnPostJoin(user, Ptr));
+ FOREACH_MOD_I(Instance,I_OnPostJoin,OnPostJoin(memb));
return Ptr;
}
*/
long Channel::PartUser(User *user, std::string &reason)
{
- bool silent = false;
-
if (!user)
return this->GetUserCounter();
- UCListIter i = user->chans.find(this);
- if (i != user->chans.end())
+ Membership* memb = GetUser(user);
+
+ if (memb)
{
- FOREACH_MOD(I_OnUserPart,OnUserPart(user, this, reason, silent));
+ CUList except_list;
+ FOREACH_MOD(I_OnUserPart,OnUserPart(memb, reason, except_list));
- if (!silent)
- this->WriteChannel(user, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
+ WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
- user->chans.erase(i);
+ user->chans.erase(this);
this->RemoveAllPrefixes(user);
}
long Channel::KickUser(User *src, User *user, const char* reason)
{
- bool silent = false;
-
if (!src || !user || !reason)
return this->GetUserCounter();
+ Membership* memb = GetUser(user);
if (IS_LOCAL(src))
{
- if (!this->HasUser(user))
+ if (!memb)
{
src->WriteNumeric(ERR_USERNOTINCHANNEL, "%s %s %s :They are not on that channel",src->nick.c_str(), user->nick.c_str(), this->name.c_str());
return this->GetUserCounter();
if (ServerInstance->ULine(src->server))
res = MOD_RES_ALLOW;
if (res == MOD_RES_PASSTHRU)
- FIRST_MOD_RESULT(ServerInstance, OnUserPreKick, res, (src,user,this,reason));
+ FIRST_MOD_RESULT(ServerInstance, OnUserPreKick, res, (src,memb,reason));
if (res == MOD_RES_PASSTHRU)
FIRST_MOD_RESULT(ServerInstance, OnAccessCheck, res, (src,user,this,AC_KICK));
}
}
- FOREACH_MOD(I_OnUserKick,OnUserKick(src, user, this, reason, silent));
-
- UCListIter i = user->chans.find(this);
- if (i != user->chans.end())
+ if (memb)
{
- /* zap it from the channel list of the user */
- if (!silent)
- this->WriteChannel(src, "KICK %s %s :%s", this->name.c_str(), user->nick.c_str(), reason);
+ CUList except_list;
+ FOREACH_MOD(I_OnUserKick,OnUserKick(src, memb, reason, except_list));
+
+ WriteAllExcept(src, false, 0, except_list, "KICK %s %s :%s", name.c_str(), user->nick.c_str(), reason);
- user->chans.erase(i);
+ user->chans.erase(this);
this->RemoveAllPrefixes(user);
}
if (call_modules != MOD_RES_DENY)
{
- FOREACH_MOD(I_OnNamesListItem, OnNamesListItem(user, i->first, this, prefixlist, nick));
+ FOREACH_MOD(I_OnNamesListItem, OnNamesListItem(user, i->second, prefixlist, nick));
/* Nick was nuked, a module wants us to skip it */
if (nick.empty())
return pf;
}
+unsigned int Membership::getRank()
+{
+ char mchar = modes.c_str()[0];
+ unsigned int rv = 0;
+ if (mchar)
+ {
+ ModeHandler* mh = chan->ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL);
+ if (mh)
+ rv = mh->GetPrefixRank();
+ }
+ return rv;
+}
const char* Channel::GetAllPrefixChars(User* user)
{
}
}
- for(std::map<int,std::pair<char,char> >::iterator n = prefixes.begin(); n != prefixes.end(); n++)
+ for(std::map<int,std::pair<char,char> >::reverse_iterator n = prefixes.rbegin(); n != prefixes.rend(); n++)
{
mletters = mletters + n->second.first;
mprefixes = mprefixes + n->second.second;
void Module::OnUserConnect(User*) { }
void Module::OnUserQuit(User*, const std::string&, const std::string&) { }
void Module::OnUserDisconnect(User*) { }
-void Module::OnUserJoin(User*, Channel*, bool, bool&, bool) { }
-void Module::OnPostJoin(User*, Channel*) { }
-void Module::OnUserPart(User*, Channel*, std::string&, bool&) { }
+void Module::OnUserJoin(Membership*, bool, bool, CUList&) { }
+void Module::OnPostJoin(Membership*) { }
+void Module::OnUserPart(Membership*, std::string&, CUList&) { }
void Module::OnPreRehash(User*, const std::string&) { }
void Module::OnModuleRehash(User*, const std::string&) { }
void Module::OnRehash(User*) { }
void Module::OnPostCommand(const std::string&, const std::vector<std::string>&, User *, CmdResult, const std::string&) { }
ModResult Module::OnCheckReady(User*) { return MOD_RES_PASSTHRU; }
ModResult Module::OnUserRegister(User*) { return MOD_RES_PASSTHRU; }
-ModResult Module::OnUserPreKick(User*, User*, Channel*, const std::string&) { return MOD_RES_PASSTHRU; }
-void Module::OnUserKick(User*, User*, Channel*, const std::string&, bool&) { }
+ModResult Module::OnUserPreKick(User*, Membership*, const std::string&) { return MOD_RES_PASSTHRU; }
+void Module::OnUserKick(User*, Membership*, const std::string&, CUList&) { }
ModResult Module::OnRawMode(User*, Channel*, const char, const std::string &, bool, int) { return MOD_RES_PASSTHRU; }
ModResult Module::OnCheckInvite(User*, Channel*) { return MOD_RES_PASSTHRU; }
ModResult Module::OnCheckKey(User*, Channel*, const std::string&) { return MOD_RES_PASSTHRU; }
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&) { }
+void Module::OnNamesListItem(User*, Membership*, std::string&, std::string&) { }
ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MOD_RES_PASSTHRU; }
void Module::OnHookIO(EventHandler*, ListenSocketBase*) { }
ModResult Module::OnHostCycle(User*) { return MOD_RES_PASSTHRU; }
}
- virtual ~ModuleAuditorium()
+ ~ModuleAuditorium()
{
ServerInstance->Modes->DelMode(&aum);
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ConfigReader conf(ServerInstance);
ShowOps = conf.ReadFlag("auditorium", "showops", 0);
OperOverride = conf.ReadFlag("auditorium", "operoverride", 0);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
- virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
+ void OnNamesListItem(User* issuer, Membership* memb, std::string &prefixes, std::string &nick)
{
- if (!channel->IsModeSet('u'))
+ if (!memb->chan->IsModeSet('u'))
return;
/* Some module hid this from being displayed, dont bother */
if (OperOverride && issuer->HasPrivPermission("channels/auspex"))
return;
- if (ShowOps && (issuer != user) && (channel->GetPrefixValue(user) < OP_VALUE))
+ if (ShowOps && (issuer != memb->user) && (memb->getRank() < OP_VALUE))
{
/* Showops is set, hide all non-ops from the user, except themselves */
nick.clear();
return;
}
- if (!ShowOps && (issuer != user))
+ if (!ShowOps && (issuer != memb->user))
{
/* ShowOps is not set, hide everyone except the user whos requesting NAMES */
nick.clear();
}
}
- void WriteOverride(User* source, Channel* channel, const std::string &text)
+ void BuildExcept(Membership* memb, CUList& excepts)
{
- if (!OperOverride)
+ if (!memb->chan->IsModeSet('u'))
+ return;
+ if (ShowOps && memb->getRank() >= OP_VALUE)
return;
- const UserMembList *ulist = channel->GetUsers();
- for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++)
+ const UserMembList* users = memb->chan->GetUsers();
+ for(UserMembCIter i = users->begin(); i != users->end(); i++)
{
- if (i->first->HasPrivPermission("channels/auspex") && source != i->first)
- if (!ShowOps || (ShowOps && channel->GetPrefixValue(i->first) < OP_VALUE))
- i->first->WriteFrom(source, "%s",text.c_str());
+ if (i->first == memb->user || !IS_LOCAL(i->first))
+ continue;
+ if (ShowOps && i->second->getRank() >= OP_VALUE)
+ continue;
+ if (OperOverride && i->first->HasPrivPermission("channels/auspex"))
+ continue;
+ // This is a different user in the channel, local, and not op/oper
+ // so, hide the join from them
+ excepts.insert(i->first);
}
}
-
- virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts)
{
- if (channel->IsModeSet('u'))
- {
- silent = true;
- /* Because we silenced the event, make sure it reaches the user whos joining (but only them of course) */
- user->WriteFrom(user, "JOIN %s", channel->name.c_str());
- if (ShowOps)
- channel->WriteAllExceptSender(user, false, channel->GetPrefixValue(user) >= OP_VALUE ? 0 : '@', "JOIN %s", channel->name.c_str());
- WriteOverride(user, channel, "JOIN "+channel->name);
- }
+ BuildExcept(memb, excepts);
}
- void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
+ void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts)
{
- if (channel->IsModeSet('u'))
- {
- silent = true;
- /* Because we silenced the event, make sure it reaches the user whos leaving (but only them of course) */
- user->WriteFrom(user, "PART %s%s%s", channel->name.c_str(),
- partmessage.empty() ? "" : " :",
- partmessage.empty() ? "" : partmessage.c_str());
- if (ShowOps)
- {
- channel->WriteAllExceptSender(user, false, channel->GetPrefixValue(user) >= OP_VALUE ? 0 : '@', "PART %s%s%s", channel->name.c_str(), partmessage.empty() ? "" : " :",
- partmessage.empty() ? "" : partmessage.c_str());
- }
- WriteOverride(user, channel, "PART " + channel->name + (partmessage.empty() ? "" : (" :" + partmessage)));
- }
+ BuildExcept(memb, excepts);
}
- void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
+ void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts)
{
- if (chan->IsModeSet('u'))
- {
- silent = true;
- /* Send silenced event only to the user being kicked and the user doing the kick */
- source->WriteFrom(source, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), reason.c_str());
- if (ShowOps)
- chan->WriteAllExceptSender(source, false, chan->GetPrefixValue(user) >= OP_VALUE ? 0 : '@', "KICK %s %s %s", chan->name.c_str(), user->nick.c_str(), reason.c_str());
- if ((!ShowOps) || (chan->GetPrefixValue(user) < OP_VALUE)) /* make sure the target gets the event */
- user->WriteFrom(source, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), reason.c_str());
- WriteOverride(source, chan, "KICK " + chan->name + " " + user->nick + " :" + reason);
- }
+ BuildExcept(memb, excepts);
}
ModResult OnHostCycle(User* user)
ServerInstance->Modules->Attach(eventlist, this, 1);
}
- virtual ~ModuleChanCreate()
+ ~ModuleChanCreate()
{
ServerInstance->SNO->DisableSnomask('j');
ServerInstance->SNO->DisableSnomask('J');
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$",VF_VENDOR,API_VERSION);
}
- virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except)
{
if (created)
{
- if (IS_LOCAL(user))
- ServerInstance->SNO->WriteToSnoMask('j', "Channel %s created by %s!%s@%s", channel->name.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str());
- else
- ServerInstance->SNO->WriteToSnoMask('J', "Channel %s created by %s!%s@%s", channel->name.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str());
+ ServerInstance->SNO->WriteToSnoMask(IS_LOCAL(memb->user) ? 'j' : 'J', "Channel %s created by %s!%s@%s",
+ memb->chan->name.c_str(), memb->user->nick.c_str(), memb->user->ident.c_str(), memb->user->host.c_str());
}
}
};
}
~ModuleDelayJoin();
Version GetVersion();
- void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick);
- void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created);
+ void OnNamesListItem(User* issuer, Membership*, std::string &prefixes, std::string &nick);
+ void OnUserJoin(Membership*, bool, bool, CUList&);
void CleanUser(User* user);
ModResult OnHostCycle(User* user);
- void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent);
- void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent);
+ void OnUserPart(Membership*, std::string &partmessage, CUList&);
+ void OnUserKick(User* source, Membership*, const std::string &reason, CUList&);
void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message);
void OnText(User* user, void* dest, int target_type, const std::string &text, char status, CUList &exempt_list);
- void WriteCommonFrom(User *user, Channel* channel, const char* text, ...) CUSTOM_PRINTF(4, 5);
};
/* $ModDesc: Allows for delay-join channels (+D) where users dont appear to join until they speak */
return Version("$Id$", VF_COMMON | VF_VENDOR);
}
-void ModuleDelayJoin::OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
+void ModuleDelayJoin::OnNamesListItem(User* issuer, Membership* memb, std::string &prefixes, std::string &nick)
{
- if (!channel->IsModeSet('D'))
- return;
-
- if (nick.empty())
- return;
-
/* don't prevent the user from seeing themself */
- if (issuer == user)
+ if (issuer == memb->user)
return;
- Membership* memb = channel->GetUser(user);
/* If the user is hidden by delayed join, hide them from the NAMES list */
- if (memb && unjoined.get(memb))
+ if (unjoined.get(memb))
nick.clear();
}
-void ModuleDelayJoin::OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+static void populate(CUList& except, Membership* memb)
{
- if (channel->IsModeSet('D'))
+ const UserMembList* users = memb->chan->GetUsers();
+ for(UserMembCIter i = users->begin(); i != users->end(); i++)
{
- silent = true;
- /* Because we silenced the event, make sure it reaches the user whos joining (but only them of course) */
- user->WriteFrom(user, "JOIN %s", channel->name.c_str());
-
- Membership* memb = channel->GetUser(user);
+ if (i->first == memb->user || !IS_LOCAL(i->first))
+ continue;
+ except.insert(i->first);
+ }
+}
+void ModuleDelayJoin::OnUserJoin(Membership* memb, bool sync, bool created, CUList& except)
+{
+ if (memb->chan->IsModeSet('D'))
+ {
unjoined.set(memb, 1);
+ populate(except, memb);
}
}
-void ModuleDelayJoin::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
+void ModuleDelayJoin::OnUserPart(Membership* memb, std::string &partmessage, CUList& except)
{
- Membership* memb = channel->GetUser(user);
if (unjoined.set(memb, 0))
- {
- silent = true;
- /* Because we silenced the event, make sure it reaches the user whos leaving (but only them of course) */
- user->WriteFrom(user, "PART %s%s%s", channel->name.c_str(), partmessage.empty() ? "" : " :", partmessage.empty() ? "" : partmessage.c_str());
- }
+ populate(except, memb);
}
-void ModuleDelayJoin::OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
+void ModuleDelayJoin::OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except)
{
- Membership* memb = chan->GetUser(user);
if (unjoined.set(memb, 0))
- {
- silent = true;
- user->WriteFrom(source, "KICK %s %s %s", chan->name.c_str(), user->nick.c_str(), reason.c_str());
- }
+ populate(except, memb);
}
ModResult ModuleDelayJoin::OnHostCycle(User* user)
std::string n = this->ServerInstance->Modes->ModeString(user, channel);
if (n.length() > 0)
- this->WriteCommonFrom(user, channel, "MODE %s +%s", channel->name.c_str(), n.c_str());
+ channel->WriteAllExceptSender(user, false, 0, "MODE %s +%s", channel->name.c_str(), n.c_str());
}
MODULE_INIT(ModuleDelayJoin)
}
~ModuleDelayMsg();
Version GetVersion();
- void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created);
- void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent);
- void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent);
- void OnCleanup(int target_type, void* item);
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList&);
ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list);
};
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
-void ModuleDelayMsg::OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+void ModuleDelayMsg::OnUserJoin(Membership* memb, bool sync, bool created, CUList&)
{
- if (channel->IsModeSet('d'))
+ if (memb->chan->IsModeSet('d'))
{
- Membership* memb = channel->GetUser(user);
djm.jointime.set(memb, ServerInstance->Time());
}
}
/* $ModDesc: Allows for opered clients to join channels without being seen, similar to unreal 3.1 +I mode */
-static ConfigReader* conf;
-
class InvisibleMode : public ModeHandler
{
public:
ModuleInvisible(InspIRCd* Me)
: Module(Me), qm(Me, this), ido(Me)
{
- conf = new ConfigReader(ServerInstance);
if (!ServerInstance->Modes->AddMode(&qm))
throw ModuleException("Could not add new modes!");
if (!ServerInstance->Modes->AddModeWatcher(&ido))
ServerInstance->Users->ServerNoticeAll("*** m_invisible.so has just been loaded on this network. For more information, please visit http://inspircd.org/wiki/Modules/invisible");
Implementation eventlist[] = {
I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserJoin, I_OnUserPart, I_OnUserQuit,
- I_OnRehash, I_OnHostCycle, I_OnSendWhoLine
+ I_OnHostCycle, I_OnSendWhoLine, I_OnNamesListItem
};
ServerInstance->Modules->Attach(eventlist, this, 8);
};
- virtual ~ModuleInvisible()
+ ~ModuleInvisible()
{
ServerInstance->Modes->DelMode(&qm);
ServerInstance->Modes->DelModeWatcher(&ido);
- delete conf;
};
Version GetVersion();
- void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created);
- void OnRehash(User* user);
- void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent);
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts);
+ void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts);
void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message);
ModResult OnHostCycle(User* user);
ModResult OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list);
ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list);
- void WriteCommonFrom(User *user, Channel* channel, const char* text, ...) CUSTOM_PRINTF(4, 5);
void OnSendWhoLine(User* source, User* user, Channel* channel, std::string& line);
+ void OnNamesListItem(User* issuer, Membership* memb, std::string &prefixes, std::string &nick);
};
Version ModuleInvisible::GetVersion()
{
- return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
+ return Version("Allows opers to join channels invisibly", VF_COMMON | VF_VENDOR);
}
-void ModuleInvisible::OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+static void BuildExcept(Membership* memb, CUList& excepts)
{
- if (user->IsModeSet('Q'))
+ const UserMembList* users = memb->chan->GetUsers();
+ for(UserMembCIter i = users->begin(); i != users->end(); i++)
{
- silent = true;
- /* Because we silenced the event, make sure it reaches the user whos joining (but only them of course) */
- this->WriteCommonFrom(user, channel, "JOIN %s", channel->name.c_str());
- ServerInstance->SNO->WriteToSnoMask('a', "\2NOTICE\2: Oper %s has joined %s invisibly (+Q)", user->GetFullHost().c_str(), channel->name.c_str());
+ // hide from all local non-opers
+ if (IS_LOCAL(i->first) && !IS_OPER(i->first))
+ excepts.insert(i->first);
}
}
-void ModuleInvisible::OnRehash(User* user)
+void ModuleInvisible::OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts)
{
- delete conf;
- conf = new ConfigReader(ServerInstance);
+ if (memb->user->IsModeSet('Q'))
+ {
+ BuildExcept(memb, excepts);
+ ServerInstance->SNO->WriteToSnoMask('a', "\2NOTICE\2: Oper %s has joined %s invisibly (+Q)",
+ memb->user->GetFullHost().c_str(), memb->chan->name.c_str());
+ }
}
-void ModuleInvisible::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
+void ModuleInvisible::OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts)
{
- if (user->IsModeSet('Q'))
+ if (memb->user->IsModeSet('Q'))
{
- silent = true;
- /* Because we silenced the event, make sure it reaches the user whos leaving (but only them of course) */
- this->WriteCommonFrom(user, channel, "PART %s%s%s", channel->name.c_str(),
- partmessage.empty() ? "" : " :",
- partmessage.empty() ? "" : partmessage.c_str());
+ BuildExcept(memb, excepts);
}
}
return OnUserPreNotice(user, dest, target_type, text, status, exempt_list);
}
-/* Fix by Eric @ neowin.net, thanks :) -- Brain */
-void ModuleInvisible::WriteCommonFrom(User *user, Channel* channel, const char* text, ...)
-{
- va_list argsPtr;
- char textbuffer[MAXBUF];
- char tb[MAXBUF];
-
- va_start(argsPtr, text);
- vsnprintf(textbuffer, MAXBUF, text, argsPtr);
- va_end(argsPtr);
- snprintf(tb,MAXBUF,":%s %s",user->GetFullHost().c_str(), textbuffer);
-
- const UserMembList *ulist = channel->GetUsers();
-
- for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++)
- {
- /* User only appears to vanish for non-opers */
- if (IS_LOCAL(i->first) && IS_OPER(i->first))
- {
- i->first->Write(std::string(tb));
- }
- }
-}
-
void ModuleInvisible::OnSendWhoLine(User* source, User* user, Channel* channel, std::string& line)
{
if (user->IsModeSet('Q') && !IS_OPER(source))
line.clear();
}
+void ModuleInvisible::OnNamesListItem(User* issuer, Membership* memb, std::string &prefixes, std::string &nick)
+{
+ if (memb->user->IsModeSet('Q') && !IS_OPER(issuer))
+ nick.clear();
+}
+
MODULE_INIT(ModuleInvisible)
return MOD_RES_PASSTHRU;
}
- void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts)
{
/* We arent interested in JOIN events caused by a network burst */
if (sync)
return;
- joinfloodsettings *f = jf.ext.get(channel);
+ joinfloodsettings *f = jf.ext.get(memb->chan);
/* But all others are OK */
if (f)
{
f->clear();
f->lock();
- channel->WriteChannelWithServ((char*)ServerInstance->Config->ServerName, "NOTICE %s :This channel has been closed to new users for 60 seconds because there have been more than %d joins in %d seconds.", channel->name.c_str(), f->joins, f->secs);
+ memb->chan->WriteChannelWithServ((char*)ServerInstance->Config->ServerName, "NOTICE %s :This channel has been closed to new users for 60 seconds because there have been more than %d joins in %d seconds.", memb->chan->name.c_str(), f->joins, f->secs);
}
}
}
return MOD_RES_PASSTHRU;
}
- void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
+ void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts)
{
- if (chan->IsModeSet('J') && (source != user))
+ if (memb->chan->IsModeSet('J') && (source != memb->user))
{
- delaylist* dl = kr.ext.get(chan);
+ delaylist* dl = kr.ext.get(memb->chan);
if (dl)
{
dl = new delaylist;
- kr.ext.set(chan, dl);
+ kr.ext.set(memb->chan, dl);
}
- (*dl)[user] = ServerInstance->Time() + strtoint(chan->GetModeParameter('J'));
+ (*dl)[memb->user] = ServerInstance->Time() + strtoint(memb->chan->GetModeParameter('J'));
}
}
return MOD_RES_PASSTHRU;
}
- void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
+ void OnNamesListItem(User* issuer, Membership* memb, std::string &prefixes, std::string &nick)
{
if (!cap.ext.get(issuer))
return;
if (nick.empty())
return;
- prefixes = channel->GetAllPrefixChars(user);
+ prefixes = memb->chan->GetAllPrefixChars(memb->user);
}
void OnEvent(Event *ev)
}
- virtual void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
+ virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts)
{
- if (!IS_LOCAL(user))
+ if (!IS_LOCAL(memb->user))
return;
- if (channel->GetExtBanStatus(user, 'p') == MOD_RES_DENY)
+ if (memb->chan->GetExtBanStatus(memb->user, 'p') == MOD_RES_DENY)
partmessage = "";
return;
ServerInstance->SendMode(modechange,this->ServerInstance->FakeClient);
}
- void OnPostJoin(User *user, Channel *channel)
+ void OnPostJoin(Membership* memb)
{
- if (user && IS_OPER(user))
- {
- if (user->IsModeSet('H'))
- {
- /* we respect your wish to be invisible */
- return;
- }
- PushChanMode(channel, user);
- }
+ if (IS_OPER(memb->user) && !memb->user->IsModeSet('H'))
+ PushChanMode(memb->chan, memb->user);
}
// XXX: is there a better way to do this?
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnUserPreKick(User* source, User* user, Channel* chan, const std::string &reason)
+ ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason)
{
if (IS_OPER(source) && CanOverride(source,"KICK"))
{
// If the kicker's status is less than the target's, or the kicker's status is less than or equal to voice
- if ((chan->GetPrefixValue(source) < chan->GetPrefixValue(user)) || (chan->GetPrefixValue(source) <= VOICE_VALUE))
+ if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE))
{
- ServerInstance->SNO->WriteGlobalSno('G',std::string(source->nick)+" used oper override to kick "+std::string(user->nick)+" on "+std::string(chan->name)+" ("+reason+")");
+ ServerInstance->SNO->WriteGlobalSno('G',std::string(source->nick)+" used oper override to kick "+std::string(memb->user->nick)+" on "+std::string(memb->chan->name)+" ("+reason+")");
+ return MOD_RES_ALLOW;
}
- return MOD_RES_ALLOW;
}
return MOD_RES_PASSTHRU;
}
class ModuleServProtectMode : public Module
{
-
ServProtectMode bm;
public:
ModuleServProtectMode(InspIRCd* Me)
}
- virtual ~ModuleServProtectMode()
+ ~ModuleServProtectMode()
{
ServerInstance->Modes->DelMode(&bm);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
- virtual void OnWhois(User* src, User* dst)
+ void OnWhois(User* src, User* dst)
{
if (dst->IsModeSet('k'))
{
}
}
- virtual ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string ¶m, bool adding, int pcnt)
+ ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string ¶m, bool adding, int pcnt)
{
/* Check that the mode is not a server mode, it is being removed, the user making the change is local, there is a parameter,
* and the user making the change is not a uline
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnKill(User* src, User* dst, const std::string &reason)
+ ModResult OnKill(User* src, User* dst, const std::string &reason)
{
if (src == NULL)
return MOD_RES_PASSTHRU;
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnUserPreKick(User *src, User *dst, Channel *c, const std::string &reason)
+ ModResult OnUserPreKick(User *src, Membership* memb, const std::string &reason)
{
- if (dst->IsModeSet('k'))
+ if (memb->user->IsModeSet('k'))
{
- src->WriteNumeric(484, "%s %s :You are not permitted to kick services", src->nick.c_str(), c->name.c_str());
+ src->WriteNumeric(484, "%s %s :You are not permitted to kick services",
+ src->nick.c_str(), memb->chan->name.c_str());
return MOD_RES_DENY;
}
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnWhoisLine(User* src, User* dst, int &numeric, std::string &text)
+ ModResult OnWhoisLine(User* src, User* dst, int &numeric, std::string &text)
{
return ((src != dst) && (numeric == 319) && dst->IsModeSet('k')) ? MOD_RES_DENY : MOD_RES_PASSTHRU;
}
Utils->TreeRoot->SetUserCount(1); // increment by 1
}
-void ModuleSpanningTree::OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+void ModuleSpanningTree::OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts)
{
// Only do this for local users
- if (IS_LOCAL(user))
+ if (IS_LOCAL(memb->user))
{
parameterlist params;
// set up their permissions and the channel TS with FJOIN.
// All users are FJOINed now, because a module may specify
// new joining permissions for the user.
- params.push_back(channel->name);
- params.push_back(ConvToStr(channel->age));
- params.push_back(std::string("+") + channel->ChanModes(true));
- params.push_back(ServerInstance->Modes->ModeString(user, channel, false)+","+std::string(user->uuid));
+ params.push_back(memb->chan->name);
+ params.push_back(ConvToStr(memb->chan->age));
+ params.push_back(std::string("+") + memb->chan->ChanModes(true));
+ params.push_back(memb->modes+","+std::string(memb->user->uuid));
Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FJOIN",params);
}
}
Utils->DoOneToMany(user->uuid,"FIDENT",params);
}
-void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
+void ModuleSpanningTree::OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts)
{
- if (IS_LOCAL(user))
+ if (IS_LOCAL(memb->user))
{
parameterlist params;
- params.push_back(channel->name);
+ params.push_back(memb->chan->name);
if (!partmessage.empty())
params.push_back(":"+partmessage);
- Utils->DoOneToMany(user->uuid,"PART",params);
+ Utils->DoOneToMany(memb->user->uuid,"PART",params);
}
}
}
}
-void ModuleSpanningTree::OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
+void ModuleSpanningTree::OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts)
{
parameterlist params;
- params.push_back(chan->name);
- params.push_back(user->uuid);
+ params.push_back(memb->chan->name);
+ params.push_back(memb->user->uuid);
params.push_back(":"+reason);
if (IS_LOCAL(source))
{
** *** MODULE EVENTS ***
**/
- virtual ModResult OnPreCommand(std::string &command, std::vector<std::string>& parameters, User *user, bool validated, const std::string &original_line);
- virtual void OnPostCommand(const std::string &command, const std::vector<std::string>& parameters, User *user, CmdResult result, const std::string &original_line);
- virtual void OnGetServerDescription(const std::string &servername,std::string &description);
- virtual void OnUserConnect(User* source);
- virtual void OnUserInvite(User* source,User* dest,Channel* channel, time_t);
- virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
- virtual void OnWallops(User* user, const std::string &text);
- virtual void OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list);
- virtual void OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list);
- virtual void OnBackgroundTimer(time_t curtime);
- virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created);
- virtual ModResult OnChangeLocalUserHost(User* user, const std::string &newhost);
- virtual void OnChangeName(User* user, const std::string &gecos);
- virtual void OnChangeIdent(User* user, const std::string &ident);
- virtual void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent);
- virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message);
- virtual void OnUserPostNick(User* user, const std::string &oldnick);
- virtual void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent);
- virtual void OnRemoteKill(User* source, User* dest, const std::string &reason, const std::string &operreason);
- virtual void OnPreRehash(User* user, const std::string ¶meter);
- virtual void OnRehash(User* user);
- virtual void OnOper(User* user, const std::string &opertype);
+ ModResult OnPreCommand(std::string &command, std::vector<std::string>& parameters, User *user, bool validated, const std::string &original_line);
+ void OnPostCommand(const std::string &command, const std::vector<std::string>& parameters, User *user, CmdResult result, const std::string &original_line);
+ void OnGetServerDescription(const std::string &servername,std::string &description);
+ void OnUserConnect(User* source);
+ void OnUserInvite(User* source,User* dest,Channel* channel, time_t);
+ void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
+ void OnWallops(User* user, const std::string &text);
+ void OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list);
+ void OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list);
+ void OnBackgroundTimer(time_t curtime);
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts);
+ ModResult OnChangeLocalUserHost(User* user, const std::string &newhost);
+ void OnChangeName(User* user, const std::string &gecos);
+ void OnChangeIdent(User* user, const std::string &ident);
+ void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts);
+ void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message);
+ void OnUserPostNick(User* user, const std::string &oldnick);
+ void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts);
+ void OnRemoteKill(User* source, User* dest, const std::string &reason, const std::string &operreason);
+ void OnPreRehash(User* user, const std::string ¶meter);
+ void OnRehash(User* user);
+ void OnOper(User* user, const std::string &opertype);
void OnLine(User* source, const std::string &host, bool adding, char linetype, long duration, const std::string &reason);
- virtual void OnAddLine(User *u, XLine *x);
- virtual void OnDelLine(User *u, XLine *x);
- virtual void OnMode(User* user, void* dest, int target_type, const std::vector<std::string> &text, const std::vector<TranslateType> &translate);
- virtual ModResult OnStats(char statschar, User* user, string_list &results);
- virtual ModResult OnSetAway(User* user, const std::string &awaymsg);
- virtual void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::vector<std::string> &modeline, const std::vector<TranslateType> &translate);
- virtual void ProtoSendMetaData(void* opaque, Extensible* target, const std::string &extname, const std::string &extdata);
- virtual std::string ProtoTranslate(Extensible* item);
- virtual void OnEvent(Event* event);
- virtual void OnLoadModule(Module* mod,const std::string &name);
- virtual void OnUnloadModule(Module* mod,const std::string &name);
- virtual ~ModuleSpanningTree();
- virtual Version GetVersion();
+ void OnAddLine(User *u, XLine *x);
+ void OnDelLine(User *u, XLine *x);
+ void OnMode(User* user, void* dest, int target_type, const std::vector<std::string> &text, const std::vector<TranslateType> &translate);
+ ModResult OnStats(char statschar, User* user, string_list &results);
+ ModResult OnSetAway(User* user, const std::string &awaymsg);
+ void ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::vector<std::string> &modeline, const std::vector<TranslateType> &translate);
+ void ProtoSendMetaData(void* opaque, Extensible* target, const std::string &extname, const std::string &extdata);
+ std::string ProtoTranslate(Extensible* item);
+ void OnEvent(Event* event);
+ void OnLoadModule(Module* mod,const std::string &name);
+ void OnUnloadModule(Module* mod,const std::string &name);
+ ~ModuleSpanningTree();
+ Version GetVersion();
void Prioritize();
};
ModuleUHNames(InspIRCd* Me) : Module(Me), cap(this, "userhost-in-names")
{
Implementation eventlist[] = { I_OnEvent, I_OnPreCommand, I_OnNamesListItem, I_On005Numeric };
- ServerInstance->Modules->Attach(eventlist, this, 5);
+ ServerInstance->Modules->Attach(eventlist, this, 4);
}
~ModuleUHNames()
return MOD_RES_PASSTHRU;
}
- void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
+ void OnNamesListItem(User* issuer, Membership* memb, std::string &prefixes, std::string &nick)
{
if (!cap.ext.get(issuer))
return;
if (nick.empty())
return;
- nick = user->GetFullHost();
+ nick = memb->user->GetFullHost();
}
void OnEvent(Event* ev)