diff options
-rw-r--r-- | src/channels.cpp | 40 | ||||
-rw-r--r-- | src/coremods/core_channel/core_channel.cpp | 47 |
2 files changed, 49 insertions, 38 deletions
diff --git a/src/channels.cpp b/src/channels.cpp index 352715728..b293e7fad 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -29,9 +29,6 @@ namespace { ChanModeReference ban(NULL, "ban"); - ChanModeReference inviteonlymode(NULL, "inviteonly"); - ChanModeReference keymode(NULL, "key"); - ChanModeReference limitmode(NULL, "limit"); } Channel::Channel(const std::string &cname, time_t ts) @@ -235,45 +232,12 @@ Channel* Channel::JoinUser(LocalUser* user, std::string cname, bool override, co return NULL; // If no module returned MOD_RES_DENY or MOD_RES_ALLOW (which is the case - // most of the time) then proceed to check channel modes +k, +i, +l and bans, - // in this order. + // most of the time) then proceed to check channel bans. + // // If a module explicitly allowed the join (by returning MOD_RES_ALLOW), // then this entire section is skipped if (MOD_RESULT == MOD_RES_PASSTHRU) { - std::string ckey = chan->GetModeParameter(keymode); - if (!ckey.empty()) - { - FIRST_MOD_RESULT(OnCheckKey, MOD_RESULT, (user, chan, key)); - if (!MOD_RESULT.check(InspIRCd::TimingSafeCompare(ckey, key))) - { - // If no key provided, or key is not the right one, and can't bypass +k (not invited or option not enabled) - user->WriteNumeric(ERR_BADCHANNELKEY, chan->name, "Cannot join channel (Incorrect channel key)"); - return NULL; - } - } - - if (chan->IsModeSet(inviteonlymode)) - { - FIRST_MOD_RESULT(OnCheckInvite, MOD_RESULT, (user, chan)); - if (MOD_RESULT != MOD_RES_ALLOW) - { - user->WriteNumeric(ERR_INVITEONLYCHAN, chan->name, "Cannot join channel (Invite only)"); - return NULL; - } - } - - std::string limit = chan->GetModeParameter(limitmode); - if (!limit.empty()) - { - FIRST_MOD_RESULT(OnCheckLimit, MOD_RESULT, (user, chan)); - if (!MOD_RESULT.check(chan->GetUserCounter() < ConvToNum<size_t>(limit))) - { - user->WriteNumeric(ERR_CHANNELISFULL, chan->name, "Cannot join channel (Channel is full)"); - return NULL; - } - } - if (chan->IsBanned(user)) { user->WriteNumeric(ERR_BANNEDFROMCHAN, chan->name, "Cannot join channel (You're banned)"); diff --git a/src/coremods/core_channel/core_channel.cpp b/src/coremods/core_channel/core_channel.cpp index 66630fbc3..a49f8492d 100644 --- a/src/coremods/core_channel/core_channel.cpp +++ b/src/coremods/core_channel/core_channel.cpp @@ -138,6 +138,53 @@ class CoreModChannel : public Module, public CheckExemption::EventListener } } + ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string&, std::string&, const std::string& keygiven) CXX11_OVERRIDE + { + if (!chan) + return MOD_RES_PASSTHRU; + + // Check whether the channel key is correct. + const std::string ckey = chan->GetModeParameter(&keymode); + if (!ckey.empty()) + { + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnCheckKey, MOD_RESULT, (user, chan, keygiven)); + if (!MOD_RESULT.check(InspIRCd::TimingSafeCompare(ckey, keygiven))) + { + // If no key provided, or key is not the right one, and can't bypass +k (not invited or option not enabled) + user->WriteNumeric(ERR_BADCHANNELKEY, chan->name, "Cannot join channel (Incorrect channel key)"); + return MOD_RES_DENY; + } + } + + // Check whether the invite only mode is set. + if (chan->IsModeSet(inviteonlymode)) + { + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnCheckInvite, MOD_RESULT, (user, chan)); + if (MOD_RESULT != MOD_RES_ALLOW) + { + user->WriteNumeric(ERR_INVITEONLYCHAN, chan->name, "Cannot join channel (Invite only)"); + return MOD_RES_DENY; + } + } + + // Check whether the limit would be exceeded by this user joining. + if (chan->IsModeSet(limitmode)) + { + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnCheckLimit, MOD_RESULT, (user, chan)); + if (!MOD_RESULT.check(chan->GetUserCounter() < static_cast<size_t>(limitmode.ext.get(chan)))) + { + user->WriteNumeric(ERR_CHANNELISFULL, chan->name, "Cannot join channel (Channel is full)"); + return MOD_RES_DENY; + } + } + + // Everything looks okay. + return MOD_RES_PASSTHRU; + } + void OnPostJoin(Membership* memb) CXX11_OVERRIDE { Channel* const chan = memb->chan; |