bool User::IsModeSet(unsigned char m)
{
- if (!isalpha(m))
- return false;
- return (modes[m-65]);
+ ModeHandler* mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER);
+ return (mh && modes[mh->GetId()]);
}
const char* User::FormatModes(bool showparameters)
for (unsigned char n = 0; n < 64; n++)
{
- if (modes[n])
+ ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER);
+ if (mh && IsModeSet(mh))
{
data.push_back(n + 65);
- ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER);
- if (showparameters && mh && mh->GetNumParams(true))
+ if (showparameters && mh->GetNumParams(true))
{
std::string p = mh->GetUserParameter(this);
if (p.length())
ServerInstance->Logs->Log("USERS", LOG_DEBUG, "New UUID for user: %s", uuid.c_str());
- if (!ServerInstance->Users->uuidlist->insert(std::make_pair(uuid, this)).second)
+ if (!ServerInstance->Users->uuidlist.insert(std::make_pair(uuid, this)).second)
throw CoreException("Duplicate UUID "+std::string(uuid)+" in User constructor");
}
User::~User()
{
- if (ServerInstance->Users->uuidlist->find(uuid) != ServerInstance->Users->uuidlist->end())
+ if (ServerInstance->FindUUID(uuid))
ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "User destructor for %s called without cull", uuid.c_str());
}
Invitation* inv = Invitation::Find(chan, this);
if (inv)
{
- inv->cull();
delete inv;
return true;
}
{
if (!quitting)
ServerInstance->Users->QuitUser(this, "Culled without QuitUser");
- PurgeEmptyChannels();
if (client_sa.sa.sa_family != AF_UNSPEC)
ServerInstance->Users->RemoveCloneCounts(this);
// Fake users don't quit, they just get culled.
quitting = true;
// Fake users are not inserted into UserManager::clientlist, they're only in the uuidlist
- ServerInstance->Users->uuidlist->erase(uuid);
+ ServerInstance->Users->uuidlist.erase(uuid);
return User::cull();
}
this->SetMode(opermh, true);
this->oper = info;
- this->WriteServ("MODE %s :+o", this->nick.c_str());
+ this->WriteCommand("MODE", "+o");
FOREACH_MOD(OnOper, (this, info->name));
std::string opername;
cached_fullrealhost.clear();
}
-bool User::ChangeNick(const std::string& newnick, bool force)
+bool User::ChangeNick(const std::string& newnick, bool force, time_t newts)
{
if (quitting)
{
{
// case change, don't need to check Q:lines and such
// and, if it's identical including case, we can leave right now
+ // We also don't update the nick TS if it's a case change, either
if (newnick == nick)
return true;
}
InUse->WriteTo(InUse, "NICK %s", InUse->uuid.c_str());
InUse->WriteNumeric(ERR_NICKNAMEINUSE, "%s :Nickname overruled.", InUse->nick.c_str());
- ServerInstance->Users->clientlist->erase(InUse->nick);
- (*(ServerInstance->Users->clientlist))[InUse->uuid] = InUse;
+ ServerInstance->Users->clientlist.erase(InUse->nick);
+ ServerInstance->Users->clientlist[InUse->uuid] = InUse;
InUse->nick = InUse->uuid;
InUse->InvalidateCache();
return false;
}
}
+
+ age = newts ? newts : ServerInstance->Time();
}
if (this->registered == REG_ALL)
nick = newnick;
InvalidateCache();
- ServerInstance->Users->clientlist->erase(oldnick);
- (*(ServerInstance->Users->clientlist))[newnick] = this;
+ ServerInstance->Users->clientlist.erase(oldnick);
+ ServerInstance->Users->clientlist[newnick] = this;
if (registered == REG_ALL)
FOREACH_MOD(OnUserPostNick, (this,oldnick));
void LocalUser::Write(const std::string& text)
{
- if (!ServerInstance->SE->BoundsCheckFd(&eh))
+ if (!SocketEngine::BoundsCheckFd(&eh))
return;
if (text.length() > ServerInstance->Config->Limits.MaxLine - 2)
this->WriteServ(textbuffer);
}
-void User::WriteNotice(const std::string& text)
+void User::WriteCommand(const char* command, const std::string& text)
{
- this->WriteServ("NOTICE " + (this->registered == REG_ALL ? this->nick : "*") + " :" + text);
+ this->WriteServ(command + (this->registered & REG_NICK ? " " + this->nick : " *") + " " + text);
}
void User::WriteNumeric(unsigned int numeric, const char* text, ...)
return;
const std::string message = InspIRCd::Format(":%s %03u %s %s", ServerInstance->Config->ServerName.c_str(),
- numeric, !this->nick.empty() ? this->nick.c_str() : "*", text.c_str());
+ numeric, this->registered & REG_NICK ? this->nick.c_str() : "*", text.c_str());
this->Write(message);
}
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
{
LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting && u->already_sent != LocalUser::already_sent_id)
+ if (u && u->already_sent != LocalUser::already_sent_id)
{
u->already_sent = LocalUser::already_sent_id;
u->Write(line);
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
{
LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting && (u->already_sent != uniq_id))
+ if (u && (u->already_sent != uniq_id))
{
u->already_sent = uniq_id;
u->Write(u->IsOper() ? operMessage : normalMessage);
*/
bool User::SharesChannelWith(User *other)
{
- if ((this->registered != REG_ALL) || (other->registered != REG_ALL))
- return false;
-
/* Outer loop */
for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++)
{
FOREACH_MOD(OnChangeHost, (this,shost));
- this->dhost.assign(shost, 0, 64);
+ this->dhost.assign(shost, 0, ServerInstance->Config->Limits.MaxHost);
this->InvalidateCache();
if (IS_LOCAL(this))
if (regdone && !c->config->getString("password").empty())
{
- if (ServerInstance->PassCompare(this, c->config->getString("password"), password, c->config->getString("hash")))
+ if (!ServerInstance->PassCompare(this, c->config->getString("password"), password, c->config->getString("hash")))
{
ServerInstance->Logs->Log("CONNECTCLASS", LOG_DEBUG, "Bad password, skipping");
continue;