#include "inspircd.h"
#include "xline.h"
#include "bancache.h"
+#include "iohook.h"
UserManager::UserManager()
: clientlist(new user_hash)
UserIOHandler* eh = &New->eh;
/* Give each of the modules an attempt to hook the user for I/O */
- FOREACH_MOD(I_OnHookIO, OnHookIO(eh, via));
+ FOREACH_MOD(OnHookIO, (eh, via));
if (eh->GetIOHook())
{
}
catch (CoreException& modexcept)
{
- ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
+ ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "%s threw an exception: %s", modexcept.GetSource().c_str(), modexcept.GetReason().c_str());
}
}
* Check connect class settings and initialise settings into User.
* This will be done again after DNS resolution. -- w00t
*/
- New->CheckClass();
+ New->CheckClass(ServerInstance->Config->CCOnConnect);
if (New->quitting)
return;
{
/* user banned */
ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "BanCache: Positive hit for " + New->GetIPString());
- if (!ServerInstance->Config->MoronBanner.empty())
- New->WriteNotice("*** " + ServerInstance->Config->MoronBanner);
+ if (!ServerInstance->Config->XLineMessage.empty())
+ New->WriteNotice("*** " + ServerInstance->Config->XLineMessage);
this->QuitUser(New, b->Reason);
return;
}
if (ServerInstance->Config->RawLog)
New->WriteNotice("*** Raw I/O logging is enabled on this server. All messages, passwords, and commands are being recorded.");
- FOREACH_MOD(I_OnSetUserIP,OnSetUserIP(New));
+ FOREACH_MOD(OnSetUserIP, (New));
if (New->quitting)
return;
- FOREACH_MOD(I_OnUserInit,OnUserInit(New));
+ FOREACH_MOD(OnUserInit, (New));
}
void UserManager::QuitUser(User *user, const std::string &quitreason, const char* operreason)
if (user->registered == REG_ALL)
{
- FOREACH_MOD(I_OnUserQuit,OnUserQuit(user, reason, oper_reason));
+ FOREACH_MOD(OnUserQuit, (user, reason, oper_reason));
user->WriteCommonQuit(reason, oper_reason);
}
if (IS_LOCAL(user))
{
LocalUser* lu = IS_LOCAL(user);
- FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(lu));
+ FOREACH_MOD(OnUserDisconnect, (lu));
lu->eh.Close();
}
}
}
-/* return how many users have a given mode e.g. 'a' */
-int UserManager::ModeCount(const char mode)
-{
- int c = 0;
- for(user_hash::iterator i = clientlist->begin(); i != clientlist->end(); ++i)
- {
- User* u = i->second;
- if (u->modes[mode-65])
- c++;
- }
- return c;
-}
-
void UserManager::GarbageCollect()
{
// Reset the already_sent IDs so we don't wrap it around and drop a message
FIRST_MOD_RESULT(OnCheckReady, res, (user));
return (res == MOD_RES_PASSTHRU);
}
+
+/**
+ * This function is called once a second from the mainloop.
+ * It is intended to do background checking on all the user structs, e.g.
+ * stuff like ping checks, registration timeouts, etc.
+ */
+void UserManager::DoBackgroundUserStuff()
+{
+ /*
+ * loop over all local users..
+ */
+ for (LocalUserList::iterator i = local_users.begin(); i != local_users.end(); ++i)
+ {
+ LocalUser* curr = *i;
+
+ if (curr->quitting)
+ continue;
+
+ if (curr->CommandFloodPenalty || curr->eh.getSendQSize())
+ {
+ unsigned int rate = curr->MyClass->GetCommandRate();
+ if (curr->CommandFloodPenalty > rate)
+ curr->CommandFloodPenalty -= rate;
+ else
+ curr->CommandFloodPenalty = 0;
+ curr->eh.OnDataReady();
+ }
+
+ switch (curr->registered)
+ {
+ case REG_ALL:
+ if (ServerInstance->Time() > curr->nping)
+ {
+ // This user didn't answer the last ping, remove them
+ if (!curr->lastping)
+ {
+ time_t time = ServerInstance->Time() - (curr->nping - curr->MyClass->GetPingTime());
+ const std::string message = "Ping timeout: " + ConvToStr(time) + (time == 1 ? " seconds" : " second");
+ this->QuitUser(curr, message);
+ continue;
+ }
+
+ curr->Write("PING :" + ServerInstance->Config->ServerName);
+ curr->lastping = 0;
+ curr->nping = ServerInstance->Time() + curr->MyClass->GetPingTime();
+ }
+ break;
+ case REG_NICKUSER:
+ if (AllModulesReportReady(curr))
+ {
+ /* User has sent NICK/USER, modules are okay, DNS finished. */
+ curr->FullConnect();
+ continue;
+ }
+ break;
+ }
+
+ if (curr->registered != REG_ALL && (ServerInstance->Time() > (curr->age + curr->MyClass->GetRegTimeout())))
+ {
+ /*
+ * registration timeout -- didnt send USER/NICK/HOST
+ * in the time specified in their connection class.
+ */
+ this->QuitUser(curr, "Registration timeout");
+ continue;
+ }
+ }
+}