summaryrefslogtreecommitdiff
path: root/modules/protocol
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2016-12-17 21:44:22 -0500
committerAdam <Adam@anope.org>2016-12-17 21:44:22 -0500
commit4fcbbbe4fbc137841b47c8e2372477b85649270a (patch)
treef2a5fd3b5a77ef0384df6e2712fdd74f832d7dfe /modules/protocol
parented08d1a31119adb379f8bec46d7ad47ee35c4c92 (diff)
Split ircdproto send functions out into separate services
This makes it easier to see which send functions a protocol module implements as they are all explicitly registered by the module, and avoids the problem of subtly breaking other protocol modules when using inheritance. Also split the old "core" send implementations out into a module, and the TS6 ID generator
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