Anope IRC Services  Version 2.0
irc2sql.cpp
Go to the documentation of this file.
1 #include "irc2sql.h"
2 
4 {
5  // TODO: test if we really have to use blocking query here
6  // (sometimes m_mysql get unloaded before the other thread executed all queries)
7  SQL::Result r = this->sql->RunQuery(SQL::Query("CALL " + prefix + "OnShutdown()"));
8  quitting = true;
9 }
10 
12 {
13  Configuration::Block *block = Config->GetModule(this);
14  prefix = block->Get<const Anope::string>("prefix", "anope_");
15  GeoIPDB = block->Get<const Anope::string>("geoip_database");
16  ctcpuser = block->Get<bool>("ctcpuser", "no");
17  ctcpeob = block->Get<bool>("ctcpeob", "yes");
18  Anope::string engine = block->Get<const Anope::string>("engine");
19  this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
20  if (sql)
21  this->CheckTables();
22  else
23  Log() << "IRC2SQL: no database connection to " << engine;
24 
25  const Anope::string &snick = block->Get<const Anope::string>("client");
26  if (snick.empty())
27  throw ConfigException(Module::name + ": <client> must be defined");
28  StatServ = BotInfo::Find(snick, true);
29  if (!StatServ)
30  throw ConfigException(Module::name + ": no bot named " + snick);
31 
32  if (firstrun)
33  {
34  firstrun = false;
35 
36  for (Anope::map<Server *>::const_iterator it = Servers::ByName.begin(); it != Servers::ByName.end(); ++it)
37  {
38  this->OnNewServer(it->second);
39  }
40 
41  for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
42  {
43  this->OnChannelCreate(it->second);
44  }
45 
46  for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
47  {
48  User *u = it->second;
49  bool exempt = false;
50  this->OnUserConnect(u, exempt);
51  for (User::ChanUserList::const_iterator cit = u->chans.begin(), cit_end = u->chans.end(); cit != cit_end; ++cit)
52  {
53  this->OnJoinChannel(u, cit->second->chan);
54  }
55  }
56  }
57 
58 }
59 
61 {
62  query = "INSERT DELAYED INTO `" + prefix + "server` (name, hops, comment, link_time, online, ulined) "
63  "VALUES (@name@, @hops@, @comment@, now(), 'Y', @ulined@) "
64  "ON DUPLICATE KEY UPDATE name=VALUES(name), hops=VALUES(hops), comment=VALUES(comment), "
65  "link_time=VALUES(link_time), online=VALUES(online), ulined=(ulined)";
66  query.SetValue("name", server->GetName());
67  query.SetValue("hops", server->GetHops());
68  query.SetValue("comment", server->GetDescription());
69  query.SetValue("ulined", server->IsULined() ? "Y" : "N");
70  this->RunQuery(query);
71 }
72 
74 {
75  if (quitting)
76  return;
77 
78  query = "CALL " + prefix + "ServerQuit(@name@)";
79  query.SetValue("name", server->GetName());
80  this->RunQuery(query);
81 }
82 
83 void IRC2SQL::OnUserConnect(User *u, bool &exempt)
84 {
85  if (!introduced_myself)
86  {
87  this->OnNewServer(Me);
88  introduced_myself = true;
89  }
90 
91  query = "CALL " + prefix + "UserConnect(@nick@,@host@,@vhost@,@chost@,@realname@,@ip@,@ident@,@vident@,"
92  "@account@,@secure@,@fingerprint@,@signon@,@server@,@uuid@,@modes@,@oper@)";
93  query.SetValue("nick", u->nick);
94  query.SetValue("host", u->host);
95  query.SetValue("vhost", u->vhost);
96  query.SetValue("chost", u->chost);
97  query.SetValue("realname", u->realname);
98  query.SetValue("ip", u->ip.addr());
99  query.SetValue("ident", u->GetIdent());
100  query.SetValue("vident", u->GetVIdent());
101  query.SetValue("secure", u->HasMode("SSL") || u->HasExt("ssl") ? "Y" : "N");
102  query.SetValue("account", u->Account() ? u->Account()->display : "");
103  query.SetValue("fingerprint", u->fingerprint);
104  query.SetValue("signon", u->signon);
105  query.SetValue("server", u->server->GetName());
106  query.SetValue("uuid", u->GetUID());
107  query.SetValue("modes", u->GetModes());
108  query.SetValue("oper", u->HasMode("OPER") ? "Y" : "N");
109  this->RunQuery(query);
110 
111  if (ctcpuser && (Me->IsSynced() || ctcpeob) && u->server != Me)
112  IRCD->SendPrivmsg(StatServ, u->GetUID(), "\1VERSION\1");
113 
114 }
115 
117 {
118  if (quitting || u->server->IsQuitting())
119  return;
120 
121  query = "CALL " + prefix + "UserQuit(@nick@)";
122  query.SetValue("nick", u->nick);
123  this->RunQuery(query);
124 }
125 
127 {
128  query = "UPDATE `" + prefix + "user` SET nick=@newnick@ WHERE nick=@oldnick@";
129  query.SetValue("newnick", u->nick);
130  query.SetValue("oldnick", oldnick);
131  this->RunQuery(query);
132 }
133 
135 {
136  query = "UPDATE `" + prefix + "user` SET secure=@secure@, fingerprint=@fingerprint@ WHERE nick=@nick@";
137  query.SetValue("secure", u->HasMode("SSL") || u->HasExt("ssl") ? "Y" : "N");
138  query.SetValue("fingerprint", u->fingerprint);
139  query.SetValue("nick", u->nick);
140  this->RunQuery(query);
141 }
142 
143 void IRC2SQL::OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname)
144 {
145  query = "UPDATE `" + prefix + "user` SET modes=@modes@, oper=@oper@ WHERE nick=@nick@";
146  query.SetValue("nick", u->nick);
147  query.SetValue("modes", u->GetModes());
148  query.SetValue("oper", u->HasMode("OPER") ? "Y" : "N");
149  this->RunQuery(query);
150 }
151 
152 void IRC2SQL::OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname)
153 {
154  this->OnUserModeSet(setter, u, mname);
155 }
156 
158 {
159  query = "UPDATE `" + prefix + "user` SET account=@account@ WHERE nick=@nick@";
160  query.SetValue("nick", u->nick);
161  query.SetValue("account", u->Account() ? u->Account()->display : "");
162  this->RunQuery(query);
163 }
164 
166 {
167  this->OnUserLogin(u);
168 }
169 
171 {
172  query = "UPDATE `" + prefix + "user` "
173  "SET vhost=@vhost@ "
174  "WHERE nick=@nick@";
175  query.SetValue("vhost", u->GetDisplayedHost());
176  query.SetValue("nick", u->nick);
177  this->RunQuery(query);
178 }
179 
181 {
182  query = "INSERT INTO `" + prefix + "chan` (channel, topic, topicauthor, topictime, modes) "
183  "VALUES (@channel@,@topic@,@topicauthor@,@topictime@,@modes@) "
184  "ON DUPLICATE KEY UPDATE channel=VALUES(channel), topic=VALUES(topic),"
185  "topicauthor=VALUES(topicauthor), topictime=VALUES(topictime), modes=VALUES(modes)";
186  query.SetValue("channel", c->name);
187  query.SetValue("topic", c->topic);
188  query.SetValue("topicauthor", c->topic_setter);
189  query.SetValue("topictime", c->topic_ts);
190  query.SetValue("modes", c->GetModes(true,true));
191  this->RunQuery(query);
192 }
193 
195 {
196  query = "DELETE FROM `" + prefix + "chan` WHERE channel=@channel@";
197  query.SetValue("channel", c->name);
198  this->RunQuery(query);
199 }
200 
202 {
204  ChanUserContainer *cu = u->FindChannel(c);
205  if (cu)
206  modes = cu->status.Modes();
207 
208  query = "CALL " + prefix + "JoinUser(@nick@,@channel@,@modes@)";
209  query.SetValue("nick", u->nick);
210  query.SetValue("channel", c->name);
211  query.SetValue("modes", modes);
212  this->RunQuery(query);
213 }
214 
216 {
217  query = "UPDATE `" + prefix + "chan` SET modes=@modes@ WHERE channel=@channel@";
218  query.SetValue("channel", c->name);
219  query.SetValue("modes", c->GetModes(true,true));
220  this->RunQuery(query);
221  return EVENT_CONTINUE;
222 }
223 
225 {
226  this->OnChannelModeSet(c, setter, mode, param);
227  return EVENT_CONTINUE;
228 }
229 
231 {
232  if (quitting)
233  return;
234  /*
235  * user is quitting, we already received a OnUserQuit()
236  * at this point the user is already removed from SQL and all channels
237  */
238  if (u->Quitting())
239  return;
240  query = "CALL " + prefix + "PartUser(@nick@,@channel@)";
241  query.SetValue("nick", u->nick);
242  query.SetValue("channel", c->name);
243  this->RunQuery(query);
244 }
245 
246 void IRC2SQL::OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic)
247 {
248  query = "UPDATE `" + prefix + "chan` "
249  "SET topic=@topic@, topicauthor=@author@, topictime=FROM_UNIXTIME(@time@) "
250  "WHERE channel=@channel@";
251  query.SetValue("topic", c->topic);
252  query.SetValue("author", c->topic_setter);
253  query.SetValue("time", c->topic_ts);
254  query.SetValue("channel", c->name);
255  this->RunQuery(query);
256 }
257 
259 {
260  Anope::string versionstr;
261  if (bi != StatServ)
262  return;
263  if (message[0] == '\1' && message[message.length() - 1] == '\1')
264  {
265  if (message.substr(0, 9).equals_ci("\1VERSION "))
266  {
267  if (u->HasExt("CTCPVERSION"))
268  return;
269  u->Extend<bool>("CTCPVERSION");
270 
271  versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10));
272  if (versionstr.empty())
273  return;
274  query = "UPDATE `" + prefix + "user` "
275  "SET version=@version@ "
276  "WHERE nick=@nick@";
277  query.SetValue("version", versionstr);
278  query.SetValue("nick", u->nick);
279  this->RunQuery(query);
280  }
281  }
282 }
283 
Definition: bots.h:24
bool HasMode(const Anope::string &name) const
Definition: users.cpp:513
Definition: servers.h:42
void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
Definition: irc2sql.cpp:152
Anope::string name
Definition: modules.h:221
const ModeList & GetModes() const
Definition: channels.cpp:238
const Anope::string & GetIdent() const
Definition: users.cpp:264
bool IsSynced() const
Definition: servers.cpp:298
unsigned GetHops() const
Definition: servers.cpp:180
bool IsQuitting() const
Definition: servers.cpp:324
void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override
Definition: irc2sql.cpp:246
time_t signon
Definition: users.h:79
Anope::string fingerprint
Definition: users.h:73
bool firstrun
Definition: irc2sql.h:29
virtual void SendPrivmsg(const MessageSource &source, const Anope::string &dest, const char *fmt,...)
Definition: protocol.cpp:242
Anope::string addr() const
Definition: sockets.cpp:73
void OnNewServer(Server *server) anope_override
Definition: irc2sql.cpp:60
ChanUserList chans
Definition: users.h:87
Anope::string prefix
Definition: irc2sql.h:28
void OnShutdown() anope_override
Definition: irc2sql.cpp:3
Definition: users.h:34
Anope::string topic_setter
Definition: channels.h:61
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
ChanUserContainer * FindChannel(Channel *c) const
Definition: users.cpp:716
bool ctcpeob
Definition: irc2sql.h:29
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
Definition: irc2sql.cpp:215
time_t topic_ts
Definition: channels.h:66
bool equals_ci(const char *_str) const
Definition: anope.h:78
void OnUserLogin(User *u) anope_override
Definition: irc2sql.cpp:157
bool quitting
Definition: irc2sql.h:29
void SetValue(const Anope::string &key, const T &value, bool escape=true)
Definition: sql.h:121
Anope::string name
Definition: channels.h:44
Anope::string topic
Definition: channels.h:59
Anope::string GetModes() const
Definition: users.cpp:692
void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
Definition: irc2sql.cpp:143
void OnSetDisplayedHost(User *u) anope_override
Definition: irc2sql.cpp:170
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
size_type length() const
Definition: anope.h:131
bool Quitting() const
Definition: users.cpp:763
void OnLeaveChannel(User *u, Channel *c) anope_override
Definition: irc2sql.cpp:230
void OnChannelDelete(Channel *c) anope_override
Definition: irc2sql.cpp:194
void OnJoinChannel(User *u, Channel *c) anope_override
Definition: irc2sql.cpp:201
ServiceReference< SQL::Provider > sql
Definition: irc2sql.h:24
Definition: sql.h:96
Definition: Config.cs:26
CoreExport Anope::map< Server * > ByName
Definition: servers.cpp:26
void OnChannelCreate(Channel *c) anope_override
Definition: irc2sql.cpp:180
SQL::Query query
Definition: irc2sql.h:26
const Anope::string & GetUID() const
Definition: users.cpp:230
const Anope::string & GetDisplayedHost() const
Definition: users.cpp:203
void OnServerQuit(Server *server) anope_override
Definition: irc2sql.cpp:73
Anope::string display
Definition: account.h:113
const Anope::string & GetVIdent() const
Definition: users.cpp:247
CoreExport Anope::string NormalizeBuffer(const Anope::string &)
Definition: misc.cpp:664
static Anope::map< std::pair< bool, Anope::string > > modes
Definition: cs_mode.cpp:745
bool empty() const
Definition: anope.h:126
void OnUserConnect(User *u, bool &exempt) anope_override
Definition: irc2sql.cpp:83
void OnNickLogout(User *u) anope_override
Definition: irc2sql.cpp:165
Anope::string host
Definition: users.h:65
sockaddrs ip
Definition: users.h:75
void OnUserQuit(User *u, const Anope::string &msg) anope_override
Definition: irc2sql.cpp:116
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
CoreExport channel_map ChannelList
Definition: channels.cpp:29
void CheckTables()
Definition: tables.cpp:3
ChannelStatus status
Definition: channels.h:28
void OnFingerprint(User *u) anope_override
Definition: irc2sql.cpp:134
Anope::string realname
Definition: users.h:71
Anope::string nick
Definition: users.h:62
const Anope::string & GetDescription() const
Definition: servers.cpp:190
const Anope::string & GetName() const
Definition: servers.cpp:175
Anope::string chost
Definition: users.h:69
void RunQuery(const SQL::Query &q)
Definition: utils.cpp:3
NickCore * Account() const
Definition: users.cpp:422
CoreExport Server * Me
Definition: servers.cpp:24
CoreExport user_map UserListByNick
Definition: users.cpp:28
const Anope::string & Modes() const
Definition: modes.cpp:96
Definition: logger.h:53
T Get(const Anope::string &tag)
Definition: config.h:44
bool IsULined() const
Definition: servers.cpp:308
void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
Definition: irc2sql.cpp:126
void OnReload(Configuration::Conf *config) anope_override
Definition: irc2sql.cpp:11
static BotInfo * Find(const Anope::string &nick, bool nick_only=false)
Definition: bots.cpp:249
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31
void OnBotNotice(User *u, BotInfo *bi, Anope::string &message) anope_override
Definition: irc2sql.cpp:258
Anope::string vhost
Definition: users.h:67
BotInfo * StatServ
Definition: irc2sql.h:30
EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) anope_override
Definition: irc2sql.cpp:224
bool introduced_myself
Definition: irc2sql.h:29
Anope::string GeoIPDB
Definition: irc2sql.h:28
bool ctcpuser
Definition: irc2sql.h:29