Anope IRC Services  Version 2.0
botserv.cpp
Go to the documentation of this file.
1 /* BotServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  */
11 
12 #include "module.h"
13 
14 class BotServCore : public Module
15 {
18 
19  public:
20  BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
21  persist("PERSIST"), inhabit("inhabit")
22  {
23  }
24 
26  {
27  const Anope::string &bsnick = conf->GetModule(this)->Get<const Anope::string>("client");
28  BotServ = BotInfo::Find(bsnick, true);
29  }
30 
31  void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
32  {
33  /* Do not allow removing bot modes on our service bots */
34  if (chan->ci && chan->ci->bi == user)
35  {
36  const Anope::string &botmodes = Config->GetModule(this)->Get<const Anope::string>("botmodes");
37  for (unsigned i = 0; i < botmodes.length(); ++i)
38  chan->SetMode(chan->ci->bi, ModeManager::FindChannelModeByChar(botmodes[i]), chan->ci->bi->GetUID());
39  }
40  }
41 
43  {
44  if (ci->c && ci->c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers"))
45  {
46  ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes"));
47  bi->Join(ci->c, &status);
48  }
49  }
50 
52  {
53  if (!Config || !IRCD)
54  return;
55 
56  BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL;
57  if (bi && Config->GetModule(this)->Get<bool>("smartjoin"))
58  {
59  std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN");
60 
61  /* We check for bans */
62  for (; bans.first != bans.second; ++bans.first)
63  {
64  Entry ban("BAN", bans.first->second);
65  if (ban.Matches(user))
66  c->RemoveMode(NULL, "BAN", ban.GetMask());
67  }
68 
69  Anope::string Limit;
70  unsigned limit = 0;
71  try
72  {
73  if (c->GetParam("LIMIT", Limit))
74  limit = convertTo<unsigned>(Limit);
75  }
76  catch (const ConvertException &) { }
77 
78  /* Should we be invited? */
79  if (c->HasMode("INVITE") || (limit && c->users.size() >= limit))
80  {
82  char symbol = cm ? anope_dynamic_static_cast<ChannelModeStatus *>(cm)->symbol : 0;
83  IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, "%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str());
84  }
85 
87  }
88 
89  if (user->server != Me && c->ci && c->ci->bi)
90  {
97  /* This is before the user has joined the channel, so check usercount + 1 */
98  if (c->users.size() + 1 >= Config->GetModule(this)->Get<unsigned>("minusers") && !c->FindUser(c->ci->bi))
99  {
100  ChannelStatus status(Config->GetModule(this)->Get<const Anope::string>("botmodes"));
101  c->ci->bi->Join(c, &status);
102  }
103  }
104  }
105 
107  {
108  /* Channel is persistent, it shouldn't be deleted and the service bot should stay */
109  if (c->ci && persist && persist->HasExt(c->ci))
110  return;
111 
112  /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly
113  * We also don't part the bot here either, if necessary we will part it after the sync
114  */
115  if (c->syncing)
116  return;
117 
118  /* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */
119  if (inhabit && inhabit->HasExt(c))
120  return;
121 
122  /* This is called prior to removing the user from the channnel, so c->users.size() - 1 should be safe */
123  if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->GetModule(this)->Get<unsigned>("minusers") && c->FindUser(c->ci->bi))
124  c->ci->bi->Part(c->ci->c);
125  }
126 
127  EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
128  {
129  if (!params.empty())
130  return EVENT_CONTINUE;
131 
132  if (source.c)
133  {
134  source.Reply(_("\002%s\002 allows you to execute \"fantasy\" commands in the channel.\n"
135  "Fantasy commands are commands that can be executed from messaging a\n"
136  "channel, and provide a more convenient way to execute commands. Commands that\n"
137  "require a channel as a parameter will automatically have that parameter\n"
138  "given.\n"), source.service->nick.c_str());
139  const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<const Anope::string>("fantasycharacter", "!");
140  if (!fantasycharacters.empty())
141  source.Reply(_(" \n"
142  "Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str());
143  source.Reply(_(" \n"
144  "Available commands are:"));
145  }
146  else if (*source.service == BotServ)
147  {
148  source.Reply(_("\002%s\002 allows you to have a bot on your own channel.\n"
149  "It has been created for users that can't host or\n"
150  "configure a bot, or for use on networks that don't\n"
151  "allow user bots. Available commands are listed\n"
152  "below; to use them, type \002%s%s \037command\037\002. For\n"
153  "more information on a specific command, type\n"
154  "\002%s%s %s \037command\037\002.\n"),
155  BotServ->nick.c_str(), Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(),
156  Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), source.command.c_str());
157  }
158 
159  return EVENT_CONTINUE;
160  }
161 
162  void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
163  {
164  if (!params.empty() || source.c || source.service != *BotServ)
165  return;
166 
167  source.Reply(_(" \n"
168  "Bot will join a channel whenever there is at least\n"
169  "\002%d\002 user(s) on it."), Config->GetModule(this)->Get<unsigned>("minusers"));
170  const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<const Anope::string>("fantasycharacter", "!");
171  if (!fantasycharacters.empty())
172  source.Reply(_("Additionally, if fantasy is enabled fantasy commands\n"
173  "can be executed by prefixing the command name with\n"
174  "one of the following characters: %s"), fantasycharacters.c_str());
175  }
176 
178  {
179  if (source.GetUser() && !source.GetBot() && Config->GetModule(this)->Get<bool>("smartjoin") && mode->name == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
180  {
181  BotInfo *bi = c->ci->bi;
182 
183  Entry ban("BAN", param);
184  if (ban.Matches(bi))
185  c->RemoveMode(bi, "BAN", param);
186  }
187 
188  return EVENT_CONTINUE;
189  }
190 
192  {
193  /* Set default bot flags */
194  spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("defaults", "greet fantasy"));
195  for (Anope::string token; sep.GetToken(token);)
196  ci->Extend<bool>("BS_" + token.upper());
197  }
198 
199  void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override
200  {
201  BotInfo *bi = BotInfo::Find(target->GetUID());
202  if (bi)
203  /* Bots get rejoined */
204  bi->Join(channel, &status);
205  }
206 
208  {
209  if (bi->botmodes.empty())
210  bi->botmodes = Config->GetModule(this)->Get<const Anope::string>("botumodes");
211  }
212 };
213 
215 
Definition: bots.h:24
const Anope::string GetMask() const
Definition: modes.cpp:817
static ChannelMode * FindChannelModeByName(const Anope::string &name)
Definition: modes.cpp:542
bool Matches(User *u, bool full=false) const
Definition: modes.cpp:830
Definition: hashcomp.h:84
ExtensibleRef< bool > inhabit
Definition: botserv.cpp:17
void Join(Channel *c, ChannelStatus *status=NULL)
Definition: bots.cpp:193
BotServCore(const Anope::string &modname, const Anope::string &creator)
Definition: botserv.cpp:20
void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
Definition: botserv.cpp:31
virtual void SendNotice(const MessageSource &source, const Anope::string &dest, const char *fmt,...)
Definition: protocol.cpp:221
Definition: users.h:34
void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) anope_override
Definition: botserv.cpp:42
void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override
Definition: botserv.cpp:199
void OnReload(Configuration::Conf *conf) anope_override
Definition: botserv.cpp:25
ExtensibleRef< bool > persist
Definition: botserv.cpp:17
size_type length() const
Definition: anope.h:131
Definition: Config.cs:26
void OnCreateBot(BotInfo *bi) anope_override
Definition: botserv.cpp:207
void OnPostHelp(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: botserv.cpp:162
EventReturn OnChannelModeSet(Channel *c, MessageSource &source, ChannelMode *mode, const Anope::string &param) anope_override
Definition: botserv.cpp:177
void OnCreateChan(ChannelInfo *ci) anope_override
Definition: botserv.cpp:191
Reference< BotInfo > BotServ
Definition: botserv.cpp:16
void OnLeaveChannel(User *u, Channel *c) anope_override
Definition: botserv.cpp:106
static ChannelMode * FindChannelModeByChar(char mode)
Definition: modes.cpp:524
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
const ModeList & GetModeList() const
Definition: users.cpp:711
CoreExport IRCDProto * IRCD
Definition: protocol.cpp:23
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
Server * server
Definition: users.h:77
static void ProcessModes()
Definition: modes.cpp:633
Anope::string nick
Definition: users.h:62
void OnJoinChannel(User *user, Channel *c) anope_override
Definition: botserv.cpp:51
bool GetToken(Anope::string &token)
Definition: hashcomp.cpp:99
T anope_dynamic_static_cast(O ptr)
Definition: anope.h:774
CoreExport Server * Me
Definition: servers.cpp:24
const char * c_str() const
Definition: anope.h:117
EventReturn OnPreHelp(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: botserv.cpp:127
Definition: modes.h:388
#define _(x)
Definition: services.h:50
static BotInfo * Find(const Anope::string &nick, bool nick_only=false)
Definition: bots.cpp:249