diff options
Diffstat (limited to 'src/channels.cpp')
-rw-r--r-- | src/channels.cpp | 141 |
1 files changed, 64 insertions, 77 deletions
diff --git a/src/channels.cpp b/src/channels.cpp index 3d824f0d8..98ecfe127 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -1,29 +1,36 @@ -/* Channel-handling routines. +/* + * Anope IRC Services * - * (C) 2003-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2003-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ #include "services.h" #include "channels.h" -#include "regchannel.h" #include "logger.h" #include "modules.h" #include "users.h" -#include "bots.h" #include "servers.h" #include "protocol.h" #include "users.h" #include "config.h" -#include "access.h" #include "sockets.h" #include "language.h" #include "uplink.h" +#include "event.h" +#include "modules/chanserv.h" channel_map ChannelList; std::vector<Channel *> Channel::deleting; @@ -40,21 +47,15 @@ Channel::Channel(const Anope::string &nname, time_t ts) this->server_modetime = this->chanserv_modetime = 0; this->server_modecount = this->chanserv_modecount = this->bouncy_modes = this->topic_ts = this->topic_time = 0; - this->ci = ChannelInfo::Find(this->name); - if (this->ci) - this->ci->c = this; - if (Me && Me->IsSynced()) Log(NULL, this, "create"); - FOREACH_MOD(OnChannelCreate, (this)); + EventManager::Get()->Dispatch(&Event::ChannelCreate::OnChannelCreate, this); } Channel::~Channel() { - UnsetExtensibles(); - - FOREACH_MOD(OnChannelDelete, (this)); + EventManager::Get()->Dispatch(&Event::ChannelDelete::OnChannelDelete, this); ModeManager::StackerDel(this); @@ -90,7 +91,7 @@ void Channel::Reset() for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it) this->SetCorrectModes(it->second->user, true); - + // If the channel is syncing now, do not force a sync due to Reset(), as we are probably iterating over users in Message::SJoin // A sync will come soon if (!syncing) @@ -100,7 +101,7 @@ void Channel::Reset() void Channel::Sync() { syncing = false; - FOREACH_MOD(OnChannelSync, (this)); + EventManager::Get()->Dispatch(&Event::ChannelSync::OnChannelSync, this); CheckModes(); } @@ -118,7 +119,7 @@ void Channel::CheckModes() } Reference<Channel> ref = this; - FOREACH_MOD(OnCheckModes, (ref)); + EventManager::Get()->Dispatch(&Event::CheckModes::OnCheckModes, ref); } bool Channel::CheckDelete() @@ -128,13 +129,13 @@ bool Channel::CheckDelete() */ if (this->syncing) return false; - + /* Permanent channels never get deleted */ if (this->HasMode("PERM")) return false; EventReturn MOD_RESULT; - FOREACH_RESULT(OnCheckDelete, MOD_RESULT, (this)); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::CheckDelete::OnCheckDelete, this); return MOD_RESULT != EVENT_STOP && this->users.empty(); } @@ -158,7 +159,7 @@ void Channel::DeleteUser(User *user) if (user->server && user->server->IsSynced() && !user->Quitting()) Log(user, this, "leave"); - FOREACH_MOD(OnLeaveChannel, (user, this)); + EventManager::Get()->Dispatch(&Event::LeaveChannel::OnLeaveChannel, user, this); ChanUserContainer *cu = user->FindChannel(this); if (!this->users.erase(user)) @@ -257,7 +258,7 @@ std::vector<Anope::string> Channel::GetModeList(const Anope::string &mname) return r; } -void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) +void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) { if (!ocm) return; @@ -291,7 +292,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Ano if (cc) cc->status.AddMode(cm->mchar); - FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, param)); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeSet::OnChannelModeSet, this, setter, cm, param); /* Enforce secureops, etc */ if (enforce_mlock && MOD_RESULT != EVENT_STOP) @@ -312,13 +313,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Ano return; } - if (cm->type == MODE_LIST) - { - ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - cml->OnAdd(this, param); - } - - FOREACH_RESULT(OnChannelModeSet, MOD_RESULT, (this, setter, cm, param)); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeSet::OnChannelModeSet, this, setter, cm, param); /* Check if we should enforce mlock */ if (!enforce_mlock || MOD_RESULT == EVENT_STOP) @@ -327,7 +322,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *ocm, const Ano this->CheckModes(); } -void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) +void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) { if (!ocm) return; @@ -346,8 +341,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const return; } - BotInfo *bi = BotInfo::Find(param); - User *u = bi ? bi : User::Find(param); + User *u = User::Find(param); if (!u) { @@ -362,7 +356,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const if (cc) cc->status.DelMode(cm->mchar); - FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param)); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeUnset::OnChannelModeUnset, this, setter, cm, param); if (enforce_mlock && MOD_RESULT != EVENT_STOP) this->SetCorrectModes(u, false); @@ -381,14 +375,8 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const } else this->modes.erase(cm->name); - - if (cm->type == MODE_LIST) - { - ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - cml->OnDel(this, param); - } - FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param)); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::ChannelModeUnset::OnChannelModeUnset, this, setter, cm, param); if (cm->name == "PERM") { @@ -406,7 +394,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *ocm, const this->CheckModes(); } -void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) +void Channel::SetMode(User *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { Anope::string wparam = param; if (!cm) @@ -455,16 +443,15 @@ void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, ChannelMode *wcm = cm->Wrap(wparam); ModeManager::StackerAdd(bi, this, wcm, true, wparam); - MessageSource ms(bi); - SetModeInternal(ms, wcm, wparam, enforce_mlock); + SetModeInternal(bi, wcm, wparam, enforce_mlock); } -void Channel::SetMode(BotInfo *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock) +void Channel::SetMode(User *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock) { SetMode(bi, ModeManager::FindChannelModeByName(mname), param, enforce_mlock); } -void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) +void Channel::RemoveMode(User *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { if (!cm) return; @@ -509,11 +496,10 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶ ChannelMode *wcm = cm->Wrap(wparam); ModeManager::StackerAdd(bi, this, wcm, false, wparam); - MessageSource ms(bi); - RemoveModeInternal(ms, wcm, wparam, enforce_mlock); + RemoveModeInternal(bi, wcm, wparam, enforce_mlock); } -void Channel::RemoveMode(BotInfo *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock) +void Channel::RemoveMode(User *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock) { RemoveMode(bi, ModeManager::FindChannelModeByName(mname), param, enforce_mlock); } @@ -533,7 +519,7 @@ bool Channel::GetParam(const Anope::string &mname, Anope::string &target) const return false; } -void Channel::SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...) +void Channel::SetModes(User *bi, bool enforce_mlock, const char *cmodes, ...) { char buf[BUFSIZE] = ""; va_list args; @@ -713,7 +699,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, Log(setter, this, "mode") << modestring << paramstring; else Log(LOG_DEBUG) << source.GetName() << " is setting " << this->name << " to " << modestring << paramstring; - + if (enforce_mlock) this->CheckModes(); } @@ -734,14 +720,14 @@ bool Channel::MatchesList(User *u, const Anope::string &mode) return false; } -void Channel::KickInternal(const MessageSource &source, const Anope::string &nick, const Anope::string &reason) +bool Channel::KickInternal(const MessageSource &source, const Anope::string &nick, const Anope::string &reason) { User *sender = source.GetUser(); User *target = User::Find(nick); if (!target) { Log(LOG_DEBUG) << "Channel::KickInternal got a nonexistent user " << nick << " on " << this->name << ": " << reason; - return; + return false; } if (sender) @@ -755,17 +741,22 @@ void Channel::KickInternal(const MessageSource &source, const Anope::string &nic if (cu == NULL) { Log(LOG_DEBUG) << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name; - return; + return false; } ChannelStatus status = cu->status; - FOREACH_MOD(OnPreUserKicked, (source, cu, reason)); + EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::PreUserKicked::OnPreUserKicked, source, cu, reason); + if ((sender && sender->server == Me) || source.GetServer() == Me) + if (MOD_RESULT == EVENT_STOP) + return false; + this->DeleteUser(target); - FOREACH_MOD(OnUserKicked, (source, target, this->name, status, reason)); + EventManager::Get()->Dispatch(&Event::UserKicked::OnUserKicked, source, target, this->name, status, reason); + return true; } -bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) +bool Channel::Kick(User *source, User *u, const char *reason, ...) { va_list args; char buf[BUFSIZE] = ""; @@ -776,16 +767,13 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) /* Do not kick protected clients or Ulines */ if (u->IsProtected()) return false; - - if (bi == NULL) - bi = this->ci->WhoSends(); - EventReturn MOD_RESULT; - FOREACH_RESULT(OnBotKick, MOD_RESULT, (bi, this, u, buf)); - if (MOD_RESULT == EVENT_STOP) + if (source == NULL) + source = this->ci->WhoSends(); + + if (!this->KickInternal(source, u->nick, buf)) return false; - IRCD->SendKick(bi, this, u, "%s", buf); - this->KickInternal(bi, u->nick, buf); + IRCD->SendKick(source, this, u, "%s", buf); return true; } @@ -798,7 +786,7 @@ void Channel::ChangeTopicInternal(User *u, const Anope::string &user, const Anop Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << this->topic_setter << " to " << newtopic; - FOREACH_MOD(OnTopicUpdated, (u, this, user, this->topic)); + EventManager::Get()->Dispatch(&Event::TopicUpdated::OnTopicUpdated, u, this, user, this->topic); } void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts) @@ -812,25 +800,25 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop /* Now that the topic is set update the time set. This is *after* we set it so the protocol modules are able to tell the old last set time */ this->topic_time = Anope::CurTime; - FOREACH_MOD(OnTopicUpdated, (NULL, this, user, this->topic)); + EventManager::Get()->Dispatch(&Event::TopicUpdated::OnTopicUpdated, nullptr, this, user, this->topic); } void Channel::SetCorrectModes(User *user, bool give_modes) { if (user == NULL) return; - + if (!this->ci) return; Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << this->name << " (" << (give_modes ? "" : "not ") << "giving modes)"; - AccessGroup u_access = ci->AccessFor(user); + ChanServ::AccessGroup u_access = ci->AccessFor(user); /* Initially only take modes if the channel is being created by a non netmerge */ bool take_modes = this->syncing && user->server->IsSynced(); - FOREACH_MOD(OnSetCorrectModes, (user, this, u_access, give_modes, take_modes)); + EventManager::Get()->Dispatch(&Event::SetCorrectModes::OnSetCorrectModes, user, this, u_access, give_modes, take_modes); /* Never take modes from ulines */ if (user->server->IsULined()) @@ -857,7 +845,7 @@ void Channel::SetCorrectModes(User *user, bool give_modes) } } /* modes that have no privileges assigned shouldn't be removed (like operprefix, ojoin) */ - else if (take_modes && !has_priv && ci->GetLevel(cm->name + "ME") != ACCESS_INVALID && !u_access.HasPriv(cm->name + "ME")) + else if (take_modes && !has_priv && ci->GetLevel(cm->name + "ME") != ChanServ::ACCESS_INVALID && !u_access.HasPriv(cm->name + "ME")) { /* Only remove modes if they are > voice */ if (cm->name == "VOICE") @@ -901,15 +889,14 @@ bool Channel::CheckKick(User *user) Anope::string mask, reason; - EventReturn MOD_RESULT; - FOREACH_RESULT(OnCheckKick, MOD_RESULT, (user, this, mask, reason)); + EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::CheckKick::OnCheckKick, user, this, mask, reason); if (MOD_RESULT != EVENT_STOP) return false; - + if (mask.empty()) mask = this->ci->GetIdealBan(user); if (reason.empty()) - reason = Language::Translate(user->Account(), CHAN_NOT_ALLOWED_TO_JOIN); + reason = Language::Translate(user->Account(), _("You are not permitted to be on this channel.")); Log(LOG_DEBUG) << "Autokicking " << user->nick << " (" << mask << ") from " << this->name; |