diff options
| author | Adam <Adam@anope.org> | 2013-09-29 13:39:59 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2013-09-29 15:41:32 -0400 |
| commit | 44dd8d07d9fd3461411c505d8afa6a316184a15c (patch) | |
| tree | 9f02aea8964c147bd7e112ba7912ba2ccbd9127a /modules | |
| parent | f7aa69b596500413ad33f386e74e28776507ca4f (diff) | |
Add chanserv:always_lower_ts config option to always lower registered
channels timestamps to the creation time which fixes some race
conditions regarding users joining empty registered channels and doing
things prior to the -o from services coming through.
Without always_lower_ts attempt to bounce mode changes from bad users,
which will work okay in most cases.
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/pseudoclients/chanserv.cpp | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index f3045c256..9a3e309a7 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -18,10 +18,11 @@ class ChanServCore : public Module, public ChanServService std::vector<Anope::string> defaults; ExtensibleItem<bool> inhabit; ExtensibleRef<bool> persist; + bool always_lower; public: ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), - ChanServService(this), inhabit(this, "inhabit"), persist("PERSIST") + ChanServService(this), inhabit(this, "inhabit"), persist("PERSIST"), always_lower(false) { } @@ -106,6 +107,8 @@ class ChanServCore : public Module, public ChanServService } else if (defaults[0].equals_ci("none")) defaults.clear(); + + always_lower = conf->GetModule(this)->Get<bool>("always_lower_ts"); } void OnBotDelete(BotInfo *bi) anope_override @@ -421,6 +424,36 @@ class ChanServCore : public Module, public ChanServService else if (persist->Get(ci)) ci->c->SetMode(NULL, "PERM"); } + + void OnJoinChannel(User *u, Channel *c) anope_override + { + if (always_lower && c->ci && c->creation_time > c->ci->time_registered) + { + Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->time_registered; + c->creation_time = c->ci->time_registered; + IRCD->SendChannel(c); + c->Reset(); + } + } + + EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override + { + if (!always_lower && Anope::CurTime == c->creation_time && c->ci && setter.GetUser()) + { + ChanUserContainer *cu = c->FindUser(setter.GetUser()); + ChannelMode *cm = ModeManager::FindChannelModeByName("OP"); + if (cu && cm && !cu->status.HasMode(cm->mchar)) + { + /* Our -o and their mode change crossing, bounce their mode */ + c->RemoveMode(c->ci->WhoSends(), mode, param); + /* We don't set mlocks until after the join has finished processing, it will stack with this change, + * so there isn't much for the user to remove except -nt etc which is likely locked anyway. + */ + } + } + + return EVENT_CONTINUE; + } }; MODULE_INIT(ChanServCore) |
