diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/coremods/core_info/core_info.cpp | 100 | ||||
-rw-r--r-- | src/mode.cpp | 25 | ||||
-rw-r--r-- | src/users.cpp | 36 |
3 files changed, 102 insertions, 59 deletions
diff --git a/src/coremods/core_info/core_info.cpp b/src/coremods/core_info/core_info.cpp index f1a17d089..2d7a89475 100644 --- a/src/coremods/core_info/core_info.cpp +++ b/src/coremods/core_info/core_info.cpp @@ -20,6 +20,15 @@ #include "inspircd.h" #include "core_info.h" +enum +{ + // From RFC 2812. + RPL_WELCOME = 1, + RPL_YOURHOST = 2, + RPL_CREATED = 3, + RPL_MYINFO = 4 +}; + RouteDescriptor ServerTargetCommand::GetRouting(User* user, const Params& parameters) { // Parameter must be a server name, not a nickname or uuid @@ -37,11 +46,55 @@ class CoreModInfo : public Module CommandMotd cmdmotd; CommandTime cmdtime; CommandVersion cmdversion; + Numeric::Numeric numeric004; + /** Returns a list of user or channel mode characters. + * Used for constructing the parts of the mode list in the 004 numeric. + * @param mt Controls whether to list user modes or channel modes + * @param needparam Return modes only if they require a parameter to be set + * @return The available mode letters that satisfy the given conditions + */ + static std::string CreateModeList(ModeType mt, bool needparam = false) + { + std::string modestr; + for (unsigned char mode = 'A'; mode <= 'z'; mode++) + { + ModeHandler* mh = ServerInstance->Modes.FindMode(mode, mt); + if ((mh) && ((!needparam) || (mh->NeedsParam(true)))) + modestr.push_back(mode); + } + return modestr; + } + + void OnServiceChange(const ServiceProvider& prov) + { + if (prov.service != SERVICE_MODE) + return; + + std::vector<std::string>& params = numeric004.GetParams(); + params.erase(params.begin()+2, params.end()); + + // Create lists of modes + // 1. User modes + // 2. Channel modes + // 3. Channel modes that require a parameter when set + numeric004.push(CreateModeList(MODETYPE_USER)); + numeric004.push(CreateModeList(MODETYPE_CHANNEL)); + numeric004.push(CreateModeList(MODETYPE_CHANNEL, true)); + } public: CoreModInfo() - : cmdadmin(this), cmdcommands(this), cmdinfo(this), cmdmodules(this), cmdmotd(this), cmdtime(this), cmdversion(this) + : cmdadmin(this) + , cmdcommands(this) + , cmdinfo(this) + , cmdmodules(this) + , cmdmotd(this) + , cmdtime(this) + , cmdversion(this) + , numeric004(RPL_MYINFO) { + numeric004.push(ServerInstance->Config->ServerName); + numeric004.push(INSPIRCD_BRANCH); } void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE @@ -52,6 +105,51 @@ class CoreModInfo : public Module cmdadmin.AdminNick = tag->getString("nick", "admin"); } + void OnUserConnect(LocalUser* user) CXX11_OVERRIDE + { + user->WriteNumeric(RPL_WELCOME, InspIRCd::Format("Welcome to the %s IRC Network %s", ServerInstance->Config->Network.c_str(), user->GetFullRealHost().c_str())); + user->WriteNumeric(RPL_YOURHOST, InspIRCd::Format("Your host is %s, running version %s", ServerInstance->Config->ServerName.c_str(), INSPIRCD_BRANCH)); + user->WriteNumeric(RPL_CREATED, InspIRCd::TimeString(ServerInstance->startup_time, "This server was created %H:%M:%S %b %d %Y")); + user->WriteNumeric(numeric004); + + ServerInstance->ISupport.SendTo(user); + + /* Trigger MOTD and LUSERS output, give modules a chance too */ + ModResult MOD_RESULT; + std::string command("LUSERS"); + CommandBase::Params parameters; + FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, user, true)); + if (!MOD_RESULT) + ServerInstance->Parser.CallHandler(command, parameters, user); + + MOD_RESULT = MOD_RES_PASSTHRU; + command = "MOTD"; + FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, user, true)); + if (!MOD_RESULT) + ServerInstance->Parser.CallHandler(command, parameters, user); + + if (ServerInstance->Config->RawLog) + { + ClientProtocol::Messages::Privmsg rawlogmsg(ServerInstance->FakeClient, user, "*** Raw I/O logging is enabled on user server. All messages, passwords, and commands are being recorded."); + user->Send(ServerInstance->GetRFCEvents().privmsg, rawlogmsg); + } + } + + void OnServiceAdd(ServiceProvider& service) CXX11_OVERRIDE + { + OnServiceChange(service); + } + + void OnServiceDel(ServiceProvider& service) CXX11_OVERRIDE + { + OnServiceChange(service); + } + + void Prioritize() CXX11_OVERRIDE + { + ServerInstance->Modules.SetPriority(this, I_OnUserConnect, PRIORITY_FIRST); + } + Version GetVersion() CXX11_OVERRIDE { return Version("Provides the ADMIN, COMMANDS, INFO, MODULES, MOTD, TIME and VERSION commands", VF_VENDOR|VF_CORE); diff --git a/src/mode.cpp b/src/mode.cpp index 71fce24d8..0bb97cc9e 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -630,8 +630,6 @@ void ModeParser::AddMode(ModeHandler* mh) mhlist.prefix.push_back(pm); else if (mh->IsListModeBase()) mhlist.list.push_back(mh->IsListModeBase()); - - RecreateModeListFor004Numeric(); } bool ModeParser::DelMode(ModeHandler* mh) @@ -689,8 +687,6 @@ bool ModeParser::DelMode(ModeHandler* mh) mhlist.prefix.erase(std::find(mhlist.prefix.begin(), mhlist.prefix.end(), mh->IsPrefixMode())); else if (mh->IsListModeBase()) mhlist.list.erase(std::find(mhlist.list.begin(), mhlist.list.end(), mh->IsListModeBase())); - - RecreateModeListFor004Numeric(); return true; } @@ -720,27 +716,6 @@ PrefixMode* ModeParser::FindPrefixMode(unsigned char modeletter) return mh->IsPrefixMode(); } -std::string ModeParser::CreateModeList(ModeType mt, bool needparam) -{ - std::string modestr; - - for (unsigned char mode = 'A'; mode <= 'z'; mode++) - { - ModeHandler* mh = modehandlers[mt][mode-65]; - if ((mh) && ((!needparam) || (mh->NeedsParam(true)))) - modestr.push_back(mode); - } - - return modestr; -} - -void ModeParser::RecreateModeListFor004Numeric() -{ - Cached004ModeList[0] = CreateModeList(MODETYPE_USER); - Cached004ModeList[1] = CreateModeList(MODETYPE_CHANNEL); - Cached004ModeList[2] = CreateModeList(MODETYPE_CHANNEL, true); -} - PrefixMode* ModeParser::FindPrefix(unsigned const char pfxletter) { const PrefixModeList& list = GetPrefixModes(); diff --git a/src/users.cpp b/src/users.cpp index e17c8cd79..1ddd3ca0e 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -557,45 +557,15 @@ void LocalUser::FullConnect() if (quitting) return; - this->WriteNumeric(RPL_WELCOME, InspIRCd::Format("Welcome to the %s IRC Network %s", ServerInstance->Config->Network.c_str(), GetFullRealHost().c_str())); - this->WriteNumeric(RPL_YOURHOSTIS, InspIRCd::Format("Your host is %s, running version %s", ServerInstance->Config->ServerName.c_str(), INSPIRCD_BRANCH)); - this->WriteNumeric(RPL_SERVERCREATED, InspIRCd::TimeString(ServerInstance->startup_time, "This server was created %H:%M:%S %b %d %Y")); - - const TR1NS::array<std::string, 3>& modelist = ServerInstance->Modes->GetModeListFor004Numeric(); - this->WriteNumeric(RPL_SERVERVERSION, ServerInstance->Config->ServerName, INSPIRCD_BRANCH, modelist[0], modelist[1], modelist[2]); - - ServerInstance->ISupport.SendTo(this); - - /* Now registered */ - if (ServerInstance->Users->unregistered_count) - ServerInstance->Users->unregistered_count--; - - /* Trigger MOTD and LUSERS output, give modules a chance too */ - ModResult MOD_RESULT; - std::string command("LUSERS"); - CommandBase::Params parameters; - FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true)); - if (!MOD_RESULT) - ServerInstance->Parser.CallHandler(command, parameters, this); - - MOD_RESULT = MOD_RES_PASSTHRU; - command = "MOTD"; - FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true)); - if (!MOD_RESULT) - ServerInstance->Parser.CallHandler(command, parameters, this); - - if (ServerInstance->Config->RawLog) - { - ClientProtocol::Messages::Privmsg rawlogmsg(ServerInstance->FakeClient, this, "*** Raw I/O logging is enabled on this server. All messages, passwords, and commands are being recorded."); - this->Send(ServerInstance->GetRFCEvents().privmsg, rawlogmsg); - } - /* * We don't set REG_ALL until triggering OnUserConnect, so some module events don't spew out stuff * for a user that doesn't exist yet. */ FOREACH_MOD(OnUserConnect, (this)); + /* Now registered */ + if (ServerInstance->Users->unregistered_count) + ServerInstance->Users->unregistered_count--; this->registered = REG_ALL; FOREACH_MOD(OnPostConnect, (this)); |