summaryrefslogtreecommitdiff
path: root/modules/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'modules/protocol')
-rw-r--r--modules/protocol/bahamut.cpp436
-rw-r--r--modules/protocol/charybdis.cpp204
-rw-r--r--modules/protocol/hybrid.cpp445
-rw-r--r--modules/protocol/inspircd20.cpp581
-rw-r--r--modules/protocol/ngircd.cpp188
-rw-r--r--modules/protocol/plexus.cpp219
-rw-r--r--modules/protocol/ratbox.cpp207
-rw-r--r--modules/protocol/rfc1459.cpp142
-rw-r--r--modules/protocol/ts6.cpp71
-rw-r--r--modules/protocol/unreal.cpp480
10 files changed, 1822 insertions, 1151 deletions
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 46ffb3ea2..cdb05e7f7 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -23,103 +23,175 @@
#include "modules/protocol/rfc1459.h"
#include "modules/protocol/bahamut.h"
-class ChannelModeFlood : public ChannelModeParam
+void bahamut::senders::Akill::Send(User* u, XLine* x)
{
- public:
- ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
-
- bool IsValid(Anope::string &value) const override
+ if (x->IsRegex() || x->HasNickOrReal())
{
- try
+ if (!u)
{
- Anope::string rest;
- if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
- return true;
+ /* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (x->GetManager()->Check(it->second, x))
+ this->Send(it->second, x);
+ return;
}
- catch (const ConvertException &) { }
- return false;
+ XLine *old = x;
+
+ if (old->GetManager()->HasEntry("*@" + u->host))
+ return;
+
+ /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
+ x = Serialize::New<XLine *>();
+ x->SetMask("*@" + u->host);
+ x->SetBy(old->GetBy());
+ x->SetExpires(old->GetExpires());
+ x->SetReason(old->GetReason());
+ x->SetID(old->GetID());
+ old->GetManager()->AddXLine(x);
+
+ Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask();
}
-};
-bahamut::Proto::Proto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x")
-{
- DefaultPseudoclientModes = "+";
- CanSVSNick = true;
- CanSNLine = true;
- CanSQLine = true;
- CanSQLineChannel = true;
- CanSZLine = true;
- CanSVSHold = true;
- MaxModes = 60;
+ /* ZLine if we can instead */
+ if (x->GetUser() == "*")
+ {
+ cidr a(x->GetHost());
+ if (a.valid())
+ {
+ IRCD->Send<messages::SZLine>(u, x);
+ return;
+ }
+ }
+
+ // Calculate the time left before this would expire, capping it at 2 days
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800)
+ timeleft = 172800;
+
+ Uplink::Send("AKILL", x->GetHost(), x->GetUser(), timeleft, x->GetBy(), Anope::CurTime, x->GetReason());
}
-void bahamut::Proto::SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf)
+void bahamut::senders::AkillDel::Send(XLine* x)
{
- if (Servers::Capab.count("TSMODE") > 0)
+ if (x->IsRegex() || x->HasNickOrReal())
+ return;
+
+ /* ZLine if we can instead */
+ if (x->GetUser() == "*")
{
- IRCMessage message(source, "MODE", dest->name, dest->creation_time);
- message.TokenizeAndPush(buf);
- Uplink::SendMessage(message);
+ cidr a(x->GetHost());
+ if (a.valid())
+ {
+ IRCD->Send<messages::SZLineDel>(x);
+ return;
+ }
}
- else
+
+ Uplink::Send("RAKKILL", x->GetHost(), x->GetUser());
+}
+
+void bahamut::senders::MessageChannel::Send(Channel* c)
+{
+ Anope::string modes = c->GetModes(true, true);
+ if (modes.empty())
+ modes = "+";
+ Uplink::Send("SJOIN", c->creation_time, c->name, modes, "");
+}
+
+void bahamut::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status)
+{
+ Uplink::Send(user, "SJOIN", c->creation_time, c->name);
+
+ if (status)
{
- IRCDProto::SendMode(source, dest, buf);
+ /* First save the channel status incase uc->Status == status */
+ ChannelStatus cs = *status;
+ /* If the user is internally on the channel with flags, kill them so that
+ * the stacker will allow this.
+ */
+ ChanUserContainer *uc = c->FindUser(user);
+ if (uc != NULL)
+ uc->status.Clear();
+
+ ServiceBot *setter = ServiceBot::Find(user->GetUID());
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
}
}
-void bahamut::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf)
+void bahamut::senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason)
{
- IRCMessage message(source, "SVSMODE", u->nick, u->timestamp);
- message.TokenizeAndPush(buf);
- Uplink::SendMessage(message);
+ Uplink::Send(source, "SVSKILL", target, reason);
+}
+
+/*
+ Note: if the stamp is null 0, the below usage is correct of Bahamut
+*/
+void bahamut::senders::Kill::Send(const MessageSource &source, User *user, const Anope::string &reason)
+{
+ Uplink::Send(source, "SVSKILL", user->nick, reason);
}
-void bahamut::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg)
+void bahamut::senders::Login::Send(User *u, NickServ::Nick *na)
{
- Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon);
}
-void bahamut::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg)
+void bahamut::senders::Logout::Send(User *u)
{
- Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1");
}
-/* SVSHOLD - set */
-void bahamut::Proto::SendSVSHold(const Anope::string &nick, time_t time)
+void bahamut::senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes)
{
- Uplink::Send(Me, "SVSHOLD", nick, time, "Being held for registered user");
+ IRCMessage message(source, "MODE", channel->name, channel->creation_time);
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
}
-/* SVSHOLD - release */
-void bahamut::Proto::SendSVSHoldDel(const Anope::string &nick)
+void bahamut::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes)
{
- Uplink::Send(Me, "SVSHOLD", nick, 0);
+ IRCMessage message(source, "SVSMODE", user->nick, user->timestamp);
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
}
-/* SQLINE */
-void bahamut::Proto::SendSQLine(User *, XLine *x)
+void bahamut::senders::NickIntroduction::Send(User *user)
{
- Uplink::Send(Me, "SQLINE", x->GetMask(), x->GetReason());
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send("NICK", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, user->server->GetName(), 0, 0, user->realname);
+}
+
+void bahamut::senders::NOOP::Send(Server* server, bool set)
+{
+ Uplink::Send("SVSNOOP", server->GetSID(), set ? "+" : "-");
+}
+
+void bahamut::senders::SGLine::Send(User*, XLine* x)
+{
+ Uplink::Send("SGLINE", x->GetMask().length(), x->GetMask() + ":" + x->GetReason());
}
-/* UNSLINE */
-void bahamut::Proto::SendSGLineDel(XLine *x)
+void bahamut::senders::SGLineDel::Send(XLine* x)
{
Uplink::Send("UNSGLINE", 0, x->GetMask());
}
-/* UNSZLINE */
-void bahamut::Proto::SendSZLineDel(XLine *x)
+void bahamut::senders::SQLine::Send(User*, XLine* x)
{
- /* this will likely fail so its only here for legacy */
- Uplink::Send("UNSZLINE", 0, x->GetHost());
- /* this is how we are supposed to deal with it */
- Uplink::Send("RAKILL", x->GetHost(), "*");
+ Uplink::Send(Me, "SQLINE", x->GetMask(), x->GetReason());
+}
+
+void bahamut::senders::SQLineDel::Send(XLine* x)
+{
+ Uplink::Send("UNSQLINE", x->GetMask());
}
-/* SZLINE */
-void bahamut::Proto::SendSZLine(User *, XLine *x)
+void bahamut::senders::SZLine::Send(User*, XLine* x)
{
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->GetExpires() - Anope::CurTime;
@@ -131,130 +203,69 @@ void bahamut::Proto::SendSZLine(User *, XLine *x)
Uplink::Send("AKILL", x->GetHost(), "*", timeleft, x->GetBy(), Anope::CurTime, x->GetReason());
}
-/* SVSNOOP */
-void bahamut::Proto::SendSVSNOOP(Server *server, bool set)
+void bahamut::senders::SZLineDel::Send(XLine* x)
{
- Uplink::Send("SVSNOOP", server->GetName(), set ? "+" : "-");
+ /* this will likely fail so its only here for legacy */
+ Uplink::Send("UNSZLINE", 0, x->GetHost());
+ /* this is how we are supposed to deal with it */
+ Uplink::Send("RAKILL", x->GetHost(), "*");
}
-/* SGLINE */
-void bahamut::Proto::SendSGLine(User *, XLine *x)
+void bahamut::senders::SVSHold::Send(const Anope::string& nick, time_t t)
{
- Uplink::Send("SGLINE", x->GetMask().length(), x->GetMask() + ":" + x->GetReason());
+ Uplink::Send(Me, "SVSHOLD", nick, t, "Being held for registered user");
}
-/* RAKILL */
-void bahamut::Proto::SendAkillDel(XLine *x)
+void bahamut::senders::SVSHoldDel::Send(const Anope::string& nick)
{
- if (x->IsRegex() || x->HasNickOrReal())
- return;
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr a(x->GetHost());
- if (a.valid())
- {
- IRCD->SendSZLineDel(x);
- return;
- }
- }
-
- Uplink::Send("RAKKILL", x->GetHost(), x->GetUser());
+ Uplink::Send(Me, "SVSHOLD", nick, 0);
}
-/* TOPIC */
-void bahamut::Proto::SendTopic(const MessageSource &source, Channel *c)
+void bahamut::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts)
{
- Uplink::Send(source, "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
+ Uplink::Send("SVSNICK", u->GetUID(), newnick, ts);
}
-/* UNSQLINE */
-void bahamut::Proto::SendSQLineDel(XLine *x)
+void bahamut::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
{
- Uplink::Send("UNSQLINE", x->GetMask());
+ Uplink::Send(source, "TOPIC", channel->name, topic_setter, topic_ts, topic);
}
-/* JOIN - SJOIN */
-void bahamut::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status)
+void bahamut::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg)
{
- Uplink::Send(user, "SJOIN", c->creation_time, c->name);
-
- if (status)
- {
- /* First save the channel status incase uc->Status == status */
- ChannelStatus cs = *status;
- /* If the user is internally on the channel with flags, kill them so that
- * the stacker will allow this.
- */
- ChanUserContainer *uc = c->FindUser(user);
- if (uc != NULL)
- uc->status.Clear();
-
- ServiceBot *setter = ServiceBot::Find(user->GetUID());
- for (size_t i = 0; i < cs.Modes().length(); ++i)
- c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
-
- if (uc != NULL)
- uc->status = cs;
- }
+ Uplink::Send(source, "GLOBOPS", msg);
}
-void bahamut::Proto::SendAkill(User *u, XLine *x)
+#warning "not used"
+class ChannelModeFlood : public ChannelModeParam
{
- if (x->IsRegex() || x->HasNickOrReal())
- {
- if (!u)
- {
- /* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (x->GetManager()->Check(it->second, x))
- this->SendAkill(it->second, x);
- return;
- }
-
- XLine *old = x;
-
- if (old->GetManager()->HasEntry("*@" + u->host))
- return;
-
- /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */
- x = Serialize::New<XLine *>();
- x->SetMask("*@" + u->host);
- x->SetBy(old->GetBy());
- x->SetExpires(old->GetExpires());
- x->SetReason(old->GetReason());
- x->SetID(old->GetID());
- old->GetManager()->AddXLine(x);
-
- Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask();
- }
+ public:
+ ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
+ bool IsValid(Anope::string &value) const override
{
- cidr a(x->GetHost());
- if (a.valid())
+ try
{
- IRCD->SendSZLine(u, x);
- return;
+ Anope::string rest;
+ if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
+ return true;
}
- }
-
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->GetExpires() - Anope::CurTime;
- if (timeleft > 172800)
- timeleft = 172800;
+ catch (const ConvertException &) { }
- Uplink::Send("AKILL", x->GetHost(), x->GetUser(), timeleft, x->GetBy(), Anope::CurTime, x->GetReason());
-}
+ return false;
+ }
+};
-/*
- Note: if the stamp is null 0, the below usage is correct of Bahamut
-*/
-void bahamut::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf)
+bahamut::Proto::Proto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x")
{
- Uplink::Send(source, "SVSKILL", user->nick, buf);
+ DefaultPseudoclientModes = "+";
+ CanSVSNick = true;
+ CanSNLine = true;
+ CanSQLine = true;
+ CanSQLineChannel = true;
+ CanSZLine = true;
+ CanSVSHold = true;
+ MaxModes = 60;
}
void bahamut::Proto::SendBOB()
@@ -267,23 +278,11 @@ void bahamut::Proto::SendEOB()
Uplink::Send("BURST", 0);
}
-void bahamut::Proto::SendClientIntroduction(User *u)
-{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send("NICK", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, u->server->GetName(), 0, 0, u->realname);
-}
-
-/* SERVER */
-void bahamut::Proto::SendServer(Server *server)
-{
- Uplink::Send("SERVER", server->GetName(), server->GetHops(), server->GetDescription());
-}
-
-void bahamut::Proto::SendConnect()
+void bahamut::Proto::Handshake()
{
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS");
Uplink::Send("CAPAB", "SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3");
- SendServer(Me);
+ IRCD->Send<messages::MessageServer>(Me);
/*
* SVINFO
* parv[0] = sender prefix
@@ -296,24 +295,6 @@ void bahamut::Proto::SendConnect()
this->SendBOB();
}
-void bahamut::Proto::SendChannel(Channel *c)
-{
- Anope::string modes = c->GetModes(true, true);
- if (modes.empty())
- modes = "+";
- Uplink::Send("SJOIN", c->creation_time, c->name, modes, "");
-}
-
-void bahamut::Proto::SendLogin(User *u, NickServ::Nick *)
-{
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon);
-}
-
-void bahamut::Proto::SendLogout(User *u)
-{
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1");
-}
-
void bahamut::Burst::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
Server *s = source.GetServer();
@@ -522,6 +503,45 @@ class ProtoBahamut : public Module
bahamut::SJoin message_sjoin;
bahamut::Topic message_topic;
+ /* Core message senders */
+ rfc1459::senders::GlobalNotice sender_global_notice;
+ rfc1459::senders::GlobalPrivmsg sender_global_privmsg;
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::MessageServer sender_server;
+ rfc1459::senders::SQuit sender_squit;
+
+ /* Our message senders */
+ bahamut::senders::Akill sender_akill;
+ bahamut::senders::AkillDel sender_akill_del;
+ bahamut::senders::MessageChannel sender_channel;
+ bahamut::senders::Join sender_join;
+ bahamut::senders::Kill sender_kill;
+ bahamut::senders::Login sender_login;
+ bahamut::senders::Logout sender_logout;
+ bahamut::senders::ModeChannel sender_mode_channel;
+ bahamut::senders::ModeUser sender_mode_user;
+ bahamut::senders::NickIntroduction sender_nickintroduction;
+ bahamut::senders::NOOP sender_noop;
+ bahamut::senders::SGLine sender_sgline;
+ bahamut::senders::SGLineDel sender_sgline_del;
+ bahamut::senders::SQLine sender_sqline;
+ bahamut::senders::SQLineDel sender_sqline_del;
+ bahamut::senders::SZLine sender_szline;
+ bahamut::senders::SZLineDel sender_szline_del;
+ bahamut::senders::SVSHold sender_svshold;
+ bahamut::senders::SVSHoldDel sender_svsholddel;
+ bahamut::senders::SVSNick sender_svsnick;
+ bahamut::senders::Topic sender_topic;
+ bahamut::senders::Wallops sender_wallops;
+
public:
ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
, EventHook<Event::UserNickChange>(this)
@@ -552,13 +572,55 @@ class ProtoBahamut : public Module
, message_server(this)
, message_sjoin(this)
, message_topic(this)
+
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_kill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_channel(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_noop(this)
+ , sender_topic(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sgline(this)
+ , sender_sgline_del(this)
+ , sender_sqline(this)
+ , sender_sqline_del(this)
+ , sender_szline(this)
+ , sender_szline_del(this)
+ , sender_squit(this)
+ , sender_svshold(this)
+ , sender_svsholddel(this)
+ , sender_svsnick(this)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoBahamut()
{
+ IRCD = nullptr;
}
void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
- IRCD->SendLogout(u);
+ sender_logout.Send(u);
}
};
diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp
index 4488f5425..a808bb594 100644
--- a/modules/protocol/charybdis.cpp
+++ b/modules/protocol/charybdis.cpp
@@ -23,7 +23,6 @@
#include "modules/sasl.h"
#include "modules/protocol/hybrid.h"
#include "modules/protocol/charybdis.h"
-#include "modules/protocol/ratbox.h"
#include "modules/chanserv/mode.h"
static Anope::string UplinkSID;
@@ -39,9 +38,57 @@ class ChannelModeLargeBan : public ChannelMode
}
};
+void charybdis::senders::NickIntroduction::Send(User *user)
+{
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send(Me, "EUID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, 0, user->GetUID(), "*", "*", user->realname);
+}
+void charybdis::senders::SASL::Send(const ::SASL::Message& message)
+{
+ Server *s = Server::Find(message.target.substr(0, 3));
+ Uplink::Send(Me, "ENCAP", s ? s->GetName() : message.target.substr(0, 3), "SASL", message.source, message.target, message.type, message.data, message.ext.empty() ? "" : message.ext);
+}
-charybdis::Proto::Proto(Module *creator) : IRCDProto(creator, "Charybdis 3.4+")
- , ratbox("ratbox")
+void charybdis::senders::SASLMechanisms::Send(const std::vector<Anope::string>& mechanisms)
+{
+ Anope::string mechlist;
+
+ for (unsigned int i = 0; i < mechanisms.size(); ++i)
+ {
+ mechlist += "," + mechanisms[i];
+ }
+
+ Uplink::Send(Me, "ENCAP", "*", "MECHLIST", mechlist.empty() ? "" : mechlist.substr(1));
+}
+
+void charybdis::senders::SVSHold::Send(const Anope::string& nick, time_t delay)
+{
+ Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", delay, nick);
+}
+
+void charybdis::senders::SVSHoldDel::Send(const Anope::string& nick)
+{
+ Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", 0, nick);
+}
+
+void charybdis::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost)
+{
+ Server *s = Server::Find(uid.substr(0, 3));
+ Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc);
+}
+
+void charybdis::senders::VhostDel::Send(User* u)
+{
+ IRCD->Send<messages::VhostSet>(u, "", u->host);
+}
+
+void charybdis::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost)
+{
+ Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), vhost);
+}
+
+charybdis::Proto::Proto(Module *creator) : ts6::Proto(creator, "Charybdis 3.4+")
+ , ratbox(creator)
{
DefaultPseudoclientModes = "+oiS";
CanCertFP = true;
@@ -56,7 +103,7 @@ charybdis::Proto::Proto(Module *creator) : IRCDProto(creator, "Charybdis 3.4+")
MaxModes = 4;
}
-void charybdis::Proto::SendConnect()
+void charybdis::Proto::Handshake()
{
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
@@ -86,7 +133,7 @@ void charybdis::Proto::SendConnect()
Uplink::Send("CAPAB", "BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN KNOCK MLOCK QS RSFNC SERVICES TB UNKLN");
/* Make myself known to myself in the serverlist */
- SendServer(Me);
+ Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription());
/*
* Received: SVINFO 6 6 0 :1353235537
@@ -95,66 +142,9 @@ void charybdis::Proto::SendConnect()
* arg[2] = '0'
* arg[3] = server's idea of UTC time
*/
- Uplink::Send("SVINFO", 6, 6, Anope::CurTime);
-}
-
-void charybdis::Proto::SendClientIntroduction(User *u)
-{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send(Me, "EUID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, 0, u->GetUID(), "*", "*", u->realname);
-}
-
-void charybdis::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when)
-{
- Uplink::Send(Me, "ENCAP", u->server->GetName(), "RSFNC", u->GetUID(),
- newnick, when, u->timestamp);
+ Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
}
-void charybdis::Proto::SendSVSHold(const Anope::string &nick, time_t delay)
-{
- Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", delay, nick);
-}
-
-void charybdis::Proto::SendSVSHoldDel(const Anope::string &nick)
-{
- Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", 0, nick);
-}
-
-void charybdis::Proto::SendVhost(User *u, const Anope::string &ident, const Anope::string &host)
-{
- Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), host);
-}
-
-void charybdis::Proto::SendVhostDel(User *u)
-{
- this->SendVhost(u, "", u->host);
-}
-
-void charybdis::Proto::SendSASLMechanisms(std::vector<Anope::string> &mechanisms)
-{
- Anope::string mechlist;
-
- for (unsigned i = 0; i < mechanisms.size(); ++i)
- {
- mechlist += "," + mechanisms[i];
- }
-
- Uplink::Send(Me, "ENCAP", "*", "MECHLIST", mechlist.empty() ? "" : mechlist.substr(1));
-}
-
-void charybdis::Proto::SendSASLMessage(const SASL::Message &message)
-{
- Server *s = Server::Find(message.target.substr(0, 3));
- Uplink::Send(Me, "ENCAP", s ? s->GetName() : message.target.substr(0, 3), "SASL", message.source, message.target, message.type, message.data, message.ext.empty() ? "" : message.ext);
-}
-
-void charybdis::Proto::SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost)
-{
- Server *s = Server::Find(uid.substr(0, 3));
- Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc);
-}
-
-
void charybdis::Encap::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
// In a burst, states that the source user is logged in as the account.
@@ -228,7 +218,7 @@ void charybdis::ServerMessage::Run(MessageSource &source, const std::vector<Anop
if (params[1] != "1")
return;
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
// we can't use this function from ratbox because we set a local variable here
@@ -282,6 +272,48 @@ class ProtoCharybdis : public Module
hybrid::TMode message_tmode;
ratbox::UID message_uid;
+ /* Core message senders */
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::Kill sender_svskill;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::ModeUser sender_mode_user;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::SQuit sender_squit;
+
+ hybrid::senders::Akill sender_akill;
+ hybrid::senders::AkillDel sender_akill_del;
+ hybrid::senders::MessageChannel sender_channel;
+ hybrid::senders::GlobalNotice sender_global_notice;
+ hybrid::senders::GlobalPrivmsg sender_global_privmsg;
+ hybrid::senders::Join sender_join;
+ hybrid::senders::MessageServer sender_server;
+ hybrid::senders::SGLine sender_sgline;
+ hybrid::senders::SGLineDel sender_sgline_del;
+ hybrid::senders::SVSHold sender_svshold;
+ hybrid::senders::SVSHoldDel sender_svsholddel;
+
+ ratbox::senders::Login sender_login;
+ ratbox::senders::Logout sender_logout;
+ ratbox::senders::SQLine sender_sqline;
+ ratbox::senders::SQLineDel sender_sqline_del;
+ ratbox::senders::SVSNick sender_svsnick;
+ ratbox::senders::Topic sender_topic;
+ ratbox::senders::Wallops sender_wallops;
+
+ charybdis::senders::NickIntroduction sender_nickintroduction;
+ charybdis::senders::SASL sender_sasl;
+ charybdis::senders::SASLMechanisms sender_sasl_mechs;
+ charybdis::senders::SVSLogin sender_svslogin;
+ charybdis::senders::VhostDel sender_vhost_del;
+ charybdis::senders::VhostSet sender_vhost_set;
+
bool use_server_side_mlock;
public:
@@ -322,7 +354,51 @@ class ProtoCharybdis : public Module
, message_tb(this)
, message_tmode(this)
, message_uid(this)
+
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sasl(this)
+ , sender_sasl_mechs(this)
+ , sender_sgline(this)
+ , sender_sgline_del(this)
+ , sender_sqline(this)
+ , sender_sqline_del(this)
+ , sender_squit(this)
+ , sender_svshold(this)
+ , sender_svsholddel(this)
+ , sender_svslogin(this)
+ , sender_svsnick(this)
+ , sender_topic(this)
+ , sender_vhost_del(this)
+ , sender_vhost_set(this)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoCharybdis()
{
+ IRCD = nullptr;
}
void OnReload(Configuration::Conf *conf) override
diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp
index 922083587..2cb508f0e 100644
--- a/modules/protocol/hybrid.cpp
+++ b/modules/protocol/hybrid.cpp
@@ -18,134 +18,14 @@
* along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-/* Dependencies: anope_protocol.rfc1459 */
+/* Dependencies: anope_protocol.rfc1459,anope_protocol.ts6 */
#include "module.h"
#include "modules/protocol/hybrid.h"
static Anope::string UplinkSID;
-
-ServiceBot *hybrid::Proto::FindIntroduced()
-{
- ServiceBot *bi = Config->GetClient("OperServ");
- if (bi && bi->introduced)
- return bi;
-
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u = it->second;
- if (u->type == UserType::BOT)
- {
- bi = anope_dynamic_static_cast<ServiceBot *>(u);
- if (bi->introduced)
- return bi;
- }
- }
-
- return NULL;
-}
-
-void hybrid::Proto::SendSVSKill(const MessageSource &source, User *u, const Anope::string &buf)
-{
- IRCDProto::SendSVSKill(source, u, buf);
- u->KillInternal(source, buf);
-}
-
-hybrid::Proto::Proto(Module *creator) : IRCDProto(creator, "Hybrid 8.2.x")
-{
- DefaultPseudoclientModes = "+oi";
- CanSVSNick = true;
- CanSVSHold = true;
- CanSVSJoin = true;
- CanSNLine = true;
- CanSQLine = true;
- CanSQLineChannel = true;
- CanSZLine = true;
- CanCertFP = true;
- CanSetVHost = true;
- RequiresID = true;
- MaxModes = 6;
-}
-
-void hybrid::Proto::SendInvite(const MessageSource &source, Channel *c, User *u)
-{
- Uplink::Send(source, "INVITE", u->GetUID(), c->name, c->creation_time);
-}
-
-void hybrid::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "NOTICE", "$$" + dest->GetName(), msg);
-}
-
-void hybrid::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "PRIVMSG", "$$" + dest->GetName(), msg);
-}
-
-void hybrid::Proto::SendSQLine(User *, XLine *x)
-{
- Uplink::Send(FindIntroduced(), "RESV", "*", x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetMask(), x->GetReason());
-}
-
-void hybrid::Proto::SendSGLineDel(XLine *x)
-{
- Uplink::Send(Config->GetClient("OperServ"), "UNXLINE", "*", x->GetMask());
-}
-
-void hybrid::Proto::SendSGLine(User *, XLine *x)
-{
- Uplink::Send(Config->GetClient("OperServ"), "XLINE", "*", x->GetMask(), x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetReason());
-}
-
-void hybrid::Proto::SendSZLineDel(XLine *x)
-{
- Uplink::Send(Config->GetClient("OperServ"), "UNDLINE", "*", x->GetHost());
-}
-
-void hybrid::Proto::SendSZLine(User *, XLine *x)
-{
- /* Calculate the time left before this would expire, capping it at 2 days */
- time_t timeleft = x->GetExpires() - Anope::CurTime;
-
- if (timeleft > 172800 || !x->GetExpires())
- timeleft = 172800;
-
- Uplink::Send(Config->GetClient("OperServ"), "DLINE", "*", timeleft, x->GetHost(), x->GetReason());
-}
-
-void hybrid::Proto::SendAkillDel(XLine *x)
-{
- if (x->IsRegex() || x->HasNickOrReal())
- return;
-
- Uplink::Send(Config->GetClient("OperServ"), "UNKLINE", "*", x->GetUser(), x->GetHost());
-}
-
-void hybrid::Proto::SendSQLineDel(XLine *x)
-{
- Uplink::Send(Config->GetClient("OperServ"), "UNRESV", "*", x->GetMask());
-}
-
-void hybrid::Proto::SendJoin(User *u, Channel *c, const ChannelStatus *status)
-{
- /*
- * Note that we must send our modes with the SJOIN and can not add them to the
- * mode stacker because ircd-hybrid does not allow *any* client to op itself
- */
- Uplink::Send("SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), (status != NULL ? status->BuildModePrefixList() : "") + u->GetUID());
-
- /* And update our internal status for this user since this is not going through our mode handling system */
- if (status)
- {
- ChanUserContainer *uc = c->FindUser(u);
-
- if (uc)
- uc->status = *status;
- }
-}
-
-void hybrid::Proto::SendAkill(User *u, XLine *x)
+void hybrid::senders::Akill::Send(User* u, XLine* x)
{
if (x->IsRegex() || x->HasNickOrReal())
{
@@ -157,7 +37,7 @@ void hybrid::Proto::SendAkill(User *u, XLine *x)
*/
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
if (x->GetManager()->Check(it->second, x))
- this->SendAkill(it->second, x);
+ this->Send(it->second, x);
return;
}
@@ -191,111 +71,132 @@ void hybrid::Proto::SendAkill(User *u, XLine *x)
Uplink::Send(Config->GetClient("OperServ"), "KLINE", timeleft, x->GetUser(), x->GetHost(), x->GetReason());
}
-void hybrid::Proto::SendServer(Server *server)
+void hybrid::senders::AkillDel::Send(XLine* x)
{
- if (server == Me)
- Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription());
- else
- Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription());
+ if (x->IsRegex() || x->HasNickOrReal())
+ return;
+
+ Uplink::Send(Config->GetClient("OperServ"), "UNKLINE", "*", x->GetUser(), x->GetHost());
}
-void hybrid::Proto::SendConnect()
+void hybrid::senders::MessageChannel::Send(Channel* c)
{
- Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
-
- /*
- * As of January 13, 2016, ircd-hybrid-8 supports the following capabilities
- * which are required to work with IRC-services:
- *
- * QS - Can handle quit storm removal
- * EX - Can do channel +e exemptions
- * IE - Can do invite exceptions
- * CHW - Can do channel wall @#
- * TBURST - Supports topic burst
- * ENCAP - Supports ENCAP
- * HOPS - Supports HalfOps
- * SVS - Supports services
- * EOB - Supports End Of Burst message
- */
- Uplink::Send("CAPAB", "QS EX CHW IE ENCAP TBURST SVS HOPS EOB");
+ Anope::string modes = c->GetModes(true, true);
- SendServer(Me);
+ if (modes.empty())
+ modes = "+";
- Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
+ Uplink::Send("SJOIN", c->creation_time, c->name, modes, "");
}
-void hybrid::Proto::SendClientIntroduction(User *u)
+void hybrid::senders::GlobalNotice::Send(const MessageSource &source, Server *dest, const Anope::string &msg)
{
- Anope::string modes = "+" + u->GetModes();
+ Uplink::Send(source, "NOTICE", "$$" + dest->GetName(), msg);
+}
- Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, "0.0.0.0", u->GetUID(), "*", u->realname);
+void hybrid::senders::GlobalPrivmsg::Send(const MessageSource& source, Server* dest, const Anope::string& msg)
+{
+ Uplink::Send(source, "PRIVMSG", "$$" + dest->GetName(), msg);
}
-void hybrid::Proto::SendEOB()
+void hybrid::senders::Invite::Send(const MessageSource &source, Channel *chan, User *user)
{
- Uplink::Send(Me, "EOB");
+ Uplink::Send(source, "INVITE", user->GetUID(), chan->name, chan->creation_time);
}
-void hybrid::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf)
+void hybrid::senders::Join::Send(User* u, Channel* c, const ChannelStatus* status)
{
- IRCMessage message(source, "SVSMODE", u->GetUID(), u->timestamp);
- message.TokenizeAndPush(buf);
- Uplink::SendMessage(message);
+ /*
+ * Note that we must send our modes with the SJOIN and can not add them to the
+ * mode stacker because ircd-hybrid does not allow *any* client to op itself
+ */
+ Uplink::Send("SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), (status != NULL ? status->BuildModePrefixList() : "") + u->GetUID());
+
+ /* And update our internal status for this user since this is not going through our mode handling system */
+ if (status)
+ {
+ ChanUserContainer *uc = c->FindUser(u);
+
+ if (uc)
+ uc->status = *status;
+ }
}
-void hybrid::Proto::SendLogin(User *u, NickServ::Nick *na)
+void hybrid::senders::Login::Send(User *u, NickServ::Nick *na)
{
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", na->GetAccount()->GetDisplay());
}
-void hybrid::Proto::SendLogout(User *u)
+void hybrid::senders::Logout::Send(User *u)
{
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d *");
}
-void hybrid::Proto::SendChannel(Channel *c)
+void hybrid::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes)
{
- Anope::string modes = c->GetModes(true, true);
+ IRCMessage message(source, "SVSMODE", user->GetUID(), user->timestamp);
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
+}
- if (modes.empty())
- modes = "+";
+void hybrid::senders::NickIntroduction::Send(User *user)
+{
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send(Me, "UID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, "0.0.0.0", user->GetUID(), "*", user->realname);
+}
- Uplink::Send("SJOIN", c->creation_time, c->name, modes, "");
+void hybrid::senders::MessageServer::Send(Server* server)
+{
+ Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription());
+}
+
+void hybrid::senders::SGLine::Send(User*, XLine* x)
+{
+ Uplink::Send(Config->GetClient("OperServ"), "XLINE", "*", x->GetMask(), x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetReason());
}
-void hybrid::Proto::SendTopic(const MessageSource &source, Channel *c)
+void hybrid::senders::SGLineDel::Send(XLine* x)
{
- Uplink::Send(source, "TBURST", c->creation_time, c->name, c->topic_ts, c->topic_setter, c->topic);
+ Uplink::Send(Config->GetClient("OperServ"), "UNXLINE", "*", x->GetMask());
}
-void hybrid::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when)
+void hybrid::senders::SQLine::Send(User*, XLine* x)
{
- Uplink::Send(Me, "SVSNICK", u->GetUID(), newnick, when);
+#warning "findintroduced"
+ //Uplink::Send(FindIntroduced(), "RESV", "*", x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetMask(), x->GetReason());
}
-void hybrid::Proto::SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &)
+void hybrid::senders::SQLineDel::Send(XLine* x)
{
- Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
+ Uplink::Send(Config->GetClient("OperServ"), "UNRESV", "*", x->GetMask());
}
-void hybrid::Proto::SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param)
+void hybrid::senders::SZLine::Send(User*, XLine* x)
{
- if (!param.empty())
- Uplink::Send(source, "SVSPART", u->GetUID(), chan, param);
- else
- Uplink::Send(source, "SVSPART", u->GetUID(), chan);
+ /* Calculate the time left before this would expire, capping it at 2 days */
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+
+ if (timeleft > 172800 || !x->GetExpires())
+ timeleft = 172800;
+
+ Uplink::Send(Config->GetClient("OperServ"), "DLINE", "*", timeleft, x->GetHost(), x->GetReason());
}
-void hybrid::Proto::SendSVSHold(const Anope::string &nick, time_t t)
+void hybrid::senders::SZLineDel::Send(XLine* x)
+{
+ Uplink::Send(Config->GetClient("OperServ"), "UNDLINE", "*", x->GetHost());
+}
+
+void hybrid::senders::SVSHold::Send(const Anope::string&, time_t)
{
#if 0
XLine x(nick, Me->GetName(), Anope::CurTime + t, "Being held for registered user");
this->SendSQLine(NULL, &x);
#endif
}
-#warning "xline on stack"
-void hybrid::Proto::SendSVSHoldDel(const Anope::string &nick)
+#warning "xline on stack"
+void hybrid::senders::SVSHoldDel::Send(const Anope::string&)
{
#if 0
XLine x(nick);
@@ -303,19 +204,113 @@ void hybrid::Proto::SendSVSHoldDel(const Anope::string &nick)
#endif
}
-void hybrid::Proto::SendVhost(User *u, const Anope::string &ident, const Anope::string &host)
+void hybrid::senders::SVSJoin::Send(const MessageSource& source, User* u, const Anope::string& chan, const Anope::string& key)
+{
+ Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
+}
+
+void hybrid::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts)
{
- u->SetMode(Config->GetClient("HostServ"), "CLOAK", host);
+ Uplink::Send(Me, "SVSNICK", u->GetUID(), newnick, ts);
}
-void hybrid::Proto::SendVhostDel(User *u)
+void hybrid::senders::SVSPart::Send(const MessageSource& source, User* u, const Anope::string& chan, const Anope::string& reason)
+{
+ if (!reason.empty())
+ Uplink::Send(source, "SVSPART", u->GetUID(), chan, reason);
+ else
+ Uplink::Send(source, "SVSPART", u->GetUID(), chan);
+}
+
+void hybrid::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
+{
+ Uplink::Send(source, "TBURST", channel->creation_time, channel->name, topic_ts, topic_setter, topic);
+}
+
+void hybrid::senders::VhostDel::Send(User* u)
{
u->RemoveMode(Config->GetClient("HostServ"), "CLOAK", u->host);
}
+void hybrid::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost)
+{
+ u->SetMode(Config->GetClient("HostServ"), "CLOAK", vhost);
+}
+
+void hybrid::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg)
+{
+ Uplink::Send(source, "GLOBOPS", msg);
+}
+
+ServiceBot *hybrid::Proto::FindIntroduced()
+{
+ ServiceBot *bi = Config->GetClient("OperServ");
+ if (bi && bi->introduced)
+ return bi;
+
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+ if (u->type == UserType::BOT)
+ {
+ bi = anope_dynamic_static_cast<ServiceBot *>(u);
+ if (bi->introduced)
+ return bi;
+ }
+ }
+
+ return NULL;
+}
+
+hybrid::Proto::Proto(Module *creator) : ts6::Proto(creator, "Hybrid 8.2.x")
+{
+ DefaultPseudoclientModes = "+oi";
+ CanSVSNick = true;
+ CanSVSHold = true;
+ CanSVSJoin = true;
+ CanSNLine = true;
+ CanSQLine = true;
+ CanSQLineChannel = true;
+ CanSZLine = true;
+ CanCertFP = true;
+ CanSetVHost = true;
+ RequiresID = true;
+ MaxModes = 6;
+}
+
+void hybrid::Proto::Handshake()
+{
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
+
+ /*
+ * As of January 13, 2016, ircd-hybrid-8 supports the following capabilities
+ * which are required to work with IRC-services:
+ *
+ * QS - Can handle quit storm removal
+ * EX - Can do channel +e exemptions
+ * IE - Can do invite exceptions
+ * CHW - Can do channel wall @#
+ * TBURST - Supports topic burst
+ * ENCAP - Supports ENCAP
+ * HOPS - Supports HalfOps
+ * SVS - Supports services
+ * EOB - Supports End Of Burst message
+ */
+ Uplink::Send("CAPAB", "QS EX CHW IE ENCAP TBURST SVS HOPS EOB");
+
+ Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription());
+
+ Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
+}
+
+void hybrid::Proto::SendEOB()
+{
+ Uplink::Send(Me, "EOB");
+}
+
bool hybrid::Proto::IsIdentValid(const Anope::string &ident)
{
- if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
+ if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned int>("userlen"))
return false;
Anope::string chars = "~}|{ `_^]\\[ .-$";
@@ -410,7 +405,7 @@ void hybrid::ServerMessage::Run(MessageSource &source, const std::vector<Anope::
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
void hybrid::SID::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -425,7 +420,7 @@ void hybrid::SID::Run(MessageSource &source, const std::vector<Anope::string> &p
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]);
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
void hybrid::SJoin::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -621,6 +616,45 @@ class ProtoHybrid : public Module
hybrid::TMode message_tmode;
hybrid::UID message_uid;
+ /* Core message senders */
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::Kill sender_svskill;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::SQuit sender_squit;
+
+ hybrid::senders::Akill sender_akill;
+ hybrid::senders::AkillDel sender_akill_del;
+ hybrid::senders::MessageChannel sender_channel;
+ hybrid::senders::GlobalNotice sender_global_notice;
+ hybrid::senders::GlobalPrivmsg sender_global_privmsg;
+ hybrid::senders::Invite sender_invite;
+ hybrid::senders::Join sender_join;
+ hybrid::senders::Login sender_login;
+ hybrid::senders::Logout sender_logout;
+ hybrid::senders::ModeUser sender_mode_user;
+ hybrid::senders::NickIntroduction sender_nickintroduction;
+ hybrid::senders::MessageServer sender_server;
+ hybrid::senders::SGLine sender_sgline;
+ hybrid::senders::SGLineDel sender_sgline_del;
+ hybrid::senders::SQLine sender_sqline;
+ hybrid::senders::SQLineDel sender_sqline_del;
+ hybrid::senders::SZLine sender_szline;
+ hybrid::senders::SZLineDel sender_szline_del;
+ hybrid::senders::SVSHold sender_svshold;
+ hybrid::senders::SVSHoldDel sender_svsholddel;
+ hybrid::senders::SVSNick sender_svsnick;
+ hybrid::senders::Topic sender_topic;
+ hybrid::senders::VhostDel sender_vhost_del;
+ hybrid::senders::VhostSet sender_vhost_set;
+ hybrid::senders::Wallops sender_wallops;
+
public:
ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
, EventHook<Event::UserNickChange>(this)
@@ -658,7 +692,50 @@ public:
, message_tmode(this)
, message_uid(this)
, message_certfp(this)
+
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sgline(this)
+ , sender_sgline_del(this)
+ , sender_sqline(this)
+ , sender_sqline_del(this)
+ , sender_szline(this)
+ , sender_szline_del(this)
+ , sender_squit(this)
+ , sender_svshold(this)
+ , sender_svsholddel(this)
+ , sender_svsnick(this)
+ , sender_topic(this)
+ , sender_vhost_del(this)
+ , sender_vhost_set(this)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoHybrid()
{
+ IRCD = nullptr;
}
void OnUserNickChange(User *u, const Anope::string &) override
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index a8caac27a..011ecfd13 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-/* Dependencies: anope_protocol.rfc1459 */
+/* Dependencies: anope_protocol.rfc1459,anope_protocol.ts6,anope_protocol.hybrid,anope_protocol.bahamut */
#include "module.h"
#include "modules/sasl.h"
@@ -25,6 +25,8 @@
#include "modules/chanserv/set.h"
#include "modules/protocol/rfc1459.h"
#include "modules/protocol/inspircd20.h"
+#include "modules/protocol/bahamut.h"
+#include "modules/protocol/hybrid.h"
struct SASLUser
{
@@ -37,129 +39,7 @@ static std::list<SASLUser> saslusers;
static Anope::string rsquit_server, rsquit_id;
static unsigned int spanningtree_proto_ver = 0;
-void inspircd20::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf)
-{
- IRCDProto::SendSVSKill(source, user, buf);
- user->KillInternal(source, buf);
-}
-
-void inspircd20::Proto::SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent)
-{
- if (!Servers::Capab.count("CHGIDENT"))
- Log() << "CHGIDENT not loaded!";
- else
- Uplink::Send(Me, "CHGIDENT", nick, vIdent);
-}
-
-void inspircd20::Proto::SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost)
-{
- if (!Servers::Capab.count("CHGHOST"))
- Log() << "CHGHOST not loaded!";
- else
- Uplink::Send(Me, "CHGHOST", nick, vhost);
-}
-
-void inspircd20::Proto::SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason)
-{
- Uplink::Send(Me, "ADDLINE", xtype, mask, addedby, Anope::CurTime, duration, reason);
-}
-
-void inspircd20::Proto::SendDelLine(const Anope::string &xtype, const Anope::string &mask)
-{
- Uplink::Send(Me, "DELLINE", xtype, mask);
-}
-
-inspircd20::Proto::Proto(Module *creator) : IRCDProto(creator, "InspIRCd 2.0")
-{
- DefaultPseudoclientModes = "+I";
- CanSVSNick = true;
- CanSVSJoin = true;
- CanSetVHost = true;
- CanSetVIdent = true;
- CanSQLine = true;
- CanSZLine = true;
- CanSVSHold = true;
- CanCertFP = true;
- RequiresID = true;
- MaxModes = 20;
-}
-
-void inspircd20::Proto::SendConnect()
-{
- Uplink::Send("CAPAB START 1202");
- Uplink::Send("CAPAB CAPABILITIES :PROTOCOL=1202");
- Uplink::Send("CAPAB END");
- SendServer(Me);
-}
-
-void inspircd20::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
-}
-
-void inspircd20::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
-}
-
-void inspircd20::Proto::SendAkillDel(XLine *x)
-{
- /* InspIRCd may support regex bans */
- if (x->IsRegex() && Servers::Capab.count("RLINE"))
- {
- Anope::string mask = x->GetMask();
- size_t h = mask.find('#');
- if (h != Anope::string::npos)
- mask = mask.replace(h, 1, ' ');
- SendDelLine("R", mask);
- return;
- }
- else if (x->IsRegex() || x->HasNickOrReal())
- return;
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr addr(x->GetHost());
- if (addr.valid())
- {
- IRCD->SendSZLineDel(x);
- return;
- }
- }
-
- SendDelLine("G", x->GetUser() + "@" + x->GetHost());
-}
-
-void inspircd20::Proto::SendTopic(const MessageSource &source, Channel *c)
-{
- if (Servers::Capab.count("SVSTOPIC"))
- {
- Uplink::Send(c->ci->WhoSends(), "SVSTOPIC", c->name, c->topic_ts, c->topic_setter, c->topic);
- }
- else
- {
- /* If the last time a topic was set is after the TS we want for this topic we must bump this topic's timestamp to now */
- time_t ts = c->topic_ts;
- if (c->topic_time > ts)
- ts = Anope::CurTime;
- /* But don't modify c->topic_ts, it should remain set to the real TS we want as ci->last_topic_time pulls from it */
- Uplink::Send(source, "FTOPIC", c->name, ts, c->topic_setter, c->topic);
- }
-}
-
-void inspircd20::Proto::SendVhostDel(User *u)
-{
- if (u->HasMode("CLOAK"))
- this->SendChgHostInternal(u->nick, u->chost);
- else
- this->SendChgHostInternal(u->nick, u->host);
-
- if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent())
- this->SendChgIdentInternal(u->nick, u->GetIdent());
-}
-
-void inspircd20::Proto::SendAkill(User *u, XLine *x)
+void inspircd20::senders::Akill::Send(User* u, XLine* x)
{
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->GetExpires() - Anope::CurTime;
@@ -173,7 +53,7 @@ void inspircd20::Proto::SendAkill(User *u, XLine *x)
size_t h = mask.find('#');
if (h != Anope::string::npos)
mask = mask.replace(h, 1, ' ');
- SendAddLine("R", mask, timeleft, x->GetBy(), x->GetReason());
+ proto->SendAddLine("R", mask, timeleft, x->GetBy(), x->GetReason());
return;
}
else if (x->IsRegex() || x->HasNickOrReal())
@@ -183,7 +63,7 @@ void inspircd20::Proto::SendAkill(User *u, XLine *x)
/* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
if (x->GetManager()->Check(it->second, x))
- this->SendAkill(it->second, x);
+ this->Send(it->second, x);
return;
}
@@ -209,70 +89,49 @@ void inspircd20::Proto::SendAkill(User *u, XLine *x)
cidr addr(x->GetHost());
if (addr.valid())
{
- IRCD->SendSZLine(u, x);
+ IRCD->Send<messages::SZLine>(u, x);
return;
}
}
- SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->GetBy(), x->GetReason());
+ proto->SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->GetBy(), x->GetReason());
}
-void inspircd20::Proto::SendNumeric(int numeric, User *dest, IRCMessage &message)
+void inspircd20::senders::AkillDel::Send(XLine* x)
{
- std::vector<Anope::string> params = message.GetParameters();
- if (params.empty())
+ /* InspIRCd may support regex bans */
+ if (x->IsRegex() && Servers::Capab.count("RLINE"))
+ {
+ Anope::string mask = x->GetMask();
+ size_t h = mask.find('#');
+ if (h != Anope::string::npos)
+ mask = mask.replace(h, 1, ' ');
+ proto->SendDelLine("R", mask);
+ return;
+ }
+ else if (x->IsRegex() || x->HasNickOrReal())
return;
- /* First parameter is the UID, change it to nick because it is pushed */
- params[0] = dest->nick;
-
- IRCMessage m(message.GetSource(), message.GetCommand());
- for (const Anope::string &s : params)
- m.Push(s);
-
- Uplink::Send("PUSH", dest->GetUID(), Format(m));
-}
-
-void inspircd20::Proto::SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf)
-{
- IRCMessage message(source, "FMODE", dest->name, dest->creation_time);
- message.TokenizeAndPush(buf);
- Uplink::SendMessage(message);
-}
-
-void inspircd20::Proto::SendClientIntroduction(User *u)
-{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send(Me, "UID", u->GetUID(), u->timestamp, u->nick, u->host, u->host, u->GetIdent(), "0.0.0.0", u->timestamp, modes, u->realname);
- if (modes.find('o') != Anope::string::npos)
- Uplink::Send(u, "OPERTYPE", "services");
-}
+ /* ZLine if we can instead */
+ if (x->GetUser() == "*")
+ {
+ cidr addr(x->GetHost());
+ if (addr.valid())
+ {
+ IRCD->Send<messages::SZLineDel>(x);
+ return;
+ }
+ }
-/* SERVER services-dev.chatspike.net password 0 :Description here */
-void inspircd20::Proto::SendServer(Server *server)
-{
- /* if rsquit is set then we are waiting on a squit */
- if (rsquit_id.empty() && rsquit_server.empty())
- Uplink::Send("SERVER", server->GetName(), Config->Uplinks[Anope::CurrentUplink].password, server->GetHops(), server->GetSID(), server->GetDescription());
+ proto->SendDelLine("G", x->GetUser() + "@" + x->GetHost());
}
-void inspircd20::Proto::SendSquit(Server *s, const Anope::string &message)
+void inspircd20::senders::MessageChannel::Send(Channel* c)
{
- if (s != Me)
- {
- rsquit_id = s->GetSID();
- rsquit_server = s->GetName();
-
- Uplink::Send("RSQUIT", s->GetName(), message);
- }
- else
- {
- Uplink::Send("SQUIT", s->GetName(), message);
- }
+ Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), "");
}
-/* JOIN */
-void inspircd20::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status)
+void inspircd20::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status)
{
Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), "," + user->GetUID());
@@ -300,159 +159,264 @@ void inspircd20::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *st
}
}
-/* UNSQLINE */
-void inspircd20::Proto::SendSQLineDel(XLine *x)
+void inspircd20::senders::Login::Send(User *u, NickServ::Nick *na)
{
- SendDelLine("Q", x->GetMask());
+ /* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */
+ if (na->GetAccount()->IsUnconfirmed())
+ return;
+
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay());
}
-/* SQLINE */
-void inspircd20::Proto::SendSQLine(User *, XLine *x)
+void inspircd20::senders::Logout::Send(User *u)
{
- // Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = x->GetExpires() - Anope::CurTime;
- if (timeleft > 172800 || !x->GetExpires())
- timeleft = 172800;
- SendAddLine("Q", x->GetMask(), timeleft, x->GetBy(), x->GetReason());
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", "");
}
-void inspircd20::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost)
+void inspircd20::senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes)
{
- if (!vIdent.empty())
- this->SendChgIdentInternal(u->nick, vIdent);
- if (!vhost.empty())
- this->SendChgHostInternal(u->nick, vhost);
+ IRCMessage message(source, "FMODE", channel->name, channel->creation_time);
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
}
-/* SVSHOLD - set */
-void inspircd20::Proto::SendSVSHold(const Anope::string &nick, time_t t)
+void inspircd20::senders::NickIntroduction::Send(User *user)
{
- Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick, t, "Being held for registered user");
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send(Me, "UID", user->GetUID(), user->timestamp, user->nick, user->host, user->host, user->GetIdent(), "0.0.0.0", user->timestamp, modes, user->realname);
+ if (modes.find('o') != Anope::string::npos)
+ Uplink::Send(user, "OPERTYPE", "services");
}
-/* SVSHOLD - release */
-void inspircd20::Proto::SendSVSHoldDel(const Anope::string &nick)
+
+void inspircd20::senders::SASL::Send(const ::SASL::Message& message)
{
- Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick);
+ if (!message.ext.empty())
+ Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL",
+ message.source, message.target,
+ message.type, message.data, message.ext);
+ else
+ Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL",
+ message.source, message.target,
+ message.type, message.data);
}
-/* UNSZLINE */
-void inspircd20::Proto::SendSZLineDel(XLine *x)
+void inspircd20::senders::SASLMechanisms::Send(const std::vector<Anope::string>& mechanisms)
{
- SendDelLine("Z", x->GetHost());
+ Anope::string mechlist;
+ for (unsigned int i = 0; i < mechanisms.size(); ++i)
+ mechlist += "," + mechanisms[i];
+
+ Uplink::Send(Me, "METADATA", "*", "saslmechlist", mechlist.empty() ? "" : mechlist.substr(1));
+}
+
+void inspircd20::senders::MessageServer::Send(Server* server)
+{
+ /* if rsquit is set then we are waiting on a squit */
+ if (rsquit_id.empty() && rsquit_server.empty())
+ Uplink::Send("SERVER", server->GetName(), Config->Uplinks[Anope::CurrentUplink].password, server->GetHops(), server->GetSID(), server->GetDescription());
}
-/* SZLINE */
-void inspircd20::Proto::SendSZLine(User *, XLine *x)
+void inspircd20::senders::SQLine::Send(User*, XLine* x)
{
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->GetExpires() - Anope::CurTime;
if (timeleft > 172800 || !x->GetExpires())
timeleft = 172800;
- SendAddLine("Z", x->GetHost(), timeleft, x->GetBy(), x->GetReason());
+ proto->SendAddLine("Q", x->GetMask(), timeleft, x->GetBy(), x->GetReason());
}
-void inspircd20::Proto::SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &)
+void inspircd20::senders::SQLineDel::Send(XLine* x)
{
- Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
+ proto->SendDelLine("Q", x->GetMask());
}
-void inspircd20::Proto::SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param)
+void inspircd20::senders::SQuit::Send(Server *s, const Anope::string &message)
{
- if (!param.empty())
- Uplink::Send(source, "SVSPART", u->GetUID(), chan, param);
+ if (s != Me)
+ {
+ rsquit_id = s->GetSID();
+ rsquit_server = s->GetName();
+
+ Uplink::Send("RSQUIT", s->GetName(), message);
+ }
else
- Uplink::Send(source, "SVSPART", u->GetUID(), chan);
+ {
+ Uplink::Send("SQUIT", s->GetName(), message);
+ }
}
-void inspircd20::Proto::SendSWhois(const MessageSource &, const Anope::string &who, const Anope::string &mask)
+void inspircd20::senders::SZLine::Send(User*, XLine* x)
{
- User *u = User::Find(who);
+ // Calculate the time left before this would expire, capping it at 2 days
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+ if (timeleft > 172800 || !x->GetExpires())
+ timeleft = 172800;
+ proto->SendAddLine("Z", x->GetHost(), timeleft, x->GetBy(), x->GetReason());
+}
- Uplink::Send(Me, "METADATA", u->GetUID(), "swhois", mask);
+void inspircd20::senders::SZLineDel::Send(XLine* x)
+{
+ proto->SendDelLine("Z", x->GetHost());
}
-void inspircd20::Proto::SendBOB()
+void inspircd20::senders::SVSHold::Send(const Anope::string& nick, time_t t)
{
- Uplink::Send(Me, "BURST", Anope::CurTime);
- Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- Uplink::Send(Me, "VERSION", Anope::Format("Anope-{0} {1} {2} - {3} - Built: {4} - Flags: {5}",
- Anope::Version(), Me->GetName(), IRCD->GetProtocolName(), enc ? enc->name : "(none)", Anope::VersionBuildTime(), Anope::VersionFlags()));
+ Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick, t, "Being held for registered user");
}
-void inspircd20::Proto::SendEOB()
+void inspircd20::senders::SVSHoldDel::Send(const Anope::string& nick)
{
- Uplink::Send(Me, "ENDBURST");
+ Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick);
}
-void inspircd20::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf)
+void inspircd20::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost)
{
- if (Servers::Capab.count("GLOBOPS"))
- Uplink::Send(source, "SNONOTICE", "g", buf);
- else
- Uplink::Send(source, "SNONOTICE", "A", buf);
+ Uplink::Send(Me, "METADATA", uid, "accountname", acc);
+
+ SASLUser su;
+ su.uid = uid;
+ su.acc = acc;
+ su.created = Anope::CurTime;
+
+ for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
+ {
+ SASLUser &u = *it;
+
+ if (u.created + 30 < Anope::CurTime || u.uid == uid)
+ it = saslusers.erase(it);
+ else
+ ++it;
+ }
+
+ saslusers.push_back(su);
}
-void inspircd20::Proto::SendLogin(User *u, NickServ::Nick *na)
+void inspircd20::senders::SWhois::Send(const MessageSource&, User *user, const Anope::string& swhois)
{
- /* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */
- if (na->GetAccount()->IsUnconfirmed())
- return;
+ Uplink::Send(Me, "METADATA", user->GetUID(), "swhois", swhois);
+}
- Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay());
+void inspircd20::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
+{
+ if (Servers::Capab.count("SVSTOPIC"))
+ {
+ Uplink::Send(source, "SVSTOPIC", channel->name, topic_ts, topic_setter, topic);
+ }
+ else
+ {
+ /* If the last time a topic was set is after the TS we want for this topic we must bump this topic's timestamp to now */
+ time_t ts = topic_ts;
+ if (channel->topic_time > ts)
+ ts = Anope::CurTime;
+ /* But don't modify c->topic_ts, it should remain set to the real TS we want as ci->last_topic_time pulls from it */
+ Uplink::Send(source, "FTOPIC", channel->name, ts, topic_setter, topic);
+ }
}
-void inspircd20::Proto::SendLogout(User *u)
+void inspircd20::senders::VhostDel::Send(User* u)
{
- Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", "");
+ if (u->HasMode("CLOAK"))
+ proto->SendChgHostInternal(u->nick, u->chost);
+ else
+ proto->SendChgHostInternal(u->nick, u->host);
+
+ if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent())
+ proto->SendChgIdentInternal(u->nick, u->GetIdent());
}
-void inspircd20::Proto::SendChannel(Channel *c)
+void inspircd20::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost)
{
- Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), "");
+ if (!vident.empty())
+ proto->SendChgIdentInternal(u->nick, vident);
+ if (!vhost.empty())
+ proto->SendChgHostInternal(u->nick, vhost);
}
-void inspircd20::Proto::SendSASLMechanisms(std::vector<Anope::string> &mechanisms)
+void inspircd20::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg)
{
- Anope::string mechlist;
- for (unsigned i = 0; i < mechanisms.size(); ++i)
- mechlist += "," + mechanisms[i];
+ if (Servers::Capab.count("GLOBOPS"))
+ Uplink::Send(source, "SNONOTICE", "g", msg);
+ else
+ Uplink::Send(source, "SNONOTICE", "A", msg);
+}
- Uplink::Send(Me, "METADATA", "*", "saslmechlist", mechlist.empty() ? "" : mechlist.substr(1));
+void inspircd20::Proto::SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent)
+{
+ if (!Servers::Capab.count("CHGIDENT"))
+ Log() << "CHGIDENT not loaded!";
+ else
+ Uplink::Send(Me, "CHGIDENT", nick, vIdent);
}
-void inspircd20::Proto::SendSASLMessage(const SASL::Message &message)
+void inspircd20::Proto::SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost)
{
- if (!message.ext.empty())
- Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL",
- message.source, message.target,
- message.type, message.data, message.ext);
+ if (!Servers::Capab.count("CHGHOST"))
+ Log() << "CHGHOST not loaded!";
else
- Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL",
- message.source, message.target,
- message.type, message.data);
+ Uplink::Send(Me, "CHGHOST", nick, vhost);
}
-void inspircd20::Proto::SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost)
+void inspircd20::Proto::SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason)
{
- Uplink::Send(Me, "METADATA", uid, "accountname", acc);
+ Uplink::Send(Me, "ADDLINE", xtype, mask, addedby, Anope::CurTime, duration, reason);
+}
- SASLUser su;
- su.uid = uid;
- su.acc = acc;
- su.created = Anope::CurTime;
+void inspircd20::Proto::SendDelLine(const Anope::string &xtype, const Anope::string &mask)
+{
+ Uplink::Send(Me, "DELLINE", xtype, mask);
+}
- for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
- {
- SASLUser &u = *it;
+inspircd20::Proto::Proto(Module *creator) : ts6::Proto(creator, "InspIRCd 2.0")
+{
+ DefaultPseudoclientModes = "+I";
+ CanSVSNick = true;
+ CanSVSJoin = true;
+ CanSetVHost = true;
+ CanSetVIdent = true;
+ CanSQLine = true;
+ CanSZLine = true;
+ CanSVSHold = true;
+ CanCertFP = true;
+ RequiresID = true;
+ MaxModes = 20;
+}
- if (u.created + 30 < Anope::CurTime || u.uid == uid)
- it = saslusers.erase(it);
- else
- ++it;
- }
+void inspircd20::Proto::Handshake()
+{
+ Uplink::Send("CAPAB START 1202");
+ Uplink::Send("CAPAB CAPABILITIES :PROTOCOL=1202");
+ Uplink::Send("CAPAB END");
+ IRCD->Send<messages::MessageServer>(Me);
+}
- saslusers.push_back(su);
+void inspircd20::Proto::SendNumeric(int numeric, User *dest, IRCMessage &message)
+{
+ std::vector<Anope::string> params = message.GetParameters();
+ if (params.empty())
+ return;
+
+ /* First parameter is the UID, change it to nick because it is pushed */
+ params[0] = dest->nick;
+
+ IRCMessage m(message.GetSource(), message.GetCommand());
+ for (const Anope::string &s : params)
+ m.Push(s);
+
+ Uplink::Send("PUSH", dest->GetUID(), Format(m));
+}
+
+void inspircd20::Proto::SendBOB()
+{
+ Uplink::Send(Me, "BURST", Anope::CurTime);
+ Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
+ Uplink::Send(Me, "VERSION", Anope::Format("Anope-{0} {1} {2} - {3} - Built: {4} - Flags: {5}",
+ Anope::Version(), Me->GetName(), IRCD->GetProtocolName(), enc ? enc->name : "(none)", Anope::VersionBuildTime(), Anope::VersionFlags()));
+}
+
+void inspircd20::Proto::SendEOB()
+{
+ Uplink::Send(Me, "ENDBURST");
}
bool inspircd20::Proto::IsExtbanValid(const Anope::string &mask)
@@ -1162,8 +1126,9 @@ void inspircd20::Save::Run(MessageSource &source, const std::vector<Anope::strin
return;
}
- IRCD->SendKill(Me, targ->nick, "Nick collision");
- IRCD->SendNickChange(targ, targ->nick);
+ IRCD->Send<messages::Kill>(Me, targ->nick, "Nick collision");
+ IRCD->Send<messages::NickChange>(targ, targ->nick, Anope::CurTime);
+ targ->timestamp = Anope::CurTime;
last_collide = Anope::CurTime;
}
else
@@ -1202,7 +1167,7 @@ void inspircd20::SQuit::Run(MessageSource &source, const std::vector<Anope::stri
rsquit_server.clear();
if (s && s->IsJuped())
- IRCD->SendServer(s);
+ IRCD->Send<messages::MessageServer>(s);
}
else
rfc1459::SQuit::Run(source, params);
@@ -1318,6 +1283,49 @@ class ProtoInspIRCd20 : public Module
inspircd20::Time message_time;
inspircd20::UID message_uid;
+ rfc1459::senders::GlobalNotice sender_global_notice;
+ rfc1459::senders::GlobalPrivmsg sender_global_privmsg;
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::Kill sender_svskill;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::ModeUser sender_mode_user;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+
+ hybrid::senders::SVSJoin sender_svsjoin;
+ hybrid::senders::SVSPart sender_svspart;
+
+ bahamut::senders::SVSNick sender_svsnick;
+
+ inspircd20::senders::Akill sender_akill;
+ inspircd20::senders::AkillDel sender_akill_del;
+ inspircd20::senders::MessageChannel sender_channel;
+ inspircd20::senders::Login sender_login;
+ inspircd20::senders::Logout sender_logout;
+ inspircd20::senders::NickIntroduction sender_nickintroduction;
+ inspircd20::senders::MessageServer sender_server;
+ inspircd20::senders::SASL sender_sasl;
+ inspircd20::senders::SASLMechanisms sender_sasl_mechs;
+ inspircd20::senders::SQLine sender_sqline;
+ inspircd20::senders::SQLineDel sender_sqline_del;
+ inspircd20::senders::SQuit sender_squit;
+ inspircd20::senders::SZLine sender_szline;
+ inspircd20::senders::SZLineDel sender_szline_del;
+ inspircd20::senders::SVSHold sender_svshold;
+ inspircd20::senders::SVSHoldDel sender_svsholddel;
+ inspircd20::senders::SVSLogin sender_svslogin;
+ inspircd20::senders::SWhois sender_swhois;
+ inspircd20::senders::Topic sender_topic;
+ inspircd20::senders::VhostDel sender_vhost_del;
+ inspircd20::senders::VhostSet sender_vhost_set;
+ inspircd20::senders::Wallops sender_wallops;
+
bool use_server_side_topiclock, use_server_side_mlock;
void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value)
@@ -1336,6 +1344,7 @@ class ProtoInspIRCd20 : public Module
, ircd_proto(this)
, ssl(this, "ssl")
+
, message_away(this)
, message_error(this)
, message_invite(this)
@@ -1373,7 +1382,53 @@ class ProtoInspIRCd20 : public Module
, message_squit(this)
, message_time(this)
, message_uid(this)
+
+ , sender_akill(this, &ircd_proto)
+ , sender_akill_del(this, &ircd_proto)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sasl(this)
+ , sender_sasl_mechs(this)
+ , sender_sqline(this, &ircd_proto)
+ , sender_sqline_del(this, &ircd_proto)
+ , sender_squit(this)
+ , sender_szline(this, &ircd_proto)
+ , sender_szline_del(this, &ircd_proto)
+ , sender_svshold(this)
+ , sender_svsholddel(this)
+ , sender_svslogin(this)
+ , sender_svsjoin(this)
+ , sender_svsnick(this)
+ , sender_svspart(this)
+ , sender_swhois(this)
+ , sender_topic(this)
+ , sender_vhost_del(this, &ircd_proto)
+ , sender_vhost_set(this, &ircd_proto)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoInspIRCd20()
{
+ IRCD = nullptr;
}
void OnReload(Configuration::Conf *conf) override
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
index 1818c1021..7712aec8f 100644
--- a/modules/protocol/ngircd.cpp
+++ b/modules/protocol/ngircd.cpp
@@ -24,23 +24,7 @@
#include "modules/protocol/rfc1459.h"
#include "modules/protocol/ngircd.h"
-void ngircd::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf)
-{
- IRCDProto::SendSVSKill(source, user, buf);
- user->KillInternal(source, buf);
-}
-
-ngircd::Proto::Proto(Module *creator) : IRCDProto(creator, "ngIRCd")
-{
- DefaultPseudoclientModes = "+oi";
- CanCertFP = true;
- CanSVSNick = true;
- CanSetVHost = true;
- CanSetVIdent = true;
- MaxModes = 5;
-}
-
-void ngircd::Proto::SendAkill(User *u, XLine *x)
+void ngircd::senders::Akill::Send(User* u, XLine* x)
{
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->GetExpires() - Anope::CurTime;
@@ -49,100 +33,47 @@ void ngircd::Proto::SendAkill(User *u, XLine *x)
Uplink::Send(Me, "GLINE", x->GetMask(), timeleft, x->GetReason() + " (" + x->GetBy() + ")");
}
-void ngircd::Proto::SendAkillDel(XLine *x)
+void ngircd::senders::AkillDel::Send(XLine* x)
{
Uplink::Send(Me, "GLINE", x->GetMask());
}
-void ngircd::Proto::SendChannel(Channel *c)
+void ngircd::senders::MessageChannel::Send(Channel* c)
{
Uplink::Send(Me, "CHANINFO", c->name, "+" + c->GetModes(true, true));
}
-// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
-void ngircd::Proto::SendClientIntroduction(User *u)
+void ngircd::senders::Login::Send(User *u, NickServ::Nick *na)
{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send(Me, "NICK", u->nick, 1, u->GetIdent(), u->host, 1, modes, u->realname);
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay());
}
-void ngircd::Proto::SendConnect()
+void ngircd::senders::Logout::Send(User *u)
{
- Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "0210-IRC+", "Anope|" + Anope::VersionShort(), "CLHMSo P");
- /* Make myself known to myself in the serverlist */
- SendServer(Me);
- /* finish the enhanced server handshake and register the connection */
- Uplink::Send("376", "*", "End of MOTD command");
+ Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", "");
}
-void ngircd::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when)
+void ngircd::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts)
{
Uplink::Send(Me, "SVSNICK", u->nick, newnick);
}
-void ngircd::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
-}
-
-void ngircd::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
-}
-
-void ngircd::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf)
-{
- Uplink::Send(source, "WALLOPS", buf);
-}
-
-void ngircd::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status)
-{
- Uplink::Send(user, "JOIN", c->name);
- if (status)
- {
- /* First save the channel status incase uc->Status == status */
- ChannelStatus cs = *status;
- /* If the user is internally on the channel with flags, kill them so that
- * the stacker will allow this.
- */
- ChanUserContainer *uc = c->FindUser(user);
- if (uc != NULL)
- uc->status.Clear();
-
- ServiceBot *setter = ServiceBot::Find(user->GetUID());
- for (size_t i = 0; i < cs.Modes().length(); ++i)
- c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
-
- if (uc != NULL)
- uc->status = cs;
- }
-}
-
-void ngircd::Proto::SendLogin(User *u, NickServ::Nick *na)
-{
- Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay());
-}
-
-void ngircd::Proto::SendLogout(User *u)
-{
- Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", "");
-}
-
-/* SERVER name hop descript */
-void ngircd::Proto::SendServer(Server *server)
+// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
+void ngircd::senders::NickIntroduction::Send(User *user)
{
- Uplink::Send("SERVER", server->GetName(), server->GetHops(), server->GetDescription());
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send(Me, "NICK", user->nick, 1, user->GetIdent(), user->host, 1, modes, user->realname);
}
-void ngircd::Proto::SendTopic(const MessageSource &source, Channel *c)
+void ngircd::senders::VhostDel::Send(User* u)
{
- Uplink::Send(source, "TOPIC", c->name, c->topic);
+ IRCD->Send<messages::VhostSet>(u, u->GetIdent(), "");
}
-void ngircd::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost)
+void ngircd::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost)
{
- if (!vIdent.empty())
- Uplink::Send(Me, "METADATA", u->nick, "user", vIdent);
+ if (!vident.empty())
+ Uplink::Send(Me, "METADATA", u->nick, "user", vident);
Uplink::Send(Me, "METADATA", u->nick, "cloakhost", vhost);
if (!u->HasMode("CLOAK"))
@@ -152,9 +83,23 @@ void ngircd::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope:
}
}
-void ngircd::Proto::SendVhostDel(User *u)
+ngircd::Proto::Proto(Module *creator) : IRCDProto(creator, "ngIRCd")
{
- this->SendVhost(u, u->GetIdent(), "");
+ DefaultPseudoclientModes = "+oi";
+ CanCertFP = true;
+ CanSVSNick = true;
+ CanSetVHost = true;
+ CanSetVIdent = true;
+ MaxModes = 5;
+}
+
+void ngircd::Proto::Handshake()
+{
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "0210-IRC+", "Anope|" + Anope::VersionShort(), "CLHMSo P");
+ /* Make myself known to myself in the serverlist */
+ IRCD->Send<messages::MessageServer>(Me);
+ /* finish the enhanced server handshake and register the connection */
+ Uplink::Send("376", "*", "End of MOTD command");
}
Anope::string ngircd::Proto::Format(IRCMessage &message)
@@ -508,7 +453,7 @@ void ngircd::ServerMessage::Run(MessageSource &source, const std::vector<Anope::
* when receiving a new server and then finish sync once we
* get a pong back from that server.
*/
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
class ProtongIRCd : public Module
@@ -546,6 +491,36 @@ class ProtongIRCd : public Module
ngircd::Pong message_pong;
ngircd::ServerMessage message_server;
+ /* Core message senders */
+ rfc1459::senders::GlobalNotice sender_global_notice;
+ rfc1459::senders::GlobalPrivmsg sender_global_privmsg;
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Join sender_join;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::Kill sender_svskill;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::ModeUser sender_mode_user;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::MessageServer sender_server;
+ rfc1459::senders::SQuit sender_squit;
+ rfc1459::senders::Topic sender_topic;
+ rfc1459::senders::Wallops sender_wallops;
+
+ ngircd::senders::Akill sender_akill;
+ ngircd::senders::AkillDel sender_akill_del;
+ ngircd::senders::MessageChannel sender_channel;
+ ngircd::senders::Login sender_login;
+ ngircd::senders::Logout sender_logout;
+ ngircd::senders::SVSNick sender_svsnick;
+ ngircd::senders::VhostDel sender_vhost_del;
+ ngircd::senders::VhostSet sender_vhost_set;
+
public:
ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
, EventHook<Event::UserNickChange>(this)
@@ -578,10 +553,43 @@ class ProtongIRCd : public Module
, message_pong(this)
, message_server(this)
, message_topic(this)
- {
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_squit(this)
+ , sender_svsnick(this)
+ , sender_topic(this)
+ , sender_vhost_del(this)
+ , sender_vhost_set(this)
+ , sender_wallops(this)
+ {
Servers::Capab.insert("QS");
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtongIRCd()
+ {
+ IRCD = nullptr;
}
void OnUserNickChange(User *u, const Anope::string &) override
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index eb1fe48b5..68c23f18e 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -17,78 +17,83 @@
* along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-/* Dependencies: anope_protocol.hybrid */
+/* Dependencies: anope_protocol.ratbox */
#include "module.h"
#include "modules/protocol/plexus.h"
#include "modules/protocol/hybrid.h"
+#include "modules/protocol/ratbox.h"
static Anope::string UplinkSID;
-plexus::Proto::Proto(Module *creator) : IRCDProto(creator, "hybrid-7.2.3+plexus-3.0.1")
- , hybrid("hybrid")
+void plexus::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes)
{
- DefaultPseudoclientModes = "+oiU";
- CanSVSNick = true;
- CanSVSJoin = true;
- CanSetVHost = true;
- CanSetVIdent = true;
- CanSNLine = true;
- CanSQLine = true;
- CanSQLineChannel = true;
- CanSVSHold = true;
- CanCertFP = true;
- RequiresID = true;
- MaxModes = 4;
+ IRCMessage message(source, "ENCAP", "*", "SVSMODE", user->GetUID(), user->timestamp);
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
}
-void plexus::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf)
+void plexus::senders::NickIntroduction::Send(User *user)
{
- Uplink::Send(source, "OPERWALL", buf);
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send(Me, "UID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, "255.255.255.255", user->GetUID(), 0, user->host, user->realname);
}
-void plexus::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status)
+void plexus::senders::NOOP::Send(Server* server, bool mode)
{
- Uplink::Send(Me, "SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), user->GetUID());
- if (status)
- {
- /* First save the channel status incase uc->Status == status */
- ChannelStatus cs = *status;
- /* If the user is internally on the channel with flags, kill them so that
- * the stacker will allow this.
- */
- ChanUserContainer *uc = c->FindUser(user);
- if (uc != NULL)
- uc->status.Clear();
-
- ServiceBot *setter = ServiceBot::Find(user->GetUID());
- for (size_t i = 0; i < cs.Modes().length(); ++i)
- c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
-
- if (uc != NULL)
- uc->status = cs;
- }
+ Uplink::Send("ENCAP", server->GetName(), "SVSNOOP", (mode ? "+" : "-"));
}
-void plexus::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when)
+void plexus::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
{
- Uplink::Send(Me, "ENCAP", u->server->GetName(), "SVSNICK", u->GetUID(), u->timestamp, newnick, when);
+ Uplink::Send(source, "ENCAP", "*", "TOPIC", channel->name, topic_setter, topic_ts, topic);
}
-void plexus::Proto::SendVhost(User *u, const Anope::string &ident, const Anope::string &host)
+void plexus::senders::SVSJoin::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& key)
{
- if (!ident.empty())
- Uplink::Send(Me, "ENCAP", "*", "CHGIDENT", u->GetUID(), ident);
- Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), host);
- u->SetMode(Config->GetClient("HostServ"), "CLOAK");
+ Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSJOIN", user->GetUID(), chan);
+}
+
+void plexus::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts)
+{
+ Uplink::Send(Me, "ENCAP", u->server->GetName(), "SVSNICK", u->GetUID(), u->timestamp, newnick, ts);
+}
+
+void plexus::senders::SVSPart::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& reason)
+{
+ Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSPART", user->GetUID(), chan);
}
-void plexus::Proto::SendVhostDel(User *u)
+void plexus::senders::VhostDel::Send(User* u)
{
u->RemoveMode(Config->GetClient("HostServ"), "CLOAK");
}
-void plexus::Proto::SendConnect()
+void plexus::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost)
+{
+ if (!vident.empty())
+ Uplink::Send(Me, "ENCAP", "*", "CHGIDENT", u->GetUID(), vident);
+ Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), vhost);
+ u->SetMode(Config->GetClient("HostServ"), "CLOAK");
+}
+
+plexus::Proto::Proto(Module *creator) : ts6::Proto(creator, "Plexus 4")
+{
+ DefaultPseudoclientModes = "+oiU";
+ CanSVSNick = true;
+ CanSVSJoin = true;
+ CanSetVHost = true;
+ CanSetVIdent = true;
+ CanSNLine = true;
+ CanSQLine = true;
+ CanSQLineChannel = true;
+ CanSVSHold = true;
+ CanCertFP = true;
+ RequiresID = true;
+ MaxModes = 4;
+}
+
+void plexus::Proto::Handshake()
{
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
@@ -115,7 +120,7 @@ void plexus::Proto::SendConnect()
Uplink::Send("CAPAB", "QS EX CHW IE EOB KLN UNKLN GLN HUB KNOCK TBURST PARA ENCAP SVS");
/* Make myself known to myself in the serverlist */
- SendServer(Me);
+ Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription());
/*
* SVINFO
@@ -128,42 +133,6 @@ void plexus::Proto::SendConnect()
Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
}
-void plexus::Proto::SendClientIntroduction(User *u)
-{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, "255.255.255.255", u->GetUID(), 0, u->host, u->realname);
-}
-
-void plexus::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf)
-{
- Uplink::Send(source, "ENCAP", "*", "SVSMODE", u->GetUID(), u->timestamp, buf);
-}
-
-void plexus::Proto::SendLogin(User *u, NickServ::Nick *na)
-{
- Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay());
-}
-
-void plexus::Proto::SendLogout(User *u)
-{
- Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), "");
-}
-
-void plexus::Proto::SendTopic(const MessageSource &source, Channel *c)
-{
- Uplink::Send(source, "ENCAP", "*", "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
-}
-
-void plexus::Proto::SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param)
-{
- Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSJOIN", user->GetUID(), chan);
-}
-
-void plexus::Proto::SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param)
-{
- Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSPART", user->GetUID(), chan);
-}
-
void plexus::Encap::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
/*
@@ -269,8 +238,6 @@ void plexus::UID::Run(MessageSource &source, const std::vector<Anope::string> &p
class ProtoPlexus : public Module
{
- Module *m_hybrid;
-
plexus::Proto ircd_proto;
/* Core message handlers */
@@ -308,6 +275,46 @@ class ProtoPlexus : public Module
hybrid::TMode message_tmode;
plexus::UID message_uid;
+ /* Core message senders */
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::Kill sender_svskill;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::SQuit sender_squit;
+
+ hybrid::senders::Akill sender_akill;
+ hybrid::senders::AkillDel sender_akill_del;
+ hybrid::senders::MessageChannel sender_channel;
+ hybrid::senders::GlobalNotice sender_global_notice;
+ hybrid::senders::GlobalPrivmsg sender_global_privmsg;
+ hybrid::senders::Join sender_join;
+ hybrid::senders::MessageServer sender_server;
+ hybrid::senders::SQLine sender_sqline;
+ hybrid::senders::SQLineDel sender_sqline_del;
+ hybrid::senders::SVSHold sender_svshold;
+ hybrid::senders::SVSHoldDel sender_svsholddel;
+
+ ratbox::senders::Login sender_login;
+ ratbox::senders::Logout sender_logout;
+ ratbox::senders::Wallops sender_wallops;
+
+ plexus::senders::ModeUser sender_mode_user;
+ plexus::senders::NickIntroduction sender_nickintroduction;
+ plexus::senders::NOOP sender_noop;
+ plexus::senders::SVSJoin sender_svsjoin;
+ plexus::senders::SVSNick sender_svsnick;
+ plexus::senders::SVSPart sender_svspart;
+ plexus::senders::Topic sender_topic;
+ plexus::senders::VhostDel sender_vhost_del;
+ plexus::senders::VhostSet sender_vhost_set;
+
public:
ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
, ircd_proto(this)
@@ -343,7 +350,49 @@ class ProtoPlexus : public Module
, message_tburst(this)
, message_tmode(this)
, message_uid(this)
+
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_noop(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sqline(this)
+ , sender_sqline_del(this)
+ , sender_squit(this)
+ , sender_svshold(this)
+ , sender_svsholddel(this)
+ , sender_svsjoin(this)
+ , sender_svsnick(this)
+ , sender_svspart(this)
+ , sender_topic(this)
+ , sender_vhost_del(this)
+ , sender_vhost_set(this)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoPlexus()
{
+ IRCD = nullptr;
}
};
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index 592002578..0a20093e7 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -25,6 +25,72 @@
static Anope::string UplinkSID;
+void ratbox::senders::NickIntroduction::Send(User *user)
+{
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send(Me, "UID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, 0, user->GetUID(), user->realname);
+}
+
+void ratbox::senders::Login::Send(User *u, NickServ::Nick *na)
+{
+ if (na->GetAccount()->IsUnconfirmed())
+ return;
+
+ Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay());
+}
+
+void ratbox::senders::Logout::Send(User *u)
+{
+ Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID());
+}
+
+void ratbox::senders::SQLine::Send(User*, XLine* x)
+{
+ /* Calculate the time left before this would expire, capping it at 2 days */
+ time_t timeleft = x->GetExpires() - Anope::CurTime;
+
+ if (timeleft > 172800 || !x->GetExpires())
+ timeleft = 172800;
+
+#warning "find introduced"
+// Uplink::Send(FindIntroduced(), "ENCAP", "*", "RESV", timeleft, x->GetMask(), 0, x->GetReason());
+}
+
+void ratbox::senders::SQLineDel::Send(XLine* x)
+{
+ Uplink::Send(Config->GetClient("OperServ"), "ENCAP", "*", "UNRESV", x->GetMask());
+}
+
+void ratbox::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts)
+{
+ Uplink::Send(Me, "ENCAP", u->server->GetName(), "RSFNC", u->GetUID(),
+ newnick, ts, u->timestamp);
+}
+
+void ratbox::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
+{
+ ServiceBot *bi = source.GetBot();
+ bool needjoin = channel->FindUser(bi) == NULL;
+
+ if (needjoin)
+ {
+ ChannelStatus status;
+
+ status.AddMode('o');
+ bi->Join(channel, &status);
+ }
+
+ rfc1459::senders::Topic::Send(source, channel, topic, topic_ts, topic_setter);
+
+ if (needjoin)
+ bi->Part(channel);
+}
+
+void ratbox::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg)
+{
+ Uplink::Send(source, "OPERWALL", msg);
+}
+
ServiceBot *ratbox::Proto::FindIntroduced()
{
ServiceBot *bi = Config->GetClient("OperServ");
@@ -45,10 +111,11 @@ ServiceBot *ratbox::Proto::FindIntroduced()
return NULL;
}
-ratbox::Proto::Proto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+")
- , hybrid("hybrid")
+ratbox::Proto::Proto(Module *creator) : ts6::Proto(creator, "Ratbox 3.0+")
+ , hybrid(creator)
{
DefaultPseudoclientModes = "+oiS";
+ CanSVSNick = true;
CanSNLine = true;
CanSQLine = true;
CanSQLineChannel = true;
@@ -57,12 +124,7 @@ ratbox::Proto::Proto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+")
MaxModes = 4;
}
-void ratbox::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf)
-{
- Uplink::Send(source, "OPERWALL", buf);
-}
-
-void ratbox::Proto::SendConnect()
+void ratbox::Proto::Handshake()
{
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID());
@@ -79,7 +141,7 @@ void ratbox::Proto::SendConnect()
Uplink::Send("CAPAB", "QS EX CHW IE GLN TB ENCAP");
/* Make myself known to myself in the serverlist */
- SendServer(Me);
+ Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription());
/*
* SVINFO
@@ -92,60 +154,6 @@ void ratbox::Proto::SendConnect()
Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime);
}
-void ratbox::Proto::SendClientIntroduction(User *u)
-{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, 0, u->GetUID(), u->realname);
-}
-
-void ratbox::Proto::SendLogin(User *u, NickServ::Nick *na)
-{
- if (na->GetAccount()->IsUnconfirmed())
- return;
-
- Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay());
-}
-
-void ratbox::Proto::SendLogout(User *u)
-{
- Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID());
-}
-
-void ratbox::Proto::SendTopic(const MessageSource &source, Channel *c)
-{
- ServiceBot *bi = source.GetBot();
- bool needjoin = c->FindUser(bi) == NULL;
-
- if (needjoin)
- {
- ChannelStatus status;
-
- status.AddMode('o');
- bi->Join(c, &status);
- }
-
- IRCDProto::SendTopic(source, c);
-
- if (needjoin)
- bi->Part(c);
-}
-
-void ratbox::Proto::SendSQLine(User *, XLine *x)
-{
- /* Calculate the time left before this would expire, capping it at 2 days */
- time_t timeleft = x->GetExpires() - Anope::CurTime;
-
- if (timeleft > 172800 || !x->GetExpires())
- timeleft = 172800;
-
- Uplink::Send(FindIntroduced(), "ENCAP", "*", "RESV", timeleft, x->GetMask(), 0, x->GetReason());
-}
-
-void ratbox::Proto::SendSQLineDel(XLine *x)
-{
- Uplink::Send(Config->GetClient("OperServ"), "ENCAP", "*", "UNRESV", x->GetMask());
-}
-
// Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam
void ratbox::Encap::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
@@ -197,7 +205,7 @@ void ratbox::ServerMessage::Run(MessageSource &source, const std::vector<Anope::
if (params[1] != "1")
return;
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
/*
@@ -279,6 +287,40 @@ class ProtoRatbox : public Module
hybrid::TMode message_tmode;
ratbox::UID message_uid;
+ /* Core message senders */
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::Kill sender_svskill;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::SQuit sender_squit;
+
+ hybrid::senders::Akill sender_akill;
+ hybrid::senders::AkillDel sender_akill_del;
+ hybrid::senders::MessageChannel sender_channel;
+ hybrid::senders::GlobalNotice sender_global_notice;
+ hybrid::senders::GlobalPrivmsg sender_global_privmsg;
+ hybrid::senders::Join sender_join;
+ hybrid::senders::ModeUser sender_mode_user;
+ hybrid::senders::MessageServer sender_server;
+ hybrid::senders::SGLine sender_sgline;
+ hybrid::senders::SGLineDel sender_sgline_del;
+
+ ratbox::senders::Login sender_login;
+ ratbox::senders::Logout sender_logout;
+ ratbox::senders::NickIntroduction sender_nickintroduction;
+ ratbox::senders::SQLine sender_sqline;
+ ratbox::senders::SQLineDel sender_sqline_del;
+ ratbox::senders::SVSNick sender_svsnick;
+ ratbox::senders::Topic sender_topic;
+ ratbox::senders::Wallops sender_wallops;
+
public:
ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR)
, ircd_proto(this)
@@ -314,7 +356,44 @@ class ProtoRatbox : public Module
, message_tb(this)
, message_tmode(this)
, message_uid(this)
+
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sgline(this)
+ , sender_sgline_del(this)
+ , sender_sqline(this)
+ , sender_sqline_del(this)
+ , sender_squit(this)
+ , sender_svsnick(this)
+ , sender_topic(this)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoRatbox()
{
+ IRCD = nullptr;
}
};
diff --git a/modules/protocol/rfc1459.cpp b/modules/protocol/rfc1459.cpp
index 1314f7d39..1405e121e 100644
--- a/modules/protocol/rfc1459.cpp
+++ b/modules/protocol/rfc1459.cpp
@@ -23,6 +23,146 @@
using namespace rfc1459;
+void senders::GlobalNotice::Send(const MessageSource &source, Server *dest, const Anope::string &msg)
+{
+ Uplink::Send(source, "NOTICE", "$" + dest->GetName(), msg);
+}
+
+void senders::GlobalPrivmsg::Send(const MessageSource& source, Server* dest, const Anope::string& msg)
+{
+ Uplink::Send(source, "PRIVMSG", "$" + dest->GetName(), msg);
+}
+
+void senders::Invite::Send(const MessageSource &source, Channel *chan, User *user)
+{
+ Uplink::Send(source, "INVITE", user->GetUID(), chan->name);
+}
+
+void senders::Join::Send(User* user, Channel* c, const ChannelStatus* status)
+{
+ Uplink::Send(user, "JOIN", c->name);
+
+ if (status)
+ {
+ /* First save the channel status incase uc->Status == status */
+ ChannelStatus cs = *status;
+ /* If the user is internally on the channel with flags, kill them so that
+ * the stacker will allow this.
+ */
+ ChanUserContainer *uc = c->FindUser(user);
+ if (uc != NULL)
+ uc->status.Clear();
+
+ ServiceBot *setter = ServiceBot::Find(user->GetUID());
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
+
+ if (uc != NULL)
+ uc->status = cs;
+ }
+}
+
+void senders::Kick::Send(const MessageSource &source, Channel *chan, User *user, const Anope::string &reason)
+{
+ if (!reason.empty())
+ Uplink::Send(source, "KICK", chan->name, user->GetUID(), reason);
+ else
+ Uplink::Send(source, "KICK", chan->name, user->GetUID());
+}
+
+void senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason)
+{
+ Uplink::Send(source, "KILL", target, reason);
+}
+
+void senders::Kill::Send(const MessageSource &source, User *user, const Anope::string &reason)
+{
+ Uplink::Send(source, "KILL", user->GetUID(), reason);
+ user->KillInternal(source, reason);
+}
+
+void senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes)
+{
+ IRCMessage message(source, "MODE", channel->name);
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
+}
+
+void senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes)
+{
+ IRCMessage message(source, "MODE", user->GetUID());
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
+}
+
+void senders::NickChange::Send(User *u, const Anope::string &newnick, time_t ts)
+{
+ /* this actually isn't rfc1459 which says NICK <nickname> <hopcount> */
+ Uplink::Send(u, "NICK", newnick, ts);
+}
+
+void senders::Notice::Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg)
+{
+ Uplink::Send(source, "NOTICE", dest, msg);
+}
+
+void senders::Part::Send(User *u, Channel *chan, const Anope::string &reason)
+{
+ if (!reason.empty())
+ Uplink::Send(u, "PART", chan->name, reason);
+ else
+ Uplink::Send(u, "PART", chan->name);
+}
+
+void senders::Ping::Send(const Anope::string &servname, const Anope::string &who)
+{
+ if (servname.empty())
+ Uplink::Send(Me, "PING", who);
+ else
+ Uplink::Send(Me, "PING", servname, who);
+}
+
+void senders::Pong::Send(const Anope::string &servname, const Anope::string &who)
+{
+ if (servname.empty())
+ Uplink::Send(Me, "PONG", who);
+ else
+ Uplink::Send(Me, "PONG", servname, who);
+}
+
+void senders::Privmsg::Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg)
+{
+ Uplink::Send(source, "PRIVMSG", dest, msg);
+}
+
+void senders::Quit::Send(User *user, const Anope::string &reason)
+{
+ if (!reason.empty())
+ Uplink::Send(user, "QUIT", reason);
+ else
+ Uplink::Send(user, "QUIT");
+}
+
+void senders::MessageServer::Send(Server* server)
+{
+ Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription());
+}
+
+void senders::SQuit::Send(Server *s, const Anope::string &message)
+{
+ Uplink::Send("SQUIT", s->GetSID(), message);
+}
+
+void senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
+{
+ Uplink::Send(source, "TOPIC", channel->name, topic);
+}
+
+void senders::Wallops::Send(const MessageSource &source, const Anope::string &msg)
+{
+ Uplink::Send(source, "WALLOPS", msg);
+}
+
void Away::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &msg = !params.empty() ? params[0] : "";
@@ -300,7 +440,7 @@ void Part::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Ping::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- IRCD->SendPong(params.size() > 1 ? params[1] : Me->GetSID(), params[0]);
+ IRCD->Send<messages::Pong>(params.size() > 1 ? params[1] : Me->GetSID(), params[0]);
}
void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &params)
diff --git a/modules/protocol/ts6.cpp b/modules/protocol/ts6.cpp
new file mode 100644
index 000000000..888eebcd7
--- /dev/null
+++ b/modules/protocol/ts6.cpp
@@ -0,0 +1,71 @@
+/*
+ * Anope IRC Services
+ *
+ * Copyright (C) 2016 Anope Team <team@anope.org>
+ *
+ * This file is part of Anope. Anope is free software; you can
+ * redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software
+ * Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see see <http://www.gnu.org/licenses/>.
+ */
+
+#include "module.h"
+#include "modules/protocol/ts6.h"
+
+static inline char nextID(int pos, Anope::string &buf)
+{
+ char &c = buf[pos];
+ if (c == 'Z')
+ c = '0';
+ else if (c != '9')
+ ++c;
+ else if (pos)
+ c = 'A';
+ else
+ c = '0';
+ return c;
+}
+
+Anope::string ts6::Proto::UID_Retrieve()
+{
+ if (!IRCD || !IRCD->RequiresID)
+ return "";
+
+ static Anope::string current_uid = "AAAAAA";
+ int current_len = current_uid.length() - 1;
+
+ do
+ {
+ while (current_len >= 0 && nextID(current_len--, current_uid) == 'A');
+ }
+ while (User::Find(Me->GetSID() + current_uid) != nullptr);
+
+ return Me->GetSID() + current_uid;
+}
+
+Anope::string ts6::Proto::SID_Retrieve()
+{
+ if (!IRCD || !IRCD->RequiresID)
+ return "";
+
+ static Anope::string current_sid = Config->GetBlock("serverinfo")->Get<Anope::string>("id");
+ if (current_sid.empty())
+ current_sid = "00A";
+
+ do
+ {
+ int current_len = current_sid.length() - 1;
+ while (current_len >= 0 && nextID(current_len--, current_sid) == 'A');
+ }
+ while (Server::Find(current_sid) != nullptr);
+
+ return current_sid;
+}
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 4a4a0c4d0..f319268b7 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, see see <http://www.gnu.org/licenses/>.
*/
-/* Dependencies: anope_protocol.rfc1459 */
+/* Dependencies: anope_protocol.rfc1459,anope_protocol.bahamut */
#include "module.h"
#include "modules/chanserv/mode.h"
@@ -25,75 +25,11 @@
#include "modules/operserv/stats.h"
#include "modules/protocol/rfc1459.h"
#include "modules/protocol/unreal.h"
+#include "modules/protocol/bahamut.h"
static Anope::string UplinkSID;
-unreal::Proto::Proto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4")
-{
- DefaultPseudoclientModes = "+Soiq";
- CanSVSNick = true;
- CanSVSJoin = true;
- CanSetVHost = true;
- CanSetVIdent = true;
- CanSNLine = true;
- CanSQLine = true;
- CanSZLine = true;
- CanSVSHold = true;
- CanCertFP = true;
- RequiresID = true;
- MaxModes = 12;
-}
-
-/* SVSNOOP */
-void unreal::Proto::SendSVSNOOP(Server *server, bool set)
-{
- Uplink::Send("SVSNOOP", server->GetSID(), set ? "+" : "-");
-}
-
-void unreal::Proto::SendAkillDel(XLine *x)
-{
- if (x->IsRegex() || x->HasNickOrReal())
- return;
-
- /* ZLine if we can instead */
- if (x->GetUser() == "*")
- {
- cidr a(x->GetHost());
- if (a.valid())
- {
- IRCD->SendSZLineDel(x);
- return;
- }
- }
-
- Uplink::Send("TKL", "-", "G", x->GetUser(), x->GetHost(), x->GetBy());
-}
-
-void unreal::Proto::SendTopic(const MessageSource &source, Channel *c)
-{
- Uplink::Send(source, "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
-}
-
-void unreal::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg);
-}
-
-void unreal::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg)
-{
- Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg);
-}
-
-void unreal::Proto::SendVhostDel(User *u)
-{
- ServiceBot *HostServ = Config->GetClient("HostServ");
- u->RemoveMode(HostServ, "CLOAK");
- u->RemoveMode(HostServ, "VHOST");
- ModeManager::ProcessModes();
- u->SetMode(HostServ, "CLOAK");
-}
-
-void unreal::Proto::SendAkill(User *u, XLine *x)
+void unreal::senders::Akill::Send(User* u, XLine* x)
{
if (x->IsRegex() || x->HasNickOrReal())
{
@@ -102,7 +38,7 @@ void unreal::Proto::SendAkill(User *u, XLine *x)
/* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */
for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
if (x->GetManager()->Check(it->second, x))
- this->SendAkill(it->second, x);
+ this->Send(it->second, x);
return;
}
@@ -131,7 +67,7 @@ void unreal::Proto::SendAkill(User *u, XLine *x)
cidr a(x->GetHost());
if (a.valid())
{
- IRCD->SendSZLine(u, x);
+ IRCD->Send<messages::SZLine>(u, x);
return;
}
}
@@ -143,37 +79,46 @@ void unreal::Proto::SendAkill(User *u, XLine *x)
Uplink::Send("TKL", "+", "G", x->GetUser(), x->GetHost(), x->GetBy(), Anope::CurTime + timeleft, x->GetCreated(), x->GetReason());
}
-void unreal::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf)
+void unreal::senders::AkillDel::Send(XLine* x)
{
- Uplink::Send(source, "SVSKILL", user->GetUID(), buf);
- user->KillInternal(source, buf);
-}
+ if (x->IsRegex() || x->HasNickOrReal())
+ return;
-void unreal::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf)
-{
- IRCMessage message(source, "SVS2MODE", u->GetUID());
- message.TokenizeAndPush(buf);
- Uplink::SendMessage(message);
-}
+ /* ZLine if we can instead */
+ if (x->GetUser() == "*")
+ {
+ cidr a(x->GetHost());
+ if (a.valid())
+ {
+ IRCD->Send<messages::SZLineDel>(x);
+ return;
+ }
+ }
-void unreal::Proto::SendClientIntroduction(User *u)
-{
- Anope::string modes = "+" + u->GetModes();
- Uplink::Send("UID", u->nick, 1, u->timestamp, u->GetIdent(), u->host, u->GetUID(), "*", modes, !u->vhost.empty() ? u->vhost : "*", !u->chost.empty() ? u->chost : "*", "*", u->realname);
+ Uplink::Send("TKL", "-", "G", x->GetUser(), x->GetHost(), x->GetBy());
}
-/* SERVER name hop descript */
-/* Unreal 3.2 actually sends some info about itself in the descript area */
-void unreal::Proto::SendServer(Server *server)
+void unreal::senders::MessageChannel::Send(Channel* c)
{
- if (!server->GetSID().empty() && server == Me)
- Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription());
+ /* Unreal does not support updating a channels TS without actually joining a user,
+ * so we will join and part us now
+ */
+ ServiceBot *bi = c->ci->WhoSends();
+ if (!bi)
+ ;
+ else if (c->FindUser(bi) == NULL)
+ {
+ bi->Join(c);
+ bi->Part(c);
+ }
else
- Uplink::Send("SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription());
+ {
+ bi->Part(c);
+ bi->Join(c);
+ }
}
-/* JOIN */
-void unreal::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status)
+void unreal::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status)
{
Uplink::Send(Me, "SJOIN", c->creation_time, c->name, user->GetUID());
if (status)
@@ -196,83 +141,87 @@ void unreal::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status
}
}
-/* unsqline
-*/
-void unreal::Proto::SendSQLineDel(XLine *x)
+void unreal::senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason)
{
- Uplink::Send("UNSQLINE", x->GetMask());
+ Uplink::Send(source, "SVSKILL", target, reason);
}
-/* SQLINE */
-/*
-** - Unreal will translate this to TKL for us
-**
-*/
-void unreal::Proto::SendSQLine(User *, XLine *x)
+void unreal::senders::Kill::Send(const MessageSource &source, User *user, const Anope::string &reason)
{
- Uplink::Send("SQLINE", x->GetMask(), x->GetReason());
+ Uplink::Send(source, "SVSKILL", user->GetUID(), reason);
+ user->KillInternal(source, reason);
}
-/* Functions that use serval cmd functions */
+void unreal::senders::Login::Send(User *u, NickServ::Nick *na)
+{
+ /* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */
+ if (Servers::Capab.count("ESVID") > 0 && !na->GetAccount()->IsUnconfirmed())
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", na->GetAccount()->GetDisplay());
+ else
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon);
+}
-void unreal::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost)
+void unreal::senders::Logout::Send(User *u)
{
- if (!vIdent.empty())
- Uplink::Send(Me, "CHGIDENT", u->GetUID(), vIdent);
- if (!vhost.empty())
- Uplink::Send(Me, "CHGHOST", u->GetUID(), vhost);
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0");
}
-void unreal::Proto::SendConnect()
+void unreal::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes)
{
- /*
- NICKv2 = Nick Version 2
- VHP = Sends hidden host
- UMODE2 = sends UMODE2 on user modes
- NICKIP = Sends IP on NICK
- SJ3 = Supports SJOIN
- NOQUIT = No Quit
- TKLEXT = Extended TKL we don't use it but best to have it
- MLOCK = Supports the MLOCK server command
- VL = Version Info
- SID = SID/UID mode
- */
- Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password);
- Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID");
- Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort());
- Uplink::Send("PROTOCTL", "SID=" + Me->GetSID());
- SendServer(Me);
+ IRCMessage message(source, "SVS2MODE", user->GetUID());
+ message.TokenizeAndPush(modes);
+ Uplink::SendMessage(message);
}
-/* SVSHOLD - set */
-void unreal::Proto::SendSVSHold(const Anope::string &nick, time_t t)
+void unreal::senders::NickIntroduction::Send(User *user)
{
- Uplink::Send("TKL", "+", "Q", "H", nick, Me->GetName(), Anope::CurTime + t, Anope::CurTime, "Being held for registered user");
+ Anope::string modes = "+" + user->GetModes();
+ Uplink::Send("UID", user->nick, 1, user->timestamp, user->GetIdent(), user->host, user->GetUID(), "*", modes, !user->vhost.empty() ? user->vhost : "*", !user->chost.empty() ? user->chost : "*", "*", user->realname);
}
-/* SVSHOLD - release */
-void unreal::Proto::SendSVSHoldDel(const Anope::string &nick)
+void unreal::senders::SASL::Send(const ::SASL::Message& message)
{
- Uplink::Send("TKL", "-", "Q", "*", nick, Me->GetName());
+ size_t p = message.target.find('!');
+ if (p == Anope::string::npos)
+ return;
+
+ if (!message.ext.empty())
+ Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data, message.ext);
+ else
+ Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data);
}
-/* UNSGLINE */
-/*
- * SVSNLINE - :realname mask
-*/
-void unreal::Proto::SendSGLineDel(XLine *x)
+void unreal::senders::MessageServer::Send(Server* server)
+{
+ Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription());
+}
+
+void unreal::senders::SGLine::Send(User*, XLine* x)
+{
+ /*
+ * SVSNLINE + reason_where_is_space :realname mask with spaces
+ */
+ Anope::string edited_reason = x->GetReason();
+ edited_reason = edited_reason.replace_all_cs(" ", "_");
+ Uplink::Send("SVSNLINE", "+", edited_reason, x->GetMask());
+}
+
+void unreal::senders::SGLineDel::Send(XLine* x)
{
Uplink::Send("SVSNLINE", "-", x->GetMask());
}
-/* UNSZLINE */
-void unreal::Proto::SendSZLineDel(XLine *x)
+void unreal::senders::SQLine::Send(User*, XLine* x)
{
- Uplink::Send("TKL", "-", "Z", "*", x->GetHost(), x->GetBy());
+ Uplink::Send("SQLINE", x->GetMask(), x->GetReason());
}
-/* SZLINE */
-void unreal::Proto::SendSZLine(User *, XLine *x)
+void unreal::senders::SQLineDel::Send(XLine* x)
+{
+ Uplink::Send("UNSQLINE", x->GetMask());
+}
+
+void unreal::senders::SZLine::Send(User*, XLine* x)
{
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->GetExpires() - Anope::CurTime;
@@ -281,15 +230,19 @@ void unreal::Proto::SendSZLine(User *, XLine *x)
Uplink::Send("TKL", "+", "Z", "*", x->GetHost(), x->GetBy(), Anope::CurTime + timeleft, x->GetCreated(), x->GetReason());
}
-/* SGLINE */
-/*
- * SVSNLINE + reason_where_is_space :realname mask with spaces
-*/
-void unreal::Proto::SendSGLine(User *, XLine *x)
+void unreal::senders::SZLineDel::Send(XLine* x)
{
- Anope::string edited_reason = x->GetReason();
- edited_reason = edited_reason.replace_all_cs(" ", "_");
- Uplink::Send("SVSNLINE", "+", edited_reason, x->GetMask());
+ Uplink::Send("TKL", "-", "Z", "*", x->GetHost(), x->GetBy());
+}
+
+void unreal::senders::SVSHold::Send(const Anope::string& nick, time_t t)
+{
+ Uplink::Send("TKL", "+", "Q", "H", nick, Me->GetName(), Anope::CurTime + t, Anope::CurTime, "Being held for registered user");
+}
+
+void unreal::senders::SVSHoldDel::Send(const Anope::string& nick)
+{
+ Uplink::Send("TKL", "-", "Q", "*", nick, Me->GetName());
}
/* svsjoin
@@ -298,105 +251,118 @@ void unreal::Proto::SendSGLine(User *, XLine *x)
parv[2] - channel to join
parv[3] - (optional) channel key(s)
*/
-void unreal::Proto::SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param)
+void unreal::senders::SVSJoin::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& key)
{
- if (!param.empty())
- Uplink::Send(source, "SVSJOIN", user->GetUID(), chan, param);
+ if (!key.empty())
+ Uplink::Send(source, "SVSJOIN", user->GetUID(), chan, key);
else
Uplink::Send(source, "SVSJOIN", user->GetUID(), chan);
}
-void unreal::Proto::SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param)
+void unreal::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost)
{
- if (!param.empty())
- Uplink::Send(source, "SVSPART", user->GetUID(), chan, param);
+ size_t p = uid.find('!');
+ if (p == Anope::string::npos)
+ return;
+ Uplink::Send(Me, "SVSLOGIN", uid.substr(0, p), uid, acc);
+}
+
+void unreal::senders::SVSPart::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& reason)
+{
+ if (!reason.empty())
+ Uplink::Send(source, "SVSPART", user->GetUID(), chan, reason);
else
Uplink::Send(source, "SVSPART", user->GetUID(), chan);
}
-void unreal::Proto::SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask)
+void unreal::senders::SWhois::Send(const MessageSource& source, User *user, const Anope::string& swhois)
{
- Uplink::Send(source, "SWHOIS", who, mask);
+ Uplink::Send(source, "SWHOIS", user->GetUID(), swhois);
}
-void unreal::Proto::SendEOB()
+void unreal::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter)
{
- Uplink::Send(Me, "EOS");
+ Uplink::Send(source, "TOPIC", channel->name, topic_setter, topic_ts, topic);
}
-bool unreal::Proto::IsNickValid(const Anope::string &nick)
+void unreal::senders::VhostDel::Send(User* u)
{
- if (nick.equals_ci("ircd") || nick.equals_ci("irc"))
- return false;
-
- return IRCDProto::IsNickValid(nick);
+ ServiceBot *HostServ = Config->GetClient("HostServ");
+ u->RemoveMode(HostServ, "CLOAK");
+ u->RemoveMode(HostServ, "VHOST");
+ ModeManager::ProcessModes();
+ u->SetMode(HostServ, "CLOAK");
}
-bool unreal::Proto::IsChannelValid(const Anope::string &chan)
+void unreal::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost)
{
- if (chan.find(':') != Anope::string::npos)
- return false;
-
- return IRCDProto::IsChannelValid(chan);
+ if (!vident.empty())
+ Uplink::Send(Me, "CHGIDENT", u->GetUID(), vident);
+ if (!vhost.empty())
+ Uplink::Send(Me, "CHGHOST", u->GetUID(), vhost);
}
-bool unreal::Proto:: IsExtbanValid(const Anope::string &mask)
+unreal::Proto::Proto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4")
{
- return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
+ DefaultPseudoclientModes = "+Soiq";
+ CanSVSNick = true;
+ CanSVSJoin = true;
+ CanSetVHost = true;
+ CanSetVIdent = true;
+ CanSNLine = true;
+ CanSQLine = true;
+ CanSZLine = true;
+ CanSVSHold = true;
+ CanCertFP = true;
+ RequiresID = true;
+ MaxModes = 12;
}
-void unreal::Proto::SendLogin(User *u, NickServ::Nick *na)
+void unreal::Proto::Handshake()
{
- /* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */
- if (Servers::Capab.count("ESVID") > 0 && !na->GetAccount()->IsUnconfirmed())
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", na->GetAccount()->GetDisplay());
- else
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon);
+ /*
+ NICKv2 = Nick Version 2
+ VHP = Sends hidden host
+ UMODE2 = sends UMODE2 on user modes
+ NICKIP = Sends IP on NICK
+ SJ3 = Supports SJOIN
+ NOQUIT = No Quit
+ TKLEXT = Extended TKL we don't use it but best to have it
+ MLOCK = Supports the MLOCK server command
+ VL = Version Info
+ SID = SID/UID mode
+ */
+ Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password);
+ Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID");
+ Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort());
+ Uplink::Send("PROTOCTL", "SID=" + Me->GetSID());
+ Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription());
}
-void unreal::Proto::SendLogout(User *u)
+void unreal::Proto::SendEOB()
{
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0");
+ Uplink::Send(Me, "EOS");
}
-void unreal::Proto::SendChannel(Channel *c)
+bool unreal::Proto::IsNickValid(const Anope::string &nick)
{
- /* Unreal does not support updating a channels TS without actually joining a user,
- * so we will join and part us now
- */
- ServiceBot *bi = c->ci->WhoSends();
- if (!bi)
- ;
- else if (c->FindUser(bi) == NULL)
- {
- bi->Join(c);
- bi->Part(c);
- }
- else
- {
- bi->Part(c);
- bi->Join(c);
- }
+ if (nick.equals_ci("ircd") || nick.equals_ci("irc"))
+ return false;
+
+ return IRCDProto::IsNickValid(nick);
}
-void unreal::Proto::SendSASLMessage(const ::SASL::Message &message)
+bool unreal::Proto::IsChannelValid(const Anope::string &chan)
{
- size_t p = message.target.find('!');
- if (p == Anope::string::npos)
- return;
+ if (chan.find(':') != Anope::string::npos)
+ return false;
- if (!message.ext.empty())
- Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data, message.ext);
- else
- Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data);
+ return IRCDProto::IsChannelValid(chan);
}
-void unreal::Proto::SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost)
+bool unreal::Proto:: IsExtbanValid(const Anope::string &mask)
{
- size_t p = uid.find('!');
- if (p == Anope::string::npos)
- return;
- Uplink::Send(Me, "SVSLOGIN", uid.substr(0, p), uid, acc);
+ return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
}
bool unreal::Proto::IsIdentValid(const Anope::string &ident)
@@ -889,7 +855,7 @@ void unreal::ServerMessage::Run(MessageSource &source, const std::vector<Anope::
new Server(source.GetServer(), params[0], hops, params[2]);
}
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
void unreal::SID::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -904,7 +870,7 @@ void unreal::SID::Run(MessageSource &source, const std::vector<Anope::string> &p
new Server(source.GetServer(), params[0], hops, params[3], params[2]);
- IRCD->SendPing(Me->GetName(), params[0]);
+ IRCD->Send<messages::Ping>(Me->GetName(), params[0]);
}
void unreal::SJoin::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -1156,6 +1122,48 @@ class ProtoUnreal : public Module
unreal::UID message_uid;
unreal::Umode2 message_umode2;
+ rfc1459::senders::GlobalNotice sender_global_notice;
+ rfc1459::senders::GlobalPrivmsg sender_global_privmsg;
+ rfc1459::senders::Invite sender_invite;
+ rfc1459::senders::Kick sender_kick;
+ rfc1459::senders::ModeChannel sender_mode_chan;
+ rfc1459::senders::NickChange sender_nickchange;
+ rfc1459::senders::Notice sender_notice;
+ rfc1459::senders::Part sender_part;
+ rfc1459::senders::Ping sender_ping;
+ rfc1459::senders::Pong sender_pong;
+ rfc1459::senders::Privmsg sender_privmsg;
+ rfc1459::senders::Quit sender_quit;
+ rfc1459::senders::SQuit sender_squit;
+
+ bahamut::senders::NOOP sender_noop;
+ bahamut::senders::SVSNick sender_svsnick;
+ bahamut::senders::Wallops sender_wallops;
+
+ unreal::senders::Akill sender_akill;
+ unreal::senders::AkillDel sender_akill_del;
+ unreal::senders::MessageChannel sender_channel;
+ unreal::senders::Join sender_join;
+ unreal::senders::Kill sender_svskill;
+ unreal::senders::Login sender_login;
+ unreal::senders::Logout sender_logout;
+ unreal::senders::ModeUser sender_mode_user;
+ unreal::senders::NickIntroduction sender_nickintroduction;
+ unreal::senders::MessageServer sender_server;
+ unreal::senders::SASL sender_sasl;
+ unreal::senders::SGLine sender_sgline;
+ unreal::senders::SGLineDel sender_sgline_del;
+ unreal::senders::SQLine sender_sqline;
+ unreal::senders::SQLineDel sender_sqline_del;
+ unreal::senders::SVSHold sender_svshold;
+ unreal::senders::SVSHoldDel sender_svsholddel;
+ unreal::senders::SVSJoin sender_svsjoin;
+ unreal::senders::SVSPart sender_svspart;
+ unreal::senders::SWhois sender_swhois;
+ unreal::senders::Topic sender_topic;
+ unreal::senders::VhostDel sender_vhost_del;
+ unreal::senders::VhostSet sender_vhost_set;
+
bool use_server_side_mlock;
public:
@@ -1207,7 +1215,53 @@ class ProtoUnreal : public Module
, message_topic(this)
, message_uid(this)
, message_umode2(this)
+
+ , sender_akill(this)
+ , sender_akill_del(this)
+ , sender_channel(this)
+ , sender_global_notice(this)
+ , sender_global_privmsg(this)
+ , sender_invite(this)
+ , sender_join(this)
+ , sender_kick(this)
+ , sender_svskill(this)
+ , sender_login(this)
+ , sender_logout(this)
+ , sender_mode_chan(this)
+ , sender_mode_user(this)
+ , sender_nickchange(this)
+ , sender_nickintroduction(this)
+ , sender_noop(this)
+ , sender_notice(this)
+ , sender_part(this)
+ , sender_ping(this)
+ , sender_pong(this)
+ , sender_privmsg(this)
+ , sender_quit(this)
+ , sender_server(this)
+ , sender_sasl(this)
+ , sender_sgline(this)
+ , sender_sgline_del(this)
+ , sender_sqline(this)
+ , sender_sqline_del(this)
+ , sender_squit(this)
+ , sender_svshold(this)
+ , sender_svsholddel(this)
+ , sender_svsjoin(this)
+ , sender_svsnick(this)
+ , sender_svspart(this)
+ , sender_swhois(this)
+ , sender_topic(this)
+ , sender_vhost_del(this)
+ , sender_vhost_set(this)
+ , sender_wallops(this)
+ {
+ IRCD = &ircd_proto;
+ }
+
+ ~ProtoUnreal()
{
+ IRCD = nullptr;
}
void OnReload(Configuration::Conf *conf) override
@@ -1251,7 +1305,7 @@ class ProtoUnreal : public Module
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
if (Servers::Capab.count("ESVID") == 0)
- IRCD->SendLogout(u);
+ sender_logout.Send(u);
}
void OnChannelSync(Channel *c) override