Anope IRC Services  Version 2.0
bots.cpp
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
4  * Copyright (C) 2008-2014 Anope Team <team@anope.org>
5  *
6  * Please read COPYING and README for further details.
7  *
8  */
9 
10 #include "services.h"
11 #include "anope.h"
12 #include "bots.h"
13 #include "servers.h"
14 #include "protocol.h"
15 #include "xline.h"
16 #include "regchannel.h"
17 #include "channels.h"
18 #include "config.h"
19 #include "language.h"
20 #include "serialize.h"
21 
23 
24 BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes)
25 {
26  this->lastmsg = this->created = Anope::CurTime;
27  this->introduced = false;
28  this->oper_only = this->conf = false;
29 
30  (*BotListByNick)[this->nick] = this;
31  if (!this->uid.empty())
32  (*BotListByUID)[this->uid] = this;
33 
34  FOREACH_MOD(OnCreateBot, (this));
35 
36  // If we're synchronised with the uplink already, send the bot.
37  if (Me && Me->IsSynced())
38  {
39  Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : IRCD->DefaultPseudoclientModes;
40  if (!tmodes.empty())
41  this->SetModesInternal(this, tmodes.c_str());
42 
43  XLine x(this->nick, "Reserved for services");
44  IRCD->SendSQLine(NULL, &x);
46  this->introduced = true;
47  }
48 }
49 
51 {
52  FOREACH_MOD(OnDelBot, (this));
53 
54  // If we're synchronised with the uplink already, send the bot.
55  if (Me && Me->IsSynced())
56  {
57  IRCD->SendQuit(this, "");
58  FOREACH_MOD(OnUserQuit, (this, ""));
59  this->introduced = false;
60  XLine x(this->nick);
61  IRCD->SendSQLineDel(&x);
62  }
63 
64  for (std::set<ChannelInfo *>::iterator it = this->channels->begin(), it_end = this->channels->end(); it != it_end; ++it)
65  {
66  ChannelInfo *ci = *it;
67  this->UnAssign(NULL, ci);
68  }
69 
70  BotListByNick->erase(this->nick);
71  if (!this->uid.empty())
72  BotListByUID->erase(this->uid);
73 }
74 
76 {
77  data["nick"] << this->nick;
78  data["user"] << this->ident;
79  data["host"] << this->host;
80  data["realname"] << this->realname;
81  data["created"] << this->created;
82  data["oper_only"] << this->oper_only;
83 
84  Extensible::ExtensibleSerialize(this, this, data);
85 }
86 
88 {
89  Anope::string nick, user, host, realname, flags;
90 
91  data["nick"] >> nick;
92  data["user"] >> user;
93  data["host"] >> host;
94  data["realname"] >> realname;
95 
96  BotInfo *bi;
97  if (obj)
99  else if (!(bi = BotInfo::Find(nick, true)))
100  bi = new BotInfo(nick, user, host, realname);
101 
102  data["created"] >> bi->created;
103  data["oper_only"] >> bi->oper_only;
104 
105  Extensible::ExtensibleUnserialize(bi, bi, data);
106 
107  return bi;
108 }
109 
111 {
112  if (this->introduced)
113  throw CoreException("Changing bot UID when it is introduced?");
114 
115  if (!this->uid.empty())
116  {
117  BotListByUID->erase(this->uid);
118  UserListByUID.erase(this->uid);
119  }
120 
121  this->uid = IRCD->UID_Retrieve();
122  (*BotListByUID)[this->uid] = this;
123  UserListByUID[this->uid] = this;
124 }
125 
127 {
128  this->introduced = false;
129  this->GenerateUID();
131  this->introduced = true;
132 
133  for (User::ChanUserList::const_iterator cit = this->chans.begin(), cit_end = this->chans.end(); cit != cit_end; ++cit)
134  IRCD->SendJoin(this, cit->second->chan, &cit->second->status);
135 }
136 
137 void BotInfo::SetNewNick(const Anope::string &newnick)
138 {
139  UserListByNick.erase(this->nick);
140  BotListByNick->erase(this->nick);
141 
142  this->nick = newnick;
143 
144  UserListByNick[this->nick] = this;
145  (*BotListByNick)[this->nick] = this;
146 }
147 
148 const std::set<ChannelInfo *> &BotInfo::GetChannels() const
149 {
150  return this->channels;
151 }
152 
154 {
155  EventReturn MOD_RESULT;
156  FOREACH_RESULT(OnPreBotAssign, MOD_RESULT, (u, ci, this));
157  if (MOD_RESULT == EVENT_STOP)
158  return;
159 
160  if (ci->bi)
161  ci->bi->UnAssign(u, ci);
162 
163  ci->bi = this;
164  this->channels->insert(ci);
165 
166  FOREACH_MOD(OnBotAssign, (u, ci, this));
167 }
168 
170 {
171  EventReturn MOD_RESULT;
172  FOREACH_RESULT(OnBotUnAssign, MOD_RESULT, (u, ci));
173  if (MOD_RESULT == EVENT_STOP)
174  return;
175 
176  if (ci->c && ci->c->FindUser(ci->bi))
177  {
178  if (u)
179  ci->bi->Part(ci->c, "UNASSIGN from " + u->nick);
180  else
181  ci->bi->Part(ci->c);
182  }
183 
184  ci->bi = NULL;
185  this->channels->erase(ci);
186 }
187 
188 unsigned BotInfo::GetChannelCount() const
189 {
190  return this->channels->size();
191 }
192 
194 {
195  if (c->FindUser(this) != NULL)
196  return;
197 
198  c->JoinUser(this, status);
199  if (IRCD)
200  IRCD->SendJoin(this, c, status);
201 
202  FOREACH_MOD(OnJoinChannel, (this, c));
203 }
204 
205 void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
206 {
207  bool c;
208  return this->Join(Channel::FindOrCreate(chname, c), status);
209 }
210 
211 void BotInfo::Part(Channel *c, const Anope::string &reason)
212 {
213  if (c->FindUser(this) == NULL)
214  return;
215 
216  IRCD->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : "");
217 
218  c->DeleteUser(this);
219 
220  FOREACH_MOD(OnPartChannel, (this, c, c->name, reason));
221 }
222 
223 void BotInfo::OnMessage(User *u, const Anope::string &message)
224 {
225  if (this->commands.empty())
226  return;
227 
228  CommandSource source(u->nick, u, u->Account(), u, this);
229  Command::Run(source, message);
230 }
231 
232 CommandInfo& BotInfo::SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission)
233 {
234  CommandInfo ci;
235  ci.name = sname;
236  ci.permission = permission;
237  this->commands[cname] = ci;
238  return this->commands[cname];
239 }
240 
242 {
243  CommandInfo::map::iterator it = this->commands.find(cname);
244  if (it != this->commands.end())
245  return &it->second;
246  return NULL;
247 }
248 
249 BotInfo* BotInfo::Find(const Anope::string &nick, bool nick_only)
250 {
251  if (!nick_only && IRCD != NULL && IRCD->RequiresID)
252  {
253  botinfo_map::iterator it = BotListByUID->find(nick);
254  if (it != BotListByUID->end())
255  {
256  BotInfo *bi = it->second;
257  bi->QueueUpdate();
258  return bi;
259  }
260 
261  if (IRCD->AmbiguousID)
262  return NULL;
263  }
264 
265  botinfo_map::iterator it = BotListByNick->find(nick);
266  if (it != BotListByNick->end())
267  {
268  BotInfo *bi = it->second;
269  bi->QueueUpdate();
270  return bi;
271  }
272 
273  return NULL;
274 }
275 
Definition: bots.h:24
Anope::string permission
Definition: commands.h:34
ChanUserContainer * JoinUser(User *u, const ChannelStatus *status)
Definition: channels.cpp:140
void UnAssign(User *u, ChannelInfo *ci)
Definition: bots.cpp:169
Serialize::Checker< botinfo_map > BotListByNick("BotInfo")
bool AmbiguousID
Definition: protocol.h:71
Anope::string name
Definition: commands.h:32
Anope::string uid
Definition: users.h:46
Serialize::Checker< std::set< ChannelInfo * > > channels
Definition: bots.h:27
bool IsSynced() const
Definition: servers.cpp:298
Definition: hashcomp.h:84
void Join(Channel *c, ChannelStatus *status=NULL)
Definition: bots.cpp:193
void DeleteUser(User *u)
Definition: channels.cpp:154
Anope::string ident
Definition: users.h:45
void Assign(User *u, ChannelInfo *ci)
Definition: bots.cpp:153
time_t lastmsg
Definition: bots.h:31
Anope::string botmodes
Definition: bots.h:35
virtual void SendPart(User *u, const Channel *chan, const char *fmt,...)
Definition: protocol.cpp:289
CommandInfo::map commands
Definition: bots.h:33
ChanUserList chans
Definition: users.h:87
void OnKill()
Definition: bots.cpp:126
BotInfo(const Anope::string &nick, const Anope::string &user="", const Anope::string &host="", const Anope::string &real="", const Anope::string &bmodes="")
Definition: bots.cpp:24
void QueueUpdate()
Definition: serialize.cpp:83
Definition: users.h:34
Anope::string DefaultPseudoclientModes
Definition: protocol.h:47
bool introduced
Definition: bots.h:39
virtual void SendSQLine(User *, const XLine *x)
Definition: protocol.h:120
CommandInfo & SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission="")
Definition: bots.cpp:232
virtual void SendSQLineDel(const XLine *x)
Definition: protocol.h:121
bool conf
Definition: bots.h:43
#define FOREACH_RESULT(ename, ret, args)
Definition: modules.h:95
static Channel * FindOrCreate(const Anope::string &name, bool &created, time_t ts=Anope::CurTime)
Definition: channels.cpp:929
virtual void OnMessage(User *u, const Anope::string &message)
Definition: bots.cpp:223
virtual void SendQuit(User *u, const char *fmt,...)
Definition: protocol.cpp:252
bool RequiresID
Definition: protocol.h:69
Anope::string name
Definition: channels.h:44
CoreExport time_t CurTime
Definition: main.cpp:41
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
void SetNewNick(const Anope::string &newnick)
Definition: bots.cpp:137
CoreExport user_map UserListByUID
Definition: users.cpp:28
Channel * c
Definition: regchannel.h:79
static Serializable * Unserialize(Serializable *obj, Serialize::Data &)
Definition: bots.cpp:87
unsigned GetChannelCount() const
Definition: bots.cpp:188
static void ExtensibleUnserialize(Extensible *, Serializable *, Serialize::Data &data)
Definition: extensible.cpp:50
void Part(Channel *c, const Anope::string &reason="")
Definition: bots.cpp:211
bool empty() const
Definition: anope.h:126
static void Run(CommandSource &source, const Anope::string &message)
Definition: command.cpp:199
Anope::string host
Definition: users.h:65
CoreExport IRCDProto * IRCD
Definition: protocol.cpp:23
EventReturn
Definition: modules.h:129
ChanUserContainer * FindUser(User *u) const
Definition: channels.cpp:173
time_t created
Definition: bots.h:29
Anope::string realname
Definition: users.h:71
bool oper_only
Definition: bots.h:41
Anope::string nick
Definition: users.h:62
const std::set< ChannelInfo * > & GetChannels() const
Definition: bots.cpp:148
NickCore * Account() const
Definition: users.cpp:422
Definition: xline.h:18
T anope_dynamic_static_cast(O ptr)
Definition: anope.h:774
virtual void SendClientIntroduction(User *u)=0
CoreExport Server * Me
Definition: servers.cpp:24
CoreExport user_map UserListByNick
Definition: users.cpp:28
void SetModesInternal(const MessageSource &source, const char *umodes,...)
Definition: users.cpp:645
virtual ~BotInfo()
Definition: bots.cpp:50
const char * c_str() const
Definition: anope.h:117
virtual Anope::string UID_Retrieve()
Definition: protocol.cpp:59
virtual void SendJoin(User *u, Channel *c, const ChannelStatus *status)=0
Serialize::Reference< BotInfo > bi
Definition: regchannel.h:82
void GenerateUID()
Definition: bots.cpp:110
static void ExtensibleSerialize(const Extensible *, const Serializable *, Serialize::Data &data)
Definition: extensible.cpp:41
static BotInfo * Find(const Anope::string &nick, bool nick_only=false)
Definition: bots.cpp:249
void Serialize(Serialize::Data &data) const
Definition: bots.cpp:75
Definition: anope.h:20
CommandInfo * GetCommand(const Anope::string &cname)
Definition: bots.cpp:241
Serialize::Checker< botinfo_map > BotListByUID("BotInfo")