+
+ /* ensure we don't fuck things up refcount wise, only remove them from a class if we find a new one :P */
+ if (found)
+ {
+ /* deny change if change will take class over the limit */
+ if (found->limit && (found->RefCount + 1 >= found->limit))
+ {
+ ServerInstance->Logs->Log("USERS", DEBUG, "OOPS: Connect class limit (%lu) hit, denying", found->limit);
+ return this->MyClass;
+ }
+
+ /* should always be valid, but just in case .. */
+ if (this->MyClass)
+ {
+ if (found == this->MyClass) // no point changing this shit :P
+ return this->MyClass;
+ this->MyClass->RefCount--;
+ ServerInstance->Logs->Log("USERS", DEBUG, "Untying user from connect class -- refcount: %lu", this->MyClass->RefCount);
+ }
+
+ this->MyClass = found;
+ this->MyClass->RefCount++;
+ ServerInstance->Logs->Log("USERS", DEBUG, "User tied to new class -- connect refcount now: %lu", this->MyClass->RefCount);
+ }
+
+ return this->MyClass;
+}
+
+/* looks up a users password for their connection class (<ALLOW>/<DENY> tags)
+ * NOTE: If the <ALLOW> or <DENY> tag specifies an ip, and this user resolves,
+ * then their ip will be taken as 'priority' anyway, so for example,
+ * <connect allow="127.0.0.1"> will match joe!bloggs@localhost
+ */
+ConnectClass* User::GetClass()
+{
+ return this->MyClass;
+}
+
+void User::PurgeEmptyChannels()
+{
+ std::vector<Channel*> to_delete;
+
+ // firstly decrement the count on each channel
+ for (UCListIter f = this->chans.begin(); f != this->chans.end(); f++)
+ {
+ f->first->RemoveAllPrefixes(this);
+ if (f->first->DelUser(this) == 0)
+ {
+ /* No users left in here, mark it for deletion */
+ try
+ {
+ to_delete.push_back(f->first);
+ }
+ catch (...)
+ {
+ ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::PurgeEmptyChannels to_delete.push_back()");
+ }
+ }
+ }
+
+ for (std::vector<Channel*>::iterator n = to_delete.begin(); n != to_delete.end(); n++)
+ {
+ Channel* thischan = *n;
+ chan_hash::iterator i2 = ServerInstance->chanlist->find(thischan->name);
+ if (i2 != ServerInstance->chanlist->end())
+ {
+ FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
+ delete i2->second;
+ ServerInstance->chanlist->erase(i2);
+ this->chans.erase(*n);
+ }
+ }
+
+ this->UnOper();
+}
+
+void User::ShowMOTD()
+{
+ if (!ServerInstance->Config->MOTD.size())
+ {
+ this->WriteNumeric(422, "%s :Message of the day file is missing.",this->nick);
+ return;
+ }
+ this->WriteNumeric(375, "%s :%s message of the day", this->nick, ServerInstance->Config->ServerName);
+
+ for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++)
+ this->WriteNumeric(372, "%s :- %s",this->nick,i->c_str());
+
+ this->WriteNumeric(376, "%s :End of message of the day.", this->nick);
+}
+
+void User::ShowRULES()
+{
+ if (!ServerInstance->Config->RULES.size())
+ {
+ this->WriteNumeric(434, "%s :RULES File is missing",this->nick);
+ return;
+ }
+
+ this->WriteNumeric(308, "%s :- %s Server Rules -",this->nick,ServerInstance->Config->ServerName);
+
+ for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++)
+ this->WriteNumeric(232, "%s :- %s",this->nick,i->c_str());
+
+ this->WriteNumeric(309, "%s :End of RULES command.",this->nick);
+}
+
+void User::HandleEvent(EventType et, int errornum)
+{
+ if (this->quitting) // drop everything, user is due to be quit
+ return;
+
+ /* WARNING: May delete this user! */
+ int thisfd = this->GetFd();
+
+ try
+ {
+ switch (et)
+ {
+ case EVENT_READ:
+ ServerInstance->ProcessUser(this);
+ break;
+ case EVENT_WRITE:
+ this->FlushWriteBuf();
+ break;
+ case EVENT_ERROR:
+ /** This should be safe, but dont DARE do anything after it -- Brain */
+ this->SetWriteError(errornum ? strerror(errornum) : "EOF from client");
+ break;
+ }
+ }
+ catch (...)
+ {
+ ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::HandleEvent intercepted");
+ }
+
+ /* If the user has raised an error whilst being processed, quit them now we're safe to */
+ if ((ServerInstance->SE->GetRef(thisfd) == this))
+ {
+ if (!WriteError.empty())
+ {
+ User::QuitUser(ServerInstance, this, GetWriteError());
+ }
+ }
+}
+
+void User::SetOperQuit(const std::string &oquit)
+{
+ operquitmsg = oquit;
+}
+
+const char* User::GetOperQuit()
+{
+ return operquitmsg.c_str();
+}
+
+void User::IncreasePenalty(int increase)
+{
+ this->Penalty += increase;
+}
+
+void User::DecreasePenalty(int decrease)
+{
+ this->Penalty -= decrease;
+}
+
+VisData::VisData()
+{
+}
+
+VisData::~VisData()
+{
+}
+
+bool VisData::VisibleTo(User* user)
+{
+ return true;