1
0
mirror of https://github.com/anope/anope.git synced 2026-06-17 04:34:47 +02:00

Compare commits

...

55 Commits

Author SHA1 Message Date
Sadie Powell 331c33c350 Release 2.1.24. 2026-05-01 12:38:33 +01:00
Sadie Powell 10eef1af23 Update the change log. 2026-05-01 12:38:18 +01:00
Sadie Powell 90ff716ed3 Remove using statements that break unity builds. 2026-04-30 13:37:03 +01:00
Sadie Powell f67c70e485 Get rid of the using statement for Configuration::Uplink.
This breaks unity builds.
2026-04-30 13:23:06 +01:00
Sadie Powell fd5e10c54c Fix an inverted default for should_commit. 2026-04-27 20:10:53 +01:00
Sadie Powell 029565c894 Convert some messages in cs_enforce to use format strings. 2026-04-26 18:26:23 +01:00
Sadie Powell 9b8862826c Sort the files before running xgettext so we get consistent output. 2026-04-26 18:24:19 +01:00
Sadie Powell e2dc77641a Add some helper methods to CommandSource for translation. 2026-04-26 18:07:56 +01:00
Sadie Powell 7eb710a009 Update the change log. 2026-04-26 12:57:03 +01:00
Sadie Powell b33b5a6630 Use versioned prefixes for the SQL database tables. 2026-04-26 12:49:54 +01:00
Sadie Powell f4d5b1f01d Clean up the Config script a bit. 2026-04-26 12:45:57 +01:00
Sadie Powell b61daf81b0 Allow as many dashes as provided on Config options. 2026-04-23 19:23:12 +01:00
Sadie Powell da3f667188 Update the change log. 2026-04-23 19:08:55 +01:00
Sadie Powell 040cd99027 Add more debug logging to db_json. 2026-04-23 19:08:55 +01:00
Sadie Powell 6c7977f239 Remove duplicate objects from corrupt databases on database write. 2026-04-23 19:08:55 +01:00
Sadie Powell 9b8570a2ee Banish Redis support to the shadow realm.
Nobody actually uses this and it hasn't been tested in years so it
a massive pain to maintain. It may be replaced with an alternate
NoSQL database such as MongoDB in the future.
2026-04-23 17:42:42 +01:00
Sadie Powell 64f386e29e Skip deserialising the old cert column when its empty. 2026-04-23 13:48:12 +01:00
Sadie Powell 9434be29bc Delete the cert object after removing it from the cert list. 2026-04-23 13:41:11 +01:00
Sadie Powell 9aff71fb2f Merge branch '2.0' into 2.1. 2026-04-16 11:54:36 +01:00
Sadie Powell ba26d9a15c Add a missing FNAME handler on InspIRCd 3+.
Closes #572.
2026-04-16 11:50:10 +01:00
Sadie Powell 22dc33de9f Add support for the ratified channel-context tag. 2026-04-09 12:01:16 +01:00
dependabot[bot] 11d6f58a1a Bump microsoft/setup-msbuild from 2 to 3
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 2 to 3.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v2...v3)

---
updated-dependencies:
- dependency-name: microsoft/setup-msbuild
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-01 22:06:38 +01:00
Sadie Powell f32d6453f5 Bump for 2.1.24-git. 2026-04-01 10:58:23 +01:00
Sadie Powell 1606bb01a3 Release 2.1.23. 2026-04-01 10:57:58 +01:00
Sadie Powell 3d86c82ac5 Update the change log. 2026-03-30 17:49:06 +01:00
Sadie Powell a858a1e0a0 Fix the missing AUTOLOGIN extension. 2026-03-30 17:48:07 +01:00
Sadie Powell eaa24d3b0a Fix the location of &* on types. 2026-03-26 16:32:56 +00:00
Sadie Powell 5355b53008 Remove the remaining istream use in Data. 2026-03-26 16:32:56 +00:00
Sadie Powell 85a32077b5 Add Data::Load, make the istream operator private. 2026-03-26 14:35:31 +00:00
Sadie Powell 5006993d0a Make the hops parameter to Server optional. 2026-03-26 12:25:09 +00:00
Sadie Powell 1b2b4386c1 Use ProtocolException instead of setting Quitting manually. 2026-03-26 12:06:25 +00:00
Sadie Powell b199d74088 Fix the message counts in RPL_STATSLINKINFO. 2026-03-26 11:57:13 +00:00
Sadie Powell 7e2ef3774b Move NET_BUFSIZE to socket_transport. 2026-03-24 20:18:15 +00:00
Sadie Powell e002f39509 Abolish the few remaining uses of BUFSIZE. 2026-03-23 02:14:51 +00:00
Sadie Powell d3395a5d39 Include the file name in the translation files.
This was not available when we stripped the line details and it
provides a good compromise between diff noise and clarity.
2026-03-19 00:01:53 +00:00
Sadie Powell 1deff337fe Skip the run and vendor directory when updating the translations. 2026-03-19 00:01:53 +00:00
KidProtect adf457ffb2 Update the Romanian translation. 2026-03-18 20:27:11 +00:00
TehPeGaSuS 550adc13f3 Update the Portuguese translation. 2026-03-18 20:26:04 +00:00
Sadie Powell 04bdcb8ce6 Update the en_US language file. 2026-03-17 00:50:26 +00:00
Sadie Powell 0a99866e5b Add more examples to the BotServ modules. 2026-03-17 00:47:31 +00:00
Sadie Powell c22f7a9038 Add examples to the greet module and improve the help output. 2026-03-17 00:46:11 +00:00
Sadie Powell 074ad6556c Allow migrating access entries to the flags access system. 2026-03-16 19:18:59 +00:00
Sadie Powell a657cb5edf Move access entries for other access systems under an ALL option.
This should hopefully make it clearer that the access systems are
separate.
2026-03-16 19:18:35 +00:00
Sadie Powell 63032dc8d9 Fix translating the help output when the flexible layout is used. 2026-03-16 18:21:29 +00:00
TehPeGaSuS 404f55502e Finish the Portuguese (Portugal) translation. 2026-03-16 17:52:32 +00:00
Sadie Powell 73f3621af6 Update the en_US translation file. 2026-03-16 15:17:33 +00:00
Sadie Powell 2a1409face Fix a non-translatable string which has been marked as translatable. 2026-03-16 15:16:55 +00:00
Sadie Powell 9834040948 Fix checking the wrong config option in os_stats. 2026-03-11 16:41:50 +00:00
Sadie Powell f111e3b3ec Deduplicate the messages in the os_stats akill stats. 2026-03-11 16:37:15 +00:00
Sadie Powell 22a1924bfd Allow Command::FindCommandFromService to skip hidden commands. 2026-03-11 05:44:48 +00:00
Sadie Powell fa5bb3f1bf Show the default levels in LEVELS DESC.
Closes #564.
2026-03-10 23:30:35 +00:00
Sadie Powell 12545ccbde Use auto in as many places as possible. 2026-03-05 18:04:33 +00:00
dependabot[bot] 98703052cc Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 19:04:34 +00:00
KidProtect 15635779af Update the Romanian translation. 2026-03-01 18:54:31 +00:00
Sadie Powell 1fc58c7a57 Bump for 2.1.23-git. 2026-03-01 03:00:19 +00:00
149 changed files with 7786 additions and 7451 deletions
+2 -2
View File
@@ -24,7 +24,7 @@ jobs:
distro: official
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
uses: microsoft/setup-msbuild@v3
- name: Setup Conan
uses: turtlebrowser/get-conan@v1.2
@@ -77,7 +77,7 @@ jobs:
- name: Upload artifact
if: "${{ github.event_name != 'release' }}"
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: windows-installer
path: ${{ github.workspace }}\build\\anope-*.exe
+22 -27
View File
@@ -29,43 +29,37 @@ Load_Cache () {
}
Run_Build_System () {
WITH_INST=""
WITH_RUN=""
WITH_PERM=""
EXTRA_INCLUDE=""
EXTRA_LIBS=""
BUILD_DIR="${SOURCE_DIR}/build"
CMAKE_COMMAND="${CMAKE:-cmake} -B ${BUILD_DIR} -S ${SOURCE_DIR}"
if [ "$INSTDIR" != "" ] ; then
WITH_INST="-DINSTDIR=$INSTDIR"
CMAKE_COMMAND="${CMAKE_COMMAND} -D INSTDIR=$INSTDIR"
fi
if [ "$RUNGROUP" != "" ] ; then
WITH_RUN="-DRUNGROUP=$RUNGROUP"
CMAKE_COMMAND="${CMAKE_COMMAND} -D RUNGROUP=$RUNGROUP"
fi
if [ "$UMASK" != "" ] ; then
WITH_PERM="-DDEFUMASK=$UMASK"
CMAKE_COMMAND="${CMAKE_COMMAND} -D DEFUMASK=$UMASK"
fi
if [ "$DEBUG" = "yes" ] ; then
BUILD_TYPE="-DCMAKE_BUILD_TYPE=Debug"
CMAKE_COMMAND="${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE=Debug"
else
BUILD_TYPE="-DCMAKE_BUILD_TYPE=Release"
CMAKE_COMMAND="${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE=Release"
fi
if [ "$EXTRA_INCLUDE_DIRS" != "" ] ; then
EXTRA_INCLUDE="-DEXTRA_INCLUDE=$EXTRA_INCLUDE_DIRS"
CMAKE_COMMAND="${CMAKE_COMMAND} -D EXTRA_INCLUDE=$EXTRA_INCLUDE_DIRS"
fi
if [ "$EXTRA_LIB_DIRS" != "" ] ; then
EXTRA_LIBS="-DEXTRA_LIBS=$EXTRA_LIB_DIRS"
CMAKE_COMMAND="${CMAKE_COMMAND} -D EXTRA_LIBS=$EXTRA_LIB_DIRS"
fi
BUILD_PATHS="-B ${SOURCE_DIR}/build ${SOURCE_DIR}"
CMAKE="cmake $GEN_TYPE $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $BUILD_PATHS"
echo $CMAKE
$CMAKE
echo $CMAKE_COMMAND
$CMAKE_COMMAND
if [ $? -ne 0 ]; then
echo "You should fix these issues and then run ./Config -quick to rerun CMake."
@@ -73,11 +67,7 @@ Run_Build_System () {
fi
echo ""
if [ "$PWD" = "${SOURCE_DIR}/build" ]; then
echo "Now run make to build Anope."
else
echo "Now cd build, then run make to build Anope."
fi
echo "Now run 'make -C ${BUILD_DIR#"$PWD/"} install' to build and install Anope."
}
###########################################################################
@@ -98,7 +88,12 @@ CAN_QUICK="no"
###########################################################################
while [ $# -ge 1 ] ; do
if [ $1 = "--help" ] ; then
OPTION=$1
while [ "${OPTION#-}" != "$OPTION" ]; do
OPTION="${OPTION#-}"
done
if [ "$OPTION" = "--help" ] ; then
echo "Config utility for Anope"
echo "------------------------"
echo "Syntax: ./Config [options]"
@@ -106,15 +101,15 @@ while [ $# -ge 1 ] ; do
echo "-nointro Skip intro (disclaimer, etc)"
echo "-quick Skip questions, go straight to cmake"
exit 0
elif [ $1 = "-devel" ] ; then
elif [ "$OPTION" = "devel" ] ; then
DEBUG="yes"
DEVEL="yes"
INSTDIR="$SOURCE_DIR/run"
elif [ $1 = "-nocache" ] ; then
elif [ "$OPTION" = "nocache" ] ; then
IGNORE_CACHE="1"
elif [ $1 = "-nointro" ] ; then
elif [ "$OPTION" = "nointro" ] ; then
NO_INTRO="1"
elif [ $1 = "-quick" -o $1 = "-q" ] ; then
elif [ "$OPTION" = "quick" -o "$OPTION" = "q" ] ; then
Load_Cache
if [ "$CAN_QUICK" = "yes" ] ; then
Run_Build_System
+1 -21
View File
@@ -1228,7 +1228,7 @@ module
* An optional prefix to prepended to the name of each created table.
* Do not use the same prefix for other programs.
*/
#prefix = "anope_db_"
#prefix = "anope21_"
/*
* Whether or not to import data from another database module in to SQL on
@@ -1248,26 +1248,6 @@ module
import = no
}
/*
* db_redis.
*
* This module allows using Redis (https://redis.io/) as a database backend.
* This module requires that redis is loaded and configured properly.
*
* Redis 2.8 supports keyspace notifications which allows Redis to push notifications
* to Anope about outside modifications to the database. This module supports this and
* will internally reflect any changes made to the database immediately once notified.
* See docs/REDIS for more information regarding this.
*/
#module
{
name = "db_redis"
/*
* Redis database to use. This must be configured with redis.
*/
engine = "redis/main"
}
/*
* [RECOMMENDED] Encryption modules.
+1 -1
View File
@@ -22,7 +22,7 @@ module
* An optional prefix to prepended to the name of each created table.
* Do not use the same prefix for other programs.
*/
prefix = "anope_"
#prefix = "chanstats21_"
smileyshappy = ":) :-) ;) ;-) :D :-D :P :-P"
smileyssad = ":( :-( ;( ;-("
-24
View File
@@ -374,30 +374,6 @@ module { name = "help" }
}
}
/*
* redis
*
* This module allows other modules to use Redis.
*/
#module
{
name = "redis"
/* A redis database */
redis
{
/* The name of this service */
name = "redis/main"
/*
* The redis database to use. New connections default to 0.
*/
db = 0
ip = "127.0.0.1"
port = 6379
}
}
/*
* [EXTRA] regex_pcre2
+52
View File
@@ -1,5 +1,57 @@
# Anope Change Log
## Anope 2.1.24 (unreleased)
### Breaking Changes
* If a database contains duplicate corrupt entries from a prior write failure the oldest ones will now be purged from the database. This is a destructive action so make sure you take a manual backup of your database before upgrading.
* Removed support for storing the Anope database in Redis. The Redis code was extremely bitrotted, had not been tested in years, and to our knowledge has almost no (if any) users. It is recommended that db_redis users migrate to db_json or db_sql.
* SQL tables now use versioned prefixes by default. For the SQL database backends the default is `anope21_` and for ChanStats the default is `chanstats21_`. If you do not have a prefix explicitly set in your config you will need to add one it. Alternatively, you may also want to consider exporting to db_json and re-importing to update your SQL schema for the recent database layout changes.
### Changes
* Added some helper methods to `CommandSource` to allow quickly translting messages.
* Changed the Config script to allow multiple dashes in front of options, i.e. `-quick` and `--quick` are now equivalent.
* Converted some language strings to use format strings instead of concatenation.
* Fixed a rare crash in the ns_cert module.
* Fixed building Anope as a unity build.
* Fixed the ns_cert module erasing certificate entries if using an old database.
* Fixed users having the wrong real name in log messages on InspIRCd if it has been previously changed with `CHGNAME` or `SETNAME`.
## Anope 2.1.23 (2026-04-01)
### Changes
* Added examples to several BotServ commands.
* Added missing fields to the `RPL_STATSLINKINFO` output.
* Added support for migrating access entries between systems (currently only `chanserv/flags` is supported).
* Added the default levels to the `chanserv/levels` DESC help.
* Changed access listing commands to only show their own access entries unless `ALL` is specified.
* Fixed a non-translatable string which has been marked as translatable.
* Fixed the missing AUTOLOGIN extension.
* Fixed translating the help output when the flexible layout is used.
* Improved the accuracy of the X-line expiry time in `operserv/stats`.
* Updated the Portuguese translation.
* Updated the Romanian translation.
## Anope 2.1.22 (2026-03-01)
### Breaking Changes
-160
View File
@@ -1,160 +0,0 @@
Anope has Redis database support (https://redis.io/).
This document explains the data structure used by Anope, and explains how
keyspace notification works.
This is not a tutorial on how to use Redis, see https://redis.io/documentation
for that.
Table of Contents
-----------------
1) Data structure
2) Keyspace notifications
3) Examples of modifying, deleting, and creating objects
1) Data structure
There are 4 key namespaces in Anope, they are:
id - The keys in id are used to atomically create object ids for new
objects. For example, if I were to create a new BotInfo I would first:
redis 127.0.0.1:6379> INCR id:BotInfo
To get the object ID of the new object.
ids - The keys in ids contain a set of all object ids of the given type.
For example:
redis 127.0.0.1:6379> SMEMBERS ids:BotInfo
Returns "1", "2", "3", "4", "5", "6", "7", "8" because I have 8 bots that
have IDs 1, 2, 3, 4, 5, 6, 7, and 8, respectively.
hash - The keys in hash are the actual objects, stored as hashes. For
example, if I had just looked up all BotInfo ids and wanted to iterate
over all of them, I would start by:
redis 127.0.0.1:6379> HGETALL hash:BotInfo:1
Which gets all keys and values from the hash of type BotInfo with id 1.
This may return:
"nick" -> "BotServ"
"user" -> "services"
"host" -> "services.anope.org"
"created" -> "1368704765"
value - The keys in value only exist to aid looking up object IDs. They
are sets of object IDs and are used to map key+value pairs to objects.
For example:
redis 127.0.0.1:6379> SMEMBERS value:NickAlias:nick:Adam
Returns a set of object ids of NickAlias objects that have the key
'nick' set to the value 'Adam' in its hash. Clearly this can only
ever contain at most one object, since it is not possible to have
more than one registered nick with the same name, but other keys
will contain more than one, such as:
redis 127.0.0.1:6379> SMEMBERS value:NickCore:email:adam@anope.org
Which would return all accounts with the email "adam@anope.org".
redis 127.0.0.1:6379> SMEMBERS value:ChanAccess:mask:Adam
Which would return all access entries set on the account "Adam".
Behavior similar to SQL's AND, can be achieved using the
SINTER command, which does set intersection on one or more sets.
2) Keyspace notifications
Redis 2.7 (unstable) and 2.8 (stable) and newer support keyspace notifications
(https://redis.io/topics/notifications). This allows Redis to notify Anope of
any external changes to objects in the database. Once notified, Anope will
immediately update the object. Otherwise, Anope keeps all objects in memory
and will not regularly read from the database once started.
You can use this to modify objects in Redis and have them immediately reflected
back into Anope. Additionally you can use this feature to run multiple Anope
instances simultaneously from the same database (see also, Redis database
replication).
To use keyspace notifications you MUST execute
redis 127.0.0.1:6379> CONFIG SET notify-keyspace-events KA
OK
or set notify-keyspace-events in redis.conf properly. Anope always executes
CONFIG SET when it first connects.
If you do not enable keyspace events properly Anope will be UNABLE to see any
object modifications you do.
The key space ids and value are managed entirely by Anope, you do
not (and should not) modify them. Once you modify the object (hash), Anope will
update them for you to correctly reflect any changes made to the object.
Finally, always use atomic operations. If you are inserting a new object with
multiple commands, or inserting multiple objects at once, specifically if the
objects depend on each other, you MUST use a transaction.
3) Examples of modifying, deleting, and creating objects
These examples will ONLY work if you meet the criteria in section 2.
If I want to change the email account 'Adam' to 'Adam@anope.org', I would execute the following:
redis 127.0.0.1:6379> SMEMBERS value:NickCore:display:Adam
Which returns a value of "1", which is the object id I want to modify.
Now to change the email:
redis 127.0.0.1:6379> HSET hash:NickCore:1 email Adam@anope.org
You can now see this in NickServ's INFO command:
-NickServ- Email address: Adam@anope.org
If I want to drop the account "Adam", I would execute the following:
redis 127.0.0.1:6379> SMEMBERS value:NickCore:display:Adam
Which returns a value of "1". I would then check:
redis 127.0.0.1:6379> SMEMBERS value:NickAlias:nc:Adam
To see what nicknames depend on this account to exist, as I will
have to remove those too. This returns the values "2", and "3".
Finally, I can drop the nick using a transaction via:
redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> DEL hash:NickAlias:2
QUEUED
redis 127.0.0.1:6379> DEL hash:NickAlias:3
QUEUED
redis 127.0.0.1:6379> DEL hash:NickCore:1
QUEUED
redis 127.0.0.1:6379> EXEC
Or alternatively simply:
redis 127.0.0.1:6379> DEL hash:NickAlias:2 hash:NickAlias:3 hash:NickCore:1
If I wanted to create a BotServ bot, I would execute the following:
redis 127.0.0.1:6379> INCR id:BotInfo
Which returns a new object ID for me, in this example it will be "8".
Now I can create the object:
HMSET hash:BotInfo:8 nick redis user redis host services.anope.org realname "Anope IRC Services"
Note if you are using HSET instead of HMSET you will need to use a transaction, as shown in the above example.
If you are watching your services logs you will immediately see:
USERS: redis!redis@services.anope.org (Anope IRC Services) connected to the network (services.anope.org)
And the bot redis will be in BotServ's bot list.
Notice how ids:BotInfo and the value keys are updated automatically.
+6 -1
View File
@@ -90,6 +90,11 @@ public:
void Reply(int count, const char *singular, const char *plural, ...) ATTR_FORMAT(4, 5);
void Reply(const Anope::string &message);
const char *Translate(const char *message);
const char *Translate(const Anope::string &message);
const char *Translate(int count, const char *single, const char *plural);
const char *Translate(int count, const Anope::string &single, const Anope::string &plural);
bool HasCommand(const Anope::string &cmd);
bool HasPriv(const Anope::string &cmd);
bool IsServicesOper();
@@ -189,5 +194,5 @@ public:
* @param name If found, is set to the command name, eg REGISTER
* @return true if the given command service exists
*/
static bool FindCommandFromService(const Anope::string &command_service, BotInfo *&bi, Anope::string &name);
static bool FindFromService(const Anope::string &command_service, BotInfo *&bi, Anope::string &name);
};
+2 -4
View File
@@ -185,7 +185,7 @@ public:
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
{
T t;
if (data[this->name] >> t)
if (data.TryLoad(this->name, t))
this->Set(e, t);
else
this->Unset(e);
@@ -205,9 +205,7 @@ public:
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
{
bool b = false;
data[this->name] >> b;
if (b)
if (data.Load<bool>(this->name))
this->Set(e);
else
this->Unset(e);
+6 -1
View File
@@ -44,7 +44,7 @@ namespace Language
/** Sets the locale to the specified language.
* @param lang The language to translate to.
*/
extern CoreExport void SetLocale(const char* lang);
extern CoreExport void SetLocale(const char *lang);
/** Sets the locale back to the default. */
extern CoreExport void ResetLocale();
@@ -141,6 +141,11 @@ namespace Language
#define CHAN_ACCESS_LIMIT_DEEP N_("You can only have %u access entry on a channel, including access entries from other channels.", "You can only have %u access entries on a channel, including access entries from other channels.")
#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.")
#define CHAN_ACCESS_MALFORMED _("You cannot add a malformed mask to an access list. Did you mean to add %s instead?")
#define CHAN_ACCESS_FOREIGN N_("%u access entry from other access systems not shown; use \002%s\033ALL\002 to view all access entries.", "%u access entries from other access systems not shown; use \002%s\033ALL\002 to view all access entries.")
#define CHAN_ACCESS_MIGRATED_1 _("\002%s\002 has been migrated to the %s access system.")
#define CHAN_ACCESS_MIGRATED_N N_("\002%u\002 entry has been migrated to the %s access system.", "\002%u\002 entries have been migrated to the %s access system.")
#define CHAN_ACCESS_NOT_MIGRATED_1 _("\002%s\002 can not be migrated to the %s access system because they have privileges that you do not.")
#define CHAN_ACCESS_NOT_MIGRATED_N N_("\002%u\002 entry can not be migrated to the %s access system because they have privileges that you do not.", "\002%u\002 entries can not be migrated to the %s access system because they have privileges that you do not.")
#define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except has been removed.")
#define CHAN_INFO_HEADER _("Information about channel \002%s\002:")
#define CHAN_LIMIT_EXCEEDED _("You have already exceeded your limit of \002%d\002 channels.")
+4 -2
View File
@@ -601,15 +601,17 @@ public:
* @param ci The channel
* @param source The source of the command
* @param access The access entry that was removed
* @param migrated Whether the access entry was deleted because of being migrated to another system.
*/
virtual void OnAccessDel(ChannelInfo *ci, CommandSource &source, ChanAccess *access) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
virtual void OnAccessDel(ChannelInfo *ci, CommandSource &source, ChanAccess *access, bool migrated) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
/** Called when access is added
* @param ci The channel
* @param source The source of the command
* @param access The access changed
* @param migrated Whether the access entry was added because of being migrated to another system.
*/
virtual void OnAccessAdd(ChannelInfo *ci, CommandSource &source, ChanAccess *access) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
virtual void OnAccessAdd(ChannelInfo *ci, CommandSource &source, ChanAccess *access, bool migrated) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
/** Called when the access list is cleared
* @param ci The channel
+2 -2
View File
@@ -46,7 +46,7 @@ public:
/** Retrieves the size of the messages queue for the specified user.
* @param nc The account to count queued messages for.
*/
inline size_t CountQueue(NickCore* nc) const
inline size_t CountQueue(NickCore *nc) const
{
auto *q = GetQueue(nc);
return q ? q->size() : 0;
@@ -55,7 +55,7 @@ public:
/** Retrieves the messages queue for the specified user.
* @param nc The account to retrieve queued messages for.
*/
virtual const std::vector<Anope::string> *GetQueue(NickCore* nc) const = 0;
virtual const std::vector<Anope::string> *GetQueue(NickCore *nc) const = 0;
/** Queues a message to be sent later.
* @param nc The account to queue the message for.
-83
View File
@@ -1,83 +0,0 @@
// Anope IRC Services <https://www.anope.org/>
//
// Copyright (C) 2003-2026 Anope Contributors
//
// Anope is free software. You can use, modify, and/or distribute it under the
// terms of version 2 of the GNU General Public License. See docs/LICENSE.txt
// for the complete terms of this license and docs/AUTHORS.txt for a list of
// contributors.
//
// Based on the original code of Epona by Lara
// Based on the original code of Services by Andy Church
//
// SPDX-License-Identifier: GPL-2.0-only
#pragma once
namespace Redis
{
struct Reply final
{
enum Type
{
NOT_PARSED,
NOT_OK,
OK,
INT,
BULK,
MULTI_BULK
}
type;
Reply() { Clear(); }
~Reply() { Clear(); }
void Clear()
{
type = NOT_PARSED;
i = 0;
bulk.clear();
multi_bulk_size = 0;
for (const auto *reply : multi_bulk)
delete reply;
multi_bulk.clear();
}
int64_t i;
Anope::string bulk;
int multi_bulk_size;
std::deque<Reply *> multi_bulk;
};
class Interface
{
public:
Module *owner;
Interface(Module *m) : owner(m) { }
virtual ~Interface() = default;
virtual void OnResult(const Reply &r) = 0;
virtual void OnError(const Anope::string &error) { Log(owner) << error; }
};
class Provider
: public Service
{
public:
Provider(Module *c, const Anope::string &n) : Service(c, "Redis::Provider", n) { }
virtual bool IsSocketDead() = 0;
virtual void SendCommand(Interface *i, const std::vector<Anope::string> &cmds) = 0;
virtual void SendCommand(Interface *i, const Anope::string &str) = 0;
virtual bool BlockAndProcess() = 0;
virtual void Subscribe(Interface *i, const Anope::string &pattern) = 0;
virtual void Unsubscribe(const Anope::string &pattern) = 0;
virtual void StartTransaction() = 0;
virtual void CommitTransaction() = 0;
};
}
+1 -1
View File
@@ -183,7 +183,7 @@ private:
size_t minparams;
protected:
Event(Module *o, const Anope::string& e, size_t mp = 0)
Event(Module *o, const Anope::string &e, size_t mp = 0)
: Service(o, RPC_EVENT, e)
, minparams(mp)
{
+13 -26
View File
@@ -23,46 +23,33 @@ namespace SQL
: public Serialize::Data
{
public:
typedef std::map<Anope::string, std::stringstream *> Map;
Map data;
~Data()
{
Clear();
}
std::iostream &operator[](const Anope::string &key) override
{
std::stringstream *&ss = data[key];
if (!ss)
ss = new std::stringstream();
return *ss;
}
Anope::unordered_map<Anope::string> data;
size_t Hash() const override
{
size_t hash = 0;
for (const auto &[_, value] : this->data)
{
if (!value->str().empty())
hash ^= Anope::hash_cs()(value->str());
if (!value.empty())
hash ^= Anope::hash_cs()(value);
}
return hash;
}
std::map<Anope::string, std::iostream *> GetData() const
bool LoadInternal(const Anope::string &key, Anope::string &value) override
{
std::map<Anope::string, std::iostream *> d;
for (const auto &[key, value] : this->data)
d[key] = value;
return d;
auto it = this->data.find(key);
if (it == this->data.end())
return false;
value = it->second;
return true;
}
void Clear()
bool StoreInternal(const Anope::string &key, const Anope::string &value) override
{
for (const auto &[_, value] : this->data)
delete value;
this->data.clear();
this->data[key] = value;
return true;
}
};
+1 -1
View File
@@ -307,7 +307,7 @@ public:
*/
virtual void SendOper(User *u);
virtual void SendClearModes(const MessageSource &user, Channel *c, User* u, const Anope::string &mode) { }
virtual void SendClearModes(const MessageSource &user, Channel *c, User *u, const Anope::string &mode) { }
virtual bool IsNickValid(const Anope::string &);
virtual bool IsChannelValid(const Anope::string &);
+113 -36
View File
@@ -40,43 +40,11 @@ namespace Serialize
UINT,
};
class CoreExport Data
{
protected:
std::map<Anope::string, Serialize::DataType> types;
public:
virtual ~Data() = default;
virtual std::iostream &operator[](const Anope::string &key) = 0;
template <typename T>
void Store(const Anope::string &key, const T &value)
{
using Type = std::remove_cv_t<std::remove_reference_t<T>>;
if constexpr (std::is_same_v<Type, bool>)
SetType(key, DataType::BOOL);
else if constexpr (std::is_floating_point_v<Type>)
SetType(key, DataType::FLOAT);
else if constexpr (std::is_integral_v<Type> && std::is_signed_v<Type>)
SetType(key, DataType::INT);
else if constexpr (std::is_integral_v<Type> && std::is_unsigned_v<Type>)
SetType(key, DataType::UINT);
this->operator[](key) << value;
}
virtual size_t Hash() const { throw CoreException("Not supported"); }
Serialize::DataType GetType(const Anope::string &key) const;
void SetType(const Anope::string &key, Serialize::DataType dt);
};
extern void RegisterTypes();
extern void CheckTypes();
extern void CreateTypes();
class Data;
class Type;
template<typename T> class Checker;
template<typename T> class Reference;
@@ -106,6 +74,8 @@ private:
size_t last_commit = 0;
/* The last time this object was committed to the database */
time_t last_commit_time = 0;
/** Whether this object should be committed to the database. */
bool should_commit = true;
protected:
Serializable(const Anope::string &serialize_type);
@@ -113,6 +83,20 @@ protected:
Serializable &operator=(const Serializable &);
template<typename Container,
typename Key = typename Container::key_type,
typename Value = typename Container::mapped_type>
bool InsertUnique(Container &container, const Key &key)
{
auto res = container.emplace(key, static_cast<Value>(this));
if (res.second)
return true;
res.first->second->should_commit = false;
res.first->second = static_cast<Value>(this);
return false;
}
public:
using Id = uint64_t;
virtual ~Serializable();
@@ -120,13 +104,13 @@ public:
/* Unique ID (per type, not globally) for this object */
Id object_id = 0;
/* Only used by redis, to ignore updates */
unsigned short redis_ignore = 0;
/** Marks the object as potentially being updated "soon".
*/
void QueueUpdate();
/** Determines whether the object should be committed to the database. */
bool ShouldCommit() const { return this->should_commit; }
bool IsCached(Serialize::Data &);
void UpdateCache(Serialize::Data &);
@@ -137,10 +121,103 @@ public:
* @return The serializable object type
*/
Serialize::Type *GetSerializableType() const { return this->s_type; }
const auto &GetSerializableName() const { return this->s_name; }
static const std::list<Serializable *> &GetItems();
};
class CoreExport Serialize::Data
{
protected:
/** The specified data types of known fields. */
std::map<Anope::string, Serialize::DataType> types;
Data() = default;
/** Internal method for loading data from the database.
* @param key The field to get the value of.
* @param value The location to store the retrieved value.
*/
virtual bool LoadInternal(const Anope::string &key, Anope::string &value) = 0;
/** Internal method for storing data in the database.
* @param key The field to set the value of.
* @param value The value of the field.
*/
virtual bool StoreInternal(const Anope::string &key, const Anope::string &value) = 0;
/** Sets the data type of the specified field. This is called automatically from \ref Store.
* @param key The field to specify the data type for.
* @param dt The data type of the field.
*/
void SetType(const Anope::string &key, Serialize::DataType dt);
public:
virtual ~Data() = default;
/** Retrieves the data type for the specified field. If the field does not have a data type
* specified then it will default to TEXT.
* @param key The field to retrieve the data type for.
*/
Serialize::DataType GetType(const Anope::string &key) const;
/** Retrieves a unique hash for the data set. */
virtual size_t Hash() const { throw CoreException("Not supported"); }
/** Loads the value of a specific field.
* @param key The field to get the value of.
* @param def The default value if none is set.
*/
template <typename T = Anope::string>
T Load(const Anope::string &key, T def = T())
{
T out;
if (!TryLoad(key, out))
out = def;
return out;
}
/** Stores the value of a specific field, automatically setting its type.
* @param key The field to set the value of.
* @param value The value of the field.
*/
template <typename T>
void Store(const Anope::string &key, const T &value)
{
using Type = std::remove_cv_t<std::remove_reference_t<T>>;
if constexpr (std::is_same_v<Type, bool>)
SetType(key, DataType::BOOL);
else if constexpr (std::is_floating_point_v<Type>)
SetType(key, DataType::FLOAT);
else if constexpr (std::is_integral_v<Type> && std::is_signed_v<Type>)
SetType(key, DataType::INT);
else if constexpr (std::is_integral_v<Type> && std::is_unsigned_v<Type>)
SetType(key, DataType::UINT);
StoreInternal(key, Anope::ToString(value));
}
/** Tries to load the value of a specific field.
* @param key The field to get the value of.
* @param out The location to store the retrieved value.
*/
template <typename T = Anope::string>
bool TryLoad(const Anope::string &key, T &out)
{
Anope::string out_str;
if (!LoadInternal(key, out_str))
return false;
auto out_opt = Anope::TryConvert<T>(out_str);
if (!out_opt)
return false;
out = out_opt.value();
return true;
}
};
/* A serializable type. There should be a single instance of a subclass of this
* for each subclass of Serializable as this is what is used to serialize and
* deserialize data from the database.
+4 -4
View File
@@ -57,11 +57,11 @@ private:
/* Uplink for this server */
Server *uplink;
/* Server is syncing */
bool syncing;
bool syncing = true;
/* The server is juped */
bool juped;
/* The server is about to quit */
bool quitting;
bool quitting = false;
/* Reason this server was quit */
Anope::string quit_reason;
@@ -69,12 +69,12 @@ public:
/** Constructor
* @param uplink The uplink this server is from, is only NULL when creating Me
* @param name The server name
* @param hops Hops from services server
* @param description Server rdescription
* @param sid Server sid/numeric
* @param hops Hops from services server
* @param jupe If the server is juped
*/
Server(Server *uplink, const Anope::string &name, unsigned hops, const Anope::string &description, const Anope::string &sid = "", bool jupe = false);
Server(Server *uplink, const Anope::string &name, const Anope::string &description, const Anope::string &sid = "", unsigned hops = 0, bool jupe = false);
private:
/** Destructor
+2 -2
View File
@@ -151,14 +151,14 @@ public:
const auto &GetServiceType() const { return type; }
/** Invalidates the reference and changes the name of the referenced service. */
void SetServiceName(const Anope::string& newname)
void SetServiceName(const Anope::string &newname)
{
this->invalid = true;
this->name = newname;
}
/** Invalidates the reference and changes the type of the referenced service. */
void SetServiceType(const Anope::string& newtype)
void SetServiceType(const Anope::string &newtype)
{
this->invalid = true;
this->type = newtype;
+1 -3
View File
@@ -27,7 +27,7 @@
#include <exception>
#include <fstream>
#include <functional>
#include <iostream>
#include <istream>
#include <list>
#include <map>
#include <set>
@@ -41,8 +41,6 @@
#include "defs.h"
#include "sysconf.h"
#define BUFSIZE 1024
#define _(x) x
#define N_(x, y) x, y
-2
View File
@@ -28,8 +28,6 @@
# include <afunix.h>
#endif
#define NET_BUFSIZE 65535
/** A sockaddr union used to combine IPv4 and IPv6 sockaddrs
*/
union CoreExport sockaddrs
+3 -1
View File
@@ -54,7 +54,9 @@ class UplinkSocket final
, public BufferedSocket
{
public:
bool error;
bool error = false;
size_t recv_msgs = 0;
size_t sent_msgs = 0;
UplinkSocket();
~UplinkSocket();
bool ProcessRead() override;
+2110 -105
View File
File diff suppressed because it is too large Load Diff
+3534 -4098
View File
File diff suppressed because it is too large Load Diff
+793 -571
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -15,11 +15,13 @@ fi
find ../ \
! -path '../docs/*' \
-a ! -path '../modules/third/*' \
-a ! -path '../run/*' \
-a ! -path '../vendor/*' \
-a \( -name '*.cpp' \
-o -name '*.h' \
-o -name '*.conf' \
\) \
-exec \
-print0 | sort -z | xargs -0 -I {} \
xgettext \
--language=C++ \
--sort-output \
@@ -30,13 +32,13 @@ find ../ \
--keyword \
--keyword=_ \
--keyword=N_:1,2 \
{} +
{}
for f in *.po
do
echo "Merging $f"
msgmerge \
--no-location \
--add-location=file \
--no-wrap \
--sort-output \
--update \
+14
View File
@@ -84,6 +84,13 @@ public:
"can then configure the bot for the channel so it fits "
"your needs."
));
ExampleWrapper()
.AddEntry("#opers OperServ", _(
"Assigns the \037OperServ\037 bot to \037#opers\037."
))
.SendTo(source);
return true;
}
};
@@ -150,6 +157,13 @@ public:
"be able to reassign a bot later without having to reconfigure "
"it entirely."
));
ExampleWrapper()
.AddEntry("#opers", _(
"Unassigns a previously assigned bot from \037#opers\037."
))
.SendTo(source);
return true;
}
};
+48 -26
View File
@@ -147,7 +147,7 @@ struct BadWordsImpl final
BadWordsImpl::~BadWordsImpl()
{
for (list::iterator it = badwords->begin(); it != badwords->end();)
for (auto it = badwords->begin(); it != badwords->end();)
{
auto *bw = *it;
++it;
@@ -160,10 +160,10 @@ BadWordImpl::~BadWordImpl()
ChannelInfo *ci = ChannelInfo::Find(chan);
if (ci)
{
BadWordsImpl *badwords = ci->GetExt<BadWordsImpl>(BOTSERV_BAD_WORDS_EXT);
auto *badwords = ci->GetExt<BadWordsImpl>(BOTSERV_BAD_WORDS_EXT);
if (badwords)
{
BadWordsImpl::list::iterator it = std::find(badwords->badwords->begin(), badwords->badwords->end(), this);
auto it = std::find(badwords->badwords->begin(), badwords->badwords->end(), this);
if (it != badwords->badwords->end())
badwords->badwords->erase(it);
}
@@ -172,28 +172,20 @@ BadWordImpl::~BadWordImpl()
Serializable *BadWordTypeImpl::Unserialize(Serializable *obj, Serialize::Data &data) const
{
Anope::string sci, sword;
data["ci"] >> sci;
data["word"] >> sword;
ChannelInfo *ci = ChannelInfo::Find(sci);
auto *ci = ChannelInfo::Find(data.Load("ci"));
if (!ci)
return NULL;
Anope::string n;
data["type"] >> n;
BadWordImpl *bw;
if (obj)
bw = anope_dynamic_static_cast<BadWordImpl *>(obj);
else
bw = new BadWordImpl();
bw->chan = sci;
bw->word = sword;
bw->type = StringToType(n);
bw->chan = ci->name;
bw->word = data.Load("word");
bw->type = StringToType(data.Load("type"));
BadWordsImpl *bws = ci->Require<BadWordsImpl>(BOTSERV_BAD_WORDS_EXT);
auto *bws = ci->Require<BadWordsImpl>(BOTSERV_BAD_WORDS_EXT);
if (!obj)
bws->badwords->push_back(bw);
@@ -337,7 +329,7 @@ private:
realword = word.substr(0, pos);
}
unsigned badwordsmax = Config->GetModule(this->module).Get<unsigned>("badwordsmax");
auto badwordsmax = Config->GetModule(this->module).Get<unsigned>("badwordsmax");
if (badwords->GetBadWordCount() >= badwordsmax)
{
source.Reply(_("You can only have %d bad words entries on a channel."), badwordsmax);
@@ -496,7 +488,7 @@ public:
"\n\n"
"The \002DEL\002 command removes the given word from the "
"bad words list. If a list of entry numbers is given, those "
"entries are deleted. (See the example for LIST below.)"
"entries are deleted."
"\n\n"
"The \002LIST\002 command displays the bad words list. If "
"a wildcard mask is given, only those entries matching the "
@@ -509,14 +501,44 @@ public:
source.service->GetQueryCommand("generic/help").c_str(),
source.command.nobreak().c_str());
ExampleWrapper examples;
examples.AddEntry("#channel LIST 2-5,7-9", _(
"Lists bad word entries on \037#channel\037 numbered 2 through 5 and 7 through 9."
));
examples.AddEntry("#channel LIST *UwU*", _(
"Lists bad word entries on \037#channel\037 that match \037*UwU*\037."
));
examples.SendTo(source);
ExampleWrapper()
.AddEntry("#channel ADD smeg", _(
"Add \035smeg\035 to the bad word list of \035#channel\035. If a user says this "
"word anywhere in a message they will be kicked."
))
.AddEntry("#channel ADD smeg SINGLE", _(
"Add \035smeg\035 to the bad word list of \035#channel\035. If a user says only "
"this word in a message they will be kicked."
))
.AddEntry("#channel ADD smeg START", _(
"Add \035smeg\035 to the bad word list of \035#channel\035. If a user says this "
"word at the start of a message they will be kicked."
))
.AddEntry("#channel ADD smeg END", _(
"Add \035smeg\035 to the bad word list of \035#channel\035. If a user says this "
"word at the start of a message they will be kicked."
))
.AddEntry("#channel CLEAR", _(
"Clears all bad word entries set on \035#channel\035."
))
.AddEntry("#channel DEL 2-5,7-9", _(
"Deletes bad word entries set on \035#channel\035 numbered 2 through 5 and 7 "
"through 9."
))
.AddEntry("#channel DEL heck", _(
"Deletes \035heck\035 from the bad word list of \035#channel\035."
))
.AddEntry("#channel LIST", _(
"Lists all bad word entries set on \035#channel\035."
))
.AddEntry("#channel LIST 2-5,7-9", _(
"Lists bad word entries set on \035#channel\035 numbered 2 through 5 and 7 through "
"9."
))
.AddEntry("#channel LIST *frack*", _(
"Lists bad word entries set on \035#channel\035 that match \035*frack*\035."
))
.SendTo(source);
return true;
}
+20 -2
View File
@@ -351,8 +351,7 @@ public:
"channels."
"\n\n"
"\002%s\033ADD\002 adds a bot with the given nickname, username, "
"hostname and realname. Since no integrity checks are done "
"for these settings, be really careful."
"hostname and realname."
"\n\n"
"\002%s\033CHANGE\002 allows you to change the nickname, username, hostname "
"or realname of a bot without deleting it (and "
@@ -367,6 +366,25 @@ public:
source.command.nobreak().c_str(),
source.command.nobreak().c_str(),
source.command.nobreak().c_str());
ExampleWrapper()
.AddEntry("ADD Chii chobit persocom.test Chii Motosuwa", _(
"Adds a new bot with the nickname \035Chii\035, username \035chobit\035, hostname "
"\035persocom.test\035, and realname \035Chii Motosuwa\035."
))
.AddEntry("CHANGE Elda Chii", _(
"Renames an existing bot called \035Elda\035 to \035Chii\035."
))
.AddEntry("CHANGE Chii Mahoro saint vesper.test Mahoro Andou", _(
"Changes all of the information of the bot called \035Chii\035. The new nickname "
"will be \035Mahoro\035, the new username will be \035saint\035, the new hostname "
"will be \035vesper.test\035, and the new realname will be \035Mahoro Andou\035."
))
.AddEntry("DEL Mahoro", _(
"Deletes a bot called \035Mahoro\035."
))
.SendTo(source);
return true;
}
};
+16 -2
View File
@@ -71,6 +71,13 @@ public:
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Makes the bot say the specified text on the specified channel."));
ExampleWrapper()
.AddEntry(_("#chat hello all"), _(
"Sends a message to \035#chat\035 saying \035hello all\035."
))
.SendTo(source);
return true;
}
};
@@ -126,9 +133,16 @@ public:
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_(
"Makes the bot do the equivalent of a \"/me\" command "
"on the specified channel using the specified text."
"Makes the bot do the equivalent of a \"/me\" command on the specified channel using "
"the specified text."
));
ExampleWrapper()
.AddEntry(_("#chat is eating pizza"), _(
"Sends an action message to \035#chat\035 saying \035is eating pizza\035."
))
.SendTo(source);
return true;
}
};
+15 -4
View File
@@ -58,7 +58,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::Format(Language::Translate(source.nc, bi->GetChannelCount(), N_("%u channel", "%u channels")), bi->GetChannelCount());
info[_("Used on")] = Anope::Format(source.Translate(bi->GetChannelCount(), N_("%u channel", "%u channels")), bi->GetChannelCount());
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
info.SendTo(source);
@@ -83,8 +83,8 @@ public:
source.Reply(CHAN_INFO_HEADER, ci->name.c_str());
info[_("Bot nick")] = ci->bi ? ci->bi->nick : _("not assigned yet");
Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
Anope::string enabled = source.Translate(_("Enabled"));
Anope::string disabled = source.Translate(_("Disabled"));
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
info.SendTo(source);
@@ -104,12 +104,23 @@ public:
"you'll get information about a bot, such as creation "
"time or number of channels it is on."
), source.service->nick.c_str());
ExampleWrapper()
.AddEntry("#example", _(
"Shows information about the bot assigned to \035#example\035 and its kickers and "
"options."
))
.AddEntry("ChanServ", _(
"Shows information about the \035ChanServ\035 bot."
))
.SendTo(source);
return true;
}
Anope::string GetDesc(CommandSource &source) const override
{
return Anope::Format(Language::Translate(source.GetAccount(), _("Allows you to see %s information about a channel or a bot")), source.service->nick.c_str());
return Anope::Format(source.Translate(_("Allows you to see %s information about a channel or a bot")), source.service->nick.c_str());
}
};
+30 -28
View File
@@ -51,7 +51,7 @@ struct KickerDataImpl final
if (s->GetSerializableType()->GetName() != CHANNELINFO_TYPE)
return;
const ChannelInfo *ci = anope_dynamic_static_cast<const ChannelInfo *>(e);
const auto *ci = anope_dynamic_static_cast<const ChannelInfo *>(e);
auto *kd = this->Get(ci);
if (kd == NULL)
return;
@@ -85,33 +85,35 @@ struct KickerDataImpl final
if (s->GetSerializableType()->GetName() != CHANNELINFO_TYPE)
return;
ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(e);
auto *ci = anope_dynamic_static_cast<ChannelInfo *>(e);
auto *kd = ci->Require<BotServ::KickerData>(BOTSERV_KICKER_DATA_EXT);
data["kickerdata:amsgs"] >> kd->amsgs;
data["kickerdata:badwords"] >> kd->badwords;
data["kickerdata:bolds"] >> kd->bolds;
data["kickerdata:caps"] >> kd->caps;
data["kickerdata:colors"] >> kd->colors;
data["kickerdata:flood"] >> kd->flood;
data["kickerdata:italics"] >> kd->italics;
data["kickerdata:repeat"] >> kd->repeat;
data["kickerdata:reverses"] >> kd->reverses;
data["kickerdata:underlines"] >> kd->underlines;
kd->amsgs = data.Load<bool>("kickerdata:amsgs");
kd->badwords = data.Load<bool>("kickerdata:badwords");
kd->bolds = data.Load<bool>("kickerdata:bolds");
kd->caps = data.Load<bool>("kickerdata:caps");
kd->colors = data.Load<bool>("kickerdata:colors");
kd->flood = data.Load<bool>("kickerdata:flood");
kd->italics = data.Load<bool>("kickerdata:italics");
kd->repeat = data.Load<bool>("kickerdata:repeat");
kd->reverses = data.Load<bool>("kickerdata:reverses");
kd->underlines = data.Load<bool>("kickerdata:underlines");
data["capsmin"] >> kd->capsmin;
data["capspercent"] >> kd->capspercent;
data["floodlines"] >> kd->floodlines;
data["floodsecs"] >> kd->floodsecs;
data["repeattimes"] >> kd->repeattimes;
data["dontkickops"] >> kd->dontkickops;
data["dontkickvoices"] >> kd->dontkickvoices;
kd->capsmin = data.Load<int16_t>("capsmin");
kd->capspercent = data.Load<int16_t>("capspercent");
kd->floodlines = data.Load<int16_t>("floodlines");
kd->floodsecs = data.Load<int16_t>("floodsecs");
kd->repeattimes = data.Load<int16_t>("repeattimes");
kd->dontkickops = data.Load<bool>("dontkickops");
kd->dontkickvoices = data.Load<bool>("dontkickvoices");
Anope::string ttb, tok;
data["ttb"] >> ttb;
spacesepstream sep(ttb);
for (int i = 0; sep.GetToken(tok) && i < BotServ::TTB_SIZE; ++i)
spacesepstream sep(data.Load("ttb"));
for (size_t i = 0; i < BotServ::TTB_SIZE; ++i)
{
Anope::string tok;
if (!sep.GetToken(tok))
break;
if (auto n = Anope::TryConvert<int16_t>(tok))
kd->ttb[i] = n.value();
}
@@ -988,7 +990,7 @@ public:
void purge()
{
time_t keepdata = Config->GetModule(me).Get<time_t>("keepdata");
for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
for (auto it = data_map.begin(), it_end = data_map.end(); it != it_end;)
{
const Anope::string &user = it->first;
Data &bd = it->second;
@@ -1038,7 +1040,7 @@ public:
for (auto &[_, c] : ChannelList)
{
BanData *bd = c->GetExt<BanData>("bandata");
auto *bd = c->GetExt<BanData>("bandata");
if (bd != NULL)
{
bd->purge();
@@ -1149,8 +1151,8 @@ public:
if (!ci)
return;
Anope::string enabled = Language::Translate(source.nc, _("Enabled"));
Anope::string disabled = Language::Translate(source.nc, _("Disabled"));
Anope::string enabled = source.Translate(_("Enabled"));
Anope::string disabled = source.Translate(_("Disabled"));
auto *kd = kickerdata.Get(ci);
if (kd && kd->badwords)
@@ -1488,7 +1490,7 @@ public:
if (ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
{
for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();)
for (auto it = u->chans.begin(); it != u->chans.end();)
{
Channel *chan = it->second->chan;
++it;
+7
View File
@@ -166,6 +166,13 @@ public:
"be removed after the given time. Set to 0 to disable bans from "
"automatically expiring."
));
ExampleWrapper()
.AddEntry("#wibble 15m", _(
"Sets bot bans on \035#wibble\035 to expire after \03515 minutes\035."
))
.SendTo(source);
return true;
}
};
+3 -4
View File
@@ -357,7 +357,7 @@ public:
if (!chanserv_expire || Anope::NoExpire || Anope::ReadOnly)
return;
for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; )
for (auto it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; )
{
ChannelInfo *ci = it->second;
++it;
@@ -369,7 +369,7 @@ public:
if (ci->c)
{
time_t last_used = ci->last_used;
for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
for (auto cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
ci->AccessFor(cit->second->user);
expire = last_used == ci->last_used;
}
@@ -397,11 +397,10 @@ public:
return EVENT_CONTINUE;
}
void OnUplinkSync(Server* s) override
void OnUplinkSync(Server *s) override
{
// We need to do this when the uplink is synced as we may not know if
// the mode exists before then on some IRCds (e.g. InspIRCd).
if (!persist)
return;
+56 -22
View File
@@ -23,6 +23,17 @@ static inline void reset_levels(ChannelInfo *ci)
ci->SetLevel(priv, level);
}
static Anope::string LevelToString(CommandSource &source, int16_t level)
{
if (level == ACCESS_INVALID)
return source.Translate(_("(disabled)"));
if (level == ACCESS_FOUNDER)
return source.Translate(_("(founder only)"));
return Anope::ToString(level);
}
class AccessChanAccess final
: public ChanAccess
{
@@ -276,7 +287,7 @@ private:
ServiceReference<AccessProvider> provider("AccessProvider", "access/access");
if (!provider)
return;
AccessChanAccess *access = anope_dynamic_static_cast<AccessChanAccess *>(provider->Create());
auto *access = anope_dynamic_static_cast<AccessChanAccess *>(provider->Create());
access->SetMask(mask, ci);
access->creator = source.GetNick();
access->level = level;
@@ -285,7 +296,7 @@ private:
access->description = description;
ci->AddAccess(access);
FOREACH_MOD(OnAccessAdd, (ci, source, access));
FOREACH_MOD(OnAccessAdd, (ci, source, access, false));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << " with level " << level;
if (p != NULL)
@@ -376,7 +387,7 @@ private:
ci->EraseAccess(Number - 1);
FOREACH_MOD(OnAccessDel, (ci, source, access));
FOREACH_MOD(OnAccessDel, (ci, source, access, false));
delete access;
}
}
@@ -402,7 +413,7 @@ private:
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->Mask();
ci->EraseAccess(i - 1);
FOREACH_MOD(OnAccessDel, (ci, source, access));
FOREACH_MOD(OnAccessDel, (ci, source, access, false));
delete access;
}
return;
@@ -416,6 +427,8 @@ private:
void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
{
const Anope::string &nick = params.size() > 2 ? params[2] : "";
const auto show_all = params.size() > 3 && params[3].equals_ci("ALL");
unsigned foreign = 0;
if (!ci->GetAccessCount())
source.Reply(_("%s access list is empty."), ci->name.c_str());
@@ -426,9 +439,16 @@ private:
{
ListFormatter &list;
ChannelInfo *ci;
bool show_all;
unsigned &foreign;
public:
AccessListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
AccessListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist, bool _show_all, unsigned &_foreign)
: NumberList(numlist, false)
, list(_list)
, ci(_ci)
, show_all(_show_all)
, foreign(_foreign)
{
}
@@ -438,11 +458,16 @@ private:
return;
const ChanAccess *access = ci->GetAccess(number - 1);
if (!show_all && access->provider->name != "access/access")
{
foreign++;
return;
}
AddEntry(this->list, ci, access, number);
}
}
nl_list(list, ci, nick);
nl_list(list, ci, nick, show_all, foreign);
nl_list.Process();
}
else
@@ -454,6 +479,12 @@ private:
if (!nick.empty() && !Anope::Match(access->Mask(), nick))
continue;
if (!show_all && access->provider->name != "access/access")
{
foreign++;
continue;
}
AddEntry(list, ci, access, i + 1);
}
}
@@ -466,6 +497,14 @@ private:
list.SendTo(source);
source.Reply(_("End of access list"));
}
if (foreign)
{
const auto full_command = Anope::Format("%s %s %s %s", source.command.c_str(),
ci->name.c_str(), params[1].upper().c_str(), nick.empty() ? "*" : nick.c_str()).nobreak();
source.Reply(foreign, CHAN_ACCESS_FOREIGN, foreign, full_command.c_str());
}
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -531,8 +570,8 @@ public:
this->SetDesc(_("Modify the list of privileged users"));
this->SetSyntax(_("\037channel\037 ADD \037mask\037 \037level\037 [\037description\037]"));
this->SetSyntax(_("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037] [ALL]"));
this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037list\037] [ALL]"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
@@ -635,7 +674,8 @@ public:
"The \002%s\033LIST\002 command displays the access list. If "
"a wildcard mask is given, only those entries matching the "
"mask are displayed. If a list of entry numbers is given, "
"only those entries are shown."
"only those entries are shown. The \002ALL\002 option allows "
"listing entries from other access systems as well as levels."
"\n\n"
"The \002%s\033VIEW\002 command displays the access list similar "
"to \002%s\033LIST\002 but shows the creator and last used time."
@@ -660,7 +700,7 @@ public:
BotInfo *bi;
Anope::string cmd;
if (Command::FindCommandFromService("chanserv/levels", bi, cmd))
if (Command::FindFromService("chanserv/levels", bi, cmd))
{
source.Reply(" ");
source.Reply(_(
@@ -768,14 +808,7 @@ class CommandCSLevels final
ListFormatter::ListEntry entry;
entry["Name"] = p.name;
if (j == ACCESS_INVALID)
entry["Level"] = Language::Translate(source.GetAccount(), _("(disabled)"));
else if (j == ACCESS_FOUNDER)
entry["Level"] = Language::Translate(source.GetAccount(), _("(founder only)"));
else
entry["Level"] = Anope::ToString(j);
entry["Level"] = LevelToString(source, j);
list.AddEntry(entry);
}
@@ -852,14 +885,15 @@ public:
source.Reply(_("The following feature/function names are available:"));
ListFormatter list(source.GetAccount());
list.AddColumn(_("Name")).AddColumn(_("Description"));
list.SetFlexible(_("\002{name}\002: {description}"));
list.AddColumn(_("Name")).AddColumn(_("Default")).AddColumn(_("Description"));
list.SetFlexible(_("\002{name}\002: defaults to {default} ({description})"));
for (const auto &p : PrivilegeManager::GetPrivileges())
{
ListFormatter::ListEntry entry;
entry["Name"] = p.name;
entry["Description"] = Language::Translate(source.nc, p.desc.c_str());
entry["Default"] = LevelToString(source, defaultLevels[p.name]);
entry["Description"] = source.Translate(p.desc.c_str());
list.AddEntry(entry);
}
@@ -960,7 +994,7 @@ public:
/* Access accessprovider is the only accessprovider with the concept of negative access,
* so check they don't have negative access
*/
const AccessChanAccess *aca = anope_dynamic_static_cast<const AccessChanAccess *>(highest);
const auto *aca = anope_dynamic_static_cast<const AccessChanAccess *>(highest);
if (aca->level < 0)
return EVENT_CONTINUE;
+20 -32
View File
@@ -143,46 +143,34 @@ struct AutoKickType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string sci, snc;
uint64_t sncid = 0;
data["ci"] >> sci;
data["nc"] >> snc; // Deprecated 2.0 field
data["ncid"] >> sncid;
ChannelInfo *ci = ChannelInfo::Find(sci);
auto *ci = ChannelInfo::Find(data.Load("ci"));
if (!ci)
return NULL;
const auto sncid = data.Load<uint64_t>("ncid");
auto *nc = sncid ? NickCore::FindId(sncid) : NickCore::Find(data.Load("nc"));
const auto screator = data.Load("creator");
const auto smask = data.Load("mask");
const auto sreason = data.Load("reason");
const auto saddtime = data.Load<time_t>("addtime");
const auto slastused = data.Load<time_t>("last_used");
ChanServ::AutoKick *ak;
auto *nc = sncid ? NickCore::FindId(sncid) : NickCore::Find(snc);
if (obj)
{
ak = anope_dynamic_static_cast<ChanServ::AutoKick *>(obj);
data["creator"] >> ak->creator;
data["reason"] >> ak->reason;
ak->creator = screator;
ak->reason = sreason;
ak->nc = nc;
data["mask"] >> ak->mask;
data["addtime"] >> ak->addtime;
data["last_used"] >> ak->last_used;
ak->mask = smask;
ak->addtime = saddtime;
ak->last_used = slastused;
}
else if (nc)
ak = ChanServ::akick_service->AddAKick(ci, screator, nc, sreason, saddtime, slastused);
else
{
time_t addtime, lastused;
data["addtime"] >> addtime;
data["last_used"] >> lastused;
Anope::string screator, sreason, smask;
data["creator"] >> screator;
data["reason"] >> sreason;
data["mask"] >> smask;
if (nc)
ak = ChanServ::akick_service->AddAKick(ci, screator, nc, sreason, addtime, lastused);
else
ak = ChanServ::akick_service->AddAKick(ci, screator, smask, sreason, addtime, lastused);
}
ak = ChanServ::akick_service->AddAKick(ci, screator, smask, sreason, saddtime, slastused);
return ak;
}
@@ -201,7 +189,7 @@ class CommandCSAKick final
return;
}
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
for (auto it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
auto *memb = it->second;
++it;
@@ -223,7 +211,7 @@ class CommandCSAKick final
const NickAlias *na = NickAlias::Find(mask);
NickCore *nc = NULL;
const ChanServ::AutoKick *akick;
unsigned reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
auto reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
if (reason.length() > reasonmax)
reason = reason.substr(0, reasonmax);
+2 -2
View File
@@ -128,7 +128,7 @@ public:
reason += " " + params[3];
}
unsigned reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
auto reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
if (reason.length() > reasonmax)
reason = reason.substr(0, reasonmax);
@@ -211,7 +211,7 @@ public:
}
int matched = 0, kicked = 0;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
for (auto it = c->users.begin(), it_end = c->users.end(); it != it_end;)
{
auto *memb = it->second;
++it;
+1 -1
View File
@@ -28,7 +28,7 @@ class CommandCSClone final
static void CopyAccess(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
{
std::set<Anope::string> masks;
unsigned access_max = Config->GetModule("chanserv").Get<unsigned>("accessmax", "1000");
auto access_max = Config->GetModule("chanserv").Get<unsigned>("accessmax", "1000");
unsigned count = 0;
for (unsigned i = 0; i < target_ci->GetAccessCount(); ++i)
+6 -6
View File
@@ -64,7 +64,7 @@ private:
for (auto *user : users)
{
Anope::string mask = ci->GetIdealBan(user);
Anope::string reason = Language::Translate(user, _("RESTRICTED enforced by ")) + source.GetNick();
Anope::string reason = Anope::Format(Language::Translate(user, _("RESTRICTED enforced by %s")), source.GetNick().c_str());
ci->c->SetMode(NULL, "BAN", mask);
ci->c->Kick(NULL, user, reason);
}
@@ -92,7 +92,7 @@ private:
for (auto *user : users)
{
Anope::string mask = ci->GetIdealBan(user);
Anope::string reason = Language::Translate(user, _("REGONLY enforced by ")) + source.GetNick();
Anope::string reason = Anope::Format(Language::Translate(user, _("REGONLY enforced by %s")), source.GetNick().c_str());
if (!ci->c->HasMode("REGISTEREDONLY"))
ci->c->SetMode(NULL, "BAN", mask);
ci->c->Kick(NULL, user, reason);
@@ -121,7 +121,7 @@ private:
for (auto *user : users)
{
Anope::string mask = ci->GetIdealBan(user);
Anope::string reason = Language::Translate(user, _("SSLONLY enforced by ")) + source.GetNick();
Anope::string reason = Anope::Format(Language::Translate(user, _("SSLONLY enforced by %s")), source.GetNick().c_str());
if (!ci->c->HasMode("SSL"))
ci->c->SetMode(NULL, "BAN", mask);
ci->c->Kick(NULL, user, reason);
@@ -149,7 +149,7 @@ private:
for (auto *user : users)
{
Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick();
Anope::string reason = Anope::Format(Language::Translate(user, _("BANS enforced by %s")), source.GetNick().c_str());
ci->c->Kick(NULL, user, reason);
}
@@ -177,7 +177,7 @@ private:
std::vector<User *> users;
/* The newer users are at the end of the list, so kick users starting from the end */
for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
for (auto it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
{
auto *memb = it->second;
User *user = memb->user;
@@ -197,7 +197,7 @@ private:
for (auto *user : users)
{
Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick();
Anope::string reason = Anope::Format(Language::Translate(user, _("LIMIT enforced by %s")), source.GetNick().c_str());
ci->c->Kick(NULL, user, reason);
}
+8 -15
View File
@@ -85,31 +85,24 @@ EntryMsgImpl::~EntryMsgImpl()
Serializable *EntryMsgTypeImpl::Unserialize(Serializable *obj, Serialize::Data &data) const
{
Anope::string sci, screator, smessage;
time_t swhen;
data["ci"] >> sci;
data["creator"] >> screator;
data["message"] >> smessage;
ChannelInfo *ci = ChannelInfo::Find(sci);
auto *ci = ChannelInfo::Find(data.Load("ci"));
if (!ci)
return NULL;
const auto screator = data.Load("creator");
const auto smessage = data.Load("message");
const auto swhen = data.Load<time_t>("when");
if (obj)
{
EntryMsgImpl *msg = anope_dynamic_static_cast<EntryMsgImpl *>(obj);
auto *msg = anope_dynamic_static_cast<EntryMsgImpl *>(obj);
msg->chan = ci->name;
data["creator"] >> msg->creator;
data["message"] >> msg->message;
data["when"] >> msg->when;
msg->creator = screator;
msg->message = smessage;
msg->when = swhen;
return msg;
}
auto *messages = ci->Require<ChanServ::EntryMessageList>(CHANSERV_ENTRY_MESSAGE_EXT);
data["when"] >> swhen;
auto *m = new EntryMsgImpl(ci, screator, smessage, swhen);
(*messages)->push_back(m);
return m;
+1 -1
View File
@@ -86,7 +86,7 @@ public:
void OnReload(Configuration::Conf &conf) override
{
const auto &block = conf.GetModule("chanstats");
prefix = block.Get<const Anope::string>("prefix", "anope_");
prefix = block.Get<const Anope::string>("prefix", "chanstats21_");
this->sql.SetServiceName(block.Get<const Anope::string>("engine"));
}
+1 -1
View File
@@ -114,7 +114,7 @@ public:
void OnReload(Configuration::Conf &conf) override
{
const auto &block = conf.GetModule("chanstats");
prefix = block.Get<const Anope::string>("prefix", "anope_");
prefix = block.Get<const Anope::string>("prefix", "chanstats21_");
this->sql.SetServiceName(block.Get<const Anope::string>("engine"));
}
+101 -7
View File
@@ -28,7 +28,7 @@ public:
bool HasPriv(const Anope::string &priv) const override
{
std::map<Anope::string, char>::iterator it = defaultFlags.find(priv);
auto it = defaultFlags.find(priv);
return it != defaultFlags.end() && this->flags.count(it->second) > 0;
}
@@ -286,7 +286,7 @@ class CommandCSFlags final
if (current != NULL)
{
ci->EraseAccess(current_idx - 1);
FOREACH_MOD(OnAccessDel, (ci, source, current));
FOREACH_MOD(OnAccessDel, (ci, source, current, false));
delete current;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
source.Reply(_("\002%s\002 removed from the %s access list."), mask.c_str(), ci->name.c_str());
@@ -301,7 +301,7 @@ class CommandCSFlags final
ServiceReference<AccessProvider> provider("AccessProvider", "access/flags");
if (!provider)
return;
FlagsChanAccess *access = anope_dynamic_static_cast<FlagsChanAccess *>(provider->Create());
auto *access = anope_dynamic_static_cast<FlagsChanAccess *>(provider->Create());
access->SetMask(mask, ci);
access->creator = source.GetNick();
access->description = current ? current->description : description;
@@ -314,7 +314,7 @@ class CommandCSFlags final
ci->AddAccess(access);
FOREACH_MOD(OnAccessAdd, (ci, source, access));
FOREACH_MOD(OnAccessAdd, (ci, source, access, false));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to modify " << mask << "'s flags to " << access->AccessSerialize();
if (p != NULL)
@@ -331,6 +331,7 @@ class CommandCSFlags final
static void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
const Anope::string &arg = params.size() > 2 ? params[2] : "";
const auto show_all = params.size() > 3 && params[3].equals_ci("ALL");
if (!ci->GetAccessCount())
{
@@ -348,6 +349,7 @@ class CommandCSFlags final
});
unsigned count = 0;
unsigned foreign = 0;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
const ChanAccess *access = ci->GetAccess(i);
@@ -368,6 +370,12 @@ class CommandCSFlags final
continue;
}
if (!show_all && access->provider->name != "access/flags")
{
foreign++;
continue;
}
ListFormatter::ListEntry entry;
++count;
entry["Number"] = Anope::ToString(i + 1);
@@ -390,6 +398,88 @@ class CommandCSFlags final
else
source.Reply(_("End of access list - %d/%d entries shown."), count, ci->GetAccessCount());
}
if (foreign)
{
const auto full_command = Anope::Format("%s %s LIST %s", source.command.c_str(),
ci->name.c_str(), arg.empty() ? "*" : arg.c_str()).nobreak();
source.Reply(foreign, CHAN_ACCESS_FOREIGN, foreign, full_command.c_str());
}
}
void DoMigrate(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
auto override = false;
const auto source_access = source.AccessFor(ci);
unsigned migrated = 0, notmigrated = 0;
Anope::string migratedmask, notmigratedmask;
const auto &entry = params.size() > 2 ? params[2] : "*";
for (auto idx = ci->GetAccessCount(); idx > 0; --idx)
{
auto *access = ci->GetAccess(idx - 1);
if (access->provider->name == "access/flags")
continue; // Already using flags.
if (!Anope::Match(access->Mask(), entry))
continue; // Not this entry.
std::set<char> newflags;
for (auto &[priv, flag] : defaultFlags)
{
if (access->HasPriv(priv))
continue; // Source doesn't have this flag.
// Check that the source has access to set this entry.
if (!override && !source_access.HasPriv(priv) && !source_access.founder)
{
if (!source.HasPriv("chanserv/access/modify"))
{
notmigrated++;
notmigratedmask = access->Mask();
continue; // No privs
}
override = true;
}
newflags.insert(flag);
}
migrated++;
migratedmask = access->Mask();
auto *newaccess = anope_dynamic_static_cast<FlagsChanAccess *>(FlagsAccessProvider::ap->Create());
newaccess->SetMask(access->Mask(), ci);
newaccess->creator = access->creator;
newaccess->description = access->description;
newaccess->created = access->created;
newaccess->flags = newflags;
ci->EraseAccess(idx - 1);
FOREACH_MOD(OnAccessDel, (ci, source, access, true));
delete access;
ci->AddAccess(newaccess);
FOREACH_MOD(OnAccessAdd, (ci, source, newaccess, true));
}
if (migrated == 1)
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to migrate " << migratedmask;
source.Reply(CHAN_ACCESS_MIGRATED_1, migratedmask.c_str(), source.command.nobreak().c_str());
}
else if (migrated > 1)
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to migrate " << migrated << " access entries";
source.Reply(migrated, CHAN_ACCESS_MIGRATED_N, migrated, source.command.nobreak().c_str());
}
if (notmigrated == 1)
source.Reply(CHAN_ACCESS_NOT_MIGRATED_1, notmigratedmask.c_str(), source.command.nobreak().c_str());
else if (notmigrated > 1)
source.Reply(migrated, CHAN_ACCESS_NOT_MIGRATED_N, notmigrated, source.command.nobreak().c_str());
}
void DoClear(CommandSource &source, ChannelInfo *ci)
@@ -414,7 +504,8 @@ public:
{
this->SetDesc(_("Modify the list of privileged users"));
this->SetSyntax(_("\037channel\037 [MODIFY] \037mask\037 \037changes\037 [\037description\037]"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | +\037flags\037]"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | +\037flags\037] [ALL]"));
this->SetSyntax(_("\037channel\037 MIGRATE [\037mask\037]"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
@@ -447,6 +538,8 @@ public:
source.Reply(READ_ONLY_MODE);
else if (is_list)
this->DoList(source, ci, params);
else if (cmd.equals_ci("MIGRATE"))
this->DoMigrate(source, ci, params);
else if (cmd.equals_ci("CLEAR"))
this->DoClear(source, ci);
else
@@ -487,7 +580,8 @@ public:
"The \002LIST\002 command allows you to list existing entries on the channel access list. "
"If a mask is given, the mask is wildcard matched against all existing entries on the "
"access list, and only those entries are returned. If a set of flags is given, only those "
"on the access list with the specified flags are returned."
"on the access list with the specified flags are returned. The \002ALL\002 option allows "
"listing entries from other access systems as well as flags."
"\n\n"
"The \002CLEAR\002 command clears the channel access list. This requires channel founder access."
"\n\n"
@@ -505,7 +599,7 @@ public:
Privilege *p = PrivilegeManager::FindPrivilege(priv);
if (p == NULL)
continue;
source.Reply(" %c - %s", flag, Language::Translate(source.nc, p->desc.c_str()));
source.Reply(" %c - %s", flag, source.Translate(p->desc.c_str()));
}
return true;
+2 -2
View File
@@ -47,7 +47,7 @@ public:
return;
}
unsigned reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
auto reasonmax = Config->GetModule("chanserv").Get<unsigned>("reasonmax", "200");
if (reason.length() > reasonmax)
reason = reason.substr(0, reasonmax);
@@ -90,7 +90,7 @@ public:
Log(LOG_COMMAND, source, this, ci) << "for " << mask;
int matched = 0, kicked = 0;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
for (auto it = c->users.begin(), it_end = c->users.end(); it != it_end;)
{
auto *memb = it->second;
++it;
+3 -3
View File
@@ -73,7 +73,7 @@ public:
}
Anope::string spattern = "#" + pattern;
unsigned listmax = Config->GetModule(this->owner).Get<unsigned>("listmax", "50");
auto listmax = Config->GetModule(this->owner).Get<unsigned>("listmax", "50");
source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
@@ -122,7 +122,7 @@ public:
ListFormatter::ListEntry entry;
entry["Name"] = (isnoexpire ? "!" : "") + ci->name;
if (ci->HasExt("CS_SUSPENDED"))
entry["Description"] = Language::Translate(source.GetAccount(), _("[Suspended]"));
entry["Description"] = source.Translate(_("[Suspended]"));
else
entry["Description"] = ci->desc;
list.AddEntry(entry);
@@ -245,7 +245,7 @@ public:
BotInfo *bi;
Anope::string cmd;
if (Command::FindCommandFromService("chanserv/list", bi, cmd))
if (Command::FindFromService("chanserv/list", bi, cmd))
{
source.Reply(_("When \002private\002 is set, the channel will not appear in %s's %s command."),
bi->nick.c_str(), cmd.c_str());
+8 -11
View File
@@ -64,10 +64,7 @@ struct LogSettingTypeImpl final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string sci;
data["ci"] >> sci;
ChannelInfo *ci = ChannelInfo::Find(sci);
auto *ci = ChannelInfo::Find(data.Load("ci"));
if (ci == NULL)
return NULL;
@@ -82,13 +79,13 @@ struct LogSettingTypeImpl final
}
ls->chan = ci->name;
data["service_name"] >> ls->service_name;
data["command_service"] >> ls->command_service;
data["command_name"] >> ls->command_name;
data["method"] >> ls->method;
data["extra"] >> ls->extra;
data["creator"] >> ls->creator;
data["created"] >> ls->created;
ls->service_name = data.Load("service_name");
ls->command_service = data.Load("command_service");
ls->command_name = data.Load("command_name");
ls->method = data.Load("method");
ls->extra = data.Load("extra");
ls->creator = data.Load("creator");
ls->created = data.Load<time_t>("created");
return ls;
}
+10 -14
View File
@@ -270,11 +270,7 @@ void ModeLockTypeImpl::Serialize(Serializable *obj, Serialize::Data &data) const
Serializable *ModeLockTypeImpl::Unserialize(Serializable *obj, Serialize::Data &data) const
{
Anope::string sci;
data["ci"] >> sci;
ChannelInfo *ci = ChannelInfo::Find(sci);
auto *ci = ChannelInfo::Find(data.Load("ci"));
if (!ci)
return NULL;
@@ -287,11 +283,11 @@ Serializable *ModeLockTypeImpl::Unserialize(Serializable *obj, Serialize::Data &
ml->ci = ci->name;
}
data["set"] >> ml->set;
data["created"] >> ml->created;
data["setter"] >> ml->setter;
data["name"] >> ml->name;
data["param"] >> ml->param;
ml->set = data.Load<bool>("set");
ml->created = data.Load<time_t>("created");
ml->setter = data.Load("setter");
ml->name = data.Load("name");
ml->param = data.Load("param");
if (!obj)
ci->Require<ModeLocksImpl>(CHANSERV_MODE_LOCK_EXT)->mlocks->push_back(ml);
@@ -601,7 +597,7 @@ class CommandCSMode final
}
}
for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
for (auto it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
{
auto *memb = it->second;
++it;
@@ -949,9 +945,9 @@ public:
if (!m.second.empty())
{
if (m.first)
return Anope::Format(Language::Translate(source.GetAccount(), _("Gives you or the specified nick %s status on a channel")), m.second.c_str());
return Anope::Format(source.Translate(_("Gives you or the specified nick %s status on a channel")), m.second.c_str());
else
return Anope::Format(Language::Translate(source.GetAccount(), _("Removes %s status from you or the specified nick on a channel")), m.second.c_str());
return Anope::Format(source.Translate(_("Removes %s status from you or the specified nick on a channel")), m.second.c_str());
}
else
return "";
@@ -1102,7 +1098,7 @@ public:
Anope::string param;
if (cm->type == MODE_PARAM)
{
ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
auto *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
if (add || !cmp->minus_no_arg)
{
sep.GetToken(param);
+2 -2
View File
@@ -28,7 +28,7 @@ public:
{
const Anope::string &chan = params[0];
const Anope::string &chdesc = params.size() > 1 ? params[1] : "";
unsigned maxregistered = Config->GetModule("chanserv").Get<unsigned>("maxregistered");
auto maxregistered = Config->GetModule("chanserv").Get<unsigned>("maxregistered");
User *u = source.GetUser();
NickCore *nc = source.nc;
@@ -105,7 +105,7 @@ public:
BotInfo *bi;
Anope::string cmd;
if (Command::FindCommandFromService("chanserv/access", bi, cmd))
if (Command::FindFromService("chanserv/access", bi, cmd))
{
source.Reply(" ");
source.Reply(_(
+15 -19
View File
@@ -41,7 +41,7 @@ struct SeenInfo final
~SeenInfo() override
{
database_map::iterator iter = database.find(nick);
auto iter = database.find(nick);
if (iter != database.end() && iter->second == this)
database.erase(iter);
}
@@ -111,9 +111,7 @@ struct SeenInfoType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string snick;
data["nick"] >> snick;
const auto snick = data.Load("nick");
SeenInfo *s;
if (obj)
@@ -127,14 +125,12 @@ struct SeenInfoType final
}
s->nick = snick;
data["vhost"] >> s->vhost;
Anope::string n;
data["type"] >> n;
s->type = StringToType(n);
data["nick2"] >> s->nick2;
data["channel"] >> s->channel;
data["message"] >> s->message;
data["last"] >> s->last;
s->vhost = data.Load("vhost");
s->type = StringToType(data.Load("type"));
s->nick2 = data.Load("nick2");
s->channel = data.Load("channel");
s->message = data.Load("message");
s->last = data.Load<time_t>("last");
if (!obj)
database[s->nick] = s;
@@ -144,7 +140,7 @@ struct SeenInfoType final
static SeenInfo *FindInfo(const Anope::string &nick)
{
database_map::iterator iter = database.find(nick);
auto iter = database.find(nick);
if (iter != database.end())
return iter->second;
return NULL;
@@ -203,7 +199,7 @@ public:
time = Anope::CurTime - time;
database_map::iterator buf;
size_t counter = 0;
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
for (auto it = database.begin(), it_end = database.end(); it != it_end;)
{
buf = it;
++it;
@@ -285,7 +281,7 @@ public:
if (u2)
onlinestatus = ".";
else
onlinestatus = Anope::Format(Language::Translate(source.nc, _(" but %s mysteriously dematerialized.")), target.c_str());
onlinestatus = Anope::Format(source.Translate(_(" but %s mysteriously dematerialized.")), target.c_str());
Anope::string timebuf = Anope::Duration(Anope::CurTime - info->last, source.nc);
Anope::string timebuf2 = Anope::strftime(info->last, source.nc, true);
@@ -299,9 +295,9 @@ public:
{
u2 = User::Find(info->nick2, true);
if (u2)
onlinestatus = Anope::Format(Language::Translate(source.nc, _(". %s is still online.")), u2->nick.c_str());
onlinestatus = Anope::Format(source.Translate(_(". %s is still online.")), u2->nick.c_str());
else
onlinestatus = Anope::Format(Language::Translate(source.nc, _(", but %s mysteriously dematerialized.")), info->nick2.c_str());
onlinestatus = Anope::Format(source.Translate(_(", but %s mysteriously dematerialized.")), info->nick2.c_str());
source.Reply(_("%s (%s) was last seen changing nick to %s %s ago%s"),
target.c_str(), info->vhost.c_str(), info->nick2.c_str(), timebuf.c_str(), onlinestatus.c_str());
@@ -379,9 +375,9 @@ public:
return;
auto previous_size = database.size();
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
for (auto it = database.begin(), it_end = database.end(); it != it_end;)
{
database_map::iterator cur = it;
auto cur = it;
++it;
if ((Anope::CurTime - cur->second->last) > purgetime)
+7 -7
View File
@@ -320,7 +320,7 @@ public:
}
NickCore *nc = na->nc;
unsigned max_reg = Config->GetModule("chanserv").Get<unsigned>("maxregistered");
auto max_reg = Config->GetModule("chanserv").Get<unsigned>("maxregistered");
if (max_reg && nc->channelcount >= max_reg && !source.HasPriv("chanserv/no-register-limit"))
{
source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
@@ -1018,7 +1018,7 @@ public:
"channel will be dropped."
));
unsigned max_reg = Config->GetModule("chanserv").Get<unsigned>("maxregistered");
auto max_reg = Config->GetModule("chanserv").Get<unsigned>("maxregistered");
if (max_reg)
{
source.Reply(" ");
@@ -1112,7 +1112,7 @@ class CSSet final
if (s->GetSerializableType()->GetName() != CHANNELINFO_TYPE)
return;
const ChannelInfo *ci = anope_dynamic_static_cast<const ChannelInfo *>(s);
const auto *ci = anope_dynamic_static_cast<const ChannelInfo *>(s);
Anope::string modes;
for (const auto &[last_mode, last_data] : ci->last_modes)
{
@@ -1138,11 +1138,11 @@ class CSSet final
if (s->GetSerializableType()->GetName() != CHANNELINFO_TYPE)
return;
ChannelInfo *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
Anope::string modes;
data["last_modes"] >> modes;
auto *ci = anope_dynamic_static_cast<ChannelInfo *>(s);
ci->last_modes.clear();
for (spacesepstream sep(modes); sep.GetToken(modes);)
spacesepstream sep(data.Load("last_modes"));
for (Anope::string modes; sep.GetToken(modes);)
{
if (modes[0] == '+')
{
+9 -12
View File
@@ -77,23 +77,20 @@ struct CSMiscDataType
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string sci, sname, sdata;
data["ci"] >> sci;
data["name"] >> sname;
data["data"] >> sdata;
ChannelInfo *ci = ChannelInfo::Find(sci);
auto *ci = ChannelInfo::Find(data.Load("ci"));
if (ci == NULL)
return NULL;
const auto sname = data.Load("name");
const auto sdata = data.Load("data");
CSMiscData *d = NULL;
if (obj)
{
d = anope_dynamic_static_cast<CSMiscData *>(obj);
d->object = ci->name;
data["name"] >> d->name;
data["data"] >> d->data;
d->name = sname;
d->data = sdata;
}
else
{
@@ -225,7 +222,7 @@ public:
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply("%s", Language::Translate(source.nc, it->second.description.c_str()));
source.Reply("%s", source.Translate(it->second.description.c_str()));
return true;
}
return false;
@@ -240,8 +237,8 @@ public:
this->ClearSyntax();
this->SetSyntax(Anope::Format(
Language::Translate(source.nc, _("\037channel\037 [\037%s\037]")),
Language::Translate(source.nc, value)
source.Translate(_("\037channel\037 [\037%s\037]")),
source.Translate(value)
));
Command::SendSyntax(source);
+6 -6
View File
@@ -18,9 +18,9 @@ class StatusUpdate final
: public Module
{
private:
void OnAccessChange(ChannelInfo *ci, ChanAccess *access, bool adding)
void OnAccessChange(ChannelInfo *ci, ChanAccess *access, bool migrated, bool adding)
{
if (!ci->c)
if (!ci->c || migrated)
return;
for (const auto &[_, uc] : ci->c->users)
@@ -50,14 +50,14 @@ public:
{
}
void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access) override
void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access, bool migrated) override
{
OnAccessChange(ci, access, true);
OnAccessChange(ci, access, migrated, true);
}
void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access) override
void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access, bool migrated) override
{
OnAccessChange(ci, access, false);
OnAccessChange(ci, access, migrated, false);
}
};
+9 -12
View File
@@ -42,25 +42,22 @@ struct CSSuspendInfoType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string schan;
data["chan"] >> schan;
CSSuspendInfo *si;
if (obj)
si = anope_dynamic_static_cast<CSSuspendInfo *>(obj);
else
{
ChannelInfo *ci = ChannelInfo::Find(schan);
auto *ci = ChannelInfo::Find(data.Load("chan"));
if (!ci)
return NULL;
si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
data["chan"] >> si->what;
si->what = ci->name;
}
data["by"] >> si->by;
data["reason"] >> si->reason;
data["time"] >> si->when;
data["expires"] >> si->expires;
si->by = data.Load("by");
si->reason = data.Load("reason");
si->when = data.Load<time_t>("time");
si->expires = data.Load<time_t>("expires");
return si;
}
};
@@ -116,7 +113,7 @@ public:
for (auto idx = reason_idx; idx < params.size(); ++idx)
reason.append(reason.empty() ? "" : " ").append(params[idx]);
CSSuspendInfo *si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
auto *si = ci->Extend<CSSuspendInfo>("CS_SUSPENDED");
si->what = ci->name;
si->by = source.GetNick();
si->reason = reason;
@@ -186,7 +183,7 @@ public:
}
/* Only UNSUSPEND already suspended channels */
CSSuspendInfo *si = ci->GetExt<CSSuspendInfo>("CS_SUSPENDED");
auto *si = ci->GetExt<CSSuspendInfo>("CS_SUSPENDED");
if (!si)
{
source.Reply(_("Channel \002%s\002 isn't suspended."), ci->name.c_str());
@@ -254,7 +251,7 @@ public:
void OnReload(Configuration::Conf &conf) override
{
Anope::string s = conf.GetModule(this).Get<Anope::string>("show");
auto s = conf.GetModule(this).Get<Anope::string>("show");
commasepstream(s).GetTokens(show);
std::transform(show.begin(), show.end(), show.begin(), trim());
}
+2 -2
View File
@@ -58,7 +58,7 @@ public:
{
if (!source.GetUser())
return;
for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
for (auto it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
{
Channel *c = it->second->chan;
SetModes(source.GetUser(), c);
@@ -162,7 +162,7 @@ public:
{
if (!source.GetUser())
return;
for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
for (auto it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
{
Channel *c = it->second->chan;
RemoveAll(source.GetUser(), c);
+11 -11
View File
@@ -32,7 +32,7 @@ public:
bool HasPriv(const Anope::string &priv) const override
{
for (std::vector<Anope::string>::iterator it = std::find(order.begin(), order.end(), this->type); it != order.end(); ++it)
for (auto it = std::find(order.begin(), order.end(), this->type); it != order.end(); ++it)
{
const std::vector<Anope::string> &privs = permissions[*it];
if (std::find(privs.begin(), privs.end(), priv) != privs.end())
@@ -55,7 +55,7 @@ public:
{
if (access->provider->name == "access/xop")
{
const XOPChanAccess *xaccess = anope_dynamic_static_cast<const XOPChanAccess *>(access);
const auto *xaccess = anope_dynamic_static_cast<const XOPChanAccess *>(access);
return xaccess->type;
}
else
@@ -128,7 +128,7 @@ private:
bool override = false;
const NickAlias *na = NULL;
std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
auto cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
if (!access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
@@ -252,7 +252,7 @@ private:
ServiceReference<AccessProvider> provider("AccessProvider", "access/xop");
if (!provider)
return;
XOPChanAccess *acc = anope_dynamic_static_cast<XOPChanAccess *>(provider->Create());
auto *acc = anope_dynamic_static_cast<XOPChanAccess *>(provider->Create());
acc->SetMask(mask, ci);
acc->creator = source.GetNick();
acc->description = description;
@@ -263,7 +263,7 @@ private:
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask;
FOREACH_MOD(OnAccessAdd, (ci, source, acc));
FOREACH_MOD(OnAccessAdd, (ci, source, acc, false));
source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask().c_str(), ci->name.c_str(), source.command.nobreak().c_str());
}
@@ -311,7 +311,7 @@ private:
}
}
std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
auto cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
if (!mask.equals_ci(nc->display) && !access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
@@ -372,7 +372,7 @@ private:
nicks += caccess->Mask();
ci->EraseAccess(number - 1);
FOREACH_MOD(OnAccessDel, (ci, source, caccess));
FOREACH_MOD(OnAccessDel, (ci, source, caccess, false));
delete caccess;
}
}
@@ -395,7 +395,7 @@ private:
source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->name.c_str(), source.command.nobreak().c_str());
ci->EraseAccess(i);
FOREACH_MOD(OnAccessDel, (ci, source, a));
FOREACH_MOD(OnAccessDel, (ci, source, a, false));
delete a;
return;
@@ -543,7 +543,7 @@ public:
Anope::string GetDesc(CommandSource &source) const override
{
return Anope::Format(Language::Translate(source.GetAccount(), _("Modify the list of %s users")), source.command.nobreak().c_str());
return Anope::Format(source.Translate(_("Modify the list of %s users")), source.command.nobreak().c_str());
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
@@ -636,8 +636,8 @@ public:
BotInfo *access_bi, *flags_bi;
Anope::string access_cmd, flags_cmd;
Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
Command::FindCommandFromService("chanserv/flags", flags_bi, flags_cmd);
Command::FindFromService("chanserv/access", access_bi, access_cmd);
Command::FindFromService("chanserv/flags", flags_bi, flags_cmd);
if (!access_cmd.empty() || !flags_cmd.empty())
{
source.Reply(_("Alternative methods of modifying channel access lists are available."));
+5 -5
View File
@@ -235,7 +235,7 @@ class MChanstats final
for (int i = 0; i < r.Rows(); ++i)
{
const std::map<Anope::string, Anope::string> &map = r.Row(i);
for (std::map<Anope::string, Anope::string>::const_iterator it = map.begin(); it != map.end(); ++it)
for (auto it = map.begin(); it != map.end(); ++it)
TableList.push_back(it->second);
}
query = "SHOW PROCEDURE STATUS WHERE `Db` = Database();";
@@ -254,7 +254,7 @@ class MChanstats final
bool HasTable(const Anope::string &table)
{
for (std::vector<Anope::string>::const_iterator it = TableList.begin(); it != TableList.end(); ++it)
for (auto it = TableList.begin(); it != TableList.end(); ++it)
if (*it == table)
return true;
return false;
@@ -262,7 +262,7 @@ class MChanstats final
bool HasProcedure(const Anope::string &table)
{
for (std::vector<Anope::string>::const_iterator it = ProcedureList.begin(); it != ProcedureList.end(); ++it)
for (auto it = ProcedureList.begin(); it != ProcedureList.end(); ++it)
if (*it == table)
return true;
return false;
@@ -270,7 +270,7 @@ class MChanstats final
bool HasEvent(const Anope::string &table)
{
for (std::vector<Anope::string>::const_iterator it = EventList.begin(); it != EventList.end(); ++it)
for (auto it = EventList.begin(); it != EventList.end(); ++it)
if (*it == table)
return true;
return false;
@@ -509,7 +509,7 @@ public:
void OnReload(Configuration::Conf &conf) override
{
const auto &block = conf.GetModule(this);
prefix = block.Get<const Anope::string>("prefix", "anope_");
prefix = block.Get<const Anope::string>("prefix", "chanstats21_");
SmileysHappy = block.Get<const Anope::string>("SmileysHappy");
SmileysSad = block.Get<const Anope::string>("SmileysSad");
SmileysOther = block.Get<const Anope::string>("SmileysOther");
+1 -1
View File
@@ -253,7 +253,7 @@ private:
}
}
void ApplyFlags(Extensible *ext, Anope::string &flags, char flag, const char* extname, bool extend = true)
void ApplyFlags(Extensible *ext, Anope::string &flags, char flag, const char *extname, bool extend = true)
{
auto pos = flags.find(flag);
auto has_flag = (pos != Anope::string::npos);
+8 -5
View File
@@ -21,7 +21,6 @@ public:
std::fstream *fs;
Serializable::Id id = 0;
std::map<Anope::string, Anope::string> data;
std::stringstream ss;
bool read = false;
LoadData(std::fstream &fsref)
@@ -29,7 +28,7 @@ public:
{
}
std::iostream &operator[](const Anope::string &key) override
bool LoadInternal(const Anope::string &key, Anope::string &value) override
{
if (!read)
{
@@ -51,9 +50,13 @@ public:
read = true;
}
ss.clear();
this->ss << this->data[key];
return this->ss;
value = this->data[key];
return true;
}
bool StoreInternal(const Anope::string &key, const Anope::string &value) override
{
return false; // This module can only load data.
}
size_t Hash() const override
+36 -15
View File
@@ -38,7 +38,7 @@ public:
Serializable::Id id = 0;
// Data in this database entry.
Anope::map<std::stringstream> data;
Anope::unordered_map<Anope::string> data;
// Used when writing data.
Data(Serialize::Type *s_type, Serializable *obj)
@@ -58,7 +58,7 @@ public:
if (yyjson_get_type(key) != YYJSON_TYPE_STR)
continue;
auto akey = yyjson_get_astr(key);
const auto akey = yyjson_get_astr(key);
if (akey.equals_ci("@id"))
{
this->id = yyjson_get_uint(value);
@@ -66,23 +66,28 @@ public:
}
if (yyjson_is_bool(value))
data[akey] << yyjson_get_bool(value);
data[akey] = Anope::ToString(yyjson_get_bool(value));
else if (yyjson_is_int(value))
data[akey] << yyjson_get_int(value);
data[akey] = Anope::ToString(yyjson_get_int(value));
else if (yyjson_is_null(value))
data[akey];
else if (yyjson_is_real(value))
data[akey] << yyjson_get_real(value);
data[akey] = Anope::ToString(yyjson_get_real(value));
else if (yyjson_is_str(value))
data[akey] << yyjson_get_astr(value);
data[akey] = Anope::ToString(yyjson_get_astr(value));
else if (yyjson_is_uint(value))
data[akey] << yyjson_get_uint(value);
data[akey] = Anope::ToString(yyjson_get_uint(value));
}
}
std::iostream &operator[](const Anope::string &key) override
bool LoadInternal(const Anope::string &key, Anope::string &value) override
{
return data[key];
auto it = this->data.find(key);
if (it == this->data.end())
return false;
value = it->second;
return true;
}
size_t Hash() const override
@@ -96,6 +101,12 @@ public:
}
return hash;
}
bool StoreInternal(const Anope::string &key, const Anope::string &value) override
{
this->data[key] = value;
return true;
}
};
class DBJSON final
@@ -318,22 +329,23 @@ private:
switch (data.GetType(key))
{
case Serialize::DataType::BOOL:
v = yyjson_mut_bool(doc, Anope::Convert<bool>(value.str(), false));
v = yyjson_mut_bool(doc, Anope::Convert<bool>(value, false));
break;
case Serialize::DataType::FLOAT:
v = yyjson_mut_real(doc, Anope::Convert<double>(value.str(), 0.0));
v = yyjson_mut_real(doc, Anope::Convert<double>(value, 0.0));
break;
case Serialize::DataType::INT:
v = yyjson_mut_int(doc, Anope::Convert<int64_t>(value.str(), 0));
v = yyjson_mut_int(doc, Anope::Convert<int64_t>(value, 0));
break;
case Serialize::DataType::TEXT:
{
auto str = value.str();
v = str.empty() ? yyjson_mut_null(doc) : yyjson_mut_strncpy(doc, str.c_str(), str.length());
v = value.empty()
? yyjson_mut_null(doc)
: yyjson_mut_strncpy(doc, value.c_str(), value.length());
break;
}
case Serialize::DataType::UINT:
v = yyjson_mut_uint(doc, Anope::Convert<uint64_t>(value.str(), 0));
v = yyjson_mut_uint(doc, Anope::Convert<uint64_t>(value, 0));
break;
}
@@ -400,9 +412,18 @@ public:
// Step 2: store the new data.
for (auto *item : Serializable::GetItems())
{
if (!item->ShouldCommit())
{
Log(LOG_DEBUG) << "Not committing dead " << item->GetSerializableName() << " object: " << item;
continue; // Non-committable object.
}
auto *s_type = item->GetSerializableType();
if (!s_type)
{
Log(LOG_DEBUG) << "Not committing orphaned " << item->GetSerializableName() << " object: " << item;
continue; // Provider has been unloaded.
}
// This should always be found because we create it in the previous step.
auto it = databases.find(s_type->GetOwner());
-646
View File
@@ -1,646 +0,0 @@
// Anope IRC Services <https://www.anope.org/>
//
// Copyright (C) 2003-2026 Anope Contributors
//
// Anope is free software. You can use, modify, and/or distribute it under the
// terms of version 2 of the GNU General Public License. See docs/LICENSE.txt
// for the complete terms of this license and docs/AUTHORS.txt for a list of
// contributors.
//
// Based on the original code of Epona by Lara
// Based on the original code of Services by Andy Church
//
// SPDX-License-Identifier: GPL-2.0-only
#include "module.h"
#include "modules/redis.h"
using namespace Redis;
class DatabaseRedis;
static DatabaseRedis *me;
class Data final
: public Serialize::Data
{
public:
std::map<Anope::string, std::stringstream *> data;
~Data() override
{
for (auto &[_, stream] : data)
delete stream;
}
std::iostream &operator[](const Anope::string &key) override
{
std::stringstream *&stream = data[key];
if (!stream)
stream = new std::stringstream();
return *stream;
}
size_t Hash() const override
{
size_t hash = 0;
for (const auto &[_, value] : this->data)
if (!value->str().empty())
hash ^= Anope::hash_cs()(value->str());
return hash;
}
};
class TypeLoader final
: public Interface
{
Anope::string type;
public:
TypeLoader(Module *creator, const Anope::string &t) : Interface(creator), type(t) { }
void OnResult(const Reply &r) override;
};
class ObjectLoader final
: public Interface
{
Anope::string type;
int64_t id;
public:
ObjectLoader(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
void OnResult(const Reply &r) override;
};
class IDInterface final
: public Interface
{
Reference<Serializable> o;
public:
IDInterface(Module *creator, Serializable *obj) : Interface(creator), o(obj) { }
void OnResult(const Reply &r) override;
};
class Deleter final
: public Interface
{
Anope::string type;
int64_t id;
public:
Deleter(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
void OnResult(const Reply &r) override;
};
class Updater final
: public Interface
{
Anope::string type;
int64_t id;
public:
Updater(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
void OnResult(const Reply &r) override;
};
class ModifiedObject final
: public Interface
{
Anope::string type;
int64_t id;
public:
ModifiedObject(Module *creator, const Anope::string &t, int64_t i) : Interface(creator), type(t), id(i) { }
void OnResult(const Reply &r) override;
};
class SubscriptionListener final
: public Interface
{
public:
SubscriptionListener(Module *creator) : Interface(creator) { }
void OnResult(const Reply &r) override;
};
class DatabaseRedis final
: public Module
, public Pipe
{
SubscriptionListener sl;
std::set<Serializable *> updated_items;
public:
ServiceReference<Provider> redis;
DatabaseRedis(const Anope::string &modname, const Anope::string &creator)
: Module(modname, creator, DATABASE | VENDOR)
, sl(this)
, redis("Redis::Provider")
{
me = this;
}
/* Insert or update an object */
void InsertObject(Serializable *obj)
{
Serialize::Type *t = obj->GetSerializableType();
/* If there is no id yet for this object, get one */
if (!obj->object_id)
redis->SendCommand(new IDInterface(this, obj), "INCR id:" + t->GetName());
else
{
Data data;
t->Serialize(obj, data);
if (obj->IsCached(data))
return;
obj->UpdateCache(data);
std::vector<Anope::string> args;
args.emplace_back("HGETALL");
args.push_back("hash:" + t->GetName() + ":" + Anope::ToString(obj->object_id));
/* Get object attrs to clear before updating */
redis->SendCommand(new Updater(this, t->GetName(), obj->object_id), args);
}
}
void OnNotify() override
{
for (auto *obj : this->updated_items)
{
this->InsertObject(obj);
}
this->updated_items.clear();
}
void OnReload(Configuration::Conf &conf) override
{
const auto &block = conf.GetModule(this);
this->redis.SetServiceName(block.Get<const Anope::string>("engine", "redis/main"));
}
EventReturn OnLoadDatabase() override
{
if (!redis)
{
Log(this) << "Unable to load database - unable to find redis provider";
return EVENT_CONTINUE;
}
for (const auto &type_order : Serialize::Type::GetTypeOrder())
{
Serialize::Type *sb = Serialize::Type::Find(type_order);
this->OnSerializeTypeCreate(sb);
}
while (!redis->IsSocketDead() && redis->BlockAndProcess());
if (redis->IsSocketDead())
{
Log(this) << "I/O error while loading redis database - is it online?";
return EVENT_CONTINUE;
}
redis->Subscribe(&this->sl, "__keyspace@*__:hash:*");
return EVENT_STOP;
}
void OnSerializeTypeCreate(Serialize::Type *sb) override
{
if (!redis)
return;
std::vector<Anope::string> args;
args.emplace_back("SMEMBERS");
args.push_back("ids:" + sb->GetName());
redis->SendCommand(new TypeLoader(this, sb->GetName()), args);
}
void OnSerializableConstruct(Serializable *obj) override
{
this->updated_items.insert(obj);
this->Notify();
}
void OnSerializableDestruct(Serializable *obj) override
{
Serialize::Type *t = obj->GetSerializableType();
if (t == NULL)
{
/* This is probably the module providing the type unloading.
*
* The types get registered after the extensible container is
* registered so that unserialization on module load can insert
* into the extensible container. So, the type destructs prior to
* the extensible container, which then triggers this
*/
return;
}
std::vector<Anope::string> args;
args.emplace_back("HGETALL");
args.push_back("hash:" + t->GetName() + ":" + Anope::ToString(obj->object_id));
/* Get all of the attributes for this object */
redis->SendCommand(new Deleter(this, t->GetName(), obj->object_id), args);
this->updated_items.erase(obj);
t->objects.erase(obj->object_id);
this->Notify();
}
void OnSerializableUpdate(Serializable *obj) override
{
this->updated_items.insert(obj);
this->Notify();
}
};
void TypeLoader::OnResult(const Reply &r)
{
if (r.type != Reply::MULTI_BULK || !me->redis)
{
delete this;
return;
}
for (auto *reply : r.multi_bulk)
{
if (reply->type != Reply::BULK)
continue;
auto i = Anope::TryConvert<int64_t>(reply->bulk);
if (!i)
continue;
auto id = i.value();
std::vector<Anope::string> args;
args.emplace_back("HGETALL");
args.push_back("hash:" + this->type + ":" + Anope::ToString(id));
me->redis->SendCommand(new ObjectLoader(me, this->type, id), args);
}
delete this;
}
void ObjectLoader::OnResult(const Reply &r)
{
Serialize::Type *st = Serialize::Type::Find(this->type);
if (r.type != Reply::MULTI_BULK || r.multi_bulk.empty() || !me->redis || !st)
{
delete this;
return;
}
Data data;
for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
{
const Reply *key = r.multi_bulk[i],
*value = r.multi_bulk[i + 1];
data[key->bulk] << value->bulk;
}
Serializable *&obj = st->objects[this->id];
obj = st->Unserialize(obj, data);
if (obj)
{
obj->object_id = this->id;
obj->UpdateCache(data);
}
delete this;
}
void IDInterface::OnResult(const Reply &r)
{
if (!o || r.type != Reply::INT || !r.i)
{
delete this;
return;
}
Serializable *&obj = o->GetSerializableType()->objects[r.i];
if (obj)
/* This shouldn't be possible */
obj->object_id = 0;
o->object_id = r.i;
obj = o;
/* Now that we have the id, insert this object for real */
anope_dynamic_static_cast<DatabaseRedis *>(this->owner)->InsertObject(o);
delete this;
}
void Deleter::OnResult(const Reply &r)
{
if (r.type != Reply::MULTI_BULK || !me->redis || r.multi_bulk.empty())
{
delete this;
return;
}
/* Transaction start */
me->redis->StartTransaction();
std::vector<Anope::string> args;
args.emplace_back("DEL");
args.push_back("hash:" + this->type + ":" + Anope::ToString(this->id));
/* Delete hash object */
me->redis->SendCommand(NULL, args);
args.clear();
args.emplace_back("SREM");
args.push_back("ids:" + this->type);
args.push_back(Anope::ToString(this->id));
/* Delete id from ids set */
me->redis->SendCommand(NULL, args);
for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
{
const Reply *key = r.multi_bulk[i],
*value = r.multi_bulk[i + 1];
args.clear();
args.emplace_back("SREM");
args.push_back("value:" + this->type + ":" + key->bulk + ":" + value->bulk);
args.push_back(Anope::ToString(this->id));
/* Delete value -> object id */
me->redis->SendCommand(NULL, args);
}
/* Transaction end */
me->redis->CommitTransaction();
delete this;
}
void Updater::OnResult(const Reply &r)
{
Serialize::Type *st = Serialize::Type::Find(this->type);
if (!st)
{
delete this;
return;
}
Serializable *obj = st->objects[this->id];
if (!obj)
{
delete this;
return;
}
Data data;
st->Serialize(obj, data);
/* Transaction start */
me->redis->StartTransaction();
for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
{
const Reply *key = r.multi_bulk[i],
*value = r.multi_bulk[i + 1];
std::vector<Anope::string> args;
args.emplace_back("SREM");
args.push_back("value:" + this->type + ":" + key->bulk + ":" + value->bulk);
args.push_back(Anope::ToString(this->id));
/* Delete value -> object id */
me->redis->SendCommand(NULL, args);
}
/* Add object id to id set for this type */
std::vector<Anope::string> args;
args.emplace_back("SADD");
args.push_back("ids:" + this->type);
args.push_back(Anope::ToString(obj->object_id));
me->redis->SendCommand(NULL, args);
args.clear();
args.emplace_back("HMSET");
args.push_back("hash:" + this->type + ":" + Anope::ToString(obj->object_id));
for (const auto &[key, value] : data.data)
{
args.push_back(key);
args.emplace_back(value->str());
std::vector<Anope::string> args2;
args2.emplace_back("SADD");
args2.push_back("value:" + this->type + ":" + key + ":" + value->str());
args2.push_back(Anope::ToString(obj->object_id));
/* Add to value -> object id set */
me->redis->SendCommand(NULL, args2);
}
++obj->redis_ignore;
/* Add object */
me->redis->SendCommand(NULL, args);
/* Transaction end */
me->redis->CommitTransaction();
delete this;
}
void SubscriptionListener::OnResult(const Reply &r)
{
/*
* [May 15 13:59:35.645839 2013] Debug: pmessage
* [May 15 13:59:35.645866 2013] Debug: __keyspace@*__:anope:hash:*
* [May 15 13:59:35.645880 2013] Debug: __keyspace@0__:anope:hash:type:id
* [May 15 13:59:35.645893 2013] Debug: hset
*/
if (r.multi_bulk.size() != 4)
return;
size_t sz = r.multi_bulk[2]->bulk.find(':');
if (sz == Anope::string::npos)
return;
const Anope::string &key = r.multi_bulk[2]->bulk.substr(sz + 1),
&op = r.multi_bulk[3]->bulk;
sz = key.rfind(':');
if (sz == Anope::string::npos)
return;
const Anope::string &id = key.substr(sz + 1);
size_t sz2 = key.rfind(':', sz - 1);
if (sz2 == Anope::string::npos)
return;
const Anope::string &type = key.substr(sz2 + 1, sz - sz2 - 1);
Serialize::Type *s_type = Serialize::Type::Find(type);
if (s_type == NULL)
return;
auto oid = Anope::TryConvert<Serializable::Id>(id);
if (!oid.has_value())
return;
auto obj_id = oid.value();
if (op == "hset" || op == "hdel")
{
Serializable *s = s_type->objects[obj_id];
if (s && s->redis_ignore)
{
--s->redis_ignore;
Log(LOG_DEBUG) << "redis: notify: got modify for object id " << obj_id << " of type " << type << ", but I am ignoring it";
}
else
{
Log(LOG_DEBUG) << "redis: notify: got modify for object id " << obj_id << " of type " << type;
std::vector<Anope::string> args;
args.emplace_back("HGETALL");
args.push_back("hash:" + type + ":" + id);
me->redis->SendCommand(new ModifiedObject(me, type, obj_id), args);
}
}
else if (op == "del")
{
Serializable *&s = s_type->objects[obj_id];
if (s == NULL)
return;
Log(LOG_DEBUG) << "redis: notify: deleting object id " << obj_id << " of type " << type;
Data data;
s_type->Serialize(s, data);
/* Transaction start */
me->redis->StartTransaction();
for (const auto &[k, value] : data.data)
{
std::vector<Anope::string> args;
args.emplace_back("SREM");
args.push_back("value:" + type + ":" + k + ":" + value->str());
args.push_back(id);
/* Delete value -> object id */
me->redis->SendCommand(NULL, args);
}
std::vector<Anope::string> args;
args.emplace_back("SREM");
args.push_back("ids:" + type);
args.push_back(Anope::ToString(s->object_id));
/* Delete object from id set */
me->redis->SendCommand(NULL, args);
/* Transaction end */
me->redis->CommitTransaction();
delete s;
s = NULL;
}
}
void ModifiedObject::OnResult(const Reply &r)
{
Serialize::Type *st = Serialize::Type::Find(this->type);
if (!st)
{
delete this;
return;
}
Serializable *&obj = st->objects[this->id];
/* Transaction start */
me->redis->StartTransaction();
/* Erase old object values */
if (obj)
{
Data data;
st->Serialize(obj, data);
for (auto &[key, value] : data.data)
{
std::vector<Anope::string> args;
args.emplace_back("SREM");
args.push_back("value:" + st->GetName() + ":" + key + ":" + value->str());
args.push_back(Anope::ToString(this->id));
/* Delete value -> object id */
me->redis->SendCommand(NULL, args);
}
}
Data data;
for (unsigned i = 0; i + 1 < r.multi_bulk.size(); i += 2)
{
const Reply *key = r.multi_bulk[i],
*value = r.multi_bulk[i + 1];
data[key->bulk] << value->bulk;
}
obj = st->Unserialize(obj, data);
if (obj)
{
obj->object_id = this->id;
obj->UpdateCache(data);
/* Insert new object values */
for (const auto &[key, value] : data.data)
{
std::vector<Anope::string> args;
args.emplace_back("SADD");
args.push_back("value:" + st->GetName() + ":" + key + ":" + value->str());
args.push_back(Anope::ToString(obj->object_id));
/* Add to value -> object id set */
me->redis->SendCommand(NULL, args);
}
std::vector<Anope::string> args;
args.emplace_back("SADD");
args.push_back("ids:" + st->GetName());
args.push_back(Anope::ToString(obj->object_id));
/* Add to type -> id set */
me->redis->SendCommand(NULL, args);
}
/* Transaction end */
me->redis->CommitTransaction();
delete this;
}
MODULE_INIT(DatabaseRedis)
+8 -2
View File
@@ -120,6 +120,12 @@ public:
{
if (this->sql)
{
if (!obj->ShouldCommit())
{
OnSerializableDestruct(obj);
continue; // Non-committable object.
}
Serialize::Type *s_type = obj->GetSerializableType();
if (!s_type)
continue;
@@ -168,7 +174,7 @@ public:
{
const auto &block = conf.GetModule(this);
this->sql.SetServiceName(block.Get<const Anope::string>("engine"));
this->prefix = block.Get<const Anope::string>("prefix", "anope_db_");
this->prefix = block.Get<const Anope::string>("prefix", "anope21_");
this->import = block.Get<bool>("import");
}
@@ -256,7 +262,7 @@ public:
Data data;
for (const auto &[key, value] : res.Row(j))
data[key] << value;
data.StoreInternal(key, value);
Serializable *obj = sb->Unserialize(NULL, data);
if (obj)
+8 -2
View File
@@ -104,6 +104,12 @@ public:
{
if (obj && this->SQL)
{
if (!obj->ShouldCommit())
{
OnSerializableDestruct(obj);
continue; // Non-committable object.
}
Serialize::Type *s_type = obj->GetSerializableType();
if (!s_type)
continue;
@@ -152,7 +158,7 @@ public:
const auto &block = conf.GetModule(this);
this->SQL.SetServiceName(block.Get<const Anope::string>("engine"));
this->prefix = block.Get<const Anope::string>("prefix", "anope_db_");
this->prefix = block.Get<const Anope::string>("prefix", "anope21_");
}
void OnSerializableConstruct(Serializable *obj) override
@@ -220,7 +226,7 @@ public:
Data data;
for (const auto &[key, value] : row)
data[key] << value;
data.StoreInternal(key, value);
Serializable *s = NULL;
auto it = obj->objects.find(id);
+7 -7
View File
@@ -729,7 +729,7 @@ public:
delete udpsock;
delete tcpsock;
for (std::map<unsigned short, Request *>::iterator it = this->requests.begin(), it_end = this->requests.end(); it != it_end;)
for (auto it = this->requests.begin(), it_end = this->requests.end(); it != it_end;)
{
Request *request = it->second;
++it;
@@ -909,7 +909,7 @@ public:
return true;
}
std::map<unsigned short, Request *>::iterator it = this->requests.find(recv_packet.id);
auto it = this->requests.find(recv_packet.id);
if (it == this->requests.end())
{
Log(LOG_DEBUG_2) << "Resolver: Received an answer for something we didn't request";
@@ -1043,7 +1043,7 @@ private:
*/
bool CheckCache(Request *request)
{
cache_map::iterator it = this->cache.find(*request);
auto it = this->cache.find(*request);
if (it != this->cache.end())
{
Query &record = it->second;
@@ -1070,7 +1070,7 @@ public:
~ModuleDNS() override
{
for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
for (auto it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
{
Socket *s = it->second;
++it;
@@ -1096,8 +1096,8 @@ public:
for (int i = 0; i < block.CountBlock("notify"); ++i)
{
const auto &n = block.GetBlock("notify", i);
Anope::string nip = n.Get<Anope::string>("ip");
short nport = n.Get<short>("port");
auto nip = n.Get<Anope::string>("ip");
auto nport = n.Get<short>("port");
notify.emplace_back(nip, nport);
}
@@ -1149,7 +1149,7 @@ public:
void OnModuleUnload(User *u, Module *m) override
{
for (std::map<unsigned short, Request *>::iterator it = this->manager.requests.begin(), it_end = this->manager.requests.end(); it != it_end;)
for (auto it = this->manager.requests.begin(), it_end = this->manager.requests.end(); it != it_end;)
{
unsigned short id = it->first;
Request *req = it->second;
+2 -4
View File
@@ -575,7 +575,7 @@ Query MySQLService::BuildInsert(const Anope::string &table, Serializable::Id id,
for (const auto &known_col : this->active_schema[table])
{
if (data.data.count(known_col) == 0)
data[known_col] << "";
data.data[known_col];
}
Anope::string query_text = "INSERT INTO `" + table + "` (`id`";
@@ -593,9 +593,7 @@ Query MySQLService::BuildInsert(const Anope::string &table, Serializable::Id id,
Query query(query_text);
for (auto &[field, value] : data.data)
{
Anope::string buf;
*value >> buf;
auto buf = value;
auto escape = true;
switch (data.GetType(field))
{
+1 -1
View File
@@ -39,7 +39,7 @@ public:
int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB | REG_ICASE);
if (err)
{
char buf[BUFSIZE];
char buf[256];
regerror(err, &this->regbuf, buf, sizeof(buf));
regfree(&this->regbuf);
throw RegexException("Error in regex " + expr + ": " + buf);
+1 -1
View File
@@ -37,7 +37,7 @@ public:
int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB);
if (err)
{
char buf[BUFSIZE];
char buf[256];
regerror(err, &this->regbuf, buf, sizeof(buf));
regfree(&this->regbuf);
throw RegexException("Error in regex " + expr + ": " + buf);
+2 -4
View File
@@ -311,7 +311,7 @@ Query SQLiteService::BuildInsert(const Anope::string &table, Serializable::Id id
for (const auto &known_col : this->active_schema[table])
{
if (known_col != "id" && known_col != "timestamp" && data.data.count(known_col) == 0)
data[known_col] << "";
data.data[known_col];
}
Anope::string query_text = "REPLACE INTO `" + table + "` (";
@@ -331,9 +331,7 @@ Query SQLiteService::BuildInsert(const Anope::string &table, Serializable::Id id
Query query(query_text);
for (auto &[field, value] : data.data)
{
Anope::string buf;
*value >> buf;
auto buf = value;
auto escape = true;
switch (data.GetType(field))
{
+1 -1
View File
@@ -147,7 +147,7 @@ public:
if (params.empty())
return;
CommandInfo::map::const_iterator it = Config->Fantasy.end();
auto it = Config->Fantasy.end();
unsigned count = 0;
for (unsigned max = params.size(); it == Config->Fantasy.end() && max > 0; --max)
{
+27 -10
View File
@@ -88,7 +88,7 @@ public:
CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1)
{
this->SetDesc(_("Associate a greet message with your nickname"));
this->SetSyntax(_("\037message\037"));
this->SetSyntax(_("[\037message\037]"));
}
void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
@@ -136,11 +136,19 @@ public:
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_(
"Makes the given message the greet of your nickname, that "
"will be displayed when joining a channel that has GREET "
"option enabled, provided that you have the necessary "
"access on it."
"Changes your greet message. This message will be displayed when joining a channel "
"that has GREET option enabled, provided that you have the necessary access on it."
));
ExampleWrapper()
.AddEntry(_("I come in peace"), _(
"Changes your greet message to \035I come in peace\035."
))
.AddEntry("", _(
"Removes your greet message."
))
.SendTo(source);
return true;
}
};
@@ -152,7 +160,7 @@ public:
CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1)
{
this->ClearSyntax();
this->SetSyntax(_("\037nickname\037 \037message\037"));
this->SetSyntax(_("\037nickname\037 [\037message\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
@@ -165,11 +173,20 @@ public:
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_(
"Makes the given message the greet of the nickname, that "
"will be displayed when joining a channel that has GREET "
"option enabled, provided that the user has the necessary "
"access on it."
"Changes the greet message of the specified nickname. This message will be displayed "
"when joining a channel that has GREET option enabled, provided that the user has the "
"necessary access on it."
));
ExampleWrapper()
.AddEntry(_("alien I come in peace"), _(
"Changes the greet message of \035alien\035 to \035I come in peace\035."
))
.AddEntry("zebra", _(
"Removes the greet message of \035zebra\035."
))
.SendTo(source);
return true;
}
};
+1 -1
View File
@@ -138,7 +138,7 @@ public:
full_command += " " + params[i];
full_command.erase(full_command.begin());
CommandInfo::map::const_iterator it = map.find(full_command);
auto it = map.find(full_command);
if (it == map.end())
continue;
+8 -8
View File
@@ -223,12 +223,12 @@ public:
else
ho = new HostOffer();
data["ident"] >> ho->ident;
data["host"] >> ho->host;
data["reason"] >> ho->reason;
data["creator"] >> ho->creator;
data["created"] >> ho->created;
data["expires"] >> ho->expires;
ho->ident = data.Load("ident");
ho->host = data.Load("host");
ho->reason = data.Load("reason");
ho->creator = data.Load("creator");
ho->created = data.Load<time_t>("created");
ho->expires = data.Load<time_t>("expires");
if (!obj)
host_offers->Add(ho);
@@ -669,7 +669,7 @@ public:
{
if (!show_all)
return;
mask = Anope::Format(Language::Translate(source.GetAccount(), _("%s [Invalid]")), mask.c_str());
mask = Anope::Format(source.Translate(_("%s [Invalid]")), mask.c_str());
}
ListFormatter::ListEntry entry;
@@ -835,7 +835,7 @@ private:
{
if (!show_all)
continue;
mask = Anope::Format(Language::Translate(source.GetAccount(), _("%s [Invalid]")), mask.c_str());
mask = Anope::Format(source.Translate(_("%s [Invalid]")), mask.c_str());
}
ListFormatter::ListEntry entry;
+8 -11
View File
@@ -75,10 +75,7 @@ struct HostRequestTypeImpl final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string snick;
data["nick"] >> snick;
NickAlias *na = NickAlias::Find(snick);
auto *na = NickAlias::Find(data.Load("nick"));
if (na == NULL)
return NULL;
@@ -90,11 +87,11 @@ struct HostRequestTypeImpl final
if (req)
{
req->nick = na->nick;
data["ident"] >> req->ident;
data["host"] >> req->host;
data["time"] >> req->time;
data["validation_token"] >> req->validation_token;
data["last_validation"] >> req->last_validation;
req->ident = data.Load("ident");
req->host = data.Load("host");
req->time = data.Load<time_t>("time");
req->validation_token = data.Load("validation_token");
req->last_validation = data.Load<time_t>("last_validation");
}
return req;
@@ -285,7 +282,7 @@ public:
BotInfo *bi;
Anope::string cmd;
if (dnsmanager && Command::FindCommandFromService("hostserv/validate", bi, cmd))
if (dnsmanager && Command::FindFromService("hostserv/validate", bi, cmd))
{
source.Reply(_(
"Your vhost \002%s\002 has been requested. If the requested vhost is for a valid "
@@ -404,7 +401,7 @@ public:
else
message = _("Your requested vhost has been rejected.");
MemoServ::service->Send(source.service->nick, nick, Language::Translate(source.GetAccount(), message.c_str()), true);
MemoServ::service->Send(source.service->nick, nick, source.Translate(message.c_str()), true);
}
source.Reply(_("VHost for %s has been rejected."), nick.c_str());
+2 -2
View File
@@ -354,7 +354,7 @@ public:
~HTTPD() override
{
for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
for (auto it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
{
Socket *s = it->second;
++it;
@@ -447,7 +447,7 @@ public:
spacesepstream(ext_header).GetTokens(p->ext_headers);
}
for (std::map<Anope::string, MyHTTPProvider *>::iterator it = this->providers.begin(), it_end = this->providers.end(); it != it_end;)
for (auto it = this->providers.begin(), it_end = this->providers.end(); it != it_end;)
{
HTTP::Provider *p = it->second;
++it;
+1 -1
View File
@@ -90,7 +90,7 @@ public:
BotInfo *bi;
Anope::string cmd;
if (Command::FindCommandFromService("memoserv/del", bi, cmd))
if (Command::FindFromService("memoserv/del", bi, cmd))
{
if (ci)
source.Reply(_("To delete, type: \002%s %s %d\002"), bi->GetQueryCommand({}, cmd).c_str(), ci->name.c_str(), index + 1);
+3 -3
View File
@@ -115,7 +115,7 @@ public:
, nick(na->nick)
{
/* Erase the current release timer and use the new one */
Anope::map<NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
auto nit = NickServReleases.find(this->nick);
if (nit != NickServReleases.end())
{
IRCD->SendQuit(nit->second);
@@ -379,7 +379,7 @@ public:
Log(NickServ, "nick") << "Deleting account " << nc->display;
/* Clean up this nick core from any users online */
for (std::list<User *>::iterator it = nc->users.begin(); it != nc->users.end();)
for (auto it = nc->users.begin(); it != nc->users.end();)
{
User *user = *it++;
IRCD->SendLogout(user);
@@ -610,7 +610,7 @@ public:
time_t nickserv_expire = Config->GetModule(this).Get<time_t>("expire", "1y");
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; )
for (auto it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; )
{
NickAlias *na = it->second;
++it;
+11 -15
View File
@@ -34,10 +34,10 @@ struct AJoinEntry final
~AJoinEntry() override
{
AJoinList *channels = owner->GetExt<AJoinList>("ajoinlist");
auto *channels = owner->GetExt<AJoinList>("ajoinlist");
if (channels)
{
std::vector<AJoinEntry *>::iterator it = std::find((*channels)->begin(), (*channels)->end(), this);
auto it = std::find((*channels)->begin(), (*channels)->end(), this);
if (it != (*channels)->end())
(*channels)->erase(it);
}
@@ -65,13 +65,9 @@ struct AJoinEntryType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &sd) const override
{
Anope::string sowner;
uint64_t sownerid = 0;
const auto sownerid = sd.Load<uint64_t>("ownerid");
sd["owner"] >> sowner; // Deprecated 2.0 field
sd["ownerid"] >> sownerid;
auto *nc = sownerid ? NickCore::FindId(sownerid) : NickCore::Find(sowner);
auto *nc = sownerid ? NickCore::FindId(sownerid) : NickCore::Find(sd.Load("owner"));
if (nc == NULL)
return NULL;
@@ -84,12 +80,12 @@ struct AJoinEntryType final
aj->owner = nc;
}
sd["channel"] >> aj->channel;
sd["key"] >> aj->key;
aj->channel = sd.Load("channel");
aj->key = sd.Load("key");
if (!obj)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
auto *channels = nc->Require<AJoinList>("ajoinlist");
(*channels)->push_back(aj);
}
@@ -108,7 +104,7 @@ class CommandNSAJoin final
{
static void DoList(CommandSource &source, NickCore *nc)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
auto *channels = nc->Require<AJoinList>("ajoinlist");
if ((*channels)->empty())
source.Reply(_("%s's auto join list is empty."), nc->display.c_str());
@@ -141,7 +137,7 @@ class CommandNSAJoin final
void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chans, const Anope::string &keys)
{
const auto ajoinmax = Config->GetModule(this->owner).Get<unsigned>("ajoinmax");
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
auto *channels = nc->Require<AJoinList>("ajoinlist");
Anope::string addedchans;
Anope::string alreadyadded;
@@ -208,7 +204,7 @@ class CommandNSAJoin final
void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chans)
{
AJoinList *channels = nc->Require<AJoinList>("ajoinlist");
auto *channels = nc->Require<AJoinList>("ajoinlist");
Anope::string delchans;
Anope::string notfoundchans;
commasepstream sep(chans);
@@ -344,7 +340,7 @@ public:
if (!NickServ)
return;
AJoinList *channels = u->Account()->GetExt<AJoinList>("ajoinlist");
auto *channels = u->Account()->GetExt<AJoinList>("ajoinlist");
if (channels == NULL)
return;
+2 -2
View File
@@ -63,11 +63,11 @@ public:
Anope::string privstr;
if (ci->GetFounder() == nc)
{
privstr = Language::Translate(source.GetAccount(), _("Founder"));
privstr = source.Translate(_("Founder"));
}
else if (ci->GetSuccessor() == nc)
{
privstr += Language::Translate(source.GetAccount(), _("Successor"));
privstr += source.Translate(_("Successor"));
}
AccessGroup access = ci->AccessFor(nc, false);
+15 -13
View File
@@ -184,8 +184,8 @@ public:
FOREACH_MOD(OnNickClearCert, (this->nc));
for (const auto *cert : certs)
{
delete cert;
certmap.erase(cert->fingerprint);
delete cert;
}
this->certs.clear();
}
@@ -207,21 +207,24 @@ public:
if (s->GetSerializableType()->GetName() != NICKCORE_TYPE)
return;
const auto certstr = data.Load("cert");
if (certstr.empty())
return; // Nothing to do.
auto *nc = anope_dynamic_static_cast<NickCore *>(e);
auto *cl = this->Require(nc);
// Delete the old cert list.
for (const auto *cert : cl->certs)
{
delete cert;
certmap.erase(cert->fingerprint);
delete cert;
}
cl->certs.clear();
// Add the new cert list
Anope::string buf;
data["cert"] >> buf;
for (spacesepstream sep(buf); sep.GetToken(buf); )
spacesepstream sep(certstr);
for (Anope::string buf; sep.GetToken(buf); )
{
auto *cert = new NSCertInfo(e);
cert->fingerprint = buf;
@@ -255,10 +258,7 @@ public:
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
uint64_t account = 0;
data["account"] >> account;
auto *nc = NickCore::FindId(account);
auto *nc = NickCore::FindId(data.Load<uint64_t>("account"));
if (!nc)
return nullptr; // Missing user.
@@ -268,10 +268,10 @@ public:
else
cert = new NSCertInfo(nc);
data["created"] >> cert->created;
data["creator"] >> cert->creator;
data["description"] >> cert->description;
data["fingerprint"] >> cert->fingerprint;
cert->created = data.Load<time_t>("created");
cert->creator = data.Load("creator");
cert->description = data.Load("description");
cert->fingerprint = data.Load("fingerprint");
if (!obj)
{
@@ -652,6 +652,7 @@ private:
NSCertListImpl::ExtensibleItem certs;
CertServiceImpl cs;
NSCertInfoType cert_type;
SerializableExtensibleItem<bool> autologin;
bool CanLogin(User *u, NickCore *nc)
{
@@ -681,6 +682,7 @@ public:
, commandnssasetautologin(this)
, certs(this, NICKSERV_CERT_EXT)
, cs(this)
, autologin(this, "AUTOLOGIN")
{
if (!IRCD || !IRCD->CanCertFP)
throw ModuleException("Your IRCd does not support ssl client certificates");
+2 -2
View File
@@ -146,7 +146,7 @@ public:
NickAlias *target, *na = NickAlias::Find(source.GetNick());
time_t reg_delay = Config->GetModule("nickserv").Get<time_t>("regdelay");
unsigned maxaliases = Config->GetModule(this->owner).Get<unsigned>("maxaliases");
auto maxaliases = Config->GetModule(this->owner).Get<unsigned>("maxaliases");
if (!(target = NickAlias::Find(nick)))
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
else if (user && Anope::CurTime < user->lastnickreg + reg_delay)
@@ -258,7 +258,7 @@ public:
{
NickCore *oldcore = na->nc;
std::vector<NickAlias *>::iterator it = std::find(oldcore->aliases->begin(), oldcore->aliases->end(), na);
auto it = std::find(oldcore->aliases->begin(), oldcore->aliases->end(), na);
if (it != oldcore->aliases->end())
oldcore->aliases->erase(it);
+1 -1
View File
@@ -91,7 +91,7 @@ public:
return;
}
unsigned int maxlogins = Config->GetModule(this->owner).Get<unsigned int>("maxlogins");
auto maxlogins = Config->GetModule(this->owner).Get<unsigned int>("maxlogins");
if (na && maxlogins && na->nc->users.size() >= maxlogins)
{
source.Reply(_("Account \002%s\002 has already reached the maximum number of simultaneous logins (%u)."), na->nc->display.c_str(), maxlogins);
+1 -1
View File
@@ -91,7 +91,7 @@ public:
InfoFormatter info(source.nc);
info[_("Account")] = Anope::Format(Language::Translate(source.nc, _("%s (ID: %zu)")), na->nc->display.c_str(), na->nc->GetId());
info[_("Account")] = Anope::Format(source.Translate(_("%s (ID: %zu)")), na->nc->display.c_str(), na->nc->GetId());
info[_("Account registered")] = Anope::strftime(na->nc->registered, source.GetAccount());
info[_("Nick registered")] = Anope::strftime(na->registered, source.GetAccount());
+2 -2
View File
@@ -110,9 +110,9 @@ public:
auto &status = entry["Status"];
if (na->nc->HasExt("NS_SUSPENDED"))
status = Language::Translate(source.GetAccount(), _("Suspended"));
status = source.Translate(_("Suspended"));
else if (na->nc->HasExt("UNCONFIRMED"))
status = Language::Translate(source.GetAccount(), _("Unconfirmed"));
status = source.Translate(_("Unconfirmed"));
list.AddEntry(entry);
}
++count;
+4 -4
View File
@@ -73,7 +73,7 @@ public:
{
if (!u->chans.empty())
{
NSRecoverInfo *ei = source.GetUser()->Extend<NSRecoverInfo>("recover");
auto *ei = source.GetUser()->Extend<NSRecoverInfo>("recover");
for (auto &[chan, cuc] : u->chans)
(*ei)[chan->name] = cuc->status;
}
@@ -108,7 +108,7 @@ public:
if (IRCD->CanSVSNick)
{
NSRecoverSvsnick *svs = u->Extend<NSRecoverSvsnick>("svsnick");
auto *svs = u->Extend<NSRecoverSvsnick>("svsnick");
svs->from = source.GetUser();
svs->to = u->nick;
}
@@ -253,7 +253,7 @@ public:
BotInfo *NickServ = Config->GetClient("NickServ");
if (ei != NULL && NickServ != NULL)
for (NSRecoverInfo::iterator it = ei->begin(), it_end = ei->end(); it != it_end;)
for (auto it = ei->begin(), it_end = ei->end(); it != it_end;)
{
Channel *c = Channel::Find(it->first);
const Anope::string &cname = it->first;
@@ -288,7 +288,7 @@ public:
if (ei != NULL)
{
NSRecoverInfo::iterator it = ei->find(c->name);
auto it = ei->find(c->name);
if (it != ei->end())
{
for (auto mode : it->second.Modes())
+1 -1
View File
@@ -181,7 +181,7 @@ public:
bool OnHelp(CommandSource &source, const Anope::string &subcommand) override
{
unsigned int minpasslen = Config->GetModule("nickserv").Get<unsigned>("minpasslen", "10");
auto minpasslen = Config->GetModule("nickserv").Get<unsigned>("minpasslen", "10");
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_(
+1 -1
View File
@@ -115,7 +115,7 @@ public:
Anope::string GetAgent()
{
Anope::string agent = Config->GetModule(Service::owner).Get<Anope::string>("agent", "NickServ");
auto agent = Config->GetModule(Service::owner).Get<Anope::string>("agent", "NickServ");
BotInfo *bi = Config->GetClient(agent);
if (bi)
agent = bi->GetUID();
+1 -1
View File
@@ -44,7 +44,7 @@ public:
bool ProcessMessage(SASL::Session *sess, const SASL::Message &m) override
{
Session *mysess = anope_dynamic_static_cast<Session *>(sess);
auto *mysess = anope_dynamic_static_cast<Session *>(sess);
if (m.type == "S")
{
+5 -5
View File
@@ -129,7 +129,7 @@ private:
if (s->GetSerializableType()->GetName() != NICKCORE_TYPE)
return;
const NickCore *nc = anope_dynamic_static_cast<const NickCore *>(s);
const auto *nc = anope_dynamic_static_cast<const NickCore *>(s);
Anope::string modes;
for (const auto &[last_mode, last_data] : nc->last_modes)
{
@@ -155,11 +155,11 @@ private:
if (s->GetSerializableType()->GetName() != NICKCORE_TYPE)
return;
NickCore *nc = anope_dynamic_static_cast<NickCore *>(s);
Anope::string modes;
data["last_modes"] >> modes;
auto *nc = anope_dynamic_static_cast<NickCore *>(s);
nc->last_modes.clear();
for (spacesepstream sep(modes); sep.GetToken(modes);)
spacesepstream sep(data.Load("last_modes"));
for (Anope::string modes; sep.GetToken(modes);)
{
if (modes[0] == '+')
{
+10 -13
View File
@@ -79,23 +79,20 @@ struct NSMiscDataType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string snc, sname, sdata;
data["nc"] >> snc;
data["name"] >> sname;
data["data"] >> sdata;
NickCore *nc = NickCore::Find(snc);
auto *nc = NickCore::Find(data.Load("nc"));
if (nc == NULL)
return NULL;
const auto sname = data.Load("name");
const auto sdata = data.Load("data");
NSMiscData *d = NULL;
if (obj)
{
d = anope_dynamic_static_cast<NSMiscData *>(obj);
d->object = nc->display;
data["name"] >> d->name;
data["data"] >> d->data;
d->name = sname;
d->data = sdata;
}
else
{
@@ -256,7 +253,7 @@ public:
this->SendSyntax(source);
source.Reply(" ");
source.Reply("%s", Language::Translate(source.nc, desc.c_str()));
source.Reply("%s", source.Translate(desc.c_str()));
return true;
}
@@ -268,7 +265,7 @@ public:
value = it->second.syntax.c_str();
this->ClearSyntax();
this->SetSyntax(Anope::Format("[\037%s\037]", Language::Translate(source.nc, value)));
this->SetSyntax(Anope::Format("[\037%s\037]", source.Translate(value)));
Command::SendSyntax(source);
}
@@ -297,8 +294,8 @@ public:
this->ClearSyntax();
this->SetSyntax(Anope::Format(
Language::Translate(source.nc, _("\037nickname\037 [\037%s\037]")),
Language::Translate(source.nc, value)
source.Translate(_("\037nickname\037 [\037%s\037]")),
source.Translate(value)
));
Command::SendSyntax(source);
+1 -1
View File
@@ -230,7 +230,7 @@ public:
throw ModuleException("A compiler with C++20 support is required by this module");
#else
// Build the zone list.
const auto& tzdb = std::chrono::get_tzdb();
const auto &tzdb = std::chrono::get_tzdb();
for (const auto &tz : tzdb.zones)
timezones.emplace_back(tz.name());
for (const auto &tz : tzdb.links)
+10 -12
View File
@@ -43,25 +43,23 @@ struct NSSuspendInfoType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string snick;
data["nick"] >> snick;
NSSuspendInfo *si;
if (obj)
si = anope_dynamic_static_cast<NSSuspendInfo *>(obj);
else
{
NickAlias *na = NickAlias::Find(snick);
auto *na = NickAlias::Find(data.Load("nick"));
if (!na)
return NULL;
si = na->nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
data["nick"] >> si->what;
si->what = na->nick;
}
data["by"] >> si->by;
data["reason"] >> si->reason;
data["time"] >> si->when;
data["expires"] >> si->expires;
si->by = data.Load("by");
si->reason = data.Load("reason");
si->when = data.Load<time_t>("time");
si->expires = data.Load<time_t>("expires");
return si;
}
};
@@ -124,7 +122,7 @@ public:
for (auto idx = reason_idx; idx < params.size(); ++idx)
reason.append(reason.empty() ? "" : " ").append(params[idx]);
NSSuspendInfo *si = nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
auto *si = nc->Extend<NSSuspendInfo>("NS_SUSPENDED");
si->what = nc->display;
si->by = source.GetNick();
si->reason = reason;
@@ -199,7 +197,7 @@ public:
return;
}
NSSuspendInfo *si = na->nc->GetExt<NSSuspendInfo>("NS_SUSPENDED");
auto *si = na->nc->GetExt<NSSuspendInfo>("NS_SUSPENDED");
Log(LOG_ADMIN, source, this) << "for " << na->nick << " which was suspended by " << (!si->by.empty() ? si->by : "(none)") << " for: " << (!si->reason.empty() ? si->reason : "No reason");
@@ -258,7 +256,7 @@ public:
void OnReload(Configuration::Conf &conf) override
{
Anope::string s = conf.GetModule(this).Get<Anope::string>("show");
auto s = conf.GetModule(this).Get<Anope::string>("show");
commasepstream(s).GetTokens(show);
std::transform(show.begin(), show.end(), show.begin(), trim());
}
+1 -1
View File
@@ -86,7 +86,7 @@ struct DefconConfig final
bool GetDefConParam(const Anope::string &name, Anope::string &buf)
{
std::map<Anope::string, Anope::string>::iterator it = DefConModesOnParams.find(name);
auto it = DefConModesOnParams.find(name);
buf.clear();
+19 -21
View File
@@ -38,7 +38,7 @@ struct DNSZone final
~DNSZone() override
{
std::vector<DNSZone *>::iterator it = std::find(zones->begin(), zones->end(), this);
auto it = std::find(zones->begin(), zones->end(), this);
if (it != zones->end())
zones->erase(it);
}
@@ -79,12 +79,12 @@ struct DNSZoneType final
DNSZone *zone;
Anope::string zone_name;
data["name"] >> zone_name;
zone_name = data.Load("name");
if (obj)
{
zone = anope_dynamic_static_cast<DNSZone *>(obj);
data["name"] >> zone->name;
zone->name = data.Load("name");
}
else
zone = new DNSZone(zone_name);
@@ -92,10 +92,10 @@ struct DNSZoneType final
zone->servers.clear();
for (unsigned count = 0; true; ++count)
{
Anope::string server_str;
data["server" + Anope::ToString(count)] >> server_str;
const auto server_str = data.Load(Anope::Format("server%u", count));
if (server_str.empty())
break;
zone->servers.insert(server_str);
}
@@ -127,7 +127,7 @@ public:
~DNSServer() override
{
std::vector<DNSServer *>::iterator it = std::find(dns_servers->begin(), dns_servers->end(), this);
auto it = std::find(dns_servers->begin(), dns_servers->end(), this);
if (it != dns_servers->end())
dns_servers->erase(it);
}
@@ -195,11 +195,9 @@ struct DNSServerType final
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
const auto server_name = data.Load("server_name");
DNSServer *req;
Anope::string server_name;
data["server_name"] >> server_name;
if (obj)
{
req = anope_dynamic_static_cast<DNSServer *>(obj);
@@ -210,23 +208,23 @@ struct DNSServerType final
for (unsigned i = 0; true; ++i)
{
Anope::string ip_str;
data["ip" + Anope::ToString(i)] >> ip_str;
const auto ip_str = data.Load(Anope::Format("ip%u", i));
if (ip_str.empty())
break;
req->ips.push_back(ip_str);
}
data["limit"] >> req->limit;
data["pooled"] >> req->pooled;
req->limit = data.Load<unsigned>("limit");
req->pooled = data.Load<bool>("pooled");
req->zones.clear();
for (unsigned i = 0; true; ++i)
{
Anope::string zone_str;
data["zone" + Anope::ToString(i)] >> zone_str;
const auto zone_str = data.Load(Anope::Format("zone%u", i));
if (zone_str.empty())
break;
req->zones.insert(zone_str);
}
@@ -255,7 +253,7 @@ class CommandOSDNS final
ListFormatter::ListEntry entry;
entry["Server"] = s->GetName();
entry["Limit"] = s->GetLimit() ? Anope::ToString(s->GetLimit()) : Language::Translate(source.GetAccount(), _("None"));
entry["Limit"] = s->GetLimit() ? Anope::ToString(s->GetLimit()) : source.Translate(_("None"));
Anope::string ip_str;
for (const auto &ip : s->GetIPs())
@@ -266,14 +264,14 @@ class CommandOSDNS final
entry["IP"] = ip_str;
if (s->Active())
entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Active"));
entry["State"] = source.Translate(_("Pooled/Active"));
else if (s->Pooled())
entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Not Active"));
entry["State"] = source.Translate(_("Pooled/Not Active"));
else
entry["State"] = Language::Translate(source.GetAccount(), _("Unpooled"));
entry["State"] = source.Translate(_("Unpooled"));
if (!srv)
entry["State"] += Anope::string(" ") + Language::Translate(source.GetAccount(), _("(Split)"));
entry["State"] += Anope::string(" ") + source.Translate(_("(Split)"));
lf.AddEntry(entry);
}
+10 -12
View File
@@ -113,14 +113,12 @@ Serializable *ForbidDataTypeImpl::Unserialize(Serializable *obj, Serialize::Data
else
fb = new ForbidDataImpl();
data["mask"] >> fb->mask;
data["creator"] >> fb->creator;
data["reason"] >> fb->reason;
data["created"] >> fb->created;
data["expires"] >> fb->expires;
Anope::string t;
data["type"] >> t;
fb->type = StringToType(t);
fb->mask = data.Load("mask");
fb->creator = data.Load("creator");
fb->reason = data.Load("reason");
fb->created = data.Load<time_t>("created");
fb->expires = data.Load<time_t>("expires");
fb->type = StringToType(data.Load("type"));
if (fb->type == OperServ::FT_SIZE)
return NULL;
@@ -325,7 +323,7 @@ public:
for (const auto &[_, user] : UserListByNick)
module->OnUserNickChange(user, "");
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end;)
for (auto it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end;)
{
NickAlias *na = it->second;
++it;
@@ -346,7 +344,7 @@ public:
{
int chan_matches = 0, ci_matches = 0;
for (channel_map::const_iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
for (auto it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end;)
{
Channel *c = it->second;
++it;
@@ -369,7 +367,7 @@ public:
++chan_matches;
for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;)
for (auto cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end;)
{
User *u = cit->first;
++cit;
@@ -383,7 +381,7 @@ public:
}
}
for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(); it != RegisteredChannelList->end();)
for (auto it = RegisteredChannelList->begin(); it != RegisteredChannelList->end();)
{
ChannelInfo *ci = it->second;
++it;
+4 -4
View File
@@ -66,10 +66,10 @@ Serializable *IgnoreDataTypeImpl::Unserialize(Serializable *obj, Serialize::Data
OperServ::ignore_service->AddIgnore(ign);
}
data["mask"] >> ign->mask;
data["creator"] >> ign->creator;
data["reason"] >> ign->reason;
data["time"] >> ign->time;
ign->mask = data.Load("mask");
ign->creator = data.Load("creator");
ign->reason = data.Load("reason");
ign->time = data.Load<time_t>("time");
return ign;
}
+10 -11
View File
@@ -77,10 +77,10 @@ OperInfoImpl::~OperInfoImpl()
Extensible *e = OperInfos::Find(target);
if (e)
{
OperInfos *op = e->GetExt<OperInfos>("operinfo");
auto *op = e->GetExt<OperInfos>("operinfo");
if (op)
{
std::vector<OperInfo *>::iterator it = std::find((*op)->begin(), (*op)->end(), this);
auto it = std::find((*op)->begin(), (*op)->end(), this);
if (it != (*op)->end())
(*op)->erase(it);
}
@@ -89,14 +89,13 @@ OperInfoImpl::~OperInfoImpl()
Serializable *OperInfoTypeImpl::Unserialize(Serializable *obj, Serialize::Data &data) const
{
Anope::string starget;
data["target"] >> starget;
const auto starget = data.Load("target");
Extensible *e = OperInfos::Find(starget);
if (!e)
return NULL;
OperInfos *oi = e->Require<OperInfos>("operinfo");
auto *oi = e->Require<OperInfos>("operinfo");
OperInfoImpl *o;
if (obj)
o = anope_dynamic_static_cast<OperInfoImpl *>(obj);
@@ -105,9 +104,9 @@ Serializable *OperInfoTypeImpl::Unserialize(Serializable *obj, Serialize::Data &
o = new OperInfoImpl();
o->target = starget;
}
data["info"] >> o->info;
data["adder"] >> o->adder;
data["created"] >> o->created;
o->info = data.Load("info");
o->adder = data.Load("adder");
o->created = data.Load<time_t>("created");
if (!obj)
(*oi)->push_back(o);
@@ -162,7 +161,7 @@ public:
return;
}
OperInfos *oi = e->Require<OperInfos>("operinfo");
auto *oi = e->Require<OperInfos>("operinfo");
if ((*oi)->size() >= Config->GetModule(this->module).Get<unsigned>("max", "10"))
{
@@ -195,7 +194,7 @@ public:
return;
}
OperInfos *oi = e->GetExt<OperInfos>("operinfo");
auto *oi = e->GetExt<OperInfos>("operinfo");
if (!oi)
{
@@ -234,7 +233,7 @@ public:
}
else if (cmd.equals_ci("CLEAR"))
{
OperInfos *oi = e->GetExt<OperInfos>("operinfo");
auto *oi = e->GetExt<OperInfos>("operinfo");
if (!oi)
{
+1 -1
View File
@@ -46,7 +46,7 @@ public:
IRCD->SendSquit(server, rbuf);
server->Delete(rbuf);
}
auto *juped_server = new Server(Me, jserver, 1, rbuf, sid, true);
auto *juped_server = new Server(Me, jserver, rbuf, sid, 1, true);
IRCD->SendServer(juped_server);
Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")";
+1 -1
View File
@@ -202,7 +202,7 @@ public:
source.Reply(_("Users list:"));
for (Anope::map<User *>::const_iterator it = ordered_map.begin(); it != ordered_map.end(); ++it)
for (auto it = ordered_map.begin(); it != ordered_map.end(); ++it)
{
User *u2 = it->second;
+2 -2
View File
@@ -77,7 +77,7 @@ public:
Anope::string GetDesc(CommandSource &source) const override
{
return Anope::Format(Language::Translate(source.GetAccount(), _("Login to %s")), source.service->nick.c_str());
return Anope::Format(source.Translate(_("Login to %s")), source.service->nick.c_str());
}
};
@@ -123,7 +123,7 @@ public:
Anope::string GetDesc(CommandSource &source) const override
{
return Anope::Format(Language::Translate(source.GetAccount(), _("Logout from %s")), source.service->nick.c_str());
return Anope::Format(source.Translate(_("Logout from %s")), source.service->nick.c_str());
}
};
+5 -7
View File
@@ -130,12 +130,10 @@ struct NewsItemType final
else
ni = new OperServ::NewsItem();
Anope::string t;
data["type"] >> t;
ni->type = StringToType(t);
data["text"] >> ni->text;
data["who"] >> ni->who;
data["time"] >> ni->time;
ni->type = StringToType(data.Load("type"));
ni->text = data.Load("text");
ni->who = data.Load("who");
ni->time = data.Load<time_t>("time");
if (!obj)
OperServ::news_service->AddNewsItem(ni);
@@ -265,7 +263,7 @@ protected:
source.Reply(READ_ONLY_MODE);
if (!text.equals_ci("ALL"))
{
unsigned num = Anope::Convert<unsigned>(text, 0);
auto num = Anope::Convert<unsigned>(text, 0);
if (num > 0 && num <= list.size())
{
OperServ::news_service->DelNewsItem(list[num - 1]);
+5 -8
View File
@@ -32,15 +32,11 @@ struct OSOperType
Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override
{
Anope::string stype, sname;
data["type"] >> stype;
data["name"] >> sname;
OperType *ot = OperType::Find(stype);
auto *ot = OperType::Find(data.Load("type"));
if (ot == NULL)
return NULL;
NickCore *nc = NickCore::Find(sname);
auto *nc = NickCore::Find(data.Load("name"));
if (nc == NULL)
return NULL;
@@ -49,6 +45,7 @@ struct OSOperType
myo = anope_dynamic_static_cast<OperServ::Oper *>(obj);
else
myo = new OperServ::Oper(nc->display, ot);
nc->o = myo;
Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
return myo;
@@ -169,7 +166,7 @@ public:
if (!nc->o)
continue;
source.Reply(_("%-8s %s"), nc->o->name.c_str(), nc->o->ot->GetName().c_str());
source.Reply("%-8s %s", nc->o->name.c_str(), nc->o->ot->GetName().c_str());
if (std::find(Config->Opers.begin(), Config->Opers.end(), nc->o) != Config->Opers.end())
source.Reply(_(" This oper is configured in the configuration file."));
for (auto *u : nc->users)

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