diff options
author | Adam <Adam@anope.org> | 2010-12-06 17:06:57 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-12-12 19:37:03 -0500 |
commit | aed53dbb47822a79eb9a6b61095ad04ec3d67818 (patch) | |
tree | 72d3210b5609ea2163854d14ec7fb2f48d8b4d12 /modules/protocol/unreal32.cpp | |
parent | a507816701d136a1c22d2f6779d811840d61577c (diff) |
Cleaned up some things, made the protocol modules use some basic inheritance to cut back on their code duplication. More work can be done in the future to remove even more of it.
Diffstat (limited to 'modules/protocol/unreal32.cpp')
-rw-r--r-- | modules/protocol/unreal32.cpp | 960 |
1 files changed, 432 insertions, 528 deletions
diff --git a/modules/protocol/unreal32.cpp b/modules/protocol/unreal32.cpp index 80d1ab08d..bf3d178ce 100644 --- a/modules/protocol/unreal32.cpp +++ b/modules/protocol/unreal32.cpp @@ -382,174 +382,445 @@ class UnrealIRCdProto : public IRCDProto { ircdproto->SendMode(NickServ, u, "+d 1"); } -} ircd_proto; +}; -/* Event: PROTOCTL */ -bool event_capab(const Anope::string &source, const std::vector<Anope::string> ¶ms) +class Unreal32IRCdMessage : public IRCdMessage { - for (unsigned i = 0; i < params.size(); ++i) + public: + bool OnMode(const Anope::string &source, const std::vector<Anope::string> ¶ms) { - Anope::string capab = params[i]; + if (params.size() < 2) + return true; + + bool server_source = Server::Find(source) != NULL; + Anope::string modes = params[1]; + for (unsigned i = 2; i < params.size() - (server_source ? 1 : 0); ++i) + modes += " " + params[i]; + + if (params[0][0] == '#' || params[0][0] == '&') + do_cmode(source, params[0], modes, server_source ? params[params.size() - 1] : ""); + else + do_umode(source, params[0], modes); + + return true; + } - if (capab.find("CHANMODES") != Anope::string::npos) + /* + ** NICK - new + ** source = NULL + ** parv[0] = nickname + ** parv[1] = hopcount + ** parv[2] = timestamp + ** parv[3] = username + ** parv[4] = hostname + ** parv[5] = servername + ** if NICK version 1: + ** parv[6] = servicestamp + ** parv[7] = info + ** if NICK version 2: + ** parv[6] = servicestamp + ** parv[7] = umodes + ** parv[8] = virthost, * if none + ** parv[9] = info + ** if NICKIP: + ** parv[9] = ip + ** parv[10] = info + ** + ** NICK - change + ** source = oldnick + ** parv[0] = new nickname + ** parv[1] = hopcount + */ + bool OnNick(const Anope::string &source, const std::vector<Anope::string> ¶ms) + { + if (params.size() == 7) + { + /* + <codemastr> that was a bug that is now fixed in 3.2.1 + <codemastr> in some instances it would use the non-nickv2 format + <codemastr> it's sent when a nick collision occurs + - so we have to leave it around for now -TSL + */ + do_nick(source, params[0], params[3], params[4], params[5], params[6], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, "", "*", "", ""); + } + else if (params.size() == 11) { - Anope::string modes(capab.begin() + 10, capab.end()); - commasepstream sep(modes); - Anope::string modebuf; + Anope::string decoded_ip; + b64_decode(params[9], decoded_ip); + + sockaddrs ip; + ip.ntop(params[9].length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str()); - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) + Anope::string vhost = params[8]; + if (vhost.equals_cs("*")) + vhost.clear(); + + User *user = do_nick(source, params[0], params[3], params[4], params[5], params[10], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip.addr(), vhost, "", params[7]); + if (user) { - switch (modebuf[t]) + NickAlias *na = findnick(user->nick); + + if (na && user->timestamp == convertTo<time_t>(params[6])) { - case 'b': - ModeManager::AddChannelMode(new ChannelModeBan('b')); - continue; - case 'e': - ModeManager::AddChannelMode(new ChannelModeExcept('e')); - continue; - case 'I': - ModeManager::AddChannelMode(new ChannelModeInvex('I')); - continue; - default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t])); + user->Login(na->nc); + user->SetMode(NickServ, UMODE_REGISTERED); } + else + validate_user(user); } + } + else if (params.size() != 2) + { + Anope::string vhost = params[8]; + if (vhost.equals_cs("*")) + vhost.clear(); - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) + /* NON NICKIP */ + User *user = do_nick(source, params[0], params[3], params[4], params[5], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, "", vhost, "", params[7]); + if (user) { - switch (modebuf[t]) + NickAlias *na = findnick(user->nick); + + if (na && user->timestamp == convertTo<time_t>(params[6])) { - case 'k': - ModeManager::AddChannelMode(new ChannelModeKey('k')); - continue; - case 'f': - ModeManager::AddChannelMode(new ChannelModeFlood('f')); - continue; - case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L')); - continue; - default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t])); + user->Login(na->nc); + user->SetMode(NickServ, UMODE_REGISTERED); } + else + validate_user(user); } + } + else + do_nick(source, params[0], "", "", "", "", Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0, "", "", "", ""); + + return true; + } + + bool OnServer(const Anope::string &source, const std::vector<Anope::string> ¶ms) + { + if (params[1].equals_cs("1")) + { + Anope::string vl = myStrGetToken(params[2], ' ', 0); + Anope::string upnumeric = myStrGetToken(vl, '-', 2); + Anope::string desc = myStrGetTokenRemainder(params[2], ' ', 1); + do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, desc, upnumeric); + } + else + do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[2], ""); - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) + ircdproto->SendPing(Config->ServerName, params[0]); + + return true; + } + + /* + ** source = sender prefix + ** parv[0] = channel name + ** parv[1] = topic nickname + ** parv[2] = topic time + ** parv[3] = topic text + */ + bool OnTopic(const Anope::string &, const std::vector<Anope::string> ¶ms) + { + if (params.size() != 4) + return true; + + Channel *c = findchan(params[0]); + if (!c) + { + Log() << "TOPIC for nonexistant channel " << params[0]; + return true; + } + + c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime); + + return true; + } + + bool OnCapab(const Anope::string &source, const std::vector<Anope::string> ¶ms) + { + for (unsigned i = 0; i < params.size(); ++i) + { + Anope::string capab = params[i]; + + if (capab.find("CHANMODES") != Anope::string::npos) { - switch (modebuf[t]) + Anope::string modes(capab.begin() + 10, capab.end()); + commasepstream sep(modes); + Anope::string modebuf; + + sep.GetToken(modebuf); + for (size_t t = 0, end = modebuf.length(); t < end; ++t) { - case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true)); - continue; - case 'j': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true)); - continue; - default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true)); + switch (modebuf[t]) + { + case 'b': + ModeManager::AddChannelMode(new ChannelModeBan('b')); + continue; + case 'e': + ModeManager::AddChannelMode(new ChannelModeExcept('e')); + continue; + case 'I': + ModeManager::AddChannelMode(new ChannelModeInvex('I')); + continue; + default: + ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t])); + } + } + + sep.GetToken(modebuf); + for (size_t t = 0, end = modebuf.length(); t < end; ++t) + { + switch (modebuf[t]) + { + case 'k': + ModeManager::AddChannelMode(new ChannelModeKey('k')); + continue; + case 'f': + ModeManager::AddChannelMode(new ChannelModeFlood('f')); + continue; + case 'L': + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L')); + continue; + default: + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t])); + } + } + + sep.GetToken(modebuf); + for (size_t t = 0, end = modebuf.length(); t < end; ++t) + { + switch (modebuf[t]) + { + case 'l': + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true)); + continue; + case 'j': + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true)); + continue; + default: + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true)); + } + } + + sep.GetToken(modebuf); + for (size_t t = 0, end = modebuf.length(); t < end; ++t) + { + switch (modebuf[t]) + { + case 'p': + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); + continue; + case 's': + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); + continue; + case 'm': + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); + continue; + case 'n': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); + continue; + case 't': + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); + continue; + case 'i': + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); + continue; + case 'r': + ModeManager::AddChannelMode(new ChannelModeRegistered('r')); + continue; + case 'R': + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); + continue; + case 'c': + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); + continue; + case 'O': + ModeManager::AddChannelMode(new ChannelModeOper('O')); + continue; + case 'A': + ModeManager::AddChannelMode(new ChannelModeAdmin('A')); + continue; + case 'Q': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q')); + continue; + case 'K': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K')); + continue; + case 'V': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, "CMODE_NOINVITE", 'V')); + continue; + case 'C': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C')); + continue; + case 'u': + ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u')); + continue; + case 'z': + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z')); + continue; + case 'N': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N')); + continue; + case 'S': + ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S')); + continue; + case 'M': + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M')); + continue; + case 'T': + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T')); + continue; + case 'G': + ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G')); + continue; + default: + ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t])); + } } } + } + + IRCdMessage::OnCapab(source, params); + + return true; + } + + bool OnSJoin(const Anope::string &source, const std::vector<Anope::string> ¶ms) + { + Channel *c = findchan(params[1]); + time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : 0; + bool keep_their_modes = true; - sep.GetToken(modebuf); - for (size_t t = 0, end = modebuf.length(); t < end; ++t) + if (!c) + { + c = new Channel(params[1], ts); + c->SetFlag(CH_SYNCING); + } + /* Our creation time is newer than what the server gave us */ + else if (c->creation_time > ts) + { + c->creation_time = ts; + c->Reset(); + + /* Reset mlock */ + check_modes(c); + } + /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */ + else if (ts > c->creation_time) + keep_their_modes = false; + + /* If we need to keep their modes, and this SJOIN string contains modes */ + if (keep_their_modes && params.size() >= 4) + { + Anope::string modes; + for (unsigned i = 2; i < params.size() - 1; ++i) + modes += " " + params[i]; + if (!modes.empty()) + modes.erase(modes.begin()); + /* Set the modes internally */ + c->SetModesInternal(NULL, modes); + } + + ChannelMode *ban = ModeManager::FindChannelModeByName(CMODE_BAN), + *except = ModeManager::FindChannelModeByName(CMODE_EXCEPT), + *invex = ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE); + spacesepstream sep(params[params.size() - 1]); + Anope::string buf; + while (sep.GetToken(buf)) + { + /* Ban */ + if (keep_their_modes && ban && buf[0] == '&') + { + buf.erase(buf.begin()); + c->SetModeInternal(ban, buf); + } + /* Except */ + else if (keep_their_modes && except && buf[0] == '"') + { + buf.erase(buf.begin()); + c->SetModeInternal(except, buf); + } + /* Invex */ + else if (keep_their_modes && invex && buf[0] == '\'') + { + buf.erase(buf.begin()); + c->SetModeInternal(invex, buf); + } + else { - switch (modebuf[t]) + std::list<ChannelMode *> Status; + char ch; + + /* Get prefixes from the nick */ + while ((ch = ModeManager::GetStatusChar(buf[0]))) { - case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); - continue; - case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); - continue; - case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); - continue; - case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); - continue; - case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); - continue; - case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); - continue; - case 'r': - ModeManager::AddChannelMode(new ChannelModeRegistered('r')); - continue; - case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); - continue; - case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); - continue; - case 'O': - ModeManager::AddChannelMode(new ChannelModeOper('O')); - continue; - case 'A': - ModeManager::AddChannelMode(new ChannelModeAdmin('A')); - continue; - case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q')); - continue; - case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K')); - continue; - case 'V': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, "CMODE_NOINVITE", 'V')); - continue; - case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C')); - continue; - case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u')); - continue; - case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z')); - continue; - case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N')); - continue; - case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S')); + buf.erase(buf.begin()); + ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); + if (!cm) + { + Log() << "Received unknown mode prefix " << buf[0] << " in SJOIN string"; continue; - case 'M': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M')); - continue; - case 'T': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T')); - continue; - case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G')); - continue; - default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t])); + } + + if (keep_their_modes) + Status.push_back(cm); + } + + User *u = finduser(buf); + if (!u) + { + Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << c->name; + continue; } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); + + /* Add the user to the channel */ + c->JoinUser(u); + + /* Update their status internally on the channel + * This will enforce secureops etc on the user + */ + for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) + c->SetModeInternal(*it, buf); + + /* Now set whatever modes this user is allowed to have on the channel */ + chan_set_correct_modes(u, c, 1); + + /* Check to see if modules want the user to join, if they do + * check to see if they are allowed to join (CheckKick will kick/ban them) + * Don't trigger OnJoinChannel event then as the user will be destroyed + */ + if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u)) + continue; + + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); } } - } - CapabParse(params); + /* Channel is done syncing */ + if (c->HasFlag(CH_SYNCING)) + { + /* Unset the syncing flag */ + c->UnsetFlag(CH_SYNCING); + c->Sync(); + } - return true; -} + return true; + } +}; -/* Events */ -bool event_ping(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!params.empty()) - ircdproto->SendPong(params.size() > 1 ? params[1] : Config->ServerName, params[0]); - return true; -} /** This is here because: * - * If we had servers three servers, A, B & C linked like so: A<->B<->C + * If we had three servers, A, B & C linked like so: A<->B<->C * If Anope is linked to A and B splits from A and then reconnects * B introduces itself, introduces C, sends EOS for C, introduces Bs clients * introduces Cs clients, sends EOS for B. This causes all of Cs clients to be introduced - * with their server "not syncing". We now send a PING immediatly when receiving a new server - * and then finish sync once we get a pong back from that server + * with their server "not syncing". We now send a PING immediately when receiving a new server + * and then finish sync once we get a pong back from that server. */ bool event_pong(const Anope::string &source, const std::vector<Anope::string> ¶ms) { @@ -575,82 +846,6 @@ bool event_netinfo(const Anope::string &source, const std::vector<Anope::string> return true; } -bool event_436(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!params.empty()) - m_nickcoll(params[0]); - return true; -} - -/* -** away -** parv[0] = sender prefix -** parv[1] = away message -*/ -bool event_away(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (source.empty()) - return true; - m_away(source, !params.empty() ? params[0] : ""); - return true; -} - -/* -** m_topic -** source = sender prefix -** parv[0] = channel name -** parv[1] = topic nickname -** parv[2] = topic time -** parv[3] = topic text -*/ -bool event_topic(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() != 4) - return true; - - Channel *c = findchan(params[0]); - if (!c) - { - Log() << "TOPIC for nonexistant channel " << params[0]; - return true; - } - - c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime); - - return true; -} - -bool event_squit(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() != 2) - do_squit(source, params[0]); - return true; -} - -bool event_quit(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!params.empty()) - do_quit(source, params[0]); - return true; -} - -bool event_mode(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() < 2) - return true; - - bool server_source = Server::Find(source) != NULL; - Anope::string modes = params[1]; - for (unsigned i = 2; i < params.size() - (server_source ? 1 : 0); ++i) - modes += " " + params[i]; - - if (params[0][0] == '#' || params[0][0] == '&') - do_cmode(source, params[0], modes, server_source ? params[params.size() - 1] : ""); - else - do_umode(source, params[0], modes); - return true; -} - /* Unreal sends USER modes with this */ /* umode2 @@ -666,36 +861,6 @@ bool event_umode2(const Anope::string &source, const std::vector<Anope::string> return true; } -bool event_kill(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() != 2) - return true; - - m_kill(params[0], params[1]); - return true; -} - -bool event_kick(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() != 3) - return true; - do_kick(source, params[0], params[1], params[2]); - return true; -} - -bool event_join(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!params.empty()) - do_join(source, params[0], ""); - return true; -} - -bool event_motd(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!source.empty()) - m_motd(source); - return true; -} bool event_setname(const Anope::string &source, const std::vector<Anope::string> ¶ms) { @@ -782,96 +947,6 @@ bool event_sethost(const Anope::string &source, const std::vector<Anope::string> return true; } -/* -** NICK - new -** source = NULL -** parv[0] = nickname -** parv[1] = hopcount -** parv[2] = timestamp -** parv[3] = username -** parv[4] = hostname -** parv[5] = servername -** if NICK version 1: -** parv[6] = servicestamp -** parv[7] = info -** if NICK version 2: -** parv[6] = servicestamp -** parv[7] = umodes -** parv[8] = virthost, * if none -** parv[9] = info -** if NICKIP: -** parv[9] = ip -** parv[10] = info -** -** NICK - change -** source = oldnick -** parv[0] = new nickname -** parv[1] = hopcount -*/ -bool event_nick(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() == 7) - { - /* - <codemastr> that was a bug that is now fixed in 3.2.1 - <codemastr> in some instances it would use the non-nickv2 format - <codemastr> it's sent when a nick collision occurs - - so we have to leave it around for now -TSL - */ - do_nick(source, params[0], params[3], params[4], params[5], params[6], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, "", "*", "", ""); - } - else if (params.size() == 11) - { - Anope::string decoded_ip; - b64_decode(params[9], decoded_ip); - - sockaddrs ip; - ip.ntop(params[9].length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str()); - - Anope::string vhost = params[8]; - if (vhost.equals_cs("*")) - vhost.clear(); - - User *user = do_nick(source, params[0], params[3], params[4], params[5], params[10], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip.addr(), vhost, "", params[7]); - if (user) - { - NickAlias *na = findnick(user->nick); - - if (na && user->timestamp == convertTo<time_t>(params[6])) - { - user->Login(na->nc); - user->SetMode(NickServ, UMODE_REGISTERED); - } - else - validate_user(user); - } - } - else if (params.size() != 2) - { - Anope::string vhost = params[8]; - if (vhost.equals_cs("*")) - vhost.clear(); - - /* NON NICKIP */ - User *user = do_nick(source, params[0], params[3], params[4], params[5], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, "", vhost, "", params[7]); - if (user) - { - NickAlias *na = findnick(user->nick); - - if (na && user->timestamp == convertTo<time_t>(params[6])) - { - user->Login(na->nc); - user->SetMode(NickServ, UMODE_REGISTERED); - } - else - validate_user(user); - } - } - else - do_nick(source, params[0], "", "", "", "", Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0, "", "", "", ""); - return true; -} - bool event_chghost(const Anope::string &source, const std::vector<Anope::string> ¶ms) { if (params.size() != 2) @@ -888,55 +963,6 @@ bool event_chghost(const Anope::string &source, const std::vector<Anope::string> return true; } -/* EVENT: SERVER */ -bool event_server(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params[1].equals_cs("1")) - { - Anope::string vl = myStrGetToken(params[2], ' ', 0); - Anope::string upnumeric = myStrGetToken(vl, '-', 2); - Anope::string desc = myStrGetTokenRemainder(params[2], ' ', 1); - do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, desc, upnumeric); - } - else - do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[2], ""); - ircdproto->SendPing(Config->ServerName, params[0]); - - return true; -} - -bool event_privmsg(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (params.size() > 1) - m_privmsg(source, params[0], params[1]); - return true; -} - -bool event_part(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!params.empty()) - do_part(source, params[0], params.size() > 1 ? params[1] : ""); - return true; -} - -bool event_whois(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!source.empty() && !params.empty()) - m_whois(source, params[0]); - return true; -} - -bool event_error(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - if (!params.empty()) - { - Log(LOG_DEBUG) << params[0]; - if (params[0].find("No matching link configuration") != Anope::string::npos) - Log() << "Error: Your IRCD's link block may not be setup correctly, please check unrealircd.conf"; - } - return true; -} - bool event_sdesc(const Anope::string &source, const std::vector<Anope::string> ¶ms) { Server *s = Server::Find(source); @@ -947,131 +973,6 @@ bool event_sdesc(const Anope::string &source, const std::vector<Anope::string> & return true; } -bool event_sjoin(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - Channel *c = findchan(params[1]); - time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : 0; - bool keep_their_modes = true; - - if (!c) - { - c = new Channel(params[1], ts); - c->SetFlag(CH_SYNCING); - } - /* Our creation time is newer than what the server gave us */ - else if (c->creation_time > ts) - { - c->creation_time = ts; - c->Reset(); - - /* Reset mlock */ - check_modes(c); - } - /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */ - else if (ts > c->creation_time) - keep_their_modes = false; - - /* If we need to keep their modes, and this SJOIN string contains modes */ - if (keep_their_modes && params.size() >= 4) - { - Anope::string modes; - for (unsigned i = 2; i < params.size() - 1; ++i) - modes += " " + params[i]; - if (!modes.empty()) - modes.erase(modes.begin()); - /* Set the modes internally */ - c->SetModesInternal(NULL, modes); - } - - ChannelMode *ban = ModeManager::FindChannelModeByName(CMODE_BAN), - *except = ModeManager::FindChannelModeByName(CMODE_EXCEPT), - *invex = ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE); - spacesepstream sep(params[params.size() - 1]); - Anope::string buf; - while (sep.GetToken(buf)) - { - /* Ban */ - if (keep_their_modes && ban && buf[0] == '&') - { - buf.erase(buf.begin()); - c->SetModeInternal(ban, buf); - } - /* Except */ - else if (keep_their_modes && except && buf[0] == '"') - { - buf.erase(buf.begin()); - c->SetModeInternal(except, buf); - } - /* Invex */ - else if (keep_their_modes && invex && buf[0] == '\'') - { - buf.erase(buf.begin()); - c->SetModeInternal(invex, buf); - } - else - { - std::list<ChannelMode *> Status; - char ch; - - /* Get prefixes from the nick */ - while ((ch = ModeManager::GetStatusChar(buf[0]))) - { - buf.erase(buf.begin()); - ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); - if (!cm) - { - Log() << "Received unknown mode prefix " << buf[0] << " in SJOIN string"; - continue; - } - - if (keep_their_modes) - Status.push_back(cm); - } - - User *u = finduser(buf); - if (!u) - { - Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << c->name; - continue; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); - - /* Add the user to the channel */ - c->JoinUser(u); - - /* Update their status internally on the channel - * This will enforce secureops etc on the user - */ - for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) - c->SetModeInternal(*it, buf); - - /* Now set whatever modes this user is allowed to have on the channel */ - chan_set_correct_modes(u, c, 1); - - /* Check to see if modules want the user to join, if they do - * check to see if they are allowed to join (CheckKick will kick/ban them) - * Don't trigger OnJoinChannel event then as the user will be destroyed - */ - if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u)) - continue; - - FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); - } - } - - /* Channel is done syncing */ - if (c->HasFlag(CH_SYNCING)) - { - /* Unset the syncing flag */ - c->UnsetFlag(CH_SYNCING); - c->Sync(); - } - - return true; -} - /* Borrowed part of this check from UnrealIRCd */ bool ChannelModeFlood::IsValid(const Anope::string &value) const { @@ -1148,57 +1049,60 @@ static void AddModes() class ProtoUnreal : public Module { - Message message_436, message_away, message_away2, message_join, message_join2, message_kick, message_kick2, - message_kill, message_kill2, message_mode, message_mode2, message_nick, message_nick2, message_part, - message_part2, message_ping, message_ping2, message_pong, message_pong2, message_privmsg, message_privmsg2, - message_quit, message_quit2, message_server, message_server2, message_squit, message_squit2, message_topic, - message_topic2, message_svsmode, message_svsmode2, message_svs2mode, message_svs2mode2, message_whois, message_whois2, + Message message_away, message_join, message_kick, + message_kill, message_mode, message_nick, message_part, + message_ping, message_pong, message_pong2, message_privmsg, + message_quit, message_server, message_squit, message_topic, + message_svsmode, message_svsmode2, message_svs2mode, message_svs2mode2, message_whois, message_capab, message_capab2, message_chghost, message_chghost2, message_chgident, message_chgident2, message_chgname, message_chgname2, message_netinfo, message_netinfo2, message_sethost, message_sethost2, - message_setident, message_setident2, message_setname, message_setname2, message_error, message_error2, - message_umode2, message_umode22, message_sjoin, message_sjoin2, message_sdesc, message_sdesc2; + message_setident, message_setident2, message_setname, message_setname2, message_error, + message_umode2, message_umode22, message_sjoin, message_sdesc, message_sdesc2; /* Non-token of these in messages.cpp */ Message message_stats, message_time, message_version; + + UnrealIRCdProto ircd_proto; + Unreal32IRCdMessage ircd_message; public: ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), - message_436("436", event_436), message_away("AWAY", event_away), message_away2("6", event_away), - message_join("JOIN", event_join), message_join2("C", event_join), message_kick("KICK", event_kick), - message_kick2("H", event_kick), message_kill("KILL", event_kill), message_kill2(".", event_kill), - message_mode("MODE", event_mode), message_mode2("G", event_mode), message_nick("NICK", event_nick), - message_nick2("&", event_nick), message_part("PART", event_part), message_part2("D", event_part), - message_ping("PING", event_ping), message_ping2("8", event_ping), message_pong("PONG", event_pong), - message_pong2("9", event_pong), message_privmsg("PRIVMSG", event_privmsg), message_privmsg2("!", event_privmsg), - message_quit("QUIT", event_quit), message_quit2(",", event_quit), message_server("SERVER", event_server), - message_server2("'", event_server), message_squit("SQUIT", event_squit), message_squit2("-", event_squit), - message_topic("TOPIC", event_topic), message_topic2(")", event_topic), message_svsmode("SVSMODE", event_mode), - message_svsmode2("n", event_mode), message_svs2mode("SVS2MODE", event_mode), message_svs2mode2("v", event_mode), - message_whois("WHOIS", event_whois), message_whois2("#", event_whois), message_capab("PROTOCTL", event_capab), - message_capab2("_", event_capab), message_chghost("CHGHOST", event_chghost), message_chghost2("AL", event_chghost), + message_away("6", OnAway), + message_join("C", OnJoin), + message_kick("H", OnKick), message_kill(".", OnKill), + message_mode("G", OnMode), + message_nick("&", OnNick), message_part("D", OnPart), + message_ping("8", OnPing), message_pong("PONG", event_pong), + message_pong2("9", event_pong), message_privmsg("!", OnPrivmsg), + message_quit(",", OnQuit), + message_server("'", OnServer), message_squit("-", OnSQuit), + message_topic(")", OnTopic), message_svsmode("SVSMODE", OnMode), + message_svsmode2("n", OnMode), message_svs2mode("SVS2MODE", OnMode), message_svs2mode2("v", OnMode), + message_whois("#", OnWhois), message_capab("PROTOCTL", OnCapab), + message_capab2("_", OnCapab), message_chghost("CHGHOST", event_chghost), message_chghost2("AL", event_chghost), message_chgident("CHGIDENT", event_chgident), message_chgident2("AZ", event_chgident), message_chgname("CHGNAME", event_chgname), message_chgname2("BK", event_chgname), message_netinfo("NETINFO", event_netinfo), message_netinfo2("AO", event_netinfo), message_sethost("SETHOST", event_sethost), message_sethost2("AA", event_sethost), message_setident("SETIDENT", event_setident), message_setident2("AD", event_setident), message_setname("SETNAME", event_setname), message_setname2("AE", event_setname), - message_error("ERROR", event_error), message_error2("5", event_error), message_umode2("UMODE2", event_umode2), - message_umode22("|", event_umode2), message_sjoin("SJOIN", event_sjoin), message_sjoin2("~", event_sjoin), + message_error("5", OnError), message_umode2("UMODE2", event_umode2), + message_umode22("|", event_umode2), message_sjoin("~", OnSJoin), message_sdesc("SDESC", event_sdesc), message_sdesc2("AG", event_sdesc), - message_stats("2", m_stats), message_time(">", m_time), message_version("+", m_version) + message_stats("2", OnStats), message_time(">", OnTime), message_version("+", OnVersion) { this->SetAuthor("Anope"); this->SetType(PROTOCOL); - pmodule_ircd_var(myIrcd); - CapabType c[] = { CAPAB_NOQUIT, CAPAB_NICKIP, CAPAB_ZIP, CAPAB_TOKEN, CAPAB_SSJ3, CAPAB_NICK2, CAPAB_VL, CAPAB_TLKEXT, CAPAB_CHANMODE, CAPAB_NICKCHARS }; for (unsigned i = 0; i < 10; ++i) Capab.SetFlag(c[i]); AddModes(); - pmodule_ircd_proto(&ircd_proto); + pmodule_ircd_var(myIrcd); + pmodule_ircd_proto(&this->ircd_proto); + pmodule_ircd_message(&this->ircd_message); ModuleManager::Attach(I_OnUserNickChange, this); } |