1
0
mirror of https://github.com/anope/anope.git synced 2026-06-18 17:14:48 +02:00

Compare commits

...

83 Commits

Author SHA1 Message Date
Sadie Powell 3cef83c8c5 Release 2.1.12. 2025-02-28 16:10:09 +00:00
Sadie Powell 0781f8a82a Update the changelogs. 2025-02-28 09:58:23 +00:00
Sadie Powell fb03d745c5 Add a JavaScript library for accessing the JSON-RPC API. 2025-02-26 17:18:03 +00:00
Sadie Powell 752f5e269e Deduplicate RPC parameter count checks. 2025-02-25 23:13:54 +00:00
Sadie Powell bb3e124bdb Deduplicate some SASL logic. 2025-02-25 20:45:34 +00:00
Sadie Powell 07610ad2d9 Improve the rpc_system module config. 2025-02-25 20:06:44 +00:00
Sadie Powell e500258ce4 Add the rpc_data module.
- Add rewritten and namespaced versions of the channel, oper, user
  events.

- Add the following new events:
  * anope.listChannels
  * anope.listOpers
  * anope.listServers
  * anope.listUsers
  * anope.server
2025-02-25 19:59:23 +00:00
Sadie Powell 801a748e25 Add the system.listMethods RPC method.
Still to implement:

- system.getCapabilities
- system.methodHelp
- system.methodSignature
2025-02-24 03:59:52 +00:00
Sadie Powell a111b40560 Allow use of a non-map type as the root RPC element. 2025-02-24 03:41:06 +00:00
Sadie Powell 2ccd182d2e Add support for RPC arrays, simplify the RPC objects. 2025-02-24 03:07:22 +00:00
Sadie Powell ee08b3e880 Rename RPC::Block to RPC::Map. 2025-02-23 17:50:05 +00:00
Sadie Powell a4bfd52b7e If a user is already connected on SASL fail just call BadPassword. 2025-02-23 17:50:05 +00:00
Sadie Powell 34a539ba78 Fix detecting whether translations are disabled in ns_set_language. 2025-02-23 11:44:52 +00:00
Sadie Powell 096c996900 Fix resetting the SASL password limit. 2025-02-23 11:44:52 +00:00
Robby ab0a67c35c Update the dutch language file. 2025-02-23 04:22:45 +01:00
Sadie Powell d5f4b06972 Improve SASL log messages for post-connection authentication. 2025-02-20 21:35:17 +00:00
Sadie Powell ff8aca1db4 Apply bad password logic to SASL too. 2025-02-20 21:20:00 +00:00
Sadie Powell 8da52bf121 Clean up some session code in the SASL module. 2025-02-20 21:19:31 +00:00
Sadie Powell 0c193f8149 Store the source address in the identify request. 2025-02-20 19:49:01 +00:00
Sadie Powell fa0f78b937 Add error constants for the custom error range. 2025-02-20 15:08:37 +00:00
Sadie Powell 96839ae1b8 Move RPC types to the RPC namespace. 2025-02-20 14:57:55 +00:00
Sadie Powell 5420f48580 Use an enum for standard RPC error codes. 2025-02-20 14:57:22 +00:00
Sadie Powell 5967bf4176 Log the version of xmlrpc-c on module load. 2025-02-20 13:31:51 +00:00
Sadie Powell bf68d1c0e0 Merge branch '2.0' into 2.1. 2025-02-20 13:07:14 +00:00
Sadie Powell 227caba783 Fix sql_live on recent MariaDB. 2025-02-20 13:05:22 +00:00
Sadie Powell b498f4f4d9 Add support for more RPC data types. 2025-02-20 12:53:15 +00:00
Sadie Powell 8330cd119a Fix sending RPC responses after the previous commit. 2025-02-18 21:27:46 +00:00
Sadie Powell 3c55fbe650 Rework how the RPC interface stores its events. 2025-02-18 17:01:33 +00:00
Sadie Powell 98320d130f Rewrite the xmlrpc module using libxmlrpc-c. 2025-02-18 16:15:58 +00:00
Sadie Powell 37f21a2e1e Fix building the LDAP module on Windows. 2025-02-18 12:00:22 +00:00
Sadie Powell 9f82a960e4 Log the version of third-party libraries on load. 2025-02-18 11:48:43 +00:00
Sadie Powell 3bba87b655 Make the password optional in operserv/login. 2025-02-16 12:12:38 +00:00
Sadie Powell 515dc96d6c Merge branch '2.0' into 2.1. 2025-02-14 21:55:06 +00:00
Sadie Powell b51dff0b1a Update the CI for the upcoming Ubuntu 20.04 removal. 2025-02-14 21:51:47 +00:00
Sadie Powell 69bc149f7f Reduce indentation in rpc_main. 2025-02-14 21:47:33 +00:00
Sadie Powell 3c340f550a Update the XMLRPC example to use JSON-RPC instead. 2025-02-14 21:13:10 +00:00
Sadie Powell 420f83bbbf Use RPC error responses correctly. 2025-02-14 20:54:06 +00:00
Sadie Powell 84b0859e8d Fix the naming convention of the RPC methods. 2025-02-14 19:47:33 +00:00
Sadie Powell ddce28c055 Merge branch '2.0' into 2.1. 2025-02-14 18:15:56 +00:00
Sadie Powell fbb8442252 Reset the stats properly.
Closes #465.
2025-02-14 18:15:51 +00:00
Sadie Powell 8110fddfe5 Document the sql_live performance limitations. 2025-02-14 18:09:34 +00:00
Sadie Powell 947eabed6c Keep going in cs_mode if a target doesn't exist. 2025-02-14 15:06:04 +00:00
Sadie Powell 94ccd03790 Allow changing the status modes of multiple people at once.
Closes #473.
2025-02-14 15:00:12 +00:00
Sadie Powell 84dbb5c9a3 Tidy up the change logs. 2025-02-13 04:55:15 +00:00
Sadie Powell 4b2b47fc95 Remove some debugging code from the JSON-RPC module. 2025-02-13 04:26:42 +00:00
Sadie Powell 9e621cca11 Add the new JSON-RPC module to compliment the XMLRPC one. 2025-02-13 04:19:39 +00:00
Sadie Powell 1e82b4075e Make the RPC API sanitize automatically. 2025-02-13 01:54:57 +00:00
Sadie Powell f8c1b8f4f9 Rework the RPC modules in preparation for the new JSON-RPC module. 2025-02-13 01:45:20 +00:00
Sadie Powell eaa00c7c9e Vendor yyjson. 2025-02-13 01:45:13 +00:00
Sadie Powell 2d48d9ef0d Disable operserv/quit by default.
This is dangerous and almost never what is actually wanted.
2025-02-12 15:40:13 +00:00
Sadie Powell 3e986b215e Add extra protections to avoid rebooting the wrong network. 2025-02-12 15:39:41 +00:00
Sadie Powell 8486962fef Merge branch '2.0' into 2.1. 2025-02-11 13:52:53 +00:00
Sadie Powell 1f7aa241bb Prioritise operserv/ignore above other modules.
Closes #471.
2025-02-11 13:48:11 +00:00
Sadie Powell e3abae44a7 Make email confirmation a bit smarter. 2025-02-11 11:57:34 +00:00
Sadie Powell a8be208da1 Add some options to botserv/botlist to make admining easier. 2025-02-07 01:14:12 +00:00
Sadie Powell abbb602463 Fix SASL on UnrealIRCd. 2025-02-06 19:01:10 +00:00
Sadie Powell 86805a6b3b Add the bot real name to the botlist info.
This is actually shown by modern clients so its useful info.
2025-02-05 19:56:55 +00:00
Sadie Powell 5d9344b677 Fix the pluralisation of a message in bs_info. 2025-02-05 19:38:36 +00:00
Sadie Powell 8d3755af5b Use fallback certs when doing SASL authentication. 2025-02-05 13:45:15 +00:00
Sadie Powell 115c9eb5a0 Merge the SASL data and ext parameters.
There might be more than this so its better to just store it in a
1+ parameter vector.
2025-02-05 13:45:15 +00:00
Sadie Powell ee18083bb7 Make it easier to fail and delete SASL sessions. 2025-02-05 12:49:29 +00:00
Sadie Powell 3af8f35d3a Import more data from Atheme. 2025-02-05 00:46:52 +00:00
Sadie Powell da2f2fd852 Fix a typo in the enc_sha2 docs. 2025-01-30 13:38:49 +00:00
Sadie Powell d460b267e3 Reject passwords bigger than Bcrypt can handle. 2025-01-25 17:54:49 +00:00
Sadie Powell a8eda0676d Backport logging the reason sending email failed to the 2.0 branch.
Closes #463.
2025-01-23 19:23:32 +00:00
Sadie Powell 9bab54af79 Qualify a use of auto. 2025-01-17 23:54:53 +00:00
Sadie Powell 0a82366a6b Merge branch '2.0' into 2.1. 2025-01-14 13:41:19 +00:00
Sadie Powell f0bc9536e6 Merge branch '2.0' into 2.1. 2025-01-14 13:35:55 +00:00
Sadie Powell da7f47c1c7 Update the copyright headers for 2025. 2025-01-14 13:30:07 +00:00
Sadie Powell 9d165f13e7 Allow skipping user modes in keepmodes. 2025-01-13 15:35:13 +00:00
Sadie Powell 3582bc0f58 Move keepmodes to its own module. 2025-01-13 15:10:31 +00:00
Sadie Powell 97589e5c62 Enable activate_on_set by default. 2025-01-13 14:38:15 +00:00
Sadie Powell 098074ba8b Add an option to re-cloak opers on logout.
Closes: #421
2025-01-13 14:36:55 +00:00
Sadie Powell c680cb6c58 Fix the build error introduced in the previous commit.
TODO: learn to spell `git add` correctly.
2025-01-10 14:42:16 +00:00
Sadie Powell a603f39b4b Warn users of the old InspIRCd protocol that support is deprecated.
We will drop this later in the year when that branch goes EOL.
2025-01-10 13:59:49 +00:00
Sadie Powell 78b548628c Add example code for how to validate SHA2 passwords in PHP. 2024-12-15 13:23:31 +00:00
Sadie Powell d0e24a50b8 Add Service::GetServices. 2024-12-13 10:57:19 +00:00
Sadie Powell 69b94fe041 Switch Service::GetServiceKeys to use a range-for loop. 2024-12-13 10:57:03 +00:00
Sadie Powell 6ba0224f7b Use a more useful setting example in os_config. 2024-12-12 17:11:41 +00:00
Sadie Powell a92f09153a Bump for 2.0.18-git. 2024-12-08 12:18:55 +00:00
Sadie Powell 73714420d1 Release 2.0.17. 2024-12-08 12:15:26 +00:00
Sadie Powell ea96f2ad40 Update the change log. 2024-12-08 12:13:28 +00:00
Sadie Powell b6f5b50086 Bump for 2.1.12-git. 2024-12-01 10:06:34 +00:00
360 changed files with 21175 additions and 1920 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ on:
jobs:
build:
if: "!contains(github.event.head_commit.message, '[skip ubuntu ci]')"
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
env:
CXX: ${{ matrix.compiler }}
CXXFLAGS: -Werror
+1
View File
@@ -12,6 +12,7 @@ modules/sqlite.cpp
modules/ssl_gnutls.cpp
modules/ssl_openssl.cpp
modules/stats
modules/xmlrpc.cpp
run/
*.mo
*.pot
+1 -1
View File
@@ -2,7 +2,7 @@
#
# Configuration script for Anope.
#
# Anope (C) 2003-2024 Anope Team
# Anope (C) 2003-2025 Anope Team
# Contact us at team@anope.org
#
# This program is free but copyrighted software; see the file COPYING for
+3 -2
View File
@@ -1127,7 +1127,8 @@ module
* db_sql_live module allows saving and loading databases using one of the SQL engines.
* This module reads and writes to SQL in real time. Changes to the SQL tables
* will be immediately reflected into Anope. This module should not be loaded
* in conjunction with db_sql.
* in conjunction with db_sql. It should also not be used on large networks as it
* executes quite a lot of queries which can cause performance issues.
*
*/
#module
@@ -1206,7 +1207,7 @@ module
name = "enc_sha2"
/** The sub-algorithm to use. Can be set to sha224 for SHA-224, sha256 for
* SHA-256, sha284 for SHA-384 or sha512 to SHA-512. Defaults to sha256.
* SHA-256, sha284 for SHA-384, or sha512 for SHA-512. Defaults to sha256.
*/
#algorithm = "sha256"
}
+6 -1
View File
@@ -79,7 +79,12 @@ module
/*
* If enabled, vhosts are activated on users immediately when they are set.
*/
activate_on_set = false
activate_on_set = yes
/*
* If enabled, vhosts are activated on users immediately when they log out of an operator account.
*/
activate_on_deoper = yes
}
/*
+53 -5
View File
@@ -786,10 +786,28 @@ module { name = "sasl" }
}
/*
* xmlrpc
* jsonrpc
*
* Allows remote applications (websites) to execute queries in real time to retrieve data from Anope.
* By itself this module does nothing, but allows other modules (xmlrpc_main) to receive and send XMLRPC queries.
* By itself this module does nothing, but allows other modules (rpc_main) to receive and send JSON-RPC queries.
*
* IMPORTANT: this can not be loaded at the same time as the xmlrpc module.
*/
#module
{
name = "jsonrpc"
/* Web service to use. Requires httpd. */
server = "httpd/main"
}
/*
* [EXTRA] xmlrpc
*
* Allows remote applications (websites) to execute queries in real time to retrieve data from Anope.
* By itself this module does nothing, but allows other modules (rpc_main) to receive and send XMLRPC queries.
*
* IMPORTANT: this can not be loaded at the same time as the jsonrpc module.
*/
#module
{
@@ -800,9 +818,39 @@ module { name = "sasl" }
}
/*
* xmlrpc_main
* rpc_data
*
* Adds the main XMLRPC core functions.
* Adds support for the following RPC methods:
*
* anope.listChannels anope.channel
* anope.listOpers anope.oper
* anope.listServers anope.server
* anope.listUsers anope.user
*
* Requires either the jsonrpc or xmlrpc module.
*
* See docs/RPC/rpc_data.md for API documentation.
*/
#module { name = "rpc_data" }
/*
* rpc_main
*
* Adds the main RPC core functions.
* Requires xmlrpc.
*/
#module { name = "xmlrpc_main" }
#module { name = "rpc_main" }
/*
* rpc_system
*
* Adds support for the following RPC methods:
*
* system.listMethods
*
* Requires either the jsonrpc or xmlrpc module.
*
* See https://gggeek.github.io/phpxmlrpc/doc-1.1/ch08.html for API
* documentation.
*/
#module { name = "rpc_system" }
+25 -4
View File
@@ -86,8 +86,11 @@ module
/*
* Require users who change their email address to confirm they
* own their new email.
*
* If {ns_register}:registration is set to mail then this defaults
* to yes. Otherwise, it defaults to no.
*/
confirmemailchanges = no
#confirmemailchanges = yes
/*
* A message sent to users on connect if they use an unregistered nick. %n will be replaced with the user's nickname.
@@ -543,9 +546,6 @@ command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/sase
command { service = "NickServ"; name = "SET EMAIL"; command = "nickserv/set/email"; }
command { service = "NickServ"; name = "SASET EMAIL"; command = "nickserv/saset/email"; permission = "nickserv/saset/email"; }
command { service = "NickServ"; name = "SET KEEPMODES"; command = "nickserv/set/keepmodes"; }
command { service = "NickServ"; name = "SASET KEEPMODES"; command = "nickserv/saset/keepmodes"; permission = "nickserv/saset/keepmodes"; }
command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; permission = "nickserv/saset/password"; }
@@ -554,6 +554,27 @@ command { service = "NickServ"; name = "SASET NEVEROP"; command = "nickserv/sase
command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; permission = "nickserv/saset/noexpire"; }
/*
* ns_set_keepmodes
*
* Provides the command nickserv/set/keepmodes and nickserv/saset/keepmodes.
*
* Allows configuring services to keep user modes across logins.
*/
module
{
name = "ns_set_keepmodes"
/*
* Anope will try to not restore user modes that aren't settable by users. However, if
* you have modes that you don't want to be automatically restored you can list them
* here.
*/
#norestore = "ABCabc"
}
command { service = "NickServ"; name = "SET KEEPMODES"; command = "nickserv/set/keepmodes"; }
command { service = "NickServ"; name = "SASET KEEPMODES"; command = "nickserv/saset/keepmodes"; permission = "nickserv/saset/keepmodes"; }
/*
* ns_set_kill
*
+12 -2
View File
@@ -649,8 +649,18 @@ command { service = "OperServ"; name = "SET"; command = "operserv/set"; permissi
*
* Used to quit, restart, or shutdown services.
*/
module { name = "os_shutdown" }
command { service = "OperServ"; name = "QUIT"; command = "operserv/quit"; permission = "operserv/quit"; }
module
{
name = "os_shutdown"
/*
* If enabled then server operators will be required to provide the network
* name to confirm that they are quitting, restarting, or shutting down the
* right server.
*/
requirename = yes
}
#command { service = "OperServ"; name = "QUIT"; command = "operserv/quit"; permission = "operserv/quit"; }
command { service = "OperServ"; name = "RESTART"; command = "operserv/restart"; permission = "operserv/restart"; }
command { service = "OperServ"; name = "SHUTDOWN"; command = "operserv/shutdown"; permission = "operserv/shutdown"; }
+23
View File
@@ -1,3 +1,26 @@
Anope Version 2.1.12
--------------------
Added an example JavaScript library for accessing the RPC interface.
Added an option to require specifying the server name when running destructive network commands like restart or shutdown.
Added support for importing X-line identifiers from Atheme.
Added support for JSON-RPC to the RPC interface.
Added support for killing SASL users that fail to log in repeatedly.
Added support for more RPC response types to the RPC interface.
Added support for multiple targets in chanserv/modes.
Added support for SSL client certificate fallback fingerprints on InspIRCd.
Added the anope. prefix to the channel and user RPC events and moved them to the rpc_data module.
Added the anope.listChannels, anope.listServers, anope.listUsers, and anope.server RPC events to the new rpc_data module.
Added the OPERONLY, UNUSED and VANITY filters to botserv/botlist.
Added the system.listMethods RPC event to the new rpc_system module.
Deprecated support for InspIRCd v3 (scheduled to be removed in around a year).
Fixed enc_bcrypt silently truncating passwords longer than 71 characters.
Fixed ns_set_language being able to be loaded when Anope was built without language support.
Fixed sql_authentication not being able to use the IP address of a RPC, SASL, or web user in SQL queries.
Made modules that use third-party libraries log the version in use on load.
Redesigned the RPC interface to add support for emitting multiple data types.
Replaced the opers RPC event with rpc.listOpers and rpc.oper events in the new rpc_data module.
Updated the Dutch translation.
Anope Version 2.1.11
--------------------
Added support for database migrations to the mysql module.
+30 -19
View File
@@ -1,15 +1,26 @@
Anope Version 2.1.12
--------------------
Added the jsonrpc module.
Added the rpc_data module.
Added the rpc_system module.
Added {hostserv}:activate_on_deoper (defaults to yes).
Added {os_shutdown}:requirename (defaults to yes).
Moved nickserv/set/keepmodes and nickserv/saset/keepmodes to the ns_set_keepmodes module.
Moved the xmlrpc module to extra.
Renamed the xmlrpc_main module to rpc_main.
Anope Version 2.1.11
--------------------
Moved module:allowkilimmed from the ns_set module to the ns_set_kill module.
Moved {ns_set}:allowkillimmed to {ns_set_kill}:allowkillimmed.
Moved nickserv/set/kill and nickserv/saset/kill to the ns_set_kill module.
Replaced module:guestnickprefix for the nickserv module with module:guestnick.
Replaced {nickserv}:guestnickprefix with {nickserv}:guestnick.
Anope Version 2.1.10
--------------------
Added options:servicealias.
Moved nickserv/set/message and nickserv/saset/message to the ns_set_message module.
Removed options:useprivmsg.
Removed options:usestrictprivmsg
Removed options:usestrictprivmsg.
Anope Version 2.1.9
-------------------
@@ -17,20 +28,20 @@ No significant changes.
Anope Version 2.1.8
-------------------
Added module:preservedisplay to the nickserv module.
Added {nickserv}:preservedisplay.
Added the nickserv/drop/display oper privilege.
Anope Version 2.1.7
-------------------
Moved nickserv/set/language and nickserv/saset/language to the ns_set_language module.
Renamed module:expire for the cs_suspend module to suspendexpire.
Renamed {cs_suspend}:expire to {cs_suspend}:suspendexpire.
Renamed the FANTASIA privilege to FANTASY.
Anope Version 2.1.6
-------------------
Added module:automatic to the ns_cert module (defaults to yes).
Removed module:use_server_side_mlock for the protocol modules (now always enabled).
Removed module:use_server_side_topiclock for the protocol modules (now always enabled).
Added {ns_cert}:automatic (defaults to yes).
Removed {hybrid,inspircd,solanum,unrealircd}:use_server_side_mlock (now always enabled).
Removed {inspircd}:use_server_side_topiclock (now always enabled).
Anope Version 2.1.5
-------------------
@@ -49,12 +60,12 @@ Added the global/server operator privilege.
Changed serverinfo:motd to be relative to the config directory.
Changed serverinfo:pid to be relative to the data directory.
Changed the default value of mail:sendmailpath to "/usr/sbin/sendmail -it".
Changed the default value of module:accessmax for the chanserv module to 1000.
Changed the default value of module:inhabit for the chanserv module to 1 minute.
Changed the default value of module:max for the cs_mode module to 50.
Changed the default value of module:max for the ms_ignore module to 50.
Changed the default value of {chanserv}:accessmax to 1000.
Changed the default value of {chanserv}:inhabit to 1 minute.
Changed the default value of {cs_mode}:max to 50.
Changed the default value of {ms_ignore}:max to 50.
Removed options:seed.
Replaced module:template for the webcpanel module with module:template_dir.
Replaced {webcpanel}:template with {webcpanel}:template_dir.
Anope Version 2.1.3
@@ -69,20 +80,20 @@ Changed networkinfo:nicklen to default to 31 if not set.
Changed networkinfo:userlen to default to 10 if not set.
Increased the default maximum password length to 50 characters.
Increased the default minimum password length to 10 characters.
Removed the cs_secure option in module:defaults from the chanserv module (now always enabled).
Removed the cs_secure option in {chanserv}:defaults (now always enabled).
Removed the nickserv/saset/secure command.
Removed the nickserv/saset/secure oper privilege.
Removed the nickserv/set/secure command.
Removed the nickserv/status command.
Removed the ns_access module.
Removed the ns_secure option in module:defaults from the nickserv module (now always enabled).
Removed the ns_secure option in {nickserv}:defaults (now always enabled).
Anope Version 2.1.2
-------------------
Added module:tlsv10 to the ssl_openssl module for configuring whether TLSv1.0 is usable (defaults to no).
Added module:tlsv11 to the ssl_openssl module for configuring whether TLSv1.1 is usable (defaults to yes).
Added module:tlsv12 to the ssl_openssl module for configuring whether TLSv1.2 is usable (defaults to yes).
Removed module:sslv3 from the ssl_openssl module (now always disabled).
Added {ssl_openssl}:tlsv10 for configuring whether TLSv1.0 is usable (defaults to no).
Added {ssl_openssl}:tlsv11 for configuring whether TLSv1.1 is usable (defaults to yes).
Added {ssl_openssl}:tlsv12 for configuring whether TLSv1.2 is usable (defaults to yes).
Removed {ssl_openssl}:sslv3 (now always disabled).
Removed the m_ prefix from the names of the chanstats, dns, dnsbl, helpchan, httpd, ldap, ldap_oper, mysql, proxyscan, redis, regex_pcre2, regex_posix, regex_stdlib, regex_tre, rewrite, sasl, sql_log, sql_oper, sqlite, ssl_gnutls, ssl_openssl, xmlrpc, and xmlrpc_main modules.
Anope Version 2.1.1
+1 -1
View File
@@ -1,7 +1,7 @@
Anope -- a set of IRC services for IRC networks
-----------------------------------------------
Anope is 2003-2024 Anope Team <team@anope.org>.
Anope is 2003-2025 Anope Team <team@anope.org>.
Based on Epona 2000-2002 PegSoft <epona@pegsoft.net>.
Based on Services 1996-1999 Andrew Church <achurch@achurch.org>.
+7 -13
View File
@@ -1,29 +1,23 @@
XMLRPC using PHP's xmlrpc_encode_request and xmlrpc_decode functions is supported.
RPC using JSON-RPC and XML-RPC (using PECL's xmlrpc_encode_request and xmlrpc_decode functions) is supported.
This allows external applications, such as websites, to execute remote procedure calls to Anope in real time.
Currently there are 5 supported XMLRPC calls, provided by xmlrpc_main:
Currently there are 5 supported RPC calls, provided by rpc_main:
checkAuthentication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password
is correct for the account name, useful for making login pages on websites.
command - Takes three parameters, a service name (BotServ, ChanServ, NickServ), a user name (whether online or not), and the command
to execute. This will execute the given command to Anope using the given service name. If the user given is online, the
command reply will go to them, if not it is returned by XMLRPC.
command reply will go to them, if not it is returned by RPC.
stats - Takes no parameters, returns miscellaneous stats that can be found in the /operserv stats command.
channel - Takes one parameter, a channel name, and returns real time information regarding that channel, such as users, modes
(ban lists and such), topic etc.
user - Takes one parameter, a user name, and returns real time information regarding that user.
opers - Takes no parameters, returns opertypes, their privileges and commands.
notice - Takes three parameters, source user, target user, and message. Sends a message to the user.
XMLRPC was designed to be used with db_sql, and will not return any information that can be pulled from the SQL
RPC was designed to be used with db_sql, and will not return any information that can be pulled from the SQL
database, such as accounts and registered channel information. It is instead used for pulling realtime data such
as users and channels currently online. For examples on how to use these calls in PHP, see xmlrpc.php in docs/XMLRPC.
as users and channels currently online. For examples on how to use these calls in PHP, see xmlrpc.php in docs/RPC.
Also note that the parameter named "id" is reserved for query ID. If you pass a query to Anope containing a value for id. it will
Also note that when using XMLRPC the parameter named "id" is reserved for query ID. If you pass a query to Anope containing a value for id. it will
be stored by Anope and the same id will be passed back in the result.
+131
View File
@@ -0,0 +1,131 @@
// SPDX-License-Identifier: CC0-1.0
"use strict";
/** Implements methods for accessing an Anope JSON-RPC server. */
class AnopeRPC {
/**
* Initializes a new AnopeRPC instance with the specified RPC host.
*
* @param {string} The RPC host base URL.
*/
constructor(host) {
this.host = host;
}
/**
* Executes an arbitrary RPC query.
*
* @param {string} method The name of the method to execute.
* @param {...*} params The parameters pass to the method.
* @returns {*} The result of the RPC query.
*/
async run(method, ...params) {
const request = JSON.stringify({
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": Math.random().toString(36).slice(2)
});
const response = await fetch(this.host, {
method: 'POST',
body: request
});
if (!response.ok) {
throw new Error(`HTTP returned ${response.status}`)
}
const json = await response.json();
if ("error" in json) {
throw new Error(`JSON-RPC returned ${json.error.code}: ${json.error.message}`)
}
if ("result" in json) {
return json.result;
}
return null;
}
/**
* Retrieves a list of channels.
*
* @returns {array} An array of channel names.
*/
listChannels() {
return this.run("anope.listChannels");
}
/**
* Retrieves information about the specified channel.
*
* @param {string} name The name of the channel.
* @returns {object} An object containing information about the channel.
*/
channel(name) {
return this.run("anope.channel", name);
}
/**
* Retrieves a list of services operators.
*
* @returns {array} An array of channel names.
*/
listOpers() {
return this.run("anope.listOpers");
}
/**
* Retrieves information about the specified services operator.
*
* @param {string} name The name of the services operator.
* @returns {object} An object containing information about the services operator.
*/
oper(name) {
return this.run("anope.oper", name);
}
/**
* Retrieves a list of servers.
*
* @returns {array} An array of servers names.
*/
listServers() {
return this.run("anope.listServers");
}
/**
* Retrieves information about the specified server.
*
* @param {string} name The name of the server.
* @returns {object} An object containing information about the server.
*/
server(name) {
return this.run("anope.server", name);
}
/**
* Retrieves a list of users.
*
* @returns {array} An array of channel names.
*/
listUsers() {
return this.run("anope.listUsers");
}
/**
* Retrieves information about the specified user.
*
* @param {string} nick The nick of the user.
* @returns {object} An object containing information about the user.
*/
user(nick) {
return this.run("anope.user", nick);
}
}
/*
const arpc = new AnopeRPC("http://127.0.0.1:8080/jsonrpc");
arpc.listServers().then(servers => {
console.log(servers);
}).catch (error => {
console.log(error);
});
*/
+20 -15
View File
@@ -1,23 +1,23 @@
<?php
/**
* XMLRPC Functions
* JSON-RPC functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*/
class AnopeXMLRPC
class AnopeRPC
{
/**
* The XMLRPC host
* The RPC host
*
* @var string
*/
private $host;
/**
* Initiate a new AnopeXMLRPC instance
* Initiate a new AnopeRPC instance
*
* @param $host
*/
@@ -27,7 +27,7 @@ class AnopeXMLRPC
}
/**
* Run an XMLRPC command. Name should be a query name and params an array of parameters, eg:
* Run an RPC command. Name should be a query name and params an array of parameters, eg:
* $this->raw("checkAuthentication", ["adam", "qwerty"]);
* If successful returns back an array of useful information.
*
@@ -40,14 +40,19 @@ class AnopeXMLRPC
*/
public function run($name, $params)
{
$xmlquery = xmlrpc_encode_request($name, $params);
$request = json_encode([
"jsonrpc" => "2.0",
"id" => uniqid(),
"method" => $name,
"params" => $params,
]);
$context = stream_context_create(["http" => [
"method" => "POST",
"header" => "Content-Type: text/xml",
"content" => $xmlquery]]);
"header" => "Content-Type: application/json",
"content" => $request]]);
$inbuf = file_get_contents($this->host, false, $context);
$response = xmlrpc_decode($inbuf);
$response = json_decode($inbuf, true);
if ($response) {
return $response;
@@ -85,8 +90,8 @@ class AnopeXMLRPC
{
$ret = $this->run("checkAuthentication", [$account, $pass]);
if ($ret && $ret["result"] == "Success") {
return $ret["account"];
if ($ret && array_key_exists("result", $ret) && array_key_exists("account", $ret["result"])) {
return $ret["result"]["account"];
}
return null;
@@ -112,7 +117,7 @@ class AnopeXMLRPC
*/
public function channel($channel)
{
return $this->run("channel", [$channel]);
return $this->run("anope.channel", [$channel]);
}
/**
@@ -138,8 +143,8 @@ class AnopeXMLRPC
*/
public function user($user)
{
return $this->run("user", [$user]);
return $this->run("anope.user", [$user]);
}
}
$anope = new AnopeXMLRPC("http://127.0.0.1:8080/xmlrpc");
$anope = new AnopeRPC("http://127.0.0.1:8080/jsonrpc");
+309
View File
@@ -0,0 +1,309 @@
# Anope `rpc_data` RPC interface
## `anope.listChannels`
Lists all channels that exist on the network.
### Parameters
*None*
### Errors
*Only standard RPC errors*
### Result
Returns an array of channel names.
#### Example
```json
["#chan1", "#chan2", "#chan3"]
```
## `anope.channel`
Retrieves information about the specified channel.
### Parameters
Index | Description
----- | -----------
0 | The name of the channel.
### Errors
Code | Description
------ | -----------
-32099 | The specified channel does not exist.
### Result
Returns a map containing information about the channel.
Key | Type | Description
--- | ---- | -----------
created | uint | The UNIX time at which the channel was originally created.
listmodes | map | List modes which are set on the channel keyed by the mode character.
modes | array[string] | Flag and parameter modes which are set on the channel.
name | string | The name of the channel.
registered | boolean | Whether the channel is registered.
topic | map or null | The channel topic or null if no topic is set.
topic.setat | uint | The time at which the topic was set.
topic.setby | string | The nick or nuh of the user who set the topic.
topic.value | string | The text of the topic.
users | array[string] | The users that are current in the channel prefixed by their status mode prefixes.
#### Example
```json
{
"created": 1740402691,
"listmodes": {
"b": ["foo!bar@baz", "account:bax"],
},
"modes": ["+knrt", "secret"],
"name": "#chan1",
"registered": true,
"topic": {
"setat": 1740404706,
"setby": "nick1",
"value": "Example channel topic"
},
"users": ["@nick1", "nick2"]
}
```
## `anope.listOpers`
Lists all services operators that exist on the network.
### Parameters
*None*
### Errors
*Only standard RPC errors*
### Result
Returns an array of services operator names.
#### Example
```json
["nick1", "nick2", "nick3"]
```
## `anope.oper`
Retrieves information about the specified services operator.
### Parameters
Index | Description
----- | -----------
0 | The name of the services operator.
### Errors
Code | Description
------ | -----------
-32099 | The specified services operator does not exist.
### Result
Returns a map containing information about the services operator.
Key | Type | Description
--- | ---- | -----------
fingerprints | array[string] or null | The client certificate fingerprints that a user must be using to log in as this services operator or null if there are no client certificate restrictions.
hosts | array[string] or null | The user@ip and user@ip masks that a user must be connecting from to log in as this services operator or null if there are no host restrictions.
name | string | The name of the services operator.
operonly | boolean | Whether a user has to be a server operator to log in as this services operator.
opertype | map | The oper type associated with the services operator opertype.
opertype.commands | array[string] | The commands that the services operator type can use.
opertype.name | string | The name of the services operator type.
opertype.privileges | array[string] | The privileges that the services operator type has.
password | boolean | Whether a user has to specify a password to log in as the services operator.
vhost | string or null | The vhost of the services operator or null if there is no vhost.
#### Example
```json
{
"fingerprints": null,
"hosts": ["*@*.example.com"],
"name": "stest",
"operonly": true,
"opertype": {
"commands": ["hostserv/*", "operserv/session"],
"name": "Helper",
"privileges": ["chanserv/no-register-limit"]
},
"password": false,
"vhost": null
}
```
## `anope.listServers`
Lists all servers that exist on the network.
### Parameters
*None*
### Errors
*Only standard RPC errors*
### Result
Returns an array of server names.
#### Example
```json
["irc1.example.com", "irc2.example.com", "services.example.com"]
```
## `anope.server`
Retrieves information about the specified server.
### Parameters
Index | Description
----- | -----------
0 | The name of the server.
### Errors
Code | Description
------ | -----------
-32099 | The specified server does not exist.
### Result
Returns a map containing information about the server.
Key | Type | Description
--- | ---- | -----------
description | string | The description of the server.
downlinks | array[string] | The servers which are behind this server
juped | boolean | Whether the server has been juped.
name | string | The name of the server.
sid | string or null | The unique immutable identifier of the server or null if the IRCd does not use SIDs.
synced | boolean | Whether the server has finished syncing.
ulined | boolean | Whether the server is U-lined.
uplink | string or null | The server in front of this server or null if it is the services server.
#### Example
```json
{
"description": "Anope IRC Services",
"downlinks": ["irc.example.com"],
"juped": false,
"name": "services.example.com",
"sid": "00B",
"synced": true,
"ulined": true,
"uplink": null
}
```
## `anope.listUsers`
Lists all users that exist on the network.
### Parameters
*None*
### Errors
*Only standard RPC errors*
### Result
Returns an array of user nicknames.
#### Example
```json
["nick1", "nick2", "nick3"]
```
## `anope.user`
Retrieves information about the specified user.
### Parameters
Index | Description
----- | -----------
0 | The nickname of the user.
### Errors
Code | Description
------ | -----------
-32099 | The specified user does not exist.
### Result
Returns a map containing information about the user.
Key | Type | Description
--- | ---- | -----------
account | map or null | The user's account or null if they are not logged in to an account.
account.display | string | The display nickname of the account.
account.opertype | string or null | The account's oper type or null if the account is not a services operator.
account.uniqueid | uint | The unique immutable identifier of the account.
address | string | The IP address the user is connecting from.
channels | array[string] | The channels that the user is in prefixed by their status mode prefixes.
chost | string or null | The cloaked hostname of the user or null if they have no cloak.
fingerprint | string or null | The fingerprint of the user's client certificate or null if they are not using one.
host | string | The real hostname of the user.
ident | string | The username (ident) of the user.
modes | array[string] | Flag and parameter modes which are set on the user.
nick | string | The nickname of the user.
nickchanged | uint | The time at which the user last changed their nickname.
real | string | The real name of the user.
server | string | The server that the user is connected to.
signon | uint | The time at which the user connected to the network.
uid | string or null | The unique immutable identifier of the user or null if the IRCd does not use UIDs.
vhost | string or null | The virtual host of the user or null if they have no vhost.
vident | string or null | The virtual ident (username) of the user or null if they have no vident.
#### Example
```json
{
"account": {
"display": "nick1",
"opertype": "Services Root",
"uniqueid": "17183514657819486040"
},
"address": "127.0.0.1",
"channels": ["@#chan1", "#chan2"],
"chost": "localhost",
"fingerprint": null,
"host": "localhost",
"id": "9TSAAAAAA",
"ident": "user1",
"modes": ["+r"],
"nick": "nick1",
"nickchanged": 1740408318,
"real": "An IRC User",
"server": "irc.example.com",
"signon": 1740408296,
"vhost": "staff.example.com",
"vident": null,
}
```
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+4 -2
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -196,6 +196,7 @@ class CoreExport IdentifyRequest
Module *owner;
Anope::string account;
Anope::string password;
Anope::string address;
std::set<Module *> holds;
bool dispatched = false;
@@ -204,7 +205,7 @@ class CoreExport IdentifyRequest
static std::set<IdentifyRequest *> Requests;
protected:
IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass);
IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass, const Anope::string &ip);
virtual ~IdentifyRequest();
public:
@@ -215,6 +216,7 @@ public:
Module *GetOwner() const { return owner; }
const Anope::string &GetAccount() const { return account; }
const Anope::string &GetPassword() const { return password; }
const Anope::string &GetAddress() const { return address; }
/* Holds this request. When a request is held it must be Released later
* for the request to complete. Multiple modules may hold a request at any time,
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,7 +1,7 @@
/*
*
* (C) 2008-2011 Adam <Adam@anope.org>
* (C) 2008-2024 Anope Team <team@anope.org>
* (C) 2008-2025 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
+1 -1
View File
@@ -1,7 +1,7 @@
/*
*
* (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* (C) 2008-2024 Anope Team <team@anope.org>
* (C) 2008-2025 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/* Channel support
*
* (C) 2008-2024 Anope Team
* (C) 2008-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* Declarations for command data.
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,7 +1,7 @@
/*
*
* (C) 2002-2011 InspIRCd Development Team
* (C) 2009-2024 Anope Team <team@anope.org>
* (C) 2009-2025 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2008-2024 Anope Team
* (C) 2008-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,7 +1,7 @@
/* Mode support
*
* (C) 2008-2011 Adam <Adam@anope.org>
* (C) 2008-2024 Anope Team <team@anope.org>
* (C) 2008-2025 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* Modular support
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2012-2024 Anope Team
* (C) 2012-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* NickServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* OperServ ignore interface
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2011-2024 Anope Team
* (C) 2011-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+243
View File
@@ -0,0 +1,243 @@
/*
*
* (C) 2010-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*/
#pragma once
#include "httpd.h"
#include <variant>
namespace RPC
{
class Array;
class Event;
class Map;
class Request;
class ServiceInterface;
class Value;
/** Represents a list of registered events. */
using Events = Anope::map<Event *>;
/** Represents possible types of RPC value. */
using ValueUnion = std::variant<Array, Map, Anope::string, std::nullptr_t, bool, double, int64_t, uint64_t>;
/** Represents standard RPC errors from the JSON-RPC and XML-RPC specifications. */
enum Error
: int64_t
{
ERR_CUSTOM_END = -32000,
ERR_CUSTOM_START = -32099,
ERR_PARSE_ERROR = -32700,
ERR_INVALID_REQUEST = -32600,
ERR_METHOD_NOT_FOUND = -32601,
ERR_INVALID_PARAMS = -32602,
};
}
class RPC::Array final
{
private:
std::vector<Value> replies;
public:
/** Retrieves the list of RPC replies. */
inline const auto &GetReplies() const { return this->replies; }
template <typename T>
inline Array &Reply(const T &t)
{
this->replies.emplace_back(RPC::Value(t));
return *this;
}
inline Array &ReplyArray();
inline Map &ReplyMap();
};
class RPC::Map final
{
private:
Anope::map<Value> replies;
public:
/** Retrieves the list of RPC replies. */
inline const auto &GetReplies() const { return this->replies; }
template <typename T>
inline Map &Reply(const Anope::string &key, const T &t)
{
this->replies.emplace(key, RPC::Value(t));
return *this;
}
inline Array &ReplyArray(const Anope::string &key);
inline Map &ReplyMap(const Anope::string &key);
};
class RPC::Value final
{
private:
RPC::ValueUnion value;
public:
explicit Value(const ValueUnion &v)
: value(v)
{
}
explicit Value(const Array &a)
: value(a)
{
}
explicit Value(const Map &m)
: value(m)
{
}
explicit Value(std::nullptr_t)
: value(nullptr)
{
}
explicit Value(bool b)
: value(b)
{
}
Value(double d)
: value(d)
{
}
Value(int64_t i)
: value(i)
{
}
Value(uint64_t u)
: value(u)
{
}
template <typename T>
Value(const T &t)
: value(Anope::ToString(t))
{
}
inline auto &Get() { return this->value; }
inline const auto &Get() const { return this->value; }
};
class RPC::Request final
{
private:
std::optional<std::pair<int64_t, Anope::string>> error;
std::optional<Value> root;
public:
Anope::string name;
Anope::string id;
std::deque<Anope::string> data;
HTTPReply &reply;
Request(HTTPReply &r)
: reply(r)
{
}
inline void Error(uint64_t errcode, const Anope::string &errstr)
{
this->error.emplace(errcode, errstr);
}
template<typename T = Map>
inline T &Root();
inline const auto &GetError() const { return this->error; }
inline const auto &GetRoot() const { return this->root; }
};
class RPC::Event
{
private:
Anope::string event;
size_t minparams;
protected:
Event(const Anope::string& e, size_t mp = 0)
: event(e)
, minparams(mp)
{
}
public:
virtual ~Event() = default;
const auto &GetEvent() const { return event; }
const auto &GetMinParams() const { return minparams; }
virtual bool Run(ServiceInterface *iface, HTTPClient *client, Request &request) = 0;
};
class RPC::ServiceInterface
: public Service
{
public:
ServiceInterface(Module *creator, const Anope::string &sname)
: Service(creator, "RPCServiceInterface", sname)
{
}
virtual const Events &GetEvents() = 0;
virtual bool Register(Event *event) = 0;
virtual bool Unregister(Event *event) = 0;
virtual void Reply(Request &request) = 0;
};
inline RPC::Array &RPC::Array::ReplyArray()
{
auto &reply = this->replies.emplace_back(RPC::Array());
return std::get<RPC::Array>(reply.Get());
}
inline RPC::Map &RPC::Array::ReplyMap()
{
auto &reply = this->replies.emplace_back(RPC::Map());
return std::get<RPC::Map>(reply.Get());
}
inline RPC::Array &RPC::Map::ReplyArray(const Anope::string &key)
{
auto it = this->replies.emplace(key, RPC::Array());
return std::get<RPC::Array>(it.first->second.Get());
}
inline RPC::Map &RPC::Map::ReplyMap(const Anope::string &key)
{
auto it = this->replies.emplace(key, RPC::Map());
return std::get<RPC::Map>(it.first->second.Get());
}
template<typename T>
inline T &RPC::Request::Root()
{
if (!this->root.has_value())
this->root = RPC::Value(T());
return std::get<T>(this->root.value().Get());
}
+33 -16
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2014-2024 Anope Team
* (C) 2014-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -15,8 +15,7 @@ namespace SASL
Anope::string source;
Anope::string target;
Anope::string type;
Anope::string data;
Anope::string ext;
std::vector<Anope::string> data;
};
class Mechanism;
@@ -53,6 +52,17 @@ namespace SASL
Reference<Mechanism> mech;
Session(Mechanism *m, const Anope::string &u) : created(Anope::CurTime), uid(u), mech(m) { }
inline Anope::string GetUserInfo()
{
auto *u = User::Find(uid);
if (u)
return u->GetMask();
if (!hostname.empty() && !ip.empty())
return Anope::printf("%s (%s)", hostname.c_str(), ip.c_str());
return "A user";
};
virtual ~Session()
{
if (sasl)
@@ -69,7 +79,7 @@ namespace SASL
virtual Session *CreateSession(const Anope::string &uid) { return new Session(this, uid); }
virtual void ProcessMessage(Session *session, const Message &) = 0;
virtual bool ProcessMessage(Session *session, const Message &) = 0;
virtual ~Mechanism()
{
@@ -82,10 +92,25 @@ namespace SASL
: public ::IdentifyRequest
{
Anope::string uid;
Anope::string hostname, ip;
Anope::string hostname;
inline Anope::string GetUserInfo()
{
auto *u = User::Find(uid);
if (u)
return u->GetMask();
if (!hostname.empty() && !GetAddress().empty())
return Anope::printf("%s (%s)", hostname.c_str(), GetAddress().c_str());
return "A user";
};
public:
IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass, const Anope::string &h, const Anope::string &i) : ::IdentifyRequest(m, acc, pass), uid(id), hostname(h), ip(i) { }
IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass, const Anope::string &h, const Anope::string &i)
: ::IdentifyRequest(m, acc, pass, i)
, uid(id)
, hostname(h)
{
}
void OnSuccess() override
{
@@ -103,11 +128,7 @@ namespace SASL
Session *s = sasl->GetSession(uid);
if (s)
{
Anope::string user = "A user";
if (!hostname.empty() && !ip.empty())
user = hostname + " (" + ip + ")";
Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << user << " identified to account " << this->GetAccount() << " using SASL";
Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << GetUserInfo() << " identified to account " << this->GetAccount() << " using SASL";
sasl->Succeed(s, na->nc);
delete s;
}
@@ -134,11 +155,7 @@ namespace SASL
else if (na->nc->HasExt("UNCONFIRMED"))
accountstatus = "unconfirmed ";
Anope::string user = "A user";
if (!hostname.empty() && !ip.empty())
user = hostname + " (" + ip + ")";
Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << user << " failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL";
Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << GetUserInfo() << " failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL";
}
};
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2010-2024 Anope Team
* (C) 2010-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
-50
View File
@@ -1,50 +0,0 @@
/*
*
* (C) 2010-2024 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*/
#pragma once
#include "httpd.h"
class XMLRPCRequest final
{
std::map<Anope::string, Anope::string> replies;
public:
Anope::string name;
Anope::string id;
std::deque<Anope::string> data;
HTTPReply &r;
XMLRPCRequest(HTTPReply &_r) : r(_r) { }
inline void reply(const Anope::string &dname, const Anope::string &ddata) { this->replies.emplace(dname, ddata); }
inline const std::map<Anope::string, Anope::string> &get_replies() { return this->replies; }
};
class XMLRPCServiceInterface;
class XMLRPCEvent
{
public:
virtual ~XMLRPCEvent() = default;
virtual bool Run(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) = 0;
};
class XMLRPCServiceInterface
: public Service
{
public:
XMLRPCServiceInterface(Module *creator, const Anope::string &sname) : Service(creator, "XMLRPCServiceInterface", sname) { }
virtual void Register(XMLRPCEvent *event) = 0;
virtual void Unregister(XMLRPCEvent *event) = 0;
virtual Anope::string Sanitize(const Anope::string &string) = 0;
virtual void Reply(XMLRPCRequest &request) = 0;
};
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,7 +1,7 @@
/*
*
* (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* (C) 2008-2024 Anope Team <team@anope.org>
* (C) 2008-2025 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2008-2024 Anope Team
* (C) 2008-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+18 -4
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -59,13 +59,27 @@ public:
static std::vector<Anope::string> GetServiceKeys(const Anope::string &t)
{
std::vector<Anope::string> keys;
std::map<Anope::string, std::map<Anope::string, Service *> >::iterator it = Services.find(t);
const auto it = Services.find(t);
if (it != Services.end())
for (std::map<Anope::string, Service *>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
keys.push_back(it2->first);
{
for (const auto &[key, _] : it->second)
keys.push_back(key);
}
return keys;
}
static std::vector<Service *> GetServices(const Anope::string &t)
{
std::vector<Service *> values;
const auto it = Services.find(t);
if (it != Services.end())
{
for (const auto &[_, value] : it->second)
values.push_back(value);
}
return values;
}
static void AddAlias(const Anope::string &t, const Anope::string &n, const Anope::string &v)
{
std::map<Anope::string, Anope::string> &smap = Aliases[t];
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* Timer include stuff.
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,7 +1,7 @@
/*
*
* (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* (C) 2003-2024 Anope Team <team@anope.org>
* (C) 2003-2025 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*
+1 -1
View File
@@ -1,6 +1,6 @@
/* Build bumper
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2008-2024 Anope Team
* (C) 2008-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+18 -5
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-25 01:30+0000\n"
"POT-Creation-Date: 2025-02-14 14:57+0000\n"
"PO-Revision-Date: 2024-11-25 01:32+0000\n"
"Last-Translator: Sadie Powell <sadie@witchery.services>\n"
"Language-Team: English\n"
@@ -539,6 +539,9 @@ msgstr ""
msgid "channel [user]"
msgstr ""
msgid "channel [user]+"
msgstr ""
msgid "channel [+expiry] [reason]"
msgstr ""
@@ -593,6 +596,9 @@ msgstr ""
msgid "modname"
msgstr ""
msgid "network-name"
msgstr ""
msgid "new-display"
msgstr ""
@@ -2005,7 +2011,7 @@ msgid ""
"restarted, or the configuration is reloaded.\n"
" \n"
"Example:\n"
" MODIFY nickserv forcemail no"
" MODIFY nickserv regdelay 15m"
msgstr ""
msgid ""
@@ -3481,7 +3487,7 @@ msgstr ""
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
"Gives %s status to the selected nicks on a channel. If nick is\n"
"not given, it will %s you."
msgstr ""
@@ -3764,7 +3770,14 @@ msgstr ""
msgid ""
"Lists all available bots on this network.\n"
"Bots prefixed by a * are reserved for IRC Operators."
"\n"
"If the OPERONLY, UNUSED or VANITY options are given only\n"
"bots which, respectively, are oper-only, unused or were\n"
"added at runtime will be displayed. If multiple options are\n"
"given, all nicks matching at least one option will be\n"
"displayed.\n"
"\n"
"Note that these options are limited to Services Operators."
msgstr ""
msgid "Lists all channel records"
@@ -4930,7 +4943,7 @@ msgstr ""
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
"Removes %s status from the selected nicks on a channel. If nick is\n"
"not given, it will de%s you."
msgstr ""
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-25 01:30+0000\n"
"POT-Creation-Date: 2024-12-12 17:11+0000\n"
"PO-Revision-Date: 2024-11-25 01:32+0000\n"
"Last-Translator: Val Lorentz <progval+git@progval.net>\n"
"Language-Team: French\n"
@@ -2419,7 +2419,7 @@ msgid ""
"restarted, or the configuration is reloaded.\n"
" \n"
"Example:\n"
" MODIFY nickserv forcemail no"
" MODIFY nickserv regdelay 15m"
msgstr ""
"Vous permet de voir et de modifier les paramètres de configuration.\n"
"Les paramètres modifiés par cette commande le sont temporairement\n"
+506 -598
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+40 -6
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -15,26 +15,53 @@ class CommandBSBotList final
: public Command
{
public:
CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 0)
CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 1)
{
this->SetDesc(_("Lists available bots"));
this->SetSyntax("[OPERONLY] [UNUSED] [VANITY]");
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
const bool is_admin = source.HasCommand("botserv/administration");
auto operonly = false;
auto unused = false;
auto vanity = false;
if (is_admin && !params.empty())
{
spacesepstream keywords(params[0]);
for (Anope::string keyword; keywords.GetToken(keyword); )
{
if (keyword.equals_ci("OPERONLY"))
operonly = true;
if (keyword.equals_ci("UNUSED"))
unused = true;
if (keyword.equals_ci("VANITY"))
vanity = true;
}
}
unsigned count = 0;
ListFormatter list(source.GetAccount());
list.AddColumn(_("Nick")).AddColumn(_("Mask"));
list.AddColumn(_("Nick")).AddColumn(_("Mask")).AddColumn(_("Real name"));
for (const auto &[_, bi] : *BotListByNick)
{
if (source.HasPriv("botserv/administration") || !bi->oper_only)
if (is_admin || !bi->oper_only)
{
if (operonly && !bi->oper_only)
continue;
if (unused && bi->GetChannelCount())
continue;
if (vanity && bi->conf)
continue;
++count;
ListFormatter::ListEntry entry;
entry["Nick"] = (bi->oper_only ? "* " : "") + bi->nick;
entry["Nick"] = bi->nick;
entry["Mask"] = bi->GetIdent() + "@" + bi->host;
entry["Real name"] = bi->realname;
list.AddEntry(entry);
}
}
@@ -61,7 +88,14 @@ public:
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Lists all available bots on this network.\n"
"Bots prefixed by a * are reserved for IRC Operators."));
"\n"
"If the OPERONLY, UNUSED or VANITY options are given only\n"
"bots which, respectively, are oper-only, unused or were\n"
"added at runtime will be displayed. If multiple options are\n"
"given, all nicks matching at least one option will be\n"
"displayed.\n"
"\n"
"Note that these options are limited to \037Services Operators\037."));
return true;
}
};
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+2 -2
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -55,7 +55,7 @@ public:
info[_("Real name")] = bi->realname;
info[_("Created")] = Anope::strftime(bi->created, source.GetAccount());
info[_("Options")] = bi->oper_only ? _("Private") : _("None");
info[_("Used on")] = Anope::printf(Language::Translate(source.nc, N_("%u channel", "%u channels")), bi->GetChannelCount());
info[_("Used on")] = Anope::printf(Language::Translate(source.nc, bi->GetChannelCount(), N_("%u channel", "%u channels")), bi->GetChannelCount());
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2024 Anope Team
* (C) 2003-2025 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.

Some files were not shown because too many files have changed in this diff Show More