summaryrefslogtreecommitdiff
path: root/src/users.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/users.cpp')
-rw-r--r--src/users.cpp224
1 files changed, 81 insertions, 143 deletions
diff --git a/src/users.cpp b/src/users.cpp
index 338dc343f..a992d8d04 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -32,13 +32,11 @@ time_t maxusertime;
/*************************************************************************/
/*************************************************************************/
-User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid) : modes(UserModeNameStrings)
+User::User(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 ssignon, const Anope::string &smodes, const Anope::string &suid)
{
if (snick.empty() || sident.empty() || shost.empty())
throw CoreException("Bad args passed to User::User");
- // XXX: we should also duplicate-check here.
-
/* we used to do this by calloc, no more. */
server = NULL;
invalid_pw_count = invalid_pw_time = lastmemosend = lastnickreg = lastmail = 0;
@@ -48,41 +46,86 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->nick = snick;
this->ident = sident;
this->host = shost;
+ this->vhost = svhost;
+ if (!svhost.empty())
+ this->SetCloakedHost(svhost);
+ this->ip = sip;
+ this->server = sserver;
+ this->realname = srealname;
+ this->timestamp = ssignon;
+ this->SetModesInternal("%s", smodes.c_str());
this->uid = suid;
this->SuperAdmin = false;
+ size_t old = UserListByNick.size();
UserListByNick[snick] = this;
if (!suid.empty())
UserListByUID[suid] = this;
+ if (old == UserListByNick.size())
+ Log(LOG_DEBUG) << "Duplicate user " << snick << " in user table?";
this->nc = NULL;
- ++usercnt;
+ if (sserver) // Our bots are introduced on startup with no server
+ Log(this, "connect") << (!svhost.empty() ? Anope::string("(") + svhost + ") " : "") << "(" << srealname << ") " << sip << " connected to the network (" << sserver->GetName() << ")";
+ ++usercnt;
if (usercnt > maxusercnt)
{
maxusercnt = usercnt;
maxusertime = Anope::CurTime;
Log(this, "maxusers") << "connected - new maximum user count: " << maxusercnt;
}
+
+ bool exempt = false;
+ if (server && server->IsULined())
+ exempt = true;
+ dynamic_reference<User> user = this;
+ FOREACH_MOD(I_OnUserConnect, OnUserConnect(user, exempt));
}
-void User::SetNewNick(const Anope::string &newnick)
+void User::ChangeNick(const Anope::string &newnick)
{
/* Sanity check to make sure we don't segfault */
if (newnick.empty())
- throw CoreException("User::SetNewNick() got a bad argument");
-
- UserListByNick.erase(this->nick);
+ throw CoreException("User::ChangeNick() got a bad argument");
+
+ this->SuperAdmin = false;
+ Log(this, "nick") << "(" << this->realname << ") changed nick to " << newnick;
- this->nick = newnick;
+ Anope::string old = this->nick;
- UserListByNick[this->nick] = this;
+ if (this->nick.equals_ci(newnick))
+ this->nick = newnick;
+ else
+ {
+ /* Update this only if nicks aren't the same */
+ this->my_signon = Anope::CurTime;
+
+ NickAlias *old_na = findnick(this->nick);
+ if (old_na && (this->IsIdentified(true) || this->IsRecognized()))
+ old_na->last_seen = Anope::CurTime;
+
+ UserListByNick.erase(this->nick);
+ this->nick = newnick;
+ UserListByNick[this->nick] = this;
+
+ OnAccess = false;
+ NickAlias *na = findnick(this->nick);
+ if (na)
+ OnAccess = is_on_access(this, na->nc);
+
+ if (old_na)
+ old_na->OnCancel(this);
+
+ if (na && na->nc == this->Account())
+ {
+ na->last_seen = Anope::CurTime;
+ this->UpdateHost();
+ }
+ }
- OnAccess = false;
- const NickAlias *na = findnick(this->nick);
- if (na)
- OnAccess = is_on_access(this, na->nc);
+ FOREACH_MOD(I_OnUserNickChange, OnUserNickChange(this, old));
}
void User::SetDisplayedHost(const Anope::string &shost)
@@ -102,7 +145,7 @@ void User::SetDisplayedHost(const Anope::string &shost)
*/
const Anope::string &User::GetDisplayedHost() const
{
- if (ircd->vhost && !this->vhost.empty())
+ if (!this->vhost.empty())
return this->vhost;
else if (this->HasMode(UMODE_CLOAK) && !this->GetCloakedHost().empty())
return this->GetCloakedHost();
@@ -135,7 +178,10 @@ const Anope::string &User::GetCloakedHost() const
const Anope::string &User::GetUID() const
{
- return this->uid;
+ if (!this->uid.empty())
+ return this->uid;
+ else
+ return this->nick;
}
void User::SetVIdent(const Anope::string &sident)
@@ -149,7 +195,7 @@ void User::SetVIdent(const Anope::string &sident)
const Anope::string &User::GetVIdent() const
{
- if (this->HasMode(UMODE_CLOAK) || (ircd->vident && !this->vident.empty()))
+ if (!this->vident.empty())
return this->vident;
else
return this->ident;
@@ -323,7 +369,7 @@ void User::Collide(NickAlias *na)
if (na)
na->SetFlag(NS_COLLIDED);
- if (ircd->svsnick)
+ if (ircdproto->CanSVSNick)
{
Anope::string guestnick;
@@ -386,7 +432,7 @@ void User::Identify(NickAlias *na)
if (bi != NULL)
this->SendMessage(bi, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str());
}
- if (ircd->vhost && !this->nc->o->vhost.empty())
+ if (ircdproto->CanSetVHost && !this->nc->o->vhost.empty())
{
if (bi != NULL)
this->SendMessage(bi, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str());
@@ -687,6 +733,8 @@ void User::SetModesInternal(const char *umodes, ...)
vsnprintf(buf, BUFSIZE - 1, umodes, args);
va_end(args);
+ Log(this, "mode") << "changes modes to " << buf;
+
spacesepstream sep(buf);
sep.GetToken(modebuf);
for (unsigned i = 0, end = modebuf.length(); i < end; ++i)
@@ -785,14 +833,25 @@ void User::Kill(const Anope::string &source, const Anope::string &reason)
Anope::string real_reason = real_source + " (" + reason + ")";
ircdproto->SendSVSKill(findbot(source), this, "%s", real_reason.c_str());
+}
+
+void User::KillInternal(const Anope::string &source, const Anope::string &reason)
+{
+ Log(this, "killed") << "was killed by " << source << " (Reason: " << reason << ")";
+
+ NickAlias *na = findnick(this->nick);
+ if (na && !na->nc->HasFlag(NI_SUSPENDED) && (this->IsRecognized() || this->IsIdentified(true)))
+ {
+ na->last_seen = Anope::CurTime;
+ na->last_quit = reason;
+ }
- if (!ircd->quitonkill)
- do_kill(this, real_reason);
+ delete this;
}
User *finduser(const Anope::string &nick)
{
- if (isdigit(nick[0]) && ircd->ts6)
+ if (isdigit(nick[0]) && ircdproto->RequiresID)
{
Anope::map<User *>::iterator it = UserListByUID.find(nick);
if (it != UserListByUID.end())
@@ -808,127 +867,6 @@ User *finduser(const Anope::string &nick)
return NULL;
}
-/*************************************************************************/
-
-/* Handle a server NICK command. */
-
-User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, const Anope::string &ip, const Anope::string &vhost, const Anope::string &uid, const Anope::string &modes)
-{
- if (source.empty())
- {
- Server *serv = Server::Find(server);
- if (serv == NULL)
- {
- Log() << "User " << nick << " introduced with nonexistant server " << server << "!";
- return NULL;
- }
-
- /* Allocate User structure and fill it in. */
- dynamic_reference<User> user = new User(nick, username, host, uid);
- user->ip = ip;
- user->server = serv;
- user->realname = realname;
- user->timestamp = ts;
- if (!vhost.empty())
- user->SetCloakedHost(vhost);
- user->SetVIdent(username);
- user->SetModesInternal(modes.c_str());
-
- Log(user, "connect") << (!vhost.empty() ? Anope::string("(") + vhost + ") " : "") << "(" << user->realname << ") " << user->ip << " connected to the network (" << serv->GetName() << ")";
-
- bool exempt = false;
- if (user->server && user->server->IsULined())
- exempt = true;
- FOREACH_MOD(I_OnUserConnect, OnUserConnect(user, exempt));
-
- return user;
- }
- else
- {
- /* An old user changing nicks. */
- User *user = finduser(source);
-
- if (!user)
- {
- Log() << "user: NICK from nonexistent nick " << source;
- return NULL;
- }
- user->SuperAdmin = false;
-
- Log(user, "nick") << "(" << user->realname << ") changed nick to " << nick;
-
- user->timestamp = ts;
-
- if (user->nick.equals_ci(nick))
- /* No need to redo things */
- user->SetNewNick(nick);
- else
- {
- /* Update this only if nicks aren't the same */
- user->my_signon = Anope::CurTime;
-
- NickAlias *old_na = findnick(user->nick);
- if (old_na && (old_na->nc == user->Account() || user->IsRecognized()))
- old_na->last_seen = Anope::CurTime;
-
- Anope::string oldnick = user->nick;
- user->SetNewNick(nick);
- FOREACH_MOD(I_OnUserNickChange, OnUserNickChange(user, oldnick));
-
- if (old_na)
- old_na->OnCancel(user);
-
- NickAlias *na = findnick(user->nick);
- if (na && na->nc == user->Account())
- {
- na->last_seen = Anope::CurTime;
- user->UpdateHost();
- }
- }
-
- return user;
- }
-}
-
-/*************************************************************************/
-
-void do_umode(const Anope::string &user, const Anope::string &modes)
-{
- User *u = finduser(user);
- if (!u)
- {
- Log() << "user: MODE "<< modes << " for nonexistent nick "<< user;
- return;
- }
-
- Log(u, "mode") << "changes modes to " << modes;
-
- u->SetModesInternal(modes.c_str());
-}
-
-/*************************************************************************/
-
-
-/* Handle a KILL command.
- * @param user the user being killed
- * @param msg why
- */
-void do_kill(User *user, const Anope::string &msg)
-{
- Log(user, "killed") << "was killed (Reason: " << msg << ")";
-
- NickAlias *na = findnick(user->nick);
- if (na && !na->nc->HasFlag(NI_SUSPENDED) && (user->IsRecognized() || user->IsIdentified(true)))
- {
- na->last_seen = Anope::CurTime;
- na->last_quit = msg;
- }
- delete user;
-}
-
-/*************************************************************************/
-/*************************************************************************/
-
bool matches_list(Channel *c, User *user, ChannelModeName mode)
{
if (!c || !c->HasMode(mode))