mirror of
https://github.com/anope/anope.git
synced 2026-07-10 16:03:15 +02:00
Compare commits
38 Commits
d1f6da1817
...
2.1.25
| Author | SHA1 | Date | |
|---|---|---|---|
| c9f199d7c8 | |||
| 1338316152 | |||
| 076af6bba9 | |||
| d3bf09b65b | |||
| 9b609c1ccb | |||
| cf05a92401 | |||
| 673b04f1fc | |||
| 215eba2704 | |||
| eb37dd0af1 | |||
| 58e278410d | |||
| 13f99f1ca7 | |||
| f15f8e3454 | |||
| ff52ade0cc | |||
| 4c81f45232 | |||
| cdccfaf99a | |||
| e47d379d98 | |||
| c784f08002 | |||
| 6de2ae0046 | |||
| c26f742662 | |||
| e3bff85339 | |||
| 5819c1fcf3 | |||
| 4b8f073cb7 | |||
| 67026b184d | |||
| b49f984598 | |||
| b9cacf1d0f | |||
| 09d0bd6987 | |||
| f150ee857f | |||
| d60c80a4a3 | |||
| 44b7493eb1 | |||
| a03e765172 | |||
| 17cd10ef21 | |||
| ca8fcbe119 | |||
| b9d0762f2b | |||
| 4878b1787e | |||
| 0163d92b1d | |||
| a861a059f6 | |||
| 90da25f84f | |||
| ab362c9828 |
@@ -11,7 +11,7 @@ jobs:
|
||||
container: alpine:latest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install dependencies
|
||||
run: |-
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ubuntu ci]')"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install dependencies
|
||||
run: |-
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
CONAN_FILE: ${{ github.workspace }}\src\win32\conanfile.txt
|
||||
CONAN_HOME: ${{ github.workspace }}\build\conan
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Setup MSVC
|
||||
uses: TheMrMilchmann/setup-msvc-dev@v4
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
|
||||
- name: Try to restore libraries from the cache
|
||||
if: github.event_name != 'release'
|
||||
uses: actions/cache/restore@v5
|
||||
uses: actions/cache/restore@v6
|
||||
id: library-cache
|
||||
with:
|
||||
key: Conan VS${{ env.VisualStudioVersion }} ${{ env.BUILD_TYPE }} ${{ hashFiles(env.CONAN_FILE) }}
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
|
||||
- name: Save libraries to the cache
|
||||
if: steps.library-cache.outputs.cache-hit != 'true' && github.event_name != 'release'
|
||||
uses: actions/cache/save@v5
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: ${{ steps.library-cache.outputs.cache-primary-key }}
|
||||
path: ${{ env.CONAN_HOME }}\p
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
name: irctest
|
||||
|
||||
# Last checked: 2026-06-29
|
||||
env:
|
||||
INSPIRCD_REF: v4.11.0 # 2026-06-06
|
||||
IRCTEST_REF: ff6ef19d96cacd79ea8033dda2cf660fe5cdba52 # 2026-06-20
|
||||
SOLANUM_REF: a17cc145a7de564e49b84807d335289f30b12d00 # 2026-06-23
|
||||
UNREALIRCD_REF: 1250b7f014dbbe1dae13138dbef6e52c6dcd5557 # 2026-05-15 (6.2.5)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
schedule:
|
||||
- cron: 0 0 * * 0
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-skip:
|
||||
if: "!contains(github.event.head_commit.message, '[skip irctest ci]')"
|
||||
runs-on: ubuntu-26.04-arm
|
||||
steps:
|
||||
- run: true # Avoids skip check duplication.
|
||||
|
||||
build-anope:
|
||||
needs:
|
||||
- check-skip
|
||||
runs-on: ubuntu-26.04-arm
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Build
|
||||
run: |-
|
||||
sudo apt-get install build-essential cmake --assume-yes
|
||||
cmake \
|
||||
-B "${{ github.workspace }}/build" \
|
||||
-D "CMAKE_UNITY_BUILD=ON" \
|
||||
-D "CMAKE_UNITY_BUILD_BATCH_SIZE=0" \
|
||||
-D "INSTDIR=$HOME/software/anope" \
|
||||
-G "Ninja" \
|
||||
-S "${{ github.workspace }}"
|
||||
ninja -C "${{ github.workspace }}/build" install
|
||||
|
||||
- name: Make artifact
|
||||
run: |-
|
||||
tar \
|
||||
--auto-compress \
|
||||
--create \
|
||||
--file installed-anope.tar.gz \
|
||||
$HOME/software/anope
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: installed-anope
|
||||
path: installed-anope.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
build-inspircd:
|
||||
needs:
|
||||
- check-skip
|
||||
runs-on: ubuntu-26.04-arm
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ env.INSPIRCD_REF }}
|
||||
repository: inspircd/inspircd
|
||||
|
||||
- name: Build
|
||||
run: |-
|
||||
sudo apt-get install build-essential --assume-yes
|
||||
./configure \
|
||||
--development \
|
||||
--disable-auto-extras \
|
||||
--prefix $HOME/software/inspircd
|
||||
export CXXFLAGS="-DINSPIRCD_UNLIMITED_MAINLOOP"
|
||||
make -j$(($(getconf _NPROCESSORS_ONLN) + 1)) install
|
||||
|
||||
- name: Make artifact
|
||||
run: |-
|
||||
tar \
|
||||
--auto-compress \
|
||||
--create \
|
||||
--file installed-inspircd.tar.gz \
|
||||
$HOME/software/inspircd
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: installed-inspircd
|
||||
path: installed-inspircd.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
build-solanum:
|
||||
needs:
|
||||
- check-skip
|
||||
runs-on: ubuntu-26.04-arm
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ env.SOLANUM_REF }}
|
||||
repository: solanum-ircd/solanum
|
||||
|
||||
- name: Build
|
||||
run: |-
|
||||
sudo apt-get install build-essential libltdl-dev --assume-yes
|
||||
./autogen.sh
|
||||
./configure \
|
||||
--enable-fhs-paths \
|
||||
--prefix $HOME/software/solanum
|
||||
make -j$(($(getconf _NPROCESSORS_ONLN) + 1)) install
|
||||
|
||||
- name: Make artifact
|
||||
run: |-
|
||||
tar \
|
||||
--auto-compress \
|
||||
--create \
|
||||
--file installed-solanum.tar.gz \
|
||||
$HOME/software/solanum
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: installed-solanum
|
||||
path: installed-solanum.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
build-unrealircd:
|
||||
needs:
|
||||
- check-skip
|
||||
runs-on: ubuntu-26.04-arm
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ env.UNREALIRCD_REF }}
|
||||
repository: unrealircd/unrealircd
|
||||
|
||||
- name: Build
|
||||
run: |-
|
||||
sudo apt-get install build-essential libssl-dev --assume-yes
|
||||
wget --output-document src/modules/third/metadata2.c https://raw.githubusercontent.com/progval/unrealircd-contrib/metadata2/files/metadata2.c
|
||||
echo "BASEPATH=$HOME/software/unrealircd" >> config.settings
|
||||
echo "GEOIP=none" >> config.settings
|
||||
yes "" | ./Config
|
||||
make -j$(($(getconf _NPROCESSORS_ONLN) + 1)) install
|
||||
|
||||
- name: Make artifact
|
||||
run: |-
|
||||
tar \
|
||||
--auto-compress \
|
||||
--create \
|
||||
--file installed-unrealircd.tar.gz \
|
||||
$HOME/software/unrealircd
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: installed-unrealircd
|
||||
path: installed-unrealircd.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-26.04-arm
|
||||
needs:
|
||||
- build-anope
|
||||
- build-inspircd
|
||||
- build-solanum
|
||||
- build-unrealircd
|
||||
steps:
|
||||
- name: Download Anope artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: installed-anope
|
||||
|
||||
- name: Download server artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: installed-${{ matrix.server }}
|
||||
|
||||
- name: Unpack artifacts
|
||||
run: |-
|
||||
for ARCHIVE in installed-anope installed-${{ matrix.server }}
|
||||
do
|
||||
tar \
|
||||
--directory / \
|
||||
--extract \
|
||||
--file ${ARCHIVE}.tar.gz
|
||||
done
|
||||
for SOFTWARE in $HOME/software/*
|
||||
do
|
||||
echo "Adding ${SOFTWARE} to the PATH"
|
||||
export PATH=$SOFTWARE/bin:$SOFTWARE/sbin:$PATH
|
||||
done
|
||||
echo PATH=$PATH >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout irctest
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ env.IRCTEST_REF }}
|
||||
repository: progval/irctest
|
||||
|
||||
- name: Install irctest dependencies
|
||||
run: |-
|
||||
sudo apt-get install faketime
|
||||
pip3 install --requirement requirements.txt pytest-xdist pytest-timeout
|
||||
|
||||
- name: Run irctest
|
||||
env:
|
||||
IRCTEST_DEBUG_LOGS: ${{ runner.debug }}
|
||||
PYTEST_ARGS: --color=yes --verbose
|
||||
run: |-
|
||||
make ${{ matrix.server}}-anope
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
server:
|
||||
- inspircd
|
||||
- solanum
|
||||
- unrealircd
|
||||
+40
-29
@@ -1,8 +1,8 @@
|
||||
# This usage of CMake requires at least version 3.20
|
||||
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
|
||||
|
||||
# Set the project as C++ primarily
|
||||
project(Anope CXX)
|
||||
# Set the project as C++ primarily with C for the vendored libraries
|
||||
project(Anope CXX C)
|
||||
|
||||
# Force the locale to C for later uses of things like gcc so the messages come up in English, not the user's default language
|
||||
set(ENV{LC_ALL} C)
|
||||
@@ -25,6 +25,7 @@ include(CheckFunctionExists)
|
||||
include(CheckTypeSize)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckPIESupported)
|
||||
|
||||
if(NOT WIN32)
|
||||
include(FindPkgConfig)
|
||||
@@ -40,6 +41,10 @@ if(EXTRA_LIBS)
|
||||
link_directories(${EXTRA_LIBS})
|
||||
endif()
|
||||
|
||||
# Enable -fPIC for all targets.
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
check_pie_supported()
|
||||
|
||||
# Find gettext
|
||||
find_package(Gettext)
|
||||
find_package(Intl)
|
||||
@@ -144,28 +149,37 @@ elseif(NOT CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/anope-${VERSION_MAJOR}-${VERSION_MINOR}")
|
||||
endif()
|
||||
|
||||
function(configure_path VARIABLE DEFAULT)
|
||||
if(NOT DEFINED ${VARIABLE})
|
||||
set(${VARIABLE} ${DEFAULT} CACHE PATH "Location of the ${DEFAULT} directory")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(ABSOLUTE_${VARIABLE} ${${VARIABLE}})
|
||||
else()
|
||||
cmake_path(
|
||||
APPEND CMAKE_INSTALL_PREFIX "${${VARIABLE}}"
|
||||
OUTPUT_VARIABLE ABSOLUTE_${VARIABLE}
|
||||
)
|
||||
cmake_path(NORMAL_PATH ABSOLUTE_${VARIABLE})
|
||||
endif()
|
||||
set(ABSOLUTE_${VARIABLE} ${ABSOLUTE_${VARIABLE}} CACHE INTERNAL "" FORCE)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
DESTINATION ${${VARIABLE}}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Set default paths for various directories if not already defined
|
||||
if(NOT BIN_DIR)
|
||||
set(BIN_DIR "bin")
|
||||
endif()
|
||||
if(NOT DATA_DIR)
|
||||
set(DATA_DIR "data")
|
||||
endif()
|
||||
if(NOT DOC_DIR)
|
||||
set(DOC_DIR "doc")
|
||||
endif()
|
||||
if(NOT CONF_DIR)
|
||||
set(CONF_DIR "conf")
|
||||
endif()
|
||||
if(NOT MODULE_DIR)
|
||||
set(MODULE_DIR "modules")
|
||||
endif()
|
||||
if(NOT LOCALE_DIR)
|
||||
set(LOCALE_DIR "locale")
|
||||
endif()
|
||||
if(NOT LOG_DIR)
|
||||
set(LOG_DIR "logs")
|
||||
endif()
|
||||
configure_path(BIN_DIR "bin")
|
||||
configure_path(DATA_DIR "data")
|
||||
configure_path(DOC_DIR "doc")
|
||||
configure_path(CONF_DIR "conf")
|
||||
configure_path(MODULE_DIR "modules")
|
||||
configure_path(LOCALE_DIR "locale")
|
||||
configure_path(LOG_DIR "logs")
|
||||
|
||||
# Version number processing
|
||||
# Find all lines in src/version.sh that start with VERSION_
|
||||
@@ -218,12 +232,9 @@ set(SERVICES_BINARY "$<TARGET_FILE:${PROGRAM_NAME}>")
|
||||
cmake_path(GET SERVICES_BINARY FILENAME SERVICES_BINARY)
|
||||
|
||||
# At install time, create the following additional directories
|
||||
file(REAL_PATH ${DATA_DIR} ABSOLUTE_DATA_DIR BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX})
|
||||
file(REAL_PATH ${LOG_DIR} ABSOLUTE_LOG_DIR BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX})
|
||||
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ABSOLUTE_DATA_DIR}/backups\")")
|
||||
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ABSOLUTE_LOG_DIR}\")")
|
||||
install(DIRECTORY DESTINATION "${DATA_DIR}/backups")
|
||||
if(WIN32)
|
||||
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ABSOLUTE_DATA_DIR}/runtime\")")
|
||||
install(DIRECTORY DESTINATION "${DATA_DIR}/runtime")
|
||||
endif()
|
||||
# On non-Windows platforms, if RUNGROUP is set, change the permissions of the below directories, as well as the group of the data directory
|
||||
if(NOT WIN32 AND RUNGROUP)
|
||||
@@ -238,7 +249,6 @@ if(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
file(REAL_PATH ${MODULE_DIR} ABSOLUTE_MODULE_DIR BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX})
|
||||
install(CODE "file(REMOVE_RECURSE \"$ENV{DESTDIR}${ABSOLUTE_MODULE_DIR}\")")
|
||||
|
||||
# Only process the CPack section if we have CPack
|
||||
@@ -289,6 +299,7 @@ endif()
|
||||
add_subdirectory(data)
|
||||
add_subdirectory(docs)
|
||||
add_subdirectory(language)
|
||||
add_subdirectory(vendor)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(modules)
|
||||
add_subdirectory(include)
|
||||
|
||||
@@ -201,6 +201,19 @@ module
|
||||
{
|
||||
name = "hs_request"
|
||||
|
||||
|
||||
/*
|
||||
* How long after a requested vhost is activated does a user have to wait
|
||||
* before they can request a new vhost. Defaults to 24 hours.
|
||||
*/
|
||||
#activationcooldown = 24h
|
||||
|
||||
/*
|
||||
* How long after a requested vhost is rejected does a user have to wait
|
||||
* before they can request a new vhost. Defaults to 24 hours.
|
||||
*/
|
||||
#rejectioncooldown = 24h
|
||||
|
||||
/*
|
||||
* If set, Anope will send a memo to the user requesting a vhost when it's been
|
||||
* approved or rejected.
|
||||
|
||||
@@ -120,6 +120,10 @@ module
|
||||
* - ns_keep_modes: Enables keepmodes, which retains user modes across sessions
|
||||
* - protect: Protects the registered nickname from use by unidentified users.
|
||||
* - ns_stats: Enable Chanstats for newly registered nicks
|
||||
* - ns_flexible: Set FLEXIBLE as layout for messages from services (can not be set at the same
|
||||
* time as ns_monospace)
|
||||
* - ns_monospace: Set MONOSPACE as layout for messages from services (can not be set as the same
|
||||
* time as ns_flexible)
|
||||
*
|
||||
* This directive is optional, if left blank, the options will default to memo_signon, and
|
||||
* memo_receive. If you really want no defaults, use "none" by itself as the option.
|
||||
|
||||
+64
-4
@@ -1,21 +1,81 @@
|
||||
# Anope Change Log
|
||||
|
||||
## Anope 2.1.25 (unreleased)
|
||||
## Anope 2.1.25 (2026-07-10)
|
||||
|
||||
### Changes
|
||||
### General Changes
|
||||
|
||||
* Added a cooldown timer to `hs_request` for after a vhost is approved or rejected.
|
||||
|
||||
* Added environment variables for configuring hashing algorithms to `anope-mkpasswd`.
|
||||
|
||||
* Added support for building with position-independent code on supported platforms.
|
||||
|
||||
* Added support for prioritising WHOIS entries in `ns_set_misc`.
|
||||
|
||||
* Documented the `ns_flexible` and `ns_monospace` account options.
|
||||
|
||||
* Dropped support for the `+draft/reply` tag in favour of the non-draft variant.
|
||||
|
||||
* Fixed a crash on shutdown when trying to send a global without an uplink.
|
||||
|
||||
* Fixed a crash when a temporary ban expires.
|
||||
|
||||
* Fixed a crash when trying to upgrade TLS fingerprints from an older algorithm.
|
||||
|
||||
* Fixed a potential crash caused by unusual timestamps being passed to `Anope::strftime`.
|
||||
|
||||
* Fixed confirming accounts when `{ns_register}:registration` is set to "admin".
|
||||
|
||||
* Fixed migrating access entries from xop to flags granting new privileges in cases where multiple privileges share the same flag.
|
||||
* Fixed edge cases relating to IRCd-sent account names.
|
||||
|
||||
* Fixed migrating access entries sometimes giving the wrong flags.
|
||||
* Fixed extra CMake arguments from `./Config` being ignored.
|
||||
|
||||
* Fixed flag migration sometimes giving users higher privileges than they had originally when a flag provides multiple privileges.
|
||||
|
||||
* Fixed not being able to update the description of a flags access entry.
|
||||
|
||||
* Fixed not migrating the last seen time with an access entry.
|
||||
|
||||
* Fixed not using the extra CMake arguments from `./Config`.
|
||||
|
||||
* Fixed some command descriptions not being imperative statements.
|
||||
|
||||
* Fixed some help messages that did not reflect the default flag/level/xop access when changed in the configuration.
|
||||
|
||||
* Fixed the default memory hardness in the `enc_argon2` module.
|
||||
|
||||
* Improved configuring paths at build time.
|
||||
|
||||
* Improved help output for the `nickserv/set/timezone` command.
|
||||
|
||||
* Improved importing databases from Atheme.
|
||||
|
||||
* Improved support for reproducible builds.
|
||||
|
||||
* Redocumented the `nickserv/set/keepmodes` command.
|
||||
|
||||
* Separated the delay between nickname registrations from the delay between grouping nicknames.
|
||||
|
||||
* Updated the Portuguese translation.
|
||||
|
||||
* Updated the Romanian translation.
|
||||
|
||||
### Developer Changes
|
||||
|
||||
* Added `Block::GetBlocks` to allow using a range-based for loop to iterate config blocks.
|
||||
|
||||
* Added an event to `IRCDProto` to populate common tags onto a S2S message.
|
||||
|
||||
* Added automated testing on InspIRCd, Solanum, and UnrealIRCd using irctest.
|
||||
|
||||
* Added support for adding ajoin entries from modules.
|
||||
|
||||
* Changed various configuration block index fields to use an unsigned integer.
|
||||
|
||||
* Changed vendored libraries to be built as static libraries and linked into the modules that require them.
|
||||
|
||||
* Simplified timer repeat logic by allowing tick events to return bool to control whether the timer continues running.
|
||||
|
||||
## Anope 2.1.24 (2026-04-01)
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
@@ -362,10 +362,6 @@ namespace Anope
|
||||
template<typename T>
|
||||
using unordered_map = std::unordered_map<string, T, hash_ci, compare>;
|
||||
|
||||
#if !REPRODUCIBLE_BUILD
|
||||
static const char *const compiled = __TIME__ " " __DATE__;
|
||||
#endif
|
||||
|
||||
/** The time Anope started.
|
||||
*/
|
||||
extern CoreExport time_t StartTime;
|
||||
|
||||
+13
-10
@@ -18,6 +18,7 @@
|
||||
#include "regchannel.h"
|
||||
#include "users.h"
|
||||
#include "opertype.h"
|
||||
#include "miscutils.h"
|
||||
|
||||
namespace Configuration
|
||||
{
|
||||
@@ -26,14 +27,15 @@ namespace Configuration
|
||||
friend class Configuration::Conf;
|
||||
|
||||
public:
|
||||
typedef Anope::map<Anope::string> item_map;
|
||||
typedef Anope::multimap<Block> block_map;
|
||||
typedef Anope::map<Anope::string> ItemMap;
|
||||
typedef Anope::multimap<Block> BlockMap;
|
||||
typedef Anope::iterator_range<BlockMap::const_iterator> BlockList;
|
||||
|
||||
private:
|
||||
Anope::string name;
|
||||
item_map items;
|
||||
block_map blocks;
|
||||
int linenum;
|
||||
ItemMap items;
|
||||
BlockMap blocks;
|
||||
unsigned linenum;
|
||||
|
||||
/* Represents a missing tag. */
|
||||
static Block EmptyBlock;
|
||||
@@ -41,9 +43,10 @@ namespace Configuration
|
||||
public:
|
||||
Block(const Anope::string &);
|
||||
const Anope::string &GetName() const;
|
||||
int CountBlock(const Anope::string &name) const;
|
||||
const Block &GetBlock(const Anope::string &name, int num = 0) const;
|
||||
Block *GetMutableBlock(const Anope::string &name, int num = 0);
|
||||
size_t CountBlock(const Anope::string &name) const;
|
||||
BlockList GetBlocks(const Anope::string &name) const;
|
||||
const Block &GetBlock(const Anope::string &name, size_t num = 0) const;
|
||||
Block *GetMutableBlock(const Anope::string &name, size_t num = 0);
|
||||
|
||||
template<typename T> T Get(const Anope::string &tag, const Anope::string &def = "") const
|
||||
{
|
||||
@@ -51,7 +54,7 @@ namespace Configuration
|
||||
}
|
||||
|
||||
bool Set(const Anope::string &tag, const Anope::string &value);
|
||||
const item_map &GetItems() const;
|
||||
const ItemMap &GetItems() const;
|
||||
};
|
||||
|
||||
template<> CoreExport const Anope::string Block::Get(const Anope::string &tag, const Anope::string &def) const;
|
||||
@@ -85,7 +88,7 @@ namespace Configuration
|
||||
{
|
||||
private:
|
||||
/** Replaces defined variables within a string. */
|
||||
Anope::string ReplaceVars(const Anope::string &str, const File &file, int linenumber);
|
||||
Anope::string ReplaceVars(const Anope::string &str, const File &file, unsigned linenumber);
|
||||
|
||||
public:
|
||||
/* options:readtimeout */
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// 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
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
namespace Anope
|
||||
{
|
||||
template <typename Iterator>
|
||||
class iterator_range;
|
||||
|
||||
/** Returns a range containing all elements equivalent to \p value.
|
||||
* @param collection The collection to search within.
|
||||
* @param value The value to search for.
|
||||
*/
|
||||
template <typename Collection, typename Value>
|
||||
auto equal_range(const Collection& collection, const Value& value)
|
||||
{
|
||||
return iterator_range(collection.equal_range(value));
|
||||
}
|
||||
|
||||
/** Returns a range representing a reverse iterator for the specified colleciton.
|
||||
* @param collection The collection to create a reverse iterator for.
|
||||
*/
|
||||
template <typename Collection>
|
||||
auto reverse_range(const Collection& collection)
|
||||
{
|
||||
return iterator_range(collection.rbegin(), collection.rend());
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a range of iterators. */
|
||||
template <typename Iterator>
|
||||
class Anope::iterator_range final
|
||||
{
|
||||
private:
|
||||
/** An iterator which points to the start of the range. */
|
||||
const Iterator begini;
|
||||
|
||||
/* An iterator which points to one past the end of the range. */
|
||||
const Iterator endi;
|
||||
|
||||
public:
|
||||
/** Initialises a new iterator range with the specified iterators.
|
||||
* @param begin An iterator which points to the start of the range.
|
||||
* @param end An iterator which points to one past the end of the range.
|
||||
*/
|
||||
explicit iterator_range(Iterator begin, Iterator end)
|
||||
: begini(begin)
|
||||
, endi(end)
|
||||
{
|
||||
}
|
||||
|
||||
/** Initialises a new iterator range from a pair of iterators.
|
||||
* @param range A pair of iterators in the format [first, last).
|
||||
*/
|
||||
explicit iterator_range(std::pair<Iterator, Iterator> range)
|
||||
: begini(range.first)
|
||||
, endi(range.second)
|
||||
{
|
||||
}
|
||||
|
||||
/** Determines whether the iterator range is empty. */
|
||||
bool empty() const { return begini == endi; }
|
||||
|
||||
/** Retrieves an iterator which points to the start of the range. */
|
||||
const Iterator& begin() const { return begini; }
|
||||
|
||||
/** Retrieves an iterator which points to one past the end of the range. */
|
||||
const Iterator& end() const { return endi; }
|
||||
|
||||
/** Retrieves the number of hops within the iterator range. */
|
||||
typename std::iterator_traits<Iterator>::difference_type count() const { return std::distance(begini, endi); }
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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
|
||||
|
||||
#define NICKSERV_AJOIN_LIST_EXT "ajoinlist"
|
||||
|
||||
struct AJoinEntry;
|
||||
|
||||
struct AJoinList
|
||||
: Serialize::Checker<std::vector<AJoinEntry *> >
|
||||
{
|
||||
AJoinList(Extensible *) : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
|
||||
virtual ~AJoinList() = default;
|
||||
};
|
||||
|
||||
struct AJoinEntry final
|
||||
: Serializable
|
||||
{
|
||||
Serialize::Reference<NickCore> owner;
|
||||
Anope::string channel;
|
||||
Anope::string key;
|
||||
|
||||
AJoinEntry(Extensible *) : Serializable("AJoinEntry") { }
|
||||
|
||||
~AJoinEntry() override
|
||||
{
|
||||
auto *channels = owner->GetExt<AJoinList>(NICKSERV_AJOIN_LIST_EXT);
|
||||
if (channels)
|
||||
{
|
||||
auto it = std::find((*channels)->begin(), (*channels)->end(), this);
|
||||
if (it != (*channels)->end())
|
||||
(*channels)->erase(it);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -58,6 +58,14 @@ public:
|
||||
*/
|
||||
virtual bool Parse(const Anope::string &message, Anope::map<Anope::string> &tags, Anope::string &source, Anope::string &command, std::vector<Anope::string> ¶ms);
|
||||
|
||||
/* Populates the tags that should be sent on all messages.
|
||||
* @param tags The location to store tags.
|
||||
* @param source Source of the message.
|
||||
* @param command Command name.
|
||||
* @param params Any extra parameters.
|
||||
*/
|
||||
virtual void PopulateTags(Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, const std::vector<Anope::string> ¶ms);
|
||||
|
||||
/* Formats an outgoing message so it can be sent to the IRC server.
|
||||
* @param message The location to store the formatted message.
|
||||
* @param tags IRCv3 message tags.
|
||||
|
||||
@@ -79,6 +79,12 @@ namespace Anope
|
||||
*/
|
||||
extern CoreExport Anope::string FormatCTCP(const Anope::string &name, const Anope::string &body = "");
|
||||
|
||||
/** Formats a date/time as an IS0 8601 timestamp.
|
||||
* @param ts UNIX timestamp to format.
|
||||
* @param ms Number of milliseconds to format.
|
||||
*/
|
||||
extern CoreExport Anope::string FormatISO8601(time_t ts, unsigned long long ms);
|
||||
|
||||
/** Parses a CTCP message received from a client.
|
||||
* @param text The raw message to parse.
|
||||
* @param name The location to store the name of the CTCP.
|
||||
|
||||
+17
-2
@@ -18,6 +18,8 @@
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include "sysconf.h"
|
||||
|
||||
static std::string get_git_hash(const std::string &git_dir)
|
||||
{
|
||||
std::fstream fd;
|
||||
@@ -78,14 +80,18 @@ static bool read_version_sh(const std::string &version_sh, std::map<std::string,
|
||||
|
||||
static bool write_build_h(const std::string &buildh, const std::string &git_version)
|
||||
{
|
||||
std::fstream fd(buildh.c_str(), std::ios::in);
|
||||
std::fstream fd;
|
||||
|
||||
std::string build = "#define BUILD 1";
|
||||
|
||||
#if !REPRODUCIBLE_BUILD
|
||||
fd.open(buildh.c_str(), std::ios::in);
|
||||
|
||||
if (fd.is_open())
|
||||
{
|
||||
for (std::string filebuf; getline(fd, filebuf);)
|
||||
{
|
||||
if (!filebuf.find("#define BUILD"))
|
||||
if (!filebuf.find("#define BUILD\t"))
|
||||
{
|
||||
size_t tab = filebuf.find(' ');
|
||||
|
||||
@@ -101,6 +107,8 @@ static bool write_build_h(const std::string &buildh, const std::string &git_vers
|
||||
}
|
||||
|
||||
fd.clear();
|
||||
#endif
|
||||
|
||||
fd.open(buildh.c_str(), std::ios::out);
|
||||
if (!fd.is_open())
|
||||
{
|
||||
@@ -111,6 +119,13 @@ static bool write_build_h(const std::string &buildh, const std::string &git_vers
|
||||
fd << "/* This file is automatically generated by version.cpp - do not edit it! */" << std::endl
|
||||
<< "#pragma once" << std::endl
|
||||
<< build << std::endl;
|
||||
#if !REPRODUCIBLE_BUILD
|
||||
auto time_now = time(NULL);
|
||||
auto *local_tm = localtime(&time_now);
|
||||
char buffer[100];
|
||||
strftime(buffer, sizeof(buffer), "%a %b %e %Y %T %Z", local_tm);
|
||||
fd << "#define BUILD_DATE \"" << buffer << "\"" << std::endl;
|
||||
#endif
|
||||
if (!git_version.empty())
|
||||
fd << "#define VERSION_GIT \"" << git_version << "\"" << std::endl;
|
||||
fd.close();
|
||||
|
||||
+216
-205
@@ -16,8 +16,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Anope\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-05-21 11:52+0100\n"
|
||||
"PO-Revision-Date: 2026-05-21 11:52+0100\n"
|
||||
"POT-Creation-Date: 2026-07-09 21:01+0100\n"
|
||||
"PO-Revision-Date: 2026-07-09 21:02+0100\n"
|
||||
"Last-Translator: Sadie Powell <sadie@sadiepowell.dev>\n"
|
||||
"Language-Team: English\n"
|
||||
"Language: en_US\n"
|
||||
@@ -146,7 +146,7 @@ msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_mode.cpp
|
||||
#, c-format
|
||||
msgid "%s changed your usermodes to %s."
|
||||
msgid "%s changed your user modes to %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
@@ -1019,6 +1019,13 @@ msgstr ""
|
||||
msgid "user [reason]"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_timezone.cpp
|
||||
#, c-format
|
||||
msgid " %s (%zu timezone)"
|
||||
msgid_plural " %s (%zu timezones)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: ../modules/operserv/os_oper.cpp
|
||||
#, c-format
|
||||
msgid " %s is online using this oper block."
|
||||
@@ -1857,11 +1864,11 @@ msgid "Activate the requested vhost for the given nick."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_on.cpp
|
||||
msgid "Activates the vhost currently assigned to the nick in use. When you use this command any user who performs a /whois on you will see the vhost instead of your real host/IP address."
|
||||
msgid "Activate your assigned vhost"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_on.cpp
|
||||
msgid "Activates your assigned vhost"
|
||||
msgid "Activates the vhost currently assigned to the nick in use. When you use this command any user who performs a /whois on you will see the vhost instead of your real host/IP address."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_badwords.cpp
|
||||
@@ -2351,7 +2358,7 @@ msgid "As a Services Operator, you may drop any nick."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_assign.cpp
|
||||
msgid "Assigns a bot to a channel"
|
||||
msgid "Assign a bot to a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_assign.cpp
|
||||
@@ -2464,6 +2471,10 @@ msgstr ""
|
||||
msgid "Bad words list is now empty."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_ban.cpp
|
||||
msgid "Ban a given nick or mask on a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_set.cpp
|
||||
msgid "Ban expiry may not be longer than 1 day."
|
||||
msgstr ""
|
||||
@@ -2482,10 +2493,6 @@ msgstr ""
|
||||
msgid "Ban type for channel %s is now #%d."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_ban.cpp
|
||||
msgid "Bans a given nick or mask on a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_ban.cpp
|
||||
msgid "Bans a given nick or mask on a channel. An optional expiry may be given to cause services to remove the ban after a set amount of time. Channel founders may ban masks."
|
||||
msgstr ""
|
||||
@@ -2765,7 +2772,7 @@ msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_mode.cpp
|
||||
#, c-format
|
||||
msgid "Changed usermodes of %s to %s."
|
||||
msgid "Changed user modes of %s to %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_bot.cpp
|
||||
@@ -2840,7 +2847,7 @@ msgstr ""
|
||||
|
||||
#: ../src/users.cpp
|
||||
#, c-format
|
||||
msgid "Changing your usermodes to %s"
|
||||
msgid "Changing your user modes to %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/users.cpp
|
||||
@@ -3011,12 +3018,12 @@ msgstr ""
|
||||
msgid "Chanstats statistics are now enabled for your nick."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_seen.cpp
|
||||
msgid "Checks for the last time nick was seen joining, leaving, or changing nick on the network and tells you when and, depending on channel or user settings, where it was."
|
||||
#: ../modules/memoserv/ms_check.cpp
|
||||
msgid "Check if last memo to a nick was read"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_check.cpp
|
||||
msgid "Checks if last memo to a nick was read"
|
||||
#: ../modules/chanserv/cs_seen.cpp
|
||||
msgid "Checks for the last time nick was seen joining, leaving, or changing nick on the network and tells you when and, depending on channel or user settings, where it was."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_check.cpp
|
||||
@@ -3045,25 +3052,73 @@ msgid "Command"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures AMSG kicker"
|
||||
msgid "Configure AMSG kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures badwords kicker"
|
||||
msgid "Configure badwords kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures bolds kicker"
|
||||
msgid "Configure bolds kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_set.cpp
|
||||
msgid "Configure bot options"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure caps kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_log.cpp
|
||||
msgid "Configure channel logging settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure color kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure flood kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure italics kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_keepmodes.cpp
|
||||
msgid "Configure keeping user modes set across connections"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure kickers"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure repeat kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure reverses kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_layout.cpp
|
||||
msgid "Configure the layout used for services messages"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_set.cpp
|
||||
msgid "Configure the time bot bans expire in"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configure underlines kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures bot kickers. option can be one of:"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_set.cpp
|
||||
msgid "Configures bot options"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_set.cpp
|
||||
msgid ""
|
||||
"Configures bot options.\n"
|
||||
@@ -3071,36 +3126,8 @@ msgid ""
|
||||
"Available options:"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures caps kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_log.cpp
|
||||
msgid "Configures channel logging settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures color kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures flood kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures italics kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures kickers"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures repeat kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures reverses kicker"
|
||||
#: ../modules/nickserv/ns_set_keepmodes.cpp
|
||||
msgid "Configures keeping user modes set across connections. If this is enabled, your last user modes will be remembered and will be re-set the next time you identify."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_layout.cpp
|
||||
@@ -3114,10 +3141,6 @@ msgid ""
|
||||
"When the layout is set to MONOSPACE services will format messages similar to FIXED but will prefix all messages with a monospace formatting character to force it to display correctly. This requires client support for monospace text formatting."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_layout.cpp
|
||||
msgid "Configures the layout used for services messages"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_layout.cpp
|
||||
msgid ""
|
||||
"Configures the layout used for services messages.\n"
|
||||
@@ -3129,14 +3152,6 @@ msgid ""
|
||||
"When the layout is set to MONOSPACE services will format messages similar to FIXED but will prefix all messages with a monospace formatting character to force it to display correctly. This requires client support for monospace text formatting."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_set.cpp
|
||||
msgid "Configures the time bot bans expire in"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Configures underlines kicker"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_register.cpp
|
||||
msgid "Confirm a previous account registration"
|
||||
msgstr ""
|
||||
@@ -3325,11 +3340,11 @@ msgid "Date/Time"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_off.cpp
|
||||
msgid "Deactivates the vhost currently assigned to the nick in use. When you use this command any user who performs a /whois on you will see your real host/IP address."
|
||||
msgid "Deactivate your assigned vhost"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_off.cpp
|
||||
msgid "Deactivates your assigned vhost"
|
||||
msgid "Deactivates the vhost currently assigned to the nick in use. When you use this command any user who performs a /whois on you will see your real host/IP address."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_access.cpp
|
||||
@@ -3362,6 +3377,10 @@ msgstr ""
|
||||
msgid "Delete a memo or memos"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_del.cpp
|
||||
msgid "Delete the vhost for all nicks in an account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_del.cpp
|
||||
msgid "Delete the vhost of another user"
|
||||
msgstr ""
|
||||
@@ -3502,10 +3521,6 @@ msgstr ""
|
||||
msgid "Deletes the vhost assigned to the given nick from the database."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_del.cpp
|
||||
msgid "Deletes the vhost for all nicks in an account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_del.cpp
|
||||
msgid "Deletes the vhost for all nicks in the same account as that of the given nick."
|
||||
msgstr ""
|
||||
@@ -3551,6 +3566,46 @@ msgid ""
|
||||
"Reason may be required on certain networks."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_info.cpp
|
||||
msgid "Display information about a given nickname"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_info.cpp
|
||||
msgid "Display information about your memos"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_list.cpp
|
||||
msgid "Display one or more vhost entries"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Display the top 10 users of a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Display the top 10 users of the network"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Display the top 3 users of a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Display the top 3 users of the network"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/help.cpp
|
||||
msgid "Display this list and give information about commands"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_stats.cpp
|
||||
msgid "Display your Channel Stats"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_stats.cpp
|
||||
msgid "Display your Global Stats"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_request.cpp
|
||||
#, c-format
|
||||
msgid "Displayed %d records (%d total)."
|
||||
@@ -3579,26 +3634,14 @@ msgstr ""
|
||||
msgid "Displays any new memos."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_info.cpp
|
||||
msgid "Displays information about a given nickname"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_info.cpp
|
||||
msgid "Displays information about the given nickname, such as the nick's owner, last seen address and time, and nick options. If no nick is given, and you are identified, your account name is used, else your current nickname is used."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_info.cpp
|
||||
msgid "Displays information about your memos"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_read.cpp
|
||||
msgid "Displays memos numbered 2 through 5 and 7 through 9."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_list.cpp
|
||||
msgid "Displays one or more vhost entries"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_cert.cpp
|
||||
msgid "Displays the current certificate list of nickname as well as the details about who added each entry and when they added it."
|
||||
msgstr ""
|
||||
@@ -3607,34 +3650,6 @@ msgstr ""
|
||||
msgid "Displays the current certificate list of nickname."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Displays the top 10 users of a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Displays the top 10 users of the network"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Displays the top 3 users of a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_top.cpp
|
||||
msgid "Displays the top 3 users of the network"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/help.cpp
|
||||
msgid "Displays this list and give information about commands"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_stats.cpp
|
||||
msgid "Displays your Channel Stats"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_fantasy_stats.cpp
|
||||
msgid "Displays your Global Stats"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_cert.cpp
|
||||
msgid "Displays your current certificate list as well the details about who added each entry and when they added it."
|
||||
msgstr ""
|
||||
@@ -3726,10 +3741,6 @@ msgstr ""
|
||||
msgid "Enable greet messages"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_keepmodes.cpp
|
||||
msgid "Enable or disable keep modes"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_info.cpp ../modules/botserv/bs_kick.cpp
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
@@ -3764,11 +3775,7 @@ msgid "Enables or disables keepmodes for the given channel. If keep modes is ena
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_keepmodes.cpp
|
||||
msgid "Enables or disables keepmodes for the given nick. If keep modes is enabled, services will remember users' usermodes and attempt to re-set them the next time they authenticate."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_keepmodes.cpp
|
||||
msgid "Enables or disables keepmodes for your nick. If keep modes is enabled, services will remember your usermodes and attempt to re-set them the next time you authenticate."
|
||||
msgid "Enables or disables keepmodes for the given nick. If keep modes is enabled, services will remember users' user modes and attempt to re-set them the next time they authenticate."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_set.cpp
|
||||
@@ -4145,10 +4152,6 @@ msgstr ""
|
||||
msgid "Greet mode is now on on channel %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_resetpass.cpp
|
||||
msgid "Helps you reset lost passwords"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_info.cpp
|
||||
msgid "Hide certain pieces of nickname information"
|
||||
msgstr ""
|
||||
@@ -4281,7 +4284,7 @@ msgid "Invalid value for LIMIT. Must be numerical."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_invite.cpp
|
||||
msgid "Invites you or an optionally specified nick into a channel"
|
||||
msgid "Invite you or an optionally specified nick into a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
@@ -4311,6 +4314,10 @@ msgstr ""
|
||||
msgid "Key for channel %s is %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_kick.cpp
|
||||
msgid "Kick a specified nick from a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_kick.cpp
|
||||
msgid "Kick a user from a channel"
|
||||
msgstr ""
|
||||
@@ -4320,10 +4327,6 @@ msgstr ""
|
||||
msgid "Kicked %d/%d users matching %s from %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_kick.cpp
|
||||
msgid "Kicks a specified nick from a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_kick.cpp
|
||||
msgid "Kicks a specified nick from a channel. Channel founders can also specify masks."
|
||||
msgstr ""
|
||||
@@ -4439,10 +4442,30 @@ msgstr ""
|
||||
msgid "Limit"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
msgid "List all channel records"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_group.cpp
|
||||
msgid "List all nicknames in your account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_list.cpp
|
||||
msgid "List all registered channels matching the given pattern"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_list.cpp
|
||||
msgid "List all registered nicknames that match a given pattern"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
msgid "List all user records"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_botlist.cpp
|
||||
msgid "List available bots"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_alist.cpp
|
||||
msgid "List channels you have access on"
|
||||
msgstr ""
|
||||
@@ -4452,6 +4475,10 @@ msgstr ""
|
||||
msgid "List for modes %s is full."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_info.cpp
|
||||
msgid "List information about the specified registered channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_modinfo.cpp
|
||||
msgid "List loaded modules"
|
||||
msgstr ""
|
||||
@@ -4535,10 +4562,6 @@ msgstr ""
|
||||
msgid "Lists all bad word entries set on #channel."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
msgid "Lists all channel records"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
msgid ""
|
||||
"Lists all channels currently in use on the IRC network, whether they are registered or not.\n"
|
||||
@@ -4553,18 +4576,10 @@ msgid ""
|
||||
"Channels that have the NOEXPIRE option set will be prefixed by an exclamation mark. The nickname parameter is limited to Services Operators."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_group.cpp
|
||||
msgid "Lists all nicknames in your account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_group.cpp
|
||||
msgid "Lists all nicknames that belong to your account."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_list.cpp
|
||||
msgid "Lists all registered channels matching the given pattern"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_list.cpp
|
||||
msgid ""
|
||||
"Lists all registered channels matching the given pattern. Channels with the PRIVATE option set will only be displayed to Services Operators with the proper access. Channels with the NOEXPIRE option set will have a ! prefixed to the channel for Services Operators to see.\n"
|
||||
@@ -4623,10 +4638,6 @@ msgstr ""
|
||||
msgid "Lists all registered nicks within the given range (51-100)."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
msgid "Lists all user records"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_list.cpp
|
||||
msgid ""
|
||||
"Lists all users currently online on the IRC network, whether their nick is registered or not.\n"
|
||||
@@ -4642,10 +4653,6 @@ msgstr ""
|
||||
msgid "Lists any new memos."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_botlist.cpp
|
||||
msgid "Lists available bots"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_badwords.cpp
|
||||
msgid "Lists bad word entries set on #channel numbered 2 through 5 and 7 through 9."
|
||||
msgstr ""
|
||||
@@ -4658,10 +4665,6 @@ msgstr ""
|
||||
msgid "Lists currently loaded modules."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_info.cpp
|
||||
msgid "Lists information about the specified registered channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_info.cpp
|
||||
msgid "Lists information about the specified registered channel, including its founder, time of registration, last time used, and description. If the user issuing the command has the appropriate access for it, then the successor, last topic set, settings and expiration time will also be displayed when applicable."
|
||||
msgstr ""
|
||||
@@ -4744,12 +4747,16 @@ msgid ""
|
||||
"The %sCLEAR command is an easy way to clear modes on a channel. what may be any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If what is not given then all basic modes are removed."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_bot.cpp
|
||||
msgid "Maintain network bot list"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_akick.cpp
|
||||
msgid "Maintain the AutoKick list"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_bot.cpp
|
||||
msgid "Maintains network bot list"
|
||||
#: ../modules/botserv/bs_badwords.cpp
|
||||
msgid "Maintain the bad words list"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_xop.cpp
|
||||
@@ -4797,22 +4804,18 @@ msgid ""
|
||||
"The CLEAR command clears all entries from the bad words list."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_badwords.cpp
|
||||
msgid "Maintains the bad words list"
|
||||
#: ../modules/botserv/bs_control.cpp
|
||||
msgid "Make the bot do the equivalent of a \"/me\" command"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_control.cpp
|
||||
msgid "Makes the bot do the equivalent of a \"/me\" command"
|
||||
msgid "Make the bot say the specified text on the specified channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_control.cpp
|
||||
msgid "Makes the bot do the equivalent of a \"/me\" command on the specified channel using the specified text."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_control.cpp
|
||||
msgid "Makes the bot say the specified text on the specified channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_control.cpp
|
||||
msgid "Makes the bot say the specified text on the specified channel."
|
||||
msgstr ""
|
||||
@@ -4834,7 +4837,7 @@ msgid "Manage your auto join list"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/global/gl_queue.cpp
|
||||
msgid "Manages your pending message queue."
|
||||
msgid "Manage your pending message queue."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_sxline.cpp
|
||||
@@ -4878,7 +4881,7 @@ msgid "Masks and unregistered users may not be on access lists."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_email.cpp
|
||||
msgid "Matches and returns all users that registered using given email address"
|
||||
msgid "Match and return all users that registered using given email address"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_logsearch.cpp
|
||||
@@ -5795,7 +5798,7 @@ msgid "Redefine the meanings of access levels"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_recover.cpp
|
||||
msgid "Regains control of your nick"
|
||||
msgid "Regain control of your nick"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_akill.cpp ../modules/operserv/os_sxline.cpp
|
||||
@@ -5881,7 +5884,7 @@ msgid "Reject the requested vhost of a user"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_suspend.cpp
|
||||
msgid "Releases a suspended channel"
|
||||
msgid "Release a suspended channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_suspend.cpp
|
||||
@@ -5900,6 +5903,10 @@ msgstr ""
|
||||
msgid "Remove a nick from an account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_updown.cpp
|
||||
msgid "Remove a selected nicks status from a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_unban.cpp
|
||||
msgid "Remove all bans preventing a user from entering a channel"
|
||||
msgstr ""
|
||||
@@ -5933,10 +5940,6 @@ msgstr ""
|
||||
msgid "Removes %s status from you or the specified nick on a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_updown.cpp
|
||||
msgid "Removes a selected nicks status from a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_updown.cpp
|
||||
msgid "Removes a selected nicks status modes on a channel. If nick is omitted then your status is removed. If channel is omitted then your channel status is removed on every channel you are in."
|
||||
msgstr ""
|
||||
@@ -6018,11 +6021,11 @@ msgid "Retain topic when channel is not in use"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_request.cpp
|
||||
msgid "Retrieves the vhost requests"
|
||||
msgid "Retrieve the vhost requests"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_getkey.cpp
|
||||
msgid "Returns the key of the given channel"
|
||||
msgid "Return the key of the given channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_getkey.cpp
|
||||
@@ -6033,6 +6036,10 @@ msgstr ""
|
||||
msgid "Returns the matching accounts that used given email."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_logout.cpp
|
||||
msgid "Reverse the effect of the IDENTIFY command"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_kick.cpp
|
||||
msgid "Reverses kicker"
|
||||
msgstr ""
|
||||
@@ -6041,10 +6048,6 @@ msgstr ""
|
||||
msgid "Reverses the effect of the IDENTIFY command, i.e. make you not recognized as the real owner of the nick anymore. Note, however, that you won't be asked to reidentify yourself."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_logout.cpp
|
||||
msgid "Reverses the effect of the IDENTIFY command"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_noop.cpp
|
||||
msgid "SET server"
|
||||
msgstr ""
|
||||
@@ -6077,7 +6080,7 @@ msgid "Save databases and restart services"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_logsearch.cpp
|
||||
msgid "Searches logs for a matching pattern"
|
||||
msgid "Search logs for a matching pattern"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_logsearch.cpp
|
||||
@@ -6132,6 +6135,10 @@ msgstr ""
|
||||
msgid "See the %s command (%sACCESS) for information on giving a subset of these privileges to other channel users."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_rsend.cpp
|
||||
msgid "Send a memo and requests a read receipt"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_send.cpp
|
||||
msgid "Send a memo to a nick or channel"
|
||||
msgstr ""
|
||||
@@ -6152,6 +6159,10 @@ msgstr ""
|
||||
msgid "Send a message to all users on a server"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_resetpass.cpp
|
||||
msgid "Send an email to recover access to an account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_list.cpp
|
||||
msgid "Sender"
|
||||
msgstr ""
|
||||
@@ -6160,10 +6171,6 @@ msgstr ""
|
||||
msgid "Sends a confirmation code to the nickname's email address with instructions on how to reset their password. email must be the email address associated with the account."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/memoserv/ms_rsend.cpp
|
||||
msgid "Sends a memo and requests a read receipt"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_log.cpp
|
||||
msgid "Sends a memo to the channel when someone uses the chanserv/xop command on #anope."
|
||||
msgstr ""
|
||||
@@ -6481,6 +6488,18 @@ msgstr ""
|
||||
msgid "Set various global services options"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_op.cpp
|
||||
msgid "Set whether services should set channel status modes on you automatically."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_op.cpp
|
||||
msgid "Set whether you can be added to a channel access list."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_cert.cpp
|
||||
msgid "Set whether you should automatically be logged in when you connect using a known SSL certificate."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set.cpp
|
||||
msgid "Set your nickname password"
|
||||
msgstr ""
|
||||
@@ -6617,10 +6636,6 @@ msgstr ""
|
||||
msgid "Sets voice status on all users in the channel."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_set_op.cpp
|
||||
msgid "Sets whether services should set channel status modes on you automatically."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_set.cpp
|
||||
msgid "Sets whether the given channel will expire. Setting this to ON prevents the channel from expiring."
|
||||
msgstr ""
|
||||
@@ -6647,10 +6662,6 @@ msgstr ""
|
||||
msgid "Sets whether you can be added to a channel access list."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_cert.cpp
|
||||
msgid "Sets whether you should automatically be logged in when you connect using a known SSL certificate."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_cert.cpp
|
||||
#, c-format
|
||||
msgid "Sets whether you should automatically be logged in when you connect using a known SSL certificate. You can configure your SSL certificate using the %s command."
|
||||
@@ -6813,6 +6824,10 @@ msgstr ""
|
||||
msgid "Suspension expires"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_group.cpp
|
||||
msgid "Sync the vhost for all nicks in an account"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_sync.cpp
|
||||
msgid "Sync users channel modes"
|
||||
msgstr ""
|
||||
@@ -6821,10 +6836,6 @@ msgstr ""
|
||||
msgid "Syncs all modes set on users on the channel with the modes they should have based on their access."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_group.cpp
|
||||
msgid "Syncs the vhost for all nicks in an account"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/command.cpp
|
||||
msgid "Syntax"
|
||||
msgstr ""
|
||||
@@ -6904,6 +6915,10 @@ msgstr ""
|
||||
msgid "TAKE {vhost | entry-num}"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_seen.cpp
|
||||
msgid "Tell you about the last time a user was seen"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_identify.cpp
|
||||
#, c-format
|
||||
msgid "Tells %s that you are really the owner of this nick. Many commands require you to authenticate yourself with this command before you use them. The password should be the same one you sent with the REGISTER command."
|
||||
@@ -6923,10 +6938,6 @@ msgstr ""
|
||||
msgid "Tells services to jupiter a server -- that is, to create a fake \"server\" connected to services which prevents the real server of that name from connecting. The jupe may be removed using a standard SQUIT. If a reason is given, it is placed in the server information field; otherwise, the server information field will contain the text \"Juped by <nick>\", showing the nickname of the person who jupitered the server."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_seen.cpp
|
||||
msgid "Tells you about the last time a user was seen"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/operserv/os_shutdown.cpp
|
||||
msgid "Terminate services WITHOUT saving"
|
||||
msgstr ""
|
||||
@@ -7668,7 +7679,7 @@ msgid "Unable to remove module %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_assign.cpp
|
||||
msgid "Unassigns a bot from a channel"
|
||||
msgid "Unassign a bot from a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/botserv/bs_assign.cpp
|
||||
@@ -7760,15 +7771,15 @@ msgid "Unsuspends a nickname which allows it to be used again."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_updown.cpp
|
||||
msgid "Updates a selected nicks status modes on a channel. If nick is omitted then your status is updated. If channel is omitted then your channel status is updated on every channel you are in."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_updown.cpp
|
||||
msgid "Updates a selected nicks status on a channel"
|
||||
msgid "Update a selected nicks status on a channel"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_update.cpp
|
||||
msgid "Updates your current status, i.e. it checks for new memos"
|
||||
msgid "Update your current status, i.e. it checks for new memos"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/chanserv/cs_updown.cpp
|
||||
msgid "Updates a selected nicks status modes on a channel. If nick is omitted then your status is updated. If channel is omitted then your channel status is updated on every channel you are in."
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/nickserv/ns_update.cpp
|
||||
@@ -7917,7 +7928,7 @@ msgid "VIEW [vhost-mask | entry-num | list]"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_request.cpp
|
||||
msgid "Validates a previously requested vhost using DNS"
|
||||
msgid "Validate a previously requested vhost using DNS"
|
||||
msgstr ""
|
||||
|
||||
#: ../modules/hostserv/hs_request.cpp
|
||||
|
||||
@@ -50,7 +50,7 @@ macro(inline_cmake TARGET FILE)
|
||||
set(CODE "${CODE}\n${CLEAN_LINE}")
|
||||
endif()
|
||||
elseif(LINE MATCHES "^/// BEGIN CMAKE$")
|
||||
message(STATUS "Executing inline CMake code for ${TARGET}")
|
||||
message(DEBUG "Executing inline CMake code for ${TARGET}")
|
||||
set(IN_CODE ON)
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -77,6 +77,12 @@ macro(build_module SRC MODULE_SRC)
|
||||
PREFIX ""
|
||||
SUFFIX ""
|
||||
)
|
||||
list(LENGTH MODULE_SRC MODULE_SRC_COUNT)
|
||||
if(MODULE_SRC_COUNT LESS_EQUAL 1)
|
||||
set_target_properties(${SO} PROPERTIES
|
||||
UNITY_BUILD OFF
|
||||
)
|
||||
endif()
|
||||
add_dependencies(${SO} ${PROGRAM_NAME})
|
||||
if(HAVE_LOCALIZATION)
|
||||
add_dependencies(${SO} module_language)
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandBSAssign final
|
||||
public:
|
||||
CommandBSAssign(Module *creator) : Command(creator, "botserv/assign", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Assigns a bot to a channel"));
|
||||
this->SetDesc(_("Assign a bot to a channel"));
|
||||
this->SetSyntax(_("\037channel\037 \037nick\037"));
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ class CommandBSUnassign final
|
||||
public:
|
||||
CommandBSUnassign(Module *creator) : Command(creator, "botserv/unassign", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Unassigns a bot from a channel"));
|
||||
this->SetDesc(_("Unassign a bot from a channel"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ private:
|
||||
public:
|
||||
CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Maintains the bad words list"));
|
||||
this->SetDesc(_("Maintain the bad words list"));
|
||||
this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]"));
|
||||
this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}"));
|
||||
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
|
||||
|
||||
@@ -264,7 +264,7 @@ private:
|
||||
public:
|
||||
CommandBSBot(Module *creator) : Command(creator, "botserv/bot", 1, 6)
|
||||
{
|
||||
this->SetDesc(_("Maintains network bot list"));
|
||||
this->SetDesc(_("Maintain network bot list"));
|
||||
this->SetSyntax(_("\002ADD \037nick\037 \037user\037 \037host\037 \037real\037\002"));
|
||||
this->SetSyntax(_("\002CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002"));
|
||||
this->SetSyntax(_("\002DEL \037nick\037\002"));
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandBSBotList final
|
||||
public:
|
||||
CommandBSBotList(Module *creator) : Command(creator, "botserv/botlist", 0, 1)
|
||||
{
|
||||
this->SetDesc(_("Lists available bots"));
|
||||
this->SetDesc(_("List available bots"));
|
||||
this->SetSyntax("[OPERONLY] [UNUSED] [VANITY]");
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandBSSay final
|
||||
public:
|
||||
CommandBSSay(Module *creator) : Command(creator, "botserv/say", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Makes the bot say the specified text on the specified channel"));
|
||||
this->SetDesc(_("Make the bot say the specified text on the specified channel"));
|
||||
this->SetSyntax(_("\037channel\037 \037text\037"));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class CommandBSAct final
|
||||
public:
|
||||
CommandBSAct(Module *creator) : Command(creator, "botserv/act", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
|
||||
this->SetDesc(_("Make the bot do the equivalent of a \"/me\" command"));
|
||||
this->SetSyntax(_("\037channel\037 \037text\037"));
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -129,7 +129,7 @@ class CommandBSKick final
|
||||
public:
|
||||
CommandBSKick(Module *creator) : Command(creator, "botserv/kick", 0)
|
||||
{
|
||||
this->SetDesc(_("Configures kickers"));
|
||||
this->SetDesc(_("Configure kickers"));
|
||||
this->SetSyntax(_("\037option\037 \037channel\037 {\037ON|OFF\037} [\037settings\037]"));
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ class CommandBSKickAMSG final
|
||||
public:
|
||||
CommandBSKickAMSG(Module *creator) : CommandBSKickBase(creator, "botserv/kick/amsg", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures AMSG kicker"));
|
||||
this->SetDesc(_("Configure AMSG kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ class CommandBSKickBadwords final
|
||||
public:
|
||||
CommandBSKickBadwords(Module *creator) : CommandBSKickBase(creator, "botserv/kick/badwords", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures badwords kicker"));
|
||||
this->SetDesc(_("Configure badwords kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ class CommandBSKickBolds final
|
||||
public:
|
||||
CommandBSKickBolds(Module *creator) : CommandBSKickBase(creator, "botserv/kick/bolds", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures bolds kicker"));
|
||||
this->SetDesc(_("Configure bolds kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ class CommandBSKickCaps final
|
||||
public:
|
||||
CommandBSKickCaps(Module *creator) : CommandBSKickBase(creator, "botserv/kick/caps", 2, 5)
|
||||
{
|
||||
this->SetDesc(_("Configures caps kicker"));
|
||||
this->SetDesc(_("Configure caps kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002"));
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ class CommandBSKickColors final
|
||||
public:
|
||||
CommandBSKickColors(Module *creator) : CommandBSKickBase(creator, "botserv/kick/colors", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures color kicker"));
|
||||
this->SetDesc(_("Configure color kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ class CommandBSKickFlood final
|
||||
public:
|
||||
CommandBSKickFlood(Module *creator) : CommandBSKickBase(creator, "botserv/kick/flood", 2, 5)
|
||||
{
|
||||
this->SetDesc(_("Configures flood kicker"));
|
||||
this->SetDesc(_("Configure flood kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002"));
|
||||
}
|
||||
|
||||
@@ -602,7 +602,7 @@ class CommandBSKickItalics final
|
||||
public:
|
||||
CommandBSKickItalics(Module *creator) : CommandBSKickBase(creator, "botserv/kick/italics", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures italics kicker"));
|
||||
this->SetDesc(_("Configure italics kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
@@ -639,7 +639,7 @@ class CommandBSKickRepeat final
|
||||
public:
|
||||
CommandBSKickRepeat(Module *creator) : CommandBSKickBase(creator, "botserv/kick/repeat", 2, 4)
|
||||
{
|
||||
this->SetDesc(_("Configures repeat kicker"));
|
||||
this->SetDesc(_("Configure repeat kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002"));
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ class CommandBSKickReverses final
|
||||
public:
|
||||
CommandBSKickReverses(Module *creator) : CommandBSKickBase(creator, "botserv/kick/reverses", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures reverses kicker"));
|
||||
this->SetDesc(_("Configure reverses kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
@@ -787,7 +787,7 @@ class CommandBSKickUnderlines final
|
||||
public:
|
||||
CommandBSKickUnderlines(Module *creator) : CommandBSKickBase(creator, "botserv/kick/underlines", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures underlines kicker"));
|
||||
this->SetDesc(_("Configure underlines kicker"));
|
||||
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037} [\037ttb\037]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandBSSet final
|
||||
public:
|
||||
CommandBSSet(Module *creator) : Command(creator, "botserv/set", 3, 3)
|
||||
{
|
||||
this->SetDesc(_("Configures bot options"));
|
||||
this->SetDesc(_("Configure bot options"));
|
||||
this->SetSyntax(_("\037option\037 \037(channel | bot)\037 \037settings\037"));
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
|
||||
CommandBSSetBanExpire(Module *creator, const Anope::string &sname = "botserv/set/banexpire") : Command(creator, sname, 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Configures the time bot bans expire in"));
|
||||
this->SetDesc(_("Configure the time bot bans expire in"));
|
||||
this->SetSyntax(_("\037channel\037 \037time\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -963,10 +963,8 @@ public:
|
||||
{
|
||||
defaultLevels.clear();
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("privilege"); ++i)
|
||||
for (const auto &[_, priv] : conf.GetBlocks("privilege"))
|
||||
{
|
||||
const auto &priv = conf.GetBlock("privilege", i);
|
||||
|
||||
const Anope::string &pname = priv.Get<const Anope::string>("name");
|
||||
|
||||
Privilege *p = PrivilegeManager::FindPrivilege(pname);
|
||||
|
||||
@@ -73,7 +73,7 @@ class CommandCSBan final
|
||||
public:
|
||||
CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 4)
|
||||
{
|
||||
this->SetDesc(_("Bans a given nick or mask on a channel"));
|
||||
this->SetDesc(_("Ban a given nick or mask on a channel"));
|
||||
this->SetSyntax(_("\037channel\037 [+\037expiry\037] {\037nick\037 | \037mask\037} [\037reason\037]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -299,11 +299,7 @@ public:
|
||||
{
|
||||
Anope::map<Anope::string> tags;
|
||||
if (timestamp)
|
||||
{
|
||||
char timebuf[32];
|
||||
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S.000Z", gmtime(&message->when));
|
||||
tags["time"] = timebuf;
|
||||
}
|
||||
tags["time"] = Anope::FormatISO8601(message->when, 0);
|
||||
|
||||
if (u->ShouldPrivmsg())
|
||||
IRCD->SendContextPrivmsg(c->ci->WhoSends(), u, c, message->message, tags);
|
||||
|
||||
@@ -41,7 +41,7 @@ class CommandCSStats final
|
||||
public:
|
||||
CommandCSStats(Module *creator) : Command (creator, "chanserv/stats", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Displays your Channel Stats"));
|
||||
this->SetDesc(_("Display your Channel Stats"));
|
||||
this->SetSyntax(_("[\037channel\037] [\037nick\037]"));
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class CommandCSGStats final
|
||||
public:
|
||||
CommandCSGStats(Module *creator) : Command (creator, "chanserv/gstats", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Displays your Global Stats"));
|
||||
this->SetDesc(_("Display your Global Stats"));
|
||||
this->SetSyntax(_("\037nick\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class CommandCSTop final
|
||||
public:
|
||||
CommandCSTop(Module *creator) : Command (creator, "chanserv/top", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Displays the top 3 users of a channel"));
|
||||
this->SetDesc(_("Display the top 3 users of a channel"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class CommandCSTop10 final
|
||||
public:
|
||||
CommandCSTop10(Module *creator) : Command (creator, "chanserv/top10", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Displays the top 10 users of a channel"));
|
||||
this->SetDesc(_("Display the top 10 users of a channel"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class CommandCSGTop final
|
||||
public:
|
||||
CommandCSGTop(Module *creator) : Command (creator, "chanserv/gtop", 0, 1)
|
||||
{
|
||||
this->SetDesc(_("Displays the top 3 users of the network"));
|
||||
this->SetDesc(_("Display the top 3 users of the network"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms);
|
||||
@@ -78,7 +78,7 @@ class CommandCSGTop10 final
|
||||
public:
|
||||
CommandCSGTop10(Module *creator) : Command (creator, "chanserv/gtop10", 0, 1)
|
||||
{
|
||||
this->SetDesc(_("Displays the top 10 users of the network"));
|
||||
this->SetDesc(_("Display the top 10 users of the network"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms);
|
||||
|
||||
@@ -661,10 +661,8 @@ public:
|
||||
{
|
||||
defaultFlags.clear();
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("privilege"); ++i)
|
||||
for (const auto &[_, priv] : conf.GetBlocks("privilege"))
|
||||
{
|
||||
const auto &priv = conf.GetBlock("privilege", i);
|
||||
|
||||
const Anope::string &pname = priv.Get<const Anope::string>("name");
|
||||
|
||||
Privilege *p = PrivilegeManager::FindPrivilege(pname);
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandCSGetKey final
|
||||
public:
|
||||
CommandCSGetKey(Module *creator) : Command(creator, "chanserv/getkey", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Returns the key of the given channel"));
|
||||
this->SetDesc(_("Return the key of the given channel"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandCSInfo final
|
||||
public:
|
||||
CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2)
|
||||
{
|
||||
this->SetDesc(_("Lists information about the specified registered channel"));
|
||||
this->SetDesc(_("List information about the specified registered channel"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
this->AllowUnregistered(true);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandCSInvite final
|
||||
public:
|
||||
CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
|
||||
{
|
||||
this->SetDesc(_("Invites you or an optionally specified nick into a channel"));
|
||||
this->SetDesc(_("Invite you or an optionally specified nick into a channel"));
|
||||
this->SetSyntax(_("\037channel\037 [\037nick\037]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandCSKick final
|
||||
public:
|
||||
CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Kicks a specified nick from a channel"));
|
||||
this->SetDesc(_("Kick a specified nick from a channel"));
|
||||
this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
|
||||
this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class CommandCSList final
|
||||
public:
|
||||
CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2)
|
||||
{
|
||||
this->SetDesc(_("Lists all registered channels matching the given pattern"));
|
||||
this->SetDesc(_("List all registered channels matching the given pattern"));
|
||||
this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ class CommandCSLog final
|
||||
public:
|
||||
CommandCSLog(Module *creator) : Command(creator, "chanserv/log", 1, 4)
|
||||
{
|
||||
this->SetDesc(_("Configures channel logging settings"));
|
||||
this->SetDesc(_("Configure channel logging settings"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
this->SetSyntax(_("\037channel\037 \037command\037 \037method\037 [\037status\037]"));
|
||||
}
|
||||
@@ -331,10 +331,8 @@ public:
|
||||
const auto &block = conf.GetModule(this);
|
||||
defaults.clear();
|
||||
|
||||
for (int i = 0; i < block.CountBlock("default"); ++i)
|
||||
for (const auto &[_, def] : block.GetBlocks("default"))
|
||||
{
|
||||
const auto &def = block.GetBlock("default", i);
|
||||
|
||||
LogDefault ld;
|
||||
|
||||
ld.service = def.Get<const Anope::string>("service");
|
||||
|
||||
@@ -999,10 +999,8 @@ public:
|
||||
{
|
||||
modes.clear();
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("command"); ++i)
|
||||
for (const auto &[_, block] : conf.GetBlocks("command"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("command", i);
|
||||
|
||||
const Anope::string &cname = block.Get<const Anope::string>("name"),
|
||||
&cmd = block.Get<const Anope::string>("command");
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ class CommandSeen final
|
||||
public:
|
||||
CommandSeen(Module *creator) : Command(creator, "chanserv/seen", 1, 2)
|
||||
{
|
||||
this->SetDesc(_("Tells you about the last time a user was seen"));
|
||||
this->SetDesc(_("Tell you about the last time a user was seen"));
|
||||
this->SetSyntax(_("\037nick\037"));
|
||||
this->AllowUnregistered(true);
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@ public:
|
||||
void OnReload(Configuration::Conf &conf) override
|
||||
{
|
||||
command_data.clear();
|
||||
for (int i = 0; i < conf.CountBlock("command"); ++i)
|
||||
|
||||
for (const auto &[_, block] : conf.GetBlocks("command"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("command", i);
|
||||
if (block.Get<const Anope::string>("command") != "chanserv/set/misc")
|
||||
continue;
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ class CommandCSUnSuspend final
|
||||
public:
|
||||
CommandCSUnSuspend(Module *creator) : Command(creator, "chanserv/unsuspend", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Releases a suspended channel"));
|
||||
this->SetDesc(_("Release a suspended channel"));
|
||||
this->SetSyntax(_("\037channel\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class CommandCSUp final
|
||||
public:
|
||||
CommandCSUp(Module *creator) : Command(creator, "chanserv/up", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Updates a selected nicks status on a channel"));
|
||||
this->SetDesc(_("Update a selected nicks status on a channel"));
|
||||
this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ class CommandCSDown final
|
||||
public:
|
||||
CommandCSDown(Module *creator) : Command(creator, "chanserv/down", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Removes a selected nicks status from a channel"));
|
||||
this->SetDesc(_("Remove a selected nicks status from a channel"));
|
||||
this->SetSyntax(_("[\037channel\037 [\037nick\037]]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -688,9 +688,8 @@ public:
|
||||
order.clear();
|
||||
permissions.clear();
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("privilege"); ++i)
|
||||
for (const auto &[_, block] : conf.GetBlocks("privilege"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("privilege", i);
|
||||
const Anope::string &pname = block.Get<const Anope::string>("name");
|
||||
|
||||
Privilege *p = PrivilegeManager::FindPrivilege(pname);
|
||||
@@ -704,9 +703,8 @@ public:
|
||||
permissions[xop].push_back(pname);
|
||||
}
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("command"); ++i)
|
||||
for (const auto &[_, block] : conf.GetBlocks("command"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("command", i);
|
||||
const Anope::string &cname = block.Get<const Anope::string>("name"),
|
||||
&cserv = block.Get<const Anope::string>("command");
|
||||
if (cname.empty() || cserv != "chanserv/xop")
|
||||
|
||||
+181
-24
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/botserv/badwords.h"
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "modules/chanserv/mode.h"
|
||||
#include "modules/hostserv/request.h"
|
||||
#include "modules/info.h"
|
||||
#include "modules/nickserv/ajoin.h"
|
||||
#include "modules/nickserv/cert.h"
|
||||
#include "modules/operserv/forbid.h"
|
||||
#include "modules/operserv/news.h"
|
||||
@@ -73,10 +75,10 @@ public:
|
||||
}
|
||||
|
||||
// Retrieves the remaining data in the row.
|
||||
Anope::string GetRemaining()
|
||||
Anope::string GetRemaining(bool allow_empty = false)
|
||||
{
|
||||
auto remaining = stream.GetRemaining();
|
||||
if (remaining.empty())
|
||||
if (remaining.empty() && !allow_empty)
|
||||
error++;
|
||||
return remaining;
|
||||
}
|
||||
@@ -120,14 +122,49 @@ struct ModeLockData final
|
||||
}
|
||||
};
|
||||
|
||||
struct FounderSuccessorCandidate
|
||||
{
|
||||
// Flags ranked from founder down, for successor candidate ranking
|
||||
static const Anope::string FLAG_PRIORITY;
|
||||
|
||||
NickCore* nc;
|
||||
size_t priority;
|
||||
time_t mtime;
|
||||
|
||||
FounderSuccessorCandidate()
|
||||
: nc(nullptr)
|
||||
, priority(99) // arbitrary; for log readability
|
||||
, mtime(std::numeric_limits<std::time_t>::max())
|
||||
{
|
||||
}
|
||||
|
||||
FounderSuccessorCandidate(NickCore *c, const Anope::string &flags, time_t m)
|
||||
: nc(c)
|
||||
, priority(FLAG_PRIORITY.find_first_of(flags))
|
||||
, mtime(m)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const FounderSuccessorCandidate& other)
|
||||
{
|
||||
return std::tie(priority, mtime) < std::tie(other.priority, other.mtime);
|
||||
}
|
||||
|
||||
FounderSuccessorCandidate& operator=(const FounderSuccessorCandidate& other) = default;
|
||||
};
|
||||
|
||||
const Anope::string FounderSuccessorCandidate::FLAG_PRIORITY = "FSRsaOoHh";
|
||||
|
||||
struct ChannelData final
|
||||
{
|
||||
Anope::unordered_map<ChanServ::AutoKick *> akicks;
|
||||
Anope::string bot;
|
||||
FounderSuccessorCandidate founder_candidate;
|
||||
Anope::string info_adder;
|
||||
Anope::string info_message;
|
||||
time_t info_ts = 0;
|
||||
std::vector<ModeLockData> mlocks;
|
||||
FounderSuccessorCandidate successor_candidate;
|
||||
Anope::string suspend_by;
|
||||
Anope::string suspend_reason;
|
||||
time_t suspend_ts = 0;
|
||||
@@ -135,6 +172,7 @@ struct ChannelData final
|
||||
|
||||
struct UserData final
|
||||
{
|
||||
Anope::map<Anope::string> ajoins;
|
||||
Anope::string info_adder;
|
||||
Anope::string info_message;
|
||||
time_t info_ts = 0;
|
||||
@@ -236,21 +274,40 @@ private:
|
||||
{ "XL", &DBAtheme::HandleXL },
|
||||
};
|
||||
|
||||
void ApplyAccess(Anope::string &in, char flag, Anope::string &out, std::initializer_list<const char*> privs)
|
||||
static void RemoveAll(Anope::string& in, const Anope::string& unwanted)
|
||||
{
|
||||
for (const auto *priv : privs)
|
||||
auto it = std::remove_if(in.begin(), in.end(), [&](char c){
|
||||
return unwanted.find_first_of(c) != unwanted.npos;
|
||||
});
|
||||
in.erase(it, in.end());
|
||||
}
|
||||
|
||||
static bool RemoveFirstOccurrence(Anope::string& in, char c)
|
||||
{
|
||||
auto pos = in.find(c);
|
||||
if (pos != Anope::string::npos)
|
||||
{
|
||||
auto pos = in.find(flag);
|
||||
if (pos != Anope::string::npos)
|
||||
in.erase(pos, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ApplyAccess(Anope::string &in, char flag, Anope::string &out, std::initializer_list<const char*> privs)
|
||||
{
|
||||
const bool flag_found = RemoveFirstOccurrence(in, flag);
|
||||
if (flag_found)
|
||||
{
|
||||
for (const auto *priv : privs)
|
||||
{
|
||||
auto privchar = flags.find(priv);
|
||||
if (privchar != flags.end())
|
||||
{
|
||||
out.push_back(privchar->second);
|
||||
in.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag_found;
|
||||
}
|
||||
|
||||
void ApplyFlags(Extensible *ext, Anope::string &flags, char flag, const char *extname, bool extend = true)
|
||||
@@ -609,16 +666,17 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *data = chandata.Require(ci);
|
||||
|
||||
auto *nc = NickCore::Find(mask);
|
||||
if (flags.find('b') != Anope::string::npos)
|
||||
{
|
||||
if (ChanServ::akick_service)
|
||||
if (!ChanServ::akick_service)
|
||||
{
|
||||
Log(this) << "Unable to import channel akick for " << ci->name << " as cs_akick is not loaded";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto *data = chandata.Require(ci);
|
||||
if (nc)
|
||||
data->akicks[mask] = ChanServ::akick_service->AddAKick(ci, setter, nc, "", modifiedtime, modifiedtime);
|
||||
else
|
||||
@@ -638,7 +696,6 @@ private:
|
||||
ApplyAccess(flags, 'a', accessflags, { "AUTOPROTECT", "PROTECT", "PROTECTME" });
|
||||
ApplyAccess(flags, 'e', accessflags, { "GETKEY", "NOKICK", "UNBANME" });
|
||||
ApplyAccess(flags, 'f', accessflags, { "ACCESS_CHANGE" });
|
||||
ApplyAccess(flags, 'F', accessflags, { "FOUNDER" });
|
||||
ApplyAccess(flags, 'H', accessflags, { "AUTOHALFOP" });
|
||||
ApplyAccess(flags, 'h', accessflags, { "HALFOP", "HALFOPME" });
|
||||
ApplyAccess(flags, 'i', accessflags, { "INVITE" });
|
||||
@@ -662,6 +719,35 @@ private:
|
||||
ci->AddAccess(access);
|
||||
}
|
||||
|
||||
// Atheme allows multiple founders and picks a successor based on rank if one is not explicitly assigned.
|
||||
bool is_founder_candidate = RemoveFirstOccurrence(flags, 'F');
|
||||
RemoveAll(flags, "SR");
|
||||
|
||||
FounderSuccessorCandidate current_candidate(nc, originalflags, modifiedtime);
|
||||
|
||||
if (nc && current_candidate < data->successor_candidate)
|
||||
{
|
||||
if (is_founder_candidate && current_candidate < data->founder_candidate)
|
||||
{
|
||||
Log(LOG_DEBUG) << ci->name << ": Demoting founder candidate ("
|
||||
<< ( data->founder_candidate.nc ? data->founder_candidate.nc->display : "NONE" )
|
||||
<< ", " << data->founder_candidate.priority
|
||||
<< ") to successor; replacing with (" << current_candidate.nc->display
|
||||
<< ", " << current_candidate.priority << ")";
|
||||
data->successor_candidate = data->founder_candidate;
|
||||
data->founder_candidate = current_candidate;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(LOG_DEBUG) << ci->name << ": Replacing successor candidate ("
|
||||
<< ( data->successor_candidate.nc ? data->successor_candidate.nc->display : "NONE" )
|
||||
<< ", " << data->successor_candidate.priority
|
||||
<< ") with (" << current_candidate.nc->display
|
||||
<< ", " << current_candidate.priority << ")";
|
||||
data->successor_candidate = current_candidate;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags != "+")
|
||||
Log(this) << "Unable to convert channel access flags " << flags << " for " << mask << " on " << ci->name;
|
||||
|
||||
@@ -788,7 +874,7 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
auto *xl = new XLine(user + "@" + host, setby, settime + duration, reason);
|
||||
auto *xl = new XLine(user + "@" + host, setby, duration ? settime + duration : 0, reason);
|
||||
xl->id = id;
|
||||
sglinemgr->AddXLine(xl);
|
||||
return true;
|
||||
@@ -879,6 +965,7 @@ private:
|
||||
ci->last_used = used;
|
||||
|
||||
// No equivalent: elnv
|
||||
RemoveFirstOccurrence(flags, 'v'); // verbose, com
|
||||
ApplyFlags(ci, flags, 'h', "CS_NO_EXPIRE");
|
||||
ApplyFlags(ci, flags, 'k', "KEEPTOPIC");
|
||||
ApplyFlags(ci, flags, 'o', "NOAUTOOP");
|
||||
@@ -985,6 +1072,10 @@ private:
|
||||
if (akick != data->akicks.end())
|
||||
akick->second->reason = value;
|
||||
}
|
||||
else if (key == "expires")
|
||||
{
|
||||
Log(this) << "Unable to set access expiration for " << mask << " on " << ci->name << ": unimplemented";
|
||||
}
|
||||
else
|
||||
Log(this) << "Unknown channel access metadata for " << mask << " on " << ci->name << ": " << key << " = " << value;
|
||||
|
||||
@@ -1146,10 +1237,7 @@ private:
|
||||
// MDU <display> <key> <value>
|
||||
auto display = row.Get();
|
||||
auto key = row.Get();
|
||||
auto value = row.GetRemaining();
|
||||
|
||||
if (!row)
|
||||
return row.LogError(this);
|
||||
auto value = row.GetRemaining(true);
|
||||
|
||||
auto *nc = NickCore::Find(display);
|
||||
if (!nc)
|
||||
@@ -1160,7 +1248,17 @@ private:
|
||||
|
||||
auto *data = userdata.Require(nc);
|
||||
if (key == "private:autojoin")
|
||||
return true; // TODO
|
||||
{
|
||||
commasepstream autojoins(value, true);
|
||||
for (Anope::string autojoin; autojoins.GetToken(autojoin); )
|
||||
{
|
||||
spacesepstream entry(autojoin);
|
||||
Anope::string cname, ckey;
|
||||
if (entry.GetToken(cname))
|
||||
entry.GetToken(ckey);
|
||||
data->ajoins[cname] = ckey;
|
||||
}
|
||||
}
|
||||
else if (key == "private:doenforce")
|
||||
data->protect = true;
|
||||
else if (key == "private:enforcetime")
|
||||
@@ -1189,6 +1287,12 @@ private:
|
||||
data->info_adder = value;
|
||||
else if (key == "private:mark:timestamp")
|
||||
data->info_ts = Anope::Convert<time_t>(value, 0);
|
||||
else if (key == "private:sendpass:sender")
|
||||
return HandleIgnoreMetadata(nc->display, key, value);
|
||||
else if (key == "private:sendpass:timestamp")
|
||||
return HandleIgnoreMetadata(nc->display, key, value);
|
||||
else if (key == "private:setpass:key")
|
||||
return HandleIgnoreMetadata(nc->display, key, value);
|
||||
else if (key == "private:swhois")
|
||||
return HandleIgnoreMetadata(nc->display, key, value);
|
||||
else if (key == "private:usercloak")
|
||||
@@ -1410,6 +1514,7 @@ private:
|
||||
ApplyPassword(nc, flags, pass);
|
||||
|
||||
// No equivalent: bglmNQrS
|
||||
RemoveFirstOccurrence(flags, 'b'); // nick b flag is ephemeral, ignore
|
||||
ApplyFlags(nc, flags, 'E', "PROTECT");
|
||||
ApplyFlags(nc, flags, 'e', "MEMO_MAIL");
|
||||
ApplyFlags(nc, flags, 'n', "NEVEROP");
|
||||
@@ -1499,7 +1604,7 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
auto *xl = new XLine(nick, setby, settime + duration, reason);
|
||||
auto *xl = new XLine(nick, setby, duration ? settime + duration : 0, reason);
|
||||
xl->id = id;
|
||||
sqlinemgr->AddXLine(xl);
|
||||
return true;
|
||||
@@ -1561,7 +1666,7 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
auto *xl = new XLine(real, setby, settime + duration, reason);
|
||||
auto *xl = new XLine(real, setby, duration ? settime + duration : 0, reason);
|
||||
xl->id = id;
|
||||
snlinemgr->AddXLine(xl);
|
||||
return true;
|
||||
@@ -1584,9 +1689,8 @@ public:
|
||||
const auto &modconf = conf.GetModule(this);
|
||||
|
||||
csmiscdata.clear();
|
||||
for (auto idx = 0; idx < modconf.CountBlock("cs_set_misc"); ++idx)
|
||||
for (const auto &[_, data] : modconf.GetBlocks("cs_set_misc"))
|
||||
{
|
||||
const auto &data = modconf.GetBlock("cs_set_misc", idx);
|
||||
const auto &anope = data.Get<const Anope::string>("anope");
|
||||
const auto &atheme = data.Get<const Anope::string>("atheme");
|
||||
if (!anope.empty() && !atheme.empty())
|
||||
@@ -1594,9 +1698,8 @@ public:
|
||||
}
|
||||
|
||||
nsmiscdata.clear();
|
||||
for (auto idx = 0; idx < modconf.CountBlock("ns_set_misc"); ++idx)
|
||||
for (const auto &[_, data] : modconf.GetBlocks("ns_set_misc"))
|
||||
{
|
||||
const auto &data = modconf.GetBlock("ns_set_misc", idx);
|
||||
const auto &anope = data.Get<const Anope::string>("anope");
|
||||
const auto &atheme = data.Get<const Anope::string>("atheme");
|
||||
if (!anope.empty() && !atheme.empty())
|
||||
@@ -1604,9 +1707,8 @@ public:
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
for (int i = 0; i < Config->CountBlock("privilege"); ++i)
|
||||
for (const auto &[_, priv] : conf.GetBlocks("privilege"))
|
||||
{
|
||||
const auto &priv = Config->GetBlock("privilege", i);
|
||||
const Anope::string &name = priv.Get<const Anope::string>("name");
|
||||
const Anope::string &value = priv.Get<const Anope::string>("flag");
|
||||
if (!name.empty() && !value.empty())
|
||||
@@ -1684,6 +1786,12 @@ public:
|
||||
si.when = data->suspend_ts;
|
||||
ci->Extend("CS_SUSPENDED", si);
|
||||
}
|
||||
|
||||
if (data->founder_candidate.nc)
|
||||
ci->SetFounder(data->founder_candidate.nc);
|
||||
|
||||
if (data->successor_candidate.nc)
|
||||
ci->SetSuccessor(data->successor_candidate.nc);
|
||||
}
|
||||
|
||||
for (const auto &[_, nc] : *NickCoreList)
|
||||
@@ -1692,6 +1800,55 @@ public:
|
||||
if (!data)
|
||||
continue;
|
||||
|
||||
if (!data->ajoins.empty())
|
||||
{
|
||||
auto *channels = nc->Require<AJoinList>(NICKSERV_AJOIN_LIST_EXT);
|
||||
if (channels)
|
||||
{
|
||||
for (const auto& ajoin : data->ajoins)
|
||||
{
|
||||
auto &channel = ajoin.first, &key = ajoin.second;
|
||||
if (!key.empty())
|
||||
{
|
||||
Channel *c = Channel::Find(channel);
|
||||
Anope::string k;
|
||||
if (c && c->GetParam("KEY", k) && key != k)
|
||||
{
|
||||
Log(this) << "Skipping ajoin with incorrect key for channel " << channel
|
||||
<< ", user " << nc->display;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IRCD->IsChannelValid(channel))
|
||||
{
|
||||
Log(this) << "Invalid ajoin channel " << channel << " for " << nc->display;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto it = std::find_if((*channels)->cbegin(), (*channels)->cend(), [&](const AJoinEntry* a){
|
||||
return a->channel == channel;
|
||||
});
|
||||
|
||||
if (it != (*channels)->cend())
|
||||
{
|
||||
Log(this) << "Skipping duplicate ajoin channel" << channel << " for " << nc->display;
|
||||
continue;
|
||||
}
|
||||
auto* entry = new AJoinEntry(nc);
|
||||
entry->owner = nc;
|
||||
entry->channel = channel;
|
||||
entry->key = key;
|
||||
(*channels)->push_back(entry); // ignore ajoinmax for non-disruptive migration
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(this) << "Unable to convert autojoins for " << nc->display << " as ns_ajoin is not loaded";
|
||||
}
|
||||
}
|
||||
|
||||
if (!data->info_message.empty())
|
||||
{
|
||||
auto *oil = nc->Require<OperInfoList>("operinfo");
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
/// BEGIN CMAKE
|
||||
/// target_link_libraries(${SO} PRIVATE "vendored_yyjson")
|
||||
/// END CMAKE
|
||||
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
#include "yyjson/yyjson.c"
|
||||
#include "yyjson/yyjson.h"
|
||||
|
||||
#include "module.h"
|
||||
|
||||
|
||||
+1
-2
@@ -1095,9 +1095,8 @@ public:
|
||||
refresh = block.Get<int>("refresh", "3600");
|
||||
|
||||
std::vector<std::pair<Anope::string, short> > notify;
|
||||
for (int i = 0; i < block.CountBlock("notify"); ++i)
|
||||
for (const auto &[_, n] : block.GetBlocks("notify"))
|
||||
{
|
||||
const auto &n = block.GetBlock("notify", i);
|
||||
auto nip = n.Get<Anope::string>("ip");
|
||||
auto nport = n.Get<short>("port");
|
||||
|
||||
|
||||
+3
-6
@@ -126,9 +126,8 @@ public:
|
||||
this->add_to_akill = block.Get<bool>("add_to_akill", "yes");
|
||||
|
||||
this->blacklists.clear();
|
||||
for (int i = 0; i < block.CountBlock("blacklist"); ++i)
|
||||
for (const auto &[_, bl] : block.GetBlocks("blacklist"))
|
||||
{
|
||||
const auto &bl = block.GetBlock("blacklist", i);
|
||||
Blacklist blacklist;
|
||||
|
||||
blacklist.name = bl.Get<Anope::string>("name");
|
||||
@@ -137,9 +136,8 @@ public:
|
||||
blacklist.bantime = bl.Get<time_t>("time", "4h");
|
||||
blacklist.reason = bl.Get<Anope::string>("reason");
|
||||
|
||||
for (int j = 0; j < bl.CountBlock("reply"); ++j)
|
||||
for (const auto &[_, reply] : block.GetBlocks("reply"))
|
||||
{
|
||||
const auto &reply = bl.GetBlock("reply", j);
|
||||
Blacklist::Reply r;
|
||||
|
||||
r.code = reply.Get<int>("code");
|
||||
@@ -153,9 +151,8 @@ public:
|
||||
}
|
||||
|
||||
this->exempts.clear();
|
||||
for (int i = 0; i < block.CountBlock("exempt"); ++i)
|
||||
for (const auto &[_, bl] : block.GetBlocks("exempt"))
|
||||
{
|
||||
const auto &bl = block.GetBlock("exempt", i);
|
||||
this->exempts.insert(bl.Get<Anope::string>("ip"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,17 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
/// BEGIN CMAKE
|
||||
/// target_link_libraries(${SO} PRIVATE "vendored_bcrypt")
|
||||
/// END CMAKE
|
||||
|
||||
#include <climits>
|
||||
#include <random>
|
||||
|
||||
#include "bcrypt/crypt_blowfish.c"
|
||||
extern "C"
|
||||
{
|
||||
#include "bcrypt/crypt_blowfish.h"
|
||||
}
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/encryption.h"
|
||||
|
||||
@@ -12,10 +12,17 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
/// BEGIN CMAKE
|
||||
/// target_link_libraries(${SO} PRIVATE "vendored_md5")
|
||||
/// END CMAKE
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/encryption.h"
|
||||
|
||||
#include "md5/md5.c"
|
||||
extern "C"
|
||||
{
|
||||
#include "md5/md5.h"
|
||||
}
|
||||
|
||||
class MD5Context final
|
||||
: public Encryption::Context
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
/// BEGIN CMAKE
|
||||
/// target_link_libraries(${SO} PRIVATE "vendored_sha1")
|
||||
/// END CMAKE
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/encryption.h"
|
||||
|
||||
#include "sha1/sha1.c"
|
||||
#include "sha1/sha1.h"
|
||||
|
||||
class SHA1Context final
|
||||
: public Encryption::Context
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
/// BEGIN CMAKE
|
||||
/// target_link_libraries(${SO} PRIVATE "vendored_sha2")
|
||||
/// END CMAKE
|
||||
|
||||
#include <climits>
|
||||
#include <random>
|
||||
|
||||
#include "sha2/sha2.c"
|
||||
#include "sha2/sha2.h"
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/encryption.h"
|
||||
|
||||
@@ -634,7 +634,7 @@ public:
|
||||
{
|
||||
const Anope::string &cname = it->first;
|
||||
LDAPService *s = it->second;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
++it;
|
||||
|
||||
@@ -654,10 +654,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("ldap"); ++i)
|
||||
for (const auto &[_, ldap] : conf.GetBlocks("ldap"))
|
||||
{
|
||||
const auto &ldap = conf.GetBlock("ldap", i);
|
||||
|
||||
const Anope::string &connname = ldap.Get<const Anope::string>("name", "ldap/main");
|
||||
|
||||
if (this->LDAPServices.find(connname) == this->LDAPServices.end())
|
||||
|
||||
@@ -281,7 +281,7 @@ public:
|
||||
{
|
||||
const Anope::string &cname = it->first;
|
||||
MySQLService *s = it->second;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
++it;
|
||||
|
||||
@@ -298,9 +298,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < config.CountBlock("mysql"); ++i)
|
||||
for (const auto &[_, block] : config.GetBlocks("mysql"))
|
||||
{
|
||||
const auto &block = config.GetBlock("mysql", i);
|
||||
const Anope::string &connname = block.Get<const Anope::string>("name", "mysql/main");
|
||||
|
||||
if (this->MySQLServices.find(connname) == this->MySQLServices.end())
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
{
|
||||
const Anope::string &cname = it->first;
|
||||
SQLiteService *s = it->second;
|
||||
int i, num;
|
||||
size_t i, num;
|
||||
++it;
|
||||
|
||||
for (i = 0, num = config.CountBlock("sqlite"); i < num; ++i)
|
||||
@@ -145,9 +145,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < config.CountBlock("sqlite"); ++i)
|
||||
for (const auto &[_, block] : config.GetBlocks("sqlite"))
|
||||
{
|
||||
const auto &block = config.GetBlock("sqlite", i);
|
||||
Anope::string connname = block.Get<const Anope::string>("name", "sqlite/main");
|
||||
|
||||
if (this->SQLiteServices.find(connname) == this->SQLiteServices.end())
|
||||
|
||||
@@ -331,10 +331,8 @@ public:
|
||||
throw ConfigException("Unable to find http reference, is httpd loaded?");
|
||||
|
||||
xmlrpcinterface.tokens.clear();
|
||||
for (int i = 0; i < modconf.CountBlock("token"); ++i)
|
||||
for (const auto &[_, block] : modconf.GetBlocks("token"))
|
||||
{
|
||||
const auto &block = modconf.GetBlock("token", i);
|
||||
|
||||
RPC::Token token;
|
||||
token.token = block.Get<const Anope::string>("token");
|
||||
if (!token.token.empty())
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
CommandGLQueue(Module *creator)
|
||||
: Command(creator, "global/queue", 1, 2)
|
||||
{
|
||||
this->SetDesc(_("Manages your pending message queue."));
|
||||
this->SetDesc(_("Manage your pending message queue."));
|
||||
this->SetSyntax(_("ADD \037message\037"));
|
||||
this->SetSyntax(_("DEL \037entry-num\037"));
|
||||
this->SetSyntax("LIST");
|
||||
|
||||
@@ -156,7 +156,12 @@ public:
|
||||
if (server)
|
||||
this->ServerGlobal(sender, server, false, line);
|
||||
else
|
||||
this->ServerGlobal(sender, Servers::GetUplink(), true, line);
|
||||
{
|
||||
auto* uplink = Servers::GetUplink();
|
||||
if (!uplink)
|
||||
return false;
|
||||
this->ServerGlobal(sender, uplink, true, line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class CommandHelp final
|
||||
public:
|
||||
CommandHelp(Module *creator) : Command(creator, "generic/help", 0)
|
||||
{
|
||||
this->SetDesc(_("Displays this list and give information about commands"));
|
||||
this->SetDesc(_("Display this list and give information about commands"));
|
||||
this->AllowUnregistered(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class CommandHSDelAll final
|
||||
public:
|
||||
CommandHSDelAll(Module *creator) : Command(creator, "hostserv/delall", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Deletes the vhost for all nicks in an account"));
|
||||
this->SetDesc(_("Delete the vhost for all nicks in an account"));
|
||||
this->SetSyntax(_("\037nick\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0)
|
||||
{
|
||||
this->SetDesc(_("Syncs the vhost for all nicks in an account"));
|
||||
this->SetDesc(_("Sync the vhost for all nicks in an account"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandHSList final
|
||||
public:
|
||||
CommandHSList(Module *creator) : Command(creator, "hostserv/list", 0, 1)
|
||||
{
|
||||
this->SetDesc(_("Displays one or more vhost entries"));
|
||||
this->SetDesc(_("Display one or more vhost entries"));
|
||||
this->SetSyntax(_("[\037key\037|\037#X-Y\037]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandHSOff final
|
||||
public:
|
||||
CommandHSOff(Module *creator) : Command(creator, "hostserv/off", 0, 0)
|
||||
{
|
||||
this->SetDesc(_("Deactivates your assigned vhost"));
|
||||
this->SetDesc(_("Deactivate your assigned vhost"));
|
||||
this->RequireUser(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandHSOn final
|
||||
public:
|
||||
CommandHSOn(Module *creator) : Command(creator, "hostserv/on", 0, 0)
|
||||
{
|
||||
this->SetDesc(_("Activates your assigned vhost"));
|
||||
this->SetDesc(_("Activate your assigned vhost"));
|
||||
this->RequireUser(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,29 @@ namespace
|
||||
Anope::string validation_record;
|
||||
}
|
||||
|
||||
struct SharedData final
|
||||
{
|
||||
// How long after a requested vhost is activated does a user have to wait before they can request a new vhost.
|
||||
time_t activationcooldown = 0;
|
||||
|
||||
// How long after a requested vhost is rejected does a user have to wait before they can request a new vhost.
|
||||
time_t rejectioncooldown = 0;
|
||||
|
||||
// How long should users have to wait between attempts at DNS validation.
|
||||
time_t validationcooldown = 0;
|
||||
|
||||
// Extensible that stores the time a user had a vhost activated/rejected.
|
||||
SerializableExtensibleItem<time_t> requestcooldown;
|
||||
|
||||
// The name of the DNS record used for validation.
|
||||
Anope::string validationrecord;
|
||||
|
||||
SharedData(Module *mod)
|
||||
: requestcooldown(mod, "HS_REQUEST_COOLDOWN")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct HostRequestImpl final
|
||||
: HostServ::HostRequest
|
||||
, Serializable
|
||||
@@ -105,6 +128,7 @@ private:
|
||||
Command *command;
|
||||
Reference<NickAlias> nickalias;
|
||||
CommandSource source;
|
||||
SharedData &data;
|
||||
|
||||
void HandleError(HostRequestImpl *hr)
|
||||
{
|
||||
@@ -119,11 +143,12 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
DNSHostResolver(Command *cmd, HostServ::HostRequest *hr, NickAlias *na, const CommandSource &src)
|
||||
DNSHostResolver(Command *cmd, HostServ::HostRequest *hr, NickAlias *na, const CommandSource &src, SharedData &sd)
|
||||
: Request(dnsmanager, cmd->module, hr->host, DNS::QUERY_TXT, false)
|
||||
, command(cmd)
|
||||
, nickalias(na)
|
||||
, source(src)
|
||||
, data(sd)
|
||||
{
|
||||
hr->last_validation = Anope::CurTime;
|
||||
Log(LOG_DEBUG) << "Checking " << hr->host << " for " << hr->validation_token;
|
||||
@@ -171,6 +196,8 @@ public:
|
||||
|
||||
source.Reply(_("VHost for %s has been validated using DNS."), na->nick.c_str());
|
||||
Log(LOG_COMMAND, source, command) << "for " << na->nick << " for vhost " << hr->Mask();
|
||||
|
||||
data.requestcooldown.Set(na, Anope::CurTime + data.activationcooldown);
|
||||
na->Shrink<HostRequestImpl>(HOSTSERV_HOST_REQUEST_EXT);
|
||||
|
||||
return; // We're done.
|
||||
@@ -183,8 +210,13 @@ public:
|
||||
class CommandHSRequest final
|
||||
: public Command
|
||||
{
|
||||
private:
|
||||
SharedData &data;
|
||||
|
||||
public:
|
||||
CommandHSRequest(Module *creator) : Command(creator, "hostserv/request", 1, 1)
|
||||
CommandHSRequest(Module *creator, SharedData &sd)
|
||||
: Command(creator, "hostserv/request", 1, 1)
|
||||
, data(sd)
|
||||
{
|
||||
this->SetDesc(_("Request a vhost for your nick"));
|
||||
this->SetSyntax(_("vhost"));
|
||||
@@ -263,12 +295,25 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
time_t send_delay = Config->GetModule("memoserv").Get<time_t>("senddelay");
|
||||
if (Config->GetModule(this->owner).Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime)
|
||||
time_t waituntil = 0;
|
||||
{
|
||||
auto waitperiod = (u->lastmemosend + send_delay) - Anope::CurTime;
|
||||
// Check whether the user is on a request cooldown.
|
||||
const auto *last_req = data.requestcooldown.Get(na);
|
||||
if (last_req)
|
||||
waituntil = *last_req;
|
||||
}
|
||||
if (Config->GetModule(this->owner).Get<bool>("memooper"))
|
||||
{
|
||||
// Check whether the user can send a memo to opers yet.
|
||||
const auto send_delay = Config->GetModule("memoserv").Get<time_t>("senddelay");
|
||||
if (send_delay > 0 && u && u->lastmemosend)
|
||||
waituntil = std::max(waituntil, u->lastmemosend + send_delay);
|
||||
}
|
||||
|
||||
if (waituntil && waituntil > Anope::CurTime)
|
||||
{
|
||||
const auto waitperiod = waituntil - Anope::CurTime;
|
||||
source.Reply(_("Please wait %s before requesting a new vhost."), Anope::Duration(waitperiod, source.GetAccount()).c_str());
|
||||
u->lastmemosend = Anope::CurTime;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -319,8 +364,13 @@ public:
|
||||
class CommandHSActivate final
|
||||
: public Command
|
||||
{
|
||||
private:
|
||||
SharedData &data;
|
||||
|
||||
public:
|
||||
CommandHSActivate(Module *creator) : Command(creator, "hostserv/activate", 1, 1)
|
||||
CommandHSActivate(Module *creator, SharedData &sd)
|
||||
: Command(creator, "hostserv/activate", 1, 1)
|
||||
, data(sd)
|
||||
{
|
||||
this->SetDesc(_("Approve the requested vhost of a user"));
|
||||
this->SetSyntax(_("\037nick\037"));
|
||||
@@ -348,6 +398,8 @@ public:
|
||||
|
||||
source.Reply(_("VHost for %s has been activated."), na->nick.c_str());
|
||||
Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host;
|
||||
|
||||
data.requestcooldown.Set(na, Anope::CurTime + data.activationcooldown);
|
||||
na->Shrink<HostRequestImpl>(HOSTSERV_HOST_REQUEST_EXT);
|
||||
}
|
||||
else
|
||||
@@ -369,8 +421,13 @@ public:
|
||||
class CommandHSReject final
|
||||
: public Command
|
||||
{
|
||||
private:
|
||||
SharedData &data;
|
||||
|
||||
public:
|
||||
CommandHSReject(Module *creator) : Command(creator, "hostserv/reject", 1, 2)
|
||||
CommandHSReject(Module *creator, SharedData &sd)
|
||||
: Command(creator, "hostserv/reject", 1, 2)
|
||||
, data(sd)
|
||||
{
|
||||
this->SetDesc(_("Reject the requested vhost of a user"));
|
||||
this->SetSyntax(_("\037nick\037 [\037reason\037]"));
|
||||
@@ -391,6 +448,7 @@ public:
|
||||
auto *req = HostRequestImpl::Get(na);
|
||||
if (req)
|
||||
{
|
||||
data.requestcooldown.Set(na, Anope::CurTime + data.rejectioncooldown);
|
||||
na->Shrink<HostRequestImpl>(HOSTSERV_HOST_REQUEST_EXT);
|
||||
|
||||
if (Config->GetModule(this->owner).Get<bool>("memouser") && MemoServ::service)
|
||||
@@ -429,7 +487,7 @@ class CommandHSWaiting final
|
||||
public:
|
||||
CommandHSWaiting(Module *creator) : Command(creator, "hostserv/waiting", 0, 0)
|
||||
{
|
||||
this->SetDesc(_("Retrieves the vhost requests"));
|
||||
this->SetDesc(_("Retrieve the vhost requests"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
@@ -481,13 +539,15 @@ public:
|
||||
class CommandHSValidate final
|
||||
: public Command
|
||||
{
|
||||
public:
|
||||
time_t cooldown;
|
||||
private:
|
||||
SharedData &data;
|
||||
|
||||
CommandHSValidate(Module *creator)
|
||||
public:
|
||||
CommandHSValidate(Module *creator, SharedData &sd)
|
||||
: Command(creator, "hostserv/validate", 0)
|
||||
, data(sd)
|
||||
{
|
||||
this->SetDesc(_("Validates a previously requested vhost using DNS"));
|
||||
this->SetDesc(_("Validate a previously requested vhost using DNS"));
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
@@ -512,7 +572,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
auto next_validation = req->last_validation + cooldown;
|
||||
auto next_validation = req->last_validation + data.validationcooldown;
|
||||
if (req->last_validation && next_validation > Anope::CurTime)
|
||||
{
|
||||
source.Reply(_("You must wait for %s before trying DNS validation again."),
|
||||
@@ -526,7 +586,7 @@ public:
|
||||
if (!dnsmanager)
|
||||
throw SocketException("DNS is not available");
|
||||
|
||||
res = new DNSHostResolver(this, req, na, source);
|
||||
res = new DNSHostResolver(this, req, na, source, data);
|
||||
dnsmanager->Process(res);
|
||||
}
|
||||
catch (const SocketException &ex)
|
||||
@@ -553,8 +613,10 @@ public:
|
||||
class HSRequest final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
SharedData data;
|
||||
CommandHSRequest commandhsrequest;
|
||||
CommandHSActivate commandhsactive;
|
||||
CommandHSActivate commandhsactivate;
|
||||
CommandHSReject commandhsreject;
|
||||
CommandHSWaiting commandhswaiting;
|
||||
CommandHSValidate commandhsvalidate;
|
||||
@@ -564,11 +626,12 @@ class HSRequest final
|
||||
public:
|
||||
HSRequest(const Anope::string &modname, const Anope::string &creator)
|
||||
: Module(modname, creator, VENDOR)
|
||||
, commandhsrequest(this)
|
||||
, commandhsactive(this)
|
||||
, commandhsreject(this)
|
||||
, data(this)
|
||||
, commandhsrequest(this, data)
|
||||
, commandhsactivate(this, data)
|
||||
, commandhsreject(this, data)
|
||||
, commandhswaiting(this)
|
||||
, commandhsvalidate(this)
|
||||
, commandhsvalidate(this, data)
|
||||
, hostrequest(this, HOSTSERV_HOST_REQUEST_EXT)
|
||||
{
|
||||
if (!IRCD || !IRCD->CanSetVHost)
|
||||
@@ -578,7 +641,9 @@ public:
|
||||
void OnReload(Configuration::Conf &conf) override
|
||||
{
|
||||
const auto &block = conf.GetModule(this);
|
||||
commandhsvalidate.cooldown = block.Get<time_t>("validationcooldown", "5m");
|
||||
data.activationcooldown = block.Get<time_t>("activationcooldown", "24h");
|
||||
data.rejectioncooldown = block.Get<time_t>("rejectioncooldown", "24h");
|
||||
data.validationcooldown = block.Get<time_t>("validationcooldown", "5m");
|
||||
validation_record = block.Get<const Anope::string>("validationrecord", "anope-dns-validation");
|
||||
}
|
||||
};
|
||||
|
||||
+1
-4
@@ -372,11 +372,8 @@ public:
|
||||
const auto &conf = config.GetModule(this);
|
||||
std::set<Anope::string> existing;
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("httpd"); ++i)
|
||||
for (const auto &[_, block] : conf.GetBlocks("httpd"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("httpd", i);
|
||||
|
||||
|
||||
const Anope::string &hname = block.Get<const Anope::string>("name", "httpd/main");
|
||||
existing.insert(hname);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandMSCheck final
|
||||
public:
|
||||
CommandMSCheck(Module *creator) : Command(creator, "memoserv/check", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Checks if last memo to a nick was read"));
|
||||
this->SetDesc(_("Check if last memo to a nick was read"));
|
||||
this->SetSyntax(_("\037nick\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandMSInfo final
|
||||
public:
|
||||
CommandMSInfo(Module *creator) : Command(creator, "memoserv/info", 0, 1)
|
||||
{
|
||||
this->SetDesc(_("Displays information about your memos"));
|
||||
this->SetDesc(_("Display information about your memos"));
|
||||
this->SetSyntax(_("[\037nick\037 | \037channel\037]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class CommandMSRSend final
|
||||
public:
|
||||
CommandMSRSend(Module *creator) : Command(creator, "memoserv/rsend", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Sends a memo and requests a read receipt"));
|
||||
this->SetDesc(_("Send a memo and requests a read receipt"));
|
||||
this->SetSyntax(_("{\037nick\037 | \037channel\037} \037memo-text\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,34 +13,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/nickserv/ajoin.h"
|
||||
|
||||
struct AJoinEntry;
|
||||
|
||||
struct AJoinList final
|
||||
: Serialize::Checker<std::vector<AJoinEntry *> >
|
||||
struct AJoinListImpl final : public AJoinList
|
||||
{
|
||||
AJoinList(Extensible *) : Serialize::Checker<std::vector<AJoinEntry *> >("AJoinEntry") { }
|
||||
~AJoinList();
|
||||
};
|
||||
|
||||
struct AJoinEntry final
|
||||
: Serializable
|
||||
{
|
||||
Serialize::Reference<NickCore> owner;
|
||||
Anope::string channel;
|
||||
Anope::string key;
|
||||
|
||||
AJoinEntry(Extensible *) : Serializable("AJoinEntry") { }
|
||||
|
||||
~AJoinEntry() override
|
||||
AJoinListImpl(Extensible * e) : AJoinList(e) { }
|
||||
~AJoinListImpl()
|
||||
{
|
||||
auto *channels = owner->GetExt<AJoinList>("ajoinlist");
|
||||
if (channels)
|
||||
{
|
||||
auto it = std::find((*channels)->begin(), (*channels)->end(), this);
|
||||
if (it != (*channels)->end())
|
||||
(*channels)->erase(it);
|
||||
}
|
||||
for (const auto *ajoin : *(*this))
|
||||
delete ajoin;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -93,12 +74,6 @@ struct AJoinEntryType final
|
||||
}
|
||||
};
|
||||
|
||||
AJoinList::~AJoinList()
|
||||
{
|
||||
for (const auto *ajoin : *(*this))
|
||||
delete ajoin;
|
||||
}
|
||||
|
||||
class CommandNSAJoin final
|
||||
: public Command
|
||||
{
|
||||
@@ -321,7 +296,7 @@ class NSAJoin final
|
||||
: public Module
|
||||
{
|
||||
CommandNSAJoin commandnsajoin;
|
||||
ExtensibleItem<AJoinList> ajoinlist;
|
||||
ExtensibleItem<AJoinListImpl> ajoinlist;
|
||||
AJoinEntryType ajoinentry_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -164,12 +164,12 @@ public:
|
||||
if (newit != this->certs.end())
|
||||
{
|
||||
// The cert we're upgrading to already exists.
|
||||
delete *newit;
|
||||
this->certs.erase(newit);
|
||||
delete *oldit;
|
||||
this->certs.erase(oldit);
|
||||
return;
|
||||
}
|
||||
|
||||
auto *cert = *newit;
|
||||
auto *cert = *oldit;
|
||||
cert->fingerprint = newentry;
|
||||
certmap[newentry] = cert;
|
||||
FOREACH_MOD(OnNickAddCert, (this->nc, cert));
|
||||
@@ -548,7 +548,7 @@ public:
|
||||
CommandNSSetAutologin(Module *creator, const Anope::string &sname = "nickserv/set/autologin", size_t min = 1)
|
||||
: Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Sets whether you should automatically be logged in when you connect using a known SSL certificate."));
|
||||
this->SetDesc(_("Set whether you should automatically be logged in when you connect using a known SSL certificate."));
|
||||
this->SetSyntax("{ON | OFF}");
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ public:
|
||||
CommandNSGetEmail(Module *creator)
|
||||
: Command(creator, "nickserv/getemail", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Matches and returns all users that registered using given email address"));
|
||||
this->SetDesc(_("Match and return all users that registered using given email address"));
|
||||
this->SetSyntax(_("\037email\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ class CommandNSGList final
|
||||
public:
|
||||
CommandNSGList(Module *creator) : Command(creator, "nickserv/glist", 0, 1)
|
||||
{
|
||||
this->SetDesc(_("Lists all nicknames in your account"));
|
||||
this->SetDesc(_("List all nicknames in your account"));
|
||||
this->SetSyntax(_("[\037nickname\037]"), [](auto &source) { return source.IsServicesOper(); });
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandNSInfo final
|
||||
public:
|
||||
CommandNSInfo(Module *creator) : Command(creator, "nickserv/info", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Displays information about a given nickname"));
|
||||
this->SetDesc(_("Display information about a given nickname"));
|
||||
this->SetSyntax(_("[\037nickname\037]"));
|
||||
this->AllowUnregistered(true);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class CommandNSLogout final
|
||||
public:
|
||||
CommandNSLogout(Module *creator) : Command(creator, "nickserv/logout", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Reverses the effect of the IDENTIFY command"));
|
||||
this->SetDesc(_("Reverse the effect of the IDENTIFY command"));
|
||||
this->SetSyntax(_("[\037nickname\037 [REVALIDATE]]"), [](auto &source) { return source.IsServicesOper(); });
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ class CommandNSRecover final
|
||||
public:
|
||||
CommandNSRecover(Module *creator) : Command(creator, "nickserv/recover", 1, 2)
|
||||
{
|
||||
this->SetDesc(_("Regains control of your nick"));
|
||||
this->SetDesc(_("Regain control of your nick"));
|
||||
this->SetSyntax(_("\037nickname\037 [\037password\037]"));
|
||||
this->AllowUnregistered(true);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class CommandNSResetPass final
|
||||
public:
|
||||
CommandNSResetPass(Module *creator) : Command(creator, "nickserv/resetpass", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Helps you reset lost passwords"));
|
||||
this->SetDesc(_("Send an email to recover access to an account"));
|
||||
this->SetSyntax(_("\037nickname\037 \037email\037"));
|
||||
this->AllowUnregistered(true);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
CommandNSSetKeepModes(Module *creator, const Anope::string &sname = "nickserv/set/keepmodes", size_t min = 1)
|
||||
: Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Enable or disable keep modes"));
|
||||
this->SetDesc(_("Configure keeping user modes set across connections"));
|
||||
this->SetSyntax("{ON | OFF}");
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ public:
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_(
|
||||
"Enables or disables keepmodes for your nick. If keep "
|
||||
"modes is enabled, services will remember your usermodes "
|
||||
"and attempt to re-set them the next time you authenticate."
|
||||
"Configures keeping user modes set across connections. If this is "
|
||||
"enabled, your last user modes will be remembered and will be "
|
||||
"re-set the next time you identify."
|
||||
));
|
||||
return true;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
source.Reply(" ");
|
||||
source.Reply(_(
|
||||
"Enables or disables keepmodes for the given nick. If keep "
|
||||
"modes is enabled, services will remember users' usermodes "
|
||||
"modes is enabled, services will remember users' user modes "
|
||||
"and attempt to re-set them the next time they authenticate."
|
||||
));
|
||||
return true;
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
CommandNSSetLayout(Module *creator, const Anope::string &sname = "nickserv/set/layout", size_t min = 1)
|
||||
: Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Configures the layout used for services messages"));
|
||||
this->SetDesc(_("Configure the layout used for services messages"));
|
||||
this->SetSyntax("{FIXED | FLEXIBLE | MONOSPACE}");
|
||||
}
|
||||
|
||||
|
||||
@@ -330,9 +330,9 @@ public:
|
||||
command_data.clear();
|
||||
items_by_priority.clear();
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("command"); ++i)
|
||||
time_t default_priority = 0;
|
||||
for (const auto &[_, block] : conf.GetBlocks("command"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("command", i);
|
||||
const Anope::string &cmd = block.Get<const Anope::string>("command");
|
||||
if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc")
|
||||
continue;
|
||||
@@ -353,6 +353,8 @@ public:
|
||||
continue;
|
||||
}
|
||||
|
||||
default_priority += 1000;
|
||||
|
||||
data.set_description = desc;
|
||||
data.pattern = block.Get<const Anope::string>("misc_pattern");
|
||||
data.syntax = block.Get<const Anope::string>("misc_syntax");
|
||||
@@ -361,7 +363,7 @@ public:
|
||||
if (data.priority <= 0)
|
||||
{
|
||||
// If no priority is specified, go by order processed
|
||||
data.priority = i * 1000;
|
||||
data.priority = default_priority;
|
||||
}
|
||||
data.swhois = block.Get<bool>("misc_swhois");
|
||||
items_by_priority.emplace_back(data.priority, item);
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
CommandNSSetOpAutoOp(Module *creator, const Anope::string &sname = "nickserv/set/autoop", size_t min = 1)
|
||||
: Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Sets whether services should set channel status modes on you automatically."));
|
||||
this->SetDesc(_("Set whether services should set channel status modes on you automatically."));
|
||||
this->SetSyntax("{ON | OFF}");
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
CommandNSSetOpNeverOp(Module *creator, const Anope::string &sname = "nickserv/set/neverop", size_t min = 1)
|
||||
: Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Sets whether you can be added to a channel access list."));
|
||||
this->SetDesc(_("Set whether you can be added to a channel access list."));
|
||||
this->SetSyntax("{ON | OFF}");
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,9 @@ protected:
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
buffer.append(buffer.empty() ? " " : ", ");
|
||||
buffer.append(timezone);
|
||||
buffer
|
||||
.append(buffer.empty() ? " " : ", ")
|
||||
.append(timezone);
|
||||
}
|
||||
|
||||
if (!buffer.empty())
|
||||
@@ -156,7 +157,10 @@ public:
|
||||
));
|
||||
|
||||
for (const auto &[timeregion, timezone] : timeregions)
|
||||
source.Reply(" %s (%zu timezones)", timeregion.c_str(), timezone.size());
|
||||
{
|
||||
source.Reply(timezone.size(), N_(" %s (%zu timezone)", " %s (%zu timezones)"),
|
||||
timeregion.c_str(), timezone.size());
|
||||
}
|
||||
|
||||
source.Reply(_("Type \002%s\033\037region\037\002 to list timezones for a region."),
|
||||
source.service->GetQueryCommand("generic/help", source.command).c_str());
|
||||
@@ -240,12 +244,32 @@ public:
|
||||
// Build the region list.
|
||||
for (const auto &timezone : timezones)
|
||||
{
|
||||
auto tzsep = timezone.find('/');
|
||||
const auto tzsep = timezone.rfind('/');
|
||||
auto region = tzsep == Anope::string::npos ? "Misc" : timezone.substr(0, tzsep);
|
||||
timeregions[region].push_back(timezone);
|
||||
}
|
||||
for (auto &[_, timeregion] : timeregions)
|
||||
std::sort(timeregion.begin(), timeregion.end());
|
||||
|
||||
// Eliminate regions with only one timezone.
|
||||
for (auto it = timeregions.end(); it != timeregions.begin(); )
|
||||
{
|
||||
it--;
|
||||
const auto &[timeregion, timezones] = *it;
|
||||
if (!timeregion.equals_ci("Misc") && timezones.size() < 2)
|
||||
{
|
||||
const auto trsep = timeregion.rfind('/');
|
||||
auto region = trsep == Anope::string::npos ? "Misc" : timeregion.substr(0, trsep);
|
||||
|
||||
auto& parentregion = timeregions[region];
|
||||
parentregion.insert(parentregion.end(), timezones.begin(), timezones.end());
|
||||
|
||||
it = timeregions.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the timezone list is ordered alphabetically.
|
||||
for (auto &[_, timezones] : timeregions)
|
||||
std::sort(timezones.begin(), timezones.end());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandNSUpdate final
|
||||
public:
|
||||
CommandNSUpdate(Module *creator) : Command(creator, "nickserv/update", 0, 0)
|
||||
{
|
||||
this->SetDesc(_("Updates your current status, i.e. it checks for new memos"));
|
||||
this->SetDesc(_("Update your current status, i.e. it checks for new memos"));
|
||||
this->RequireUser(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
for (unsigned i = 0; !show_blocks[i].empty(); ++i)
|
||||
{
|
||||
const auto &block = Config->GetBlock(show_blocks[i]);
|
||||
const Configuration::Block::item_map &items = block.GetItems();
|
||||
const auto &items = block.GetItems();
|
||||
|
||||
ListFormatter lflist(source.GetAccount());
|
||||
lflist.AddColumn(_("Name")).AddColumn(_("Value"));
|
||||
@@ -84,10 +84,9 @@ public:
|
||||
lflist.AddColumn(_("Module Name")).AddColumn(_("Name")).AddColumn(_("Value"));
|
||||
lflist.SetFlexible(_("\002{}{module_name}}:{name}\002 = {value}"));
|
||||
|
||||
for (int i = 0; i < Config->CountBlock("module"); ++i)
|
||||
for (const auto &[_, block] : Config->GetBlocks("module"))
|
||||
{
|
||||
const auto &block = Config->GetBlock("module", i);
|
||||
const Configuration::Block::item_map &items = block.GetItems();
|
||||
const auto &items = block.GetItems();
|
||||
|
||||
if (items.size() <= 1)
|
||||
continue;
|
||||
|
||||
@@ -529,10 +529,8 @@ public:
|
||||
fileforbids.clear();
|
||||
|
||||
const auto &modconf = conf.GetModule(this);
|
||||
for (auto i = 0; i < modconf.CountBlock("file"); ++i)
|
||||
for (const auto &[_, fileblock] : modconf.GetBlocks("file"))
|
||||
{
|
||||
const auto &fileblock = modconf.GetBlock("file", i);
|
||||
|
||||
const auto reasonstr = fileblock.Get<const Anope::string>("reason");
|
||||
|
||||
const auto typestr = fileblock.Get<const Anope::string>("type");
|
||||
|
||||
@@ -20,7 +20,7 @@ class CommandOSChanList final
|
||||
public:
|
||||
CommandOSChanList(Module *creator) : Command(creator, "operserv/chanlist", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Lists all channel records"));
|
||||
this->SetDesc(_("List all channel records"));
|
||||
this->SetSyntax(_("[{\037pattern\037 | \037nick\037} [\037SECRET\037]]"));
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ class CommandOSUserList final
|
||||
public:
|
||||
CommandOSUserList(Module *creator) : Command(creator, "operserv/userlist", 0, 2)
|
||||
{
|
||||
this->SetDesc(_("Lists all user records"));
|
||||
this->SetDesc(_("List all user records"));
|
||||
this->SetSyntax(_("[{\037pattern\037 | \037channel\037} [\037INVISIBLE\037]]"));
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class CommandOSLogSearch final
|
||||
public:
|
||||
CommandOSLogSearch(Module *creator) : Command(creator, "operserv/logsearch", 1, 3)
|
||||
{
|
||||
this->SetDesc(_("Searches logs for a matching pattern"));
|
||||
this->SetDesc(_("Search logs for a matching pattern"));
|
||||
this->SetSyntax(_("[+\037days\037d] [+\037limit\037l] \037pattern\037"));
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ public:
|
||||
{
|
||||
bool all = params.size() > 2 && params[2].equals_ci("ALL");
|
||||
|
||||
for (const auto &[mode, data] : c->GetModes())
|
||||
auto cmodes = c->GetModes();
|
||||
for (const auto &[mode, data] : cmodes)
|
||||
c->RemoveMode(c->WhoSends(), mode, data.value, false);
|
||||
|
||||
if (!c)
|
||||
@@ -163,9 +164,9 @@ public:
|
||||
else
|
||||
{
|
||||
u2->SetModes(source.service, modes);
|
||||
source.Reply(_("Changed usermodes of \002%s\002 to %s."), u2->nick.c_str(), modes.c_str());
|
||||
source.Reply(_("Changed user modes of \002%s\002 to %s."), u2->nick.c_str(), modes.c_str());
|
||||
|
||||
u2->SendMessage(source.service, _("\002%s\002 changed your usermodes to %s."), source.GetNick().c_str(), modes.c_str());
|
||||
u2->SendMessage(source.service, _("\002%s\002 changed your user modes to %s."), source.GetNick().c_str(), modes.c_str());
|
||||
|
||||
Log(LOG_ADMIN, source, this) << modes << " on " << target;
|
||||
}
|
||||
|
||||
@@ -734,7 +734,7 @@ public:
|
||||
bool IsTagValid(const Anope::string &tname, const Anope::string &tvalue) override
|
||||
{
|
||||
// InspIRCd accepts arbitrary message tags.
|
||||
return true;
|
||||
return Me->IsSynced();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1814,9 +1814,27 @@ private:
|
||||
{
|
||||
// If we're bursting then then the user was probably logged in
|
||||
// during a previous connection.
|
||||
auto *nc = NickCore::Find(value);
|
||||
if (nc)
|
||||
auto *na = NickAlias::Find(value);
|
||||
if (!na)
|
||||
{
|
||||
// Nick has been dropped, force the IRCd to deauth them.
|
||||
IRCD->SendLogout(u);
|
||||
return;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
if (na == nc->na)
|
||||
{
|
||||
// User is logged into their display nick.
|
||||
u->Login(nc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is logged into a non-display nick, their display has
|
||||
// probably expired due to a config change so reauthenticate
|
||||
// them as their new display nick.
|
||||
u->Identify(nc->na);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -329,9 +329,29 @@ struct IRCDMessageMetadata final
|
||||
}
|
||||
if (params[1].equals_cs("accountname"))
|
||||
{
|
||||
NickCore *nc = NickCore::Find(params[2]);
|
||||
if (nc)
|
||||
// If we're bursting then then the user was probably logged in
|
||||
// during a previous connection.
|
||||
auto *na = NickAlias::Find(params[2]);
|
||||
if (!na)
|
||||
{
|
||||
// Nick has been dropped, force the IRCd to deauth them.
|
||||
IRCD->SendLogout(u);
|
||||
return;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
if (na == nc->na)
|
||||
{
|
||||
// User is logged into their display nick.
|
||||
u->Login(nc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is logged into a non-display nick, their display has
|
||||
// probably expired due to a config change so reauthenticate
|
||||
// them as their new display nick.
|
||||
u->Identify(nc->na);
|
||||
}
|
||||
}
|
||||
else if (params[1].equals_cs("certfp"))
|
||||
{
|
||||
|
||||
@@ -227,11 +227,33 @@ struct IRCDMessageEncap final
|
||||
if (params[1].equals_cs("SU"))
|
||||
{
|
||||
User *u = User::Find(params[2]);
|
||||
NickCore *nc = NickCore::Find(params[3]);
|
||||
if (u && nc)
|
||||
if (!u)
|
||||
return; // Should never happen.
|
||||
|
||||
// If we're bursting then then the user was probably logged in
|
||||
// during a previous connection.
|
||||
auto *na = NickAlias::Find(params[3]);
|
||||
if (!na)
|
||||
{
|
||||
// Nick has been dropped, force the IRCd to deauth them.
|
||||
IRCD->SendLogout(u);
|
||||
return;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
if (na == nc->na)
|
||||
{
|
||||
// User is logged into their display nick.
|
||||
u->Login(nc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is logged into a non-display nick, their display has
|
||||
// probably expired due to a config change so reauthenticate
|
||||
// them as their new display nick.
|
||||
u->Identify(nc->na);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -156,11 +156,32 @@ struct IRCDMessageEncap final
|
||||
if (params[1] == "LOGIN" || params[1] == "SU")
|
||||
{
|
||||
User *u = source.GetUser();
|
||||
if (!u)
|
||||
return; // Should never happen.
|
||||
|
||||
NickCore *nc = NickCore::Find(params[2]);
|
||||
if (!nc)
|
||||
// If we're bursting then then the user was probably logged in
|
||||
// during a previous connection.
|
||||
auto *na = NickAlias::Find(params[2]);
|
||||
if (!na)
|
||||
{
|
||||
// Nick has been dropped, force the IRCd to deauth them.
|
||||
IRCD->SendLogout(u);
|
||||
return;
|
||||
u->Login(nc);
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
if (na == nc->na)
|
||||
{
|
||||
// User is logged into their display nick.
|
||||
u->Login(nc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is logged into a non-display nick, their display has
|
||||
// probably expired due to a config change so reauthenticate
|
||||
// them as their new display nick.
|
||||
u->Identify(nc->na);
|
||||
}
|
||||
|
||||
/* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if
|
||||
* their server isn't syncing) and then we receive this.. so tell them about it.
|
||||
|
||||
@@ -318,12 +318,32 @@ struct IRCDMessageEncap final
|
||||
if (params[1] == "LOGIN" || params[1] == "SU")
|
||||
{
|
||||
User *u = source.GetUser();
|
||||
NickCore *nc = NickCore::Find(params[2]);
|
||||
|
||||
if (!u || !nc)
|
||||
if (!u)
|
||||
return;
|
||||
|
||||
u->Login(nc);
|
||||
// If we're bursting then then the user was probably logged in
|
||||
// during a previous connection.
|
||||
auto *na = NickAlias::Find(params[2]);
|
||||
if (!na)
|
||||
{
|
||||
// Nick has been dropped, force the IRCd to deauth them.
|
||||
IRCD->SendLogout(u);
|
||||
return;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
if (na == nc->na)
|
||||
{
|
||||
// User is logged into their display nick.
|
||||
u->Login(nc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is logged into a non-display nick, their display has
|
||||
// probably expired due to a config change so reauthenticate
|
||||
// them as their new display nick.
|
||||
u->Identify(nc->na);
|
||||
}
|
||||
}
|
||||
// Received: :42XAAAAAE ENCAP * CERTFP :3f122a9cc7811dbad3566bf2cec3009007c0868f
|
||||
else if (params[1] == "CERTFP")
|
||||
|
||||
@@ -1651,11 +1651,29 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're bursting then then the user was probably logged
|
||||
// in during a previous connection.
|
||||
NickCore *nc = NickCore::Find(params[2]);
|
||||
if (nc)
|
||||
// If we're bursting then then the user was probably logged in
|
||||
// during a previous connection.
|
||||
auto *na = NickAlias::Find(params[2]);
|
||||
if (!na)
|
||||
{
|
||||
// Nick has been dropped, force the IRCd to deauth them.
|
||||
IRCD->SendLogout(u);
|
||||
return;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
if (na == nc->na)
|
||||
{
|
||||
// User is logged into their display nick.
|
||||
u->Login(nc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is logged into a non-display nick, their display has
|
||||
// probably expired due to a config change so reauthenticate
|
||||
// them as their new display nick.
|
||||
u->Identify(nc->na);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -309,9 +309,9 @@ public:
|
||||
}
|
||||
|
||||
this->proxyscans.clear();
|
||||
for (int i = 0; i < config.CountBlock("proxyscan"); ++i)
|
||||
|
||||
for (const auto &[_, block] : config.GetBlocks("proxyscan"))
|
||||
{
|
||||
const auto &block = config.GetBlock("proxyscan", i);
|
||||
ProxyCheck p;
|
||||
Anope::string token;
|
||||
|
||||
|
||||
+1
-3
@@ -173,10 +173,8 @@ public:
|
||||
{
|
||||
Rewrite::rewrites.clear();
|
||||
|
||||
for (int i = 0; i < conf.CountBlock("command"); ++i)
|
||||
for (const auto &[_, block] : conf.GetBlocks("command"))
|
||||
{
|
||||
const auto &block = conf.GetBlock("command", i);
|
||||
|
||||
if (!block.Get<bool>("rewrite"))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -12,11 +12,17 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
/// BEGIN CMAKE
|
||||
/// target_link_libraries(${SO} PRIVATE "vendored_yyjson")
|
||||
/// END CMAKE
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "module.h"
|
||||
#include "modules/rpc.h"
|
||||
#include "modules/httpd.h"
|
||||
|
||||
#include "yyjson/yyjson.c"
|
||||
#include "yyjson/yyjson.h"
|
||||
|
||||
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
@@ -313,10 +319,9 @@ public:
|
||||
throw ConfigException("Unable to find http reference, is httpd loaded?");
|
||||
|
||||
jsonrpcinterface.tokens.clear();
|
||||
for (int i = 0; i < modconf.CountBlock("token"); ++i)
|
||||
{
|
||||
const auto &block = modconf.GetBlock("token", i);
|
||||
|
||||
for (const auto &[_, block] : modconf.GetBlocks("token"))
|
||||
{
|
||||
RPC::Token token;
|
||||
token.token = block.Get<const Anope::string>("token");
|
||||
if (!token.token.empty())
|
||||
|
||||
@@ -25,7 +25,7 @@ if(HAVE_LOCALIZATION)
|
||||
)
|
||||
|
||||
# Install the new language file
|
||||
install(CODE "FILE(MAKE_DIRECTORY ${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES/)")
|
||||
install(DIRECTORY DESTINATION "${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES")
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG_MO} DESTINATION ${LOCALE_DIR}/${LANG_LANG}/LC_MESSAGES RENAME ${LANG_DOMAIN}.mo PERMISSIONS ${PERMS})
|
||||
endforeach()
|
||||
|
||||
|
||||
+1
-1
@@ -402,5 +402,5 @@ bool Command::FindFromService(const Anope::string &command_service, BotInfo *&bo
|
||||
}
|
||||
}
|
||||
|
||||
return name.empty();
|
||||
return !name.empty();
|
||||
}
|
||||
|
||||
+34
-47
@@ -38,28 +38,37 @@ const Anope::string &Configuration::Block::GetName() const
|
||||
return name;
|
||||
}
|
||||
|
||||
int Configuration::Block::CountBlock(const Anope::string &bname) const
|
||||
size_t Configuration::Block::CountBlock(const Anope::string &bname) const
|
||||
{
|
||||
return blocks.count(bname);
|
||||
}
|
||||
|
||||
const Configuration::Block &Configuration::Block::GetBlock(const Anope::string &bname, int num) const
|
||||
Configuration::Block::BlockList Configuration::Block::GetBlocks(const Anope::string &bname) const
|
||||
{
|
||||
std::pair<block_map::const_iterator, block_map::const_iterator> it = blocks.equal_range(bname);
|
||||
return Anope::equal_range(blocks, bname);
|
||||
}
|
||||
|
||||
for (int i = 0; it.first != it.second; ++it.first, ++i)
|
||||
const Configuration::Block &Configuration::Block::GetBlock(const Anope::string &bname, size_t num) const
|
||||
{
|
||||
auto it = blocks.equal_range(bname);
|
||||
|
||||
for (size_t i = 0; it.first != it.second; ++it.first, ++i)
|
||||
{
|
||||
if (i == num)
|
||||
return it.first->second;
|
||||
}
|
||||
return EmptyBlock;
|
||||
}
|
||||
|
||||
Configuration::Block *Configuration::Block::GetMutableBlock(const Anope::string &bname, int num)
|
||||
Configuration::Block *Configuration::Block::GetMutableBlock(const Anope::string &bname, size_t num)
|
||||
{
|
||||
std::pair<block_map::iterator, block_map::iterator> it = blocks.equal_range(bname);
|
||||
auto it = blocks.equal_range(bname);
|
||||
|
||||
for (int i = 0; it.first != it.second; ++it.first, ++i)
|
||||
for (size_t i = 0; it.first != it.second; ++it.first, ++i)
|
||||
{
|
||||
if (i == num)
|
||||
return &it.first->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -69,7 +78,7 @@ bool Configuration::Block::Set(const Anope::string &tag, const Anope::string &va
|
||||
return true;
|
||||
}
|
||||
|
||||
const Configuration::Block::item_map &Configuration::Block::GetItems() const
|
||||
const Configuration::Block::ItemMap &Configuration::Block::GetItems() const
|
||||
{
|
||||
return items;
|
||||
}
|
||||
@@ -125,10 +134,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
|
||||
this->LoadConf(ServicesConf);
|
||||
|
||||
for (int i = 0; i < this->CountBlock("include"); ++i)
|
||||
for (const auto &[_, include] : this->GetBlocks("include"))
|
||||
{
|
||||
const auto &include = this->GetBlock("include", i);
|
||||
|
||||
const Anope::string &type = include.Get<const Anope::string>("type"),
|
||||
&file = include.Get<const Anope::string>("name");
|
||||
|
||||
@@ -205,10 +212,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
this->TimeoutCheck = options.Get<time_t>("timeoutcheck");
|
||||
this->NickChars = networkinfo.Get<Anope::string>("nick_chars");
|
||||
|
||||
for (int i = 0; i < this->CountBlock("uplink"); ++i)
|
||||
for (const auto &[_, uplink] : this->GetBlocks("uplink"))
|
||||
{
|
||||
const auto &uplink = this->GetBlock("uplink", i);
|
||||
|
||||
int protocol;
|
||||
const Anope::string &protocolstr = uplink.Get<const Anope::string>("protocol", "ipv4");
|
||||
if (protocolstr == "ipv4")
|
||||
@@ -238,10 +243,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
this->Uplinks.emplace_back(host, port, password, protocol);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->CountBlock("module"); ++i)
|
||||
for (const auto &[_, module] : this->GetBlocks("module"))
|
||||
{
|
||||
const auto &module = this->GetBlock("module", i);
|
||||
|
||||
const Anope::string &modname = module.Get<const Anope::string>("name");
|
||||
|
||||
ValidateNotEmptyOrSpaces("module", "name", modname);
|
||||
@@ -249,10 +252,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
this->ModulesAutoLoad.push_back(modname);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->CountBlock("opertype"); ++i)
|
||||
for (const auto &[_, opertype] : this->GetBlocks("opertype"))
|
||||
{
|
||||
const auto &opertype = this->GetBlock("opertype", i);
|
||||
|
||||
const Anope::string &oname = opertype.Get<const Anope::string>("name"),
|
||||
&modes = opertype.Get<const Anope::string>("modes"),
|
||||
&inherits = opertype.Get<const Anope::string>("inherits"),
|
||||
@@ -292,10 +293,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
this->MyOperTypes.push_back(ot);
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->CountBlock("oper"); ++i)
|
||||
for (const auto &[_, oper] : this->GetBlocks("oper"))
|
||||
{
|
||||
const auto &oper = this->GetBlock("oper", i);
|
||||
|
||||
const Anope::string &nname = oper.Get<const Anope::string>("name"),
|
||||
&type = oper.Get<const Anope::string>("type"),
|
||||
&password = oper.Get<const Anope::string>("password"),
|
||||
@@ -330,10 +329,9 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
|
||||
for (const auto &[_, bi] : *BotListByNick)
|
||||
bi->conf = false;
|
||||
for (int i = 0; i < this->CountBlock("service"); ++i)
|
||||
{
|
||||
const auto &service = this->GetBlock("service", i);
|
||||
|
||||
for (const auto &[_, service] : this->GetBlocks("service"))
|
||||
{
|
||||
const Anope::string &nick = service.Get<const Anope::string>("nick"),
|
||||
&user = service.Get<const Anope::string>("user", nick.lower()),
|
||||
&host = service.Get<const Anope::string>("host", servername),
|
||||
@@ -421,10 +419,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->CountBlock("log"); ++i)
|
||||
for (const auto &[_, log] : this->GetBlocks("log"))
|
||||
{
|
||||
const auto &log = this->GetBlock("log", i);
|
||||
|
||||
int logage = log.Get<int>("logage");
|
||||
bool rawio = log.Get<bool>("rawio");
|
||||
bool debug = log.Get<bool>("debug");
|
||||
@@ -447,10 +443,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
|
||||
for (const auto &[_, bi] : *BotListByNick)
|
||||
bi->commands.clear();
|
||||
for (int i = 0; i < this->CountBlock("command"); ++i)
|
||||
for (const auto &[_, command] : this->GetBlocks("command"))
|
||||
{
|
||||
const auto &command = this->GetBlock("command", i);
|
||||
|
||||
const Anope::string &service = command.Get<const Anope::string>("service"),
|
||||
&nname = command.Get<const Anope::string>("name"),
|
||||
&cmd = command.Get<const Anope::string>("command"),
|
||||
@@ -472,10 +466,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
}
|
||||
|
||||
PrivilegeManager::ClearPrivileges();
|
||||
for (int i = 0; i < this->CountBlock("privilege"); ++i)
|
||||
for (const auto &[_, privilege] : this->GetBlocks("privilege"))
|
||||
{
|
||||
const auto &privilege = this->GetBlock("privilege", i);
|
||||
|
||||
const Anope::string &nname = privilege.Get<const Anope::string>("name"),
|
||||
&desc = privilege.Get<const Anope::string>("desc");
|
||||
int rank = privilege.Get<int>("rank");
|
||||
@@ -483,10 +475,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
PrivilegeManager::AddPrivilege(Privilege(nname, desc, rank));
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->CountBlock("fantasy"); ++i)
|
||||
for (const auto &[_, fantasy] : this->GetBlocks("fantasy"))
|
||||
{
|
||||
const auto &fantasy = this->GetBlock("fantasy", i);
|
||||
|
||||
const Anope::string &nname = fantasy.Get<const Anope::string>("name"),
|
||||
&service = fantasy.Get<const Anope::string>("command"),
|
||||
&permission = fantasy.Get<const Anope::string>("permission"),
|
||||
@@ -504,10 +494,8 @@ Configuration::Conf::Conf() : Configuration::Block("")
|
||||
c.require_privilege = fantasy.Get<bool>("require_privilege", "yes");
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->CountBlock("command_group"); ++i)
|
||||
for (const auto &[_, command_group] : this->GetBlocks("command_group"))
|
||||
{
|
||||
const auto &command_group = this->GetBlock("command_group", i);
|
||||
|
||||
const Anope::string &nname = command_group.Get<const Anope::string>("name"),
|
||||
&description = command_group.Get<const Anope::string>("description");
|
||||
|
||||
@@ -655,7 +643,7 @@ Configuration::Block &Configuration::Conf::GetModule(const Anope::string &mname)
|
||||
auto *&block = modules[mname];
|
||||
|
||||
/* Search for the block */
|
||||
for (std::pair<block_map::iterator, block_map::iterator> iters = blocks.equal_range("module"); iters.first != iters.second; ++iters.first)
|
||||
for (auto iters = blocks.equal_range("module"); iters.first != iters.second; ++iters.first)
|
||||
{
|
||||
auto &b = iters.first->second;
|
||||
|
||||
@@ -688,7 +676,7 @@ const Configuration::Block &Configuration::Conf::GetCommand(CommandSource &sourc
|
||||
{
|
||||
const Anope::string &block_name = source.c ? "fantasy" : "command";
|
||||
|
||||
for (std::pair<block_map::iterator, block_map::iterator> iters = blocks.equal_range(block_name); iters.first != iters.second; ++iters.first)
|
||||
for (auto iters = blocks.equal_range(block_name); iters.first != iters.second; ++iters.first)
|
||||
{
|
||||
auto &b = iters.first->second;
|
||||
|
||||
@@ -782,7 +770,7 @@ void Configuration::Conf::LoadConf(Configuration::File &file)
|
||||
|
||||
Anope::string itemname, wordbuffer;
|
||||
std::stack<Configuration::Block *> block_stack;
|
||||
int linenumber = 0;
|
||||
unsigned linenumber = 0;
|
||||
bool in_word = false, in_quote = false, in_comment = false;
|
||||
|
||||
Log(LOG_DEBUG) << "Start to read conf " << file.GetPath();
|
||||
@@ -984,7 +972,7 @@ void Configuration::Conf::LoadConf(Configuration::File &file)
|
||||
}
|
||||
}
|
||||
|
||||
Anope::string Configuration::Conf::ReplaceVars(const Anope::string &str, const Configuration::File &file, int linenumber)
|
||||
Anope::string Configuration::Conf::ReplaceVars(const Anope::string &str, const Configuration::File &file, unsigned linenumber)
|
||||
{
|
||||
Anope::string ret;
|
||||
for (auto it = str.begin(); it != str.end(); )
|
||||
@@ -1020,9 +1008,8 @@ Anope::string Configuration::Conf::ReplaceVars(const Anope::string &str, const C
|
||||
}
|
||||
|
||||
auto found = false;
|
||||
for (int i = 0; i < this->CountBlock("define"); ++i)
|
||||
for (const auto &[_, define] : this->GetBlocks("define"))
|
||||
{
|
||||
const auto &define = this->GetBlock("define", i);
|
||||
const auto defname = define.Get<const Anope::string>("name");
|
||||
if (defname == var)
|
||||
{
|
||||
|
||||
+2
-2
@@ -537,8 +537,8 @@ bool Anope::Init(int ac, char **av)
|
||||
|
||||
/* load modules */
|
||||
Log() << "Loading modules...";
|
||||
for (int i = 0; i < Config->CountBlock("module"); ++i)
|
||||
ModuleManager::LoadModule(Config->GetBlock("module", i).Get<const Anope::string>("name"), NULL);
|
||||
for (const auto &[_, block] : Config->GetBlocks("module"))
|
||||
ModuleManager::LoadModule(block.Get<const Anope::string>("name"), NULL);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* If we're root, issue a warning now */
|
||||
|
||||
+20
-2
@@ -952,9 +952,9 @@ Anope::string Anope::VersionShort()
|
||||
Anope::string Anope::VersionBuildString()
|
||||
{
|
||||
#if REPRODUCIBLE_BUILD
|
||||
Anope::string s = "build #" + Anope::ToString(BUILD);
|
||||
auto s = Anope::Format("build #%u", BUILD);
|
||||
#else
|
||||
Anope::string s = "build #" + Anope::ToString(BUILD) + ", compiled " + Anope::compiled;
|
||||
auto s = Anope::Format("build #%u, compiled %s", BUILD, BUILD_DATE);
|
||||
#endif
|
||||
Anope::string flags;
|
||||
|
||||
@@ -1178,6 +1178,24 @@ Anope::string Anope::FormatCTCP(const Anope::string &name, const Anope::string &
|
||||
return Anope::Format("\1%s %s\1", name.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
Anope::string Anope::FormatISO8601(time_t ts, unsigned long long ms)
|
||||
{
|
||||
static time_t last_ts = -1;
|
||||
static unsigned long long last_ms = -1;
|
||||
static Anope::string timestamp;
|
||||
if (ts != last_ts || ms != last_ms)
|
||||
{
|
||||
last_ts = ts;
|
||||
last_ms = ms;
|
||||
char timebuf[32];
|
||||
const auto *tm = gmtime(&ts);
|
||||
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", tm);
|
||||
timestamp = Anope::Format("%s.%03lldZ", timebuf, ms);
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
bool Anope::ParseCTCP(const Anope::string &text, Anope::string &name, Anope::string &body)
|
||||
{
|
||||
// According to draft-oakley-irc-ctcp-02 a valid CTCP must begin with SOH and
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user