summaryrefslogtreecommitdiff
path: root/modules/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'modules/protocol')
-rw-r--r--modules/protocol/bahamut.cpp322
-rw-r--r--modules/protocol/inspircd-ts6.h386
-rw-r--r--modules/protocol/inspircd11.cpp571
-rw-r--r--modules/protocol/inspircd12.cpp389
-rw-r--r--modules/protocol/inspircd20.cpp399
-rw-r--r--modules/protocol/plexus.cpp538
-rw-r--r--modules/protocol/ratbox.cpp445
-rw-r--r--modules/protocol/unreal.cpp783
8 files changed, 1848 insertions, 1985 deletions
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 73955149d..8aeee39c8 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -13,34 +13,40 @@
#include "module.h"
-IRCDVar myIrcd = {
- "Bahamut 1.8.x", /* ircd name */
- "+", /* Modes used by pseudoclients */
- 1, /* SVSNICK */
- 0, /* Vhost */
- 1, /* Supports SNlines */
- 1, /* Supports SQlines */
- 1, /* Supports SZlines */
- 0, /* Join 2 Message */
- 1, /* Chan SQlines */
- 1, /* Quit on Kill */
- 0, /* vidents */
- 1, /* svshold */
- 1, /* time stamp on mode */
- 0, /* O:LINE */
- 1, /* UMODE */
- 1, /* No Knock requires +i */
- 0, /* Can remove User Channel Modes with SVSMODE */
- 0, /* Sglines are not enforced until user reconnects */
- 0, /* ts6 */
- "$", /* TLD Prefix for Global */
- 6, /* Max number of modes we can send per line */
- 0 /* IRCd sends a SSL users certificate fingerprint */
-};
+class ChannelModeFlood : public ChannelModeParam
+{
+ public:
+ ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
+ bool IsValid(const Anope::string &value) const anope_override
+ {
+ try
+ {
+ 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;
+ }
+ catch (const ConvertException &) { }
+
+ return false;
+ }
+};
class BahamutIRCdProto : public IRCDProto
{
+ public:
+ BahamutIRCdProto() : IRCDProto("Bahamut 1.8.x")
+ {
+ DefaultPseudoclientModes = "+";
+ CanSVSNick = true;
+ CanSNLine = true;
+ CanSQLine = true;
+ CanSQLineChannel = true;
+ CanSZLine = true;
+ CanSVSHold = true;
+ MaxModes = 60;
+ }
+
void SendModeInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf) anope_override
{
if (Capab.count("TSMODE") > 0)
@@ -62,6 +68,16 @@ class BahamutIRCdProto : public IRCDProto
UplinkSocket::Message(Me) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf;
}
+ void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ {
+ UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
+ }
+
+ void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ {
+ UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
+ }
+
/* SVSHOLD - set */
void SendSVSHold(const Anope::string &nick) anope_override
{
@@ -290,46 +306,82 @@ class BahamutIRCdProto : public IRCDProto
}
};
-class BahamutIRCdMessage : public IRCdMessage
+struct IRCDMessageBurst : IRCDMessage
{
- public:
- bool OnMode(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.size() > 2 && (params[0][0] == '#' || params[0][0] == '&'))
- do_cmode(source, params[0], params[2], params[1]);
- else if (params.size() > 1)
- do_umode(params[0], params[1]);
+ IRCDMessageBurst() : IRCDMessage("BURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ /* If we found a server with the given source, that one just
+ * finished bursting. If there was no source, then our uplink
+ * server finished bursting. -GD
+ */
+ Server *s = source.GetServer();
+ if (!s)
+ s = Me->GetLinks().front();
+ if (s)
+ s->Sync(true);
return true;
}
+};
- /*
- ** NICK - new
- ** source = NULL
- ** parv[0] = nickname
- ** parv[1] = hopcount
- ** parv[2] = timestamp
- ** parv[3] = modes
- ** parv[4] = username
- ** parv[5] = hostname
- ** parv[6] = server
- ** parv[7] = servicestamp
- ** parv[8] = IP
- ** parv[9] = info
- ** NICK - change
- ** source = oldnick
- ** parv[0] = new nickname
- ** parv[1] = hopcount
- */
- bool OnNick(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params.size() != 2)
+struct IRCDMessageMode : IRCDMessage
+{
+ IRCDMessageMode(const Anope::string &n) : IRCDMessage(n, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ if (params.size() > 2 && ircdproto->IsChannelValid(params[0]))
+ {
+ Channel *c = findchan(params[0]);
+ time_t ts = Anope::CurTime;
+ try
+ {
+ ts = convertTo<time_t>(params[1]);
+ }
+ catch (const ConvertException &) { }
+
+ if (c)
+ c->SetModesInternal(source, params[2], ts);
+ }
+ else
{
- /* Currently bahamut has no ipv6 support */
- sockaddrs ip;
- ip.ntop(AF_INET, params[8].c_str());
+ User *u = finduser(params[0]);
+ if (u)
+ u->SetModesInternal("%s", params[1].c_str());
+ }
+
+ return true;
+ }
+};
+
+/*
+ ** NICK - new
+ ** source = NULL
+ ** parv[0] = nickname
+ ** parv[1] = hopcount
+ ** parv[2] = timestamp
+ ** parv[3] = modes
+ ** parv[4] = username
+ ** parv[5] = hostname
+ ** parv[6] = server
+ ** parv[7] = servicestamp
+ ** parv[8] = IP
+ ** parv[9] = info
+ ** NICK - change
+ ** source = oldnick
+ ** parv[0] = new nickname
+ ** parv[1] = hopcount
+ */
+struct IRCDMessageNick : IRCDMessage
+{
+ IRCDMessageNick() : IRCDMessage("NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- User *user = do_nick(source, params[0], params[4], params[5], params[6], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip.addr(), "", "", params[3]);
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ if (params.size() == 10)
+ {
+ User *user = new User(params[0], params[4], params[5], "", params[8], source.GetServer(), params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3]);
if (user && nickserv)
{
const NickAlias *na;
@@ -345,35 +397,29 @@ class BahamutIRCdMessage : public IRCdMessage
}
}
else
- do_nick(source, params[0], "", "", "", "", Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0, "", "", "", "");
+ source.GetUser()->ChangeNick(params[0]);
return true;
}
+};
- bool OnServer(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[2], "");
- return true;
- }
+struct IRCDMessageServer : IRCDMessage
+{
+ IRCDMessageServer() : IRCDMessage("SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- bool OnTopic(const Anope::string &, const std::vector<Anope::string> &params) anope_override
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (params.size() < 4)
- return true;
-
- Channel *c = findchan(params[0]);
- if (!c)
- {
- Log() << "TOPIC for nonexistant channel " << params[0];
- return true;
- }
-
- c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
-
+ unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
+ new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[2]);
return true;
}
+};
- bool OnSJoin(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
+struct IRCDMessageSJoin : IRCDMessage
+{
+ IRCDMessageSJoin() : IRCDMessage("SJOIN", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
Channel *c = findchan(params[1]);
time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : 0;
@@ -403,7 +449,7 @@ class BahamutIRCdMessage : public IRCdMessage
modes += " " + params[i];
if (!modes.empty())
modes.erase(modes.begin());
- c->SetModesInternal(NULL, modes);
+ c->SetModesInternal(source, modes);
}
/* For some reason, bahamut will send a SJOIN from the user joining a channel
@@ -411,28 +457,24 @@ class BahamutIRCdMessage : public IRCdMessage
*/
if (!c->HasFlag(CH_SYNCING) && params.size() == 2)
{
- User *u = finduser(source);
- if (!u)
- Log(LOG_DEBUG) << "SJOIN for nonexistant user " << source << " on " << c->name;
- else
- {
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
+ User *u = source.GetUser();
- /* Add the user to the channel */
- c->JoinUser(u);
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
- /* Now set whatever modes this user is allowed to have on the channel */
- chan_set_correct_modes(u, c, 1, true);
+ /* Add the user to the channel */
+ c->JoinUser(u);
- /* Check to see if modules want the user to join, if they do
- * check to see if they are allowed to join (CheckKick will kick/ban them)
- * Don't trigger OnJoinChannel event then as the user will be destroyed
- */
- if (MOD_RESULT == EVENT_STOP && (!c->ci || !c->ci->CheckKick(u)))
- {
- FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
- }
+ /* Now set whatever modes this user is allowed to have on the channel */
+ chan_set_correct_modes(u, c, 1, true);
+
+ /* Check to see if modules want the user to join, if they do
+ * check to see if they are allowed to join (CheckKick will kick/ban them)
+ * Don't trigger OnJoinChannel event then as the user will be destroyed
+ */
+ if (MOD_RESULT == EVENT_STOP && (!c->ci || !c->ci->CheckKick(u)))
+ {
+ FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
}
}
else
@@ -476,7 +518,7 @@ class BahamutIRCdMessage : public IRCdMessage
* This will enforce secureops etc on the user
*/
for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
- c->SetModeInternal(NULL, *it, buf);
+ c->SetModeInternal(source, *it, buf);
/* Now set whatever modes this user is allowed to have on the channel */
chan_set_correct_modes(u, c, 1, true);
@@ -504,53 +546,48 @@ class BahamutIRCdMessage : public IRCdMessage
}
};
-bool event_burst(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- Server *s = Server::Find(source);
-
- if (params.empty())
- {
- /* for future use - start burst */
- }
- else
- {
- /* If we found a server with the given source, that one just
- * finished bursting. If there was no source, then our uplink
- * server finished bursting. -GD
- */
- if (!s)
- s = Me->GetLinks().front();
- if (s)
- s->Sync(true);
- }
- return true;
-}
-
-class ChannelModeFlood : public ChannelModeParam
+struct IRCDMessageTopic : IRCDMessage
{
- public:
- ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { }
+ IRCDMessageTopic() : IRCDMessage("TOPIC", 4) { }
- bool IsValid(const Anope::string &value) const anope_override
+ bool Run(MessageSource &, const std::vector<Anope::string> &params) anope_override
{
- try
- {
- 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;
- }
- catch (const ConvertException &) { }
-
- return false;
+ Channel *c = findchan(params[0]);
+ if (c)
+ c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
+ return true;
}
};
class ProtoBahamut : public Module
{
- Message message_svsmode, message_burst;
-
BahamutIRCdProto ircd_proto;
- BahamutIRCdMessage ircd_message;
+
+ /* Core message handlers */
+ CoreIRCDMessageAway core_message_away;
+ CoreIRCDMessageCapab core_message_capab;
+ CoreIRCDMessageError core_message_error;
+ CoreIRCDMessageJoin core_message_join;
+ CoreIRCDMessageKill core_message_kill;
+ CoreIRCDMessageMOTD core_message_motd;
+ CoreIRCDMessagePart core_message_part;
+ CoreIRCDMessagePing core_message_ping;
+ CoreIRCDMessagePrivmsg core_message_privmsg;
+ CoreIRCDMessageQuit core_message_quit;
+ CoreIRCDMessageSQuit core_message_squit;
+ CoreIRCDMessageStats core_message_stats;
+ CoreIRCDMessageTime core_message_time;
+ CoreIRCDMessageTopic core_message_topic;
+ CoreIRCDMessageVersion core_message_version;
+ CoreIRCDMessageWhois core_message_whois;
+
+ /* Our message handlers */
+ IRCDMessageBurst message_burst;
+ IRCDMessageMode message_mode, message_svsmode;
+ IRCDMessageNick message_nick;
+ IRCDMessageServer message_server;
+ IRCDMessageSJoin message_sjoin;
+ IRCDMessageTopic message_topic;
void AddModes()
{
@@ -591,26 +628,15 @@ class ProtoBahamut : public Module
public:
ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
- message_svsmode("SVSMODE", OnMode), message_burst("BURST", event_burst)
+ message_mode("MODE"), message_svsmode("SVSMODE")
{
this->SetAuthor("Anope");
- pmodule_ircd_var(&myIrcd);
- pmodule_ircd_proto(&this->ircd_proto);
- pmodule_ircd_message(&this->ircd_message);
-
this->AddModes();
ModuleManager::Attach(I_OnUserNickChange, this);
}
- ~ProtoBahamut()
- {
- pmodule_ircd_var(NULL);
- pmodule_ircd_proto(NULL);
- pmodule_ircd_message(NULL);
- }
-
void OnUserNickChange(User *u, const Anope::string &) anope_override
{
u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h
index 0ce5be921..f0af01cc9 100644
--- a/modules/protocol/inspircd-ts6.h
+++ b/modules/protocol/inspircd-ts6.h
@@ -47,7 +47,30 @@ class InspIRCdTS6Proto : public IRCDProto
UplinkSocket::Message(Me) << "CHGHOST " << nick << " " << vhost;
}
- public:
+ protected:
+ InspIRCdTS6Proto(const Anope::string &name) : IRCDProto(name)
+ {
+ DefaultPseudoclientModes = "+I";
+ CanSVSNick = true;
+ CanSetVHost = true;
+ CanSetVIdent = true;
+ CanSQLine = true;
+ CanSZLine = true;
+ CanSVSHold = true;
+ CanCertFP = true;
+ RequiresID = true;
+ MaxModes = 20;
+ }
+
+ void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ {
+ UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
+ }
+
+ void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ {
+ UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
+ }
void SendAkillDel(const XLine *x) anope_override
{
@@ -225,7 +248,7 @@ class InspIRCdTS6Proto : public IRCDProto
SendServer(Me);
UplinkSocket::Message(Me) << "BURST";
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << ircd->name << " - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString();
+ UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << ircdproto->GetProtocolName() << " - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString();
}
/* SVSHOLD - set */
@@ -319,83 +342,37 @@ class InspIRCdTS6Proto : public IRCDProto
}
};
-class InspircdIRCdMessage : public IRCdMessage
+struct IRCDMessageEndburst : IRCDMessage
{
- public:
- bool OnMode(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- if (params[0][0] == '#' || params[0][0] == '&')
- do_cmode(source, params[0], params[2], params[1]);
- else
- {
- /* InspIRCd lets opers change another
- users modes, we have to kludge this
- as it slightly breaks RFC1459
- */
- User *u = finduser(source);
- // This can happen with server-origin modes.
- if (!u)
- u = finduser(params[0]);
- // if it's still null, drop it like fire.
- // most likely situation was that server introduced a nick which we subsequently akilled
- if (!u)
- return true;
+ IRCDMessageEndburst() : IRCDMessage("ENDBURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
- do_umode(u->nick, params[1]);
- }
-
- return true;
- }
-
- virtual bool OnUID(const Anope::string &source, const std::vector<Anope::string> &params) anope_override = 0;
-
- bool OnNick(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
- do_nick(source, params[0], "", "", "", "", 0, "", "", "", "");
- return true;
- }
-
- bool OnPrivmsg(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- /* Ignore privmsgs from the server, which can happen. */
- if (Server::Find(source) != NULL)
- return true;
+ Server *s = source.GetServer();
- return IRCdMessage::OnPrivmsg(source, params);
- }
+ Log(LOG_DEBUG) << "Processed ENDBURST for " << s->GetName();
- /*
- * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central!
- * 0: name
- * 1: pass
- * 2: hops
- * 3: numeric
- * 4: desc
- */
- bool OnServer(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- do_server(source, params[0], Anope::string(params[2]).is_pos_number_only() ? convertTo<unsigned>(params[2]) : 0, params[4], params[3]);
+ s->Sync(true);
return true;
}
+};
- bool OnTopic(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- Channel *c = findchan(params[0]);
-
- if (!c)
- {
- Log() << "TOPIC " << params[1] << " for nonexistent channel " << params[0];
- return true;
- }
-
- c->ChangeTopicInternal(source, (params.size() > 1 ? params[1] : ""), Anope::CurTime);
+struct IRCDMessageFHost : IRCDMessage
+{
+ IRCDMessageFHost(const Anope::string &n) : IRCDMessage(n, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ source.GetUser()->SetDisplayedHost(params[0]);
return true;
}
+};
- virtual bool OnCapab(const Anope::string &, const std::vector<Anope::string> &) anope_override = 0;
+struct IRCDMessageFJoin : IRCDMessage
+{
+ IRCDMessageFJoin() : IRCDMessage("FJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- bool OnSJoin(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
Channel *c = findchan(params[0]);
time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0;
@@ -425,7 +402,7 @@ class InspircdIRCdMessage : public IRCdMessage
if (!modes.empty())
modes.erase(modes.begin());
/* Set the modes internally */
- c->SetModesInternal(NULL, modes);
+ c->SetModesInternal(source, modes);
}
spacesepstream sep(params[params.size() - 1]);
@@ -468,7 +445,7 @@ class InspircdIRCdMessage : public IRCdMessage
* This will enforce secureops etc on the user
*/
for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
- c->SetModeInternal(NULL, *it, buf);
+ c->SetModeInternal(source, *it, buf);
/* Now set whatever modes this user is allowed to have on the channel */
chan_set_correct_modes(u, c, 1, true);
@@ -495,33 +472,268 @@ class InspircdIRCdMessage : public IRCdMessage
}
};
-bool event_idle(const Anope::string &source, const std::vector<Anope::string> &params)
+struct IRCDMessageFMode : IRCDMessage
+{
+ IRCDMessageFMode() : IRCDMessage("FMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ /* :source FMODE #test 12345678 +nto foo */
+
+ Anope::string modes = params[2];
+ for (unsigned n = 3; n < params.size(); ++n)
+ modes += " " + params[n];
+
+ Channel *c = findchan(params[0]);
+ time_t ts;
+
+ try
+ {
+ ts = convertTo<time_t>(params[1]);
+ }
+ catch (const ConvertException &)
+ {
+ ts = Anope::CurTime;
+ }
+
+ if (c)
+ c->SetModesInternal(source, modes, ts);
+
+ return true;
+ }
+};
+
+struct IRCDMessageFTopic : IRCDMessage
+{
+ IRCDMessageFTopic() : IRCDMessage("FTOPIC", 4) { }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ /* :source FTOPIC channel ts setby :topic */
+
+ Channel *c = findchan(params[0]);
+ if (c)
+ c->ChangeTopicInternal(params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime);
+
+ return true;
+ }
+};
+
+struct IRCDMessageIdle : IRCDMessage
+{
+ IRCDMessageIdle() : IRCDMessage("IDLE", 1) { }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ const BotInfo *bi = findbot(params[0]);
+ if (bi)
+ UplinkSocket::Message(bi) << "IDLE " << source.GetSource() << " " << start_time << " " << (Anope::CurTime - bi->lastmsg);
+ return true;
+ }
+};
+
+/*
+ * source = numeric of the sending server
+ * params[0] = uuid
+ * params[1] = metadata name
+ * params[2] = data
+ */
+struct IRCDMessageMetadata : IRCDMessage
+{
+ IRCDMessageMetadata() : IRCDMessage("METADATA", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ if (params[1].equals_cs("accountname"))
+ {
+ User *u = finduser(params[0]);
+ NickCore *nc = findcore(params[2]);
+ if (u && nc)
+ {
+ u->Login(nc);
+
+ const NickAlias *user_na = findnick(u->nick);
+ if (!Config->NoNicknameOwnership && nickserv && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
+ u->SetMode(findbot(Config->NickServ), UMODE_REGISTERED);
+ }
+ }
+
+ /*
+ * possible incoming ssl_cert messages:
+ * Received: :409 METADATA 409AAAAAA ssl_cert :vTrSe c38070ce96e41cc144ed6590a68d45a6 <...> <...>
+ * Received: :409 METADATA 409AAAAAC ssl_cert :vTrSE Could not get peer certificate: error:00000000:lib(0):func(0):reason(0)
+ */
+ else if (params[1].equals_cs("ssl_cert"))
+ {
+ User *u = finduser(params[0]);
+ if (!u)
+ return true;
+ std::string data = params[2].c_str();
+ size_t pos1 = data.find(' ') + 1;
+ size_t pos2 = data.find(' ', pos1);
+ if ((pos2 - pos1) >= 32) // inspircd supports md5 and sha1 fingerprint hashes -> size 32 or 40 bytes.
+ {
+ u->fingerprint = data.substr(pos1, pos2 - pos1);
+ FOREACH_MOD(I_OnFingerprint, OnFingerprint(u));
+ }
+ }
+ return true;
+ }
+};
+
+struct IRCDMessageMode : IRCDMessage
+{
+ IRCDMessageMode() : IRCDMessage("MODE", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ if (ircdproto->IsChannelValid(params[0]))
+ {
+ Channel *c = findchan(params[0]);
+ time_t ts;
+
+ try
+ {
+ ts = convertTo<time_t>(params[1]);
+ }
+ catch (const ConvertException &)
+ {
+ ts = Anope::CurTime;
+ }
+
+ if (c)
+ c->SetModesInternal(source, params[2], ts);
+ }
+ else
+ {
+ /* InspIRCd lets opers change another
+ users modes, we have to kludge this
+ as it slightly breaks RFC1459
+ */
+ User *u = source.GetUser();
+ // This can happen with server-origin modes.
+ if (!u)
+ u = finduser(params[0]);
+ // if it's still null, drop it like fire.
+ // most likely situation was that server introduced a nick which we subsequently akilled
+ if (u)
+ u->SetModesInternal("%s", params[1].c_str());
+ }
+
+ return true;
+ }
+};
+
+struct IRCDMessageNick : IRCDMessage
+{
+ IRCDMessageNick() : IRCDMessage("NICK", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ source.GetUser()->ChangeNick(params[0]);
+ return true;
+ }
+};
+
+struct IRCDMessageOperType : IRCDMessage
+{
+ IRCDMessageOperType() : IRCDMessage("OPERTYPE", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_USER); }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ /* opertype is equivalent to mode +o because servers
+ dont do this directly */
+ User *u = source.GetUser();
+ if (!u->HasMode(UMODE_OPER))
+ u->SetModesInternal("+o");
+
+ return true;
+ }
+};
+
+struct IRCDMessageRSQuit : IRCDMessage
{
- const BotInfo *bi = findbot(params[0]);
- if (bi)
- UplinkSocket::Message(bi) << "IDLE " << source << " " << start_time << " " << (Anope::CurTime - bi->lastmsg);
- return true;
-}
+ IRCDMessageRSQuit() : IRCDMessage("RSQUIT", 1) { }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ Server *s = Server::Find(params[0]);
+ if (!s)
+ return true;
+
+ /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */
+ if (s->HasFlag(SERVER_JUPED))
+ UplinkSocket::Message(Me) << "SQUIT " << s->GetSID() << " :" << (params.size() > 1 ? params[1].c_str() : "");
+
+ FOREACH_MOD(I_OnServerQuit, OnServerQuit(s));
+
+ s->Delete(s->GetName() + " " + s->GetUplink()->GetName());
+
+ return true;
+ }
+};
-bool event_time(const Anope::string &source, const std::vector<Anope::string> &params)
+struct IRCDMessageServer : IRCDMessage
{
- if (params.size() < 2)
+ IRCDMessageServer() : IRCDMessage("SERVER", 5) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+
+ /*
+ * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central!
+ * 0: name
+ * 1: pass
+ * 2: hops
+ * 3: numeric
+ * 4: desc
+ */
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ unsigned int hops = Anope::string(params[2]).is_pos_number_only() ? convertTo<unsigned>(params[2]) : 0;
+ new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[4], params[3]);
return true;
+ }
+};
- UplinkSocket::Message(Me) << "TIME " << source << " " << params[1] << " " << Anope::CurTime;
- return true;
-}
+struct IRCDMessageTime : IRCDMessage
+{
+ IRCDMessageTime() : IRCDMessage("TIME", 2) { }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ UplinkSocket::Message(Me) << "TIME " << source.GetSource() << " " << params[1] << " " << Anope::CurTime;
+ return true;
+ }
+};
-bool event_rsquit(const Anope::string &source, const std::vector<Anope::string> &params)
+struct IRCDMessageUID : IRCDMessage
{
- /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */
- Server *s = Server::Find(params[0]);
- if (s && s->HasFlag(SERVER_JUPED))
- UplinkSocket::Message(Me) << "SQUIT " << s->GetSID() << " :" << (params.size() > 1 ? params[1].c_str() : "");
+ IRCDMessageUID() : IRCDMessage("UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
+
+ /*
+ * [Nov 03 22:09:58.176252 2009] debug: Received: :964 UID 964AAAAAC 1225746297 w00t2 localhost testnet.user w00t 127.0.0.1 1225746302 +iosw +ACGJKLNOQcdfgjklnoqtx :Robin Burchell <w00t@inspircd.org>
+ * 0: uid
+ * 1: ts
+ * 2: nick
+ * 3: host
+ * 4: dhost
+ * 5: ident
+ * 6: ip
+ * 7: signon
+ * 8+: modes and params -- IMPORTANT, some modes (e.g. +s) may have parameters. So don't assume a fixed position of realname!
+ * last: realname
+ */
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ time_t ts = convertTo<time_t>(params[1]);
- ircdmessage->OnSQuit(source, params);
+ Anope::string modes = params[8];
+ for (unsigned i = 9; i < params.size() - 1; ++i)
+ modes += " " + params[i];
- return true;
-}
+ User *u = new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0]);
+ if (u->server->IsSynced() && nickserv)
+ nickserv->Validate(u);
+ return true;
+ }
+};
diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp
index 7470d61aa..1eba8321f 100644
--- a/modules/protocol/inspircd11.cpp
+++ b/modules/protocol/inspircd11.cpp
@@ -13,31 +13,6 @@
#include "module.h"
-IRCDVar myIrcd = {
- "InspIRCd 1.1", /* ircd name */
- "+I", /* Modes used by pseudoclients */
- 1, /* SVSNICK */
- 1, /* Vhost */
- 1, /* Supports SNlines */
- 1, /* Supports SQlines */
- 1, /* Supports SZlines */
- 1, /* Join 2 Message */
- 0, /* Chan SQlines */
- 0, /* Quit on Kill */
- 1, /* vidents */
- 1, /* svshold */
- 0, /* time stamp on mode */
- 1, /* O:LINE */
- 1, /* UMODE */
- 1, /* No Knock requires +i */
- 0, /* Can remove User Channel Modes with SVSMODE */
- 0, /* Sglines are not enforced until user reconnects */
- 0, /* ts6 */
- "$", /* TLD Prefix for Global */
- 20, /* Max number of modes we can send per line */
- 0 /* IRCd sends a SSL users certificate fingerprint */
-};
-
static bool has_servicesmod = false;
static bool has_globopsmod = false;
static bool has_svsholdmod = false;
@@ -45,40 +20,60 @@ static bool has_chghostmod = false;
static bool has_chgidentmod = false;
static bool has_hidechansmod = false;
-/* CHGHOST */
-void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost)
+class InspIRCdProto : public IRCDProto
{
- const BotInfo *bi = findbot(Config->OperServ);
- if (has_chghostmod)
+ public:
+ InspIRCdProto() : IRCDProto("InspIRCd 1.1")
{
- if (nick.empty() || vhost.empty())
- return;
- UplinkSocket::Message(bi) << "CHGHOST " << nick << " " << vhost;
+ DefaultPseudoclientModes = "+I";
+ CanSVSNick = true;
+ CanSetVHost = true;
+ CanSetVIdent = true;
+ CanSNLine = true;
+ CanSQLine = true;
+ CanSZLine = true;
+ CanSVSHold = true;
+ CanSVSO = true;
+ MaxModes = 20;
}
- else
+ private:
+
+ Anope::string current_pass;
+
+ void inspircd_cmd_chgident(const Anope::string &nick, const Anope::string &vIdent)
{
- if (bi)
- ircdproto->SendGlobops(bi, "CHGHOST not loaded!");
+ if (has_chgidentmod)
+ {
+ if (nick.empty() || vIdent.empty())
+ return;
+ UplinkSocket::Message(findbot(Config->OperServ)) << "CHGIDENT " << nick << " " << vIdent;
+ }
+ else
+ Log() << "CHGIDENT not loaded!";
}
-}
-bool event_idle(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- const BotInfo *bi = findbot(params[0]);
- UplinkSocket::Message(bi) << "IDLE " << source << " " << start_time << " " << (bi ? Anope::CurTime - bi->lastmsg : 0);
- return true;
-}
+ void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost)
+ {
+ if (has_chghostmod)
+ {
+ if (nick.empty() || vhost.empty())
+ return;
+ UplinkSocket::Message(findbot(Config->OperServ)) << "CHGHOST " << nick << " " << vhost;
+ }
+ else
+ Log() << "CHGHOST not loaded!";
+ }
-static Anope::string currentpass;
+ void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ {
+ UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
+ }
-/* PASS */
-void inspircd_cmd_pass(const Anope::string &pass)
-{
- currentpass = pass;
-}
+ void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
+ {
+ UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
+ }
-class InspIRCdProto : public IRCDProto
-{
void SendAkillDel(const XLine *x) anope_override
{
if (x->IsRegex() || x->HasNickOrReal())
@@ -159,12 +154,18 @@ class InspIRCdProto : public IRCDProto
UplinkSocket::Message(Me) << "ADDLINE G " << x->Mask << " " << x->By << " " << Anope::CurTime << " " << timeleft << " :" << x->GetReason();
}
- void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf) anope_override
+ void SendSVSKillInternal(const BotInfo *source, User *user, cons