diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
index 37d58b26f..df4471ddc 100644
--- a/data/CMakeLists.txt
+++ b/data/CMakeLists.txt
@@ -1,6 +1,6 @@
# Only install cron.example.sh and anope.example.conf from this directory
# NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file)
-set(DATA cron.example.sh anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf irc2sql.example.conf stats.standalone.example.conf)
+set(DATA cron.example.sh anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf)
install(FILES ${DATA}
DESTINATION ${CONF_DIR}
)
diff --git a/data/anope.example.conf b/data/anope.example.conf
index 2b7860f2a..68db39c4d 100644
--- a/data/anope.example.conf
+++ b/data/anope.example.conf
@@ -1414,23 +1414,3 @@ include
type = "file"
name = "chanstats.example.conf"
}
-
-/*
- * [DEPRECATED] IRC2SQL Gateway
- *
- * This module collects data about users, channels and servers. It doesn't build stats
- * itself, however, it gives you the database, it's up to you how you use it.
- *
- * This module is deprecated in favour of the RPC interface and the rpc_data
- * module. This should provide almost all of the same information as irc2sql but
- * without requiring MySQL and with much better performance. If you have a use
- * case which is not covered by rpc_data then please open an issue so we can
- * extend rpc_data before irc2sql is removed.
- *
- * Requires a MySQL Database and MySQL version 5.5 or higher
- */
-#include
-{
- type = "file"
- name = "irc2sql.example.conf"
-}
diff --git a/data/irc2sql.example.conf b/data/irc2sql.example.conf
deleted file mode 100644
index 260cf836a..000000000
--- a/data/irc2sql.example.conf
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Example configuration file for the irc2sql gateway
- *
- */
-
-service
-{
- /*
- * The name of the StatServ client.
- */
- nick = "StatServ"
-
- /*
- * The username of the StatServ client.
- */
- user = "StatServ"
-
- /*
- * The hostname of the StatServ client.
- */
- host = "${services.host}"
-
- /*
- * The realname of the StatServ client.
- */
- real = "Statistical 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"
-
- /*
- * An optional comma separated list of channels this service should join. Outside
- * of log channels this is not very useful, as the service will just idle in the
- * specified channels, and will not accept any types of commands.
- *
- * Prefixes may be given to the channels in the form of mode characters or prefix symbols.
- */
- #channels = "@#stats,#mychan"
-}
-
-module
-{
- name = "irc2sql"
-
- /*
- * The name of the client that should send the CTCP VERSION requests.
- * It must already exist or must be defined in the following service block.
- */
- client = "StatServ"
-
- /*
- * The name of the SQL engine to use.
- * This must be MySQL and must match the name in the mysql{} block
- */
- engine = "mysql/main"
-
- /*
- * An optional prefix to prepended to the name of each created table.
- * Do not use the same prefix for other programs.
- */
- prefix = "anope_"
-
- /*
- * GeoIP - Automatically adds users geoip location to the user table.
- * Tables are created by irc2sql, you have to run the
- * geoipupdate script after you started Anope to download
- * and import the GeoIP database.
- *
- * The geoip database can be the smaller "country" database or the
- * larger "city" database. Comment to disable geoip lookup.
- */
- geoip_database = "country"
-
- /*
- * Get the CTCP version from users
- * The users connecting to the network will receive a CTCP VERSION
- * request from the above configured stats client
- */
- ctcpuser = "yes"
-
- /*
- * Send out CTCP VERSION requests to users during burst.
- * Disable this if you restart Anope often and don't want to
- * annoy your users.
- */
- ctcpeob = "yes"
-}
diff --git a/data/stats.standalone.example.conf b/data/stats.standalone.example.conf
deleted file mode 100644
index 00c2e3e17..000000000
--- a/data/stats.standalone.example.conf
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Example configuration file for Anope. After making the appropriate
- * changes to this file, place it in the Anope conf directory (as
- * specified in the "Config" script, default /home/username/anope/conf)
- * under the name "anope.conf".
- *
- * The format of this file is fairly simple: three types of comments are supported:
- * - All text after a '#' on a line is ignored, as in shell scripting
- * - All text after '//' on a line is ignored, as in C++
- * - A block of text like this one is ignored, as in C
- *
- * Outside of comments, there are three structures: blocks, keys, and values.
- *
- * A block is a named container, which contains a number of key to value pairs
- * - you may think of this as an array.
- *
- * A block is created like so:
- * foobar
- * {
- * moo = "cow"
- * foo = bar
- * }
- *
- * Note that nameless blocks are allowed and are often used with comments to allow
- * easily commenting an entire block, for example:
- * #foobar
- * {
- * moo = "cow"
- * foo = bar
- * }
- * is an entirely commented block.
- *
- * Keys are case insensitive. Values depend on what key - generally, information is
- * given in the key comment. The quoting of values (and most other syntax) is quite
- * flexible, however, please do not forget to quote your strings:
- *
- * "This is a parameter string with spaces in it"
- *
- * If you need to include a double quote inside a quoted string, precede it
- * by a backslash:
- *
- * "This string has \"double quotes\" in it"
- *
- * Time parameters can be specified either as an integer representing a
- * number of seconds (e.g. "3600" = 1 hour), or as an integer with a unit
- * specifier: "s" = seconds, "m" = minutes, "h" = hours, "d" = days.
- * Combinations (such as "1h30m") are not permitted. Examples (all of which
- * represent the same length of time, one day):
- *
- * "86400", "86400s", "1440m", "24h", "1d"
- *
- * In the documentation for each directive, one of the following will be
- * included to indicate whether an option is required:
- *
- * [REQUIRED]
- * Indicates a directive which must be given. Without it, Anope will
- * not start.
- *
- * [RECOMMENDED]
- * Indicates a directive which may be omitted, but omitting it may cause
- * undesirable side effects.
- *
- * [OPTIONAL]
- * Indicates a directive which is optional. If not given, the feature
- * will typically be disabled. If this is not the case, more
- * information will be given in the documentation.
- *
- * [DISCOURAGED]
- * Indicates a directive which may cause undesirable side effects if
- * specified.
- *
- * [DEPRECATED]
- * Indicates a directive which will disappear in a future version of
- * Anope, usually because its functionality has been either
- * superseded by that of other directives or incorporated into the main
- * program.
- */
-
-/*
- * [OPTIONAL] Defines
- *
- * You can use defines for repeated information, which can be used to easily change many
- * values in the configuration at once.
- *
- * To use a define called foo.bar you use ${foo.bar} in your config file. You can also use
- * environment variables by prefixing their name with "env." like ${env.USER}.
- */
-
-/*
- * The services.host define is used in multiple different locations throughout the
- * configuration for the server name and pseudoclient hostnames.
- */
-define
-{
- name = "services.host"
- value = "stats.example.com"
-}
-
-/*
- * [OPTIONAL] Additional Includes
- *
- * You can include additional configuration files here.
- * You may also include executable files, which will be executed and
- * the output from it will be included into your configuration.
- */
-
-#include
-{
- type = "file"
- name = "some.conf"
-}
-
-#include
-{
- type = "executable"
- name = "/usr/bin/wget -q -O - https://some.misconfigured.network.com/stats.conf"
-}
-
-/*
- * [REQUIRED] IRCd Config
- *
- * This section is used to set up Anope to connect to your IRC network.
- * This section can be included multiple times, and Anope will attempt to
- * connect to each server until it finally connects.
- *
- * Each uplink IRCd should have a corresponding configuration to allow Anope
- * to link to it.
- *
- * An example configuration for InspIRCd that is compatible with the below uplink
- * and serverinfo configuration would look like:
- *
- * # This goes in inspircd.conf, *NOT* your Anope config!
- *
- *
- *
- *
- * An example configuration for UnrealIRCd that is compatible with the below uplink
- * and serverinfo configuration would look like:
- *
- * // This goes in unrealircd.conf, *NOT* your Anope config!
- * listen {
- * ip 127.0.0.1;
- * port 7000;
- * options {
- * serversonly;
- * };
- * };
- * link stats.example.com {
- * incoming {
- * mask *@127.0.0.1;
- * };
- * password "mypassword";
- * class servers;
- * };
- * ulines { stats.example.com; };
- */
-uplink
-{
- /*
- * The IP address, hostname, or UNIX socket path of the IRC server you wish
- * to connect Anope to.
- * Usually, you will want to connect over 127.0.0.1 (aka localhost).
- *
- * NOTE: On some shell providers, this will not be an option.
- */
- host = "127.0.0.1"
-
- /*
- * The protocol that Anope should use when connecting to the uplink. Can
- * be set to "ipv4" (the default), "ipv6", or "unix".
- */
- protocol = "ipv4"
-
- /*
- * Enable if Anope should connect using SSL.
- * You must have an SSL module loaded for this to work.
- */
- ssl = no
-
- /*
- * The port to connect to.
- * The IRCd *MUST* be configured to listen on this port, and to accept
- * server connections.
- *
- * Refer to your IRCd documentation for how this is to be done.
- */
- port = 7000
-
- /*
- * The password to send to the IRC server for authentication.
- * This must match the link block on your IRCd.
- *
- * Refer to your IRCd documentation for more information on link blocks.
- */
- password = "mypassword"
-}
-
-/*
- * [REQUIRED] Server Information
- *
- * This section contains information about the services server.
- */
-serverinfo
-{
- /*
- * The hostname that Anope will be seen as, it must have no conflicts with any
- * other server names on the rest of your IRC network. Note that it does not have
- * to be an existing hostname, just one that isn't on your network already.
- */
- name = "${services.host}"
-
- /*
- * The text which should appear as the server's information in /WHOIS and similar
- * queries.
- */
- description = "Anope IRC Statistics"
-
- /*
- * The local address that Anope will bind to before connecting to the remote
- * server. This may be useful for multihomed hosts. If omitted, Anope will let
- * the Operating System choose the local address. This directive is optional.
- *
- * If you don't know what this means or don't need to use it, just leave this
- * directive commented out.
- */
- #localhost = "nowhere."
-
- /*
- * What Server ID to use for this connection?
- * Note: This should *ONLY* be used for TS6/P10 IRCds. Refer to your IRCd documentation
- * to see if this is needed.
- */
- #id = "00A"
-
- /*
- * The filename containing the Anope process ID. The path is relative to the
- * data directory.
- */
- pid = "anope.pid"
-
- /*
- * The filename containing the Message of the Day. The path is relative to the
- * config directory.
- */
- motd = "motd.txt"
-}
-
-/*
- * [REQUIRED] Protocol module
- *
- * This directive tells Anope which IRCd Protocol to speak when connecting.
- * You MUST modify this to match the IRCd you run.
- *
- * Supported:
- * - hybrid
- * - inspircd
- * - ngircd
- * - plexus
- * - ratbox
- * - solanum
- * - unrealircd
- */
-module
-{
- name = "inspircd"
-}
-
-/*
- * [REQUIRED] Network Information
- *
- * This section contains information about the IRC network that Anope will be
- * connecting to.
- */
-networkinfo
-{
- /*
- * This is the name of the network that Anope will be running on.
- */
- networkname = "LocalNet"
-
- /*
- * Set this to the maximum allowed nick length on your network.
- * Be sure to set this correctly, as setting this wrong can result in
- * Anope being disconnected from the network. Defaults to 31.
- */
- #nicklen = 31
-
- /* Set this to the maximum allowed ident length on your network.
- * Be sure to set this correctly, as setting this wrong can result in
- * Anope being disconnected from the network. Defaults to 10.
- */
- #userlen = 10
-
- /* Set this to the maximum allowed hostname length on your network.
- * Be sure to set this correctly, as setting this wrong can result in
- * Anope being disconnected from the network. Defaults to 64.
- */
- #hostlen = 64
-
- /* Set this to the maximum allowed channel length on your network.
- * Defaults to 64.
- */
- #chanlen = 32
-
- /* The maximum number of list modes settable on a channel (such as b, e, I).
- * Comment out or set to 0 to disable.
- */
- modelistsize = 100
-
- /*
- * The characters allowed in hostnames. This is used for validating hostnames given
- * to services, such as BotServ bot hostnames and user vhosts. Changing this is not
- * recommended unless you know for sure your IRCd supports whatever characters you are
- * wanting to use. Telling services to set a vhost containing characters your IRCd
- * disallows could potentially break the IRCd and/or Anope.
- *
- * It is recommended you DON'T change this.
- */
- vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
-
- /*
- * If enabled, allows vhosts to not contain dots (.).
- * Newer IRCds generally do not have a problem with this, but the same warning as
- * vhost_chars applies.
- *
- * It is recommended you DON'T change this.
- */
- allow_undotted_vhosts = no
-
- /*
- * The characters that are not allowed to be at the very beginning or very ending
- * of a vhost. The same warning as vhost_chars applies.
- *
- * It is recommended you DON'T change this.
- */
- disallow_start_or_end = ".-"
-}
-
-/*
- * [REQUIRED] Anope Options
- *
- * This section contains various options which determine how Anope will operate.
- */
-options
-{
- /*
- * On Linux/UNIX systems Anope can setuid and setgid to this user and group
- * after starting up. This is useful if Anope has to bind to privileged ports.
- */
- #user = "anope"
- #group = "anope"
-
- /*
- * The case mapping used by services. This must be set to a valid locale name
- * installed on your machine. Anope uses this case map to compare, with
- * case insensitivity, things such as nick names, channel names, etc.
- *
- * We provide two special casemaps shipped with Anope, ascii and rfc1459.
- *
- * This value should be set to what your IRCd uses, which is probably rfc1459,
- * however Anope has always used ascii for comparison, so the default is ascii.
- *
- * Changing this value once set is not recommended.
- */
- casemap = "ascii"
-
- /*
- * Sets the timeout period for reading from the uplink.
- */
- readtimeout = 5s
-
- /*
- * If set, Anope will only show /stats o to IRC Operators. This directive
- * is optional.
- */
- #hidestatso = yes
-
- /*
- * A space-separated list of U-lined servers on your network, it is assumed that
- * the servers in this list are allowed to set channel modes and Anope will
- * not attempt to reverse their mode changes.
- *
- * WARNING: Do NOT put your normal IRC user servers in this directive.
- *
- * This directive is optional.
- */
- #ulineservers = "services.your.network"
-
- /*
- * How long to wait between connection retries with the uplink(s).
- */
- retrywait = 60s
-}
-
-/*
- * [RECOMMENDED] Logging Configuration
- *
- * This section is used for configuring what is logged and where it is logged to.
- * You may have multiple log blocks if you wish. Remember to properly secure any
- * channels you choose to have Anope log to!
- */
-log
-{
- /*
- * Target(s) to log to, which may be one of the following:
- * - a channel name
- * - a filename
- * - globops
- */
- target = "stats.log"
-
- /* Log to both stats.log and the channel #stats
- *
- * Note that some older IRCds, such as Ratbox, require services to be in the
- * log channel to be able to message it. To do this, configure service:channels to
- * join your logging channel.
- */
- #target = "stats.log #stats"
-
- /*
- * The source(s) to only accept log messages from. Leave commented to allow all sources.
- * This can be a users name, a channel name, one of our clients (e.g. OperServ), or a server name.
- */
- #source = ""
-
- /*
- * The bot used to log generic messages which have no predefined sender if there
- * is a channel in the target directive.
- */
- bot = "Global"
-
- /*
- * The number of days to keep log files, only useful if you are logging to a file.
- * Set to 0 to never delete old log files.
- *
- * Note that Anope must run 24 hours a day for this feature to work correctly.
- */
- logage = 7
-
- /*
- * What types of log messages should be logged by this block. There are nine general categories:
- *
- * servers - Server actions, linking, squitting, etc.
- * channels - Actions in channels such as joins, parts, kicks, etc.
- * users - User actions such as connecting, disconnecting, changing name, etc.
- * other - All other messages without a category.
- * rawio - Logs raw input and output from services
- * debug - Debug messages (log files can become VERY large from this).
- *
- * These options determine what messages from the categories should be logged. Wildcards are accepted, and
- * you can also negate values with a ~. For example, "~operserv/akill operserv/*" would log all operserv
- * messages except for operserv/akill. Note that processing stops at the first matching option, which
- * means "* ~operserv/*" would log everything because * matches everything.
- *
- * Valid server options are:
- * connect, quit, sync, squit
- *
- * Valid channel options are:
- * create, destroy, join, part, kick, leave, mode
- *
- * Valid user options are:
- * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper, away
- *
- * Rawio and debug are simple yes/no answers, there are no types for them.
- *
- * Note that modules may add their own values to these options.
- */
- servers = "*"
- #channels = "~mode *"
- users = "connect disconnect nick"
- other = "*"
- rawio = no
- debug = no
-}
-
-/*
- * [REQUIRED] MySQL Database configuration.
- *
- * mysql
- *
- * This module allows other modules to use MySQL.
- */
-module
-{
- name = "mysql"
-
- mysql
- {
- /* The name of this service. */
- name = "mysql/main"
- database = "anope"
- server = "127.0.0.1"
- username = "anope"
- password = "mypassword"
- port = 3306
- }
-}
-
-/*
- * IRC2SQL Gateway
- * This module collects data about users, channels and servers. It doesn't build stats
- * itself, however, it gives you the database, it's up to you how you use it.
- *
- * Requires a MySQL Database and MySQL version 5.5 or higher
- */
-include
-{
- type = "file"
- name = "irc2sql.example.conf"
-}
diff --git a/modules/irc2sql/CMakeLists.txt b/modules/irc2sql/CMakeLists.txt
deleted file mode 100644
index 781f0ef1f..000000000
--- a/modules/irc2sql/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/modules/irc2sql/irc2sql.cpp b/modules/irc2sql/irc2sql.cpp
deleted file mode 100644
index 629a749d2..000000000
--- a/modules/irc2sql/irc2sql.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- *
- * (C) 2013-2025 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 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)
-{
- const auto &block = Config->GetModule(this);
- prefix = block.Get("prefix", "anope_");
- GeoIPDB = block.Get("geoip_database");
- ctcpuser = block.Get("ctcpuser", "no");
- ctcpeob = block.Get("ctcpeob", "yes");
- Anope::string engine = block.Get("engine");
- this->sql = ServiceReference("SQL::Provider", engine);
- if (sql)
- this->CheckTables();
- else
- Log() << "IRC2SQL: no database connection to " << engine;
-
- const Anope::string &snick = block.Get("client");
- if (snick.empty())
- throw ConfigException(Module::name + ": 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::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->IsIdentified() ? 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(), Anope::FormatCTCP("VERSION"));
-
-}
-
-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->IsIdentified() ? 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 ModeData &data)
-{
- if (mode->type == MODE_STATUS)
- {
- User *u = User::Find(data.value);
- 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 ¶m)
-{
- 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, const Anope::map &tags)
-{
- if (bi != StatServ)
- return;
-
- Anope::string ctcpname, ctcpbody;
- if (!Anope::ParseCTCP(message, ctcpname, ctcpbody) || ctcpname != "VERSION")
- return;
-
- if (u->HasExt("CTCPVERSION"))
- return;
-
- u->Extend("CTCPVERSION");
- auto versionstr = Anope::NormalizeBuffer(ctcpbody);
- 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/irc2sql/irc2sql.h b/modules/irc2sql/irc2sql.h
deleted file mode 100644
index 95d01cc4a..000000000
--- a/modules/irc2sql/irc2sql.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *
- * (C) 2013-2025 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 final
- : 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) << "irc2sql: Error executing query " << r.finished_query << ": " << r.GetError();
- else
- Log(LOG_DEBUG) << "irc2sql: Error executing query: " << r.GetError();
- }
-};
-
-class IRC2SQL final
- : public Module
-{
- ServiceReference sql;
- MySQLInterface sqlinterface;
- SQL::Query query;
- std::vector TableList, ProcedureList, EventList;
- Anope::string prefix, GeoIPDB;
- bool quitting, introduced_myself, ctcpuser, ctcpeob, firstrun;
- BotInfo *StatServ;
- PrimitiveExtensibleItem 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 ModeData &data) override;
- EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) 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, const Anope::map &tags) override;
-};
diff --git a/modules/irc2sql/tables.cpp b/modules/irc2sql/tables.cpp
deleted file mode 100644
index b00c0e9a5..000000000
--- a/modules/irc2sql/tables.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- *
- * (C) 2013-2025 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 UNSIGNED NOT NULL AUTO_INCREMENT,"
- "`name` varchar(64) NOT NULL,"
- "`hops` tinyint NOT NULL,"
- "`comment` varchar(255) NOT NULL,"
- "`link_time` datetime DEFAULT NULL,"
- "`split_time` datetime DEFAULT NULL,"
- "`version` varchar(127) DEFAULT NULL,"
- "`currentusers` int 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 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 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 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 unsigned NOT NULL default '0',"
- "`chanid` int 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 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(255), "
- "ident_ varchar(255), vident_ varchar(255), account_ varchar(255), "
- "secure_ enum('Y','N'), fingerprint_ varchar(255), signon_ int, "
- "server_ varchar(255), uuid_ varchar(32), modes_ varchar(255), "
- "oper_ enum('Y','N')) "
- "BEGIN "
- "DECLARE cur int;"
- "DECLARE max int;"
- "INSERT INTO `" + prefix + "user` "
- "(nick, host, vhost, chost, realname, ip, ident, vident, account, "
- "secure, fingerprint, signon, server, uuid, modes, oper) "
- "VALUES (nick_, host_, vhost_, chost_, realname_, ip_, ident_, vident_, "
- "account_, secure_, fingerprint_, FROM_UNIXTIME(signon_), server_, "
- "uuid_, modes_, oper_) "
- "ON DUPLICATE KEY UPDATE host=VALUES(host), vhost=VALUES(vhost), "
- "chost=VALUES(chost), realname=VALUES(realname), ip=VALUES(ip), "
- "ident=VALUES(ident), vident=VALUES(vident), account=VALUES(account), "
- "secure=VALUES(secure), fingerprint=VALUES(fingerprint), signon=VALUES(signon), "
- "server=VALUES(server), uuid=VALUES(uuid), modes=VALUES(modes), "
- "oper=VALUES(oper);"
- "UPDATE `" + prefix + "user` as `u`, `" + prefix + "server` as `s`"
- "SET u.servid = s.id, "
- "s.currentusers = s.currentusers + 1 "
- "WHERE s.name = server_ AND u.nick = nick_;"
- "SELECT `currentusers` INTO cur FROM `" + prefix + "server` WHERE name=server_;"
- "SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=server_;"
- "IF found_rows() AND cur <= max THEN "
- "UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=server_;"
- "ELSE "
- "INSERT INTO `" + prefix + "maxusers` (name, maxusers, maxtime, lastused) "
- "VALUES ( server_, cur, now(), now() ) "
- "ON DUPLICATE KEY UPDATE "
- "name=VALUES(name), maxusers=VALUES(maxusers),"
- "maxtime=VALUES(maxtime), lastused=VALUES(lastused);"
- "END IF;"
- + geoquery +
- "END";
- this->RunQuery(query);
-
- if (this->HasProcedure(prefix + "ServerQuit"))
- this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "ServerQuit"));
- query = "CREATE PROCEDURE " + prefix + "ServerQuit(sname_ varchar(255)) "
- "BEGIN "
- /* 1.
- * remove all users on the splitting server from the ison table
- */
- "DELETE i FROM `" + prefix + "ison` AS i "
- "INNER JOIN `" + prefix + "server` AS s "
- "INNER JOIN `" + prefix + "user` AS u "
- "WHERE i.nickid = u.nickid "
- "AND u.servid = s.id "
- "AND s.name = sname_;"
-
- /* 2.
- * remove all users on the splitting server from the user table
- */
- "DELETE u FROM `" + prefix + "user` AS u "
- "INNER JOIN `" + prefix + "server` AS s "
- "WHERE s.id = u.servid "
- "AND s.name = sname_;"
-
- /* 3.
- * on the splitting server, set usercount = 0, split_time = now(), online = 'N'
- */
- "UPDATE `" + prefix + "server` SET currentusers = 0, split_time = now(), online = 'N' "
- "WHERE name = sname_;"
- "END;"; // end of the procedure
- this->RunQuery(query);
-
-
- if (this->HasProcedure(prefix + "UserQuit"))
- this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "UserQuit"));
- query = "CREATE PROCEDURE `" + prefix + "UserQuit`"
- "(nick_ varchar(255)) "
- "BEGIN "
- /* decrease usercount on the server where the user was on */
- "UPDATE `" + prefix + "user` AS `u`, `" + prefix + "server` AS `s` "
- "SET s.currentusers = s.currentusers - 1 "
- "WHERE u.nick=nick_ AND u.servid = s.id; "
- /* remove from all channels where the user was on */
- "DELETE i FROM `" + prefix + "ison` AS i "
- "INNER JOIN `" + prefix + "user` as u "
- "WHERE u.nick = nick_ "
- "AND i.nickid = u.nickid;"
- /* remove the user from the user table */
- "DELETE FROM `" + prefix + "user` WHERE nick = nick_; "
- "END";
- this->RunQuery(query);
-
- if (this->HasProcedure(prefix + "ShutDown"))
- this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "ShutDown"));
- query = "CREATE PROCEDURE `" + prefix + "ShutDown`()"
- "BEGIN "
- "UPDATE `" + prefix + "server` "
- "SET currentusers=0, online='N', split_time=now();"
- "TRUNCATE TABLE `" + prefix + "user`;"
- "TRUNCATE TABLE `" + prefix + "chan`;"
- "TRUNCATE TABLE `" + prefix + "ison`;"
- "END";
- this->RunQuery(query);
-
- if (this->HasProcedure(prefix + "JoinUser"))
- this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "JoinUser"));
- query = "CREATE PROCEDURE `"+ prefix + "JoinUser`"
- "(nick_ varchar(255), channel_ varchar(255), modes_ varchar(255)) "
- "BEGIN "
- "DECLARE cur int;"
- "DECLARE max int;"
- "INSERT INTO `" + prefix + "ison` (nickid, chanid, modes) "
- "SELECT u.nickid, c.chanid, modes_ "
- "FROM " + prefix + "user AS u, " + prefix + "chan AS c "
- "WHERE u.nick=nick_ AND c.channel=channel_;"
- "SELECT count(i.chanid) INTO cur "
- "FROM `" + prefix + "chan` AS c, " + prefix + "ison AS i "
- "WHERE i.chanid = c.chanid AND c.channel=channel_;"
- "SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=channel_;"
- "IF found_rows() AND cur <= max THEN "
- "UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=channel_;"
- "ELSE "
- "INSERT INTO `" + prefix + "maxusers` (name, maxusers, maxtime, lastused) "
- "VALUES ( channel_, cur, now(), now() ) "
- "ON DUPLICATE KEY UPDATE "
- "name=VALUES(name), maxusers=VALUES(maxusers),"
- "maxtime=VALUES(maxtime), lastused=VALUES(lastused);"
- "END IF;"
- "END";
- this->RunQuery(query);
-
- if (this->HasProcedure(prefix + "PartUser"))
- this->RunQuery(SQL::Query("DROP PROCEDURE " + prefix + "PartUser"));
- query = "CREATE PROCEDURE `" + prefix + "PartUser`"
- "(nick_ varchar(255), channel_ varchar(255)) "
- "BEGIN "
- "DELETE i FROM `" + prefix + "ison` AS i "
- "INNER JOIN `" + prefix + "user` AS u "
- "INNER JOIN `" + prefix + "chan` AS c "
- "WHERE i.nickid = u.nickid "
- "AND u.nick = nick_ "
- "AND i.chanid = c.chanid "
- "AND c.channel = channel_;"
- "END";
- this->RunQuery(query);
-}
diff --git a/modules/irc2sql/utils.cpp b/modules/irc2sql/utils.cpp
deleted file mode 100644
index 7debdda9d..000000000
--- a/modules/irc2sql/utils.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * (C) 2013-2025 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- */
-
-#include "irc2sql.h"
-
-void IRC2SQL::RunQuery(const SQL::Query &q)
-{
- if (sql)
- sql->Run(&sqlinterface, q);
-}
-
-void IRC2SQL::GetTables()
-{
- TableList.clear();
- ProcedureList.clear();
- EventList.clear();
- if (!sql)
- return;
-
- SQL::Result r = this->sql->RunQuery(this->sql->GetTables(prefix));
- for (int i = 0; i < r.Rows(); ++i)
- {
- const std::map &map = r.Row(i);
- for (std::map::const_iterator it = map.begin(); it != map.end(); ++it)
- TableList.push_back(it->second);
- }
- query = "SHOW PROCEDURE STATUS WHERE `Db` = Database();";
- r = this->sql->RunQuery(query);
- for (int i = 0; i < r.Rows(); ++i)
- {
- ProcedureList.push_back(r.Get(i, "Name"));
- }
- query = "SHOW EVENTS WHERE `Db` = Database();";
- r = this->sql->RunQuery(query);
- for (int i = 0; i < r.Rows(); ++i)
- {
- EventList.push_back(r.Get(i, "Name"));
- }
-}
-
-bool IRC2SQL::HasTable(const Anope::string &table)
-{
- for (std::vector::const_iterator it = TableList.begin(); it != TableList.end(); ++it)
- if (*it == table)
- return true;
- return false;
-}
-
-bool IRC2SQL::HasProcedure(const Anope::string &table)
-{
- for (std::vector::const_iterator it = ProcedureList.begin(); it != ProcedureList.end(); ++it)
- if (*it == table)
- return true;
- return false;
-}
-
-bool IRC2SQL::HasEvent(const Anope::string &table)
-{
- for (std::vector::const_iterator it = EventList.begin(); it != EventList.end(); ++it)
- if (*it == table)
- return true;
- return false;
-}
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 249a036ad..56130e004 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -41,9 +41,6 @@ if(NOT WIN32)
install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/anoperc
DESTINATION ${BIN_DIR}
)
- install (PROGRAMS geoipupdate.sh
- DESTINATION ${BIN_DIR}
- )
endif()
# On non-Windows platforms, if RUNGROUP is set, change the permissions of the tools directory
diff --git a/src/tools/geoipupdate.sh b/src/tools/geoipupdate.sh
deleted file mode 100755
index fbc521318..000000000
--- a/src/tools/geoipupdate.sh
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-
-# This script is a helper script for the irc2sql module.
-# It downloads the configured geoip databases and inserts
-# them into existing mysql tables. The tables are created
-# by the irc2sql module on the first load.
-
-# Don't forget to rename this file or your changes
-# will be overwritten on the next 'make install'
-
-############################
-# Config
-############################
-
-
-geoip_database="country" # available options: "country" and "city"
-mysql_host="localhost"
-mysql_user="anope"
-mysql_password="anope"
-mysql_database="anope"
-prefix="anope_"
-die="yes"
-
-###########################
-
-# The GeoIP data is created by MaxMind, available from www.maxmind.com.
-geoip_country_source="https://mirrors-cdn.liferay.com/geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip"
-geoip_city_source="https://mirrors-cdn.liferay.com/geolite.maxmind.com/download/geoip/database/GeoLiteCity-latest.tar.xz"
-geoip_region_source="https://www.maxmind.com/download/geoip/misc/region_codes.csv"
-
-###########################
-LOGIN="--host=$mysql_host --user=$mysql_user --password=$mysql_password $mysql_database"
-PARAMS="--delete --local --fields-terminated-by=, --fields-enclosed-by=\" --lines-terminated-by=\n $LOGIN"
-
-download() {
- local url=$1
- local desc=$2
- echo -n " $desc "
- wget --progress=dot $url 2>&1 | grep --line-buffered "%" | sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}'
- echo -ne " Done\n"
-}
-
-
-if test $die = "yes"; then
- echo "You have to edit and configure this script first."
- exit
-fi
-
-
-if test $geoip_database = "country"; then
- echo "Downloading..."
- download "$geoip_country_source" "Country Database:"
- echo "Unpacking..."
- unzip -jo GeoIPCountryCSV.zip
- rm GeoIPCountryCSV.zip
- echo "Converting to UTF-8..."
- iconv -f ISO-8859-1 -t UTF-8 GeoIPCountryWhois.csv -o $prefix"geoip_country.csv"
- rm GeoIPCountryWhois.csv
- echo "Importing..."
- mysqlimport --columns=@x,@x,start,end,countrycode,countryname $PARAMS $prefix"geoip_country.csv"
- rm $prefix"geoip_country.csv" $prefix"geoip_country6.csv"
- echo "Done..."
-elif test $geoip_database = "city"; then
- echo "Downloading..."
- download "$geoip_city_source" "City Database:"
- download "$geoip_region_source" "Region Database:"
- echo "Unpacking..."
- tar -xf GeoLiteCity-latest.tar.xz --strip-components 1
- rm GeoLiteCity-latest.tar.xz
- echo "Converting to utf-8..."
- iconv -f ISO-8859-1 -t UTF-8 GeoLiteCity-Blocks.csv -o $prefix"geoip_city_blocks.csv"
- iconv -f ISO-8859-1 -t UTF-8 GeoLiteCity-Location.csv -o $prefix"geoip_city_location.csv"
- iconv -f ISO-8859-1 -t UTF-8 region_codes.csv -o $prefix"geoip_city_region.csv"
- rm GeoLiteCity-Blocks.csv GeoLiteCity-Location.csv region_codes.csv
- echo "Importing..."
- mysqlimport --columns=start,end,locID --ignore-lines=2 $PARAMS $prefix"geoip_city_blocks.csv"
- mysqlimport --columns=locID,country,region,city,@x,latitude,longitude,@x,areaCode --ignore-lines=2 $PARAMS $prefix"geoip_city_location.csv"
- mysqlimport --columns=country,region,regionname $PARAMS $prefix"geoip_city_region.csv"
- rm $prefix"geoip_city_blocks.csv" $prefix"geoip_city_location.csv" $prefix"geoip_city_region.csv"
- echo "Done..."
-fi