mirror of
https://github.com/anope/anope.git
synced 2026-07-07 08:33:12 +02:00
Don't delete users immediately when quit or killed, instead wait until message processing is done
This commit is contained in:
+3
-6
@@ -262,13 +262,10 @@ void RunCommand(CommandSource &source, const Anope::string &message)
|
||||
return;
|
||||
}
|
||||
|
||||
bool had_u = source.GetUser(), had_nc = source.nc;
|
||||
Reference<User> user_reference(source.GetUser());
|
||||
Reference<NickCore> nc_reference(source.nc);
|
||||
c->Execute(source, params);
|
||||
if (had_u == user_reference && had_nc == nc_reference)
|
||||
{
|
||||
FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params));
|
||||
}
|
||||
if (!nc_reference)
|
||||
source.nc = NULL;
|
||||
FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -351,7 +351,7 @@ void Quit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms)
|
||||
na->last_quit = reason;
|
||||
}
|
||||
FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, reason));
|
||||
delete user;
|
||||
user->Quit(reason);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ void NickAlias::Release()
|
||||
User *u = User::Find(this->nick);
|
||||
if (u && u->server == Me)
|
||||
{
|
||||
delete u;
|
||||
u->Quit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -137,7 +137,8 @@ Server::~Server()
|
||||
na->last_quit = this->quit_reason;
|
||||
}
|
||||
|
||||
delete u;
|
||||
u->Quit(this->quit_reason);
|
||||
u->server = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,34 +33,9 @@ bool BufferedSocket::ProcessRead()
|
||||
return false;
|
||||
|
||||
tbuffer[len] = 0;
|
||||
this->read_buffer.append(tbuffer);
|
||||
this->recv_len = len;
|
||||
|
||||
Anope::string sbuffer = this->extra_buf;
|
||||
sbuffer += tbuffer;
|
||||
this->extra_buf.clear();
|
||||
size_t lastnewline = sbuffer.rfind('\n');
|
||||
if (lastnewline == Anope::string::npos)
|
||||
{
|
||||
this->extra_buf = sbuffer;
|
||||
return true;
|
||||
}
|
||||
if (lastnewline < sbuffer.length() - 1)
|
||||
{
|
||||
this->extra_buf = sbuffer.substr(lastnewline);
|
||||
this->extra_buf.trim();
|
||||
sbuffer = sbuffer.substr(0, lastnewline);
|
||||
}
|
||||
|
||||
sepstream stream(sbuffer, '\n');
|
||||
|
||||
Anope::string tbuf;
|
||||
while (stream.GetToken(tbuf))
|
||||
{
|
||||
tbuf.trim();
|
||||
if (!Read(tbuf))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,9 +51,15 @@ bool BufferedSocket::ProcessWrite()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BufferedSocket::Read(const Anope::string &buf)
|
||||
const Anope::string BufferedSocket::GetLine()
|
||||
{
|
||||
return false;
|
||||
size_t s = this->read_buffer.find('\n');
|
||||
if (s == Anope::string::npos)
|
||||
return "";
|
||||
Anope::string str = this->read_buffer.substr(0, s + 1);
|
||||
this->read_buffer.erase(0, s + 1);
|
||||
this->read_buffer.ltrim();
|
||||
return str.trim();
|
||||
}
|
||||
|
||||
void BufferedSocket::Write(const char *buffer, size_t l)
|
||||
|
||||
+7
-2
@@ -116,9 +116,14 @@ UplinkSocket::~UplinkSocket()
|
||||
}
|
||||
}
|
||||
|
||||
bool UplinkSocket::Read(const Anope::string &buf)
|
||||
bool UplinkSocket::ProcessRead()
|
||||
{
|
||||
Anope::Process(buf);
|
||||
BufferedSocket::ProcessRead();
|
||||
for (Anope::string buf; (buf = this->GetLine()).empty() == false;)
|
||||
{
|
||||
Anope::Process(buf);
|
||||
User::QuitUsers();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+41
-9
@@ -30,12 +30,15 @@ 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 &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");
|
||||
|
||||
/* we used to do this by calloc, no more. */
|
||||
quit = false;
|
||||
server = NULL;
|
||||
invalid_pw_count = invalid_pw_time = lastmemosend = lastnickreg = lastmail = 0;
|
||||
on_access = false;
|
||||
@@ -79,8 +82,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
|
||||
bool exempt = false;
|
||||
if (server && server->IsULined())
|
||||
exempt = true;
|
||||
Reference<User> user = this;
|
||||
FOREACH_MOD(I_OnUserConnect, OnUserConnect(user, exempt));
|
||||
FOREACH_MOD(I_OnUserConnect, OnUserConnect(this, exempt));
|
||||
}
|
||||
|
||||
void User::ChangeNick(const Anope::string &newnick, time_t ts)
|
||||
@@ -229,10 +231,11 @@ void User::SetRealname(const Anope::string &srealname)
|
||||
|
||||
User::~User()
|
||||
{
|
||||
Log(LOG_DEBUG_2) << "User::~User() called";
|
||||
|
||||
Log(this, "disconnect") << "(" << this->realname << ") " << "disconnected from the network (" << this->server->GetName() << ")";
|
||||
--this->server->users;
|
||||
if (this->server != NULL)
|
||||
{
|
||||
Log(this, "disconnect") << "(" << this->realname << ") disconnected from the network (" << this->server->GetName() << ")";
|
||||
--this->server->users;
|
||||
}
|
||||
|
||||
FOREACH_MOD(I_OnUserLogoff, OnUserLogoff(this));
|
||||
|
||||
@@ -252,8 +255,6 @@ User::~User()
|
||||
NickAlias *na = NickAlias::Find(this->nick);
|
||||
if (na)
|
||||
na->OnCancel(this);
|
||||
|
||||
Log(LOG_DEBUG_2) << "User::~User() done";
|
||||
}
|
||||
|
||||
void User::SendMessage(const BotInfo *source, const char *fmt, ...)
|
||||
@@ -752,6 +753,12 @@ void User::Kill(const Anope::string &source, const Anope::string &reason)
|
||||
|
||||
void User::KillInternal(const Anope::string &source, const Anope::string &reason)
|
||||
{
|
||||
if (this->quit)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Duplicate quit for " << this->nick;
|
||||
return;
|
||||
}
|
||||
|
||||
Log(this, "killed") << "was killed by " << source << " (Reason: " << reason << ")";
|
||||
|
||||
NickAlias *na = NickAlias::Find(this->nick);
|
||||
@@ -761,7 +768,25 @@ void User::KillInternal(const Anope::string &source, const Anope::string &reason
|
||||
na->last_quit = reason;
|
||||
}
|
||||
|
||||
delete this;
|
||||
this->quit = true;
|
||||
quitting_users.push_back(this);
|
||||
}
|
||||
|
||||
void User::Quit(const Anope::string &reason)
|
||||
{
|
||||
if (this->quit)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Duplicate quit for " << this->nick;
|
||||
return;
|
||||
}
|
||||
|
||||
this->quit = true;
|
||||
quitting_users.push_back(this);
|
||||
}
|
||||
|
||||
bool User::Quitting() const
|
||||
{
|
||||
return this->quit;
|
||||
}
|
||||
|
||||
Anope::string User::Mask() const
|
||||
@@ -829,3 +854,10 @@ User* User::Find(const Anope::string &name, bool nick_only)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void User::QuitUsers()
|
||||
{
|
||||
for (std::list<User *>::iterator it = quitting_users.begin(), it_end = quitting_users.end(); it != it_end; ++it)
|
||||
delete *it;
|
||||
quitting_users.clear();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user