summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/botserv.example.conf13
-rw-r--r--data/chanserv.example.conf13
-rw-r--r--data/global.example.conf13
-rw-r--r--data/hostserv.example.conf13
-rw-r--r--data/memoserv.example.conf13
-rw-r--r--data/nickserv.example.conf13
-rw-r--r--data/operserv.example.conf13
-rw-r--r--docs/TODO4
-rw-r--r--include/bots.h3
-rw-r--r--include/services.h2
-rw-r--r--include/users.h5
-rw-r--r--modules/commands/bs_bot.cpp2
-rw-r--r--modules/protocol/bahamut.cpp5
-rw-r--r--modules/protocol/inspircd-ts6.h3
-rw-r--r--modules/protocol/inspircd11.cpp3
-rw-r--r--modules/protocol/plexus.cpp5
-rw-r--r--modules/protocol/ratbox.cpp5
-rw-r--r--modules/protocol/unreal.cpp7
-rw-r--r--src/bots.cpp9
-rw-r--r--src/config.cpp9
-rw-r--r--src/init.cpp2
-rw-r--r--src/nickserv.cpp2
-rw-r--r--src/servers.cpp8
-rw-r--r--src/users.cpp16
24 files changed, 150 insertions, 31 deletions
diff --git a/data/botserv.example.conf b/data/botserv.example.conf
index 0c763cfea..e52a88943 100644
--- a/data/botserv.example.conf
+++ b/data/botserv.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the BotServ client.
*/
gecos = "Bot Service"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf
index 048dee6cc..12f4840a5 100644
--- a/data/chanserv.example.conf
+++ b/data/chanserv.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the ChanServ client.
*/
gecos = "Channel Registration Service"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/data/global.example.conf b/data/global.example.conf
index d60144056..d5a4119c7 100644
--- a/data/global.example.conf
+++ b/data/global.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the Global client.
*/
gecos = "Global Noticer"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/data/hostserv.example.conf b/data/hostserv.example.conf
index 73c12f1c8..7e30cfccd 100644
--- a/data/hostserv.example.conf
+++ b/data/hostserv.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the HostServ client.
*/
gecos = "vHost Service"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/data/memoserv.example.conf b/data/memoserv.example.conf
index af52fa5b2..181ee66d1 100644
--- a/data/memoserv.example.conf
+++ b/data/memoserv.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the MemoServ client.
*/
gecos = "Memo Service"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf
index ba5d5225f..c7dbaa68f 100644
--- a/data/nickserv.example.conf
+++ b/data/nickserv.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the NickServ client.
*/
gecos = "Nickname Registration Service"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/data/operserv.example.conf b/data/operserv.example.conf
index 3779ea54a..0e5801441 100644
--- a/data/operserv.example.conf
+++ b/data/operserv.example.conf
@@ -26,6 +26,19 @@ service
* The realname of the OperServ client.
*/
gecos = "Operator Service"
+
+ /*
+ * The modes this client should use.
+ * Do not modify this unless you know what you are doing.
+ *
+ * These modes are very IRCd specific. If left commented, sane defaults
+ * are used based on what protocol module you have loaded.
+ *
+ * Note that setting this option incorrectly could potentially BREAK some if
+ * not all usefulness of the client. We will not support you if this client is
+ * unable to do certain things if this option is enabled.
+ */
+ #modes = "+o"
}
/*
diff --git a/docs/TODO b/docs/TODO
index 49a7dbacb..aa078f210 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -11,8 +11,7 @@ Legend:
[x] Rewrite commands system
[x] Rewrite access system
[x] NS INFO: separate field for last seen realhost, shown to SRA only
-[ ] Customize email messages
-[ ] Configurable bot usermodes
+[x] Configurable bot usermodes
Future
@@ -34,3 +33,4 @@ Future
[ ] HS ACTIVATE -ALL (rob sez this all needs reviewing)
[ ] No nickname ownership?
[ ] More commands need to be split up such as /bs bot, /ms set, /bs kick, /bs set, /os set? etc.
+[ ] Customize email messages
diff --git a/include/bots.h b/include/bots.h
index 446287abf..477380c2c 100644
--- a/include/bots.h
+++ b/include/bots.h
@@ -40,6 +40,7 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
time_t lastmsg; /* Last time we said something */
typedef Anope::insensitive_map<CommandInfo> command_map;
command_map commands; /* Commands, actual name to service name */
+ Anope::string botmodes; /* Modes the bot should have as configured in service:modes */
/** Create a new bot.
* @param nick The nickname to assign to the bot.
@@ -47,7 +48,7 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
* @param host The hostname to give the bot.
* @param real The realname to give the bot.
*/
- BotInfo(const Anope::string &nick, const Anope::string &user = "", const Anope::string &host = "", const Anope::string &real = "");
+ BotInfo(const Anope::string &nick, const Anope::string &user = "", const Anope::string &host = "", const Anope::string &real = "", const Anope::string &modes = "");
/** Destroy a bot, clearing up appropriately.
*/
diff --git a/include/services.h b/include/services.h
index 6e7243c10..388eff5d8 100644
--- a/include/services.h
+++ b/include/services.h
@@ -800,7 +800,7 @@ class CoreExport IRCDProto
virtual void SendSVSKill(const BotInfo *source, const User *user, const char *fmt, ...);
virtual void SendMode(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
virtual void SendMode(const BotInfo *bi, const User *u, const char *fmt, ...);
- virtual void SendClientIntroduction(const User *u, const Anope::string &) = 0;
+ virtual void SendClientIntroduction(const User *u) = 0;
virtual void SendKick(const BotInfo *bi, const Channel *chan, const User *user, const char *fmt, ...);
virtual void SendNoticeChanops(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
virtual void SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
diff --git a/include/users.h b/include/users.h
index b02705bda..6d7d8635e 100644
--- a/include/users.h
+++ b/include/users.h
@@ -271,6 +271,11 @@ class CoreExport User : public Extensible
*/
void SetModesInternal(const char *umodes, ...);
+ /** Get modes set for this user.
+ * @return A string of modes set on the user
+ */
+ Anope::string GetModes() const;
+
/** Find the channel container for Channel c that the user is on
* This is preferred over using FindUser in Channel, as there are usually more users in a channel
* than channels a user is in
diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp
index 7500d1926..02af6b340 100644
--- a/modules/commands/bs_bot.cpp
+++ b/modules/commands/bs_bot.cpp
@@ -249,7 +249,7 @@ class CommandBSBot : public Command
if (!user.empty())
{
- ircdproto->SendClientIntroduction(bi, ircd->pseudoclient_mode);
+ ircdproto->SendClientIntroduction(bi);
bi->RejoinAll();
}
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 1fca45c39..cecc480f3 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -214,10 +214,9 @@ class BahamutIRCdProto : public IRCDProto
send_cmd(source->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
}
- void SendClientIntroduction(const User *u, const Anope::string &modes)
+ void SendClientIntroduction(const User *u)
{
- XLine x(u->nick, "Reserved for services");
- ircdproto->SendSQLine(NULL, &x);
+ Anope::string modes = "+" + u->GetModes();
send_cmd("", "NICK %s 1 %ld %s %s %s %s 0 0 :%s", u->nick.c_str(), static_cast<long>(u->timestamp), modes.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->server->GetName().c_str(), u->realname.c_str());
}
diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h
index 2a60062b2..e4d9995b3 100644
--- a/modules/protocol/inspircd-ts6.h
+++ b/modules/protocol/inspircd-ts6.h
@@ -103,8 +103,9 @@ class InspIRCdTS6Proto : public IRCDProto
send_cmd(bi ? bi->GetUID() : Config->Numeric, "MODE %s %s", u->GetUID().c_str(), buf.c_str());
}
- void SendClientIntroduction(const User *u, const Anope::string &modes)
+ void SendClientIntroduction(const User *u)
{
+ Anope::string modes = "+" + u->GetModes();
send_cmd(Config->Numeric, "UID %s %ld %s %s %s %s 0.0.0.0 %ld %s :%s", u->GetUID().c_str(), static_cast<long>(u->timestamp), u->nick.c_str(), u->host.c_str(), u->host.c_str(), u->GetIdent().c_str(), static_cast<long>(u->my_signon), modes.c_str(), u->realname.c_str());
}
diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp
index effd280c9..4d39c585d 100644
--- a/modules/protocol/inspircd11.cpp
+++ b/modules/protocol/inspircd11.cpp
@@ -135,8 +135,9 @@ class InspIRCdProto : public IRCDProto
send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
}
- void SendClientIntroduction(const User *u, const Anope::string &modes)
+ void SendClientIntroduction(const User *u)
{
+ Anope::string modes = "+" + u->GetModes();
send_cmd(Config->ServerName, "NICK %ld %s %s %s %s %s 0.0.0.0 :%s", static_cast<long>(u->timestamp), u->nick.c_str(), u->host.c_str(), u->host.c_str(), u->GetIdent().c_str(), modes.c_str(), u->realname.c_str());
send_cmd(u->nick, "OPERTYPE Service");
}
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index 038ed0358..2379dcc27 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -168,10 +168,9 @@ class PlexusProto : public IRCDProto
plexus_cmd_svinfo();
}
- void SendClientIntroduction(const User *u, const Anope::string &modes)
+ void SendClientIntroduction(const User *u)
{
- XLine x(u->nick, "Reserved for services");
- ircdproto->SendSQLine(NULL, &x);
+ Anope::string modes = "+" + u->GetModes();
send_cmd(Config->Numeric, "UID %s 1 %ld %s %s %s 255.255.255.255 %s 0 %s :%s", u->nick.c_str(), static_cast<long>(u->timestamp), modes.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->GetUID().c_str(), u->host.c_str(), u->realname.c_str());
}
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index e52493aed..516452ce5 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -168,10 +168,9 @@ class RatboxProto : public IRCDProto
ratbox_cmd_svinfo();
}
- void SendClientIntroduction(const User *u, const Anope::string &modes)
+ void SendClientIntroduction(const User *u)
{
- XLine x(u->nick, "Reserved for services");
- ircdproto->SendSQLine(NULL, &x);
+ Anope::string modes = "+" + u->GetModes();
send_cmd(Config->Numeric, "UID %s 1 %ld %s %s %s 0 %s :%s", u->nick.c_str(), static_cast<long>(u->timestamp), modes.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->GetUID().c_str(), u->realname.c_str());
}
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 4f8bc5e6f..60419c481 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -140,11 +140,10 @@ class UnrealIRCdProto : public IRCDProto
send_cmd(bi ? bi->nick : Config->ServerName, "v %s %s", u->nick.c_str(), buf.c_str());
}
- void SendClientIntroduction(const User *u, const Anope::string &modes)
+ void SendClientIntroduction(const User *u)
{
- XLine x(u->nick, "Reserved for services");
- ircdproto->SendSQLine(NULL, &x);
- send_cmd("", "& %s 1 %ld %s %s %s 0 %s %s * :%s", u->nick.c_str(), static_cast<long>(u->timestamp), u->GetIdent().c_str(), u->host.c_str(), Config->ServerName.c_str(), modes.c_str(), u->host.c_str(), u->realname.c_str());
+ Anope::string modes = "+" + u->GetModes();
+ send_cmd("", "& %s 1 %ld %s %s %s 0 %s %s * :%s", u->nick.c_str(), static_cast<long>(u->timestamp), u->GetIdent().c_str(), u->host.c_str(), u->server->GetName().c_str(), modes.c_str(), u->host.c_str(), u->realname.c_str());
}
void SendKickInternal(const BotInfo *source, const Channel *chan, const User *user, const Anope::string &buf)
diff --git a/src/bots.cpp b/src/bots.cpp
index 2ebe4bb58..e94691b05 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -13,7 +13,7 @@
Anope::insensitive_map<BotInfo *> BotListByNick;
Anope::map<BotInfo *> BotListByUID;
-BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal) : User(nnick, nuser, nhost, ts6_uid_retrieve()), Flags<BotFlag, BI_END>(BotFlagString)
+BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &modes) : User(nnick, nuser, nhost, ts6_uid_retrieve()), Flags<BotFlag, BI_END>(BotFlagString), botmodes(modes)
{
this->realname = nreal;
this->server = Me;
@@ -28,13 +28,14 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A
// If we're synchronised with the uplink already, send the bot.
if (Me && Me->IsSynced())
{
- ircdproto->SendClientIntroduction(this, ircd->pseudoclient_mode);
+ ircdproto->SendClientIntroduction(this);
XLine x(this->nick, "Reserved for services");
ircdproto->SendSQLine(NULL, &x);
}
- this->SetModeInternal(ModeManager::FindUserModeByName(UMODE_PROTECTED));
- this->SetModeInternal(ModeManager::FindUserModeByName(UMODE_GOD));
+ Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : (ircd ? ircd->pseudoclient_mode : "");
+ if (!tmodes.empty())
+ this->SetModesInternal(tmodes.c_str());
if (Config)
for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
diff --git a/src/config.cpp b/src/config.cpp
index c4d59d6fc..baedb92ba 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -937,6 +937,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope:
Anope::string user = values[1].GetValue();
Anope::string host = values[2].GetValue();
Anope::string gecos = values[3].GetValue();
+ Anope::string modes = values[4].GetValue();
ValueItem vi(nick);
if (!ValidateNotEmpty(config, "service", "nick", vi))
@@ -958,7 +959,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope:
BotInfo *bi = findbot(nick);
if (bi != NULL)
return true;
- bi = new BotInfo(nick, user, host, gecos);
+ bi = new BotInfo(nick, user, host, gecos, modes);
bi->SetFlag(BI_CONF);
return true;
}
@@ -1257,9 +1258,9 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{DT_STRING, DT_STRING, DT_STRING, DT_STRING},
InitOpers, DoOper, DoneOpers},
{"service",
- {"nick", "user", "host", "gecos", ""},
- {"", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING},
+ {"nick", "user", "host", "gecos", "modes", ""},
+ {"", "", "", "", "", ""},
+ {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
InitServices, DoServices, DoneServices},
{"log",
{"target", "source", "logage", "inhabitlogchannel", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
diff --git a/src/init.cpp b/src/init.cpp
index 721b6aa8e..0a218f099 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -27,7 +27,7 @@ void introduce_user(const Anope::string &user)
User *u = finduser(user);
if (u)
{
- ircdproto->SendClientIntroduction(u, ircd->pseudoclient_mode);
+ ircdproto->SendClientIntroduction(u);
BotInfo *bi = findbot(u->nick);
if (bi)
diff --git a/src/nickserv.cpp b/src/nickserv.cpp
index 9825c3ecc..c88eab55f 100644
--- a/src/nickserv.cpp
+++ b/src/nickserv.cpp
@@ -60,7 +60,7 @@ NickServRelease::NickServRelease(NickAlias *na, time_t delay) : User(na->nick, C
NickServReleases.insert(std::make_pair(this->nick, this));
- ircdproto->SendClientIntroduction(this, "+");
+ ircdproto->SendClientIntroduction(this);
}
NickServRelease::~NickServRelease()
diff --git a/src/servers.cpp b/src/servers.cpp
index 2ebf555c7..e63311eef 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -55,6 +55,12 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A
/* Load MLock from the database now that we know what modes exist */
for (registered_channel_map::iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
it->second->LoadMLock();
+ for (botinfo_map::iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
+ {
+ BotInfo *bi = it->second;
+ Anope::string modes = !bi->botmodes.empty() ? ("+" + bi->botmodes) : ircd->pseudoclient_mode;
+ bi->SetModesInternal(modes.c_str());
+ }
ircdproto->SendBOB();
@@ -71,7 +77,7 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A
{
User *u = it->second;
- ircdproto->SendClientIntroduction(u, ircd->pseudoclient_mode);
+ ircdproto->SendClientIntroduction(u);
BotInfo *bi = findbot(u->nick);
if (bi)
diff --git a/src/users.cpp b/src/users.cpp
index d1b9945b9..9e4b935fc 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -705,6 +705,22 @@ void User::SetModesInternal(const char *umodes, ...)
}
}
+Anope::string User::GetModes() const
+{
+ Anope::string ret;
+
+ for (size_t i = UMODE_BEGIN + 1; i < UMODE_END; ++i)
+ if (this->modes.HasFlag(static_cast<UserModeName>(i)))
+ {
+ UserMode *um = ModeManager::FindUserModeByName(static_cast<UserModeName>(i));
+ if (um == NULL)
+ continue;
+ ret += um->ModeChar;
+ }
+
+ return ret;
+}
+
/** Find the channel container for Channel c that the user is on
* This is preferred over using FindUser in Channel, as there are usually more users in a channel
* than channels a user is in