summaryrefslogtreecommitdiff
path: root/src/users.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/users.cpp')
-rw-r--r--src/users.cpp259
1 files changed, 138 insertions, 121 deletions
diff --git a/src/users.cpp b/src/users.cpp
index 264f5ceba..3d4b7e1b7 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -1,18 +1,25 @@
-/* Routines to maintain a list of online users.
+/*
+ * 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 "modules.h"
#include "users.h"
-#include "account.h"
#include "protocol.h"
#include "servers.h"
#include "channels.h"
@@ -22,16 +29,17 @@
#include "language.h"
#include "sockets.h"
#include "uplink.h"
+#include "event.h"
+#include "modules/nickserv.h"
-user_map UserListByNick, UserListByUID;
+user_map UserListByNick;
+uid_map UserListByUID;
int OperCount = 0;
-unsigned MaxUserCount = 0;
-time_t MaxUserTime = 0;
std::list<User *> User::quitting_users;
-User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &uip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *account) : ip(uip)
+User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &uip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *account) : ip(uip)
{
if (snick.empty() || sident.empty() || shost.empty())
throw CoreException("Bad args passed to User::User");
@@ -53,7 +61,6 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->SetModesInternal(sserver, "%s", smodes.c_str());
this->uid = suid;
this->super_admin = false;
- this->nc = NULL;
size_t old = UserListByNick.size();
UserListByNick[snick] = this;
@@ -72,18 +79,10 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
Log(this, "connect") << (!vhost.empty() && vhost != host ? "(" + vhost + ") " : "") << "(" << srealname << ") " << (!uip.empty() && uip != host ? "[" + uip + "] " : "") << "connected to the network (" << sserver->GetName() << ")";
}
- if (UserListByNick.size() > MaxUserCount)
- {
- MaxUserCount = UserListByNick.size();
- MaxUserTime = Anope::CurTime;
- if (sserver && sserver->IsSynced())
- Log(this, "maxusers") << "connected - new maximum user count: " << UserListByNick.size();
- }
-
bool exempt = false;
if (server && server->IsULined())
exempt = true;
- FOREACH_MOD(OnUserConnect, (this, exempt));
+ EventManager::Get()->Dispatch(&Event::UserConnect::OnUserConnect, this, exempt);
}
static void CollideKill(User *target, const Anope::string &reason)
@@ -96,7 +95,7 @@ static void CollideKill(User *target, const Anope::string &reason)
IRCD->SendQuit(target, "%s", reason.c_str());
// Reintroduce my client
- if (BotInfo *bi = dynamic_cast<BotInfo *>(target))
+ if (ServiceBot *bi = dynamic_cast<ServiceBot *>(target))
bi->OnKill();
else
target->Quit(reason);
@@ -111,7 +110,7 @@ static void Collide(User *u, const Anope::string &id, const Anope::string &type)
CollideKill(u, type);
}
-User* User::OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc)
+User* User::OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *nc)
{
// How IRCds handle collisions varies a lot, for safety well just always kill both sides
// With properly set qlines, this can almost never happen anyway
@@ -141,7 +140,7 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
/* Sanity check to make sure we don't segfault */
if (newnick.empty())
throw CoreException("User::ChangeNick() got a bad argument");
-
+
this->super_admin = false;
Log(this, "nick") << "(" << this->realname << ") changed nick to " << newnick;
@@ -152,10 +151,10 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
this->nick = newnick;
else
{
- NickAlias *old_na = NickAlias::Find(this->nick);
+ NickServ::Nick *old_na = NickServ::FindNick(this->nick);
if (old_na && (this->IsIdentified(true) || this->IsRecognized()))
- old_na->last_seen = Anope::CurTime;
-
+ old_na->SetLastSeen(Anope::CurTime);
+
UserListByNick.erase(this->nick);
this->nick = newnick;
@@ -170,18 +169,23 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
other = this;
on_access = false;
- NickAlias *na = NickAlias::Find(this->nick);
- if (na)
- on_access = na->nc->IsOnAccess(this);
-
- if (na && na->nc == this->Account())
+ if (NickServ::service)
{
- na->last_seen = Anope::CurTime;
- this->UpdateHost();
+ NickServ::Nick *na = NickServ::service->FindNick(this->nick);
+ if (na)
+ {
+ on_access = na->GetAccount()->IsOnAccess(this);
+
+ if (na->GetAccount() == this->Account())
+ {
+ na->SetLastSeen(Anope::CurTime);
+ this->UpdateHost();
+ }
+ }
}
}
- FOREACH_MOD(OnUserNickChange, (this, old));
+ EventManager::Get()->Dispatch(&Event::UserNickChange::OnUserNickChange, this, old);
}
void User::SetDisplayedHost(const Anope::string &shost)
@@ -193,7 +197,7 @@ void User::SetDisplayedHost(const Anope::string &shost)
Log(this, "host") << "changed vhost to " << shost;
- FOREACH_MOD(OnSetDisplayedHost, (this));
+ EventManager::Get()->Dispatch(&Event::SetDisplayedHost::OnSetDisplayedHost, this);
this->UpdateHost();
}
@@ -280,18 +284,18 @@ void User::SetRealname(const Anope::string &srealname)
throw CoreException("realname empty in SetRealname");
this->realname = srealname;
- NickAlias *na = NickAlias::Find(this->nick);
+
+ //XXX event
+ NickServ::Nick *na = NickServ::FindNick(this->nick);
if (na && (this->IsIdentified(true) || this->IsRecognized()))
- na->last_realname = srealname;
+ na->SetLastRealname(srealname);
Log(this, "realname") << "changed realname to " << srealname;
}
User::~User()
{
- UnsetExtensibles();
-
if (this->server != NULL)
{
if (this->server->IsSynced())
@@ -299,7 +303,7 @@ User::~User()
--this->server->users;
}
- FOREACH_MOD(OnPreUserLogoff, (this));
+ EventManager::Get()->Dispatch(&Event::PreUserLogoff::OnPreUserLogoff, this);
ModeManager::StackerDel(this);
this->Logout();
@@ -314,25 +318,10 @@ User::~User()
if (!this->uid.empty())
UserListByUID.erase(this->uid);
- FOREACH_MOD(OnPostUserLogoff, (this));
+ EventManager::Get()->Dispatch(&Event::PostUserLogoff::OnPostUserLogoff, this);
}
-void User::SendMessage(BotInfo *source, const char *fmt, ...)
-{
- va_list args;
- char buf[BUFSIZE] = "";
-
- const char *translated_message = Language::Translate(this, fmt);
-
- va_start(args, fmt);
- vsnprintf(buf, BUFSIZE - 1, translated_message, args);
-
- this->SendMessage(source, Anope::string(buf));
-
- va_end(args);
-}
-
-void User::SendMessage(BotInfo *source, const Anope::string &msg)
+void User::SendMessage(const MessageSource &source, const Anope::string &msg)
{
const char *translated_message = Language::Translate(this, msg.c_str());
@@ -341,54 +330,77 @@ void User::SendMessage(BotInfo *source, const Anope::string &msg)
* - The user is not registered and NSDefMsg is enabled
* - The user is registered and has set /ns set msg on
*/
- bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasExt("MSG")));
+ bool send_privmsg = Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasFieldS("MSG")));
sepstream sep(translated_message, '\n', true);
for (Anope::string tok; sep.GetToken(tok);)
{
- if (send_privmsg)
- IRCD->SendPrivmsg(source, this->GetUID(), "%s", tok.c_str());
- else
- IRCD->SendNotice(source, this->GetUID(), "%s", tok.c_str());
+ if (tok.empty())
+ tok = " ";
+ spacesepstream ssep(tok, true);
+ Anope::string buf;
+ for (Anope::string word; ssep.GetToken(word);)
+ {
+ Anope::string add = buf.empty() ? word : " " + word;
+ if (buf.length() + add.length() > Config->LineWrap)
+ {
+ if (send_privmsg)
+ IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str());
+ else
+ IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str());
+ buf.clear();
+ add = word;
+ }
+ buf.append(add);
+ }
+
+ if (!buf.empty())
+ {
+ if (send_privmsg)
+ IRCD->SendPrivmsg(source, this->GetUID(), "%s", buf.c_str());
+ else
+ IRCD->SendNotice(source, this->GetUID(), "%s", buf.c_str());
+ }
}
}
-void User::Identify(NickAlias *na)
+void User::Identify(NickServ::Nick *na)
{
- if (this->nick.equals_ci(na->nick))
+ if (this->nick.equals_ci(na->GetNick()))
{
- na->last_usermask = this->GetIdent() + "@" + this->GetDisplayedHost();
- na->last_realhost = this->GetIdent() + "@" + this->host;
- na->last_realname = this->realname;
- na->last_seen = Anope::CurTime;
+ na->SetLastUsermask(this->GetIdent() + "@" + this->GetDisplayedHost());
+ na->SetLastRealhost(this->GetIdent() + "@" + this->host);
+ na->SetLastRealname(this->realname);
+ na->SetLastSeen(Anope::CurTime);
}
IRCD->SendLogin(this, na);
- this->Login(na->nc);
+ this->Login(na->GetAccount());
- FOREACH_MOD(OnNickIdentify, (this));
+ EventManager::Get()->Dispatch(&Event::NickIdentify::OnNickIdentify, this);
if (this->IsServicesOper())
{
- if (!this->nc->o->ot->modes.empty())
+ Anope::string m = this->nc->o->GetType()->modes;
+ if (!m.empty())
{
- this->SetModes(NULL, "%s", this->nc->o->ot->modes.c_str());
- this->SendMessage(NULL, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str());
+ this->SetModes(NULL, "%s", m.c_str());
+ this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m.c_str());
UserMode *um = ModeManager::FindUserModeByName("OPER");
- if (um && !this->HasMode("OPER") && this->nc->o->ot->modes.find(um->mchar) != Anope::string::npos)
+ if (um && !this->HasMode("OPER") && m.find(um->mchar) != Anope::string::npos)
IRCD->SendOper(this);
}
- if (IRCD->CanSetVHost && !this->nc->o->vhost.empty())
+ if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty())
{
- this->SendMessage(NULL, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str());
- this->SetDisplayedHost(this->nc->o->vhost);
- IRCD->SendVhost(this, "", this->nc->o->vhost);
+ this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost());
+ this->SetDisplayedHost(this->nc->o->GetVhost());
+ IRCD->SendVhost(this, "", this->nc->o->GetVhost());
}
}
}
-void User::Login(NickCore *core)
+void User::Login(NickServ::Account *core)
{
if (!core || core == this->nc)
return;
@@ -400,26 +412,26 @@ void User::Login(NickCore *core)
this->UpdateHost();
if (this->server->IsSynced())
- Log(this, "account") << "is now identified as " << this->nc->display;
-
- FOREACH_MOD(OnUserLogin, (this));
+ Log(this, "account") << "is now identified as " << this->nc->GetDisplay();
+
+ EventManager::Get()->Dispatch(&Event::UserLogin::OnUserLogin, this);
}
void User::Logout()
{
if (!this->nc)
return;
-
- Log(this, "account") << "is no longer identified as " << this->nc->display;
- std::list<User *>::iterator it = std::find(this->nc->users.begin(), this->nc->users.end(), this);
+ Log(this, "account") << "is no longer identified as " << this->nc->GetDisplay();
+
+ auto it = std::find(this->nc->users.begin(), this->nc->users.end(), this);
if (it != this->nc->users.end())
this->nc->users.erase(it);
this->nc = NULL;
}
-NickCore *User::Account() const
+NickServ::Account *User::Account() const
{
return this->nc;
}
@@ -428,8 +440,8 @@ bool User::IsIdentified(bool check_nick) const
{
if (check_nick && this->nc)
{
- NickAlias *na = NickAlias::Find(this->nick);
- return na && *na->nc == *this->nc;
+ NickServ::Nick *na = NickServ::FindNick(nick);
+ return na && na->GetAccount() == *this->nc;
}
return this->nc ? true : false;
@@ -439,9 +451,9 @@ bool User::IsRecognized(bool check_secure) const
{
if (check_secure && on_access)
{
- const NickAlias *na = NickAlias::Find(this->nick);
+ NickServ::Nick *na = NickServ::FindNick(nick);
- if (!na || na->nc->HasExt("NS_SECURE"))
+ if (!na || na->GetAccount()->HasFieldS("NS_SECURE"))
return false;
}
@@ -453,24 +465,27 @@ bool User::IsServicesOper()
if (!this->nc || !this->nc->IsServicesOper())
// No opertype.
return false;
- else if (this->nc->o->require_oper && !this->HasMode("OPER"))
+ else if (this->nc->o->GetRequireOper() && !this->HasMode("OPER"))
return false;
- else if (!this->nc->o->certfp.empty() && this->fingerprint != this->nc->o->certfp)
+ else if (!this->nc->o->GetCertFP().empty() && this->fingerprint != this->nc->o->GetCertFP())
// Certfp mismatch
return false;
- else if (!this->nc->o->hosts.empty())
+ else if (!this->nc->o->GetHost().empty())
{
+ std::vector<Anope::string> hosts;
+ spacesepstream(this->nc->o->GetHost()).GetTokens(hosts);
+
bool match = false;
Anope::string match_host = this->GetIdent() + "@" + this->host;
- for (unsigned i = 0; i < this->nc->o->hosts.size(); ++i)
- if (Anope::Match(match_host, this->nc->o->hosts[i]))
+ for (Anope::string h : hosts)
+ if (Anope::Match(match_host, h))
match = true;
if (match == false)
return false;
}
EventReturn MOD_RESULT;
- FOREACH_RESULT(IsServicesOper, MOD_RESULT, (this));
+ MOD_RESULT = EventManager::Get()->Dispatch(&Event::IsServicesOperEvent::IsServicesOper, this);
if (MOD_RESULT == EVENT_STOP)
return false;
@@ -480,14 +495,14 @@ bool User::IsServicesOper()
bool User::HasCommand(const Anope::string &command)
{
if (this->IsServicesOper())
- return this->nc->o->ot->HasCommand(command);
+ return this->nc->o->GetType()->HasCommand(command);
return false;
}
bool User::HasPriv(const Anope::string &priv)
{
if (this->IsServicesOper())
- return this->nc->o->ot->HasPriv(priv);
+ return this->nc->o->GetType()->HasPriv(priv);
return false;
}
@@ -496,19 +511,20 @@ void User::UpdateHost()
if (this->host.empty())
return;
- NickAlias *na = NickAlias::Find(this->nick);
+ //XXX event
+ NickServ::Nick *na = NickServ::FindNick(this->nick);
on_access = false;
if (na)
- on_access = na->nc->IsOnAccess(this);
+ on_access = na->GetAccount()->IsOnAccess(this);
if (na && (this->IsIdentified(true) || this->IsRecognized()))
{
Anope::string last_usermask = this->GetIdent() + "@" + this->GetDisplayedHost();
Anope::string last_realhost = this->GetIdent() + "@" + this->host;
- na->last_usermask = last_usermask;
- na->last_realhost = last_realhost;
+ na->SetLastUsermask(last_usermask);
+ na->SetLastRealhost(last_realhost);
// This is called on signon, and if users are introduced with an account it won't update
- na->last_realname = this->realname;
+ na->SetLastRealname(this->realname);
}
}
@@ -530,19 +546,20 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop
if (this->IsServicesOper())
{
- if (!this->nc->o->ot->modes.empty())
+ Anope::string m = this->nc->o->GetType()->modes;
+ if (!m.empty())
{
- this->SetModes(NULL, "%s", this->nc->o->ot->modes.c_str());
- this->SendMessage(NULL, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str());
+ this->SetModes(NULL, "%s", m.c_str());
+ this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m);
UserMode *oper = ModeManager::FindUserModeByName("OPER");
- if (oper && !this->HasMode("OPER") && this->nc->o->ot->modes.find(oper->mchar) != Anope::string::npos)
+ if (oper && !this->HasMode("OPER") && m.find(oper->mchar) != Anope::string::npos)
IRCD->SendOper(this);
}
- if (IRCD->CanSetVHost && !this->nc->o->vhost.empty())
+ if (IRCD->CanSetVHost && !this->nc->o->GetVhost().empty())
{
- this->SendMessage(NULL, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str());
- this->SetDisplayedHost(this->nc->o->vhost);
- IRCD->SendVhost(this, "", this->nc->o->vhost);
+ this->SendMessage(Me, "Changing your vhost to \002{0}\002", this->nc->o->GetVhost());
+ this->SetDisplayedHost(this->nc->o->GetVhost());
+ IRCD->SendVhost(this, "", this->nc->o->GetVhost());
}
}
}
@@ -550,7 +567,7 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop
if (um->name == "CLOAK" || um->name == "VHOST")
this->UpdateHost();
- FOREACH_MOD(OnUserModeSet, (source, this, um->name));
+ EventManager::Get()->Dispatch(&Event::UserModeSet::OnUserModeSet, source, this, um->name);
}
void User::RemoveModeInternal(const MessageSource &source, UserMode *um)
@@ -569,10 +586,10 @@ void User::RemoveModeInternal(const MessageSource &source, UserMode *um)
this->UpdateHost();
}
- FOREACH_MOD(OnUserModeUnset, (source, this, um->name));
+ EventManager::Get()->Dispatch(&Event::UserModeUnset::OnUserModeUnset, source, this, um->name);
}
-void User::SetMode(BotInfo *bi, UserMode *um, const Anope::string &param)
+void User::SetMode(ServiceBot *bi, UserMode *um, const Anope::string &param)
{
if (!um || HasMode(um->name))
return;
@@ -581,12 +598,12 @@ void User::SetMode(BotInfo *bi, UserMode *um, const Anope::string &param)
SetModeInternal(bi, um, param);
}
-void User::SetMode(BotInfo *bi, const Anope::string &uname, const Anope::string &param)
+void User::SetMode(ServiceBot *bi, const Anope::string &uname, const Anope::string &param)
{
SetMode(bi, ModeManager::FindUserModeByName(uname), param);
}
-void User::RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param)
+void User::RemoveMode(ServiceBot *bi, UserMode *um, const Anope::string &param)
{
if (!um || !HasMode(um->name))
return;
@@ -595,12 +612,12 @@ void User::RemoveMode(BotInfo *bi, UserMode *um, const Anope::string &param)
RemoveModeInternal(bi, um);
}
-void User::RemoveMode(BotInfo *bi, const Anope::string &name, const Anope::string &param)
+void User::RemoveMode(ServiceBot *bi, const Anope::string &name, const Anope::string &param)
{
RemoveMode(bi, ModeManager::FindUserModeByName(name), param);
}
-void User::SetModes(BotInfo *bi, const char *umodes, ...)
+void User::SetModes(ServiceBot *bi, const char *umodes, ...)
{
char buf[BUFSIZE] = "";
va_list args;
@@ -756,7 +773,7 @@ void User::Quit(const Anope::string &reason)
return;
}
- FOREACH_MOD(OnUserQuit, (this, reason));
+ EventManager::Get()->Dispatch(&Event::UserQuit::OnUserQuit, this, reason);
this->quit = true;
quitting_users.push_back(this);
@@ -818,7 +835,7 @@ User* User::Find(const Anope::string &name, bool nick_only)
{
if (!nick_only && IRCD->RequiresID)
{
- user_map::iterator it = UserListByUID.find(name);
+ uid_map::iterator it = UserListByUID.find(name);
if (it != UserListByUID.end())
return it->second;