summaryrefslogtreecommitdiff
path: root/modules/extra
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2024-01-09 21:14:41 +0000
committerSadie Powell <sadie@witchery.services>2024-01-09 21:25:44 +0000
commit349ae043b68e65314dff93aa5a1eee92acfe7e9a (patch)
treefd3aa43e8e3b3d57bae8838e52cd9e89b49dbbd4 /modules/extra
parent710e7dd3a2b59afd7a2b49aef83aedb89050c704 (diff)
Always build the stats modules.
These have no external dependencies so it makes no sense to not always build them.
Diffstat (limited to 'modules/extra')
-rw-r--r--modules/extra/stats/cs_fantasy_stats.cpp176
-rw-r--r--modules/extra/stats/cs_fantasy_top.cpp188
-rw-r--r--modules/extra/stats/irc2sql/CMakeLists.txt1
-rw-r--r--modules/extra/stats/irc2sql/irc2sql.cpp326
-rw-r--r--modules/extra/stats/irc2sql/irc2sql.h86
-rw-r--r--modules/extra/stats/irc2sql/tables.cpp343
-rw-r--r--modules/extra/stats/irc2sql/utils.cpp68
-rw-r--r--modules/extra/stats/m_chanstats.cpp655
8 files changed, 0 insertions, 1843 deletions
diff --git a/modules/extra/stats/cs_fantasy_stats.cpp b/modules/extra/stats/cs_fantasy_stats.cpp
deleted file mode 100644
index 75e3442ab..000000000
--- a/modules/extra/stats/cs_fantasy_stats.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Chanstats core functions
- *
- * (C) 2003-2024 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- */
-
-#include "module.h"
-#include "modules/sql.h"
-
-class MySQLInterface : public SQL::Interface
-{
-public:
- MySQLInterface(Module *o) : SQL::Interface(o) { }
-
- void OnResult(const SQL::Result &r) override
- {
- }
-
- void OnError(const SQL::Result &r) override
- {
- if (!r.GetQuery().query.empty())
- Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError();
- else
- Log(LOG_DEBUG) << "Chanstats: Error executing query: " << r.GetError();
- }
-};
-
-
-class CommandCSStats : public Command
-{
-public:
- CommandCSStats(Module *creator) : Command (creator, "chanserv/stats", 0, 2)
- {
- this->SetDesc(_("Displays your Channel Stats"));
- this->SetSyntax(_("[\037channel\037] [\037nick\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params);
-};
-
-class CommandCSGStats : public Command
-{
-public:
- CommandCSGStats(Module *creator) : Command (creator, "chanserv/gstats", 0, 2)
- {
- this->SetDesc(_("Displays your Global Stats"));
- this->SetSyntax(_("\037nick\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params);
-};
-
-
-class CSStats;
-static CSStats *me;
-class CSStats : public Module
-{
- CommandCSStats commandcsstats;
- CommandCSGStats commandcsgstats;
- ServiceReference<SQL::Provider> sql;
- MySQLInterface sqlinterface;
- Anope::string prefix;
-public:
- CSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsstats(this), commandcsgstats(this), sql("", ""), sqlinterface(this)
- {
- me = this;
-
- }
-
- void OnReload(Configuration::Conf *conf) override
- {
- prefix = conf->GetModule("m_chanstats")->Get<const Anope::string>("prefix", "anope_");
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<const Anope::string>("engine"));
- }
-
- SQL::Result RunQuery(const SQL::Query &query)
- {
- if (!this->sql)
- throw SQL::Exception("Unable to locate SQL reference, is m_mysql loaded and configured correctly?");
-
- SQL::Result res = this->sql->RunQuery(query);
- if (!res.GetError().empty())
- throw SQL::Exception(res.GetError());
- return res;
- }
-
- void DoStats(CommandSource &source, const bool is_global, const std::vector<Anope::string> &params)
- {
- Anope::string display, channel;
-
- /*
- * possible parameters are:
- * stats [channel] [nick]
- * stats [channel]
- * stats [nick]
- * stats
- */
-
- switch (params.size())
- {
- case 2:
- channel = params[0];
- display = params[1];
- break;
- case 1:
- if (params[0][0] == '#')
- channel = params[0];
- else
- {
- if (NickAlias *na = NickAlias::Find(params[0]))
- display = na->nc->display;
- else
- {
- source.Reply(_("%s not found."), params[0].c_str());
- return;
- }
- }
- break;
- }
-
- if (display.empty())
- display = source.nc->display;
-
- try
- {
- SQL::Query query;
- query = "SELECT letters, words, line, smileys_happy+smileys_sad+smileys_other as smileys,"
- "actions FROM `" + prefix + "chanstats` "
- "WHERE `nick` = @nick@ AND `chan` = @channel@ AND `type` = 'total';";
- if (is_global || channel.empty())
- query.SetValue("channel", "");
- else
- query.SetValue("channel", channel);
- query.SetValue("nick", display);
- SQL::Result res = this->RunQuery(query);
-
- if (res.Rows() > 0)
- {
- if (is_global)
- source.Reply(_("Network stats for %s:"), display.c_str());
- else
- source.Reply(_("Channel stats for %s on %s:"), display.c_str(), channel.c_str());
-
- source.Reply(_("letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"),
- res.Get(0, "letters").c_str(), res.Get(0, "words").c_str(),
- res.Get(0, "line").c_str(), res.Get(0, "smileys").c_str(),
- res.Get(0, "actions").c_str());
- }
- else
- source.Reply(_("No stats for %s."), display.c_str());
- }
- catch (const SQL::Exception &ex)
- {
- Log(LOG_DEBUG) << ex.GetReason();
- }
-
- }
-};
-
-void CommandCSStats::Execute(CommandSource &source, const std::vector<Anope::string> &params)
-{
- me->DoStats(source, false, params);
-}
-
-void CommandCSGStats::Execute(CommandSource &source, const std::vector<Anope::string> &params)
-{
- me->DoStats(source, true, params);
-}
-
-MODULE_INIT(CSStats)
diff --git a/modules/extra/stats/cs_fantasy_top.cpp b/modules/extra/stats/cs_fantasy_top.cpp
deleted file mode 100644
index ee1e5656f..000000000
--- a/modules/extra/stats/cs_fantasy_top.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Chanstats core functions
- *
- * (C) 2003-2024 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- */
-
-#include "module.h"
-#include "modules/sql.h"
-
-class MySQLInterface : public SQL::Interface
-{
-public:
- MySQLInterface(Module *o) : SQL::Interface(o) { }
-
- void OnResult(const SQL::Result &r) override
- {
- }
-
- void OnError(const SQL::Result &r) override
- {
- if (!r.GetQuery().query.empty())
- Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError();
- else
- Log(LOG_DEBUG) << "Chanstats: Error executing query: " << r.GetError();
- }
-};
-
-class CommandCSTop : public Command
-{
-public:
- CommandCSTop(Module *creator) : Command (creator, "chanserv/top", 0, 2)
- {
- this->SetDesc(_("Displays the top 3 users of a channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params);
-};
-
-class CommandCSTop10 : public Command
-{
-public:
- CommandCSTop10(Module *creator) : Command (creator, "chanserv/top10", 0, 2)
- {
- this->SetDesc(_("Displays the top 10 users of a channel"));
- this->SetSyntax(_("\037channel\037"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params);
-};
-
-class CommandCSGTop : public Command
-{
-public:
- CommandCSGTop(Module *creator) : Command (creator, "chanserv/gtop", 0, 1)
- {
- this->SetDesc(_("Displays the top 3 users of the network"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params);
-};
-
-class CommandCSGTop10 : public Command
-{
-public:
- CommandCSGTop10(Module *creator) : Command (creator, "chanserv/gtop10", 0, 1)
- {
- this->SetDesc(_("Displays the top 10 users of the network"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params);
-};
-
-
-class CSTop;
-static CSTop *me;
-class CSTop : public Module
-{
- CommandCSTop commandcstop;
- CommandCSGTop commandcsgtop;
- CommandCSTop10 commandcstop10;
- CommandCSGTop10 commandcsgtop10;
- ServiceReference<SQL::Provider> sql;
- MySQLInterface sqlinterface;
- Anope::string prefix;
-
-public:
- CSTop(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcstop(this), commandcsgtop(this), commandcstop10(this), commandcsgtop10(this), sql("", ""),
- sqlinterface(this)
- {
- me = this;
-
- }
-
- void OnReload(Configuration::Conf *conf) override
- {
- prefix = conf->GetModule("m_chanstats")->Get<const Anope::string>("prefix", "anope_");
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<const Anope::string>("engine"));
- }
-
- SQL::Result RunQuery(const SQL::Query &query)
- {
- if (!this->sql)
- throw SQL::Exception("Unable to locate SQL reference, is m_mysql loaded and configured correctly?");
-
- SQL::Result res = sql->RunQuery(query);
- if (!res.GetError().empty())
- throw SQL::Exception(res.GetError());
- return res;
- }
-
- void DoTop(CommandSource &source, const std::vector<Anope::string> &params, bool is_global, int limit = 1)
- {
-
- Anope::string channel;
- if (!params.empty())
- channel = params[0];
- else if (source.c && source.c->ci)
- channel = source.c->ci->name;
-
- if (!is_global && channel.empty())
- is_global = true;
-
- try
- {
- SQL::Query query;
- query = "SELECT nick, letters, words, line, actions,"
- "smileys_happy+smileys_sad+smileys_other as smileys "
- "FROM `" + prefix + "chanstats` "
- "WHERE `nick` != '' AND `chan` = @channel@ AND `type` = 'total' "
- "ORDER BY `letters` DESC LIMIT @limit@;";
- query.SetValue("limit", limit, false);
-
- if (is_global)
- query.SetValue("channel", "");
- else
- query.SetValue("channel", channel.c_str());
-
- SQL::Result res = this->RunQuery(query);
-
- if (res.Rows() > 0)
- {
- source.Reply(_("Top %i of %s"), limit, (is_global ? "Network" : channel.c_str()));
- for (int i = 0; i < res.Rows(); ++i)
- {
- source.Reply(_("%2d \002%-16s\002 letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"),
- i+1, res.Get(i, "nick").c_str(), res.Get(i, "letters").c_str(),
- res.Get(i, "words").c_str(), res.Get(i, "line").c_str(),
- res.Get(i, "smileys").c_str(), res.Get(i, "actions").c_str());
- }
- }
- else
- source.Reply(_("No stats for %s."), is_global ? "Network" : channel.c_str());
- }
- catch (const SQL::Exception &ex)
- {
- Log(LOG_DEBUG) << ex.GetReason();
- }
- }
-};
-
-void CommandCSTop::Execute(CommandSource &source, const std::vector<Anope::string> &params)
-{
- me->DoTop(source, params, false, 3);
-}
-
-void CommandCSTop10::Execute(CommandSource &source, const std::vector<Anope::string> &params)
-{
- me->DoTop(source, params, false, 10);
-}
-
-void CommandCSGTop::Execute(CommandSource &source, const std::vector<Anope::string> &params)
-{
- me->DoTop(source, params, true, 3);
-}
-
-void CommandCSGTop10::Execute(CommandSource &source, const std::vector<Anope::string> &params)
-{
- me->DoTop(source, params, true, 10);
-}
-
-MODULE_INIT(CSTop)
diff --git a/modules/extra/stats/irc2sql/CMakeLists.txt b/modules/extra/stats/irc2sql/CMakeLists.txt
deleted file mode 100644
index 781f0ef1f..000000000
--- a/modules/extra/stats/irc2sql/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/extra/stats/irc2sql/irc2sql.cpp b/modules/extra/stats/irc2sql/irc2sql.cpp
deleted file mode 100644
index 2753dc00e..000000000
--- a/modules/extra/stats/irc2sql/irc2sql.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- *
- * (C) 2013-2024 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "irc2sql.h"
-
-void IRC2SQL::OnShutdown()
-{
- // TODO: test if we really have to use blocking query here
- // (sometimes m_mysql get unloaded before the other thread executed all queries)
- if (this->sql)
- SQL::Result r = this->sql->RunQuery(SQL::Query("CALL " + prefix + "OnShutdown()"));
- quitting = true;
-}
-
-void IRC2SQL::OnReload(Configuration::Conf *conf)
-{
- Configuration::Block *block = Config->GetModule(this);
- prefix = block->Get<const Anope::string>("prefix", "anope_");
- GeoIPDB = block->Get<const Anope::string>("geoip_database");
- ctcpuser = block->Get<bool>("ctcpuser", "no");
- ctcpeob = block->Get<bool>("ctcpeob", "yes");
- Anope::string engine = block->Get<const Anope::string>("engine");
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
- if (sql)
- this->CheckTables();
- else
- Log() << "IRC2SQL: no database connection to " << engine;
-
- const Anope::string &snick = block->Get<const Anope::string>("client");
- if (snick.empty())
- throw ConfigException(Module::name + ": <client> must be defined");
- StatServ = BotInfo::Find(snick, true);
- if (!StatServ)
- throw ConfigException(Module::name + ": no bot named " + snick);
-
- if (firstrun)
- {
- firstrun = false;
-
- for (Anope::map<Server *>::const_iterator it = Servers::ByName.begin(); it != Servers::ByName.end(); ++it)
- {
- this->OnNewServer(it->second);
- }
-
- for (const auto &[_, c] : ChannelList)
- {
- this->OnChannelCreate(c);
- }
-
- for (const auto &[_, u] : UserListByNick)
- {
- bool exempt = false;
- this->OnUserConnect(u, exempt);
- for (const auto &[_, uc] : u->chans)
- {
- this->OnJoinChannel(u, uc->chan);
- }
- }
- }
-
-}
-
-void IRC2SQL::OnNewServer(Server *server)
-{
- query = "INSERT DELAYED INTO `" + prefix + "server` (name, hops, comment, link_time, online, ulined) "
- "VALUES (@name@, @hops@, @comment@, now(), 'Y', @ulined@) "
- "ON DUPLICATE KEY UPDATE name=VALUES(name), hops=VALUES(hops), comment=VALUES(comment), "
- "link_time=VALUES(link_time), online=VALUES(online), ulined=VALUES(ulined)";
- query.SetValue("name", server->GetName());
- query.SetValue("hops", server->GetHops());
- query.SetValue("comment", server->GetDescription());
- query.SetValue("ulined", server->IsULined() ? "Y" : "N");
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnServerQuit(Server *server)
-{
- if (quitting)
- return;
-
- query = "CALL " + prefix + "ServerQuit(@name@)";
- query.SetValue("name", server->GetName());
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnUserConnect(User *u, bool &exempt)
-{
- if (!introduced_myself)
- {
- this->OnNewServer(Me);
- introduced_myself = true;
- }
-
- query = "CALL " + prefix + "UserConnect(@nick@,@host@,@vhost@,@chost@,@realname@,@ip@,@ident@,@vident@,"
- "@account@,@secure@,@fingerprint@,@signon@,@server@,@uuid@,@modes@,@oper@)";
- query.SetValue("nick", u->nick);
- query.SetValue("host", u->host);
- query.SetValue("vhost", u->vhost);
- query.SetValue("chost", u->chost);
- query.SetValue("realname", u->realname);
- query.SetValue("ip", u->ip.addr());
- query.SetValue("ident", u->GetIdent());
- query.SetValue("vident", u->GetVIdent());
- query.SetValue("secure", u->IsSecurelyConnected() ? "Y" : "N");
- query.SetValue("account", u->Account() ? u->Account()->display : "");
- query.SetValue("fingerprint", u->fingerprint);
- query.SetValue("signon", u->signon);
- query.SetValue("server", u->server->GetName());
- query.SetValue("uuid", u->GetUID());
- query.SetValue("modes", u->GetModes());
- query.SetValue("oper", u->HasMode("OPER") ? "Y" : "N");
- this->RunQuery(query);
-
- if (ctcpuser && (Me->IsSynced() || ctcpeob) && u->server != Me)
- IRCD->SendPrivmsg(StatServ, u->GetUID(), "\1VERSION\1");
-
-}
-
-void IRC2SQL::OnUserQuit(User *u, const Anope::string &msg)
-{
- if (quitting || u->server->IsQuitting())
- return;
-
- query = "CALL " + prefix + "UserQuit(@nick@)";
- query.SetValue("nick", u->nick);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnUserNickChange(User *u, const Anope::string &oldnick)
-{
- query = "UPDATE `" + prefix + "user` SET nick=@newnick@ WHERE nick=@oldnick@";
- query.SetValue("newnick", u->nick);
- query.SetValue("oldnick", oldnick);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnUserAway(User *u, const Anope::string &message)
-{
- query = "UPDATE `" + prefix + "user` SET away=@away@, awaymsg=@awaymsg@ WHERE nick=@nick@";
- query.SetValue("away", (!message.empty()) ? "Y" : "N");
- query.SetValue("awaymsg", message);
- query.SetValue("nick", u->nick);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnFingerprint(User *u)
-{
- query = "UPDATE `" + prefix + "user` SET secure=@secure@, fingerprint=@fingerprint@ WHERE nick=@nick@";
- query.SetValue("secure", u->IsSecurelyConnected() ? "Y" : "N");
- query.SetValue("fingerprint", u->fingerprint);
- query.SetValue("nick", u->nick);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname)
-{
- query = "UPDATE `" + prefix + "user` SET modes=@modes@, oper=@oper@ WHERE nick=@nick@";
- query.SetValue("nick", u->nick);
- query.SetValue("modes", u->GetModes());
- query.SetValue("oper", u->HasMode("OPER") ? "Y" : "N");
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname)
-{
- this->OnUserModeSet(setter, u, mname);
-}
-
-void IRC2SQL::OnUserLogin(User *u)
-{
- query = "UPDATE `" + prefix + "user` SET account=@account@ WHERE nick=@nick@";
- query.SetValue("nick", u->nick);
- query.SetValue("account", u->Account() ? u->Account()->display : "");
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnNickLogout(User *u)
-{
- this->OnUserLogin(u);
-}
-
-void IRC2SQL::OnSetDisplayedHost(User *u)
-{
- query = "UPDATE `" + prefix + "user` "
- "SET vhost=@vhost@ "
- "WHERE nick=@nick@";
- query.SetValue("vhost", u->GetDisplayedHost());
- query.SetValue("nick", u->nick);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnChannelCreate(Channel *c)
-{
- query = "INSERT INTO `" + prefix + "chan` (channel, topic, topicauthor, topictime, modes) "
- "VALUES (@channel@,@topic@,@topicauthor@,@topictime@,@modes@) "
- "ON DUPLICATE KEY UPDATE channel=VALUES(channel), topic=VALUES(topic),"
- "topicauthor=VALUES(topicauthor), topictime=VALUES(topictime), modes=VALUES(modes)";
- query.SetValue("channel", c->name);
- query.SetValue("topic", c->topic);
- query.SetValue("topicauthor", c->topic_setter);
- if (c->topic_ts > 0)
- query.SetValue("topictime", c->topic_ts);
- else
- query.SetValue("topictime", "NULL", false);
- query.SetValue("modes", c->GetModes(true,true));
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnChannelDelete(Channel *c)
-{
- query = "DELETE FROM `" + prefix + "chan` WHERE channel=@channel@";
- query.SetValue("channel", c->name);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnJoinChannel(User *u, Channel *c)
-{
- Anope::string modes;
- ChanUserContainer *cu = u->FindChannel(c);
- if (cu)
- modes = cu->status.Modes();
-
- query = "CALL " + prefix + "JoinUser(@nick@,@channel@,@modes@)";
- query.SetValue("nick", u->nick);
- query.SetValue("channel", c->name);
- query.SetValue("modes", modes);
- this->RunQuery(query);
-}
-
-EventReturn IRC2SQL::OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param)
-{
- if (mode->type == MODE_STATUS)
- {
- User *u = User::Find(param);
- if (u == NULL)
- return EVENT_CONTINUE;
-
- ChanUserContainer *cc = u->FindChannel(c);
- if (cc == NULL)
- return EVENT_CONTINUE;
-
- query = "UPDATE `" + prefix + "user` AS u, `" + prefix + "ison` AS i, `" + prefix + "chan` AS c"
- " SET i.modes=@modes@"
- " WHERE u.nick=@nick@ AND c.channel=@channel@"
- " AND u.nickid = i.nickid AND c.chanid = i.chanid";
- query.SetValue("nick", u->nick);
- query.SetValue("modes", cc->status.Modes());
- query.SetValue("channel", c->name);
- this->RunQuery(query);
- }
- else
- {
- query = "UPDATE `" + prefix + "chan` SET modes=@modes@ WHERE channel=@channel@";
- query.SetValue("channel", c->name);
- query.SetValue("modes", c->GetModes(true,true));
- this->RunQuery(query);
- }
- return EVENT_CONTINUE;
-}
-
-EventReturn IRC2SQL::OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param)
-{
- this->OnChannelModeSet(c, setter, mode, param);
- return EVENT_CONTINUE;
-}
-
-void IRC2SQL::OnLeaveChannel(User *u, Channel *c)
-{
- if (quitting)
- return;
- /*
- * user is quitting, we already received a OnUserQuit()
- * at this point the user is already removed from SQL and all channels
- */
- if (u->Quitting())
- return;
- query = "CALL " + prefix + "PartUser(@nick@,@channel@)";
- query.SetValue("nick", u->nick);
- query.SetValue("channel", c->name);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic)
-{
- query = "UPDATE `" + prefix + "chan` "
- "SET topic=@topic@, topicauthor=@author@, topictime=FROM_UNIXTIME(@time@) "
- "WHERE channel=@channel@";
- query.SetValue("topic", c->topic);
- query.SetValue("author", c->topic_setter);
- query.SetValue("time", c->topic_ts);
- query.SetValue("channel", c->name);
- this->RunQuery(query);
-}
-
-void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message)
-{
- Anope::string versionstr;
- if (bi != StatServ)
- return;
- if (message[0] == '\1' && message[message.length() - 1] == '\1')
- {
- if (message.substr(0, 9).equals_ci("\1VERSION "))
- {
- if (u->HasExt("CTCPVERSION"))
- return;
- u->Extend<bool>("CTCPVERSION");
-
- versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10));
- if (versionstr.empty())
- return;
- query = "UPDATE `" + prefix + "user` "
- "SET version=@version@ "
- "WHERE nick=@nick@";
- query.SetValue("version", versionstr);
- query.SetValue("nick", u->nick);
- this->RunQuery(query);
- }
- }
-}
-
-MODULE_INIT(IRC2SQL)
diff --git a/modules/extra/stats/irc2sql/irc2sql.h b/modules/extra/stats/irc2sql/irc2sql.h
deleted file mode 100644
index c033b2a43..000000000
--- a/modules/extra/stats/irc2sql/irc2sql.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *
- * (C) 2013-2024 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#pragma once
-
-#include "module.h"
-#include "modules/sql.h"
-
-class MySQLInterface : public SQL::Interface
-{
-public:
- MySQLInterface(Module *o) : SQL::Interface(o) { }
-
- void OnResult(const SQL::Result &r) override
- {
- }
-
- void OnError(const SQL::Result &r) override
- {
- if (!r.GetQuery().query.empty())
- Log(LOG_DEBUG) << "m_irc2sql: Error executing query " << r.finished_query << ": " << r.GetError();
- else
- Log(LOG_DEBUG) << "m_irc2sql: Error executing query: " << r.GetError();
- }
-};
-
-class IRC2SQL : public Module
-{
- ServiceReference<SQL::Provider> sql;
- MySQLInterface sqlinterface;
- SQL::Query query;
- std::vector<Anope::string> TableList, ProcedureList, EventList;
- Anope::string prefix, GeoIPDB;
- bool quitting, introduced_myself, ctcpuser, ctcpeob, firstrun;
- BotInfo *StatServ;
- PrimitiveExtensibleItem<bool> versionreply;
-
- void RunQuery(const SQL::Query &q);
- void GetTables();
-
- bool HasTable(const Anope::string &table);
- bool HasProcedure(const Anope::string &table);
- bool HasEvent(const Anope::string &table);
-
- void CheckTables();
-
-public:
- IRC2SQL(const Anope::string &modname, const Anope::string &creator) :
- Module(modname, creator, EXTRA | VENDOR), sql("", ""), sqlinterface(this), versionreply(this, "CTCPVERSION")
- {
- firstrun = true;
- quitting = false;
- introduced_myself = false;
- }
-
- void OnShutdown() override;
- void OnReload(Configuration::Conf *config) override;
- void OnNewServer(Server *server) override;
- void OnServerQuit(Server *server) override;
- void OnUserConnect(User *u, bool &exempt) override;
- void OnUserQuit(User *u, const Anope::string &msg) override;
- void OnUserNickChange(User *u, const Anope::string &oldnick) override;
- void OnUserAway(User *u, const Anope::string &message) override;
- void OnFingerprint(User *u) override;
- void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override;
- void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override;
- void OnUserLogin(User *u) override;
- void OnNickLogout(User *u) override;
- void OnSetDisplayedHost(User *u) override;
-
- void OnChannelCreate(Channel *c) override;
- void OnChannelDelete(Channel *c) override;
- void OnLeaveChannel(User *u, Channel *c) override;
- void OnJoinChannel(User *u, Channel *c) override;
- EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) override;
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) override;
-
- void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override;
-
- void OnBotNotice(User *u, BotInfo *bi, Anope::string &message) override;
-};
diff --git a/modules/extra/stats/irc2sql/tables.cpp b/modules/extra/stats/irc2sql/tables.cpp
deleted file mode 100644
index 807c7c8cd..000000000
--- a/modules/extra/stats/irc2sql/tables.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- *
- * (C) 2013-2024 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "irc2sql.h"
-
-void IRC2SQL::CheckTables()
-{
- Anope::string geoquery("");
-
- if (firstrun)
- {
- /*
- * reset some tables to make sure they are really empty
- */
- this->sql->RunQuery("TRUNCATE TABLE " + prefix + "user");
- this->sql->RunQuery("TRUNCATE TABLE " + prefix + "chan");
- this->sql->RunQuery("TRUNCATE TABLE " + prefix + "ison");
- this->sql->RunQuery("UPDATE `" + prefix + "server` SET currentusers=0, online='N'");
- }
-
- this->GetTables();
-
- if (GeoIPDB.equals_ci("country"))
- {
- if (!this->HasTable(prefix + "geoip_country"))
- {
- query = "CREATE TABLE `" + prefix + "geoip_country` ("
- "`start` INT UNSIGNED NOT NULL,"
- "`end` INT UNSIGNED NOT NULL,"
- "`countrycode` varchar(2),"
- "`countryname` varchar(50),"
- "PRIMARY KEY `end` (`end`),"
- "KEY `start` (`start`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- }
- else if (GeoIPDB.equals_ci("city"))
- {
- if (!this->HasTable(prefix + "geoip_city_blocks"))
- {
- query = "CREATE TABLE `" + prefix + "geoip_city_blocks` ("
- "`start` INT UNSIGNED NOT NULL,"
- "`end` INT UNSIGNED NOT NULL,"
- "`locId` INT UNSIGNED NOT NULL,"
- "PRIMARY KEY `end` (`end`),"
- "KEY `start` (`start`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (!this->HasTable(prefix + "geoip_city_location"))
- {
- query = "CREATE TABLE `" + prefix + "geoip_city_location` ("
- "`locId` INT UNSIGNED NOT NULL,"
- "`country` CHAR(2) NOT NULL,"
- "`region` CHAR(2) NOT NULL,"
- "`city` VARCHAR(50),"
- "`latitude` FLOAT,"
- "`longitude` FLOAT,"
- "`areaCode` INT,"
- "PRIMARY KEY (`locId`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (!this->HasTable(prefix + "geoip_city_region"))
- { query = "CREATE TABLE `" + prefix + "geoip_city_region` ("
- "`country` CHAR(2) NOT NULL,"
- "`region` CHAR(2) NOT NULL,"
- "`regionname` VARCHAR(100) NOT NULL,"
- "PRIMARY KEY (`country`,`region`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- }
- if (!this->HasTable(prefix + "server"))
- {
- query = "CREATE TABLE `" + prefix + "server` ("
- "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,"
- "`name` varchar(64) NOT NULL,"
- "`hops` tinyint(3) NOT NULL,"
- "`comment` varchar(255) NOT NULL,"
- "`link_time` datetime DEFAULT NULL,"
- "`split_time` datetime DEFAULT NULL,"
- "`version` varchar(127) DEFAULT NULL,"
- "`currentusers` int(15) DEFAULT 0,"
- "`online` enum('Y','N') NOT NULL DEFAULT 'Y',"
- "`ulined` enum('Y','N') NOT NULL DEFAULT 'N',"
- "PRIMARY KEY (`id`),"
- "UNIQUE KEY `name` (`name`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (!this->HasTable(prefix + "chan"))
- {
- query = "CREATE TABLE `" + prefix + "chan` ("
- "`chanid` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,"
- "`channel` varchar(255) NOT NULL,"
- "`topic` varchar(512) DEFAULT NULL,"
- "`topicauthor` varchar(255) DEFAULT NULL,"
- "`topictime` datetime DEFAULT NULL,"
- "`modes` varchar(512) DEFAULT NULL,"
- "PRIMARY KEY (`chanid`),"
- "UNIQUE KEY `channel`(`channel`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (!this->HasTable(prefix + "user"))
- {
- query = "CREATE TABLE `" + prefix + "user` ("
- "`nickid` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,"
- "`nick` varchar(255) NOT NULL DEFAULT '',"
- "`host` varchar(255) NOT NULL DEFAULT '',"
- "`vhost` varchar(255) NOT NULL DEFAULT '',"
- "`chost` varchar(255) NOT NULL DEFAULT '',"
- "`realname` varchar(255) NOT NULL DEFAULT '',"
- "`ip` varchar(255) NOT NULL DEFAULT '',"
- "`ident` varchar(32) NOT NULL DEFAULT '',"
- "`vident` varchar(32) NOT NULL DEFAULT '',"
- "`modes` varchar(255) NOT NULL DEFAULT '',"
- "`account` varchar(255) NOT NULL DEFAULT '',"
- "`secure` enum('Y','N') NOT NULL DEFAULT 'N',"
- "`fingerprint` varchar(128) NOT NULL DEFAULT '',"
- "`signon` datetime DEFAULT NULL,"
- "`server` varchar(255) NOT NULL DEFAULT '',"
- "`servid` int(11) UNSIGNED NOT NULL DEFAULT '0',"
- "`uuid` varchar(32) NOT NULL DEFAULT '',"
- "`oper` enum('Y','N') NOT NULL DEFAULT 'N',"
- "`away` enum('Y','N') NOT NULL DEFAULT 'N',"
- "`awaymsg` varchar(255) NOT NULL DEFAULT '',"
- "`version` varchar(255) NOT NULL DEFAULT '',"
- "`geocode` varchar(16) NOT NULL DEFAULT '',"
- "`geocountry` varchar(64) NOT NULL DEFAULT '',"
- "`georegion` varchar(100) NOT NULL DEFAULT '',"
- "`geocity` varchar(128) NOT NULL DEFAULT '',"
- "`locId` INT UNSIGNED,"
- "PRIMARY KEY (`nickid`),"
- "UNIQUE KEY `nick` (`nick`),"
- "KEY `servid` (`servid`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (!this->HasTable(prefix + "ison"))
- {
- query = "CREATE TABLE `" + prefix + "ison` ("
- "`nickid` int(11) unsigned NOT NULL default '0',"
- "`chanid` int(11) unsigned NOT NULL default '0',"
- "`modes` varchar(255) NOT NULL default '',"
- "PRIMARY KEY (`nickid`,`chanid`),"
- "KEY `modes` (`modes`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (!this->HasTable(prefix + "maxusers"))
- {
- query = "CREATE TABLE `" + prefix + "maxusers` ("
- "`name` VARCHAR(255) NOT NULL,"
- "`maxusers` INT(15) NOT NULL,"
- "`maxtime` DATETIME NOT NULL,"
- "`lastused` DATETIME NOT NULL,"
- "UNIQUE KEY `name` (`name`)"
- ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
- this->RunQuery(query);
- }
- if (this->HasProcedure(prefix + "UserConnect"))
- this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "UserConnect"));
-
- if (GeoIPDB.equals_ci("country"))
- geoquery = "UPDATE `" + prefix + "user` AS u "
- "JOIN ( SELECT `countrycode`, `countryname` "
- "FROM `" + prefix + "geoip_country` "
- "WHERE INET_ATON(ip_) <= `end` "
- "AND `start` <= INET_ATON(ip_) "
- "ORDER BY `end` ASC LIMIT 1 ) as c "
- "SET u.geocode = c.countrycode, u.geocountry = c.countryname "
- "WHERE u.nick = nick_; ";
- else if (GeoIPDB.equals_ci("city"))
- geoquery = "UPDATE `" + prefix + "user` as u "
- "JOIN ( SELECT * FROM `" + prefix + "geoip_city_location` "
- "WHERE `locID` = ( SELECT `locID` "
- "FROM `" + prefix + "geoip_city_blocks` "
- "WHERE INET_ATON(ip_) <= `end` "
- "AND `start` <= INET_ATON(ip_) "
- "ORDER BY `end` ASC LIMIT 1 ) "
- ") as l "
- "SET u.geocode = l.country, "
- "u.geocity = l.city, "
- "u.locID = l.locID, "
- "u.georegion = ( SELECT `regionname` "
- "FROM `" + prefix + "geoip_city_region` "
- "WHERE `country` = l.country "
- "AND `region` = l.region )"
- "WHERE u.nick = nick_;";
-
- query = "CREATE PROCEDURE `" + prefix + "UserConnect`"
- "(nick_ varchar(255), host_ varchar(255), vhost_ varchar(255), "
- "chost_ varchar(255), realname_ varchar(255), ip_ varchar(