diff options
-rw-r--r-- | data/botserv.example.conf | 13 | ||||
-rw-r--r-- | data/chanserv.example.conf | 13 | ||||
-rw-r--r-- | data/global.example.conf | 13 | ||||
-rw-r--r-- | data/hostserv.example.conf | 13 | ||||
-rw-r--r-- | data/memoserv.example.conf | 13 | ||||
-rw-r--r-- | data/nickserv.example.conf | 13 | ||||
-rw-r--r-- | data/operserv.example.conf | 13 | ||||
-rw-r--r-- | docs/TODO | 4 | ||||
-rw-r--r-- | include/bots.h | 3 | ||||
-rw-r--r-- | include/services.h | 2 | ||||
-rw-r--r-- | include/users.h | 5 | ||||
-rw-r--r-- | modules/commands/bs_bot.cpp | 2 | ||||
-rw-r--r-- | modules/protocol/bahamut.cpp | 5 | ||||
-rw-r--r-- | modules/protocol/inspircd-ts6.h | 3 | ||||
-rw-r--r-- | modules/protocol/inspircd11.cpp | 3 | ||||
-rw-r--r-- | modules/protocol/plexus.cpp | 5 | ||||
-rw-r--r-- | modules/protocol/ratbox.cpp | 5 | ||||
-rw-r--r-- | modules/protocol/unreal.cpp | 7 | ||||
-rw-r--r-- | src/bots.cpp | 9 | ||||
-rw-r--r-- | src/config.cpp | 9 | ||||
-rw-r--r-- | src/init.cpp | 2 | ||||
-rw-r--r-- | src/nickserv.cpp | 2 | ||||
-rw-r--r-- | src/servers.cpp | 8 | ||||
-rw-r--r-- | src/users.cpp | 16 |
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" } /* @@ -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 |