1
0
mirror of https://github.com/anope/anope.git synced 2026-06-15 21:14:46 +02:00

Compare commits

..

138 Commits

Author SHA1 Message Date
Sadie Powell ab0b851d28 Release 2.1.8. 2024-09-01 09:46:17 +01:00
Sadie Powell 4e3720b810 Merge branch '2.0' into 2.1. 2024-09-01 09:43:38 +01:00
TehPeGaSuS 4b48fc98d3 Fix the documentation of mail:usemail.
`nickserv:registration` only has as options: none, admin, mail.

I assume that `mail` is the word that should replace `yes`
2024-09-01 09:41:32 +01:00
Sadie Powell 82993c8d1e Update the changelogs. 2024-08-30 14:49:43 +01:00
Sadie Powell d352718a39 Fix parsing named extbans on InspIRCd. 2024-08-30 14:49:39 +01:00
Sadie Powell d44632e57d Use CMake's -B option instead of cding to the build directory. 2024-08-30 14:48:31 +01:00
Sadie Powell 80451011dd Remove pointless semicolons in the config for the webcpanel module. 2024-08-29 13:40:39 +01:00
Sadie Powell b4e673b2f4 Refactor ns_getemail slightly. 2024-08-29 13:21:18 +01:00
Sadie Powell 58a78e9aa5 Allow server admins to require that a display nick drops last.
Closes #348.
2024-08-29 13:14:39 +01:00
Sadie Powell 6da4a148fa Fix translating mail:memo_message. 2024-08-24 12:27:05 +01:00
Sadie Powell a3edb09eda Use CanClearBans/SendClearBans when enforcing smartjoin. 2024-08-22 00:29:30 +01:00
Sadie Powell 27beb8f877 Improve the CTCP version output. 2024-08-21 15:38:35 +01:00
Sadie Powell 136680f917 Fix the grammar of some info messages. 2024-08-18 03:17:33 +01:00
Sadie Powell 378ae21ac7 Add account identifier to nickserv/info output. 2024-08-18 01:19:39 +01:00
Sadie Powell e35a86661d Remove support for MinGW.
All of our builds are fully native on Windows so there's no need
for this anymore.
2024-08-15 12:14:06 +01:00
Sadie Powell 528b5938ec Automatically determine SQL column type from the field.
Also add more column types to ensure we are storing data in the
best format in the database.
2024-08-14 05:47:55 +01:00
Sadie Powell 03bee17063 Remove the unused KeySet method in Serialize::Data. 2024-08-14 00:10:12 +01:00
Sadie Powell fe18050c49 Fix parsing SVSMODE and SVS2MODE messages on UnrealIRCd.
At some point UnrealIRCd made an undocumented change to the protocol
where the last parameter on a server-source message would not be a
timestamp. This behaviour is preserved for MODE.
2024-08-09 20:39:46 +01:00
Wilson Birney aa0496f69b Add <cstring> include to services.h to fix build on some musl systems.
Co-authored-by: blackbeard420 <blackbeard@blackbeard420.me>
2024-08-06 11:00:47 +01:00
Sadie Powell 4ee22ab05e Merge branch '2.0' into 2.1. 2024-07-28 22:50:30 +01:00
Sadie Powell 63ad540e55 Add a note to LANGUAGE about rebuilding from scratch. 2024-07-20 19:25:58 +01:00
Sadie Powell a1165eea94 Fix the type of the InspIRCd IJOIN chants when converting. 2024-07-20 19:25:58 +01:00
Sadie Powell bfca74f6b3 Bump for 2.0.17-git. 2024-07-19 13:24:41 +01:00
Sadie Powell 3acf74483c Release 2.0.16. 2024-07-19 12:49:56 +01:00
Sadie Powell a3ec8329f4 Document the previous commit. 2024-07-19 12:48:44 +01:00
Sadie Powell 7d0184ca34 Merge branch '2.0' into 2.1. 2024-07-19 01:43:41 +01:00
Sadie Powell 31bc597c81 Send the vhost/vident before the account name on InspIRCd.
This fixes IRCd-side account cloaks causing CHGHOST spam.
2024-07-19 01:11:32 +01:00
Sadie Powell e0b687f289 Merge branch '2.0' into 2.1. 2024-07-14 16:42:26 +01:00
Sadie Powell 2de0dddb1c Fix joining channels with keys on InspIRCd v3. 2024-07-14 16:39:37 +01:00
Sadie Powell ff65b68dfa Fix the name of the key parameter in SendSVSJoin. 2024-07-14 15:21:00 +01:00
Sadie Powell 94456a6063 Fix sending global messages to remotely linked servers. 2024-07-14 11:44:22 +01:00
Sadie Powell 41ea346551 Update the change log. 2024-07-11 01:13:59 +01:00
Sadie Powell 439ad3e736 Make it clear that inspircd3 also works with InspIRCd 4. 2024-07-11 01:13:59 +01:00
Sadie Powell 347d82f59b Qualify a use of auto in db_atheme. 2024-07-08 00:53:47 +01:00
Sadie Powell fe68f40634 Remove some obsolete echo compatibility wrappers. 2024-07-08 00:53:47 +01:00
ItsOnlyBinary 08b1344056 Add UNIX socket support to mysql module.
Ref: #419
2024-07-04 13:13:56 +01:00
Sadie Powell ff67a80a71 Bump for 2.1.8-git. 2024-07-01 10:08:16 +01:00
Sadie Powell 230e85798d Release 2.1.7. 2024-07-01 10:06:17 +01:00
Sadie Powell 9604690e9d Update the change logs. 2024-06-29 16:25:17 +01:00
Sadie Powell 01e0cf4868 Add support for sending tag messages. 2024-06-24 14:46:41 +01:00
Sadie Powell 693eeed762 Rework how CTCP messages are sent and received. 2024-06-24 14:29:55 +01:00
Sadie Powell 6e5713d64a Remove the formatting overloads of SendNotice/SendPrivmsg. 2024-06-24 13:30:17 +01:00
Sadie Powell 249ad3dfea Update the Turkish translation.
Co-authored-by: CaPa CuL <capacul@gmail.com>
2024-06-23 18:36:00 +01:00
Sadie Powell b94c3740b9 Make the language around fantasy commands less weird. 2024-06-23 14:36:03 +01:00
Sadie Powell 59ec42f0e6 Rename suspend in cs_expire to suspendexpire to match ns_expire. 2024-06-23 13:55:25 +01:00
Sadie Powell 8a65f116b6 Merge branch '2.0' into 2.1. 2024-06-23 13:52:46 +01:00
Sadie Powell 8105607257 Fix the default config for channel suspensions. 2024-06-23 13:51:53 +01:00
Sadie Powell 601da1141e Fix the default config for channel suspensions. 2024-06-23 13:50:50 +01:00
Sadie Powell 8c0edef714 Split nickserv/{sa,}set/language out to its own module. 2024-06-22 17:46:42 +01:00
Sadie Powell c3efd9426d Update the change log. 2024-06-20 17:16:16 +01:00
Sadie Powell a386439f86 Misc improvements to db_atheme. 2024-06-20 17:16:16 +01:00
Sadie Powell 016a5b3903 Fix importing Atheme mode locks. 2024-06-20 17:16:16 +01:00
Sadie Powell 60aeb2a71a Silently ignore some Atheme metadata that we know we can't import. 2024-06-19 22:45:43 +01:00
Sadie Powell 54ea63df66 Avoid creating extra service references in db_atheme. 2024-06-19 22:44:31 +01:00
Sadie Powell 01fc3ea22e Fix importing Atheme opers. 2024-06-19 22:44:31 +01:00
Sadie Powell 3388736fab Use auto in more places in db_atheme. 2024-06-19 22:44:31 +01:00
Sadie Powell 0065a0f405 Only import clones from Atheme if we recognise the database version. 2024-06-19 22:44:16 +01:00
Sadie Powell 490f832dc0 Fix importing Atheme session limits. 2024-06-19 21:12:28 +01:00
Sadie Powell a44acb6de5 Fix importing Atheme forbid reasons. 2024-06-19 20:31:55 +01:00
Sadie Powell 13e5ddf807 Fix importing Atheme akick reasons. 2024-06-19 20:22:57 +01:00
Sadie Powell e42c728ab8 Log the channel that a mode lock was unable to be imported for. 2024-06-19 19:41:16 +01:00
Sadie Powell 4eec5c5435 Save the databases directly after importing. 2024-06-19 19:30:24 +01:00
Sadie Powell 2667d9e90c Update the databases more regularly. 2024-06-19 11:28:21 +01:00
Sadie Powell f2b66278aa Fix a string that should be marked as translatable in ns_info. 2024-06-12 17:53:15 +01:00
Sadie Powell 5b7d952626 Remove the broken Catalan, Hungarian, and Russian translations. 2024-06-12 17:50:00 +01:00
Sadie Powell 24375d53e6 Add support for looking up account information from a nick.
Closes #407.
2024-06-12 17:46:07 +01:00
Sadie Powell 88ac47e217 The sender can be null in OnBotUnAssign. 2024-06-10 12:51:56 +01:00
Sadie Powell 8a1bffba9b Fix a crash in ns_cert. 2024-06-10 11:16:05 +01:00
TehPeGaSuS 01eef7a392 Rename example.chk to cron.example.sh. 2024-06-07 23:23:44 +01:00
Sadie Powell 67b76fadca Fix a memory leak in os_akill and os_sxline. 2024-06-07 22:39:08 +01:00
Sadie Powell 7861712437 Add nullability attributes to the module events. 2024-06-07 22:15:58 +01:00
Sadie Powell ccc088d946 Log a user out fully when their nick gets suspended.
Closes #409.
2024-06-04 22:41:32 +01:00
Sadie Powell 4468fe77fa Fix an inverted if in the global odule. 2024-06-03 20:02:03 +01:00
Sadie Powell e71a9e2894 Avoid NickAlias lookups by storing a pointer in the NickCore. 2024-06-03 16:04:53 +01:00
Sadie Powell f80bdf06ba Fix a null pointer dereference in the sasl module. 2024-06-03 14:39:08 +01:00
Sadie Powell 2d6033c73f Bump for 2.1.7-git. 2024-06-01 09:44:43 +01:00
Sadie Powell 756dc49813 Release 2.1.6. 2024-06-01 09:43:36 +01:00
Sadie Powell aa92559aa0 Document the previous commit. 2024-06-01 09:43:20 +01:00
Sadie Powell eb12a89b8e Fix creating the runtime directory on Windows. 2024-05-28 01:07:27 +01:00
Sadie Powell d4a34308e5 Update the change logs. 2024-05-23 16:02:54 +01:00
Sadie Powell aab3a8e5b6 Clarify that one non-deprecated protocol module must be loaded. 2024-05-23 15:40:56 +01:00
Sadie Powell c72e12d0a6 Fix setting the history mode on UnrealIRCd.
Closes #406.
2024-05-22 15:08:13 +01:00
Sadie Powell bce0d629fd Fix another iterator invalidation issue. 2024-05-22 14:30:18 +01:00
Sadie Powell 7d0dacc86c Change --modulesdir to be singular like the other config options. 2024-05-22 10:30:03 +01:00
Sadie Powell 729aa4ab4a Fix parsing the flood mode on UnrealIRCd. 2024-05-18 18:36:17 +01:00
Sadie Powell 18e9e12261 Fix an iterator invalidation issue in cs_set and ns_set. 2024-05-18 16:35:35 +01:00
TehPeGaSuS 9d68b29c9e Initial Portuguese retranslation. 2024-05-17 17:24:24 +01:00
Sadie Powell a4792412ba Merge branch '2.0' into 2.1. 2024-05-16 18:00:13 +01:00
Sadie Powell 8bb83f6b1a Explicitly specify ROW_FORMAT=DYNAMIC when creating tables.
Resolves the issues some people were having with extremely wide rows.
2024-05-16 17:29:25 +01:00
Sadie Powell da99a53dfa Don't specify a width for DT_INT columns.
This isn't actually used by MySQL for the column width.
2024-05-16 17:28:15 +01:00
Sadie Powell a9e9ac32a0 Store boolean extension items as DT_INT. 2024-05-16 17:28:15 +01:00
Sadie Powell 05e6df23a2 Mark boolean columns as DT_INT in bs_kick. 2024-05-16 16:50:41 +01:00
Sadie Powell 3f9fc23270 Remove some unnecessary advice. 2024-05-16 16:44:38 +01:00
Sadie Powell cb21c7c1fa Fix some untranslated strings in the Turkish translation. 2024-05-11 18:35:17 +01:00
Sadie Powell 4008e64f26 Store when the account name was registered in the NickCore. 2024-05-11 17:40:38 +01:00
Sadie Powell 1cf5918574 Merge branch '2.0' into 2.1. 2024-05-11 14:24:37 +01:00
Sadie Powell afe87bf693 Ensure we are connected to MySQL before trying to escape data. 2024-05-11 11:36:29 +01:00
Sadie Powell ff1c5adb8b Always use server-side topic and mode locks where available. 2024-05-10 19:03:50 +01:00
Sadie Powell c36030c826 Remove CanSVSLogout and implement logout support on Plexus. 2024-05-09 18:54:40 +01:00
Sadie Powell 33a02b1223 Require a reason when throwing an exception. 2024-05-09 18:37:16 +01:00
Sadie Powell 68f4556609 Store an IP in CommandSource for IRC messages too. 2024-05-06 17:08:37 +01:00
Sadie Powell 23db58a303 Change badpasslimit from int to unsigned int. 2024-05-06 16:42:13 +01:00
Sadie Powell ee69dc3105 Fix parsing backup client certificate fingerprints on InspIRCd. 2024-05-01 21:21:19 +01:00
Sadie Powell e9243c3fde Add the ReplaceCert method to CertService. 2024-05-01 21:20:31 +01:00
Sadie Powell 4cfee23303 Simplify InspIRCd user metadata handler slightly. 2024-05-01 20:20:47 +01:00
Sadie Powell be3822523b Automatically add client certificates to the cert list on register. 2024-05-01 17:23:10 +01:00
dependabot[bot] 111f81aa95 Bump microsoft/setup-msbuild from 1.3 to 2
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.3 to 2.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Changelog](https://github.com/microsoft/setup-msbuild/blob/main/building-release.md)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.3...v2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-01 17:20:06 +01:00
Sadie Powell f12e1ad222 Bump for 2.1.6-git. 2024-05-01 14:37:06 +01:00
Sadie Powell 72318a6bf0 Release 2.1.5. 2024-05-01 14:16:09 +01:00
Sadie Powell 2f77cb38e2 Update the changelogs. 2024-05-01 14:15:17 +01:00
Sadie Powell 84ca4c0d27 Update the inspircd module for recent 1206 protocol changes. 2024-05-01 14:03:11 +01:00
Sadie Powell 1f9a197b18 Merge branch '2.0' into 2.1. 2024-04-29 08:36:23 +01:00
Sadie Powell 0c5bf51378 Skip serializing data without a type in db_flatfile. 2024-04-29 08:16:45 +01:00
Sadie Powell 1647968c50 Fix message truncation in global/global and global/server. 2024-04-28 08:52:16 +01:00
Sadie Powell 5473311bd7 Only enable os_noop on IRCDs that actually have a SendSVSNOOP impl. 2024-04-15 21:08:40 +01:00
Sadie Powell f3ebb67469 Make SendChannel abstract. 2024-04-15 21:00:10 +01:00
Sadie Powell 0d149ce195 Install a systemd service file on Linux. 2024-04-15 20:29:57 +01:00
Sadie Powell d68ba1b570 Implement support for BIGLINES on UnrealIRCd. 2024-04-15 20:05:43 +01:00
Sadie Powell 1877833e73 Bump Bahamut support to require 2.0 or newer. 2024-04-15 18:29:36 +01:00
Sadie Powell 63c3710785 Fix some missing translations in the tr_TR translation. 2024-04-15 15:32:19 +01:00
Sadie Powell 0043d137e5 Update the Turkish translation for the changes in 2.1.4.
Co-authored-by: CaPa CuL <capacul@gmail.com>
2024-04-15 15:26:55 +01:00
Sadie Powell 3e5d3c5bdc Avoid packaging unnecessary .lib files on Windows.
[skip alpine ci]
[skip ubuntu ci]
2024-04-15 12:41:56 +01:00
Sadie Powell 62deedfa75 Automatically upload the Windows package on release.
[skip alpine ci]
[skip ubuntu ci]
2024-04-15 11:57:40 +01:00
Sadie Powell 44af4eac6b Update the Windows CI to the latest Conan. 2024-04-15 11:11:40 +01:00
Sadie Powell 5fdc637327 Expand relative paths when installing. 2024-04-14 12:23:19 +01:00
Sadie Powell 7c93007aa6 Avoid duplicate entries in ReplaceCert. 2024-04-14 12:23:19 +01:00
Robert Scheck e8fee93a7e Fix a typo in the example configs. 2024-04-14 09:21:50 +01:00
Sadie Powell 260539e987 Add more documentation for overriding confirmation codes. 2024-04-07 15:52:24 +01:00
Sadie Powell 4603cd467b Add an operator privilege to allow overriding drop codes.
Closes #392
2024-04-05 14:14:10 +01:00
Sadie Powell 00549bc9b2 Merge branch '2.0' into 2.1. 2024-04-04 19:59:19 +01:00
Sadie Powell e0a6f7456b Fix extracting timestamps from UnrealIRCd MODE messages.
Oversight from commit 04e1a4f5c8.
2024-04-04 19:48:34 +01:00
Sadie Powell 5a54b37aeb Remove the g prefix from git hashes. 2024-04-04 14:16:21 +01:00
Sadie Powell 2e43665266 Log the services directory when chdiring to it. 2024-04-04 14:02:57 +01:00
Sadie Powell 8b4cd65e2a Fix erroring out when sendmailpath is empty.
This has a default now.
2024-04-02 16:52:41 +01:00
Sadie Powell c08aaa86d1 Sync the build system directory names with the core. 2024-04-02 16:52:41 +01:00
Sadie Powell 87a8af0ad7 Use the paths from the build system instead of hardcoding them. 2024-04-02 16:45:49 +01:00
Sadie Powell 4691dfa3f0 Bump for 2.1.5-git. 2024-04-01 11:26:07 +01:00
Sadie Powell d41764bfd6 Fix sending emails to nicks ending with a backslash. 2024-03-15 18:52:12 +00:00
122 changed files with 4324 additions and 36342 deletions
+15 -4
View File
@@ -2,6 +2,9 @@ name: Windows CI
on:
pull_request:
push:
release:
types:
- published
schedule:
- cron: '0 0 * * 0'
jobs:
@@ -12,12 +15,12 @@ jobs:
- uses: actions/checkout@v4
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1.3
uses: microsoft/setup-msbuild@v2
- name: Setup Conan
uses: turtlebrowser/get-conan@v1.2
with:
version: 1.59.0
version: 1.64.0
- name: Install libraries
run: |
@@ -27,9 +30,17 @@ jobs:
run: |
mkdir ${{ github.workspace }}\build
cd ${{ github.workspace }}\build
cmake -A "x64" -G "Visual Studio 16 2019" ..
cmake -A "x64" -D "CMAKE_BUILD_TYPE=${{ github.event_name == 'release' && 'Release' || 'Debug' }}" -G "Visual Studio 16 2019" ..
- name: Build Anope
working-directory: ${{ github.workspace }}\build
run: |
msbuild PACKAGE.vcxproj /M:3 /P:Configuration=Release /P:Platform=x64 /VERBOSITY:MINIMAL
msbuild PACKAGE.vcxproj /M:3 /P:Configuration=${{ github.event_name == 'release' && 'Release' || 'Debug' }} /P:Platform=x64 /VERBOSITY:MINIMAL
- name: Upload installer
if: "${{ github.event_name == 'release' }}"
working-directory: ${{ github.workspace }}\build
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload ${{ github.event.release.tag_name }} $(Get-ChildItem anope-*.exe)
+17 -30
View File
@@ -31,12 +31,8 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$")
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-search-dirs OUTPUT_VARIABLE LINES OUTPUT_STRIP_TRAILING_WHITESPACE)
# Find only the part after "libraries: "
string(REGEX REPLACE ".*\nlibraries: (.*)$" "\\1" LINE "${LINES}")
# Replace the colons in the list with semicolons (only when not on MinGW, which uses semicolons already), and if on MinGW, just copy the line
if(NOT MINGW)
string(REGEX REPLACE ":" ";" LIBRARIES ${LINE})
else()
set(LIBRARIES "${LINE}")
endif()
# Replace the colons in the list with semicolons
string(REGEX REPLACE ":" ";" LIBRARIES ${LINE})
# Iterate through the libraries
foreach(LIBRARY ${LIBRARIES})
# Check if the first character is an equal sign, and skip that library directory as it is (I believe) the primary default and shows up later in the list anyways
@@ -106,13 +102,6 @@ if(NOT MSVC)
endif()
endif()
# If running under MinGW, we have to force the resource compiler settings (hopefully this will be fixed in a later version of CMake)
if(MINGW)
set(CMAKE_RC_COMPILER_INIT windres)
enable_language(RC)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>")
endif()
# Include the checking functions used later in this CMakeLists.txt
include(CheckFunctionExists)
include(CheckTypeSize)
@@ -189,11 +178,6 @@ if(CMAKE_THREAD_LIBS_INIT)
list(APPEND LINK_LIBS ${CMAKE_THREAD_LIBS_INIT})
endif()
# Under MinGW, the -shared flag isn't properly set in the module-specific linker flags, add it from the C flags for shared libraries
if(MINGW)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}")
endif()
if(NOT PROGRAM_NAME)
set(PROGRAM_NAME anope)
endif()
@@ -256,8 +240,8 @@ endif()
if(NOT BIN_DIR)
set(BIN_DIR "bin")
endif()
if(NOT DB_DIR)
set(DB_DIR "data")
if(NOT DATA_DIR)
set(DATA_DIR "data")
endif()
if(NOT DOC_DIR)
set(DOC_DIR "doc")
@@ -265,14 +249,14 @@ endif()
if(NOT CONF_DIR)
set(CONF_DIR "conf")
endif()
if(NOT LIB_DIR)
set(LIB_DIR "lib")
if(NOT MODULE_DIR)
set(MODULE_DIR "modules")
endif()
if(NOT LOCALE_DIR)
set(LOCALE_DIR "locale")
endif()
if(NOT LOGS_DIR)
set(LOGS_DIR "logs")
if(NOT LOG_DIR)
set(LOG_DIR "logs")
endif()
# Version number processing
@@ -350,15 +334,17 @@ set(SERVICES_BINARY "$<TARGET_FILE:${PROGRAM_NAME}>")
get_filename_component(SERVICES_BINARY ${SERVICES_BINARY} NAME)
# At install time, create the following additional directories
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${DB_DIR}/backups\")")
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${LOGS_DIR}\")")
get_filename_component(ABSOLUTE_DATA_DIR ${DATA_DIR} REALPATH BASE_DIR ${CMAKE_INSTALL_PREFIX})
get_filename_component(ABSOLUTE_LOG_DIR ${LOG_DIR} REALPATH BASE_DIR ${CMAKE_INSTALL_PREFIX})
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ABSOLUTE_DATA_DIR}/backups\")")
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ABSOLUTE_LOG_DIR}\")")
if(WIN32)
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${DB_DIR}/runtime\")")
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${ABSOLUTE_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)
install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DB_DIR}/backups\")")
install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${LOGS_DIR}\")")
install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}${ABSOLUTE_DATA_DIR}/backups\")")
install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}${ABSOLUTE_LOG_DIR}\")")
install(CODE "execute_process(COMMAND ${CHGRP} -R ${RUNGROUP} \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}\")")
endif()
# On Windows platforms, install extra files
@@ -368,7 +354,8 @@ if(WIN32)
)
endif()
install(CODE "file(REMOVE_RECURSE \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/modules\")")
get_filename_component(ABSOLUTE_MODULE_DIR ${MODULE_DIR} REALPATH BASE_DIR ${CMAKE_INSTALL_PREFIX})
install(CODE "file(REMOVE_RECURSE \"$ENV{DESTDIR}${ABSOLUTE_MODULE_DIR}\")")
# Only process the CPack section if we have CPack
if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
+18 -43
View File
@@ -13,10 +13,6 @@
#
###########################################################################
echo2 () {
$ECHO2 "$*$ECHO2SUF" # these are defined later
}
exists () { # because some shells don't have test -e
if [ -f $1 -o -d $1 -o -p $1 -o -c $1 -o -b $1 ] ; then
return 0
@@ -42,7 +38,6 @@ Run_Build_System () {
WITH_PERM=""
EXTRA_INCLUDE=""
EXTRA_LIBS=""
GEN_TYPE=""
if [ "$INSTDIR" != "" ] ; then
WITH_INST="-DINSTDIR:STRING=$INSTDIR"
@@ -70,45 +65,25 @@ Run_Build_System () {
EXTRA_LIBS="-DEXTRA_LIBS:STRING=$EXTRA_LIB_DIRS"
fi
if [ "$SOURCE_DIR" = "." ] ; then
pwdsave=`pwd`
test -d build || mkdir build
cd "build"
REAL_SOURCE_DIR=".."
else
REAL_SOURCE_DIR="$SOURCE_DIR"
fi
BUILD_PATHS="-B ${SOURCE_DIR}/build ${SOURCE_DIR}"
echo "cmake $GEN_TYPE $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $REAL_SOURCE_DIR"
CMAKE="cmake $GEN_TYPE $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $BUILD_PATHS"
echo $CMAKE
$CMAKE
cmake $GEN_TYPE $WITH_INST $WITH_RUN $WITH_PERM $BUILD_TYPE $EXTRA_INCLUDE $EXTRA_LIBS $EXTRA_CONFIG_ARGS $REAL_SOURCE_DIR
if [ $? -ne 0 ]; then
echo "You should fix these issues and then run ./Config -quick to rerun CMake."
exit 1
fi
echo ""
if [ "$SOURCE_DIR" = "." ] ; then
echo "Now cd build, then run make to build Anope."
cd "$pwdsave"
else
if [ "$PWD" = "${SOURCE_DIR}/build" ]; then
echo "Now run make to build Anope."
else
echo "Now cd build, then run make to build Anope."
fi
}
ECHO2SUF=''
if [ "`echo -n a ; echo -n b`" = "ab" ] ; then
ECHO2='echo -n'
elif [ "`echo 'a\c' ; echo 'b\c'`" = "ab" ] ; then
ECHO2='echo' ; ECHO2SUF='\c'
elif [ "`printf 'a' 2>&1 ; printf 'b' 2>&1`" = "ab" ] ; then
ECHO2='printf "%s"'
else
# oh well...
ECHO2='echo'
fi
export ECHO2 ECHO2SUF
###########################################################################
# Init values
###########################################################################
@@ -121,7 +96,7 @@ EXTRA_INCLUDE_DIRS=
EXTRA_LIB_DIRS=
EXTRA_CONFIG_ARGS=
CAN_QUICK="no"
SOURCE_DIR=`dirname $0`
SOURCE_DIR="$(cd "$(dirname "$0")" && pwd)"
###########################################################################
# Check out the options
@@ -138,7 +113,7 @@ while [ $# -ge 1 ] ; do
exit 0
elif [ $1 = "-devel" ] ; then
DEBUG="yes"
INSTDIR="$PWD/run"
INSTDIR="$SOURCE_DIR/run"
elif [ $1 = "-nocache" ] ; then
IGNORE_CACHE="1"
elif [ $1 = "-nointro" ] ; then
@@ -199,7 +174,7 @@ export ok INPUT
ok=0
echo "In what directory should Anope be installed?"
while [ $ok -eq 0 ] ; do
echo2 "[$INSTDIR] "
echo -n "[$INSTDIR] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ ! "$INPUT" ] ; then
INPUT=$INSTDIR
@@ -209,7 +184,7 @@ while [ $ok -eq 0 ] ; do
echo "$INPUT exists, but is not a directory!"
else
echo "$INPUT does not exist. Create it?"
echo2 "[y] "
echo -n "[y] "
read YN
if [ "$YN" != "n" ] ; then
if mkdir -p $INPUT ; then
@@ -238,7 +213,7 @@ else
echo "should not force files to be owned by a particular group, just press"
echo "Return.)"
fi
echo2 "[$RUNGROUP] "
echo -n "[$RUNGROUP] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ "$INPUT" ] ; then
if [ "$INPUT" = "none" ] ; then
@@ -263,7 +238,7 @@ ok=0
echo "What should the default umask for data files be (in octal)?"
echo "(077 = only accessible by owner; 007 = accessible by owner and group)"
while [ $ok -eq 0 ] ; do
echo2 "[$UMASK] "
echo -n "[$UMASK] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ ! "$INPUT" ] ; then
INPUT=$UMASK
@@ -287,7 +262,7 @@ if [ "$DEBUG" = "yes" ] ; then
TEMP_YN="y"
fi
echo "Would you like to build a debug version of Anope?"
echo2 "[$TEMP_YN] "
echo -n "[$TEMP_YN] "
read YN
if [ "$YN" ] ; then
if [ "$YN" = "y" ] ; then
@@ -305,7 +280,7 @@ echo "You may only need to do this if CMake is unable to locate"
echo "missing dependencies without hints."
echo "Separate directories with semicolons."
echo "If you need no extra include directories, enter NONE in all caps."
echo2 "[$EXTRA_INCLUDE_DIRS] "
echo -n "[$EXTRA_INCLUDE_DIRS] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ "$INPUT" ] ; then
if [ "$INPUT" = "NONE" ] ; then
@@ -323,7 +298,7 @@ echo "You may only need to do this if CMake is unable to locate"
echo "missing dependencies without hints."
echo "Separate directories with semicolons."
echo "If you need no extra library directories, enter NONE in all caps."
echo2 "[$EXTRA_LIB_DIRS] "
echo -n "[$EXTRA_LIB_DIRS] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ "$INPUT" ] ; then
if [ "$INPUT" = "NONE" ] ; then
@@ -338,7 +313,7 @@ echo ""
echo "Are there any extra arguments you wish to pass to CMake?"
echo "If you need no extra arguments to CMake, enter NONE in all caps."
echo2 "[$EXTRA_CONFIG_ARGS] "
echo -n "[$EXTRA_CONFIG_ARGS] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ "$INPUT" ] ; then
if [ "$INPUT" = "NONE" ] ; then
@@ -355,7 +330,7 @@ echo ""
# Store values
################################################################################
echo2 "Saving configuration results in config.cache... "
echo -n "Saving configuration results in config.cache... "
cat <<EOT >$SOURCE_DIR/config.cache
INSTDIR="$INSTDIR"
+1 -1
View File
@@ -1,6 +1,6 @@
# Only install example.chk and anope.example.conf from this directory
# NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file)
set(DATA example.chk anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf irc2sql.example.conf stats.standalone.example.conf)
set(DATA cron.example.sh anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf irc2sql.example.conf stats.standalone.example.conf)
install(FILES ${DATA}
DESTINATION ${CONF_DIR}
)
+9 -30
View File
@@ -265,26 +265,7 @@ serverinfo
* - solanum
* - unrealircd
*/
module
{
name = "inspircd"
/*
* Some protocol modules can enforce mode locks server-side. This reduces the spam caused by
* services immediately reversing mode changes for locked modes.
*
* If the protocol module you have loaded does not support this, this setting will have no effect.
*/
use_server_side_mlock = yes
/*
* Some protocol modules can enforce topic locks server-side. This reduces the spam caused by
* services immediately reversing topic changes.
*
* If the protocol module you have loaded does not support this, this setting will have no effect.
*/
use_server_side_topiclock = yes
}
module { name = "inspircd" }
/*
* [REQUIRED] Network Information
@@ -421,7 +402,7 @@ options
/*
* Sets the delay between automatic database updates.
*/
updatetimeout = 5m
updatetimeout = 2m
/*
* Sets the delay between checks for expired nicknames and channels.
@@ -530,7 +511,7 @@ options
*
* Removing .UTF-8 will instead use the default encoding for the language, e.g. iso-8859-1 for western European languages.
*/
languages = "ca_ES.UTF-8 de_DE.UTF-8 el_GR.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 hu_HU.UTF-8 it_IT.UTF-8 nl_NL.UTF-8 pl_PL.UTF-8 pt_PT.UTF-8 ru_RU.UTF-8 tr_TR.UTF-8"
languages = "de_DE.UTF-8 el_GR.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 it_IT.UTF-8 nl_NL.UTF-8 pl_PL.UTF-8 pt_PT.UTF-8 tr_TR.UTF-8"
/*
* Default language that non- and newly-registered nicks will receive messages in.
@@ -749,13 +730,14 @@ log
*
* Available privileges:
* botserv/administration - Can view and assign private BotServ bots
* botserv/fantasy - Can use fantasy commands without the FANTASIA privilege
* botserv/fantasy - Can use fantasy commands without the FANTASY privilege
* chanserv/administration - Can modify the settings of any channel (including changing of the owner!)
* chanserv/access/list - Can view channel access and akick lists, but not modify them
* chanserv/access/modify - Can modify channel access and akick lists, and use /chanserv enforce
* chanserv/auspex - Can see any information with /CHANSERV INFO
* chanserv/no-register-limit - May register an unlimited number of channels and nicknames
* chanserv/kick - Can kick and ban users from channels through ChanServ
* chanserv/drop/override - Allows dropping channels without using a confirmation code
* memoserv/info - Can see any information with /MEMOSERV INFO
* memoserv/set-limit - Can set the limit of max stored memos on any user and channel
* memoserv/no-limit - Can send memos through limits and throttles
@@ -764,6 +746,8 @@ log
* nickserv/cert - Can modify other users certificate lists
* nickserv/confirm - Can confirm other users nicknames
* nickserv/drop - Can drop other users nicks
* nickserv/drop/display - Allows dropping display nicks when preservedisplay is enabled
* nickserv/drop/override - Allows dropping nicks without using a confirmation code
* nickserv/recover - Can recover other users nicks
* operserv/config - Can modify services's configuration
* operserv/oper/modify - Can add and remove operators with at most the same privileges
@@ -932,7 +916,7 @@ mail
* If set, this option enables the mail commands in Anope. You may choose
* to disable it if you have no Sendmail-compatible mailer installed. Whilst
* this directive (and entire block) is optional, it is required if
* nickserv:registration is set to yes.
* nickserv:registration is set to mail.
*/
usemail = yes
@@ -1151,11 +1135,6 @@ module
* This is only useful with very large databases, with hundreds
* of thousands of objects, that have a noticeable delay from
* writing databases.
*
* If your database is large enough cause a noticeable delay when
* saving you should consider a more powerful alternative such
* as db_sql or db_redis, which incrementally update their
* databases asynchronously in real time.
*/
fork = no
}
@@ -1311,7 +1290,7 @@ module
* [EXTRA] enc_posix
*
* Provides verify-only support for passwords encrypted using the POSIX crypt()
* function. Load this if you are migratign from another services packages such
* function. Load this if you are migrating from another services packages such
* as Atheme. See https://en.wikipedia.org/wiki/Crypt_(C) for more information.
*
* You must load another encryption method before this to re-encrypt passwords
+5 -6
View File
@@ -107,10 +107,9 @@ module
/*
* The length of time before a channel registration expires.
*
* This directive is optional, but recommended.
* If not set, the default is 30 days.
* This directive is optional. If not set, the default is never.
*/
expire = 30d
#expire = 90d
/*
* The maximum number of entries on a channel's access list.
@@ -392,7 +391,7 @@ privilege
}
/*
* FANTASIA privilege.
* FANTASY privilege.
*
* Used by botserv/main and chanserv/xop.
*
@@ -400,7 +399,7 @@ privilege
*/
privilege
{
name = "FANTASIA"
name = "FANTASY"
desc = _("Allowed to use fantasy commands")
rank = 30
level = 3
@@ -1278,7 +1277,7 @@ module
* This directive is optional.
* If not set, the default is never.
*/
expire = 90d
suspendexpire = 90d
/*
* Settings to show to non-opers in ChanServ's INFO output.
+5 -4
View File
@@ -372,6 +372,7 @@ module { name = "help" }
username = "anope"
password = "mypassword"
port = 3306
socket = ""
}
}
@@ -754,7 +755,7 @@ module { name = "sasl" }
name = "sqlite/main"
/* The database name, it will be created if it does not exist. */
database = "anope.db"
database = "anope.sqlite"
}
}
@@ -772,16 +773,16 @@ module { name = "sasl" }
name = "webcpanel"
/* Web server to use. */
server = "httpd/main";
server = "httpd/main"
/*
* The directory containing the webcpanel templates. This is relative to the
* data directory.
*/
template_dir = "webcpanel/templates/default";
template_dir = "webcpanel/templates/default"
/* Page title. */
title = "Anope IRC Services";
title = "Anope IRC Services"
}
/*
+22 -4
View File
@@ -219,6 +219,12 @@ module
* This directive is optional. If not set it defaults to 50.
*/
maxpasslen = 50
/*
* Whether all of the secondary nicks of a nick group have to expire or be
dropped before the display nick can expire or be dropped.
*/
preservedisplay = no
}
/*
@@ -286,6 +292,12 @@ module
{
name = "ns_cert"
/*
* Should users who are connected with a SSL client certificate have its fingerprint be added to
* their account when they register. Defaults to yes.
*/
automatic = yes
/*
* The maximum number of entries allowed on a nickname's certificate fingerprint list.
* The default is 5. This number cannot be set to 0.
@@ -500,7 +512,6 @@ command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpas
* nickserv/set/email, nickserv/saset/email - Used for setting a users email address.
* nickserv/set/keepmodes, nickserv/saset/keepmodes - Configure whether or not services should retain a user's modes across sessions.
* nickserv/set/kill, nickserv/saset/kill - Used for configuring nickname protection.
* nickserv/set/language, nickserv/saset/language - Used for configuring what language services use.
* nickserv/set/message, nickserv/saset/message - Used to configure how services send messages to you.
* nickserv/set/neverop, nickserv/saset/neverop - Used to configure whether a user can be added to access lists
* nickserv/saset/noexpire - Used for configuring noexpire, which prevents nicks from expiring.
@@ -536,9 +547,6 @@ command { service = "NickServ"; name = "SASET KEEPMODES"; command = "nickserv/sa
command { service = "NickServ"; name = "SET KILL"; command = "nickserv/set/kill"; }
command { service = "NickServ"; name = "SASET KILL"; command = "nickserv/saset/kill"; permission = "nickserv/saset/kill"; }
command { service = "NickServ"; name = "SET LANGUAGE"; command = "nickserv/set/language"; }
command { service = "NickServ"; name = "SASET LANGUAGE"; command = "nickserv/saset/language"; permission = "nickserv/saset/language"; }
command { service = "NickServ"; name = "SET MESSAGE"; command = "nickserv/set/message"; }
command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/saset/message"; permission = "nickserv/saset/message"; }
@@ -550,6 +558,16 @@ command { service = "NickServ"; name = "SASET NEVEROP"; command = "nickserv/sase
command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; permission = "nickserv/saset/noexpire"; }
/*
* ns_set_language
*
* Provides the command nickserv/set/language and nickserv/saset/language.
*
* Allows configuring the language that services uses.
*/
module { name = "ns_set_language" }
command { service = "NickServ"; name = "SET LANGUAGE"; command = "nickserv/set/language"; }
command { service = "NickServ"; name = "SASET LANGUAGE"; command = "nickserv/saset/language"; permission = "nickserv/saset/language"; }
/*
* ns_set_misc
+1 -1
View File
@@ -503,7 +503,7 @@ command { service = "OperServ"; name = "RANDOMNEWS"; command = "operserv/randomn
*
* Used to NOOP a server, which prevents users from opering on that server.
*/
module { name = "os_noop" }
#module { name = "os_noop" }
command { service = "OperServ"; name = "NOOP"; command = "operserv/noop"; permission = "operserv/noop"; }
/*
+52
View File
@@ -1,3 +1,55 @@
Anope Version 2.1.8
-------------------
Added account identifiers to the nickserv/info output.
Added support for bool, float, and uint SQL columns.
Added the ability to automatically determine SQL column types based on the native type.
Added UNIX socket support to mysql module.
Changed smartjoin to use SendClearBans where available.
Dropped support for MinGW in favour of native builds.
Fixed parsing named extbans on InspIRCd.
Fixed parsing SVSMODE and SVS2MODE from UnrealIRCd.
Fixed sending global messages to remotely linked servers.
Removed the services server name from the CTCP version response.
Anope Version 2.1.7
-------------------
Added importing of akick reasons, forbid reasons, opers and session exceptions to db_atheme.
Added support for sending tag messages.
Added the ability to look up account information of an authenticated user.
Fixed a crash in ns_cert when an IRC user is not present during a nick registration.
Fixed a null pointer dereference in the global module.
Fixed a rare memory leak in os_akill and os_sxline.
Improved the performance of some code that looks up the primary nick from an account.
Removed the broken Catalan, Hungarian, and Russian translations.
Reworked the protocol interface for sending messages.
Updated the Turkish translation.
Anope Version 2.1.6
-------------------
Added opportunistic upgrading of TLS fingerprints to more secure algorithms on InspIRCd.
Added support for logging out partially connected users on Plexus.
Added the account registration time to nickserv/info.
Changed ns_cert to automatically add a TLS fingerprint to new accounts if available.
Clarified that a non-deprecated encryption module must be loaded.
Fixed creating the runtime directory on Windows.
Fixed mistakenly allowing badpasslimit to be set to a negative value.
Fixed parsing backup TLS fingerprints on InspIRCd.
Fixed parsing the flood mode on UnrealIRCd.
Fixed parsing the history mode on UnrealIRCd.
Fixed various iterator invalidation issues.
Partially rewrote the Portuguese translation.
Removed some incorrect strings from the Turkish translation.
Renamed the --modulesdir option to --moduledir to match the name of other path options.
Anope Version 2.1.5
-------------------
Added an example systemd unit file.
Added support for BIGLINES on UnrealIRCd.
Bumped the minimum supported version of Bahamut to 2.0.
Fixed truncating messages in global/global and global/server.
Improved building Anope for use as a system package.
Updated the Turkish translation.
Anope Version 2.1.4
-------------------
Added a check for a non-deprecated encryption module on start.
+21
View File
@@ -1,3 +1,24 @@
Anope Version 2.1.8
-------------------
Added module:preservedisplay to the nickserv module.
Added the nickserv/drop/display oper privilege.
Anope Version 2.1.7
-------------------
Moved nickserv/set/language and nickserv/saset/language to the ns_set_language module.
Renamed module:expire for the cs_suspend module to suspendexpire.
Renamed the FANTASIA privilege to FANTASY.
Anope Version 2.1.6
-------------------
Added module:automatic to the ns_cert module (defaults to yes).
Removed module:use_server_side_mlock for the protocol modules (now always enabled).
Removed module:use_server_side_topiclock for the protocol modules (now always enabled).
Anope Version 2.1.5
-------------------
Added the nickserv/drop/override and chanserv/drop/override oper privileges.
Anope Version 2.1.4
-------------------
Added the db_atheme module.
+2
View File
@@ -19,6 +19,8 @@ Anope Multi Language Support
Then execute:
dpkg-reconfigure locales
If you have already built Anope you will need to delete the build directory and rebuild from scratch.
Building Anope on Windows with gettext support is explained in docs/WIN32.txt
2) Adding a new language
+1 -1
View File
@@ -166,7 +166,7 @@ Table of Contents
Anope currently works with:
* Bahamut 1.4.27 or later (including 1.8)
* Bahamut 2.0 or later
* ircd-hybrid 8.2.23 or later
* InspIRCd 3 or later
* ngIRCd 19.2 or later
+5 -1
View File
@@ -130,6 +130,8 @@ public:
Anope::string language;
/* Last time an email was sent to this user */
time_t lastmail = 0;
/* The time this account was registered */
time_t time_registered = Anope::CurTime;
MemoInfo memos;
std::map<Anope::string, Anope::string> last_modes;
@@ -143,6 +145,8 @@ public:
/* Unsaved data */
/** The display nick for this account. */
NickAlias *na = nullptr;
/* Number of channels registered by this account */
uint16_t channelcount = 0;
/* Users online now logged into this account */
@@ -161,7 +165,7 @@ public:
/** Changes the display for this account
* @param na The new display, must be grouped to this account.
*/
void SetDisplay(const NickAlias *na);
void SetDisplay(NickAlias *na);
/** Checks whether this account is a services oper or not.
* @return True if this account is a services oper, false otherwise.
+14 -7
View File
@@ -601,6 +601,20 @@ namespace Anope
/** Expands a module path. */
inline auto ExpandModule(const Anope::string &path) { return Expand(ModuleDir, path); }
/** Formats a CTCP message for sending to a client.
* @param name The name of the CTCP.
* @param body If present then the body of the CTCP.
* @return A formatted CTCP ready to send to a client.
*/
extern CoreExport Anope::string FormatCTCP(const Anope::string &name, const Anope::string &body = "");
/** 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.
* @param body The location to store body of the CTCP if one is present.
* @return True if the message was a well formed CTCP; otherwise, false.
*/
extern CoreExport bool ParseCTCP(const Anope::string &text, Anope::string &name, Anope::string &body);
}
/** sepstream allows for splitting token separated lists.
@@ -717,9 +731,6 @@ protected:
*/
Anope::string source;
public:
/** Default constructor, just uses the error message 'Core threw an exception'.
*/
CoreException() : err("Core threw an exception"), source("The core") { }
/** This constructor can be used to specify an error message before throwing.
*/
CoreException(const Anope::string &message) : err(message), source("The core") { }
@@ -750,10 +761,6 @@ class CoreExport ModuleException
: public CoreException
{
public:
/** Default constructor, just uses the error message 'Module threw an exception'.
*/
ModuleException() : CoreException("Module threw an exception", "A Module") { }
/** This constructor can be used to specify an error message before throwing.
*/
ModuleException(const Anope::string &message) : CoreException(message, "A Module") { }
+2 -2
View File
@@ -173,7 +173,7 @@ public:
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const override
{
T *t = this->Get(e);
data[this->name] << *t;
data.Store(this->name, *t);
}
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
@@ -194,7 +194,7 @@ public:
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const override
{
data[this->name] << true;
data.Store(this->name, true);
}
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
+1 -1
View File
@@ -108,7 +108,7 @@ namespace Language
#define CHAN_SETTING_CHANGED _("%s for %s set to %s.")
#define CHAN_SETTING_UNSET _("%s for %s unset.")
#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.")
#define CHAN_INFO_HEADER _("Information for channel \002%s\002:")
#define CHAN_INFO_HEADER _("Information about channel \002%s\002:")
#define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except has been removed.")
#define MEMO_NEW_X_MEMO_ARRIVED _("There is a new memo on channel %s.\n" \
"Type \002%s%s READ %s %zu\002 to read it.")
+120 -118
View File
@@ -199,6 +199,8 @@ public:
class CoreExport NotImplementedException final
: public CoreException
{
public:
NotImplementedException() : CoreException("") { }
};
/** Every module in Anope is actually a class.
@@ -288,7 +290,7 @@ public:
* @param cu The user, channel, and status of the user being kicked
* @param kickmsg The reason for the kick.
*/
virtual void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) { throw NotImplementedException(); }
virtual void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a user has been kicked from a channel.
* @param source The kicker
@@ -297,13 +299,13 @@ public:
* @param status The status the kicked user had on the channel before they were kicked
* @param kickmsg The reason for the kick.
*/
virtual void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) { throw NotImplementedException(); }
virtual void OnUserKicked(const MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when the configuration is being (re)loaded.
* @param conf The config that is being built now and will replace the global Config object
* @throws A ConfigException to abort the config (re)loading process.
*/
virtual void OnReload(Configuration::Conf *conf) { throw NotImplementedException(); }
virtual void OnReload(Configuration::Conf *conf) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called before a bot is assigned to a channel.
* @param sender The user assigning the bot
@@ -311,35 +313,35 @@ public:
* @param bi The bot being assigned.
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the assign.
*/
virtual EventReturn OnPreBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { throw NotImplementedException(); }
virtual EventReturn OnPreBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) ATTR_NOT_NULL(2, 3, 4) { throw NotImplementedException(); }
/** Called when a bot is assigned ot a channel
*/
virtual void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { throw NotImplementedException(); }
virtual void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) ATTR_NOT_NULL(2, 3, 4) { throw NotImplementedException(); }
/** Called before a bot is unassigned from a channel.
* @param sender The user unassigning the bot
* @param ci The channel the bot is being removed from
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the unassign.
*/
virtual EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci) { throw NotImplementedException(); }
virtual EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a new user connects to the network.
* @param u The connecting user.
* @param exempt set to true/is true if the user should be excepted from bans etc
*/
virtual void OnUserConnect(User *u, bool &exempt) { throw NotImplementedException(); }
virtual void OnUserConnect(User *u, bool &exempt) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a new server connects to the network.
* @param s The server that has connected to the network
*/
virtual void OnNewServer(Server *s) { throw NotImplementedException(); }
virtual void OnNewServer(Server *s) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called after a user changed the nick
* @param u The user.
* @param oldnick The old nick of the user
*/
virtual void OnUserNickChange(User *u, const Anope::string &oldnick) { throw NotImplementedException(); }
virtual void OnUserNickChange(User *u, const Anope::string &oldnick) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when someone uses the generic/help command
* @param source Command source
@@ -360,14 +362,14 @@ public:
* @param params The parameters the user is sending
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) { throw NotImplementedException(); }
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called after a command has been executed.
* @param source The source of the command
* @param command The command the user executed
* @param params The parameters the user sent
*/
virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when the databases are saved
*/
@@ -389,7 +391,7 @@ public:
* @param params The params
* @return EVENT_STOP to halt processing and not run the command, EVENT_ALLOW to allow the command to be executed
*/
virtual EventReturn OnBotFantasy(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
virtual EventReturn OnBotFantasy(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called on fantasy command without access
* @param source The source of the command
@@ -398,31 +400,31 @@ public:
* @param params The params
* @return EVENT_STOP to halt processing and not run the command, EVENT_ALLOW to allow the command to be executed
*/
virtual EventReturn OnBotNoFantasyAccess(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) { throw NotImplementedException(); }
virtual EventReturn OnBotNoFantasyAccess(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called when a bot places a ban
* @param u User being banned
* @param ci Channel the ban is placed on
* @param mask The mask being banned
*/
virtual void OnBotBan(User *u, ChannelInfo *ci, const Anope::string &mask) { throw NotImplementedException(); }
virtual void OnBotBan(User *u, ChannelInfo *ci, const Anope::string &mask) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called before a badword is added to the badword list
* @param ci The channel
* @param bw The badword
*/
virtual void OnBadWordAdd(ChannelInfo *ci, const BadWord *bw) { throw NotImplementedException(); }
virtual void OnBadWordAdd(ChannelInfo *ci, const BadWord *bw) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called before a badword is deleted from a channel
* @param ci The channel
* @param bw The badword
*/
virtual void OnBadWordDel(ChannelInfo *ci, const BadWord *bw) { throw NotImplementedException(); }
virtual void OnBadWordDel(ChannelInfo *ci, const BadWord *bw) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a bot is created or destroyed
*/
virtual void OnCreateBot(BotInfo *bi) { throw NotImplementedException(); }
virtual void OnDelBot(BotInfo *bi) { throw NotImplementedException(); }
virtual void OnCreateBot(BotInfo *bi) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
virtual void OnDelBot(BotInfo *bi) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called before a bot kicks a user
* @param bi The bot sending the kick
@@ -431,13 +433,13 @@ public:
* @param reason The reason
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason) { throw NotImplementedException(); }
virtual EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason) ATTR_NOT_NULL(2, 3, 4) { throw NotImplementedException(); }
/** Called before a user parts a channel
* @param u The user
* @param c The channel
*/
virtual void OnPrePartChannel(User *u, Channel *c) {}
virtual void OnPrePartChannel(User *u, Channel *c) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a user parts a channel
* @param u The user
@@ -445,14 +447,14 @@ public:
* @param channel The channel name
* @param msg The part reason
*/
virtual void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) { throw NotImplementedException(); }
virtual void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a user leaves a channel.
* From either parting, being kicked, or quitting/killed!
* @param u The user
* @param c The channel
*/
virtual void OnLeaveChannel(User *u, Channel *c) { throw NotImplementedException(); }
virtual void OnLeaveChannel(User *u, Channel *c) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called after a user joins a channel
* If this event triggers the user is allowed to be in the channel, and will
@@ -461,7 +463,7 @@ public:
* @param u The user
* @param channel The channel
*/
virtual void OnJoinChannel(User *u, Channel *c) { throw NotImplementedException(); }
virtual void OnJoinChannel(User *u, Channel *c) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a new topic is set
* @param source The user changing the topic, if any
@@ -469,18 +471,18 @@ public:
* @param setter The user who set the new topic, if there is no source
* @param topic The new topic
*/
virtual void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) { throw NotImplementedException(); }
virtual void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called before a channel expires
* @param ci The channel
* @param expire Set to true to allow the chan to expire
*/
virtual void OnPreChanExpire(ChannelInfo *ci, bool &expire) { throw NotImplementedException(); }
virtual void OnPreChanExpire(ChannelInfo *ci, bool &expire) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called before a channel expires
* @param ci The channel
*/
virtual void OnChanExpire(ChannelInfo *ci) { throw NotImplementedException(); }
virtual void OnChanExpire(ChannelInfo *ci) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called before Anope connects to its uplink
*/
@@ -492,7 +494,7 @@ public:
/** Called when we are almost done synching with the uplink, just before we send the EOB
*/
virtual void OnPreUplinkSync(Server *serv) { throw NotImplementedException(); }
virtual void OnPreUplinkSync(Server *serv) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when Anope disconnects from its uplink, before it tries to reconnect
*/
@@ -510,12 +512,12 @@ public:
* @param na The nick
* @param expire Set to true to allow the nick to expire
*/
virtual void OnPreNickExpire(NickAlias *na, bool &expire) { throw NotImplementedException(); }
virtual void OnPreNickExpire(NickAlias *na, bool &expire) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a nick drops
* @param na The nick
*/
virtual void OnNickExpire(NickAlias *na) { throw NotImplementedException(); }
virtual void OnNickExpire(NickAlias *na) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when defcon level changes
* @param level The level
@@ -526,13 +528,13 @@ public:
* @param ex The exception
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnExceptionAdd(Exception *ex) { throw NotImplementedException(); }
virtual EventReturn OnExceptionAdd(Exception *ex) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called before an exception is deleted
* @param source The source deleting it
* @param ex The exception
*/
virtual void OnExceptionDel(CommandSource &source, Exception *ex) { throw NotImplementedException(); }
virtual void OnExceptionDel(CommandSource &source, Exception *ex) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called before a XLine is added
* @param source The source of the XLine
@@ -540,31 +542,31 @@ public:
* @param xlm The xline manager it was added to
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnAddXLine(CommandSource &source, const XLine *x, XLineManager *xlm) { throw NotImplementedException(); }
virtual EventReturn OnAddXLine(CommandSource &source, const XLine *x, XLineManager *xlm) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called before a XLine is deleted
* @param source The source of the XLine
* @param x The XLine
* @param xlm The xline manager it was deleted from
*/
virtual void OnDelXLine(CommandSource &source, const XLine *x, XLineManager *xlm) { throw NotImplementedException(); }
virtual void OnDelXLine(CommandSource &source, const XLine *x, XLineManager *xlm) ATTR_NOT_NULL(4) { throw NotImplementedException(); }
/** Called when a user is checked for whether they are a services oper
* @param u The user
* @return EVENT_ALLOW to allow, anything else to deny
*/
virtual EventReturn IsServicesOper(User *u) { throw NotImplementedException(); }
virtual EventReturn IsServicesOper(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a server quits
* @param server The server
*/
virtual void OnServerQuit(Server *server) { throw NotImplementedException(); }
virtual void OnServerQuit(Server *server) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user quits, or is killed
* @param u The user
* @param msg The quit message
*/
virtual void OnUserQuit(User *u, const Anope::string &msg) { throw NotImplementedException(); }
virtual void OnUserQuit(User *u, const Anope::string &msg) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user is quit, before and after being internally removed from
* This is different from OnUserQuit, which takes place at the time of the quit.
@@ -572,43 +574,43 @@ public:
* all lists (channels, user list, etc)
* @param u The user
*/
virtual void OnPreUserLogoff(User *u) { throw NotImplementedException(); }
virtual void OnPostUserLogoff(User *u) { throw NotImplementedException(); }
virtual void OnPreUserLogoff(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
virtual void OnPostUserLogoff(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a new bot is made
* @param bi The bot
*/
virtual void OnBotCreate(BotInfo *bi) { throw NotImplementedException(); }
virtual void OnBotCreate(BotInfo *bi) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a bot is changed
* @param bi The bot
*/
virtual void OnBotChange(BotInfo *bi) { throw NotImplementedException(); }
virtual void OnBotChange(BotInfo *bi) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a bot is deleted
* @param bi The bot
*/
virtual void OnBotDelete(BotInfo *bi) { throw NotImplementedException(); }
virtual void OnBotDelete(BotInfo *bi) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called after an access entry is deleted from a channel
* @param ci The channel
* @param source The source of the command
* @param access The access entry that was removed
*/
virtual void OnAccessDel(ChannelInfo *ci, CommandSource &source, ChanAccess *access) { throw NotImplementedException(); }
virtual void OnAccessDel(ChannelInfo *ci, CommandSource &source, ChanAccess *access) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
/** Called when access is added
* @param ci The channel
* @param source The source of the command
* @param access The access changed
*/
virtual void OnAccessAdd(ChannelInfo *ci, CommandSource &source, ChanAccess *access) { throw NotImplementedException(); }
virtual void OnAccessAdd(ChannelInfo *ci, CommandSource &source, ChanAccess *access) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
/** Called when the access list is cleared
* @param ci The channel
* @param u The user who cleared the access
*/
virtual void OnAccessClear(ChannelInfo *ci, CommandSource &source) { throw NotImplementedException(); }
virtual void OnAccessClear(ChannelInfo *ci, CommandSource &source) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a level for a channel is changed
* @param source The source of the command
@@ -616,63 +618,63 @@ public:
* @param priv The privilege changed
* @param what The new level
*/
virtual void OnLevelChange(CommandSource &source, ChannelInfo *ci, const Anope::string &priv, int16_t what) { throw NotImplementedException(); }
virtual void OnLevelChange(CommandSource &source, ChannelInfo *ci, const Anope::string &priv, int16_t what) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called right before a channel is dropped
* @param source The user dropping the channel
* @param ci The channel
*/
virtual EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) { throw NotImplementedException(); }
virtual EventReturn OnChanDrop(CommandSource &source, ChannelInfo *ci) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a channel is registered
* @param ci The channel
*/
virtual void OnChanRegistered(ChannelInfo *ci) { throw NotImplementedException(); }
virtual void OnChanRegistered(ChannelInfo *ci) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a channel is suspended
* @param ci The channel
*/
virtual void OnChanSuspend(ChannelInfo *ci) { throw NotImplementedException(); }
virtual void OnChanSuspend(ChannelInfo *ci) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a channel is unsuspended
* @param ci The channel
*/
virtual void OnChanUnsuspend(ChannelInfo *ci) { throw NotImplementedException(); }
virtual void OnChanUnsuspend(ChannelInfo *ci) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a channel is being created, for any reason
* @param ci The channel
*/
virtual void OnCreateChan(ChannelInfo *ci) { throw NotImplementedException(); }
virtual void OnCreateChan(ChannelInfo *ci) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a channel is being deleted, for any reason
* @param ci The channel
*/
virtual void OnDelChan(ChannelInfo *ci) { throw NotImplementedException(); }
virtual void OnDelChan(ChannelInfo *ci) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a new channel is created
* Note that this channel may not be introduced to the uplink at this point.
* @param c The channel
*/
virtual void OnChannelCreate(Channel *c) { throw NotImplementedException(); }
virtual void OnChannelCreate(Channel *c) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a channel is deleted
* @param c The channel
*/
virtual void OnChannelDelete(Channel *c) { throw NotImplementedException(); }
virtual void OnChannelDelete(Channel *c) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called after adding an akick to a channel
* @param source The source of the command
* @param ci The channel
* @param ak The akick
*/
virtual void OnAkickAdd(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) { throw NotImplementedException(); }
virtual void OnAkickAdd(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called before removing an akick from a channel
* @param source The source of the command
* @param ci The channel
* @param ak The akick
*/
virtual void OnAkickDel(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) { throw NotImplementedException(); }
virtual void OnAkickDel(CommandSource &source, ChannelInfo *ci, const AutoKick *ak) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called after a user join a channel when we decide whether to kick them or not
* @param u The user
@@ -682,7 +684,7 @@ public:
* @param reason The reason for the kick
* @return EVENT_STOP to prevent the user from joining by kicking/banning the user
*/
virtual EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) { throw NotImplementedException(); }
virtual EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a user requests info for a channel
* @param source The user requesting info
@@ -690,109 +692,109 @@ public:
* @param info Data to show the user requesting information
* @param show_hidden true if we should show the user everything
*/
virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) { throw NotImplementedException(); }
virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Checks if access has the channel privilege 'priv'.
* @param access THe access struct
* @param priv The privilege being checked for
* @return EVENT_ALLOW for yes, EVENT_STOP to stop all processing
*/
virtual EventReturn OnCheckPriv(const ChanAccess *access, const Anope::string &priv) { throw NotImplementedException(); }
virtual EventReturn OnCheckPriv(const ChanAccess *access, const Anope::string &priv) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Check whether an access group has a privilege
* @param group The group
* @param priv The privilege
* @return MOD_ALLOW to allow, MOD_STOP to stop
*/
virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) { throw NotImplementedException(); }
virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a nick is dropped
* @param source The source of the command
* @param na The nick
*/
virtual void OnNickDrop(CommandSource &source, NickAlias *na) { throw NotImplementedException(); }
virtual void OnNickDrop(CommandSource &source, NickAlias *na) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a user groups their nick
* @param u The user grouping
* @param target The target they're grouping to
*/
virtual void OnNickGroup(User *u, NickAlias *target) { throw NotImplementedException(); }
virtual void OnNickGroup(User *u, NickAlias *target) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a user identifies to a nick
* @param u The user
*/
virtual void OnNickIdentify(User *u) { throw NotImplementedException(); }
virtual void OnNickIdentify(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user is logged into an account
* @param u The user
*/
virtual void OnUserLogin(User *u) { throw NotImplementedException(); }
virtual void OnUserLogin(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a nick logs out
* @param u The nick
*/
virtual void OnNickLogout(User *u) { throw NotImplementedException(); }
virtual void OnNickLogout(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a nick is registered
* @param user The user registering the nick, of any
* @param The nick
* @param pass The password of the newly registered nick
*/
virtual void OnNickRegister(User *user, NickAlias *na, const Anope::string &pass) { throw NotImplementedException(); }
virtual void OnNickRegister(User *user, NickAlias *na, const Anope::string &pass) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a nick is confirmed. This will never be called if registration confirmation is not enabled.
* @param user The user confirming the nick
* @param The account being confirmed
* @param nc The account being confirmed
*/
virtual void OnNickConfirm(User *user, NickCore *) { throw NotImplementedException(); }
virtual void OnNickConfirm(User *user, NickCore *nc) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a nick is suspended
* @param na The nick alias
*/
virtual void OnNickSuspend(NickAlias *na) { throw NotImplementedException(); }
virtual void OnNickSuspend(NickAlias *na) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a nick is unsuspended
* @param na The nick alias
*/
virtual void OnNickUnsuspended(NickAlias *na) { throw NotImplementedException(); }
virtual void OnNickUnsuspended(NickAlias *na) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called on delnick()
* @ param na pointer to the nickalias
*/
virtual void OnDelNick(NickAlias *na) { throw NotImplementedException(); }
virtual void OnDelNick(NickAlias *na) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a nickcore is created
* @param nc The nickcore
*/
virtual void OnNickCoreCreate(NickCore *nc) { throw NotImplementedException(); }
virtual void OnNickCoreCreate(NickCore *nc) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called on delcore()
* @param nc pointer to the NickCore
*/
virtual void OnDelCore(NickCore *nc) { throw NotImplementedException(); }
virtual void OnDelCore(NickCore *nc) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called on change_core_display()
* @param nc pointer to the NickCore
* @param newdisplay the new display
*/
virtual void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) { throw NotImplementedException(); }
virtual void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** called from NickCore::ClearCert()
* @param nc pointer to the NickCore
*/
virtual void OnNickClearCert(NickCore *nc) { throw NotImplementedException(); }
virtual void OnNickClearCert(NickCore *nc) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user adds an entry to their cert list
* @param nc The nick
* @param entry The entry
*/
virtual void OnNickAddCert(NickCore *nc, const Anope::string &entry) { throw NotImplementedException(); }
virtual void OnNickAddCert(NickCore *nc, const Anope::string &entry) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called from NickCore::EraseCert()
* @param nc pointer to the NickCore
* @param entry The fingerprint
*/
virtual void OnNickEraseCert(NickCore *nc, const Anope::string &entry) { throw NotImplementedException(); }
virtual void OnNickEraseCert(NickCore *nc, const Anope::string &entry) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user requests info for a nick
* @param source The user requesting info
@@ -800,55 +802,55 @@ public:
* @param info Data to show the user requesting information
* @param show_hidden true if we should show the user everything
*/
virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) { throw NotImplementedException(); }
virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a user uses botserv/info on a bot or channel.
*/
virtual void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) { throw NotImplementedException(); }
virtual void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info) ATTR_NOT_NULL(4) { throw NotImplementedException(); }
/** Check whether a username and password is correct
* @param u The user trying to identify, if applicable.
* @param req The login request
*/
virtual void OnCheckAuthentication(User *u, IdentifyRequest *req) { throw NotImplementedException(); }
virtual void OnCheckAuthentication(User *u, IdentifyRequest *req) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a user does /ns update
* @param u The user
*/
virtual void OnNickUpdate(User *u) { throw NotImplementedException(); }
virtual void OnNickUpdate(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when we get informed about a users SSL fingerprint
* when we call this, the fingerprint should already be stored in the user struct
* @param u pointer to the user
*/
virtual void OnFingerprint(User *u) { throw NotImplementedException(); }
virtual void OnFingerprint(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user becomes (un)away
* @param message The message, is .empty() if unaway
*/
virtual void OnUserAway(User *u, const Anope::string &message) { throw NotImplementedException(); }
virtual void OnUserAway(User *u, const Anope::string &message) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user invites one of our users to a channel
* @param source The user doing the inviting
* @param c The channel the user is inviting to
* @param targ The user being invited
*/
virtual void OnInvite(User *source, Channel *c, User *targ) { throw NotImplementedException(); }
virtual void OnInvite(User *source, Channel *c, User *targ) ATTR_NOT_NULL(2, 3, 4) { throw NotImplementedException(); }
/** Called when a vhost is deleted
* @param na The nickalias of the vhost
*/
virtual void OnDeleteVHost(NickAlias *na) { throw NotImplementedException(); }
virtual void OnDeleteVHost(NickAlias *na) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a vhost is set
* @param na The nickalias of the vhost
*/
virtual void OnSetVHost(NickAlias *na) { throw NotImplementedException(); }
virtual void OnSetVHost(NickAlias *na) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a users host changes
* @param u The user
*/
virtual void OnSetDisplayedHost(User *) { throw NotImplementedException(); }
virtual void OnSetDisplayedHost(User *u) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a memo is sent
* @param source The source of the memo
@@ -856,14 +858,14 @@ public:
* @param mi Memo info for target
* @param m The memo
*/
virtual void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m) { throw NotImplementedException(); }
virtual void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m) ATTR_NOT_NULL(4, 5) { throw NotImplementedException(); }
/** Called when a memo is deleted
* @param target The target the memo is being deleted from (nick or channel)
* @param mi The memo info
* @param m The memo
*/
virtual void OnMemoDel(const Anope::string &target, MemoInfo *mi, const Memo *m) { throw NotImplementedException(); }
virtual void OnMemoDel(const Anope::string &target, MemoInfo *mi, const Memo *m) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called when a mode is set on a channel
* @param c The channel
@@ -872,7 +874,7 @@ public:
* @param param The mode param, if there is one
* @return EVENT_STOP to make mlock/secureops etc checks not happen
*/
virtual EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) { throw NotImplementedException(); }
virtual EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
/** Called when a mode is unset on a channel
* @param c The channel
@@ -881,67 +883,67 @@ public:
* @param param The mode param, if there is one
* @return EVENT_STOP to make mlock/secureops etc checks not happen
*/
virtual EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) { throw NotImplementedException(); }
virtual EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string &param) ATTR_NOT_NULL(2, 4) { throw NotImplementedException(); }
/** Called when a mode is set on a user
* @param setter who/what is setting the mode
* @param u The user
* @param mname The mode name
*/
virtual void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) { throw NotImplementedException(); }
virtual void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a mode is unset from a user
* @param setter who/what is setting the mode
* @param u The user
* @param mname The mode name
*/
virtual void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) { throw NotImplementedException(); }
virtual void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a channel mode is introduced into Anope
* @param cm The mode
*/
virtual void OnChannelModeAdd(ChannelMode *cm) { throw NotImplementedException(); }
virtual void OnChannelModeAdd(ChannelMode *cm) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a user mode is introduced into Anope
* @param um The mode
*/
virtual void OnUserModeAdd(UserMode *um) { throw NotImplementedException(); }
virtual void OnUserModeAdd(UserMode *um) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a mode is about to be mlocked
* @param ci The channel the mode is being locked on
* @param lock The mode lock
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
*/
virtual EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) { throw NotImplementedException(); }
virtual EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a mode is about to be unlocked
* @param ci The channel the mode is being unlocked from
* @param lock The mode lock
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
*/
virtual EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) { throw NotImplementedException(); }
virtual EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called after a module is loaded
* @param u The user loading the module, can be NULL
* @param m The module
*/
virtual void OnModuleLoad(User *u, Module *m) { throw NotImplementedException(); }
virtual void OnModuleLoad(User *u, Module *m) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called before a module is unloaded
* @param u The user, can be NULL
* @param m The module
*/
virtual void OnModuleUnload(User *u, Module *m) { throw NotImplementedException(); }
virtual void OnModuleUnload(User *u, Module *m) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a server is synced
* @param s The server, can be our uplink server
*/
virtual void OnServerSync(Server *s) { throw NotImplementedException(); }
virtual void OnServerSync(Server *s) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when we sync with our uplink
* @param s Our uplink
*/
virtual void OnUplinkSync(Server *s) { throw NotImplementedException(); }
virtual void OnUplinkSync(Server *s) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when we receive a PRIVMSG for one of our clients
* @param u The user sending the PRIVMSG
@@ -950,7 +952,7 @@ public:
* @param tags Message tags
* @return EVENT_STOP to halt processing
*/
virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message, const Anope::map<Anope::string> &tags) { throw NotImplementedException(); }
virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message, const Anope::map<Anope::string> &tags) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when we receive a NOTICE for one of our clients
* @param u The user sending the NOTICE
@@ -958,7 +960,7 @@ public:
* @param tags Message tags
* @param message The message
*/
virtual void OnBotNotice(User *u, BotInfo *bi, Anope::string &message, const Anope::map<Anope::string> &tags) { throw NotImplementedException(); }
virtual void OnBotNotice(User *u, BotInfo *bi, Anope::string &message, const Anope::map<Anope::string> &tags) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when we receive a PRIVMSG for a registered channel we are in
* @param u The source of the message
@@ -966,12 +968,12 @@ public:
* @param msg The message
* @param tags Message tags
*/
virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg, const Anope::map<Anope::string> &tags) { throw NotImplementedException(); }
virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg, const Anope::map<Anope::string> &tags) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a message is logged
* @param l The log message
*/
virtual void OnLog(Log *l) { throw NotImplementedException(); }
virtual void OnLog(Log *l) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a log message is actually logged to a given log info
* The message has already passed validation checks by the LogInfo
@@ -979,13 +981,13 @@ public:
* @param l The log message
* @param msg The final formatted message, derived from 'l'
*/
virtual void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) { throw NotImplementedException(); }
virtual void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
/** Called when a DNS request (question) is received.
* @param req The dns request
* @param reply The reply that will be sent
*/
virtual void OnDnsRequest(DNS::Query &req, DNS::Query *reply) { throw NotImplementedException(); }
virtual void OnDnsRequest(DNS::Query &req, DNS::Query *reply) ATTR_NOT_NULL(3) { throw NotImplementedException(); }
/** Called when a channels modes are being checked to see if they are allowed,
* mostly to ensure mlock/+r are set.
@@ -998,7 +1000,7 @@ public:
* for a newly created channel to set the correct modes, topic,
* set.
*/
virtual void OnChannelSync(Channel *c) { throw NotImplementedException(); }
virtual void OnChannelSync(Channel *c) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called to set the correct modes on the user on the given channel
* @param user The user
@@ -1007,13 +1009,13 @@ public:
* @param give_modes If giving modes is desired
* @param take_modes If taking modes is desired
*/
virtual void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) { throw NotImplementedException(); }
virtual void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
virtual void OnSerializeCheck(Serialize::Type *) { throw NotImplementedException(); }
virtual void OnSerializableConstruct(Serializable *) { throw NotImplementedException(); }
virtual void OnSerializableDestruct(Serializable *) { throw NotImplementedException(); }
virtual void OnSerializableUpdate(Serializable *) { throw NotImplementedException(); }
virtual void OnSerializeTypeCreate(Serialize::Type *) { throw NotImplementedException(); }
virtual void OnSerializeCheck(Serialize::Type *st) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
virtual void OnSerializableConstruct(Serializable *st) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
virtual void OnSerializableDestruct(Serializable *st) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
virtual void OnSerializableUpdate(Serializable *st) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
virtual void OnSerializeTypeCreate(Serialize::Type *st) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called when a chanserv/set command is used
* @param source The source of the command
@@ -1022,7 +1024,7 @@ public:
* @param setting The setting passed to the command. Probably ON/OFF.
* @return EVENT_ALLOW to bypass access checks, EVENT_STOP to halt immediately.
*/
virtual EventReturn OnSetChannelOption(CommandSource &source, Command *cmd, ChannelInfo *ci, const Anope::string &setting) { throw NotImplementedException(); }
virtual EventReturn OnSetChannelOption(CommandSource &source, Command *cmd, ChannelInfo *ci, const Anope::string &setting) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called when a nickserv/set command is used.
* @param source The source of the command
@@ -1031,7 +1033,7 @@ public:
* @param setting The setting passed to the command. Probably ON/OFF.
* @return EVENT_STOP to halt immediately
*/
virtual EventReturn OnSetNickOption(CommandSource &source, Command *cmd, NickCore *nc, const Anope::string &setting) { throw NotImplementedException(); }
virtual EventReturn OnSetNickOption(CommandSource &source, Command *cmd, NickCore *nc, const Anope::string &setting) ATTR_NOT_NULL(3, 4) { throw NotImplementedException(); }
/** Called whenever a message is received from the uplink
* @param source The source of the message
@@ -1046,9 +1048,9 @@ public:
* @param u The user
* @param cm The mode
*/
virtual EventReturn OnCanSet(User *u, const ChannelMode *cm) { throw NotImplementedException(); }
virtual EventReturn OnCanSet(User *u, const ChannelMode *cm) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
virtual EventReturn OnCheckDelete(Channel *) { throw NotImplementedException(); }
virtual EventReturn OnCheckDelete(Channel *c) ATTR_NOT_NULL(2) { throw NotImplementedException(); }
/** Called every options:expiretimeout seconds. Should be used to expire nicks,
* channels, etc.
@@ -1061,7 +1063,7 @@ public:
* @param na The nick they are on
* @return EVENT_STOP to force the user off of the nick
*/
virtual EventReturn OnNickValidate(User *u, NickAlias *na) { throw NotImplementedException(); }
virtual EventReturn OnNickValidate(User *u, NickAlias *na) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); }
};
enum Implementation
+1
View File
@@ -79,4 +79,5 @@ public:
CertService(Module *c) : Service(c, "CertService", "certs") { }
virtual NickCore *FindAccountFromCert(const Anope::string &cert) = 0;
virtual void ReplaceCert(const Anope::string &oldcert, const Anope::string &newcert) = 0;
};
+46
View File
@@ -0,0 +1,46 @@
/*
*
* (C) 2011-2024 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*/
#pragma once
struct MyOper final
: Oper
, Serializable
{
MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { }
void Serialize(Serialize::Data &data) const override
{
data.Store("name", this->name);
data.Store("type", this->ot->GetName());
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
{
Anope::string stype, sname;
data["type"] >> stype;
data["name"] >> sname;
OperType *ot = OperType::Find(stype);
if (ot == NULL)
return NULL;
NickCore *nc = NickCore::Find(sname);
if (nc == NULL)
return NULL;
MyOper *myo;
if (obj)
myo = anope_dynamic_static_cast<MyOper *>(obj);
else
myo = new MyOper(nc->display, ot);
nc->o = myo;
Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
return myo;
}
};
+6 -6
View File
@@ -62,12 +62,12 @@ static ServiceReference<SessionService> session_service("SessionService", "sessi
void Exception::Serialize(Serialize::Data &data) const
{
data["mask"] << this->mask;
data["limit"] << this->limit;
data["who"] << this->who;
data["reason"] << this->reason;
data["time"] << this->time;
data["expires"] << this->expires;
data.Store("mask", this->mask);
data.Store("limit", this->limit);
data.Store("who", this->who);
data.Store("reason", this->reason);
data.Store("time", this->time);
data.Store("expires", this->expires);
}
Serializable *Exception::Unserialize(Serializable *obj, Serialize::Data &data)
+6 -14
View File
@@ -19,7 +19,7 @@ namespace SQL
public:
typedef std::map<Anope::string, std::stringstream *> Map;
Map data;
std::map<Anope::string, Type> types;
std::map<Anope::string, Serialize::DataType> types;
~Data()
{
@@ -34,14 +34,6 @@ namespace SQL
return *ss;
}
std::set<Anope::string> KeySet() const override
{
std::set<Anope::string> keys;
for (const auto &[key, _] : this->data)
keys.insert(key);
return keys;
}
size_t Hash() const override
{
size_t hash = 0;
@@ -68,17 +60,17 @@ namespace SQL
this->data.clear();
}
void SetType(const Anope::string &key, Type t) override
void SetType(const Anope::string &key, Serialize::DataType dt) override
{
this->types[key] = t;
this->types[key] = dt;
}
Type GetType(const Anope::string &key) const override
Serialize::DataType GetType(const Anope::string &key) const override
{
std::map<Anope::string, Type>::const_iterator it = this->types.find(key);
auto it = this->types.find(key);
if (it != this->types.end())
return it->second;
return DT_TEXT;
return Serialize::DataType::TEXT;
}
};
+12 -14
View File
@@ -41,9 +41,9 @@ public:
virtual ~IRCDProto();
virtual void SendNoticeInternal(const MessageSource &, const Anope::string &dest, const Anope::string &msg, const Anope::map<Anope::string> &tags = {});
virtual void SendPrivmsgInternal(const MessageSource &, const Anope::string &dest, const Anope::string &msg, const Anope::map<Anope::string> &tags = {});
virtual void SendCTCPInternal(const MessageSource &, const Anope::string &dest, const Anope::string &buf);
virtual void SendNotice(const MessageSource &source, const Anope::string &dest, const Anope::string &msg, const Anope::map<Anope::string> &tags = {});
virtual void SendPrivmsg(const MessageSource &source, const Anope::string &dest, const Anope::string &msg, const Anope::map<Anope::string> &tags = {});
virtual void SendTagmsg(const MessageSource &source, const Anope::string &dest, const Anope::map<Anope::string> &tags);
/** Parses an incoming message from the IRC server.
* @param message The message to parse.
@@ -74,6 +74,9 @@ public:
/* Can we force join or part users? */
bool CanSVSJoin = false;
/** Can we force servers to remove opers? */
bool CanSVSNOOP = false;
/* Can we set vhosts on users? */
bool CanSetVHost = false;
@@ -98,9 +101,6 @@ public:
/* See ns_cert */
bool CanCertFP = false;
/* Can users log out before being fully connected? */
bool CanSVSLogout = false;
/* Whether this IRCd requires unique IDs for each user or server. See TS6/P10. */
bool RequiresID = false;
@@ -110,6 +110,9 @@ public:
/** Can we ask the server to unban a user? */
bool CanClearBans = false;
/** Can we send tag messages? */
bool CanTagMessage = false;
/* The maximum length of a channel name. */
size_t MaxChannel = 0;
@@ -213,11 +216,6 @@ public:
virtual void SendKick(const MessageSource &source, const Channel *chan, User *user, const Anope::string &msg);
virtual void SendNotice(const MessageSource &source, const Anope::string &dest, const char *fmt, ...) ATTR_FORMAT(4, 5);
virtual void SendPrivmsg(const MessageSource &source, const Anope::string &dest, const char *fmt, ...) ATTR_FORMAT(4, 5);
virtual void SendAction(const MessageSource &source, const Anope::string &dest, const char *fmt, ...) ATTR_FORMAT(4, 5);
virtual void SendCTCP(const MessageSource &source, const Anope::string &dest, const char *fmt, ...) ATTR_FORMAT(4, 5);
virtual void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) = 0;
virtual void SendGlobalPrivmsg(BotInfo *bi, const Server *desc, const Anope::string &msg) = 0;
@@ -242,9 +240,9 @@ public:
* @param bi The source of the message
* @param u The user to join
* @param chan The channel to join the user to
* @param param Channel key?
* @param key Channel key
*/
virtual void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) { }
virtual void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) { }
/** Force parts a user that isn't ours from a channel.
* @param source The source of the message
@@ -299,7 +297,7 @@ public:
/** Send a channel creation message to the uplink.
* On most TS6 IRCds this is a SJOIN with no nick
*/
virtual void SendChannel(Channel *c) { }
virtual void SendChannel(Channel *c) = 0;
/** Make the user an IRC operator
* Normally this is a simple +o, though some IRCds require us to send the oper type
+30 -9
View File
@@ -18,23 +18,44 @@
namespace Serialize
{
enum class DataType
: uint8_t
{
BOOL,
FLOAT,
INT,
TEXT,
UINT,
};
class Data
{
public:
enum Type
{
DT_TEXT,
DT_INT
};
virtual ~Data() = default;
virtual std::iostream &operator[](const Anope::string &key) = 0;
virtual std::set<Anope::string> KeySet() const { throw CoreException("Not supported"); }
template <typename T>
void Store(const Anope::string &key, const T &value)
{
using Type = std::remove_cv_t<std::remove_reference_t<T>>;
if constexpr (std::is_same_v<Type, bool>)
SetType(key, DataType::BOOL);
else if constexpr (std::is_floating_point_v<Type>)
SetType(key, DataType::FLOAT);
else if constexpr (std::is_integral_v<Type> && std::is_signed_v<Type>)
SetType(key, DataType::INT);
else if constexpr (std::is_integral_v<Type> && std::is_unsigned_v<Type>)
SetType(key, DataType::UINT);
this->operator[](key) << value;
}
virtual size_t Hash() const { throw CoreException("Not supported"); }
virtual void SetType(const Anope::string &key, Type t) { }
virtual Type GetType(const Anope::string &key) const { return DT_TEXT; }
virtual void SetType(const Anope::string &key, DataType dt) { }
virtual DataType GetType(const Anope::string &key) const { return DataType::TEXT; }
};
extern void RegisterTypes();
+1
View File
@@ -16,6 +16,7 @@
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
+17
View File
@@ -20,6 +20,21 @@
// Whether Anope was built in debug mode.
#cmakedefine01 DEBUG_BUILD
// The default config directory.
#define DEFAULT_CONF_DIR "@CONF_DIR@"
// The default data directory.
#define DEFAULT_DATA_DIR "@DATA_DIR@"
// The default locale directory.
#define DEFAULT_LOCALE_DIR "@LOCALE_DIR@"
// The default log directory.
#define DEFAULT_LOG_DIR "@LOG_DIR@"
// The default module directory.
#define DEFAULT_MODULE_DIR "@MODULE_DIR@"
// Whether the clock_gettime() function is available.
#cmakedefine01 HAVE_CLOCK_GETTIME
@@ -36,6 +51,8 @@
#if defined __GNUC__
# define ATTR_FORMAT(STRINGPOS, FIRSTPOS) __attribute__((format(printf, STRINGPOS, FIRSTPOS)))
# define ATTR_NOT_NULL(...) __attribute__((nonnull(__VA_ARGS__)))
#else
# define ATTR_FORMAT(STRINGPOS, FIRSTPOS)
# define ATTR_NOT_NULL(...)
#endif
+5
View File
@@ -215,6 +215,11 @@ public:
*/
NickCore *Account() const;
/** Get the account nick the user is logged in using
* @return The account nick or NULL
*/
NickAlias *AccountNick() const;
/** Check if the user is identified for their nick
* @param check_nick True to check if the user is identified to the nickname they are on too
* @return true or false
+1 -1
View File
@@ -42,7 +42,7 @@ static std::string get_git_hash(const std::string &git_dir)
}
fd.close();
return "g" + filebuf.substr(0, 7);
return filebuf.substr(0, 7);
}
static bool read_version_sh(const std::string &version_sh, std::map<std::string, std::string> &versions)
File diff suppressed because it is too large Load Diff
+42 -15
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-15 12:41+0000\n"
"PO-Revision-Date: 2024-03-15 12:41+0000\n"
"POT-Creation-Date: 2024-08-18 03:16+0100\n"
"PO-Revision-Date: 2024-08-18 03:17+0100\n"
"Last-Translator: Sadie Powell <sadie@witchery.services>\n"
"Language-Team: English\n"
"Language: en_US\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.4\n"
"X-Generator: Poedit 3.4.2\n"
#, c-format
msgid "%d channel(s) cleared, and %d channel(s) dropped."
@@ -866,9 +866,9 @@ msgid ""
"fantasy commands on a channel when prefixed\n"
"with one of the following fantasy characters: %s\n"
" \n"
"Note that users wanting to use fantaisist\n"
"commands MUST have enough access for both\n"
"the FANTASIA and the command they are executing."
"Note that users wanting to use fantasy commands\n"
"MUST have enough access for both the FANTASY\n"
"privilege and the command they are executing."
msgstr ""
" \n"
"Enables or disables fantasy mode on a channel.\n"
@@ -876,9 +876,9 @@ msgstr ""
"fantasy commands on a channel when prefixed\n"
"with one of the following fantasy characters: %s\n"
" \n"
"Note that users wanting to use fantaisist\n"
"commands MUST have enough access for both\n"
"the FANTASIA and the command they are executing."
"Note that users wanting to use fantasy commands\n"
"MUST have enough access for both the FANTASY\n"
"privilege and the command they are executing."
msgid ""
" \n"
@@ -1812,6 +1812,12 @@ msgstr "Account"
msgid "Account %s has already reached the maximum number of simultaneous logins (%u)."
msgstr "Account %s has already reached the maximum number of simultaneous logins (%u)."
msgid "Account id"
msgstr "Account id"
msgid "Account registered"
msgstr "Account registered"
msgid "Accounts can not be registered right now. Please try again later."
msgstr "Accounts can not be registered right now. Please try again later."
@@ -1875,6 +1881,13 @@ msgstr ""
"Adding, deleting, or clearing entry messages requires the\n"
"SET permission."
msgid ""
"Additionally, Services Operators with the chanserv/drop/override permission can\n"
"replace code with OVERRIDE to drop without a confirmation code."
msgstr ""
"Additionally, Services Operators with the chanserv/drop/override permission can\n"
"replace code with OVERRIDE to drop without a confirmation code."
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
@@ -1882,6 +1895,13 @@ msgstr ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
"replace passcode with a users nick to force validate them."
msgid ""
"Additionally, Services Operators with the nickserv/drop/override permission can\n"
"replace code with OVERRIDE to drop without a confirmation code."
msgstr ""
"Additionally, Services Operators with the nickserv/drop/override permission can\n"
"replace code with OVERRIDE to drop without a confirmation code."
#, c-format
msgid ""
"Additionally, if fantasy is enabled fantasy commands\n"
@@ -3652,8 +3672,8 @@ msgstr "Email for %s is invalid."
msgid "Email matched: %s (%s) to %s."
msgstr "Email matched: %s (%s) to %s."
msgid "Enable fantaisist commands"
msgstr "Enable fantaisist commands"
msgid "Enable fantasy commands"
msgstr "Enable fantasy commands"
msgid "Enable greet messages"
msgstr "Enable greet messages"
@@ -4177,12 +4197,12 @@ msgid "Info about a loaded module"
msgstr "Info about a loaded module"
#, c-format
msgid "Information for bot %s:"
msgstr "Information for bot %s:"
msgid "Information about bot %s:"
msgstr "Information about bot %s:"
#, c-format
msgid "Information for channel %s:"
msgstr "Information for channel %s:"
msgid "Information about channel %s:"
msgstr "Information about channel %s:"
#, c-format
msgid "Invalid duration %s, using %d days."
@@ -5127,6 +5147,9 @@ msgstr "Nick %s is now released."
msgid "Nick %s is now suspended."
msgstr "Nick %s is now suspended."
msgid "Nick registered"
msgstr "Nick registered"
#, c-format
msgid "Nick too long, max length is %zu characters."
msgstr "Nick too long, max length is %zu characters."
@@ -8072,6 +8095,10 @@ msgstr "Used to manage the list of privileged users"
msgid "Used to modify the channel status of you or other users"
msgstr "Used to modify the channel status of you or other users"
#, c-format
msgid "User %s isn't currently logged in to an account."
msgstr "User %s isn't currently logged in to an account."
msgid "User has been banned from the channel"
msgstr "User has been banned from the channel"
File diff suppressed because it is too large Load Diff
+2350 -4599
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+260 -367
View File
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -94,7 +94,9 @@ macro(build_modules SRC)
target_link_libraries(${SO} ${PROGRAM_NAME})
endif()
# Set the module to be installed to the module directory under the data directory
install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules)
install(TARGETS ${SO}
DESTINATION ${MODULE_DIR}
LIBRARY)
endif()
endif()
endforeach()
@@ -168,7 +170,9 @@ macro(build_subdir)
endif()
# Set the module to be installed to the module directory under the data directory
install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules)
install(TARGETS ${SO}
DESTINATION ${MODULE_DIR}
LIBRARY)
endmacro()
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+15 -6
View File
@@ -57,12 +57,20 @@ public:
BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL;
if (bi && Config->GetModule(this)->Get<bool>("smartjoin"))
{
/* We check for bans */
for (const auto &entry : c->GetModeList("BAN"))
if (IRCD->CanClearBans)
{
Entry ban("BAN", entry);
if (ban.Matches(user))
c->RemoveMode(NULL, "BAN", ban.GetMask());
// We can ask the IRCd to clear bans.
IRCD->SendClearBans(bi, c, bi);
}
else
{
// We have to check for bans.
for (const auto &entry : c->GetModeList("BAN"))
{
Entry ban("BAN", entry);
if (ban.Matches(user))
c->RemoveMode(NULL, "BAN", ban.GetMask());
}
}
Anope::string Limit;
@@ -75,7 +83,8 @@ public:
{
ChannelMode *cm = ModeManager::FindChannelModeByName("OP");
char symbol = cm ? anope_dynamic_static_cast<ChannelModeStatus *>(cm)->symbol : 0;
IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, "%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str());
const auto message = Anope::printf("%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str());
IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, message);
}
ModeManager::ProcessModes();
+3 -3
View File
@@ -21,9 +21,9 @@ struct BadWordImpl final
void Serialize(Serialize::Data &data) const override
{
data["ci"] << this->chan;
data["word"] << this->word;
data.SetType("type", Serialize::Data::DT_INT); data["type"] << this->type;
data.Store("ci", this->chan);
data.Store("word", this->word);
data.Store("type", this->type);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &);
+2 -6
View File
@@ -56,7 +56,7 @@ public:
return;
}
IRCD->SendPrivmsg(*ci->bi, ci->name, "%s", text.c_str());
IRCD->SendPrivmsg(*ci->bi, ci->name, text);
ci->bi->lastmsg = Anope::CurTime;
bool override = !source.AccessFor(ci).HasPriv("SAY");
@@ -111,11 +111,7 @@ public:
return;
}
message = message.replace_all_cs("\1", "");
if (message.empty())
return;
IRCD->SendAction(*ci->bi, ci->name, "%s", message.c_str());
IRCD->SendPrivmsg(*ci->bi, ci->name, Anope::FormatCTCP("ACTION", message));
ci->bi->lastmsg = Anope::CurTime;
bool override = !source.AccessFor(ci).HasPriv("SAY");
+1 -1
View File
@@ -50,7 +50,7 @@ public:
if (bi)
{
source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
source.Reply(_("Information about bot \002%s\002:"), bi->nick.c_str());
info[_("Mask")] = bi->GetIdent() + "@" + bi->host;
info[_("Real name")] = bi->realname;
info[_("Created")] = Anope::strftime(bi->created, source.GetAccount());
+23 -23
View File
@@ -53,26 +53,28 @@ struct KickerDataImpl final
if (kd == NULL)
return;
data["kickerdata:amsgs"] << kd->amsgs;
data["kickerdata:badwords"] << kd->badwords;
data["kickerdata:bolds"] << kd->bolds;
data["kickerdata:caps"] << kd->caps;
data["kickerdata:colors"] << kd->colors;
data["kickerdata:flood"] << kd->flood;
data["kickerdata:italics"] << kd->italics;
data["kickerdata:repeat"] << kd->repeat;
data["kickerdata:reverses"] << kd->reverses;
data["kickerdata:underlines"] << kd->underlines;
data.Store("kickerdata:amsgs", kd->amsgs);
data.Store("kickerdata:badwords", kd->badwords);
data.Store("kickerdata:bolds", kd->bolds);
data.Store("kickerdata:caps", kd->caps);
data.Store("kickerdata:colors", kd->colors);
data.Store("kickerdata:flood", kd->flood);
data.Store("kickerdata:italics", kd->italics);
data.Store("kickerdata:repeat", kd->repeat);
data.Store("kickerdata:reverses", kd->reverses);
data.Store("kickerdata:underlines", kd->underlines);
data.Store("capsmin", kd->capsmin);
data.Store("capspercent", kd->capspercent);
data.Store("floodlines", kd->floodlines);
data.Store("floodsecs", kd->floodsecs);
data.Store("repeattimes", kd->repeattimes);
data.Store("dontkickops", kd->dontkickops);
data.Store("dontkickvoices", kd->dontkickvoices);
data.SetType("capsmin", Serialize::Data::DT_INT); data["capsmin"] << kd->capsmin;
data.SetType("capspercent", Serialize::Data::DT_INT); data["capspercent"] << kd->capspercent;
data.SetType("floodlines", Serialize::Data::DT_INT); data["floodlines"] << kd->floodlines;
data.SetType("floodsecs", Serialize::Data::DT_INT); data["floodsecs"] << kd->floodsecs;
data.SetType("repeattimes", Serialize::Data::DT_INT); data["repeattimes"] << kd->repeattimes;
data.SetType("dontkickops", Serialize::Data::DT_INT); data["dontkickops"] << kd->dontkickops;
data.SetType("dontkickvoices", Serialize::Data::DT_INT); data["dontkickvoices"] << kd->dontkickvoices;
std::ostringstream oss;
for (auto ttbtype : kd->ttb)
data["ttb"] << ttbtype << " ";
oss << ttbtype << " ";
data.Store("ttb", oss.str());
}
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
@@ -1216,11 +1218,9 @@ public:
/* If it's a /me, cut the CTCP part because the ACTION will cause
* problems with the caps or badwords kicker
*/
if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
{
realbuf.erase(0, 8);
realbuf.erase(realbuf.length() - 1);
}
Anope::string ctcpname, ctcpbody;
if (Anope::ParseCTCP(msg, ctcpname, ctcpbody) && ctcpname.equals_ci("ACTION"))
realbuf = ctcpbody;
if (realbuf.empty())
return;
+5 -1
View File
@@ -50,7 +50,7 @@ public:
}
auto *code = dropcode.Get(ci);
if (params.size() < 2 || !code || !code->equals_ci(params[1]))
if (params.size() < 2 || ((!code || !code->equals_ci(params[1])) && (!source.HasPriv("chanserv/drop/override") || params[1] != "OVERRIDE")))
{
if (!code)
{
@@ -94,6 +94,10 @@ public:
source.Reply(_("Unregisters the named channel. Can only be used by\n"
"the \002channel founder\002."));
source.Reply(" ");
if (source.HasPriv("chanserv/drop/override"))
source.Reply(_("Additionally, Services Operators with the \037chanserv/drop/override\037 permission can\n"
"replace \037code\037 with \002OVERRIDE\002 to drop without a confirmation code."));
return true;
}
};
+4 -4
View File
@@ -32,10 +32,10 @@ struct EntryMsgImpl final
void Serialize(Serialize::Data &data) const override
{
data["ci"] << this->chan;
data["creator"] << this->creator;
data["message"] << this->message;
data.SetType("when", Serialize::Data::DT_INT); data["when"] << this->when;
data.Store("ci", this->chan);
data.Store("creator", this->creator);
data.Store("message", this->message);
data.Store("when", this->when);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data);
+10 -10
View File
@@ -37,14 +37,14 @@ struct LogSettingImpl final
void Serialize(Serialize::Data &data) const override
{
data["ci"] << chan;
data["service_name"] << service_name;
data["command_service"] << command_service;
data["command_name"] << command_name;
data["method"] << method;
data["extra"] << extra;
data["creator"] << creator;
data.SetType("created", Serialize::Data::DT_INT); data["created"] << created;
data.Store("ci", chan);
data.Store("service_name", service_name);
data.Store("command_service", command_service);
data.Store("command_name", command_name);
data.Store("method", method);
data.Store("extra", extra);
data.Store("creator", creator);
data.Store("created", created);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
@@ -391,11 +391,11 @@ public:
/* Sending a channel message or notice in response to a fantasy command */;
else if (log->method.equals_ci("MESSAGE") && l->ci->c)
{
IRCD->SendPrivmsg(l->ci->WhoSends(), log->extra + l->ci->c->name, "%s", buffer.c_str());
IRCD->SendPrivmsg(l->ci->WhoSends(), log->extra + l->ci->c->name, buffer);
l->ci->WhoSends()->lastmsg = Anope::CurTime;
}
else if (log->method.equals_ci("NOTICE") && l->ci->c)
IRCD->SendNotice(l->ci->WhoSends(), log->extra + l->ci->c->name, "%s", buffer.c_str());
IRCD->SendNotice(l->ci->WhoSends(), log->extra + l->ci->c->name, buffer);
}
}
}
+8 -7
View File
@@ -205,12 +205,12 @@ struct ModeLocksImpl final
void ModeLockImpl::Serialize(Serialize::Data &data) const
{
data["ci"] << this->ci;
data["set"] << this->set;
data["name"] << this->name;
data["param"] << this->param;
data["setter"] << this->setter;
data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
data.Store("ci", this->ci);
data.Store("set", this->set);
data.Store("name", this->name);
data.Store("param", this->param);
data.Store("setter", this->setter);
data.Store("created", this->created);
}
Serializable *ModeLockImpl::Unserialize(Serializable *obj, Serialize::Data &data)
@@ -658,7 +658,8 @@ class CommandCSMode final
}
else
{
for (const auto &mode : ci->c->GetModeList(cm->name))
std::vector<Anope::string> v = ci->c->GetModeList(cm->name);
for (const auto &mode : v)
{
if (Anope::Match(mode, param))
ci->c->RemoveMode(NULL, cm, mode);
+7 -7
View File
@@ -46,13 +46,13 @@ struct SeenInfo final
void Serialize(Serialize::Data &data) const override
{
data["nick"] << nick;
data["vhost"] << vhost;
data["type"] << type;
data["nick2"] << nick2;
data["channel"] << channel;
data["message"] << message;
data.SetType("last", Serialize::Data::DT_INT); data["last"] << last;
data.Store("nick", nick);
data.Store("vhost", vhost);
data.Store("type", type);
data.Store("nick2", nick2);
data.Store("channel", channel);
data.Store("message", message);
data.Store("last", last);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+2 -2
View File
@@ -1068,7 +1068,7 @@ class CSSet final
if (!last_value.empty())
modes += "," + last_value;
}
data["last_modes"] << modes;
data.Store("last_modes", modes);
}
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
@@ -1146,7 +1146,7 @@ public:
if (c->ci && keep_modes.HasExt(c->ci))
{
Channel::ModeList ml = c->ci->last_modes;
for (const auto &[last_mode, last_value] : c->ci->last_modes)
for (const auto &[last_mode, last_value] : ml)
c->SetMode(c->ci->WhoSends(), last_mode, last_value);
}
}
+3 -3
View File
@@ -46,9 +46,9 @@ struct CSMiscData final
void Serialize(Serialize::Data &sdata) const override
{
sdata["ci"] << this->object;
sdata["name"] << this->name;
sdata["data"] << this->data;
sdata.Store("ci", this->object);
sdata.Store("name", this->name);
sdata.Store("data", this->data);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+6 -6
View File
@@ -20,11 +20,11 @@ struct CSSuspendInfo final
void Serialize(Serialize::Data &data) const override
{
data["chan"] << what;
data["by"] << by;
data["reason"] << reason;
data["time"] << when;
data["expires"] << expires;
data.Store("chan", what);
data.Store("by", by);
data.Store("reason", reason);
data.Store("time", when);
data.Store("expires", expires);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
@@ -67,7 +67,7 @@ public:
const Anope::string &chan = params[0];
Anope::string expiry = params[1];
Anope::string reason = params.size() > 2 ? params[2] : "";
time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("expire");
time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire");
if (!expiry.empty() && expiry[0] != '+')
{
+262 -83
View File
@@ -20,6 +20,8 @@
#include "modules/info.h"
#include "modules/ns_cert.h"
#include "modules/os_forbid.h"
#include "modules/os_oper.h"
#include "modules/os_session.h"
#include "modules/suspend.h"
// Handles reading from an Atheme database row.
@@ -83,20 +85,39 @@ public:
struct ModeData final
{
char letter;
Anope::string name;
Anope::string value;
bool set;
ModeData(const Anope::string &n, bool s, const Anope::string &v = "")
: name(n)
: letter(0)
, name(n)
, value(v)
, set(s)
{
}
ModeData(char l, const Anope::string &v = "")
: letter(l)
, value(v)
, set(true)
{
}
Anope::string str() const
{
std::stringstream buf;
buf << '+' << (name.empty() ? letter : name);
if (value.empty())
buf << ' ' << value;
return buf.str();
}
};
struct ChannelData final
{
Anope::unordered_map<AutoKick *> akicks;
Anope::string bot;
Anope::string info_adder;
Anope::string info_message;
@@ -126,6 +147,12 @@ struct UserData final
time_t vhost_ts = 0;
};
namespace
{
// Whether we can safely import clones.
bool import_clones = true;
}
class DBAtheme final
: public Module
{
@@ -133,71 +160,70 @@ private:
ServiceReference<AccessProvider> accessprov;
PrimitiveExtensibleItem<ChannelData> chandata;
std::map<Anope::string, char> flags;
ServiceReference<ForbidService> forbidsvc;
PrimitiveExtensibleItem<UserData> userdata;
ServiceReference<XLineManager> sglinemgr;
ServiceReference<XLineManager> snlinemgr;
ServiceReference<XLineManager> sqlinemgr;
Anope::map<std::function<bool(DBAtheme*,AthemeRow&)>> rowhandlers = {
{ "AC", &DBAtheme::HandleIgnore },
{ "AR", &DBAtheme::HandleIgnore },
{ "BE", &DBAtheme::HandleBE },
{ "BLE", &DBAtheme::HandleIgnore },
{ "BOT", &DBAtheme::HandleBOT },
{ "BOT-COUNT", &DBAtheme::HandleIgnore },
{ "BW", &DBAtheme::HandleBW },
{ "CA", &DBAtheme::HandleCA },
{ "CF", &DBAtheme::HandleIgnore },
{ "CFCHAN", &DBAtheme::HandleIgnore },
{ "CFDBV", &DBAtheme::HandleIgnore },
{ "CFMD", &DBAtheme::HandleIgnore },
{ "CFOP", &DBAtheme::HandleIgnore },
{ "CLONES-CD", &DBAtheme::HandleIgnore },
{ "CLONES-CK", &DBAtheme::HandleIgnore },
{ "CLONES-DBV", &DBAtheme::HandleIgnore },
{ "CLONES-EX", &DBAtheme::HandleIgnore },
{ "CLONES-GR", &DBAtheme::HandleIgnore },
{ "CSREQ", &DBAtheme::HandleIgnore },
{ "CSREQ", &DBAtheme::HandleIgnore },
{ "DBV", &DBAtheme::HandleDBV },
{ "GACL", &DBAtheme::HandleIgnore },
{ "GDBV", &DBAtheme::HandleIgnore },
{ "GE", &DBAtheme::HandleIgnore },
{ "GFA", &DBAtheme::HandleIgnore },
{ "GRP", &DBAtheme::HandleIgnore },
{ "GRVER", &DBAtheme::HandleGRVER },
{ "HE", &DBAtheme::HandleIgnore },
{ "HO", &DBAtheme::HandleIgnore },
{ "HR", &DBAtheme::HandleHR },
{ "JM", &DBAtheme::HandleIgnore },
{ "KID", &DBAtheme::HandleIgnore },
{ "KL", &DBAtheme::HandleKL },
{ "LUID", &DBAtheme::HandleIgnore },
{ "MC", &DBAtheme::HandleMC },
{ "MCFP", &DBAtheme::HandleMCFP },
{ "MDA", &DBAtheme::HandleMDA },
{ "MDC", &DBAtheme::HandleMDC },
{ "MDEP", &DBAtheme::HandleIgnore },
{ "MDG", &DBAtheme::HandleIgnore },
{ "MDN", &DBAtheme::HandleMDN },
{ "MDU", &DBAtheme::HandleMDU },
{ "ME", &DBAtheme::HandleME },
{ "MI", &DBAtheme::HandleMI },
{ "MM", &DBAtheme::HandleMM },
{ "MN", &DBAtheme::HandleMN },
{ "MU", &DBAtheme::HandleMU },
{ "NAM", &DBAtheme::HandleNAM },
{ "QID", &DBAtheme::HandleIgnore },
{ "QL", &DBAtheme::HandleQL },
{ "RM", &DBAtheme::HandleIgnore },
{ "RR", &DBAtheme::HandleIgnore },
{ "RW", &DBAtheme::HandleIgnore },
{ "SI", &DBAtheme::HandleIgnore },
{ "SO", &DBAtheme::HandleIgnore },
{ "TS", &DBAtheme::HandleIgnore },
{ "XID", &DBAtheme::HandleIgnore },
{ "XL", &DBAtheme::HandleXL },
{ "AC", &DBAtheme::HandleIgnore },
{ "AR", &DBAtheme::HandleIgnore },
{ "BE", &DBAtheme::HandleBE },
{ "BLE", &DBAtheme::HandleIgnore },
{ "BOT", &DBAtheme::HandleBOT },
{ "BOT-COUNT", &DBAtheme::HandleIgnore },
{ "BW", &DBAtheme::HandleBW },
{ "CA", &DBAtheme::HandleCA },
{ "CF", &DBAtheme::HandleIgnore },
{ "CFCHAN", &DBAtheme::HandleIgnore },
{ "CFDBV", &DBAtheme::HandleIgnore },
{ "CFMD", &DBAtheme::HandleIgnore },
{ "CFOP", &DBAtheme::HandleIgnore },
{ "CLONES-CD", &DBAtheme::HandleIgnore },
{ "CLONES-CK", &DBAtheme::HandleIgnore },
{ "CLONES-DBV", &DBAtheme::HandleCLONESDBV },
{ "CLONES-EX", &DBAtheme::HandleCLONESEX },
{ "CLONES-GR", &DBAtheme::HandleIgnore },
{ "CSREQ", &DBAtheme::HandleIgnore },
{ "CSREQ", &DBAtheme::HandleIgnore },
{ "DBV", &DBAtheme::HandleDBV },
{ "GACL", &DBAtheme::HandleIgnore },
{ "GDBV", &DBAtheme::HandleIgnore },
{ "GE", &DBAtheme::HandleIgnore },
{ "GFA", &DBAtheme::HandleIgnore },
{ "GRP", &DBAtheme::HandleIgnore },
{ "GRVER", &DBAtheme::HandleGRVER },
{ "HE", &DBAtheme::HandleIgnore },
{ "HO", &DBAtheme::HandleIgnore },
{ "HR", &DBAtheme::HandleHR },
{ "JM", &DBAtheme::HandleIgnore },
{ "KID", &DBAtheme::HandleIgnore },
{ "KL", &DBAtheme::HandleKL },
{ "LUID", &DBAtheme::HandleIgnore },
{ "MC", &DBAtheme::HandleMC },
{ "MCFP", &DBAtheme::HandleMCFP },
{ "MDA", &DBAtheme::HandleMDA },
{ "MDC", &DBAtheme::HandleMDC },
{ "MDEP", &DBAtheme::HandleIgnore },
{ "MDG", &DBAtheme::HandleIgnore },
{ "MDN", &DBAtheme::HandleMDN },
{ "MDU", &DBAtheme::HandleMDU },
{ "ME", &DBAtheme::HandleME },
{ "MI", &DBAtheme::HandleMI },
{ "MM", &DBAtheme::HandleMM },
{ "MN", &DBAtheme::HandleMN },
{ "MU", &DBAtheme::HandleMU },
{ "NAM", &DBAtheme::HandleNAM },
{ "QID", &DBAtheme::HandleIgnore },
{ "QL", &DBAtheme::HandleQL },
{ "RM", &DBAtheme::HandleIgnore },
{ "RR", &DBAtheme::HandleIgnore },
{ "RW", &DBAtheme::HandleIgnore },
{ "SI", &DBAtheme::HandleIgnore },
{ "SO", &DBAtheme::HandleSO },
{ "TS", &DBAtheme::HandleIgnore },
{ "XID", &DBAtheme::HandleIgnore },
{ "XL", &DBAtheme::HandleXL },
};
void ApplyAccess(Anope::string &in, char flag, Anope::string &out, std::initializer_list<const char*> privs)
@@ -403,6 +429,9 @@ private:
return;
}
// We are processing an encrypted password.
flags.erase(pos, 1);
// Atheme supports several password hashing methods. We can only import
// some of them currently.
//
@@ -480,7 +509,7 @@ private:
bool HandleBE(AthemeRow &row)
{
// BE <email <created> <creator> <reason>
// BE <email> <created> <creator> <reason>
auto email = row.Get();
auto created = row.GetNum<time_t>();
auto creator = row.Get();
@@ -489,19 +518,19 @@ private:
if (!row)
return row.LogError(this);
if (!forbidsvc)
if (!forbid_service)
{
Log(this) << "Unable to convert forbidden email " << email << " as os_forbid is not loaded";
return true;
}
auto *forbid = forbidsvc->CreateForbid();
auto *forbid = forbid_service->CreateForbid();
forbid->created = created;
forbid->creator = creator;
forbid->mask = email;
forbid->reason = reason;
forbid->type = FT_EMAIL;
forbidsvc->AddForbid(forbid);
forbid_service->AddForbid(forbid);
return true;
}
@@ -583,10 +612,11 @@ private:
auto *nc = NickCore::Find(mask);
if (flags.find('b') != Anope::string::npos)
{
auto *data = chandata.Require(ci);
if (nc)
ci->AddAkick(setter, nc, "", modifiedtime, modifiedtime);
data->akicks[mask] = ci->AddAkick(setter, nc, "", modifiedtime, modifiedtime);
else
ci->AddAkick(setter, mask, "", modifiedtime, modifiedtime);
data->akicks[mask] = ci->AddAkick(setter, mask, "", modifiedtime, modifiedtime);
return true;
}
@@ -626,15 +656,59 @@ private:
}
if (flags != "+")
Log(this) << "Unable to convert channel access flags " << flags << " for " << ci->name;
Log(this) << "Unable to convert channel access flags " << flags << " for " << mask << " on " << ci->name;
return true;
}
bool HandleCLONESDBV(AthemeRow &row)
{
// CLONES-DBV <version>
auto version = row.GetNum<unsigned>();
if (version != 3)
{
Log(this) << "Clones database is version " << version << " which is not supported!";
import_clones = false;
}
return true;
}
bool HandleCLONESEX(AthemeRow &row)
{
if (!import_clones)
return HandleIgnore(row);
// CLONES-EX <ip> <allowed> <warn> <expires> <reason>
auto ip = row.Get();
auto allowed = row.GetNum<unsigned>();
/* auto warn = */ row.GetNum<unsigned>();
auto expires = row.GetNum<time_t>();
auto reason = row.GetRemaining();
if (!row)
return row.LogError(this);
if (!session_service)
{
Log(this) << "Unable to import session limit for " << ip << " as os_session is not loaded";
return true;
}
auto *exception = session_service->CreateException();
exception->mask = ip;
exception->limit = allowed;
exception->who = "Unknown";
exception->time = Anope::CurTime;
exception->expires = expires;
exception->reason = reason;
session_service->AddException(exception);
return true;
}
bool HandleDBV(AthemeRow &row)
{
// DBV <version>
unsigned version = row.GetNum<unsigned>();
auto version = row.GetNum<unsigned>();
if (version != 12)
{
Log(this) << "Database is version " << version << " which is not supported!";
@@ -646,7 +720,7 @@ private:
bool HandleGRVER(AthemeRow &row)
{
// GRVER <version>
unsigned version = row.GetNum<unsigned>();
auto version = row.GetNum<unsigned>();
if (version != 1)
{
Log(this) << "Database grammar is version " << version << " which is not supported!";
@@ -718,6 +792,12 @@ private:
return true;
}
bool HandleIgnoreMetadata(const Anope::string &target, const Anope::string &key, const Anope::string &value)
{
Log(LOG_DEBUG_3) << "Intentionally ignoring Atheme database metadata for " << target << ": " << key << " = " << value;
return true;
}
bool HandleMC(AthemeRow &row)
{
// MC <channel> <regtime> <used> <flags> <mlock-on> <mlock-off> <mlock-limit> [<mlock-key>]
@@ -822,7 +902,7 @@ private:
bool HandleMDA(AthemeRow &row)
{
// MDA <channel> <account/mask> <key> <value>
auto display = row.Get();
auto channel = row.Get();
auto mask = row.Get();
auto key = row.Get();
auto value = row.GetRemaining();
@@ -830,7 +910,23 @@ private:
if (!row)
return row.LogError(this);
Log(this) << "Unknown channel access metadata " << key << " = " << value;
auto *ci = ChannelInfo::Find(channel);
if (!ci)
{
Log(this) << "Missing ChannelInfo for MDA: " << channel;
return false;
}
if (key == "reason")
{
auto *data = chandata.Require(ci);
auto akick = data->akicks.find(mask);
if (akick != data->akicks.end())
akick->second->reason = value;
}
else
Log(this) << "Unknown channel access metadata for " << mask << " on " << ci->name << ": " << key << " = " << value;
return true;
}
@@ -858,6 +954,8 @@ private:
ci->Extend<bool>("BS_FANTASY");
else if (key == "private:botserv:no-bot")
ci->Extend<bool>("BS_NOBOT");
else if (key == "private:channelts")
return HandleIgnoreMetadata(ci->name, key, value);
else if (key == "private:close:closer")
data->suspend_by = value;
else if (key == "private:close:reason")
@@ -892,29 +990,60 @@ private:
data->info_adder = value;
else if (key == "private:mark:timestamp")
data->info_ts = Anope::Convert<time_t>(value, 0);
else if (key == "private:mlockext")
{
spacesepstream mlocks(value);
for (Anope::string mlock; mlocks.GetToken(mlock); )
data->mlocks.emplace_back(mlock[0], mlock.substr(1));
}
else if (key == "private:templates")
return HandleIgnoreMetadata(ci->name, key, value);
else if (key == "private:topic:setter")
ci->last_topic_setter = value;
else if (key == "private:topic:text")
ci->last_topic = value;
else if (key == "private:topic:ts")
ci->last_topic_time = Anope::Convert<time_t>(value, 0);
else if (key.compare(0, 14, "private:stats:", 14) == 0)
return HandleIgnoreMetadata(ci->name, key, value);
else
Log(this) << "Unknown channel metadata " << key << " = " << value;
Log(this) << "Unknown channel metadata for " << ci->name << ": " << key << " = " << value;
return true;
}
bool HandleMDN(AthemeRow &row)
{
// MDN <display> <key> <value>
auto display = row.Get();
// MDN <nick> <key> <value>
auto nick = row.Get();
auto key = row.Get();
auto value = row.GetRemaining();
if (!row)
return row.LogError(this);
Log(this) << "Unknown nick metadata " << key << " = " << value;
if (!forbid_service)
{
Log(this) << "Unable to convert forbidden nick " << nick << " metadata as os_forbid is not loaded";
return true;
}
auto *forbid = forbid_service->FindForbidExact(nick, FT_NICK);
if (!forbid)
{
Log(this) << "Missing forbid for MDN: " << nick;
return false;
}
if (key == "private:mark:reason")
forbid->reason = value;
else if (key == "private:mark:setter")
forbid->creator = value;
else if (key == "private:mark:timestamp")
forbid->created = Anope::Convert<time_t>(value, 0);
else
Log(this) << "Unknown forbidden nick metadata for " << forbid->mask << ": " << key << " = " << value;
return true;
}
@@ -967,12 +1096,20 @@ private:
data->last_mask = value;
else if (key == "private:lastquit:message")
data->last_quit = value;
else if (key == "private:loginfail:failnum")
return HandleIgnoreMetadata(nc->display, key, value);
else if (key == "private:loginfail:lastfailaddr")
return HandleIgnoreMetadata(nc->display, key, value);
else if (key == "private:loginfail:lastfailtime")
return HandleIgnoreMetadata(nc->display, key, value);
else if (key == "private:mark:reason")
data->info_message = value;
else if (key == "private:mark:setter")
data->info_adder = value;
else if (key == "private:mark:timestamp")
data->info_ts = Anope::Convert<time_t>(value, 0);
else if (key == "private:swhois")
return HandleIgnoreMetadata(nc->display, key, value);
else if (key == "private:usercloak")
data->vhost = value;
else if (key == "private:usercloak-assigner")
@@ -982,7 +1119,7 @@ private:
else if (key.compare(0, 18, "private:usercloak:", 18) == 0)
data->vhost_nick[key.substr(18)] = value;
else
Log(this) << "Unknown account metadata " << key << " = " << value;
Log(this) << "Unknown account metadata for " << nc->display << ": " << key << " = " << value;
return true;
}
@@ -1131,7 +1268,7 @@ private:
auto display = row.Get();
auto pass = row.Get();
auto email = row.Get();
/* auto regtime = */ row.GetNum<time_t>();
auto regtime = row.GetNum<time_t>();
/* auto lastlogin = */ row.Get();
auto flags = row.Get();
auto language = row.Get();
@@ -1141,6 +1278,7 @@ private:
auto *nc = new NickCore(display);
nc->email = email;
nc->time_registered = regtime;
ApplyPassword(nc, flags, pass);
// No equivalent: bglmNQrS
@@ -1199,18 +1337,18 @@ private:
if (!row)
return row.LogError(this);
if (!forbidsvc)
if (!forbid_service)
{
Log(this) << "Unable to convert forbidden nick " << nick << " as os_forbid is not loaded";
return true;
}
auto *forbid = forbidsvc->CreateForbid();
auto *forbid = forbid_service->CreateForbid();
forbid->creator = "Unknown";
forbid->mask = nick;
forbid->reason = "Unknown";
forbid->type = FT_NICK;
forbidsvc->AddForbid(forbid);
forbid_service->AddForbid(forbid);
return true;
}
@@ -1238,6 +1376,43 @@ private:
return true;
}
bool HandleSO(AthemeRow &row)
{
// SO <display> <type> <flags>
auto display = row.Get();
auto type = row.Get();
auto flags = row.Get();
if (!row)
return row.LogError(this);
auto *nc = NickCore::Find(display);
if (!nc)
{
Log(this) << "Missing NickCore for SO: " << display;
return false;
}
auto *ot = OperType::Find(type);
if (!ot)
{
// Attempt to convert oper types.
if (type == "sra")
ot = OperType::Find("Services Root");
else if (type == "ircop")
ot = OperType::Find("Services Operator");
}
if (!ot)
{
Log(this) << "Unable to convert operator status for " << nc->display << " as there is no equivalent oper type: " << type;
return true;
}
nc->o = new MyOper(nc->display, ot);
return true;
}
bool HandleXL(AthemeRow &row)
{
// XL <id> <real> <duration> <settime> <setby> <reason>
@@ -1267,7 +1442,6 @@ public:
: Module(modname, creator, DATABASE | VENDOR)
, accessprov("AccessProvider", "access/flags")
, chandata(this, "ATHEME_CHANDATA")
, forbidsvc("ForbidService", "forbid")
, userdata(this, "ATHEME_USERDATA")
, sglinemgr("XLineManager","xlinemanager/sgline")
, snlinemgr("XLineManager","xlinemanager/snline")
@@ -1416,16 +1590,21 @@ public:
for (const auto &mlock : data->mlocks)
{
auto mh = ModeManager::FindChannelModeByName(mlock.name);
ChannelMode *mh;
if (mlock.name.empty())
mh = ModeManager::FindChannelModeByChar(mlock.letter);
else
mh = ModeManager::FindChannelModeByName(mlock.name);
if (!mh)
{
Log(this) << "Unable to find mode while importing mode lock: " << mlock.name;
Log(this) << "Unable to find mode while importing mode lock on " << ci->name << ": " << mlock.str();
continue;
}
ml->SetMLock(mh, mlock.set, mlock.value, "Unknown");
}
}
Anope::SaveDatabases();
}
};
+2 -8
View File
@@ -71,14 +71,6 @@ public:
return this->ss;
}
std::set<Anope::string> KeySet() const override
{
std::set<Anope::string> keys;
for (const auto &[key, _]: this->data)
keys.insert(key);
return keys;
}
size_t Hash() const override
{
size_t hash = 0;
@@ -311,6 +303,8 @@ public:
for (auto *base : items)
{
Serialize::Type *s_type = base->GetSerializableType();
if (!s_type)
continue;
data.fs = databases[s_type->GetOwner()];
if (!data.fs || !data.fs->is_open())
+5 -10
View File
@@ -252,7 +252,7 @@ static Anope::string GetLevelName(int level)
case 15:
return "NOKICK";
case 16:
return "FANTASIA";
return "FANTASY";
case 17:
return "SAY";
case 18:
@@ -537,24 +537,18 @@ static void LoadNicks()
case LANG_DE:
nc->language = "de_DE.UTF-8";
break;
case LANG_CAT:
nc->language = "ca_ES.UTF-8"; // yes, iso639 defines catalan as CA
break;
case LANG_GR:
nc->language = "el_GR.UTF-8";
break;
case LANG_NL:
nc->language = "nl_NL.UTF-8";
break;
case LANG_RU:
nc->language = "ru_RU.UTF-8";
break;
case LANG_HUN:
nc->language = "hu_HU.UTF-8";
break;
case LANG_PL:
nc->language = "pl_PL.UTF-8";
break;
case LANG_CAT:
case LANG_HUN:
case LANG_RU:
case LANG_EN_US:
case LANG_JA_JIS:
case LANG_JA_EUC:
@@ -1348,6 +1342,7 @@ public:
if (ci->c)
ci->c->CheckModes();
}
Anope::SaveDatabases();
}
};
-8
View File
@@ -34,14 +34,6 @@ public:
return *stream;
}
std::set<Anope::string> KeySet() const override
{
std::set<Anope::string> keys;
for (const auto &[key, _] : this->data)
keys.insert(key);
return keys;
}
size_t Hash() const override
{
size_t hash = 0;
+1 -1
View File
@@ -37,7 +37,7 @@ private:
}
else
{
if (Anope::CurTime - Config->GetBlock("options")->Get<time_t>("updatetimeout", "5m") > lastwarn)
if (Anope::CurTime - Config->GetBlock("options")->Get<time_t>("updatetimeout", "2m") > lastwarn)
{
Log() << "Unable to locate SQL reference, going to readonly...";
Anope::ReadOnly = this->ro = true;
+68 -24
View File
@@ -121,6 +121,7 @@ class MySQLService final
Anope::string user;
Anope::string password;
unsigned int port;
Anope::string socket;
MYSQL *sql = nullptr;
@@ -136,7 +137,7 @@ public:
*/
std::mutex Lock;
MySQLService(Module *o, const Anope::string &n, const Anope::string &d, const Anope::string &s, const Anope::string &u, const Anope::string &p, unsigned int po);
MySQLService(Module *o, const Anope::string &n, const Anope::string &d, const Anope::string &s, const Anope::string &u, const Anope::string &p, unsigned int po, const Anope::string &so);
~MySQLService();
@@ -157,6 +158,29 @@ public:
Anope::string BuildQuery(const Query &q);
Anope::string FromUnixtime(time_t) override;
Anope::string GetColumnType(Serialize::DataType dt)
{
switch (dt)
{
case Serialize::DataType::BOOL:
return "TINYINT NOT NULL";
case Serialize::DataType::FLOAT:
return "DOUBLE PRECISION NOT NULL";
case Serialize::DataType::INT:
return "BIGINT NOT NULL";
case Serialize::DataType::TEXT:
return "TEXT";
case Serialize::DataType::UINT:
return "BIGINT UNSIGNED NOT NULL";
}
return "TEXT"; // Should never be reached
}
};
/** The SQL thread used to execute queries
@@ -248,13 +272,14 @@ public:
const Anope::string &user = block->Get<const Anope::string>("username", "anope");
const Anope::string &password = block->Get<const Anope::string>("password");
unsigned int port = block->Get<unsigned int>("port", "3306");
const Anope::string &socket = block->Get<const Anope::string>("socket");
try
{
auto *ss = new MySQLService(this, connname, database, server, user, password, port);
auto *ss = new MySQLService(this, connname, database, server, user, password, port, socket);
this->MySQLServices.emplace(connname, ss);
Log(LOG_NORMAL, "mysql") << "MySQL: Successfully connected to server " << connname << " (" << server << ")";
Log(LOG_NORMAL, "mysql") << "MySQL: Successfully connected to server " << connname << " (" << (socket.empty() ? server + ":" + port : socket) << ")";
}
catch (const SQL::Exception &ex)
{
@@ -309,13 +334,14 @@ public:
}
};
MySQLService::MySQLService(Module *o, const Anope::string &n, const Anope::string &d, const Anope::string &s, const Anope::string &u, const Anope::string &p, unsigned int po)
MySQLService::MySQLService(Module *o, const Anope::string &n, const Anope::string &d, const Anope::string &s, const Anope::string &u, const Anope::string &p, unsigned int po, const Anope::string &so)
: Provider(o, n)
, database(d)
, server(s)
, user(u)
, password(p)
, port(po)
, socket(so)
{
Connect();
}
@@ -354,9 +380,14 @@ Result MySQLService::RunQuery(const Query &query)
{
this->Lock.lock();
Anope::string real_query = this->BuildQuery(query);
if (!this->CheckConnection())
{
this->Lock.unlock();
return MySQLResult(query, query.query, mysql_error(this->sql));
}
if (this->CheckConnection() && !mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
Anope::string real_query = this->BuildQuery(query);
if (!mysql_real_query(this->sql, real_query.c_str(), real_query.length()))
{
MYSQL_RES *res = mysql_store_result(this->sql);
unsigned int id = mysql_insert_id(this->sql);
@@ -402,19 +433,15 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D
if (known_cols.empty())
{
Anope::string query_text = "CREATE TABLE `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
Anope::string query_text = "CREATE TABLE `" + table + "` (`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,"
" `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
for (const auto &[column, _] : data.data)
{
known_cols.insert(column);
query_text += ", `" + column + "` ";
if (data.GetType(column) == Serialize::Data::DT_INT)
query_text += "int(11)";
else
query_text += "text";
query_text += ", `" + column + "` " + GetColumnType(data.GetType(column));
}
query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))";
query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`)) ROW_FORMAT=DYNAMIC";
queries.push_back(query_text);
}
else
@@ -426,11 +453,7 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D
known_cols.insert(column);
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + column + "` ";
if (data.GetType(column) == Serialize::Data::DT_INT)
query_text += "int(11)";
else
query_text += "text";
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + column + "` " + GetColumnType(data.GetType(column));
queries.push_back(query_text);
}
@@ -466,11 +489,29 @@ Query MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Dat
Anope::string buf;
*value >> buf;
bool escape = true;
if (buf.empty())
auto escape = true;
switch (data.GetType(field))
{
buf = "NULL";
escape = false;
case Serialize::DataType::BOOL:
case Serialize::DataType::FLOAT:
case Serialize::DataType::INT:
case Serialize::DataType::UINT:
{
if (buf.empty())
buf = "0";
escape = false;
break;
}
case Serialize::DataType::TEXT:
{
if (buf.empty())
{
buf = "NULL";
escape = false;
}
break;
}
}
query.SetValue(field, buf, escape);
@@ -491,12 +532,15 @@ void MySQLService::Connect()
const unsigned int timeout = 1;
mysql_options(this->sql, MYSQL_OPT_CONNECT_TIMEOUT, reinterpret_cast<const char *>(&timeout));
bool connect = mysql_real_connect(this->sql, this->server.c_str(), this->user.c_str(), this->password.c_str(), this->database.c_str(), this->port, NULL, CLIENT_MULTI_RESULTS);
bool connect = mysql_real_connect(this->sql, this->server.c_str(), this->user.c_str(), this->password.c_str(), this->database.c_str(), this->port, this->socket.empty() ? nullptr : this->socket.c_str(), CLIENT_MULTI_RESULTS);
if (!connect)
throw SQL::Exception("Unable to connect to MySQL service " + this->name + ": " + mysql_error(this->sql));
Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->server << ":" << this->port;
if (this->socket.empty())
Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->server << ":" << this->port;
else
Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->socket;
}
+54 -11
View File
@@ -68,6 +68,31 @@ public:
Anope::string BuildQuery(const Query &q);
Anope::string FromUnixtime(time_t) override;
Anope::string GetColumnType(Serialize::DataType dt)
{
switch (dt)
{
case Serialize::DataType::BOOL:
return "INTEGER";
case Serialize::DataType::FLOAT:
return "REAL";
case Serialize::DataType::INT:
return "INTEGER";
case Serialize::DataType::TEXT:
return "TEXT";
// SQLite lacks support for 64-bit unsigned integers so we have to
// store them as text columns instead.
case Serialize::DataType::UINT:
return "TEXT";
}
return "TEXT"; // Should never be reached
}
};
class ModuleSQLite final
@@ -237,11 +262,7 @@ std::vector<Query> SQLiteService::CreateTable(const Anope::string &table, const
{
known_cols.insert(column);
query_text += ", `" + column + "` ";
if (data.GetType(column) == Serialize::Data::DT_INT)
query_text += "int(11)";
else
query_text += "text";
query_text += ", `" + column + "` " + GetColumnType(data.GetType(column));
}
query_text += ")";
@@ -266,11 +287,7 @@ std::vector<Query> SQLiteService::CreateTable(const Anope::string &table, const
known_cols.insert(column);
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + column + "` ";
if (data.GetType(column) == Serialize::Data::DT_INT)
query_text += "int(11)";
else
query_text += "text";
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + column + "` " + GetColumnType(data.GetType(column));;
queries.push_back(query_text);
}
@@ -307,7 +324,33 @@ Query SQLiteService::BuildInsert(const Anope::string &table, unsigned int id, Da
{
Anope::string buf;
*value >> buf;
query.SetValue(field, buf);
auto escape = true;
switch (data.GetType(field))
{
case Serialize::DataType::BOOL:
case Serialize::DataType::FLOAT:
case Serialize::DataType::INT:
{
if (buf.empty())
buf = "0";
escape = false;
break;
}
case Serialize::DataType::TEXT:
case Serialize::DataType::UINT:
{
if (buf.empty())
{
buf = "NULL";
escape = false;
}
break;
}
}
query.SetValue(field, buf, escape);
}
return query;
+7 -7
View File
@@ -17,7 +17,7 @@ class CommandBSSetFantasy final
public:
CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2)
{
this->SetDesc(_("Enable fantaisist commands"));
this->SetDesc(_("Enable fantasy commands"));
this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
}
@@ -73,9 +73,9 @@ public:
"fantasy commands on a channel when prefixed\n"
"with one of the following fantasy characters: \002%s\002\n"
" \n"
"Note that users wanting to use fantaisist\n"
"commands MUST have enough access for both\n"
"the FANTASIA and the command they are executing."),
"Note that users wanting to use fantasy commands\n"
"MUST have enough access for both the FANTASY\n"
"privilege and the command they are executing."),
Config->GetModule(this->owner)->Get<const Anope::string>("fantasycharacter", "!").c_str());
return true;
}
@@ -186,10 +186,10 @@ public:
source.permission = info.permission;
AccessGroup ag = c->ci->AccessFor(u);
bool has_fantasia = ag.HasPriv("FANTASIA") || source.HasPriv("botserv/fantasy");
bool has_fantasy = ag.HasPriv("FANTASY") || source.HasPriv("botserv/fantasy");
EventReturn MOD_RESULT;
if (has_fantasia)
if (has_fantasy)
{
FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params));
}
@@ -198,7 +198,7 @@ public:
FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params));
}
if (MOD_RESULT == EVENT_STOP || !has_fantasia)
if (MOD_RESULT == EVENT_STOP || !has_fantasy)
return;
if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission))
+1 -1
View File
@@ -29,7 +29,7 @@ private:
public:
CommandGLGlobal(Module *creator)
: Command(creator, "global/global", 0)
: Command(creator, "global/global", 0, 1)
, global("GlobalService", "Global")
{
this->SetDesc(_("Send a message to all users"));
+1 -1
View File
@@ -29,7 +29,7 @@ private:
public:
CommandGLServer(Module *creator)
: Command(creator, "global/server", 1)
: Command(creator, "global/server", 1, 2)
, global("GlobalService", "Global")
{
this->SetDesc(_("Send a message to all users on a server"));
+2 -5
View File
@@ -137,9 +137,6 @@ public:
if (!sender)
return false;
if (!server)
server = Servers::GetUplink();
Anope::string line;
if (source && !Config->GetModule(this)->Get<bool>("anonymousglobal"))
{
@@ -153,9 +150,9 @@ public:
}
if (server)
this->ServerGlobal(sender, Servers::GetUplink(), true, line);
else
this->ServerGlobal(sender, server, false, line);
else
this->ServerGlobal(sender, Servers::GetUplink(), true, line);
return true;
}
+2 -1
View File
@@ -198,7 +198,8 @@ public:
Anope::string *greet = ns_greet.Get(user->Account());
if (bs_greet.HasExt(c->ci) && greet != NULL && !greet->empty() && c->FindUser(c->ci->bi) && c->ci->AccessFor(user).HasPriv("GREET"))
{
IRCD->SendPrivmsg(*c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), greet->c_str());
const auto message = Anope::printf("[%s] %s", user->Account()->display.c_str(), greet->c_str());
IRCD->SendPrivmsg(*c->ci->bi, c->name, message);
c->ci->bi->lastmsg = Anope::CurTime;
}
}
+1 -1
View File
@@ -43,7 +43,7 @@ public:
const NickAlias *na = NickAlias::Find(u->nick);
if (!na || na->nc != u->Account() || !na->HasVHost())
na = NickAlias::Find(u->Account()->display);
na = u->AccountNick();
if (!na || !na->HasVHost())
return;
+1 -1
View File
@@ -27,7 +27,7 @@ public:
const NickAlias *na = NickAlias::Find(u->nick);
if (!na || na->nc != u->Account() || !na->HasVHost())
na = NickAlias::Find(u->Account()->display);
na = u->AccountNick();
if (!na || !na->HasVHost())
source.Reply(HOST_NOT_ASSIGNED);
+1 -1
View File
@@ -29,7 +29,7 @@ public:
User *u = source.GetUser();
const NickAlias *na = NickAlias::Find(u->nick);
if (!na || na->nc != u->Account() || !na->HasVHost())
na = NickAlias::Find(u->Account()->display);
na = u->AccountNick();
if (na && u->Account() == na->nc && na->HasVHost())
{
source.Reply(_("Your vhost of \002%s\002 is now activated."), na->GetVHostMask().c_str());
+4 -4
View File
@@ -32,10 +32,10 @@ struct HostRequestImpl final
void Serialize(Serialize::Data &data) const override
{
data["nick"] << this->nick;
data["ident"] << this->ident;
data["host"] << this->host;
data.SetType("time", Serialize::Data::DT_INT); data["time"] << this->time;
data.Store("nick", this->nick);
data.Store("ident", this->ident);
data.Store("host", this->host);
data.Store("time", this->time);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+19 -20
View File
@@ -117,7 +117,7 @@ void IRC2SQL::OnUserConnect(User *u, bool &exempt)
this->RunQuery(query);
if (ctcpuser && (Me->IsSynced() || ctcpeob) && u->server != Me)
IRCD->SendPrivmsg(StatServ, u->GetUID(), "\1VERSION\1");
IRCD->SendPrivmsg(StatServ, u->GetUID(), Anope::FormatCTCP("VERSION"));
}
@@ -299,28 +299,27 @@ void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user
void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message, const Anope::map<Anope::string> &tags)
{
Anope::string versionstr;
if (bi != StatServ)
return;
if (message[0] == '\1' && message[message.length() - 1] == '\1')
{
if (message.substr(0, 9).equals_ci("\1VERSION "))
{
if (u->HasExt("CTCPVERSION"))
return;
u->Extend<bool>("CTCPVERSION");
versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10));
if (versionstr.empty())
return;
query = "UPDATE `" + prefix + "user` "
"SET version=@version@ "
"WHERE nick=@nick@";
query.SetValue("version", versionstr);
query.SetValue("nick", u->nick);
this->RunQuery(query);
}
}
Anope::string ctcpname, ctcpbody;
if (!Anope::ParseCTCP(message, ctcpname, ctcpbody) || ctcpname != "VERSION")
return;
if (u->HasExt("CTCPVERSION"))
return;
u->Extend<bool>("CTCPVERSION");
auto versionstr = Anope::NormalizeBuffer(message.substr(9, message.length() - 10));
if (versionstr.empty())
return;
query = "UPDATE `" + prefix + "user` "
"SET version=@version@ "
"WHERE nick=@nick@";
query.SetValue("version", versionstr);
query.SetValue("nick", u->nick);
this->RunQuery(query);
}
MODULE_INIT(IRC2SQL)
+1 -1
View File
@@ -20,7 +20,7 @@ class MemoServCore final
static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
{
Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_subject").c_str()),
message = Language::Translate(Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str());
message = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str());
subject = subject.replace_all_cs("%n", nc->display);
subject = subject.replace_all_cs("%s", m->sender);
+3
View File
@@ -536,6 +536,9 @@ public:
if (nickserv_expire && Anope::CurTime - na->last_seen >= nickserv_expire)
expire = true;
if (na->nc->na == na && na->nc->aliases->size() > 1 && Config->GetModule("nickserv")->Get<bool>("preservedisplay"))
expire = false;
FOREACH_MOD(OnPreNickExpire, (na, expire));
if (expire)
+4 -4
View File
@@ -40,14 +40,14 @@ struct AJoinEntry final
}
}
void Serialize(Serialize::Data &sd) const override
void Serialize(Serialize::Data &data) const override
{
if (!this->owner)
return;
sd["owner"] << this->owner->display;
sd["channel"] << this->channel;
sd["key"] << this->key;
data.Store("owner", this->owner->display);
data.Store("channel", this->channel);
data.Store("key", this->key);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &sd)
+31 -1
View File
@@ -26,6 +26,17 @@ struct CertServiceImpl final
return it->second;
return NULL;
}
void ReplaceCert(const Anope::string &oldcert, const Anope::string &newcert) override
{
auto *nc = FindAccountFromCert(oldcert);
if (!nc)
return;
auto *cl = nc->GetExt<NSCertList>("certificates");
if (cl)
cl->ReplaceCert(oldcert, newcert);
}
};
struct NSCertListImpl final
@@ -111,6 +122,14 @@ public:
FOREACH_MOD(OnNickEraseCert, (this->nc, oldentry));
certmap.erase(oldentry);
if (std::find(this->certs.begin(), this->certs.end(), newentry) != this->certs.end())
{
// The cert we're upgrading to already exists.
this->certs.erase(it);
return;
}
*it = newentry;
certmap[newentry] = nc;
FOREACH_MOD(OnNickAddCert, (this->nc, newentry));
@@ -149,8 +168,10 @@ public:
if (c == NULL || !c->GetCertCount())
return;
std::ostringstream oss;
for (unsigned i = 0; i < c->GetCertCount(); ++i)
data["cert"] << c->GetCert(i) << " ";
oss << c->GetCert(i) << " ";
data.Store("cert", oss.str());
}
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
@@ -397,6 +418,15 @@ public:
Log(NickServ) << u->GetMask() << " automatically identified for account " << nc->display << " via SSL certificate fingerprint";
}
void OnNickRegister(User *u, NickAlias *na, const Anope::string &pass) override
{
if (!Config->GetModule(this)->Get<bool>("automatic", "yes") || !u || u->fingerprint.empty())
return;
auto *cl = certs.Require(na->nc);
cl->AddCert(u->fingerprint);
}
EventReturn OnNickValidate(User *u, NickAlias *na) override
{
NSCertList *cl = certs.Get(na->nc);
+13 -1
View File
@@ -57,8 +57,14 @@ public:
return;
}
if (na->nc->na == na && na->nc->aliases->size() > 1 && Config->GetModule("nickserv")->Get<bool>("preservedisplay") && !source.HasPriv("nickserv/drop/display"))
{
source.Reply(_("You may not drop \002%s\002 as it is the display nick for the account."), na->nick.c_str());
return;
}
auto *code = dropcode.Get(na);
if (params.size() < 2 || !code || !code->equals_ci(params[1]))
if (params.size() < 2 || ((!code || !code->equals_ci(params[1])) && (!source.HasPriv("nickserv/drop/override") || params[1] != "OVERRIDE")))
{
if (!code)
{
@@ -87,11 +93,17 @@ public:
"is dropped you may lose all of your access and channels that\n"
"you may own. Any other user will be able to gain control of\n"
"this nick."));
source.Reply(" ");
if (!source.HasPriv("nickserv/drop"))
source.Reply(_("You may drop any nick within your group."));
else
source.Reply(_("As a Services Operator, you may drop any nick."));
source.Reply(" ");
if (source.HasPriv("nickserv/drop/override"))
source.Reply(_("Additionally, Services Operators with the \037nickserv/drop/override\037 permission can\n"
"replace \037code\037 with \002OVERRIDE\002 to drop without a confirmation code."));
return true;
}
};
+11 -7
View File
@@ -15,11 +15,12 @@
#include "module.h"
class CommandNSGetEMail final
class CommandNSGetEmail final
: public Command
{
public:
CommandNSGetEMail(Module *creator) : Command(creator, "nickserv/getemail", 1, 1)
CommandNSGetEmail(Module *creator)
: Command(creator, "nickserv/getemail", 1, 1)
{
this->SetDesc(_("Matches and returns all users that registered using given email"));
this->SetSyntax(_("\037email\037"));
@@ -59,16 +60,19 @@ public:
}
};
class NSGetEMail final
class NSGetEmail final
: public Module
{
CommandNSGetEMail commandnsgetemail;
private:
CommandNSGetEmail commandnsgetemail;
public:
NSGetEMail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnsgetemail(this)
NSGetEmail(const Anope::string &modname, const Anope::string &creator)
: Module(modname, creator, VENDOR)
, commandnsgetemail(this)
{
}
};
MODULE_INIT(NSGetEMail)
MODULE_INIT(NSGetEmail)
+31 -2
View File
@@ -24,8 +24,35 @@ public:
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
Anope::string nick;
if (params.empty())
{
// Use the display of the source if logged in; otherwise, use their nick.
nick = source.nc ? source.nc->na->nick : source.GetNick();
}
else if (params[0][0] == '=' && params[0].length() > 1)
{
// Look up the account of the specified user.
nick = params[0].substr(1);
auto *u = User::Find(nick);
if (!u)
{
source.Reply(NICK_X_NOT_IN_USE, nick.c_str());
return;
}
if (!u->AccountNick())
{
source.Reply(_("User \002%s\002 isn't currently logged in to an account."), nick.c_str());
return;
}
nick = u->AccountNick()->nick;
}
else
{
// Just use the nick the user specified.
nick = params[0];
}
const Anope::string &nick = params.size() ? params[0] : (source.nc ? source.nc->display : source.GetNick());
NickAlias *na = NickAlias::Find(nick);
bool has_auspex = source.HasPriv("nickserv/auspex");
@@ -62,6 +89,7 @@ public:
InfoFormatter info(source.nc);
info[_("Account")] = na->nc->display;
info[_("Account id")] = Anope::ToString(na->nc->GetId());
if (nick_online)
{
bool shown = false;
@@ -88,7 +116,8 @@ public:
info[_("Last seen address")] = na->last_realhost;
}
info[_("Registered")] = Anope::strftime(na->time_registered, source.GetAccount());
info[_("Account registered")] = Anope::strftime(na->nc->time_registered, source.GetAccount());
info[_("Nick registered")] = Anope::strftime(na->time_registered, source.GetAccount());
if (!nick_online)
info[_("Last seen")] = Anope::strftime(na->last_seen, source.GetAccount());
+1 -1
View File
@@ -401,7 +401,7 @@ public:
u->SendMessage(NickServ, _("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
else
u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you."));
const NickAlias *this_na = NickAlias::Find(u->Account()->display);
const NickAlias *this_na = u->AccountNick();
time_t time_registered = Anope::CurTime - this_na->time_registered;
time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
if (unconfirmed_expire > time_registered)
+3 -120
View File
@@ -892,120 +892,6 @@ public:
}
};
class CommandNSSetLanguage
: public Command
{
public:
CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1) : Command(creator, sname, min, min + 1)
{
this->SetDesc(_("Set the language services will use when messaging you"));
this->SetSyntax(_("\037language\037"));
}
void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
{
if (Anope::ReadOnly)
{
source.Reply(READ_ONLY_MODE);
return;
}
const NickAlias *na = NickAlias::Find(user);
if (!na)
{
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
return;
}
NickCore *nc = na->nc;
EventReturn MOD_RESULT;
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
if (MOD_RESULT == EVENT_STOP)
return;
if (param != "en_US")
for (unsigned j = 0; j < Language::Languages.size(); ++j)
{
if (Language::Languages[j] == param)
break;
else if (j + 1 == Language::Languages.size())
{
this->OnSyntaxError(source, "");
return;
}
}
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the language of " << nc->display << " to " << param;
nc->language = param;
if (source.GetAccount() == nc)
source.Reply(_("Language changed to \002English\002."));
else
source.Reply(_("Language for \002%s\002 changed to \002%s\002."), nc->display.c_str(), Language::Translate(param.c_str(), _("English")));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &param) override
{
this->Run(source, source.nc->display, param[0]);
}
bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Changes the language services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
"\037language\037 should be chosen from the following list of\n"
"supported languages:"));
source.Reply(" en_US (English)");
for (const auto &language : Language::Languages)
{
const Anope::string &langname = Language::Translate(language.c_str(), _("English"));
if (langname == "English")
continue;
source.Reply(" %s (%s)", language.c_str(), langname.c_str());
}
return true;
}
};
class CommandNSSASetLanguage final
: public CommandNSSetLanguage
{
public:
CommandNSSASetLanguage(Module *creator) : CommandNSSetLanguage(creator, "nickserv/saset/language", 2)
{
this->ClearSyntax();
this->SetSyntax(_("\037nickname\037 \037language\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
this->Run(source, params[0], params[1]);
}
bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Changes the language services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
"\037language\037 should be chosen from the following list of\n"
"supported languages:"));
source.Reply(" en (English)");
for (const auto &language : Language::Languages)
{
const Anope::string &langname = Language::Translate(language.c_str(), _("English"));
if (langname == "English")
continue;
source.Reply(" %s (%s)", language.c_str(), langname.c_str());
}
return true;
}
};
class CommandNSSetMessage
: public Command
{
@@ -1189,9 +1075,6 @@ class NSSet final
CommandNSSetKill commandnssetkill;
CommandNSSASetKill commandnssasetkill;
CommandNSSetLanguage commandnssetlanguage;
CommandNSSASetLanguage commandnssasetlanguage;
CommandNSSetMessage commandnssetmessage;
CommandNSSASetMessage commandnssasetmessage;
@@ -1225,7 +1108,7 @@ class NSSet final
if (!last_value.empty())
modes += "," + last_value;
}
data["last_modes"] << modes;
data.Store("last_modes", modes);
}
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
@@ -1262,7 +1145,6 @@ public:
commandnssetemail(this), commandnssasetemail(this),
commandnssetkeepmodes(this), commandnssasetkeepmodes(this),
commandnssetkill(this), commandnssasetkill(this),
commandnssetlanguage(this), commandnssasetlanguage(this),
commandnssetmessage(this), commandnssasetmessage(this),
commandnssetpassword(this), commandnssasetpassword(this),
commandnssasetnoexpire(this),
@@ -1354,7 +1236,8 @@ public:
{
if (keep_modes.HasExt(u->Account()))
{
for (const auto &[last_mode, last_value] : u->Account()->last_modes)
User::ModeList modes = u->Account()->last_modes;
for (const auto &[last_mode, last_value] : modes)
{
UserMode *um = ModeManager::FindUserModeByName(last_mode);
/* if the null user can set the mode, then it's probably safe */
+149
View File
@@ -0,0 +1,149 @@
/* NickServ core functions
*
* (C) 2003-2024 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
#include "module.h"
class CommandNSSetLanguage
: public Command
{
public:
CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1)
: Command(creator, sname, min, min + 1)
{
this->SetDesc(_("Set the language services will use when messaging you"));
this->SetSyntax(_("\037language\037"));
}
void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
{
if (Anope::ReadOnly)
{
source.Reply(READ_ONLY_MODE);
return;
}
const NickAlias *na = NickAlias::Find(user);
if (!na)
{
source.Reply(NICK_X_NOT_REGISTERED, user.c_str());
return;
}
NickCore *nc = na->nc;
EventReturn MOD_RESULT;
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
if (MOD_RESULT == EVENT_STOP)
return;
if (param != "en_US")
{
for (unsigned j = 0; j < Language::Languages.size(); ++j)
{
if (Language::Languages[j] == param)
break;
else if (j + 1 == Language::Languages.size())
{
this->OnSyntaxError(source, "");
return;
}
}
}
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change the language of " << nc->display << " to " << param;
nc->language = param;
if (source.GetAccount() == nc)
source.Reply(_("Language changed to \002English\002."));
else
source.Reply(_("Language for \002%s\002 changed to \002%s\002."), nc->display.c_str(), Language::Translate(param.c_str(), _("English")));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &param) override
{
this->Run(source, source.nc->display, param[0]);
}
bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Changes the language services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
"\037language\037 should be chosen from the following list of\n"
"supported languages:"));
source.Reply(" en_US (English)");
for (const auto &language : Language::Languages)
{
const Anope::string &langname = Language::Translate(language.c_str(), _("English"));
if (langname != "English")
source.Reply(" %s (%s)", language.c_str(), langname.c_str());
}
return true;
}
};
class CommandNSSASetLanguage final
: public CommandNSSetLanguage
{
public:
CommandNSSASetLanguage(Module *creator)
: CommandNSSetLanguage(creator, "nickserv/saset/language", 2)
{
this->ClearSyntax();
this->SetSyntax(_("\037nickname\037 \037language\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params) override
{
this->Run(source, params[0], params[1]);
}
bool OnHelp(CommandSource &source, const Anope::string &) override
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Changes the language services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
"\037language\037 should be chosen from the following list of\n"
"supported languages:"));
source.Reply(" en_US (English)");
for (const auto &language : Language::Languages)
{
const Anope::string &langname = Language::Translate(language.c_str(), _("English"));
if (langname != "English")
source.Reply(" %s (%s)", language.c_str(), langname.c_str());
}
return true;
}
};
class NSSetLanguage final
: public Module
{
private:
CommandNSSetLanguage commandnssetlanguage;
CommandNSSASetLanguage commandnssasetlanguage;
public:
NSSetLanguage(const Anope::string &modname, const Anope::string &creator)
: Module(modname, creator, VENDOR)
, commandnssetlanguage(this)
, commandnssasetlanguage(this)
{
#ifndef HAVE_LOCALIZATION
throw ModuleException("Anope was not built with localization support");
#endif
}
};
MODULE_INIT(NSSetLanguage)
+3 -3
View File
@@ -46,9 +46,9 @@ struct NSMiscData final
void Serialize(Serialize::Data &sdata) const override
{
sdata["nc"] << this->object;
sdata["name"] << this->name;
sdata["data"] << this->data;
sdata.Store("nc", this->object);
sdata.Store("name", this->name);
sdata.Store("data", this->data);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+7 -5
View File
@@ -22,11 +22,11 @@ struct NSSuspendInfo final
void Serialize(Serialize::Data &data) const override
{
data["nick"] << what;
data["by"] << by;
data["reason"] << reason;
data["time"] << when;
data["expires"] << expires;
data.Store("nick", what);
data.Store("by", by);
data.Store("reason", reason);
data.Store("time", when);
data.Store("expires", expires);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
@@ -128,6 +128,8 @@ public:
User *u2 = User::Find(na2->nick, true);
if (u2)
{
IRCD->SendLogout(u2);
u2->RemoveMode(source.service, "REGISTERED");
u2->Logout();
if (nickserv)
nickserv->Collide(u2, na2);
+3
View File
@@ -188,7 +188,10 @@ private:
}
if (!akills->CanAdd(source, mask, expires, reason))
{
delete x;
return;
}
EventReturn MOD_RESULT;
FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, akills));
+7 -7
View File
@@ -39,10 +39,10 @@ struct DNSZone final
void Serialize(Serialize::Data &data) const override
{
data["name"] << name;
data.Store("name", name);
unsigned count = 0;
for (const auto &server : servers)
data["server" + Anope::ToString(count++)] << server;
data.Store("server" + Anope::ToString(count++), server);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
@@ -144,14 +144,14 @@ public:
void Serialize(Serialize::Data &data) const override
{
data["server_name"] << server_name;
data.Store("server_name", server_name);
for (unsigned i = 0; i < ips.size(); ++i)
data["ip" + Anope::ToString(i)] << ips[i];
data["limit"] << limit;
data["pooled"] << pooled;
data.Store("ip" + Anope::ToString(i), ips[i]);
data.Store("limit", limit);
data.Store("pooled", pooled);
unsigned count = 0;
for (const auto &zone : zones)
data["zone" + Anope::ToString(count++)] << zone;
data.Store("zone" + Anope::ToString(count++), zone);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+7 -7
View File
@@ -25,12 +25,12 @@ struct ForbidDataImpl final
void ForbidDataImpl::Serialize(Serialize::Data &data) const
{
data["mask"] << this->mask;
data["creator"] << this->creator;
data["reason"] << this->reason;
data["created"] << this->created;
data["expires"] << this->expires;
data["type"] << this->type;
data.Store("mask", this->mask);
data.Store("creator", this->creator);
data.Store("reason", this->reason);
data.Store("created", this->created);
data.Store("expires", this->expires);
data.Store("type", this->type);
}
Serializable *ForbidDataImpl::Unserialize(Serializable *obj, Serialize::Data &data)
@@ -532,7 +532,7 @@ public:
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) override
{
if (command->name == "nickserv/info" && params.size() > 0)
if (command->name == "nickserv/info" && !params.empty() && params[0][0] != '=')
{
ForbidData *d = this->forbidService.FindForbid(params[0], FT_NICK);
if (d != NULL)
+4 -4
View File
@@ -30,10 +30,10 @@ IgnoreDataImpl::~IgnoreDataImpl()
void IgnoreDataImpl::Serialize(Serialize::Data &data) const
{
data["mask"] << this->mask;
data["creator"] << this->creator;
data["reason"] << this->reason;
data["time"] << this->time;
data.Store("mask", this->mask);
data.Store("creator", this->creator);
data.Store("reason", this->reason);
data.Store("time", this->time);
}
Serializable *IgnoreDataImpl::Unserialize(Serializable *obj, Serialize::Data &data)
+4 -4
View File
@@ -28,10 +28,10 @@ struct OperInfoImpl final
void Serialize(Serialize::Data &data) const override
{
data["target"] << target;
data["info"] << info;
data["adder"] << adder;
data["created"] << created;
data.Store("target", target);
data.Store("info", info);
data.Store("adder", adder);
data.Store("created", created);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data);
+4 -4
View File
@@ -69,10 +69,10 @@ struct MyNewsItem final
{
void Serialize(Serialize::Data &data) const override
{
data["type"] << this->type;
data["text"] << this->text;
data["who"] << this->who;
data["time"] << this->time;
data.Store("type", this->type);
data.Store("text", this->text);
data.Store("who", this->who);
data.Store("time", this->time);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+2 -1
View File
@@ -82,7 +82,8 @@ public:
OSNOOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandosnoop(this), noop(this, "noop")
{
if (!IRCD || !IRCD->CanSVSNOOP)
throw ModuleException("Your IRCd does not support SVSNOOP.");
}
void OnUserModeSet(const MessageSource &, User *u, const Anope::string &mname) override
+1 -37
View File
@@ -10,43 +10,7 @@
*/
#include "module.h"
struct MyOper final
: Oper
, Serializable
{
MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { }
void Serialize(Serialize::Data &data) const override
{
data["name"] << this->name;
data["type"] << this->ot->GetName();
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
{
Anope::string stype, sname;
data["type"] >> stype;
data["name"] >> sname;
OperType *ot = OperType::Find(stype);
if (ot == NULL)
return NULL;
NickCore *nc = NickCore::Find(sname);
if (nc == NULL)
return NULL;
MyOper *myo;
if (obj)
myo = anope_dynamic_static_cast<MyOper *>(obj);
else
myo = new MyOper(nc->display, ot);
nc->o = myo;
Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName();
return myo;
}
};
#include "modules/os_oper.h"
class CommandOSOper final
: public Command
+2 -2
View File
@@ -24,8 +24,8 @@ struct Stats final
void Serialize(Serialize::Data &data) const override
{
data["maxusercnt"] << MaxUserCount;
data["maxusertime"] << MaxUserTime;
data.Store("maxusercnt", MaxUserCount);
data.Store("maxusertime", MaxUserTime);
}
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
+3
View File
@@ -389,7 +389,10 @@ class CommandOSSNLine final
}
if (!this->xlm()->CanAdd(source, mask, expires, reason))
{
delete x;
return;
}
EventReturn MOD_RESULT;
FOREACH_RESULT(OnAddXLine, MOD_RESULT, (source, x, this->xlm()));
+8 -23
View File
@@ -35,10 +35,11 @@ class BahamutIRCdProto final
: public IRCDProto
{
public:
BahamutIRCdProto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x")
BahamutIRCdProto(Module *creator) : IRCDProto(creator, "Bahamut 2+")
{
DefaultPseudoclientModes = "+";
CanSVSNick = true;
CanSVSNOOP = true;
CanSNLine = true;
CanSQLine = true;
CanSQLineChannel = true;
@@ -49,14 +50,9 @@ public:
void SendModeInternal(const MessageSource &source, Channel *chan, const Anope::string &modes, const std::vector<Anope::string> &values) override
{
if (Servers::Capab.count("TSMODE") > 0)
{
auto params = values;
params.insert(params.begin(), { chan->name, Anope::ToString(chan->creation_time), modes });
Uplink::SendInternal({}, source, "MODE", params);
}
else
IRCDProto::SendModeInternal(source, chan, modes, values);
auto params = values;
params.insert(params.begin(), { chan->name, Anope::ToString(chan->creation_time), modes });
Uplink::SendInternal({}, source, "MODE", params);
}
void SendModeInternal(const MessageSource &source, User *u, const Anope::string &modes, const std::vector<Anope::string> &values) override
@@ -103,10 +99,6 @@ public:
/* UNSZLINE */
void SendSZLineDel(const XLine *x) override
{
/* this will likely fail so its only here for legacy */
Uplink::Send("UNSZLINE", 0, x->GetHost());
/* this is how we are supposed to deal with it */
Uplink::Send("RAKILL", x->GetHost(), '*');
}
@@ -115,11 +107,6 @@ public:
{
// Calculate the time left before this would expire
time_t timeleft = x->expires ? x->expires - Anope::CurTime : x->expires;
/* this will likely fail so its only here for legacy */
Uplink::Send("SZLINE", x->GetHost(), x->GetReason());
/* this is how we are supposed to deal with it */
Uplink::Send("AKILL", x->GetHost(), '*', timeleft, x->by, Anope::CurTime, x->GetReason());
}
@@ -252,7 +239,7 @@ public:
void SendClientIntroduction(User *u) override
{
Uplink::Send("NICK", u->nick, 1, u->timestamp, "+" + u->GetModes(), u->GetIdent(), u->host, u->server->GetName(), 0, 0, u->realname);
Uplink::Send("NICK", u->nick, 1, u->timestamp, "+" + u->GetModes(), u->GetIdent(), u->host, u->server->GetName(), 0, "0.0.0.0", u->realname);
}
/* SERVER */
@@ -264,7 +251,7 @@ public:
void SendConnect() override
{
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS");
Uplink::Send("CAPAB", "SSJOIN", "NOQUIT", "BURST", "UNCONNECT", "NICKIP", "TSMODE", "TS3");
Uplink::Send("CAPAB", "BURST", "NICKIPSTR", "SSJOIN", "UNCONNECT");
SendServer(Me);
/*
* SVINFO
@@ -274,7 +261,7 @@ public:
* parv[3] = server is standalone or connected to non-TS only
* parv[4] = server's idea of UTC time
*/
Uplink::Send("SVINFO", 3, 1, 0, Anope::CurTime);
Uplink::Send("SVINFO", 5, 5, 0, Anope::CurTime);
this->SendBOB();
}
@@ -557,9 +544,7 @@ public:
message_burst(this), message_mode(this, "MODE"), message_svsmode(this, "SVSMODE"),
message_nick(this), message_server(this), message_sjoin(this), message_topic(this)
{
this->AddModes();
}
void OnUserNickChange(User *u, const Anope::string &) override
+5 -12
View File
@@ -238,7 +238,7 @@ public:
Uplink::Send("SVSNICK", u->GetUID(), u->timestamp, newnick, when);
}
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) override
{
Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
}
@@ -711,8 +711,6 @@ class ProtoHybrid final
IRCDMessageTMode message_tmode;
IRCDMessageUID message_uid;
bool use_server_side_mlock;
static void AddModes()
{
/* Add user modes */
@@ -819,18 +817,13 @@ public:
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
}
void OnReload(Configuration::Conf *conf) override
{
use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
}
void OnChannelSync(Channel *c) override
{
if (!c->ci)
return;
ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
if (use_server_side_mlock && modelocks && Servers::Capab.count("MLOCK"))
if (modelocks && Servers::Capab.count("MLOCK"))
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
Uplink::Send("MLOCK", c->creation_time, c->ci->name, Anope::CurTime, modes);
@@ -839,7 +832,7 @@ public:
void OnDelChan(ChannelInfo *ci) override
{
if (use_server_side_mlock && ci->c && Servers::Capab.count("MLOCK"))
if (ci->c && Servers::Capab.count("MLOCK"))
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, Anope::CurTime, "");
}
@@ -847,7 +840,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK"))
if (cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK"))
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, Anope::CurTime, modes);
@@ -860,7 +853,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK"))
if (cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK"))
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, Anope::CurTime, modes);
+98 -60
View File
@@ -10,9 +10,10 @@
*/
#include "module.h"
#include "modules/encryption.h"
#include "modules/cs_mode.h"
#include "modules/encryption.h"
#include "modules/httpd.h"
#include "modules/ns_cert.h"
#include "modules/sasl.h"
typedef std::map<char, unsigned> ListLimits;
@@ -41,6 +42,22 @@ namespace
// The version of the InspIRCd protocol that we are using.
size_t spanningtree_proto_ver = 1205;
bool IsExtBan(const Anope::string &str, bool &inverted, Anope::string &name, Anope::string &value)
{
auto startpos = 0;
if (!str.empty() && str[0] == '!')
startpos++;
auto endpos = str.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", startpos);
if (endpos == Anope::string::npos || str[endpos] != ':' || endpos+1 == str.length())
return false;
inverted = !!startpos;
name = str.substr(startpos, endpos - startpos);
value = str.substr(endpos + 1);
return true;
}
// Parses a module name in the format "m_foo.so=bar" to {foo, bar}.
void ParseModule(const Anope::string &module, Anope::string &modname, Anope::string &moddata)
{
@@ -144,7 +161,6 @@ public:
CanSetVIdent = true;
CanSQLine = true;
CanSZLine = true;
CanSVSLogout = true;
CanCertFP = true;
RequiresID = true;
MaxModes = 0;
@@ -207,7 +223,7 @@ public:
{
if (spanningtree_proto_ver >= 1206)
{
IRCD->SendNoticeInternal(bi, target->GetUID(), msg, {
IRCD->SendNotice(bi, target->GetUID(), msg, {
{ "~context", context->name },
});
return;
@@ -219,7 +235,7 @@ public:
{
if (spanningtree_proto_ver >= 1206)
{
IRCD->SendPrivmsgInternal(bi, target->GetUID(), msg, {
IRCD->SendPrivmsg(bi, target->GetUID(), msg, {
{ "~context", context->name },
});
return;
@@ -509,9 +525,12 @@ public:
SendAddLine("Z", x->GetHost(), timeleft, x->by, x->GetReason());
}
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &other) override
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) override
{
Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
if (key.empty())
Uplink::Send(source, "SVSJOIN", u->GetUID(), chan);
else
Uplink::Send(source, "SVSJOIN", u->GetUID(), chan, key);
}
void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &param) override
@@ -562,8 +581,11 @@ public:
void SendLogin(User *u, NickAlias *na) override
{
/* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */
if (!na->nc->HasExt("UNCONFIRMED"))
SendAccount(u->GetUID(), na);
if (na->nc->HasExt("UNCONFIRMED"))
return;
IRCD->SendVHost(u, na->GetVHostIdent(), na->GetVHostHost());
SendAccount(u->GetUID(), na);
}
void SendLogout(User *u) override
@@ -617,7 +639,9 @@ public:
bool IsExtbanValid(const Anope::string &mask) override
{
return mask.length() >= 3 && mask[1] == ':';
bool inverted;
Anope::string name, value;
return IsExtBan(mask, inverted, name, value);
}
bool IsIdentValid(const Anope::string &ident) override
@@ -698,19 +722,15 @@ namespace InspIRCdExtBan
if (cm->type != MODE_LIST)
return cm;
auto startpos = 0;
if (param[0] == '!')
startpos++;
auto endpos = param.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", startpos);
if (endpos == Anope::string::npos || param[endpos] != ':')
bool inverted;
Anope::string name, value;
if (!IsExtBan(param, inverted, name, value))
return cm;
auto name = param.substr(startpos, endpos - startpos);
if (param.length() >= endpos || (name.length() == 1 ? name[0] != xbchar : name != xbname))
if (name.length() == 1 ? name[0] != xbchar : name != xbname)
return cm;
param.erase(0, endpos);
param = value;
return this;
}
};
@@ -1147,6 +1167,7 @@ struct IRCDMessageCapab final
IRCD->CanClearBans = false;
IRCD->CanSQLineChannel = false;
IRCD->CanSVSHold = false;
IRCD->CanTagMessage = false;
IRCD->DefaultPseudoclientModes = "+oI";
}
else if (params[0].equals_cs("CHANMODES") && params.size() > 1)
@@ -1523,6 +1544,9 @@ struct IRCDMessageCapab final
else if (modname.equals_cs("chgident"))
Servers::Capab.insert("CHGIDENT");
else if (modname.equals_cs("ircv3_ctctags"))
IRCD->CanTagMessage = true;
}
const auto &anoperegex = Config->GetBlock("options")->Get<const Anope::string>("regexengine");
@@ -1583,6 +1607,9 @@ struct IRCDMessageCapab final
if (!IRCD->CanSQLineChannel)
Log() << "The remote server does not have the cban module; services will manually enforce forbidden channels until the module is loaded.";
if (!IRCD->CanTagMessage)
Log() << "The remote server does not have the ircv3_ctctags module; sending tag messages is disabled until the module is loaded.";
if (!Servers::Capab.count("CHGHOST"))
Log() << "The remote server does not have the chghost module; vhosts are disabled until the module is loaded.";
@@ -1592,7 +1619,10 @@ struct IRCDMessageCapab final
if (!Servers::Capab.count("GLOBOPS"))
Log() << "The remote server does not have the globops module; oper notices will be sent as announcements until the module is loaded.";
Uplink::Send("SERVER", Me->GetName(), GetPassword(), 0, Me->GetSID(), Me->GetDescription());
if (spanningtree_proto_ver < 1206)
Uplink::Send("SERVER", Me->GetName(), GetPassword(), 0, Me->GetSID(), Me->GetDescription());
else
Uplink::Send("SERVER", Me->GetName(), GetPassword(), Me->GetSID(), Me->GetDescription());
}
}
};
@@ -1802,12 +1832,20 @@ struct IRCDMessageSave final
class IRCDMessageMetadata final
: IRCDMessage
{
const bool &do_topiclock;
const bool &do_mlock;
private:
ServiceReference<CertService> certs;
PrimitiveExtensibleItem<ListLimits> &maxlist;
public:
IRCDMessageMetadata(Module *creator, const bool &handle_topiclock, const bool &handle_mlock, PrimitiveExtensibleItem<ListLimits> &listlimits) : IRCDMessage(creator, "METADATA", 3), do_topiclock(handle_topiclock), do_mlock(handle_mlock), maxlist(listlimits) { SetFlag(FLAG_REQUIRE_SERVER); SetFlag(FLAG_SOFT_LIMIT); }
IRCDMessageMetadata(Module *creator, PrimitiveExtensibleItem<ListLimits> &listlimits)
: IRCDMessage(creator, "METADATA", 3)
, certs("CertService", "certs")
, maxlist(listlimits)
{
SetFlag(FLAG_REQUIRE_SERVER);
SetFlag(FLAG_SOFT_LIMIT);
}
void Run(MessageSource &source, const std::vector<Anope::string> &params, const Anope::map<Anope::string> &tags) override
{
@@ -1819,7 +1857,7 @@ public:
Channel *c = Channel::Find(params[0]);
if (c)
{
if ((c->ci) && (do_mlock) && (params[2] == "mlock"))
if (c->ci && params[2] == "mlock")
{
ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
Anope::string modes;
@@ -1830,7 +1868,7 @@ public:
if (modes != params[3])
Uplink::Send("METADATA", c->name, c->creation_time, "mlock", modes);
}
else if ((c->ci) && (do_topiclock) && (params[2] == "topiclock"))
else if (c->ci && params[2] == "topiclock")
{
bool mystate = c->ci->HasExt("TOPICLOCK");
bool serverstate = (params[3] == "1");
@@ -1852,12 +1890,12 @@ public:
}
else if (isdigit(params[0][0]))
{
auto *u = User::Find(params[0]);
if (!u)
return;
if (params[1].equals_cs("accountname"))
{
User *u = User::Find(params[0]);
if (!u)
return; // Should never happen.
if (params[2].empty())
{
// The user has been logged out by the IRC server.
@@ -1880,18 +1918,22 @@ public:
*/
else if (params[1].equals_cs("ssl_cert"))
{
User *u = User::Find(params[0]);
if (!u)
return;
u->Extend<bool>("ssl");
Anope::string data = params[2].c_str();
size_t pos1 = data.find(' ') + 1;
size_t pos2 = data.find(' ', pos1);
if ((pos2 - pos1) >= 32) // inspircd supports md5 and sha1 fingerprint hashes -> size 32 or 40 bytes.
{
u->fingerprint = data.substr(pos1, pos2 - pos1);
}
Anope::string data;
spacesepstream tokens(params[2]);
if (!tokens.GetToken(data) || data.find('E') != Anope::string::npos || !tokens.GetToken(data))
return; // Malformed or no client certificate.
commasepstream fingerprints(data);
if (!fingerprints.GetToken(data))
return; // Should never happen?
u->fingerprint = data;
FOREACH_MOD(OnFingerprint, (u));
while (certs && fingerprints.GetToken(data))
certs->ReplaceCert(data, u->fingerprint);
}
}
else if (params[0] == "*")
@@ -1939,6 +1981,9 @@ public:
else if (modname.equals_cs("hidechans"))
required = true;
else if (modname.equals_cs("ircv3_ctctags"))
IRCD->CanTagMessage = plus;
else if (modname.equals_cs("rline"))
capab = "RLINE";
@@ -2285,18 +2330,18 @@ struct IRCDMessageServer final
void Run(MessageSource &source, const std::vector<Anope::string> &params, const Anope::map<Anope::string> &tags) override
{
if (!source.GetServer() && params.size() == 5)
size_t paramcount = spanningtree_proto_ver < 1206 ? 5 : 4;
if (!source.GetServer() && params.size() == paramcount)
{
/*
* SERVER testnet.inspircd.org hunter7 0 123 :InspIRCd Test Network
* 0: name
* 1: pass
* 2: hops
* 3: numeric
* 4: desc
* 2: unused (v3 only)
* 3(2): numeric
* 4(3): desc
*/
auto hops = Anope::Convert<unsigned>(params[2], 0);
new Server(Me, params[0], hops, params[4], params[3]);
new Server(Me, params[0], 0, params.back(), params[spanningtree_proto_ver < 1206 ? 3 : 2]);
}
else if (source.GetServer())
{
@@ -2434,8 +2479,6 @@ class ProtoInspIRCd final
IRCDMessageSQuit message_squit;
IRCDMessageUID message_uid;
bool use_server_side_topiclock, use_server_side_mlock;
static void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value)
{
Uplink::Send("METADATA", c->name, c->creation_time, metadataname, value);
@@ -2472,7 +2515,7 @@ public:
, message_ijoin(this)
, message_kick(this)
, message_lmode(this)
, message_metadata(this, use_server_side_topiclock, use_server_side_mlock, ircd_proto.maxlist)
, message_metadata(this, ircd_proto.maxlist)
, message_mode(this)
, message_nick(this)
, message_opertype(this)
@@ -2486,12 +2529,6 @@ public:
{
}
void OnReload(Configuration::Conf *conf) override
{
use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock");
use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
}
void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
@@ -2506,13 +2543,13 @@ public:
void OnChanRegistered(ChannelInfo *ci) override
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
if (use_server_side_mlock && ci->c && modelocks && !modelocks->GetMLockAsString(false).empty())
if (ci->c && modelocks && !modelocks->GetMLockAsString(false).empty())
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
SendChannelMetadata(ci->c, "mlock", modes);
}
if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c)
if (Servers::Capab.count("TOPICLOCK") && ci->c)
{
if (ci->HasExt("TOPICLOCK"))
SendChannelMetadata(ci->c, "topiclock", "1");
@@ -2521,10 +2558,11 @@ public:
void OnDelChan(ChannelInfo *ci) override
{
if (use_server_side_mlock && ci->c)
SendChannelMetadata(ci->c, "mlock", "");
if (!ci->c)
return;
if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c)
SendChannelMetadata(ci->c, "mlock", "");
if (Servers::Capab.count("TOPICLOCK"))
SendChannelMetadata(ci->c, "topiclock", "");
}
@@ -2532,7 +2570,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
if (cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
SendChannelMetadata(ci->c, "mlock", modes);
@@ -2545,7 +2583,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
if (cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
SendChannelMetadata(ci->c, "mlock", modes);
+11 -2
View File
@@ -25,6 +25,7 @@ public:
DefaultPseudoclientModes = "+iU";
CanSVSNick = true;
CanSVSJoin = true;
CanSVSNOOP = true;
CanSetVHost = true;
CanSetVIdent = true;
CanSNLine = true;
@@ -163,7 +164,7 @@ public:
Uplink::Send(source, "ENCAP", '*', "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic);
}
void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &key) override
{
Uplink::Send(source, "ENCAP", '*', "SVSJOIN", user->GetUID(), chan);
}
@@ -186,7 +187,15 @@ public:
void SendSVSLogin(const Anope::string &uid, NickAlias *na) override
{
Server *s = Server::Find(uid.substr(0, 3));
Uplink::Send("ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, '*', '*', na->GetVHostHost().empty() ? "*" : na->GetVHostHost(), na->nc->display);
Anope::string target = s ? s->GetName() : uid.substr(0, 3);
if (na)
{
Uplink::Send("ENCAP", target, "SVSLOGIN", uid, '*', '*', na->GetVHostHost().empty() ? "*" : na->GetVHostHost(), na->nc->display);
}
else
{
Uplink::Send("ENCAP", target, "SU", uid, "");
}
}
void SendSVSNOOP(const Server *server, bool set) override
+3 -11
View File
@@ -45,7 +45,6 @@ public:
CanSZLine = true;
CanSVSNick = true;
CanSVSHold = true;
CanSVSLogout = true;
CanSetVHost = true;
RequiresID = true;
MaxModes = 4;
@@ -355,8 +354,6 @@ class ProtoSolanum final
IRCDMessagePrivmsg message_privmsg;
IRCDMessageServer message_server;
bool use_server_side_mlock;
static void AddModes()
{
/* Add user modes */
@@ -445,18 +442,13 @@ public:
OnUserLogin(u);
}
void OnReload(Configuration::Conf *conf) override
{
use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
}
void OnChannelSync(Channel *c) override
{
if (!c->ci)
return;
ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
if (use_server_side_mlock && modelocks && Servers::Capab.count("MLOCK") > 0)
if (modelocks && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
Uplink::Send("MLOCK", c->creation_time, c->ci->name, modes);
@@ -467,7 +459,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
if (cm && ci->c && modelocks && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, modes);
@@ -480,7 +472,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
if (cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, modes);
+74 -46
View File
@@ -28,6 +28,7 @@ public:
DefaultPseudoclientModes = "+BioqS";
CanSVSNick = true;
CanSVSJoin = true;
CanSVSNOOP = true;
CanSetVHost = true;
CanSetVIdent = true;
CanSNLine = true;
@@ -36,8 +37,8 @@ public:
CanSZLine = true;
CanSVSHold = true;
CanClearBans = true;
CanSVSLogout = true;
CanCertFP = true;
CanTagMessage = true;
RequiresID = true;
MaxModes = 12;
}
@@ -229,7 +230,7 @@ private:
*/
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password);
Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID", "MTAGS");
Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID", "MTAGS", "BIGLINES");
Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort());
Uplink::Send("PROTOCTL", "SID=" + Me->GetSID());
@@ -298,12 +299,12 @@ private:
/* In older Unreal SVSJOIN and SVSNLINE tokens were mixed so SVSJOIN and SVSNLINE are broken
when coming from a none TOKEN'd server
*/
void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &key) override
{
if (!param.empty())
Uplink::Send("SVSJOIN", user->GetUID(), chan, param);
else
if (key.empty())
Uplink::Send("SVSJOIN", user->GetUID(), chan);
else
Uplink::Send("SVSJOIN", user->GetUID(), chan, key);
}
void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string &param) override
@@ -675,24 +676,18 @@ public:
/* Borrowed part of this check from UnrealIRCd */
bool IsValid(Anope::string &value) const override
{
if (value.empty() || value[0] == ':')
if (value.empty() || value[0] != '[')
return false;
Anope::string rest;
auto num1 = Anope::Convert<unsigned>(value[0] == '*' ? value.substr(1) : value, 0, &rest);
if (!num1 || rest[0] != ':' || rest.length() <= 1)
return false;
if (Anope::Convert<int>(rest.substr(1), 0, &rest) > 0 && rest.empty())
return true;
/* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */
size_t end_bracket = value.find(']', 1);
if (end_bracket == Anope::string::npos)
return false;
Anope::string xbuf = value.substr(0, end_bracket);
if (value[end_bracket + 1] != ':')
return false;
commasepstream args(xbuf.substr(1));
Anope::string arg;
while (args.GetToken(arg))
@@ -735,8 +730,7 @@ public:
// The part after the ':' is a duration and it
// can be in the user friendly "1d3h20m" format, make sure we accept that
auto n = Anope::DoTime(rest.substr(1));
return n <= 0;
return false;
return n > 0;
}
};
@@ -1032,6 +1026,8 @@ struct IRCDMessageCapab final
ModeManager::AddChannelMode(new ChannelModeStatus(mode_name, mode_chars[t], mode_prefixes[t], t));
}
}
else if (capab.equals_ci("BIGLINES"))
IRCD->MaxLine = 16384;
}
Message::Capab::Run(source, params, tags);
@@ -1147,19 +1143,27 @@ struct IRCDMessageMD final
struct IRCDMessageMode final
: IRCDMessage
{
IRCDMessageMode(Module *creator, const Anope::string &mname) : IRCDMessage(creator, mname, 2) { SetFlag(FLAG_SOFT_LIMIT); }
bool server_ts;
IRCDMessageMode(Module *creator, const Anope::string &mname, bool sts)
: IRCDMessage(creator, mname, 2)
, server_ts(sts)
{
SetFlag(FLAG_SOFT_LIMIT);
}
void Run(MessageSource &source, const std::vector<Anope::string> &params, const Anope::map<Anope::string> &tags) override
{
bool server_source = source.GetServer() != NULL;
auto final_is_ts = server_ts && source.GetServer() != NULL;
Anope::string modes = params[1];
for (unsigned i = 2; i < params.size() - (server_source ? 1 : 0); ++i)
for (unsigned i = 2; i < params.size() - (final_is_ts ? 1 : 0); ++i)
modes += " " + params[i];
if (IRCD->IsChannelValid(params[0]))
{
Channel *c = Channel::Find(params[0]);
auto ts = IRCD->ExtractTimestamp(params.back());
auto ts = final_is_ts ? IRCD->ExtractTimestamp(params.back()) : 0;
if (c)
c->SetModesInternal(source, modes, ts);
@@ -1693,23 +1697,52 @@ class ProtoUnreal final
IRCDMessageUID message_uid;
IRCDMessageUmode2 message_umode2;
bool use_server_side_mlock;
public:
ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR),
ircd_proto(this),
message_away(this), message_error(this), message_invite(this), message_join(this), message_kick(this),
message_kill(this), message_svskill(this, "SVSKILL"), message_motd(this), message_notice(this), message_part(this), message_ping(this),
message_privmsg(this), message_quit(this), message_squit(this), message_stats(this), message_time(this),
message_version(this), message_whois(this),
message_capab(this), message_chghost(this), message_chgident(this), message_chgname(this),
message_md(this, ircd_proto.ClientModData, ircd_proto.ChannelModData),message_mode(this, "MODE"),
message_svsmode(this, "SVSMODE"), message_svs2mode(this, "SVS2MODE"), message_netinfo(this), message_nick(this), message_pong(this),
message_sasl(this), message_sdesc(this), message_sethost(this), message_setident(this), message_setname(this), message_server(this),
message_sid(this), message_sjoin(this), message_svslogin(this), message_topic(this), message_uid(this), message_umode2(this)
ProtoUnreal(const Anope::string &modname, const Anope::string &creator)
: Module(modname, creator, PROTOCOL | VENDOR)
, ircd_proto(this)
, message_away(this)
, message_error(this)
, message_invite(this)
, message_join(this)
, message_kick(this)
, message_kill(this)
, message_svskill(this, "SVSKILL")
, message_motd(this)
, message_notice(this)
, message_part(this)
, message_ping(this)
, message_privmsg(this)
, message_quit(this)
, message_squit(this)
, message_stats(this)
, message_time(this)
, message_version(this)
, message_whois(this)
, message_capab(this)
, message_chghost(this)
, message_chgident(this)
, message_chgname(this)
, message_md(this, ircd_proto.ClientModData, ircd_proto.ChannelModData)
, message_mode(this, "MODE", true)
, message_svsmode(this, "SVSMODE", false)
, message_svs2mode(this, "SVS2MODE", false)
, message_netinfo(this)
, message_nick(this)
, message_pong(this)
, message_sasl(this)
, message_sdesc(this)
, message_sethost(this)
, message_setident(this)
, message_setname(this)
, message_server(this)
, message_sid(this)
, message_sjoin(this)
, message_svslogin(this)
, message_topic(this)
, message_uid(this)
, message_umode2(this)
{
}
void Prioritize() override
@@ -1717,11 +1750,6 @@ public:
ModuleManager::SetPriority(this, PRIORITY_FIRST);
}
void OnReload(Configuration::Conf *conf) override
{
use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
}
void OnUserNickChange(User *u, const Anope::string &) override
{
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
@@ -1735,7 +1763,7 @@ public:
return;
ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && modelocks)
if (Servers::Capab.count("MLOCK") > 0 && modelocks)
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
Uplink::Send("MLOCK", c->creation_time, c->ci->name, modes);
@@ -1745,7 +1773,7 @@ public:
void OnChanRegistered(ChannelInfo *ci) override
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
if (!ci->c || !use_server_side_mlock || !modelocks || !Servers::Capab.count("MLOCK"))
if (!ci->c || !modelocks || !Servers::Capab.count("MLOCK"))
return;
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, modes);
@@ -1753,7 +1781,7 @@ public:
void OnDelChan(ChannelInfo *ci) override
{
if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK"))
if (!ci->c || !Servers::Capab.count("MLOCK"))
return;
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, "");
}
@@ -1762,7 +1790,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
if (cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, modes);
@@ -1775,7 +1803,7 @@ public:
{
ModeLocks *modelocks = ci->GetExt<ModeLocks>("modelocks");
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
if (use_server_side_mlock && cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
if (cm && modelocks && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = modelocks->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
Uplink::Send("MLOCK", ci->c->creation_time, ci->name, modes);
+1 -1
View File
@@ -237,7 +237,7 @@ public:
void StartTransaction() override
{
if (in_transaction)
throw CoreException();
throw ModuleException("Tried to start a transaction while one was already in progress");
this->SendCommand(NULL, "MULTI");
in_transaction = true;
+1 -9
View File
@@ -145,14 +145,6 @@ public:
void ProcessMessage(Session *sess, const SASL::Message &m) override
{
if (!IRCD->CanSVSLogout && !User::Find(sess->uid))
{
// This IRCd can't log users out yet.
sasl->Fail(sess);
delete sess;
return;
}
if (m.type == "S")
{
sasl->SendMessage(sess, "C", "+");
@@ -310,7 +302,7 @@ public:
// If the user is already introduced then we log them in now.
// Otherwise, we send an SVSLOGIN to log them in later.
User *user = User::Find(session->uid);
NickAlias *na = NickAlias::Find(nc->display);
NickAlias *na = nc ? nc->na : nullptr;
if (user)
{
if (na)
+1 -1
View File
@@ -1,5 +1,5 @@
build_subdir(${CMAKE_CURRENT_SOURCE_DIR})
install(DIRECTORY "templates/"
DESTINATION "${DB_DIR}/webcpanel/templates/default"
DESTINATION "${DATA_DIR}/webcpanel/templates/default"
)
+1 -1
View File
@@ -103,7 +103,7 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str
replacements["DISPLAY"] = na->nc->display;
if (!na->nc->email.empty())
replacements["EMAIL"] = na->nc->email;
replacements["TIME_REGISTERED"] = Anope::strftime(na->time_registered, na->nc);
replacements["TIME_REGISTERED"] = Anope::strftime(na->nc->time_registered, na->nc);
if (na->HasVHost())
replacements["VHOST"] = na->GetVHostMask();
Anope::string *greet = na->nc->GetExt<Anope::string>("greet");
+3 -12
View File
@@ -30,18 +30,8 @@ if(WIN32)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc LANGUAGE RC)
# Add the resource file to the list of sources
list(APPEND SRC_SRCS ${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc)
# For MinGW, we have to change the compile flags
if(MINGW)
set(RC_CFLAGS "-DMINGW -Ocoff -I${Anope_SOURCE_DIR}/include")
# If any sort of debugging is being enabled, add a _DEBUG define to the flags for the resource compiler
if(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
set(RC_CFLAGS "${RC_CFLAGS} -D_DEBUG")
endif()
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc COMPILE_FLAGS "${RC_CFLAGS}")
# For anything else, assumingly Visual Studio at this point, use a different set of compile flags
else()
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc COMPILE_FLAGS "/i\"${Anope_SOURCE_DIR}/include\"")
endif()
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/win32/win32.rc COMPILE_FLAGS "/i\"${Anope_SOURCE_DIR}/include\"")
endif()
# If compiling with Visual Studio, create a static library out of win32/win32_memory.cpp to be included with everything else, needed to override its override of new/delete operators
@@ -95,4 +85,5 @@ endif()
# Set Anope to be installed to the bin directory
install(TARGETS ${PROGRAM_NAME}
DESTINATION ${BIN_DIR}
RUNTIME
)
+8 -8
View File
@@ -160,14 +160,14 @@ NickCore *ChanAccess::GetAccount() const
void ChanAccess::Serialize(Serialize::Data &data) const
{
data["provider"] << this->provider->name;
data["ci"] << this->ci->name;
data["mask"] << this->Mask();
data["creator"] << this->creator;
data["description"] << this->description;
data.SetType("last_seen", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
data["data"] << this->AccessSerialize();
data.Store("provider", this->provider->name);
data.Store("ci", this->ci->name);
data.Store("mask", this->Mask());
data.Store("creator", this->creator);
data.Store("description", this->description);
data.Store("last_seen", this->last_seen);
data.Store("created", this->created);
data.Store("data", this->AccessSerialize());
}
Serializable *ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data)

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