diff options
| author | Adam <Adam@anope.org> | 2012-10-01 01:56:57 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2012-10-01 01:56:57 -0400 |
| commit | 89428a9d1032e3c2a6e397629a32862b3e58d708 (patch) | |
| tree | d507904b3fa1cc084f0f3e688c839bcdd47f79d7 /src | |
| parent | b937d6310d9a7c0e2434200306b63d513cb2ae61 (diff) | |
Cleanup of all of the protocol modules, rewrote message handling system to be a bit more C++ ish
Diffstat (limited to 'src')
| -rw-r--r-- | src/bots.cpp | 7 | ||||
| -rw-r--r-- | src/botserv.cpp | 2 | ||||
| -rw-r--r-- | src/channels.cpp | 249 | ||||
| -rw-r--r-- | src/init.cpp | 2 | ||||
| -rw-r--r-- | src/main.cpp | 10 | ||||
| -rw-r--r-- | src/messages.cpp | 393 | ||||
| -rw-r--r-- | src/modes.cpp | 4 | ||||
| -rw-r--r-- | src/modules.cpp | 52 | ||||
| -rw-r--r-- | src/nickalias.cpp | 9 | ||||
| -rw-r--r-- | src/nickserv.cpp | 11 | ||||
| -rw-r--r-- | src/process.cpp | 28 | ||||
| -rw-r--r-- | src/protocol.cpp | 297 | ||||
| -rw-r--r-- | src/servers.cpp | 57 | ||||
| -rw-r--r-- | src/users.cpp | 224 |
14 files changed, 537 insertions, 808 deletions
diff --git a/src/bots.cpp b/src/bots.cpp index 53f9b78c1..ffe814351 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -21,11 +21,8 @@ serialize_checker<botinfo_map> BotListByNick("BotInfo"); serialize_checker<botinfouid_map> BotListByUID("BotInfo"); -BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, ts6_uid_retrieve()), Flags<BotFlag, BI_END>(BotFlagString), botmodes(bmodes) +BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", ts6_uid_retrieve()), Flags<BotFlag, BI_END>(BotFlagString), botmodes(bmodes) { - this->realname = nreal; - this->server = Me; - this->lastmsg = this->created = Anope::CurTime; this->introduced = false; @@ -36,7 +33,7 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A // If we're synchronised with the uplink already, send the bot. if (Me && Me->IsSynced()) { - Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : (ircd ? ircd->pseudoclient_mode : ""); + Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : (ircdproto ? ircdproto->DefaultPseudoclientModes : ""); if (!tmodes.empty()) this->SetModesInternal(tmodes.c_str()); diff --git a/src/botserv.cpp b/src/botserv.cpp index 5718be81a..27666f7ec 100644 --- a/src/botserv.cpp +++ b/src/botserv.cpp @@ -25,7 +25,7 @@ BotInfo* findbot(const Anope::string &nick) { BotInfo *bi = NULL; - if (isdigit(nick[0]) && ircd->ts6) + if (isdigit(nick[0]) && ircdproto->RequiresID) { botinfouid_map::iterator it = BotListByUID->find(nick); if (it != BotListByUID->end()) diff --git a/src/channels.cpp b/src/channels.cpp index e89b6010d..1790ddda1 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -337,7 +337,7 @@ std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> Channel::Get * @param param The param * @param EnforeMLock true if mlocks should be enforced, false to override mlock */ -void Channel::SetModeInternal(User *setter, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) +void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) { if (!cm) return; @@ -412,7 +412,7 @@ void Channel::SetModeInternal(User *setter, ChannelMode *cm, const Anope::string * @param param The param * @param EnforceMLock true if mlocks should be enforced, false to override mlock */ -void Channel::RemoveModeInternal(User *setter, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) +void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) { if (!cm) return; @@ -537,7 +537,8 @@ void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, } ModeManager::StackerAdd(bi, this, cm, true, param); - SetModeInternal(bi, cm, param, EnforceMLock); + MessageSource ms(bi); + SetModeInternal(ms, cm, param, EnforceMLock); } /** @@ -589,7 +590,8 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶ } ModeManager::StackerAdd(bi, this, cm, false, realparam); - RemoveModeInternal(bi, cm, realparam, EnforceMLock); + MessageSource ms(bi); + RemoveModeInternal(ms, cm, realparam, EnforceMLock); } /** @@ -680,13 +682,29 @@ void Channel::SetModes(BotInfo *bi, bool EnforceMLock, const char *cmodes, ...) } } -/** Set a string of modes internally on a channel - * @param setter The setter, if it is a user - * @param mode the modes - * @param EnforceMLock true to enforce mlock - */ -void Channel::SetModesInternal(User *setter, const Anope::string &mode, bool EnforceMLock) +void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts, bool EnforceMLock) { + if (source.GetServer()) + { + if (Anope::CurTime != this->server_modetime) + { + this->server_modecount = 0; + this->server_modetime = Anope::CurTime; + } + + ++this->server_modecount; + } + + if (ts > 0 && ts < this->creation_time) + return; + else if (ts > this->creation_time) + { + Log(LOG_DEBUG) << "Changing TS of " << this->name << " from " << this->creation_time << " to " << ts; + this->creation_time = ts; + this->Reset(); + } + + User *setter = source.GetUser(); /* Removing channel modes *may* delete this channel */ dynamic_reference<Channel> this_reference(this); @@ -727,9 +745,9 @@ void Channel::SetModesInternal(User *setter, const Anope::string &mode, bool Enf if (cm->Type == MODE_REGULAR) { if (add) - this->SetModeInternal(setter, cm, "", EnforceMLock); + this->SetModeInternal(source, cm, "", EnforceMLock); else - this->RemoveModeInternal(setter, cm, "", EnforceMLock); + this->RemoveModeInternal(source, cm, "", EnforceMLock); continue; } else if (cm->Type == MODE_PARAM) @@ -738,7 +756,7 @@ void Channel::SetModesInternal(User *setter, const Anope::string &mode, bool Enf if (!add && cmp->MinusNoArg) { - this->RemoveModeInternal(setter, cm, "", EnforceMLock); + this->RemoveModeInternal(source, cm, "", EnforceMLock); continue; } } @@ -752,9 +770,9 @@ void Channel::SetModesInternal(User *setter, const Anope::string &mode, bool Enf paramstring += " " + token; if (add) - this->SetModeInternal(setter, cm, token, EnforceMLock); + this->SetModeInternal(source, cm, token, EnforceMLock); else - this->RemoveModeInternal(setter, cm, token, EnforceMLock); + this->RemoveModeInternal(source, cm, token, EnforceMLock); } else Log() << "warning: Channel::SetModesInternal() recieved more modes requiring params than params, modes: " << mode; @@ -766,7 +784,7 @@ void Channel::SetModesInternal(User *setter, const Anope::string &mode, bool Enf if (setter) Log(setter, this, "mode") << modestring << paramstring; else - Log(LOG_DEBUG) << "Setting " << this->name << " to " << modestring << paramstring; + Log(LOG_DEBUG) << source.GetName() << " is setting " << this->name << " to " << modestring << paramstring; } /** Kick a user from a channel internally @@ -774,23 +792,24 @@ void Channel::SetModesInternal(User *setter, const Anope::string &mode, bool Enf * @param nick The nick being kicked * @param reason The reason for the kick */ -void Channel::KickInternal(const Anope::string &source, const Anope::string &nick, const Anope::string &reason) +void Channel::KickInternal(MessageSource &source, const Anope::string &nick, const Anope::string &reason) { - User *sender = finduser(source); - BotInfo *bi = NULL; - if (this->ci && this->ci->bi) - bi = findbot(nick); - User *target = bi ? bi : finduser(nick); + User *sender = source.GetUser(); + User *target = finduser(nick); if (!target) { Log() << "Channel::KickInternal got a nonexistent user " << nick << " on " << this->name << ": " << reason; return; } + BotInfo *bi = NULL; + if (target->server == Me) + bi = findbot(nick); + if (sender) Log(sender, this, "kick") << "kicked " << target->nick << " (" << reason << ")"; else - Log(target, this, "kick") << "was kicked by " << source << " (" << reason << ")"; + Log(target, this, "kick") << "was kicked by " << source.GetSource() << " (" << reason << ")"; Anope::string chname = this->name; @@ -802,7 +821,7 @@ void Channel::KickInternal(const Anope::string &source, const Anope::string &nic this->DeleteUser(target); } else - Log() << "Channel::KickInternal got kick for user " << target->nick << " from " << (sender ? sender->nick : source) << " who isn't on channel " << this->name; + Log() << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name; /* Bots get rejoined */ if (bi) @@ -833,13 +852,17 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) /* Do not kick protected clients */ if (u->IsProtected()) return false; + + if (bi == NULL) + bi = this->ci->WhoSends(); EventReturn MOD_RESULT; FOREACH_RESULT(I_OnBotKick, OnBotKick(bi, this, u, buf)); if (MOD_RESULT == EVENT_STOP) return false; - ircdproto->SendKick(bi ? bi : this->ci->WhoSends(), this, u, "%s", buf); - this->KickInternal(bi ? bi->nick : this->ci->WhoSends()->nick, u->nick, buf); + ircdproto->SendKick(bi, this, u, "%s", buf); + MessageSource ms(bi); + this->KickInternal(ms, u->nick, buf); return true; } @@ -870,13 +893,14 @@ Anope::string Channel::GetModes(bool complete, bool plus) void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts) { User *u = finduser(user); + this->topic = newtopic; this->topic_setter = u ? u->nick : user; this->topic_time = ts; - Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << user << " to " << newtopic; + Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << (u ? u->nick : user) << " to " << newtopic; - FOREACH_MOD(I_OnTopicUpdated, OnTopicUpdated(this, u, this->topic)); + FOREACH_MOD(I_OnTopicUpdated, OnTopicUpdated(this, user, this->topic)); if (this->ci) this->ci->CheckTopic(); @@ -885,13 +909,14 @@ void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts) { User *u = finduser(user); + this->topic = newtopic; this->topic_setter = u ? u->nick : user; this->topic_time = ts; ircdproto->SendTopic(this->ci->WhoSends(), this); - FOREACH_MOD(I_OnTopicUpdated, OnTopicUpdated(this, u, this->topic)); + FOREACH_MOD(I_OnTopicUpdated, OnTopicUpdated(this, user, this->topic)); if (this->ci) this->ci->CheckTopic(); @@ -978,172 +1003,6 @@ User *nc_on_chan(Channel *c, const NickCore *nc) return NULL; } -/*************************************************************************/ -/*************************** Message Handling ****************************/ -/*************************************************************************/ - -/** Handle a JOIN command - * @param source user joining - * @param channels being joined - * @param ts TS for the join - */ -void do_join(const Anope::string &source, const Anope::string &channels, const Anope::string &ts) -{ - User *user = finduser(source); - if (!user) - { - Log() << "JOIN from nonexistent user " << source << ": " << channels; - return; - } - - commasepstream sep(channels); - Anope::string buf; - while (sep.GetToken(buf)) - { - if (buf[0] == '0') - { - for (UChannelList::iterator it = user->chans.begin(), it_end = user->chans.end(); it != it_end; ) - { - ChannelContainer *cc = *it++; - - Anope::string channame = cc->chan->name; - FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan)); - cc->chan->DeleteUser(user); - FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame), channame, "")); - } - user->chans.clear(); - continue; - } - - Channel *chan = findchan(buf); - - /* Channel doesn't exist, create it */ - if (!chan) - chan = new Channel(buf, Anope::CurTime); - - /* Join came with a TS */ - if (!ts.empty()) - { - time_t t = Anope::string(ts).is_pos_number_only() ? convertTo<time_t>(ts) : 0; - - /* Their time is older, we lose */ - if (t && chan->creation_time > t) - { - Log(LOG_DEBUG) << "Recieved an older TS " << chan->name << " in JOIN, changing from " << chan->creation_time << " to " << ts; - chan->creation_time = t; - - chan->Reset(); - } - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(user, chan)); - - /* Join the user to the channel */ - chan->JoinUser(user); - /* Set the propre modes on the user */ - chan_set_correct_modes(user, chan, 1, true); - - /* Modules may want to allow this user in the channel, check. - * If not, CheckKick will kick/ban them, don't call OnJoinChannel after this as the user will have - * been destroyed - */ - if (MOD_RESULT != EVENT_STOP && chan && chan->ci && chan->ci->CheckKick(user)) - continue; - - FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(user, chan)); - } -} - -/*************************************************************************/ - -/** Handle a KICK command. - * @param source The source of the kick - * @param users the user(s) being kicked - * @param reason The reason for the kick - */ -void do_kick(const Anope::string &source, const Anope::string &channel, const Anope::string &users, const Anope::string &reason) -{ - Channel *c = findchan(channel); - if (!c) - { - Log() << "Recieved kick for nonexistant channel " << channel; - return; - } - - Anope::string buf; - commasepstream sep(users); - while (sep.GetToken(buf)) - c->KickInternal(source, buf, reason); -} - -/*************************************************************************/ - -void do_part(const Anope::string &source, const Anope::string &channels, const Anope::string &reason) -{ - User *user = finduser(source); - if (!user) - { - Log() << "PART from nonexistent user " << source << ": " << reason; - return; - } - - commasepstream sep(channels); - Anope::string buf; - while (sep.GetToken(buf)) - { - Channel *c = findchan(buf); - - if (!c) - Log() << "Recieved PART from " << user->nick << " for nonexistant channel " << buf; - else if (user->FindChannel(c)) - { - Log(user, c, "part") << "Reason: " << (!reason.empty() ? reason : "No reason"); - FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, c)); - Anope::string ChannelName = c->name; - c->DeleteUser(user); - FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(ChannelName), ChannelName, !reason.empty() ? reason : "")); - } - else - Log() << "Recieved PART from " << user->nick << " for " << c->name << ", but " << user->nick << " isn't in " << c->name << "?"; - } -} - -/*************************************************************************/ - -/** Process a MODE command from the server, and set the modes on the user/channel - * it was sent for - * @param source The source of the command - * @param channel the channel to change modes on - * @param modes the mode changes - * @param ts the timestamp for the modes - */ -void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts) -{ - Channel *c = findchan(channel); - if (!c) - { - Log(LOG_DEBUG) << "MODE " << modes << " for nonexistant channel " << channel; - return; - } - - Log(LOG_DEBUG) << "MODE " << channel << " " << modes << " ts: " << ts; - - if (source.find('.') != Anope::string::npos) - { - if (Anope::CurTime != c->server_modetime) - { - c->server_modecount = 0; - c->server_modetime = Anope::CurTime; - } - ++c->server_modecount; - } - - c->SetModesInternal(finduser(source), modes); -} - -/*************************************************************************/ - /** * Set the correct modes, or remove the ones granted without permission, * for the specified user on ths specified channel. This doesn't give diff --git a/src/init.cpp b/src/init.cpp index b1001904c..ee36cb39a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -481,8 +481,6 @@ void Init(int ac, char **av) /* Initialize the socket engine */ SocketEngine::Init(); - init_core_messages(); - /* Write our PID to the PID file. */ write_pidfile(); diff --git a/src/main.cpp b/src/main.cpp index cdddc3163..d43bda2bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -213,10 +213,7 @@ UplinkSocket::Message::~Message() return; } - if (ircd->ts6) - message_source = this->server->GetSID(); - else - message_source = this->server->GetName(); + message_source = this->server->GetSID(); } else if (this->user != NULL) { @@ -233,10 +230,7 @@ UplinkSocket::Message::~Message() return; } - if (ircd->ts6) - message_source = this->user->GetUID(); - else - message_source = this->user->nick; + message_source = this->user->GetUID(); } if (!UplinkSock) diff --git a/src/messages.cpp b/src/messages.cpp index b34841094..2faa1cbb1 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -1,4 +1,4 @@ -/* Definitions of IRC message functions and list of messages. +/* Common message handlers * * (C) 2003-2012 Anope Team * Contact us at team@anope.org @@ -17,30 +17,288 @@ #include "extern.h" #include "uplink.h" #include "opertype.h" +#include "messages.h" +#include "servers.h" +#include "channels.h" -bool OnStats(const Anope::string &source, const std::vector<Anope::string> ¶ms) +bool CoreIRCDMessageAway::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (params.size() < 1) + FOREACH_MOD(I_OnUserAway, OnUserAway(source.GetUser(), params.empty() ? "" : params[0])); + return true; +} + +bool CoreIRCDMessageCapab::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + for (unsigned i = 0; i < params.size(); ++i) + Capab.insert(params[i]); + return true; +} + +bool CoreIRCDMessageError::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + Log(LOG_TERMINAL) << "ERROR: " << params[0]; + quitmsg = "Received ERROR from uplink: " + params[0]; + + return true; +} + +bool CoreIRCDMessageJoin::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + User *user = source.GetUser(); + const Anope::string &channels = params[0]; + + Anope::string channel; + commasepstream sep(channels); + + while (sep.GetToken(channel)) + { + /* Special case for /join 0 */ + if (channel == "0") + { + for (UChannelList::iterator it = user->chans.begin(), it_end = user->chans.end(); it != it_end; ) + { + ChannelContainer *cc = *it++; + + Anope::string channame = cc->chan->name; + FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan)); + cc->chan->DeleteUser(user); + FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame), channame, "")); + } + user->chans.clear(); + continue; + } + + Channel *chan = findchan(channel); + /* Channel doesn't exist, create it */ + if (!chan) + chan = new Channel(channel, Anope::CurTime); + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(user, chan)); + + /* Join the user to the channel */ + chan->JoinUser(user); + /* Set the proper modes on the user */ + chan_set_correct_modes(user, chan, 1, true); + + /* Modules may want to allow this user in the channel, check. + * If not, CheckKick will kick/ban them, don't call OnJoinChannel after this as the user will have + * been destroyed + */ + if (MOD_RESULT != EVENT_STOP && chan && chan->ci && chan->ci->CheckKick(user)) + continue; + + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(user, chan)); + } + + return true; +} + +bool CoreIRCDMessageKill::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + User *u = finduser(params[0]); + BotInfo *bi; + + if (!u) return true; - User *u = finduser(source); + /* Recover if someone kills us. */ + if (u->server == Me && (bi = dynamic_cast<BotInfo *>(u))) + { + bi->introduced = false; + introduce_user(bi->nick); + bi->RejoinAll(); + } + else + u->KillInternal(source.GetSource(), params[1]); + + return true; +} + +/* XXX We should cache the file somewhere not open/read/close it on every request */ +bool CoreIRCDMessageMOTD::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + Server *s = Server::Find(params[0]); + if (s != Me) + return true; + + FILE *f = fopen(Config->MOTDFilename.c_str(), "r"); + if (f) + { + ircdproto->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", Config->ServerName.c_str()); + char buf[BUFSIZE]; + while (fgets(buf, sizeof(buf), f)) + { + buf[strlen(buf) - 1] = 0; + ircdproto->SendNumeric(372, source.GetSource(), ":- %s", buf); + } + fclose(f); + ircdproto->SendNumeric(376, source.GetSource(), ":End of /MOTD command."); + } + else + ircdproto->SendNumeric(422, source.GetSource(), ":- MOTD file not found! Please contact your IRC administrator."); + + return true; +} + +bool CoreIRCDMessagePart::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + User *u = source.GetUser(); + const Anope::string &reason = params.size() > 1 ? params[1] : ""; + + Anope::string channel; + commasepstream sep(params[0]); + + while (sep.GetToken(channel)) + { + dynamic_reference<Channel> c = findchan(channel); + + if (!c || !u->FindChannel(c)) + continue; + + Log(u, c, "part") << "Reason: " << (!reason.empty() ? reason : "No reason"); + FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(u, c)); + Anope::string ChannelName = c->name; + c->DeleteUser(u); + FOREACH_MOD(I_OnPartChannel, OnPartChannel(u, c, ChannelName, !reason.empty() ? reason : "")); + } + + return true; +} + +bool CoreIRCDMessagePing::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + ircdproto->SendPong(params.size() > 1 ? params[1] : Me->GetSID(), params[0]); + return true; +} + +bool CoreIRCDMessagePrivmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + const Anope::string &receiver = params[0]; + Anope::string message = params[1]; + + User *u = source.GetUser(); + + if (ircdproto->IsChannelValid(receiver)) + { + Channel *c = findchan(receiver); + if (c) + { + FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message)); + } + } + else + { + /* If a server is specified (nick@server format), make sure it matches + * us, and strip it off. */ + Anope::string botname = receiver; + size_t s = receiver.find('@'); + if (s != Anope::string::npos) + { + Anope::string servername(receiver.begin() + s + 1, receiver.end()); + botname = botname.substr(0, s); + if (!servername.equals_ci(Config->ServerName)) + return true; + } + else if (Config->UseStrictPrivMsg) + { + const BotInfo *bi = findbot(receiver); + if (!bi) + return true; + Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick; + u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), receiver.c_str(), receiver.c_str(), Config->ServerName.c_str(), receiver.c_str()); + return true; + } + + BotInfo *bi = findbot(botname); + + if (bi) + { + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnBotPrivmsg, OnBotPrivmsg(u, bi, message)); + if (MOD_RESULT == EVENT_STOP) + return true; + + if (message[0] == '\1' && message[message.length() - 1] == '\1') + { + if (message.substr(0, 6).equals_ci("\1PING ")) + { + Anope::string buf = message; + buf.erase(buf.begin()); + buf.erase(buf.end() - 1); + ircdproto->SendCTCP(bi, u->nick, "%s", buf.c_str()); + } + else if (message.substr(0, 9).equals_ci("\1VERSION\1")) + { + Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); + ircdproto->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircdproto->GetProtocolName().c_str(), enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); + } + return true; + } + + bi->OnMessage(u, message); + } + } + + return true; +} + +bool CoreIRCDMessageQuit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + const Anope::string &reason = params[0]; + User *user = source.GetUser(); + + Log(user, "quit") << "quit (Reason: " << (!reason.empty() ? reason : "no reason") << ")"; + + NickAlias *na = findnick(user->nick); + if (na && !na->nc->HasFlag(NI_SUSPENDED) && (user->IsRecognized() || user->IsIdentified(true))) + { + na->last_seen = Anope::CurTime; + na->last_quit = reason; + } + FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, reason)); + delete user; + + return true; +} + +bool CoreIRCDMessageSQuit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + Server *s = Server::Find(params[0]); + + if (!s) + { + Log() << "SQUIT for nonexistent server " << params[0]; + return true; + } + + FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); + + s->Delete(s->GetName() + " " + s->GetUplink()->GetName()); + + return true; +} + +bool CoreIRCDMessageStats::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + User *u = source.GetUser(); switch (params[0][0]) { case 'l': - if (u && u->HasMode(UMODE_OPER)) + if (u->HasMode(UMODE_OPER)) { - ircdproto->SendNumeric(211, source, "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime"); - ircdproto->SendNumeric(211, source, "%s %d %d %d %d %d %d %ld", Config->Uplinks[CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - start_time)); + ircdproto->SendNumeric(211, source.GetSource(), "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime"); + ircdproto->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - start_time)); } - ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); break; case 'o': case 'O': /* Check whether the user is an operator */ - if (u && !u->HasMode(UMODE_OPER) && Config->HideStatsO) - ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); + if (!u->HasMode(UMODE_OPER) && Config->HideStatsO) + ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); else { for (unsigned i = 0; i < Config->Opers.size(); ++i) @@ -49,127 +307,74 @@ bool OnStats(const Anope::string &source, const std::vector<Anope::string> ¶ const NickAlias *na = findnick(o->name); if (na) - ircdproto->SendNumeric(243, source, "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); + ircdproto->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); } - ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); } break; - case 'u': { time_t uptime = Anope::CurTime - start_time; - ircdproto->SendNumeric(242, source, ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); - ircdproto->SendNumeric(250, source, ":Current users: %d (%d ops); maximum %d", usercnt, opcnt, maxusercnt); - ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(242, source.GetSource(), ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); + ircdproto->SendNumeric(250, source.GetSource(), ":Current users: %d (%d ops); maximum %d", usercnt, opcnt, maxusercnt); + ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); break; } /* case 'u' */ default: - ircdproto->SendNumeric(219, source, "%c :End of /STATS report.", params[0][0]); + ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); } return true; } -bool OnTime(const Anope::string &source, const std::vector<Anope::string> &) +bool CoreIRCDMessageTime::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (source.empty()) - return true; - time_t t; time(&t); struct tm *tm = localtime(&t); char buf[64]; strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm); - ircdproto->SendNumeric(391, source, "%s :%s", Config->ServerName.c_str(), buf); + ircdproto->SendNumeric(391, source.GetSource(), "%s :%s", Config->ServerName.c_str(), buf); + return true; +} + +bool CoreIRCDMessageTopic::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +{ + Channel *c = findchan(params[0]); + if (c) + c->ChangeTopicInternal(source.GetSource(), params[1], Anope::CurTime); + return true; } -bool OnVersion(const Anope::string &source, const std::vector<Anope::string> &) +bool CoreIRCDMessageVersion::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - ircdproto->SendNumeric(351, source, "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); + ircdproto->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircdproto->GetProtocolName().c_str(), enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); return true; } -/* XXX We should cache the file somewhere not open/read/close it on every request */ -bool OnMotd(const Anope::string &source, const std::vector<Anope::string> &) +bool CoreIRCDMessageWhois::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (source.empty()) - return true; + User *u = finduser(params[0]); - FILE *f = fopen(Config->MOTDFilename.c_str(), "r"); - if (f) + if (u && u->server == Me) { - ircdproto->SendNumeric(375, source, ":- %s Message of the Day", Config->ServerName.c_str()); - char buf[BUFSIZE]; - while (fgets(buf, sizeof(buf), f)) - { - buf[strlen(buf) - 1] = 0; - ircdproto->SendNumeric(372, source, ":- %s", buf); - } - fclose(f); - ircdproto->SendNumeric(376, source, ":End of /MOTD command."); + const BotInfo *bi = findbot(u->nick); + ircdproto->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str()); + if (bi) + ircdproto->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str()); + ircdproto->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str()); + if (bi) + ircdproto->SendNumeric(317, source.GetSource(), "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(start_time)); + ircdproto->SendNumeric(318, source.GetSource(), "%s :End of /WHOIS list.", params[0].c_str()); } else - ircdproto->SendNumeric(422, source, ":- MOTD file not found! Please contact your IRC administrator."); + ircdproto->SendNumeric(401, source.GetSource(), "%s :No such user.", params[0].c_str()); return true; } -#define ProtocolFunc(x) \ - inline bool x(const Anope::string &source, const std::vector<Anope::string> ¶ms) \ - { \ - return ircdmessage->x(source, params); \ - } - -ProtocolFunc(On436) |
