diff options
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); } |