diff --git a/docs/Changes.lang b/docs/Changes.lang index 8a9900381..4289ba295 100644 --- a/docs/Changes.lang +++ b/docs/Changes.lang @@ -11,6 +11,7 @@ Anope Version 1.9.3 NICK_REG_MAIL NICK_MAIL_TEXT NICK_SENDPASS + CHAN_LEVEL_FOUNDER *** Mod Strings: NICK_GLIST_REPLY diff --git a/include/extern.h b/include/extern.h index 100aceaa3..6f41c3977 100644 --- a/include/extern.h +++ b/include/extern.h @@ -124,11 +124,6 @@ E void cs_remove_nick(const NickCore * nc); E void check_modes(Channel * c); E int check_valid_admin(User * user, Channel * chan, int servermode); E int check_valid_op(User * user, Channel * chan, int servermode); -E int check_should_op(User * user, char *chan); -E int check_should_voice(User * user, char *chan); -E int check_should_halfop(User * user, char *chan); -E int check_should_owner(User * user, char *chan); -E int check_should_protect(User * user, char *chan); E void record_topic(const char *chan); E void restore_topic(const char *chan); E int check_topiclock(Channel * c, time_t topic_time); @@ -138,7 +133,6 @@ E ChannelInfo *cs_findchan(const std::string &chan); E ChannelInfo *cs_findchan(const ci::string &chan); E int check_access(User * user, ChannelInfo * ci, int what); E bool IsFounder(User *user, ChannelInfo *ci); -E bool IsRealFounder(User *user, ChannelInfo *ci); E int get_access(User *user, ChannelInfo *ci); E void update_cs_lastseen(User * user, ChannelInfo * ci); E int get_idealban(ChannelInfo * ci, User * u, char *ret, int retlen); diff --git a/include/services.h b/include/services.h index 7db58e3fb..0a4648105 100644 --- a/include/services.h +++ b/include/services.h @@ -621,8 +621,9 @@ struct BadWord #define CA_AUTOOWNER 36 #define CA_OWNER 37 #define CA_OWNERME 38 +#define CA_FOUNDER 39 -#define CA_SIZE 39 +#define CA_SIZE 40 /* BotServ SET flags */ enum BotServFlag diff --git a/lang/cat.l b/lang/cat.l index 40fc7e58d..b662ab0e0 100644 --- a/lang/cat.l +++ b/lang/cat.l @@ -1050,6 +1050,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/de.l b/lang/de.l index 663e6079e..d655be91d 100644 --- a/lang/de.l +++ b/lang/de.l @@ -1054,6 +1054,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders CHAN_ACCESS_VIEW_XOP_FORMAT %3d %s %s by %s, last seen %s diff --git a/lang/en_us.l b/lang/en_us.l index 42cdc9865..8f1e9c9f0 100644 --- a/lang/en_us.l +++ b/lang/en_us.l @@ -1028,6 +1028,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/es.l b/lang/es.l index f1e4a6f64..ba4eb8cc4 100644 --- a/lang/es.l +++ b/lang/es.l @@ -1048,6 +1048,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/fr.l b/lang/fr.l index 8172746ad..d32312478 100644 --- a/lang/fr.l +++ b/lang/fr.l @@ -1059,6 +1059,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/gr.l b/lang/gr.l index 8ab9a5fda..2adc288d1 100644 --- a/lang/gr.l +++ b/lang/gr.l @@ -1048,6 +1048,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/hun.l b/lang/hun.l index 1e277bd25..ec488369b 100644 --- a/lang/hun.l +++ b/lang/hun.l @@ -1039,6 +1039,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatikus válaszok CHAN_IS_REGISTERED diff --git a/lang/it.l b/lang/it.l index 86b16f786..1f557557d 100644 --- a/lang/it.l +++ b/lang/it.l @@ -1031,6 +1031,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/nl.l b/lang/nl.l index b63e98377..3a8c6ba51 100644 --- a/lang/nl.l +++ b/lang/nl.l @@ -1046,6 +1046,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/pl.l b/lang/pl.l index 4898de720..934e00763 100644 --- a/lang/pl.l +++ b/lang/pl.l @@ -1332,6 +1332,9 @@ CHAN_LEVEL_OWNER CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders + # Automatic responses CHAN_IS_REGISTERED Ten kana³ zosta³ zarejestrowany z %s. diff --git a/lang/pt.l b/lang/pt.l index a26479ce3..0976d01b3 100644 --- a/lang/pt.l +++ b/lang/pt.l @@ -1048,6 +1048,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/ru.l b/lang/ru.l index 257b29292..9235e396e 100644 --- a/lang/ru.l +++ b/lang/ru.l @@ -1029,6 +1029,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/lang/tr.l b/lang/tr.l index 30e9a6860..2b18ffbb3 100644 --- a/lang/tr.l +++ b/lang/tr.l @@ -1054,6 +1054,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED diff --git a/src/channels.c b/src/channels.c index 4cdfb2c42..5a439726f 100644 --- a/src/channels.c +++ b/src/channels.c @@ -1465,7 +1465,7 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) /* If this channel has secureops or the user matches autodeop or the channel is syncing and this is the first user and they are not ulined, check to remove modes */ if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !user->server->IsULined()) { - if (owner && c->HasUserStatus(user, CMODE_OWNER) && !IsFounder(user, ci)) + if (owner && c->HasUserStatus(user, CMODE_OWNER) && !check_access(user, ci, CA_FOUNDER)) c->RemoveMode(NULL, CMODE_OWNER, user->nick); if (admin && c->HasUserStatus(user, CMODE_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME)) diff --git a/src/chanserv.c b/src/chanserv.c index 17dd65a7b..36e82f6b9 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -59,6 +59,7 @@ static int def_levels[][2] = { { CA_AUTOOWNER, ACCESS_QOP }, { CA_OWNER, ACCESS_FOUNDER }, { CA_OWNERME, ACCESS_QOP }, + { CA_FOUNDER, ACCESS_QOP }, { -1 } }; @@ -103,6 +104,7 @@ LevelInfo levelinfo[] = { { CA_AUTOOWNER, "AUTOOWNER", CHAN_LEVEL_AUTOOWNER }, { CA_OWNER, "OWNER", CHAN_LEVEL_OWNER }, { CA_OWNERME, "OWNERME", CHAN_LEVEL_OWNERME }, + { CA_FOUNDER, "FOUNDER", CHAN_LEVEL_FOUNDER }, { -1 } }; int levelinfo_maxwidth = 0; @@ -466,111 +468,6 @@ int check_valid_op(User * user, Channel * chan, int servermode) /*************************************************************************/ -/* Check whether a user should be opped on a channel, and if so, do it. - * Return 1 if the user was opped, 0 otherwise. (Updates the channel's - * last used time if the user was opped.) */ - -int check_should_op(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+') - return 0; - - if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified()) - return 0; - - if (check_access(user, ci, CA_AUTOOP)) - { - ci->c->SetMode(NULL, CMODE_OP, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -/* Check whether a user should be voiced on a channel, and if so, do it. - * Return 1 if the user was voiced, 0 otherwise. */ - -int check_should_voice(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+') - return 0; - - if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified()) - return 0; - - if (check_access(user, ci, CA_AUTOVOICE)) - { - ci->c->SetMode(NULL, CMODE_VOICE, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -int check_should_halfop(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+') - return 0; - - if (check_access(user, ci, CA_AUTOHALFOP)) - { - ci->c->SetMode(NULL, CMODE_HALFOP, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -int check_should_owner(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+') - return 0; - - if ((ci->HasFlag(CI_SECUREFOUNDER) && IsRealFounder(user, ci)) - || (!ci->HasFlag(CI_SECUREFOUNDER) && IsFounder(user, ci))) { - ci->c->SetMode(NULL, CMODE_OP, user->nick); - ci->c->SetMode(NULL, CMODE_OWNER, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -int check_should_protect(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+') - return 0; - - if (check_access(user, ci, CA_AUTOPROTECT)) - { - ci->c->SetMode(NULL, CMODE_OWNER, user->nick); - ci->c->SetMode(NULL, CMODE_PROTECT, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - /* Record the current channel topic in the ChannelInfo structure. */ void record_topic(const char *chan) @@ -846,15 +743,20 @@ int check_access(User * user, ChannelInfo * ci, int what) if (level > 0) ci->last_used = time(NULL); + /* Superadmin always wins. Always. */ + if (user->isSuperAdmin) + return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1); + /* If the access of the level we are checking is disabled, they *always* get denied */ if (limit == ACCESS_INVALID) return 0; - if (limit > ACCESS_FOUNDER) - return 1; - if (limit == ACCESS_FOUNDER) - return (what == CA_AUTODEOP || what == CA_NOJOIN ? !IsRealFounder(user, ci) : IsRealFounder(user, ci)); + /* If the level of the user is >= the level for "founder" of this channel and "founder" isn't disabled, they can do anything */ + if (ci->levels[CA_FOUNDER] != ACCESS_INVALID && level >= ci->levels[CA_FOUNDER]) + return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1); + /* Hacks to make flags work */ if (what == CA_AUTODEOP && (ci->HasFlag(CI_SECUREOPS)) && level == 0) return 1; + if (what == CA_AUTODEOP || what == CA_NOJOIN) return level <= ci->levels[what]; else @@ -886,43 +788,12 @@ void reset_levels(ChannelInfo * ci) /*************************************************************************/ -/** Is the user a channel founder? (owner) - * @param user The user - * @param ci The channel - * @return true or false - */ -bool IsFounder(User *user, ChannelInfo *ci) -{ - ChanAccess *access = NULL; - - if (!user || !ci) - return false; - - if (IsRealFounder(user, ci)) - return true; - - if (user->Account()) - access = ci->GetAccess(user->Account()); - else - { - NickAlias *na = findnick(user->nick); - if (na) - access = ci->GetAccess(na->nc); - } - - /* If they're QOP+ and theyre identified or theyre recognized and the channel isn't secure */ - if (access && access->level >= ACCESS_QOP && (user->Account() || (user->IsRecognized() && !(ci->HasFlag(CI_SECURE))))) - return true; - - return false; -} - /** Is the user the real founder? * @param user The user * @param ci The channel * @return true or false */ -bool IsRealFounder(User *user, ChannelInfo *ci) +bool IsFounder(User *user, ChannelInfo *ci) { if (!user || !ci) return false; diff --git a/src/core/bs_info.c b/src/core/bs_info.c index 3f873aafd..f7d6fb46d 100644 --- a/src/core/bs_info.c +++ b/src/core/bs_info.c @@ -78,7 +78,7 @@ class CommandBSInfo : public Command } else if ((ci = cs_findchan(query))) { - if (!IsFounder(u, ci) && !u->Account()->HasPriv("botserv/administration")) + if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration")) { notice_lang(Config.s_BotServ, u, ACCESS_DENIED); return MOD_CONT; diff --git a/src/core/cs_access.c b/src/core/cs_access.c index f49fca990..6ef238b71 100644 --- a/src/core/cs_access.c +++ b/src/core/cs_access.c @@ -416,7 +416,7 @@ class CommandCSAccess : public Command return MOD_CONT; } - if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); return MOD_CONT; @@ -474,7 +474,7 @@ class CommandCSLevels : public Command this->OnSyntaxError(u, cmd); else if (ci->HasFlag(CI_XOP)) notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_XOP); - else if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else if (cmd == "SET") { level = strtol(s, &error, 10); @@ -514,16 +514,20 @@ class CommandCSLevels : public Command notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, Config.s_ChanServ); } else if (cmd == "DIS" || cmd == "DISABLE") { - for (i = 0; levelinfo[i].what >= 0; i++) { - if (stricmp(levelinfo[i].name, what) == 0) { - ci->levels[levelinfo[i].what] = ACCESS_INVALID; - FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what)); - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name - << " on channel " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED, - levelinfo[i].name, chan); - return MOD_CONT; + /* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */ + if (stricmp(what, "FOUNDER")) + { + for (i = 0; levelinfo[i].what >= 0; i++) { + if (stricmp(levelinfo[i].name, what) == 0) { + ci->levels[levelinfo[i].what] = ACCESS_INVALID; + FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what)); + + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name + << " on channel " << ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED, + levelinfo[i].name, chan); + return MOD_CONT; + } } } diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c index 42b79c362..3d56e4846 100644 --- a/src/core/cs_akick.c +++ b/src/core/cs_akick.c @@ -224,7 +224,7 @@ class CommandCSAKick : public Command { User *u2 = it->second; - if (IsFounder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci))) + if (check_access(u2, ci, CA_FOUNDER) || (get_access(u2, ci) >= get_access(u, ci))) { if (match_usermask(mask.c_str(), u2)) { diff --git a/src/core/cs_drop.c b/src/core/cs_drop.c index f7c7a8571..baae58026 100644 --- a/src/core/cs_drop.c +++ b/src/core/cs_drop.c @@ -48,7 +48,7 @@ class CommandCSDrop : public Command return MOD_CONT; } - if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)) && !u->Account()->HasCommand("chanserv/drop")) + if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop")) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); return MOD_CONT; @@ -78,7 +78,7 @@ class CommandCSDrop : public Command * drop the channel before issuing the wallops. */ if (Config.WallDrop) { - if ((level < ACCESS_FOUNDER) || (!IsRealFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER))) + if ((level < ACCESS_FOUNDER) || (!IsFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER))) ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan); } diff --git a/src/core/cs_modes.c b/src/core/cs_modes.c index 3480ca1b6..312bc55dc 100644 --- a/src/core/cs_modes.c +++ b/src/core/cs_modes.c @@ -381,7 +381,7 @@ class CSModes : public Module this->AddCommand(ChanServ, new CommandCSDeVoice()); if (Me && Me->IsSynced()) - OnUplinkSync(); + OnUplinkSync(NULL); Implementation i[] = { I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp @@ -389,7 +389,7 @@ class CSModes : public Module ModuleManager::Attach(i, this, 3); } - void OnUplinkSync() + void OnUplinkSync(Server *) { if (ModeManager::FindChannelModeByName(CMODE_OWNER)) { diff --git a/src/core/cs_set.c b/src/core/cs_set.c index 75850f453..07171bdc1 100644 --- a/src/core/cs_set.c +++ b/src/core/cs_set.c @@ -645,14 +645,14 @@ class CommandCSSet : public Command notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else if (cmd == "FOUNDER") { - if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci))) + if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else DoSetFounder(u, ci, param); } else if (cmd == "SUCCESSOR") { - if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci))) + if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else DoSetSuccessor(u, ci, param); @@ -681,7 +681,7 @@ class CommandCSSet : public Command DoSetSecureOps(u, ci, param); else if (cmd == "SECUREFOUNDER") { - if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci))) + if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else DoSetSecureFounder(u, ci, param); diff --git a/src/core/cs_xop.c b/src/core/cs_xop.c index eb4a76c47..c25bf02e2 100644 --- a/src/core/cs_xop.c +++ b/src/core/cs_xop.c @@ -421,7 +421,7 @@ class XOPBase : public Command return MOD_CONT; } - if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); return MOD_CONT; @@ -612,7 +612,7 @@ class CSXOP : public Module this->AddCommand(ChanServ, new CommandCSVOP()); if (Me && Me->IsSynced()) - OnUplinkSync(); + OnUplinkSync(NULL); Implementation i[] = { I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp @@ -620,7 +620,7 @@ class CSXOP : public Module ModuleManager::Attach(i, this, 3); } - void OnUplinkSync() + void OnUplinkSync(Server *) { if (ModeManager::FindChannelModeByName(CMODE_OWNER)) this->AddCommand(ChanServ, new CommandCSQOP()); diff --git a/src/modules.c b/src/modules.c index 822d04ea2..0044bcc56 100644 --- a/src/modules.c +++ b/src/modules.c @@ -166,6 +166,7 @@ int Module::AddCommand(BotInfo *bi, Command *c) if (!bi || !c) return MOD_ERR_PARAMS; + c->module = this; c->service = bi; std::pair::iterator, bool> it = bi->Commands.insert(std::make_pair(c->name, c));