mirror of
https://github.com/anope/anope.git
synced 2026-06-17 13:14:46 +02:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f3c94e5d23 | |||
| f2ab092742 | |||
| 7d5ca5c90b | |||
| 8ee85efd70 | |||
| 0cab675825 | |||
| f1751dcb21 | |||
| 8b02613549 | |||
| c9625ccf3f | |||
| 435ce51196 | |||
| 57ac7cb4db | |||
| 8cb2b801e9 | |||
| 66b45534a8 | |||
| 499077826c | |||
| bc4d34ebd8 | |||
| f40719787f | |||
| 934a13c21f | |||
| e5602f956d | |||
| de11a19e03 | |||
| b437468b84 | |||
| 0a99571c0f | |||
| e704fa6266 | |||
| f908514095 | |||
| bafcba023c | |||
| 9a44b74186 | |||
| 883935c3e0 | |||
| 6d34054b78 | |||
| 3da9b6df0d | |||
| 0ab0e4737c | |||
| cdf356ed33 | |||
| 7d268bb4ca | |||
| 184350ff4a | |||
| 4cdbf560e1 | |||
| cbccc79d37 | |||
| 9b188a6c04 | |||
| 2f74513246 | |||
| 94dbb19593 | |||
| 8232759a92 | |||
| b006966d25 | |||
| 6037f63ae5 | |||
| 5cdb65ca52 | |||
| f9e4ca4d06 | |||
| 66c9be8627 | |||
| 546f65c38e | |||
| 9fcb022d5e | |||
| 5a0c6b1f18 | |||
| ade8db023e | |||
| 2ae733bcd1 | |||
| cc37e6d69a | |||
| 101c68f786 | |||
| ec0cd9e7f9 | |||
| ab0b851d28 | |||
| 4e3720b810 | |||
| 4b48fc98d3 | |||
| 82993c8d1e | |||
| d352718a39 | |||
| d44632e57d | |||
| 80451011dd | |||
| b4e673b2f4 | |||
| 58a78e9aa5 | |||
| 6da4a148fa | |||
| a3edb09eda | |||
| 27beb8f877 | |||
| 136680f917 | |||
| 378ae21ac7 | |||
| e35a86661d | |||
| 528b5938ec | |||
| 03bee17063 | |||
| fe18050c49 | |||
| aa0496f69b | |||
| 4ee22ab05e | |||
| 63ad540e55 | |||
| a1165eea94 | |||
| bfca74f6b3 | |||
| 3acf74483c | |||
| a3ec8329f4 | |||
| 7d0184ca34 | |||
| 31bc597c81 | |||
| e0b687f289 | |||
| 2de0dddb1c | |||
| ff65b68dfa | |||
| 94456a6063 | |||
| 41ea346551 | |||
| 439ad3e736 | |||
| 347d82f59b | |||
| fe68f40634 | |||
| 08b1344056 | |||
| ff67a80a71 |
+1
-1
@@ -14,6 +14,6 @@ Version | Supported
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please do not report security vulnerabilities on GitHub. Instead, email the details to team@anope.org or get the attention of a developer in our development IRC channel at irc.anope.org #anope-devel and PM them the details.
|
||||
Please do not report security vulnerabilities on GitHub. Instead, email the details to team@anope.org or get the attention of a developer in our development IRC channel at irc.teranova.net #anope-devel and PM them the details.
|
||||
|
||||
We will triage your issue as soon as possible and try to release a fixed version within a week of receiving your report.
|
||||
|
||||
+2
-18
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -4,7 +4,7 @@ Anope is an open source set of IRC services. It is highly modular, with a vast n
|
||||
|
||||
* [Website](https://anope.org)
|
||||
* [GitHub](https://github.com/anope)
|
||||
* IRC \#anope on irc.anope.org
|
||||
* IRC \#anope on irc.teranova.net
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -33,7 +33,7 @@ Copy conf/anope.example.conf to conf/anope.conf
|
||||
$ cp conf/anope.example.conf conf/anope.conf
|
||||
```
|
||||
|
||||
Edit anope.conf, configuring the uplink, serverinfo, and protocol module configurations. Example link blocks for popular IRCds are included in the anope.example.conf documentation. The [Anope wiki](https://wiki.anope.org) is also a good source of information. Our support channel is located at #anope on [irc.anope.org](irc://irc.anope.org/#anope).
|
||||
Edit anope.conf, configuring the uplink, serverinfo, and protocol module configurations. Example link blocks for popular IRCds are included in the the example.conf documentation. The [Anope wiki](https://wiki.anope.org) is also a good source of information. Our support channel is located at #anope on [irc.teranova.net](ircs://irc.teranova.net/anope).
|
||||
|
||||
Note that the example configuration file includes other example configuration files. If you want to modify the other example configuration files, copy them (e.g. `modules.example.conf` to `modules.conf`) and modify the `include` directive in `anope.conf` to include the new file.
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Only install example.chk and anope.example.conf from this directory
|
||||
# Only install cron.example.sh and anope.example.conf from this directory
|
||||
# NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file)
|
||||
set(DATA cron.example.sh anope.example.conf botserv.example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf chanstats.example.conf irc2sql.example.conf stats.standalone.example.conf)
|
||||
install(FILES ${DATA}
|
||||
|
||||
+6
-28
@@ -414,12 +414,6 @@ options
|
||||
*/
|
||||
readtimeout = 5s
|
||||
|
||||
/*
|
||||
* Sets the interval between sending warning messages for program errors via
|
||||
* WALLOPS/GLOBOPS.
|
||||
*/
|
||||
warningtimeout = 4h
|
||||
|
||||
/*
|
||||
* Sets the (maximum) frequency at which the timeout list is checked. This,
|
||||
* combined with readtimeout above, determines how accurately timed events,
|
||||
@@ -436,26 +430,11 @@ options
|
||||
timeoutcheck = 3s
|
||||
|
||||
/*
|
||||
* If set, this will allow users to let services send PRIVMSGs to them
|
||||
* instead of NOTICEs. Also see the "msg" option of nickserv:defaults,
|
||||
* which also toggles the default communication (PRIVMSG or NOTICE) to
|
||||
* use for unregistered users.
|
||||
*
|
||||
* This is a feature that is against the IRC RFC and should be used ONLY
|
||||
* if absolutely necessary.
|
||||
*
|
||||
* This directive is optional, and not recommended.
|
||||
* If set Anope will tell users to use a server-side alias for messaging
|
||||
* services instead of /msg. The alias for each service defaults to the
|
||||
* bot name but can be configured in the service block.
|
||||
*/
|
||||
#useprivmsg = yes
|
||||
|
||||
/*
|
||||
* If set, will force services to only respond to PRIVMSGs addresses to
|
||||
* Nick@ServerName - e.g. NickServ@example.com. This should be used in
|
||||
* conjunction with IRCd aliases. This directive is optional.
|
||||
*
|
||||
* This option will have no effect on some IRCds, such as TS6 IRCds.
|
||||
*/
|
||||
#usestrictprivmsg = yes
|
||||
#servicealias = yes
|
||||
|
||||
/*
|
||||
* If set, Anope will only show /stats o to IRC Operators. This directive
|
||||
@@ -746,6 +725,7 @@ 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
|
||||
@@ -822,8 +802,6 @@ opertype
|
||||
*
|
||||
* This can be used to automatically oper users who identify for services operator accounts, and is
|
||||
* useful for setting modes such as Plexus's user mode +N.
|
||||
*
|
||||
* Note that some IRCds, such as InspIRCd, do not allow directly setting +o, and this will not work.
|
||||
*/
|
||||
#modes = "+o"
|
||||
}
|
||||
@@ -915,7 +893,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
|
||||
|
||||
|
||||
@@ -59,6 +59,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "BS"
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -334,10 +345,10 @@ privilege
|
||||
/*
|
||||
* fantasy
|
||||
*
|
||||
* Allows 'fantasist' commands to be used in channels.
|
||||
* Allows fantasy commands (e.g. !kick) to be used in channels.
|
||||
*
|
||||
* Provides the commands:
|
||||
* botserv/set/fantasy - Used for enabling or disabling BotServ's fantasist commands.
|
||||
* botserv/set/fantasy - Used for enabling or disabling BotServ's fantasy commands.
|
||||
*/
|
||||
module
|
||||
{
|
||||
|
||||
@@ -49,6 +49,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "CS"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -49,6 +49,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "GL"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -49,6 +49,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "HS"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -49,6 +49,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "MS"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+37
-10
@@ -49,6 +49,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "NS"
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -106,8 +117,7 @@ module
|
||||
* - memo_mail: Notify user if they have a new memo by mail
|
||||
* - autoop: User will be automatically opped in channels they enter and have access to
|
||||
* - neverop: User can not be added to access lists
|
||||
* - msg: Messages will be sent as PRIVMSGs instead of NOTICEs, requires options:useprivmsg
|
||||
* to be enabled as well
|
||||
* - msg: Messages will be sent as PRIVMSGs instead of NOTICEs
|
||||
* - ns_keep_modes: Enables keepmodes, which retains user modes across sessions
|
||||
*
|
||||
* This directive is optional, if left blank, the options will default to memo_signon, and
|
||||
@@ -124,9 +134,9 @@ module
|
||||
/*
|
||||
* The length of time before a nick's registration expires.
|
||||
*
|
||||
* This directive is optional, but recommended. If not set, the default is 90 days.
|
||||
* This directive is optional, but recommended. If not set, the default is one year.
|
||||
*/
|
||||
expire = 90d
|
||||
expire = 1y
|
||||
|
||||
/*
|
||||
* Prevents the use of the ACCESS and CERT (excluding their LIST subcommand), DROP, FORBID, SUSPEND
|
||||
@@ -219,6 +229,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
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -506,7 +522,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/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.
|
||||
* nickserv/set/password, nickserv/saset/password - Used for changing a users password.
|
||||
@@ -541,9 +556,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 MESSAGE"; command = "nickserv/set/message"; }
|
||||
command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/saset/message"; permission = "nickserv/saset/message"; }
|
||||
|
||||
command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
|
||||
command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; permission = "nickserv/saset/password"; }
|
||||
|
||||
@@ -563,6 +575,21 @@ 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_message
|
||||
*
|
||||
* Provides the command nickserv/set/message and nickserv/saset/message.
|
||||
*
|
||||
* Allows users to let services send them PRIVMSGs instead of NOTICEs.
|
||||
*
|
||||
* This might cause problems with badly written clients as the IRC RFC
|
||||
* requires that automatic responses to a PRIVMSG use a NOTICE to avoid
|
||||
* message loops. Only enable this if you are sure this can not happen.
|
||||
*/
|
||||
#module { name = "ns_set_message" }
|
||||
#command { service = "NickServ"; name = "SET MESSAGE"; command = "nickserv/set/message"; }
|
||||
#command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/saset/message"; permission = "nickserv/saset/message"; }
|
||||
|
||||
/*
|
||||
* ns_set_misc
|
||||
*
|
||||
@@ -576,10 +603,10 @@ command { service = "NickServ"; name = "SET URL"; command = "nickserv/set/misc";
|
||||
command { service = "NickServ"; name = "SASET URL"; command = "nickserv/saset/misc"; misc_description = _("Associate a URL with this account"); permission = "nickserv/saset/url"; group = "nickserv/admin"; }
|
||||
#command { service = "NickServ"; name = "SET DISCORD"; command = "nickserv/set/misc"; misc_description = _("Associate a Discord account with your account"); }
|
||||
#command { service = "NickServ"; name = "SASET DISCORD"; command = "nickserv/saset/misc"; misc_description = _("Associate a Discord account with this account"); permission = "nickserv/saset/discord"; group = "nickserv/admin"; }
|
||||
#command { service = "NickServ"; name = "SET FACEBOOK"; command = "nickserv/set/misc"; misc_description = _("Associate a Facebook URL with your account"); }
|
||||
#command { service = "NickServ"; name = "SASET FACEBOOK"; command = "nickserv/saset/misc"; misc_description = _("Associate a Facebook URL with this account"); permission = "nickserv/saset/facebook"; group = "nickserv/admin"; }
|
||||
#command { service = "NickServ"; name = "SET MASTODON"; command = "nickserv/set/misc"; misc_description = _("Associate a Mastodon account with your account"); }
|
||||
#command { service = "NickServ"; name = "SASET MASTODON"; command = "nickserv/saset/misc"; misc_description = _("Associate a Mastodon account with this account"); permission = "nickserv/saset/mastodon"; group = "nickserv/admin"; }
|
||||
#command { service = "NickServ"; name = "SET TIMEZONE"; command = "nickserv/set/misc"; misc_description = _("Associate a time zone with your account"); }
|
||||
#command { service = "NickServ"; name = "SASET TIMEZONE"; command = "nickserv/saset/misc"; misc_description = _("Associate a time zone with this account"); permission = "nickserv/saset/timezone"; group = "nickserv/admin"; }
|
||||
|
||||
/*
|
||||
* ns_suspend
|
||||
|
||||
@@ -49,6 +49,17 @@ service
|
||||
* Prefixes may be given to the channels in the form of mode characters or prefix symbols.
|
||||
*/
|
||||
#channels = "@#services,#mychan"
|
||||
|
||||
/*
|
||||
* The server alias that can be used to securely message this service. If
|
||||
* your IRC server does not have an alias for this service you can set this
|
||||
* to an empty string to tell users to use /msg instead.
|
||||
*
|
||||
* This setting is ignored when options:servicealias is disabled.
|
||||
*
|
||||
* Defaults to the nick of the service if not set.
|
||||
*/
|
||||
#alias = "OS"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -371,12 +371,6 @@ options
|
||||
*/
|
||||
readtimeout = 5s
|
||||
|
||||
/*
|
||||
* Sets the interval between sending warning messages for program errors via
|
||||
* WALLOPS/GLOBOPS.
|
||||
*/
|
||||
warningtimeout = 4h
|
||||
|
||||
/*
|
||||
* If set, Anope will only show /stats o to IRC Operators. This directive
|
||||
* is optional.
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
Anope Version 2.1.10
|
||||
--------------------
|
||||
Added support for NEXTBANS on UnrealIRCd.
|
||||
Changed hostmask access entries added by nick to use that nick as the default description.
|
||||
Changed modes to be handled internally in their split form.
|
||||
Changed ns_cert to notify a user that their certificate is being automatically added to their account.
|
||||
Fixed matching users against extended bans.
|
||||
Fixed parsing name-only extended bans on InspIRCd.
|
||||
Fixed respecting the preferred extended ban format on InspIRCd.
|
||||
Fixed the name of the cron script in the docs.
|
||||
Updated the list of supported IRCds.
|
||||
Updated the location of the Anope IRC channels
|
||||
|
||||
Anope Version 2.1.9
|
||||
-------------------
|
||||
Bumped the minimum supported version of UnrealIRCd to 6.
|
||||
Fixed granting IRC operator status to services operators.
|
||||
Fixed making users an IRC operator on InspIRCd.
|
||||
Fixed nonicknameownership on InspIRCd v4.
|
||||
Fixed some messages not being translatable.
|
||||
Fixed the Argon2 module not having test vectors.
|
||||
Increased the default nickname expiry period to one year.
|
||||
|
||||
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.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
Anope Version 2.1.10
|
||||
--------------------
|
||||
Added options:servicealias.
|
||||
Moved nickserv/set/message and nickserv/saset/message to the ns_set_message module.
|
||||
Removed options:useprivmsg.
|
||||
Removed options:usestrictprivmsg
|
||||
|
||||
Anope Version 2.1.9
|
||||
-------------------
|
||||
No significant changes.
|
||||
|
||||
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.
|
||||
|
||||
+1
-1
@@ -90,4 +90,4 @@ Anope DefCon
|
||||
6) Support
|
||||
|
||||
You might get DefCon support by posting on our online forum, or maybe on
|
||||
our #anope channel at /server irc.anope.org.
|
||||
our #anope channel at /server irc.teranova.net.
|
||||
|
||||
+5
-5
@@ -60,7 +60,7 @@ Note: You should also read the README and FAQ files!
|
||||
most likely not work!
|
||||
|
||||
If you need help, you should visit https://forum.anope.org/ or #anope on
|
||||
irc.anope.org. Provide *complete* error output, along with other relevant
|
||||
irc.teranova.net. Provide *complete* error output, along with other relevant
|
||||
information eg. OS, compiler and C++ library versions.
|
||||
See the README file for more information.
|
||||
|
||||
@@ -111,17 +111,17 @@ Note: You should also read the README and FAQ files!
|
||||
A crontab entry will allow you to check periodically whether Anope is
|
||||
still running, and restart it if not.
|
||||
|
||||
First rename the example.chk script that is in Anope path (by default,
|
||||
this is ~/anope/conf) to anope.chk and edit it. You'll need to
|
||||
First rename the cron.example.sh script that is in Anope path (by default,
|
||||
this is ~/anope/conf) to cron.sh and edit it. You'll need to
|
||||
modify the CONFIGURATION part of the file. Then ensure that the file is
|
||||
marked as executable by typing chmod +x anope.chk, and try to launch the
|
||||
marked as executable by typing chmod +x cron.sh, and try to launch the
|
||||
script to see if it works (Anope must not be running when you do this ;))
|
||||
|
||||
When this is done, you'll have to add the crontab entry. Type crontab -e.
|
||||
This will open the default text editor with the crontab file. Enter the
|
||||
following (with correct path):
|
||||
|
||||
*/5 * * * * /home/ircd/anope/conf/anope.chk >/dev/null 2>&1
|
||||
*/5 * * * * /home/ircd/anope/conf/cron.sh >/dev/null 2>&1
|
||||
|
||||
The */5 at the beginning means "check every 5 minutes". You may replace
|
||||
the 5 with other another number if you want (but less than 60). Consult
|
||||
|
||||
+5
-5
@@ -64,7 +64,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
|
||||
recommandée, et Anope ne fonctionnera probablement pas !
|
||||
|
||||
Si vous avez besoin d'aide, vous pouvez aller sur le site
|
||||
https://forum.anope.org/ ou le canal #anope sur irc.anope.org.
|
||||
https://forum.anope.org/ ou le canal #anope sur irc.teranova.net.
|
||||
Fournissez *l'essemble* des erreurs qui apparaîssent, en plus de
|
||||
toutes informations utiles, comme les versions de votre OS, du
|
||||
compilateur utilisé et de la librairie C++. Lisez le fichier README
|
||||
@@ -121,11 +121,11 @@ Note : Vous devrez également lire les fichiers README et FAQ !
|
||||
Une entrée crontab vous permettra de vérifier périodiquement si Anope
|
||||
est toujours en cours d'exécution et de le redémarrer s'il n'est pas.
|
||||
|
||||
D'abord renommez le script example.chk qui est dans les dossiers
|
||||
d'Anope (par défaut, ~/anope/conf) en anope.chk et modifiez-le.
|
||||
D'abord renommez le script cron.example.sh qui est dans les dossiers
|
||||
d'Anope (par défaut, ~/anope/conf) en cron.sh et modifiez-le.
|
||||
Vous aurez besoin de modifier la partie CONFIGURATION du fichier.
|
||||
Assurez-vous ensuite que le fichier est marqué comme exécutable en
|
||||
tapant chmod +x anope.chk et essayez de lancer le script pour voir
|
||||
tapant chmod +x cron.sh et essayez de lancer le script pour voir
|
||||
si cela fonctionne (Anope ne doit pas être en marche lorsque vous
|
||||
testez cela ;))
|
||||
|
||||
@@ -133,7 +133,7 @@ Note : Vous devrez également lire les fichiers README et FAQ !
|
||||
crontab -e. Cela va ouvrir l'éditeur de texte par défaut avec le
|
||||
fichier crontab. Entrez la ligne suivante (avec le chemin correct) :
|
||||
|
||||
*/5 * * * * /home/ircd/anope/conf/anope.chk > /dev/null 2>&1
|
||||
*/5 * * * * /home/ircd/anope/conf/cron.sh > /dev/null 2>&1
|
||||
|
||||
Le */5 au début signifie "vérifier toutes les 5 minutes". Vous pouvez
|
||||
remplacer le 5 par un autre numéro si vous voulez (mais moins de 60).
|
||||
|
||||
@@ -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
@@ -111,7 +111,7 @@ Anope Modules
|
||||
Use modules at your own risk, and make sure you get them from a
|
||||
reputable source. You might get module support by contacting the module
|
||||
author, posting on our online forum, or maybe on our #anope channel
|
||||
at /server irc.anope.org.
|
||||
at /server irc.teranova.net.
|
||||
|
||||
7) Information for Developers
|
||||
|
||||
|
||||
+4
-4
@@ -167,13 +167,13 @@ Table of Contents
|
||||
Anope currently works with:
|
||||
|
||||
* Bahamut 2.0 or later
|
||||
* ircd-hybrid 8.2.23 or later
|
||||
* InspIRCd 3 or later
|
||||
* ircd-hybrid 8.2.23 or later
|
||||
* ircd-ratbox 3 or later
|
||||
* ngIRCd 19.2 or later
|
||||
* Plexus 3 or later
|
||||
* Ratbox 2.0.6 or later
|
||||
* Solanum (all versions)
|
||||
* UnrealIRCd 4 or later
|
||||
* UnrealIRCd 6 or later
|
||||
|
||||
Anope could also work with some of the daemons derived by the ones listed
|
||||
above, but there's no support for them if they work or don't work.
|
||||
@@ -245,7 +245,7 @@ Table of Contents
|
||||
|
||||
If you read the documentation carefully, and didn't find the answer to
|
||||
your question, feel free to post on the website forums or join our irc
|
||||
channel (irc.anope.org #anope). Once you join our Support channel be as
|
||||
channel (irc.teranova.net #anope). Once you join our Support channel be as
|
||||
precise as possible when asking a question, because we have no extraordinary
|
||||
powers and can't guess things if they aren't provided.
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ public:
|
||||
time_t lastmsg;
|
||||
/* Map of actual command names -> service name/permission required */
|
||||
CommandInfo::map commands;
|
||||
/* The server-side alias used to message this bot. */
|
||||
Anope::string alias;
|
||||
/* Modes the bot should have as configured in service:modes */
|
||||
Anope::string botmodes;
|
||||
/* Channels the bot should be in as configured in service:channels */
|
||||
@@ -126,6 +128,9 @@ public:
|
||||
*/
|
||||
CommandInfo *GetCommand(const Anope::string &cname);
|
||||
|
||||
/** Get the command that users can use to send a message to this bot. */
|
||||
Anope::string GetQueryCommand() const;
|
||||
|
||||
/** Find a bot by nick
|
||||
* @param nick The nick
|
||||
* @param nick_only True to only look by nick, and not by UID
|
||||
|
||||
+1
-1
@@ -215,7 +215,7 @@ public:
|
||||
* @param mode the modes
|
||||
* @param enforce_mlock true to enforce mlock
|
||||
*/
|
||||
void SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts = 0, bool enforce_mlock = true);
|
||||
void SetModesInternal(MessageSource &source, const Anope::string &modes, const std::vector<Anope::string> ¶ms, time_t ts = 0, bool enforce_mlock = true);
|
||||
|
||||
/** Does the given user match the given list? (CMODE_BAN, CMODE_EXCEPT, etc, a list mode)
|
||||
* @param u The user
|
||||
|
||||
+2
-6
@@ -88,21 +88,17 @@ namespace Configuration
|
||||
{
|
||||
/* options:readtimeout */
|
||||
time_t ReadTimeout;
|
||||
/* options:useprivmsg */
|
||||
bool UsePrivmsg;
|
||||
/* If we should default to privmsging clients */
|
||||
bool DefPrivmsg;
|
||||
/* Default language */
|
||||
Anope::string DefLanguage;
|
||||
/* options:timeoutcheck */
|
||||
time_t TimeoutCheck;
|
||||
/* options:usestrictprivmsg */
|
||||
bool UseStrictPrivmsg;
|
||||
/* options:servicealias */
|
||||
bool ServiceAlias;
|
||||
/* networkinfo:nickchars */
|
||||
Anope::string NickChars;
|
||||
|
||||
/* either "/msg " or "/" */
|
||||
Anope::string StrictPrivmsg;
|
||||
/* List of uplink servers to try and connect to */
|
||||
std::vector<Uplink> Uplinks;
|
||||
/* A vector of our logfile options */
|
||||
|
||||
@@ -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,8 +194,7 @@ public:
|
||||
|
||||
void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const override
|
||||
{
|
||||
data.SetType(this->name, Serialize::Data::DT_INT);
|
||||
data[this->name] << true;
|
||||
data.Store(this->name, true);
|
||||
}
|
||||
|
||||
void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override
|
||||
|
||||
+6
-6
@@ -65,9 +65,9 @@ namespace Language
|
||||
} // namespace Language
|
||||
|
||||
/* Commonly used language strings */
|
||||
#define CONFIRM_DROP _("Please confirm that you want to drop \002%s\002 with \002%s%s DROP %s %s\002")
|
||||
#define CONFIRM_DROP _("Please confirm that you want to drop \002%s\002 with \002%s DROP %s %s\002")
|
||||
#define SERVICE_UNAVAILABLE _("Sorry, %s is temporarily unavailable.")
|
||||
#define MORE_INFO _("\002%s%s HELP %s\002 for more information.")
|
||||
#define MORE_INFO _("\002%s HELP %s\002 for more information.")
|
||||
#define BAD_USERHOST_MASK _("Mask must be in the form \037user\037@\037host\037.")
|
||||
#define BAD_EXPIRY_TIME _("Invalid expiry time.")
|
||||
#define USERHOST_MASK_TOO_WIDE _("%s coverage is too wide; Please use a more specific mask.")
|
||||
@@ -93,7 +93,7 @@ namespace Language
|
||||
#define NO_EXPIRE _("does not expire")
|
||||
#define LIST_INCORRECT_RANGE _("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002.")
|
||||
#define NICK_IS_SECURE _("This nickname is registered and protected. If it is your\n" \
|
||||
"nick, type \002%s%s IDENTIFY \037password\037\002. Otherwise,\n" \
|
||||
"nick, type \002%s IDENTIFY \037password\037\002. Otherwise,\n" \
|
||||
"please choose a different nick.")
|
||||
#define FORCENICKCHANGE_NOW _("This nickname has been registered; you may not use it.")
|
||||
#define NICK_CANNOT_BE_REGISTERED _("Nickname \002%s\002 may not be registered.")
|
||||
@@ -108,12 +108,12 @@ 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.")
|
||||
"Type \002%s READ %s %zu\002 to read it.")
|
||||
#define MEMO_NEW_MEMO_ARRIVED _("You have a new memo from %s.\n" \
|
||||
"Type \002%s%s READ %zu\002 to read it.")
|
||||
"Type \002%s READ %zu\002 to read it.")
|
||||
#define MEMO_HAVE_NO_MEMOS _("You have no memos.")
|
||||
#define MEMO_X_HAS_NO_MEMOS _("%s has no memos.")
|
||||
#define MEMO_HAVE_NO_NEW_MEMOS _("You have no new memos.")
|
||||
|
||||
+3
-2
@@ -66,10 +66,11 @@ namespace Message
|
||||
* @param source The source of the SJOIN
|
||||
* @param chan The channel the users are joining to
|
||||
* @param ts The TS for the channel
|
||||
* @param modes The modes sent with the SJOIN, if any
|
||||
* @param modes The mode letters sent with the SJOIN, if any
|
||||
* @param modeparams The mode parameters sent with the SJOIN, if any
|
||||
* @param users The users and their status, if any
|
||||
*/
|
||||
static void SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::list<SJoinUser> &users);
|
||||
static void SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::vector<Anope::string> &modeparams, const std::list<SJoinUser> &users);
|
||||
};
|
||||
|
||||
struct CoreExport Kick
|
||||
|
||||
+4
-1
@@ -216,9 +216,12 @@ template<typename T>
|
||||
class CoreExport ChannelModeVirtual
|
||||
: public T
|
||||
{
|
||||
Anope::string base;
|
||||
private:
|
||||
ChannelMode *basech;
|
||||
|
||||
protected:
|
||||
Anope::string base;
|
||||
|
||||
public:
|
||||
ChannelModeVirtual(const Anope::string &mname, const Anope::string &basename);
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ struct MyOper final
|
||||
|
||||
void Serialize(Serialize::Data &data) const override
|
||||
{
|
||||
data["name"] << this->name;
|
||||
data["type"] << this->ot->GetName();
|
||||
data.Store("name", this->name);
|
||||
data.Store("type", this->ot->GetName());
|
||||
}
|
||||
|
||||
static Serializable *Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -240,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 ¶m) { }
|
||||
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
|
||||
|
||||
+30
-9
@@ -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();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
|
||||
+5
-5
@@ -107,14 +107,14 @@ protected:
|
||||
* @param suid The unique identifier of the user.
|
||||
* @param nc The account the user is identified as, if any
|
||||
*/
|
||||
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
|
||||
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const std::vector<Anope::string> &smodeparams, const Anope::string &suid, NickCore *nc);
|
||||
|
||||
/** Destroy a user.
|
||||
*/
|
||||
virtual ~User();
|
||||
|
||||
public:
|
||||
static User *OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
|
||||
static User *OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc, const std::vector<Anope::string> &smodeparams = {});
|
||||
|
||||
/** Update the nickname of a user record accordingly, should be
|
||||
* called from ircd protocol.
|
||||
@@ -307,10 +307,10 @@ public:
|
||||
|
||||
/** Set a string of modes on a user internally
|
||||
* @param setter who/what is setting the mode
|
||||
* @param umodes The modes
|
||||
* @param umodes The mode letters
|
||||
* @param umodeparams The mode values
|
||||
*/
|
||||
void SetModesInternal(const MessageSource &source, const char *umodes, ...) ATTR_FORMAT(3, 4);
|
||||
void SetModesInternal(const MessageSource &source, const Anope::string &umodes);
|
||||
void SetModesInternal(const MessageSource &source, const Anope::string &umodes, const std::vector<Anope::string> &umodeparams = {});
|
||||
|
||||
/** Get modes set for this user.
|
||||
* @return A string of modes set on the user
|
||||
|
||||
+99
-76
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Anope\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-06-23 14:15+0100\n"
|
||||
"PO-Revision-Date: 2024-06-23 14:16+0100\n"
|
||||
"POT-Creation-Date: 2024-10-22 16:28+0100\n"
|
||||
"PO-Revision-Date: 2024-10-22 16:29+0100\n"
|
||||
"Last-Translator: Sadie Powell <sadie@witchery.services>\n"
|
||||
"Language-Team: English\n"
|
||||
"Language: en_US\n"
|
||||
@@ -82,47 +82,47 @@ msgid ""
|
||||
"It has been created for users that can't host or\n"
|
||||
"configure a bot, or for use on networks that don't\n"
|
||||
"allow user bots. Available commands are listed\n"
|
||||
"below; to use them, type %s%s command. For\n"
|
||||
"below; to use them, type %s command. For\n"
|
||||
"more information on a specific command, type\n"
|
||||
"%s%s %s command.\n"
|
||||
"%s %s command.\n"
|
||||
msgstr ""
|
||||
"%s allows you to have a bot on your own channel.\n"
|
||||
"It has been created for users that can't host or\n"
|
||||
"configure a bot, or for use on networks that don't\n"
|
||||
"allow user bots. Available commands are listed\n"
|
||||
"below; to use them, type %s%s command. For\n"
|
||||
"below; to use them, type %s command. For\n"
|
||||
"more information on a specific command, type\n"
|
||||
"%s%s %s command.\n"
|
||||
"%s %s command.\n"
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s allows you to register a nickname and\n"
|
||||
"prevent others from using it. The following\n"
|
||||
"commands allow for registration and maintenance of\n"
|
||||
"nicknames; to use them, type %s%s command.\n"
|
||||
"nicknames; to use them, type %s command.\n"
|
||||
"For more information on a specific command, type\n"
|
||||
"%s%s %s command.\n"
|
||||
"%s %s command.\n"
|
||||
msgstr ""
|
||||
"%s allows you to register a nickname and\n"
|
||||
"prevent others from using it. The following\n"
|
||||
"commands allow for registration and maintenance of\n"
|
||||
"nicknames; to use them, type %s%s command.\n"
|
||||
"nicknames; to use them, type %s command.\n"
|
||||
"For more information on a specific command, type\n"
|
||||
"%s%s %s command.\n"
|
||||
"%s %s command.\n"
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s allows you to register an account.\n"
|
||||
"The following commands allow for registration and maintenance of\n"
|
||||
"accounts; to use them, type %s%s command.\n"
|
||||
"accounts; to use them, type %s command.\n"
|
||||
"For more information on a specific command, type\n"
|
||||
"%s%s %s command.\n"
|
||||
"%s %s command.\n"
|
||||
msgstr ""
|
||||
"%s allows you to register an account.\n"
|
||||
"The following commands allow for registration and maintenance of\n"
|
||||
"accounts; to use them, type %s%s command.\n"
|
||||
"accounts; to use them, type %s command.\n"
|
||||
"For more information on a specific command, type\n"
|
||||
"%s%s %s command.\n"
|
||||
"%s %s command.\n"
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
@@ -131,16 +131,16 @@ msgid ""
|
||||
"malicious users from \"taking over\" channels by limiting\n"
|
||||
"who is allowed channel operator privileges. Available\n"
|
||||
"commands are listed below; to use them, type\n"
|
||||
"%s%s command. For more information on a\n"
|
||||
"specific command, type %s%s HELP command.\n"
|
||||
"%s command. For more information on a\n"
|
||||
"specific command, type %s HELP command.\n"
|
||||
msgstr ""
|
||||
"%s allows you to register and control various\n"
|
||||
"aspects of channels. %s can often prevent\n"
|
||||
"malicious users from \"taking over\" channels by limiting\n"
|
||||
"who is allowed channel operator privileges. Available\n"
|
||||
"commands are listed below; to use them, type\n"
|
||||
"%s%s command. For more information on a\n"
|
||||
"specific command, type %s%s HELP command.\n"
|
||||
"%s command. For more information on a\n"
|
||||
"specific command, type %s HELP command.\n"
|
||||
|
||||
#, c-format
|
||||
msgid "%s already exists in %s bad words list."
|
||||
@@ -387,8 +387,8 @@ msgid "%s will now permanently be ignored."
|
||||
msgstr "%s will now permanently be ignored."
|
||||
|
||||
#, c-format
|
||||
msgid "%s%s HELP %s for more information."
|
||||
msgstr "%s%s HELP %s for more information."
|
||||
msgid "%s HELP %s for more information."
|
||||
msgstr "%s HELP %s for more information."
|
||||
|
||||
msgid "ADD nick user host real"
|
||||
msgstr "ADD nick user host real"
|
||||
@@ -458,11 +458,11 @@ msgstr ""
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User access levels can be seen by using the\n"
|
||||
"%s command; type %s%s HELP LEVELS for\n"
|
||||
"%s command; type %s HELP LEVELS for\n"
|
||||
"information."
|
||||
msgstr ""
|
||||
"User access levels can be seen by using the\n"
|
||||
"%s command; type %s%s HELP LEVELS for\n"
|
||||
"%s command; type %s HELP LEVELS for\n"
|
||||
"information."
|
||||
|
||||
#, c-format
|
||||
@@ -947,12 +947,12 @@ msgstr ""
|
||||
#, c-format
|
||||
msgid ""
|
||||
" \n"
|
||||
"See the %s command (%s%s HELP ACCESS) for\n"
|
||||
"See the %s command (%s HELP ACCESS) for\n"
|
||||
"information on giving a subset of these privileges to\n"
|
||||
"other channel users.\n"
|
||||
msgstr ""
|
||||
" \n"
|
||||
"See the %s command (%s%s HELP ACCESS) for\n"
|
||||
"See the %s command (%s HELP ACCESS) for\n"
|
||||
"information on giving a subset of these privileges to\n"
|
||||
"other channel users.\n"
|
||||
|
||||
@@ -1219,11 +1219,11 @@ msgstr ""
|
||||
#, c-format
|
||||
msgid ""
|
||||
" \n"
|
||||
"Type %s%s HELP command for help on any of the\n"
|
||||
"Type %s HELP command for help on any of the\n"
|
||||
"above commands."
|
||||
msgstr ""
|
||||
" \n"
|
||||
"Type %s%s HELP command for help on any of the\n"
|
||||
"Type %s HELP command for help on any of the\n"
|
||||
"above commands."
|
||||
|
||||
#, c-format
|
||||
@@ -1249,10 +1249,6 @@ msgstr " Loaded at: %p"
|
||||
msgid " but %s mysteriously dematerialized."
|
||||
msgstr " but %s mysteriously dematerialized."
|
||||
|
||||
#, c-format
|
||||
msgid "\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
|
||||
msgstr "\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
|
||||
|
||||
msgid "\"Jupiter\" a server"
|
||||
msgstr "\"Jupiter\" a server"
|
||||
|
||||
@@ -1812,6 +1808,9 @@ 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"
|
||||
|
||||
@@ -2954,6 +2953,14 @@ msgstr ""
|
||||
"become the new founder, but if the access list is empty, the\n"
|
||||
"channel will be dropped."
|
||||
|
||||
#, c-format
|
||||
msgid "Changing your usermodes to %s"
|
||||
msgstr "Changing your usermodes to %s"
|
||||
|
||||
#, c-format
|
||||
msgid "Changing your vhost to %s"
|
||||
msgstr "Changing your vhost to %s"
|
||||
|
||||
msgid "Channel"
|
||||
msgstr "Channel"
|
||||
|
||||
@@ -4194,12 +4201,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."
|
||||
@@ -4779,7 +4786,7 @@ msgid ""
|
||||
"Maintains the bad words list for a channel. The bad\n"
|
||||
"words list determines which words are to be kicked\n"
|
||||
"when the bad words kicker is enabled. For more information,\n"
|
||||
"type %s%s HELP KICK %s.\n"
|
||||
"type %s HELP KICK %s.\n"
|
||||
" \n"
|
||||
"The ADD command adds the given word to the\n"
|
||||
"bad words list. If SINGLE is specified, a kick will be\n"
|
||||
@@ -4794,7 +4801,7 @@ msgstr ""
|
||||
"Maintains the bad words list for a channel. The bad\n"
|
||||
"words list determines which words are to be kicked\n"
|
||||
"when the bad words kicker is enabled. For more information,\n"
|
||||
"type %s%s HELP KICK %s.\n"
|
||||
"type %s HELP KICK %s.\n"
|
||||
" \n"
|
||||
"The ADD command adds the given word to the\n"
|
||||
"bad words list. If SINGLE is specified, a kick will be\n"
|
||||
@@ -5403,8 +5410,8 @@ msgid "Persistent"
|
||||
msgstr "Persistent"
|
||||
|
||||
#, c-format
|
||||
msgid "Please confirm that you want to drop %s with %s%s DROP %s %s"
|
||||
msgstr "Please confirm that you want to drop %s with %s%s DROP %s %s"
|
||||
msgid "Please confirm that you want to drop %s with %s DROP %s %s"
|
||||
msgstr "Please confirm that you want to drop %s with %s DROP %s %s"
|
||||
|
||||
msgid "Please contact an Operator to get a vhost assigned to this nick."
|
||||
msgstr "Please contact an Operator to get a vhost assigned to this nick."
|
||||
@@ -5900,18 +5907,18 @@ msgstr "Secureops enforced on %s."
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"See %s%s HELP %s for more information\n"
|
||||
"See %s HELP %s for more information\n"
|
||||
"about the access list."
|
||||
msgstr ""
|
||||
"See %s%s HELP %s for more information\n"
|
||||
"See %s HELP %s for more information\n"
|
||||
"about the access list."
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"See %s%s HELP %s for more information\n"
|
||||
"See %s HELP %s for more information\n"
|
||||
"about the flags system."
|
||||
msgstr ""
|
||||
"See %s%s HELP %s for more information\n"
|
||||
"See %s HELP %s for more information\n"
|
||||
"about the flags system."
|
||||
|
||||
msgid "Send a memo to a nick or channel"
|
||||
@@ -6225,7 +6232,7 @@ msgid ""
|
||||
"option tells the bot to kick users who say certain words\n"
|
||||
"on the channels.\n"
|
||||
"You can define bad words for your channel using the\n"
|
||||
"BADWORDS command. Type %s%s HELP BADWORDS for\n"
|
||||
"BADWORDS command. Type %s HELP BADWORDS for\n"
|
||||
"more information.\n"
|
||||
" \n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
@@ -6236,7 +6243,7 @@ msgstr ""
|
||||
"option tells the bot to kick users who say certain words\n"
|
||||
"on the channels.\n"
|
||||
"You can define bad words for your channel using the\n"
|
||||
"BADWORDS command. Type %s%s HELP BADWORDS for\n"
|
||||
"BADWORDS command. Type %s HELP BADWORDS for\n"
|
||||
"more information.\n"
|
||||
" \n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
@@ -6462,7 +6469,7 @@ msgid ""
|
||||
" LIMIT Sets the maximum number of memos you can\n"
|
||||
" receive\n"
|
||||
" \n"
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option."
|
||||
msgstr ""
|
||||
"Sets various memo options. option can be one of:\n"
|
||||
@@ -6472,7 +6479,7 @@ msgstr ""
|
||||
" LIMIT Sets the maximum number of memos you can\n"
|
||||
" receive\n"
|
||||
" \n"
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option."
|
||||
|
||||
msgid "Sets various nickname options. option can be one of:"
|
||||
@@ -6528,8 +6535,8 @@ msgstr ""
|
||||
"may not get set automatically."
|
||||
|
||||
#, c-format
|
||||
msgid "Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
|
||||
msgstr "Setting %s not known. Type %s%s HELP LEVELS for a list of valid settings."
|
||||
msgid "Setting %s not known. Type %s HELP LEVELS for a list of valid settings."
|
||||
msgstr "Setting %s not known. Type %s HELP LEVELS for a list of valid settings."
|
||||
|
||||
msgid "Setting for DEBUG must be ON, OFF, or a positive number."
|
||||
msgstr "Setting for DEBUG must be ON, OFF, or a positive number."
|
||||
@@ -7439,10 +7446,10 @@ msgstr "There is %zu memo on channel %s."
|
||||
#, c-format
|
||||
msgid ""
|
||||
"There is a new memo on channel %s.\n"
|
||||
"Type %s%s READ %s %zu to read it."
|
||||
"Type %s READ %s %zu to read it."
|
||||
msgstr ""
|
||||
"There is a new memo on channel %s.\n"
|
||||
"Type %s%s READ %s %zu to read it."
|
||||
"Type %s READ %s %zu to read it."
|
||||
|
||||
#, c-format
|
||||
msgid "There is no bot assigned to %s anymore."
|
||||
@@ -7739,20 +7746,20 @@ msgstr "This nickname is suspended."
|
||||
#, c-format
|
||||
msgid ""
|
||||
"This nickname is registered and protected. If it is your\n"
|
||||
"nick, type %s%s IDENTIFY password. Otherwise,\n"
|
||||
"nick, type %s IDENTIFY password. Otherwise,\n"
|
||||
"please choose a different nick."
|
||||
msgstr ""
|
||||
"This nickname is registered and protected. If it is your\n"
|
||||
"nick, type %s%s IDENTIFY password. Otherwise,\n"
|
||||
"nick, type %s IDENTIFY password. Otherwise,\n"
|
||||
"please choose a different nick."
|
||||
|
||||
#, c-format
|
||||
msgid "To delete, type: %s%s %s %d"
|
||||
msgstr "To delete, type: %s%s %s %d"
|
||||
msgid "To delete, type: %s %s %d"
|
||||
msgstr "To delete, type: %s %s %d"
|
||||
|
||||
#, c-format
|
||||
msgid "To delete, type: %s%s %s %s %d"
|
||||
msgstr "To delete, type: %s%s %s %s %d"
|
||||
msgid "To delete, type: %s %s %s %d"
|
||||
msgstr "To delete, type: %s %s %s %d"
|
||||
|
||||
msgid "To protect ops against bot kicks"
|
||||
msgstr "To protect ops against bot kicks"
|
||||
@@ -7907,21 +7914,21 @@ msgstr "Type"
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option."
|
||||
msgstr ""
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option."
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option.\n"
|
||||
" \n"
|
||||
"Note: access to this command is controlled by the\n"
|
||||
"level SET."
|
||||
msgstr ""
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option.\n"
|
||||
" \n"
|
||||
"Note: access to this command is controlled by the\n"
|
||||
@@ -7929,25 +7936,25 @@ msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option. The options will be set on the given\n"
|
||||
"nickname."
|
||||
msgstr ""
|
||||
"Type %s%s HELP %s option for more information\n"
|
||||
"Type %s HELP %s option for more information\n"
|
||||
"on a specific option. The options will be set on the given\n"
|
||||
"nickname."
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Type %s%s HELP %s option for more information on a\n"
|
||||
"Type %s HELP %s option for more information on a\n"
|
||||
"particular option."
|
||||
msgstr ""
|
||||
"Type %s%s HELP %s option for more information on a\n"
|
||||
"Type %s HELP %s option for more information on a\n"
|
||||
"particular option."
|
||||
|
||||
#, c-format
|
||||
msgid "Type %s%s SET EMAIL email in order to set your email."
|
||||
msgstr "Type %s%s SET EMAIL email in order to set your email."
|
||||
msgid "Type %s SET EMAIL email in order to set your email."
|
||||
msgstr "Type %s SET EMAIL email in order to set your email."
|
||||
|
||||
msgid "Un-Load a module"
|
||||
msgstr "Un-Load a module"
|
||||
@@ -7995,16 +8002,16 @@ msgid "Unknown command %s."
|
||||
msgstr "Unknown command %s."
|
||||
|
||||
#, c-format
|
||||
msgid "Unknown command %s. \"%s%s HELP\" for help."
|
||||
msgstr "Unknown command %s. \"%s%s HELP\" for help."
|
||||
msgid "Unknown command %s. \"%s HELP\" for help."
|
||||
msgstr "Unknown command %s. \"%s HELP\" for help."
|
||||
|
||||
#, c-format
|
||||
msgid "Unknown command %s. Did you mean %s?"
|
||||
msgstr "Unknown command %s. Did you mean %s?"
|
||||
|
||||
#, c-format
|
||||
msgid "Unknown command %s. Did you mean %s? \"%s%s HELP\" for help."
|
||||
msgstr "Unknown command %s. Did you mean %s? \"%s%s HELP\" for help."
|
||||
msgid "Unknown command %s. Did you mean %s? \"%s HELP\" for help."
|
||||
msgstr "Unknown command %s. Did you mean %s? \"%s HELP\" for help."
|
||||
|
||||
#, c-format
|
||||
msgid "Unknown mode character %c ignored."
|
||||
@@ -8349,10 +8356,6 @@ msgstr "You can't add a channel to its own access list."
|
||||
msgid "You can't logout %s, they are a Services Operator."
|
||||
msgstr "You can't logout %s, they are a Services Operator."
|
||||
|
||||
#, c-format
|
||||
msgid "You cannot %s on this network."
|
||||
msgstr "You cannot %s on this network."
|
||||
|
||||
#, c-format
|
||||
msgid "You cannot set the %c flag."
|
||||
msgstr "You cannot set the %c flag."
|
||||
@@ -8427,10 +8430,10 @@ msgstr "You have 1 new memo."
|
||||
#, c-format
|
||||
msgid ""
|
||||
"You have a new memo from %s.\n"
|
||||
"Type %s%s READ %zu to read it."
|
||||
"Type %s READ %zu to read it."
|
||||
msgstr ""
|
||||
"You have a new memo from %s.\n"
|
||||
"Type %s%s READ %zu to read it."
|
||||
"Type %s READ %zu to read it."
|
||||
|
||||
#, c-format
|
||||
msgid "You have been invited to %s by %s."
|
||||
@@ -8491,6 +8494,10 @@ msgstr "You may not change the email of other Services Operators."
|
||||
msgid "You may not change the password of other Services Operators."
|
||||
msgstr "You may not change the password of other Services Operators."
|
||||
|
||||
#, c-format
|
||||
msgid "You may not drop %s as it is the display nick for the account."
|
||||
msgstr "You may not drop %s as it is the display nick for the account."
|
||||
|
||||
msgid "You may not drop other Services Operators' nicknames."
|
||||
msgstr "You may not drop other Services Operators' nicknames."
|
||||
|
||||
@@ -8588,6 +8595,10 @@ msgstr "Your IRCd does not support SVSPART."
|
||||
msgid "Your IRCd does not support vidents. If this is incorrect please report this as a possible bug."
|
||||
msgstr "Your IRCd does not support vidents. If this is incorrect please report this as a possible bug."
|
||||
|
||||
#, c-format
|
||||
msgid "Your SSL certificate fingerprint %s has been automatically added to your certificate list."
|
||||
msgstr "Your SSL certificate fingerprint %s has been automatically added to your certificate list."
|
||||
|
||||
#, c-format
|
||||
msgid "Your account %s has been successfully created."
|
||||
msgstr "Your account %s has been successfully created."
|
||||
@@ -8894,3 +8905,15 @@ msgstr "{nick | channel}"
|
||||
|
||||
msgid "{nick | channel} memo-text"
|
||||
msgstr "{nick | channel} memo-text"
|
||||
|
||||
#, c-format
|
||||
#~ msgid "\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
|
||||
#~ msgstr "\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
|
||||
|
||||
#, c-format
|
||||
#~ msgid "To delete, type: %s%s %s %s %d"
|
||||
#~ msgstr "To delete, type: %s%s %s %s %d"
|
||||
|
||||
#, c-format
|
||||
#~ msgid "You cannot %s on this network."
|
||||
#~ msgstr "You cannot %s on this network."
|
||||
|
||||
@@ -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;
|
||||
@@ -145,11 +153,11 @@ public:
|
||||
"It has been created for users that can't host or\n"
|
||||
"configure a bot, or for use on networks that don't\n"
|
||||
"allow user bots. Available commands are listed\n"
|
||||
"below; to use them, type \002%s%s \037command\037\002. For\n"
|
||||
"below; to use them, type \002%s \037command\037\002. For\n"
|
||||
"more information on a specific command, type\n"
|
||||
"\002%s%s %s \037command\037\002.\n"),
|
||||
BotServ->nick.c_str(), Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(),
|
||||
Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), source.command.c_str());
|
||||
"\002%s %s \037command\037\002.\n"),
|
||||
BotServ->nick.c_str(), BotServ->GetQueryCommand().c_str(),
|
||||
BotServ->GetQueryCommand().c_str(), source.command.c_str());
|
||||
}
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
|
||||
@@ -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 &);
|
||||
@@ -430,7 +430,7 @@ public:
|
||||
source.Reply(_("Maintains the \002bad words list\002 for a channel. The bad\n"
|
||||
"words list determines which words are to be kicked\n"
|
||||
"when the bad words kicker is enabled. For more information,\n"
|
||||
"type \002%s%s HELP KICK %s\002.\n"
|
||||
"type \002%s HELP KICK %s\002.\n"
|
||||
" \n"
|
||||
"The \002ADD\002 command adds the given word to the\n"
|
||||
"bad words list. If SINGLE is specified, a kick will be\n"
|
||||
@@ -440,7 +440,7 @@ public:
|
||||
"will be done if a user says a word that ends with\n"
|
||||
"\037word\037. If you don't specify anything, a kick will\n"
|
||||
"be issued every time \037word\037 is said by a user.\n"
|
||||
" \n"), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
|
||||
" \n"), source.service->GetQueryCommand().c_str(), source.command.c_str());
|
||||
source.Reply(_("The \002DEL\002 command removes the given word from the\n"
|
||||
"bad words list. If a list of entry numbers is given, those\n"
|
||||
"entries are deleted. (See the example for LIST below.)\n"
|
||||
|
||||
@@ -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());
|
||||
|
||||
+25
-22
@@ -53,25 +53,28 @@ struct KickerDataImpl final
|
||||
if (kd == NULL)
|
||||
return;
|
||||
|
||||
data.SetType("kickerdata:amsgs", Serialize::Data::DT_INT); data["kickerdata:amsgs"] << kd->amsgs;
|
||||
data.SetType("kickerdata:badwords", Serialize::Data::DT_INT); data["kickerdata:badwords"] << kd->badwords;
|
||||
data.SetType("kickerdata:bolds", Serialize::Data::DT_INT); data["kickerdata:bolds"] << kd->bolds;
|
||||
data.SetType("kickerdata:caps", Serialize::Data::DT_INT); data["kickerdata:caps"] << kd->caps;
|
||||
data.SetType("kickerdata:colors", Serialize::Data::DT_INT); data["kickerdata:colors"] << kd->colors;
|
||||
data.SetType("kickerdata:flood", Serialize::Data::DT_INT); data["kickerdata:flood"] << kd->flood;
|
||||
data.SetType("kickerdata:italics", Serialize::Data::DT_INT); data["kickerdata:italics"] << kd->italics;
|
||||
data.SetType("kickerdata:repeat", Serialize::Data::DT_INT); data["kickerdata:repeat"] << kd->repeat;
|
||||
data.SetType("kickerdata:reverses", Serialize::Data::DT_INT); data["kickerdata:reverses"] << kd->reverses;
|
||||
data.SetType("kickerdata:underlines", Serialize::Data::DT_INT); data["kickerdata:underlines"] << kd->underlines;
|
||||
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;
|
||||
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);
|
||||
|
||||
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
|
||||
@@ -150,11 +153,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
|
||||
source.Reply(_("Type \002%s HELP %s \037option\037\002 for more information\n"
|
||||
"on a specific option.\n"
|
||||
" \n"
|
||||
"Note: access to this command is controlled by the\n"
|
||||
"level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
|
||||
"level SET."), source.service->GetQueryCommand().c_str(), this_name.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -305,12 +308,12 @@ public:
|
||||
"option tells the bot to kick users who say certain words\n"
|
||||
"on the channels.\n"
|
||||
"You can define bad words for your channel using the\n"
|
||||
"\002BADWORDS\002 command. Type \002%s%s HELP BADWORDS\002 for\n"
|
||||
"\002BADWORDS\002 command. Type \002%s HELP BADWORDS\002 for\n"
|
||||
"more information.\n"
|
||||
" \n"
|
||||
"\037ttb\037 is the number of times a user can be kicked\n"
|
||||
"before it gets banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
|
||||
"the ban system once activated."), source.service->GetQueryCommand().c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,8 +58,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
|
||||
"particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
|
||||
source.Reply(_("Type \002%s HELP %s \037option\037\002 for more information on a\n"
|
||||
"particular option."), source.service->GetQueryCommand().c_str(), this_name.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -262,9 +262,9 @@ public:
|
||||
"malicious users from \"taking over\" channels by limiting\n"
|
||||
"who is allowed channel operator privileges. Available\n"
|
||||
"commands are listed below; to use them, type\n"
|
||||
"\002%s%s \037command\037\002. For more information on a\n"
|
||||
"specific command, type \002%s%s HELP \037command\037\002.\n"),
|
||||
ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str());
|
||||
"\002%s \037command\037\002. For more information on a\n"
|
||||
"specific command, type \002%s HELP \037command\037\002.\n"),
|
||||
ChanServ->nick.c_str(), ChanServ->nick.c_str(), ChanServ->GetQueryCommand().c_str(), ChanServ->GetQueryCommand().c_str());
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -382,8 +382,11 @@ public:
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
void OnPostInit() override
|
||||
void OnUplinkSync(Server* s) override
|
||||
{
|
||||
// We need to do this when the uplink is synced as we may not know if
|
||||
// the mode exists before then on some IRCds (e.g. InspIRCd).
|
||||
|
||||
if (!persist)
|
||||
return;
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ class CommandCSAccess final
|
||||
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string mask = params[2];
|
||||
Anope::string description = params.size() > 4 ? params[4] : "";
|
||||
Privilege *p = NULL;
|
||||
int level = ACCESS_INVALID;
|
||||
|
||||
@@ -172,7 +173,11 @@ class CommandCSAccess final
|
||||
{
|
||||
User *targ = User::Find(mask, true);
|
||||
if (targ != NULL)
|
||||
{
|
||||
mask = "*!*@" + targ->GetDisplayedHost();
|
||||
if (description.empty())
|
||||
description = targ->nick;
|
||||
}
|
||||
else
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
|
||||
@@ -216,7 +221,7 @@ class CommandCSAccess final
|
||||
access->level = level;
|
||||
access->last_seen = 0;
|
||||
access->created = Anope::CurTime;
|
||||
access->description = params.size() > 4 ? params[4] : "";
|
||||
access->description = description;
|
||||
ci->AddAccess(access);
|
||||
|
||||
FOREACH_MOD(OnAccessAdd, (ci, source, access));
|
||||
@@ -625,8 +630,8 @@ public:
|
||||
Anope::string cmd;
|
||||
if (Command::FindCommandFromService("chanserv/levels", bi, cmd))
|
||||
source.Reply(_("\002User access levels\002 can be seen by using the\n"
|
||||
"\002%s\002 command; type \002%s%s HELP LEVELS\002 for\n"
|
||||
"information."), cmd.c_str(), Config->StrictPrivmsg.c_str(), bi->nick.c_str());
|
||||
"\002%s\002 command; type \002%s HELP LEVELS\002 for\n"
|
||||
"information."), cmd.c_str(), bi->GetQueryCommand().c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -660,7 +665,10 @@ class CommandCSLevels final
|
||||
{
|
||||
Privilege *p = PrivilegeManager::FindPrivilege(what);
|
||||
if (p == NULL)
|
||||
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
|
||||
{
|
||||
source.Reply(_("Setting \002%s\002 not known. Type \002%s HELP LEVELS\002 for a list of valid settings."),
|
||||
what.c_str(), source.service->GetQueryCommand().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
|
||||
@@ -701,7 +709,8 @@ class CommandCSLevels final
|
||||
return;
|
||||
}
|
||||
|
||||
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
|
||||
source.Reply(_("Setting \002%s\002 not known. Type \002%s HELP LEVELS\002 for a list of valid settings."),
|
||||
what.c_str(), source.service->GetQueryCommand().c_str());
|
||||
}
|
||||
|
||||
static void DoList(CommandSource &source, ChannelInfo *ci)
|
||||
|
||||
@@ -58,8 +58,8 @@ public:
|
||||
*code = Anope::Random(15);
|
||||
}
|
||||
|
||||
source.Reply(CONFIRM_DROP, ci->name.c_str(), Config->StrictPrivmsg.c_str(),
|
||||
source.service->nick.c_str(), ci->name.c_str(), code->c_str());
|
||||
source.Reply(CONFIRM_DROP, ci->name.c_str(), source.service->GetQueryCommand().c_str(),
|
||||
ci->name.c_str(), code->c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -79,7 +79,7 @@ FlagsAccessProvider *FlagsAccessProvider::ap;
|
||||
class CommandCSFlags final
|
||||
: public Command
|
||||
{
|
||||
void DoModify(CommandSource &source, ChannelInfo *ci, Anope::string mask, const Anope::string &flags, const Anope::string &description)
|
||||
void DoModify(CommandSource &source, ChannelInfo *ci, Anope::string mask, const Anope::string &flags, Anope::string description)
|
||||
{
|
||||
if (flags.empty())
|
||||
{
|
||||
@@ -131,7 +131,11 @@ class CommandCSFlags final
|
||||
{
|
||||
User *targ = User::Find(mask, true);
|
||||
if (targ != NULL)
|
||||
{
|
||||
mask = "*!*@" + targ->GetDisplayedHost();
|
||||
if (description.empty())
|
||||
description = targ->nick;
|
||||
}
|
||||
else
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -100,9 +100,9 @@ public:
|
||||
Anope::string cmd;
|
||||
if (Command::FindCommandFromService("chanserv/access", bi, cmd))
|
||||
source.Reply(_(" \n"
|
||||
"See the \002%s\002 command (\002%s%s HELP ACCESS\002) for\n"
|
||||
"See the \002%s\002 command (\002%s HELP ACCESS\002) for\n"
|
||||
"information on giving a subset of these privileges to\n"
|
||||
"other channel users.\n"), cmd.c_str(), Config->StrictPrivmsg.c_str(), bi->nick.c_str());
|
||||
"other channel users.\n"), cmd.c_str(), bi->GetQueryCommand().c_str());
|
||||
source.Reply(_(" \n"
|
||||
"NOTICE: In order to register a channel, you must have\n"
|
||||
"first registered your nickname."));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -59,8 +59,8 @@ public:
|
||||
c->OnServHelp(source);
|
||||
}
|
||||
}
|
||||
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
|
||||
"particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
|
||||
source.Reply(_("Type \002%s HELP %s \037option\037\002 for more information on a\n"
|
||||
"particular option."), source.service->GetQueryCommand().c_str(), this_name.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -513,12 +513,13 @@ public:
|
||||
/* Set the perm mode */
|
||||
if (cm)
|
||||
{
|
||||
if (ci->c && !ci->c->HasMode("PERM"))
|
||||
ci->c->SetMode(NULL, cm);
|
||||
/* Add it to the channels mlock */
|
||||
ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
|
||||
if (ml)
|
||||
ml->SetMLock(cm, true, "", source.GetNick());
|
||||
|
||||
if (ci->c && !ci->c->HasMode("PERM"))
|
||||
ci->c->SetMode(NULL, cm);
|
||||
}
|
||||
/* No botserv bot, no channel mode, give them ChanServ.
|
||||
* Yes, this works fine with no BotServ.
|
||||
@@ -556,12 +557,13 @@ public:
|
||||
/* Unset perm mode */
|
||||
if (cm)
|
||||
{
|
||||
if (ci->c && ci->c->HasMode("PERM"))
|
||||
ci->c->RemoveMode(NULL, cm);
|
||||
/* Remove from mlock */
|
||||
ModeLocks *ml = ci->GetExt<ModeLocks>("modelocks");
|
||||
if (ml)
|
||||
ml->RemoveMLock(cm, true);
|
||||
|
||||
if (ci->c && ci->c->HasMode("PERM"))
|
||||
ci->c->RemoveMode(NULL, cm);
|
||||
}
|
||||
/* No channel mode, no BotServ, but using ChanServ as the botserv bot
|
||||
* which was assigned when persist was set on
|
||||
@@ -1068,7 +1070,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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -11,57 +11,47 @@
|
||||
class StatusUpdate final
|
||||
: public Module
|
||||
{
|
||||
public:
|
||||
StatusUpdate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
|
||||
private:
|
||||
void OnAccessChange(ChannelInfo *ci, ChanAccess *access, bool adding)
|
||||
{
|
||||
if (!ci->c)
|
||||
return;
|
||||
|
||||
for (const auto &[_, uc] : ci->c->users)
|
||||
{
|
||||
auto *user = uc->user;
|
||||
|
||||
ChannelInfo *next;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), next))
|
||||
{
|
||||
auto ag = ci->AccessFor(user);
|
||||
|
||||
for (auto *cms : ModeManager::GetStatusChannelModesByRank())
|
||||
{
|
||||
if (!ag.HasPriv("AUTO" + cms->name))
|
||||
ci->c->RemoveMode(NULL, cms, user->GetUID());
|
||||
}
|
||||
|
||||
if (adding)
|
||||
ci->c->SetCorrectModes(user, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
StatusUpdate(const Anope::string &modname, const Anope::string &creator)
|
||||
: Module(modname, creator, VENDOR)
|
||||
{
|
||||
}
|
||||
|
||||
void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access) override
|
||||
{
|
||||
if (ci->c)
|
||||
{
|
||||
for (const auto &[_, uc] : ci->c->users)
|
||||
{
|
||||
User *user = uc->user;
|
||||
|
||||
ChannelInfo *next;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), next))
|
||||
{
|
||||
AccessGroup ag = ci->AccessFor(user);
|
||||
|
||||
for (auto *cms : ModeManager::GetStatusChannelModesByRank())
|
||||
{
|
||||
if (!ag.HasPriv("AUTO" + cms->name))
|
||||
ci->c->RemoveMode(NULL, cms, user->GetUID());
|
||||
}
|
||||
ci->c->SetCorrectModes(user, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
OnAccessChange(ci, access, true);
|
||||
}
|
||||
|
||||
void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access) override
|
||||
{
|
||||
if (ci->c)
|
||||
{
|
||||
for (const auto &[_, uc] : ci->c->users)
|
||||
{
|
||||
User *user = uc->user;
|
||||
|
||||
ChannelInfo *next;
|
||||
if (user->server != Me && access->Matches(user, user->Account(), next))
|
||||
{
|
||||
AccessGroup ag = ci->AccessFor(user);
|
||||
|
||||
for (auto *cms : ModeManager::GetStatusChannelModesByRank())
|
||||
{
|
||||
if (!ag.HasPriv("AUTO" + cms->name))
|
||||
ci->c->RemoveMode(NULL, cms, user->GetUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
OnAccessChange(ci, access, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -179,7 +179,11 @@ private:
|
||||
{
|
||||
User *targ = User::Find(mask, true);
|
||||
if (targ != NULL)
|
||||
{
|
||||
mask = "*!*@" + targ->GetDisplayedHost();
|
||||
if (description.empty())
|
||||
description = targ->nick;
|
||||
}
|
||||
else
|
||||
{
|
||||
source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
|
||||
@@ -590,11 +594,11 @@ public:
|
||||
source.Reply(_("Alternative methods of modifying channel access lists are\n"
|
||||
"available."));
|
||||
if (!access_cmd.empty())
|
||||
source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
|
||||
"about the access list."), Config->StrictPrivmsg.c_str(), access_bi->nick.c_str(), access_cmd.c_str());
|
||||
source.Reply(_("See \002%s HELP %s\002 for more information\n"
|
||||
"about the access list."), access_bi->GetQueryCommand().c_str(), access_cmd.c_str());
|
||||
if (!flags_cmd.empty())
|
||||
source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
|
||||
"about the flags system."), Config->StrictPrivmsg.c_str(), flags_bi->nick.c_str(), flags_cmd.c_str());
|
||||
source.Reply(_("See \002%s HELP %s\002 for more information\n"
|
||||
"about the flags system."), flags_bi->GetQueryCommand().c_str(), flags_cmd.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1393,7 +1393,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ot = OperType::Find(type);
|
||||
auto *ot = OperType::Find(type);
|
||||
if (!ot)
|
||||
{
|
||||
// Attempt to convert oper types.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -139,8 +139,19 @@ public:
|
||||
, argon2dprovider(this, Argon2_d)
|
||||
, argon2iprovider(this, Argon2_i)
|
||||
, argon2idprovider(this, Argon2_id)
|
||||
|
||||
{
|
||||
argon2dprovider.Check({
|
||||
{ "$argon2d$v=19$m=10,t=10,p=1$VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw$fNS8JrvE8EqKwQ", "" },
|
||||
{ "$argon2d$v=19$m=10,t=10,p=1$VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw$hTvpprMF0TwszQ", "The quick brown fox jumps over the lazy dog" },
|
||||
});
|
||||
argon2iprovider.Check({
|
||||
{ "$argon2i$v=19$m=10,t=10,p=1$VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw$neE6hYxRp4TCJA", "" },
|
||||
{ "$argon2i$v=19$m=10,t=10,p=1$VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw$/JAt4FdP1MFD+A", "The quick brown fox jumps over the lazy dog" },
|
||||
});
|
||||
argon2idprovider.Check({
|
||||
{ "$argon2id$v=19$m=10,t=10,p=1$VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw$wuNeHixFDS6Tkg", "" },
|
||||
{ "$argon2id$v=19$m=10,t=10,p=1$VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw$Po8RcmxZ7vHmdg", "The quick brown fox jumps over the lazy dog" },
|
||||
});
|
||||
}
|
||||
|
||||
void OnReload(Configuration::Conf *conf) override
|
||||
|
||||
+60
-21
@@ -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();
|
||||
}
|
||||
@@ -407,17 +433,13 @@ 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";
|
||||
else
|
||||
query_text += "text";
|
||||
query_text += ", `" + column + "` " + GetColumnType(data.GetType(column));
|
||||
}
|
||||
query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`)) ROW_FORMAT=DYNAMIC";
|
||||
queries.push_back(query_text);
|
||||
@@ -431,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";
|
||||
else
|
||||
query_text += "text";
|
||||
Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + column + "` " + GetColumnType(data.GetType(column));
|
||||
|
||||
queries.push_back(query_text);
|
||||
}
|
||||
@@ -471,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);
|
||||
@@ -496,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
@@ -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;
|
||||
|
||||
@@ -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"))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
if (ci->AccessFor(cu->user).HasPriv("MEMO"))
|
||||
{
|
||||
if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE"))
|
||||
cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), mi->memos->size());
|
||||
cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), MemoServ->GetQueryCommand().c_str(), ci->name.c_str(), mi->memos->size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
{
|
||||
User *user = User::Find(na->nick, true);
|
||||
if (user && user->IsIdentified())
|
||||
user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), mi->memos->size());
|
||||
user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), MemoServ->GetQueryCommand().c_str(), mi->memos->size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,8 +229,8 @@ public:
|
||||
if (!params.empty() || source.c || source.service != *MemoServ)
|
||||
return;
|
||||
source.Reply(_(" \n"
|
||||
"Type \002%s%s HELP \037command\037\002 for help on any of the\n"
|
||||
"above commands."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str());
|
||||
"Type \002%s HELP \037command\037\002 for help on any of the\n"
|
||||
"above commands."), MemoServ->GetQueryCommand().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -91,9 +91,9 @@ public:
|
||||
if (Command::FindCommandFromService("memoserv/del", bi, cmd))
|
||||
{
|
||||
if (ci)
|
||||
source.Reply(_("To delete, type: \002%s%s %s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), ci->name.c_str(), index + 1);
|
||||
source.Reply(_("To delete, type: \002%s %s %s %d\002"), bi->GetQueryCommand().c_str(), cmd.c_str(), ci->name.c_str(), index + 1);
|
||||
else
|
||||
source.Reply(_("To delete, type: \002%s%s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), index + 1);
|
||||
source.Reply(_("To delete, type: \002%s %s %d\002"), bi->GetQueryCommand().c_str(), cmd.c_str(), index + 1);
|
||||
}
|
||||
|
||||
source.Reply("%s", m->text.c_str());
|
||||
|
||||
@@ -232,8 +232,8 @@ public:
|
||||
" LIMIT Sets the maximum number of memos you can\n"
|
||||
" receive\n"
|
||||
" \n"
|
||||
"Type \002%s%s HELP %s \037option\037\002 for more information\n"
|
||||
"on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
|
||||
"Type \002%s HELP %s \037option\037\002 for more information\n"
|
||||
"on a specific option."), source.service->GetQueryCommand().c_str(), source.command.c_str());
|
||||
}
|
||||
else if (subcommand.equals_ci("NOTIFY"))
|
||||
source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
|
||||
|
||||
@@ -98,7 +98,7 @@ class NickServRelease final
|
||||
|
||||
public:
|
||||
NickServRelease(Module *me, NickAlias *na, time_t delay)
|
||||
: User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser", "user"), Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost", Me->GetName()), "", "", Me, "Services Enforcer", Anope::CurTime, "", IRCD->UID_Retrieve(), NULL)
|
||||
: User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser", "user"), Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost", Me->GetName()), "", "", Me, "Services Enforcer", Anope::CurTime, "", {}, IRCD->UID_Retrieve(), NULL)
|
||||
, Timer(me, delay)
|
||||
, nick(na->nick)
|
||||
{
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
|
||||
if (!na->nc->HasExt("KILL_IMMED"))
|
||||
{
|
||||
u->SendMessage(NickServ, NICK_IS_SECURE, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
|
||||
u->SendMessage(NickServ, NICK_IS_SECURE, NickServ->GetQueryCommand().c_str());
|
||||
}
|
||||
if (na->nc->HasExt("KILLPROTECT"))
|
||||
{
|
||||
@@ -362,8 +362,8 @@ public:
|
||||
u->SendMessage(NickServ, _("You must now supply an email for your nick.\n"
|
||||
"This email will allow you to retrieve your password in\n"
|
||||
"case you forget it."));
|
||||
u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037email\037\002 in order to set your email."),
|
||||
Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
|
||||
u->SendMessage(NickServ, _("Type \002%s SET EMAIL \037email\037\002 in order to set your email."),
|
||||
NickServ->GetQueryCommand().c_str());
|
||||
}
|
||||
|
||||
for (auto *c : collides)
|
||||
@@ -465,15 +465,15 @@ public:
|
||||
source.Reply(_("\002%s\002 allows you to register a nickname and\n"
|
||||
"prevent others from using it. The following\n"
|
||||
"commands allow for registration and maintenance of\n"
|
||||
"nicknames; to use them, type \002%s%s \037command\037\002.\n"
|
||||
"nicknames; to use them, type \002%s \037command\037\002.\n"
|
||||
"For more information on a specific command, type\n"
|
||||
"\002%s%s %s \037command\037\002.\n"), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
|
||||
"\002%s %s \037command\037\002.\n"), NickServ->nick.c_str(), NickServ->GetQueryCommand().c_str(), NickServ->GetQueryCommand().c_str(), source.command.c_str());
|
||||
else
|
||||
source.Reply(_("\002%s\002 allows you to register an account.\n"
|
||||
"The following commands allow for registration and maintenance of\n"
|
||||
"accounts; to use them, type \002%s%s \037command\037\002.\n"
|
||||
"accounts; to use them, type \002%s \037command\037\002.\n"
|
||||
"For more information on a specific command, type\n"
|
||||
"\002%s%s %s \037command\037\002.\n"), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
|
||||
"\002%s %s \037command\037\002.\n"), NickServ->nick.c_str(), NickServ->GetQueryCommand().c_str(), NickServ->GetQueryCommand().c_str(), source.command.c_str());
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -486,7 +486,7 @@ public:
|
||||
"Services Operators can also drop any nickname without needing\n"
|
||||
"to identify for the nick, and may view the access list for\n"
|
||||
"any nickname."));
|
||||
time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "90d");
|
||||
time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "1y");
|
||||
if (nickserv_expire >= 86400)
|
||||
source.Reply(_(" \n"
|
||||
"Accounts that are not used anymore are subject to\n"
|
||||
@@ -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)
|
||||
@@ -551,7 +554,7 @@ public:
|
||||
{
|
||||
if (!na->nc->HasExt("UNCONFIRMED"))
|
||||
{
|
||||
time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "90d");
|
||||
time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire", "1y");
|
||||
if (!na->HasExt("NS_NO_EXPIRE") && nickserv_expire && !Anope::NoExpire && (source.HasPriv("nickserv/auspex") || na->last_seen != Anope::CurTime))
|
||||
info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire, source.GetAccount());
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -168,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
|
||||
@@ -423,6 +425,9 @@ public:
|
||||
|
||||
auto *cl = certs.Require(na->nc);
|
||||
cl->AddCert(u->fingerprint);
|
||||
|
||||
auto *NickServ = Config->GetClient("NickServ");
|
||||
u->SendMessage(NickServ, _("Your SSL certificate fingerprint \002%s\002 has been automatically added to your certificate list."), u->fingerprint.c_str());
|
||||
}
|
||||
|
||||
EventReturn OnNickValidate(User *u, NickAlias *na) override
|
||||
|
||||
@@ -57,6 +57,12 @@ 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])) && (!source.HasPriv("nickserv/drop/override") || params[1] != "OVERRIDE")))
|
||||
{
|
||||
@@ -66,8 +72,8 @@ public:
|
||||
*code = Anope::Random(15);
|
||||
}
|
||||
|
||||
source.Reply(CONFIRM_DROP, na->nick.c_str(), Config->StrictPrivmsg.c_str(),
|
||||
source.service->nick.c_str(), na->nick.c_str(), code->c_str());
|
||||
source.Reply(CONFIRM_DROP, na->nick.c_str(), source.service->GetQueryCommand().c_str(),
|
||||
na->nick.c_str(), code->c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -89,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;
|
||||
|
||||
+7
-119
@@ -57,8 +57,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
|
||||
"on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
|
||||
source.Reply(_("Type \002%s HELP %s \037option\037\002 for more information\n"
|
||||
"on a specific option."), source.service->GetQueryCommand().c_str(), this_name.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -100,9 +100,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
|
||||
source.Reply(_("Type \002%s HELP %s \037option\037\002 for more information\n"
|
||||
"on a specific option. The options will be set on the given\n"
|
||||
"\037nickname\037."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
|
||||
"\037nickname\037."), source.service->GetQueryCommand().c_str(), this_name.c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -892,112 +892,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSetMessage
|
||||
: public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1) : Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Change the communication method of services"));
|
||||
this->SetSyntax("{ON | OFF}");
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m)
|
||||
{
|
||||
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;
|
||||
|
||||
if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
|
||||
{
|
||||
source.Reply(_("You cannot %s on this network."), source.command.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
EventReturn MOD_RESULT;
|
||||
FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param));
|
||||
if (MOD_RESULT == EVENT_STOP)
|
||||
return;
|
||||
|
||||
if (param.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->display;
|
||||
nc->Extend<bool>("MSG");
|
||||
source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->display;
|
||||
nc->Shrink<bool>("MSG");
|
||||
source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "MSG");
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
{
|
||||
this->Run(source, source.nc->display, params[0]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) override
|
||||
{
|
||||
Anope::string cmd = source.command;
|
||||
size_t i = cmd.find_last_of(' ');
|
||||
if (i != Anope::string::npos)
|
||||
cmd = cmd.substr(i + 1);
|
||||
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to choose the way services are communicating with\n"
|
||||
"you. With \002%s\002 set, services will use messages, else they'll\n"
|
||||
"use notices."), cmd.upper().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnServHelp(CommandSource &source) override
|
||||
{
|
||||
if (Config->GetBlock("options")->Get<bool>("useprivmsg"))
|
||||
Command::OnServHelp(source);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetMessage final
|
||||
: public CommandNSSetMessage
|
||||
{
|
||||
public:
|
||||
CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2)
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to choose the way services are communicating with\n"
|
||||
"the given user. With \002MSG\002 set, services will use messages,\n"
|
||||
"else they'll use notices."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
{
|
||||
this->Run(source, params[0], params[1]);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetNoexpire final
|
||||
: public Command
|
||||
{
|
||||
@@ -1075,16 +969,13 @@ class NSSet final
|
||||
CommandNSSetKill commandnssetkill;
|
||||
CommandNSSASetKill commandnssasetkill;
|
||||
|
||||
CommandNSSetMessage commandnssetmessage;
|
||||
CommandNSSASetMessage commandnssasetmessage;
|
||||
|
||||
CommandNSSetPassword commandnssetpassword;
|
||||
CommandNSSASetPassword commandnssasetpassword;
|
||||
|
||||
CommandNSSASetNoexpire commandnssasetnoexpire;
|
||||
|
||||
SerializableExtensibleItem<bool> autoop, neverop, killprotect, kill_quick, kill_immed,
|
||||
message, noexpire;
|
||||
noexpire;
|
||||
|
||||
struct KeepModes final
|
||||
: SerializableExtensibleItem<bool>
|
||||
@@ -1108,7 +999,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
|
||||
@@ -1145,13 +1036,12 @@ public:
|
||||
commandnssetemail(this), commandnssasetemail(this),
|
||||
commandnssetkeepmodes(this), commandnssasetkeepmodes(this),
|
||||
commandnssetkill(this), commandnssasetkill(this),
|
||||
commandnssetmessage(this), commandnssasetmessage(this),
|
||||
commandnssetpassword(this), commandnssasetpassword(this),
|
||||
commandnssasetnoexpire(this),
|
||||
|
||||
autoop(this, "AUTOOP"), neverop(this, "NEVEROP"),
|
||||
killprotect(this, "KILLPROTECT"), kill_quick(this, "KILL_QUICK"),
|
||||
kill_immed(this, "KILL_IMMED"), message(this, "MSG"),
|
||||
kill_immed(this, "KILL_IMMED"),
|
||||
noexpire(this, "NS_NO_EXPIRE"),
|
||||
|
||||
keep_modes(this, "NS_KEEP_MODES"), ns_set_email(this, "ns_set_email")
|
||||
@@ -1208,8 +1098,6 @@ public:
|
||||
info.AddOption(_("Quick protection"));
|
||||
else if (killprotect.HasExt(na->nc))
|
||||
info.AddOption(_("Protection"));
|
||||
if (message.HasExt(na->nc))
|
||||
info.AddOption(_("Message mode"));
|
||||
if (autoop.HasExt(na->nc))
|
||||
info.AddOption(_("Auto-op"));
|
||||
if (neverop.HasExt(na->nc))
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/* 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 CommandNSSetMessage
|
||||
: public Command
|
||||
{
|
||||
public:
|
||||
CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1)
|
||||
: Command(creator, sname, min, min + 1)
|
||||
{
|
||||
this->SetDesc(_("Change the communication method of services"));
|
||||
this->SetSyntax("{ON | OFF}");
|
||||
}
|
||||
|
||||
void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m)
|
||||
{
|
||||
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.equals_ci("ON"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable " << source.command << " for " << nc->display;
|
||||
nc->Extend<bool>("MSG");
|
||||
source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str());
|
||||
}
|
||||
else if (param.equals_ci("OFF"))
|
||||
{
|
||||
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable " << source.command << " for " << nc->display;
|
||||
nc->Shrink<bool>("MSG");
|
||||
source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, "MSG");
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
{
|
||||
this->Run(source, source.nc->display, params[0]);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) override
|
||||
{
|
||||
Anope::string cmd = source.command;
|
||||
size_t i = cmd.find_last_of(' ');
|
||||
if (i != Anope::string::npos)
|
||||
cmd = cmd.substr(i + 1);
|
||||
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to choose the way services are communicating with\n"
|
||||
"you. With \002%s\002 set, services will use messages, else they'll\n"
|
||||
"use notices."), cmd.upper().c_str());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandNSSASetMessage final
|
||||
: public CommandNSSetMessage
|
||||
{
|
||||
public:
|
||||
CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2)
|
||||
{
|
||||
this->ClearSyntax();
|
||||
this->SetSyntax(_("\037nickname\037 {ON | OFF}"));
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &) override
|
||||
{
|
||||
this->SendSyntax(source);
|
||||
source.Reply(" ");
|
||||
source.Reply(_("Allows you to choose the way services are communicating with\n"
|
||||
"the given user. With \002MSG\002 set, services will use messages,\n"
|
||||
"else they'll use notices."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override
|
||||
{
|
||||
this->Run(source, params[0], params[1]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class NSSetMessage final
|
||||
: public Module
|
||||
{
|
||||
private:
|
||||
CommandNSSetMessage commandnssetmessage;
|
||||
CommandNSSASetMessage commandnssasetmessage;
|
||||
SerializableExtensibleItem<bool> message;
|
||||
|
||||
public:
|
||||
NSSetMessage(const Anope::string &modname, const Anope::string &creator)
|
||||
: Module(modname, creator, VENDOR)
|
||||
, commandnssetmessage(this)
|
||||
, commandnssasetmessage(this)
|
||||
, message(this, "MSG")
|
||||
{
|
||||
}
|
||||
|
||||
void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) override
|
||||
{
|
||||
if (!show_hidden)
|
||||
return;
|
||||
if (message.HasExt(na->nc))
|
||||
info.AddOption(_("Message mode"));
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(NSSetMessage)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -312,12 +312,8 @@ struct IRCDMessageMode final
|
||||
Channel *c = Channel::Find(params[0]);
|
||||
auto ts = IRCD->ExtractTimestamp(params[1]);
|
||||
|
||||
Anope::string modes = params[2];
|
||||
for (unsigned int i = 3; i < params.size(); ++i)
|
||||
modes += " " + params[i];
|
||||
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes, ts);
|
||||
c->SetModesInternal(source, params[2], { params.begin() + 3, params.end() }, ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -400,11 +396,12 @@ struct IRCDMessageSJoin final
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
Anope::string modes;
|
||||
std::vector<Anope::string> modeparams;
|
||||
if (params.size() >= 4)
|
||||
for (unsigned i = 2; i < params.size(); ++i)
|
||||
modes += " " + params[i];
|
||||
if (!modes.empty())
|
||||
modes.erase(modes.begin());
|
||||
{
|
||||
modes = params[2];
|
||||
modeparams = { params.begin() + 3, params.end() };
|
||||
}
|
||||
|
||||
std::list<Message::Join::SJoinUser> users;
|
||||
|
||||
@@ -445,7 +442,7 @@ struct IRCDMessageSJoin final
|
||||
}
|
||||
|
||||
auto ts = IRCD->ExtractTimestamp(params[0]);
|
||||
Message::Join::SJoin(source, params[1], ts, modes, users);
|
||||
Message::Join::SJoin(source, params[1], ts, modes, modeparams, users);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -547,14 +547,6 @@ struct IRCDMessageSJoin final
|
||||
/* :0MC SJOIN 1654877335 #nether +nt :@0MCAAAAAB +0MCAAAAAC */
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
Anope::string modes;
|
||||
|
||||
for (unsigned i = 2; i < params.size() - 1; ++i)
|
||||
modes += " " + params[i];
|
||||
|
||||
if (!modes.empty())
|
||||
modes.erase(modes.begin());
|
||||
|
||||
std::list<Message::Join::SJoinUser> users;
|
||||
|
||||
spacesepstream sep(params[params.size() - 1]);
|
||||
@@ -582,7 +574,7 @@ struct IRCDMessageSJoin final
|
||||
}
|
||||
|
||||
auto ts = IRCD->ExtractTimestamp(params[0]);
|
||||
Message::Join::SJoin(source, params[1], ts, modes, users);
|
||||
Message::Join::SJoin(source, params[1], ts, params[2], { params.begin() + 3, params.end() - 1 }, users);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -637,13 +629,9 @@ struct IRCDMessageTMode final
|
||||
{
|
||||
auto ts = IRCD->ExtractTimestamp(params[0]);
|
||||
Channel *c = Channel::Find(params[1]);
|
||||
Anope::string modes = params[2];
|
||||
|
||||
for (unsigned i = 3; i < params.size(); ++i)
|
||||
modes += " " + params[i];
|
||||
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes, ts);
|
||||
c->SetModesInternal(source, params[2], { params.begin() + 3, params.end() }, ts);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ struct SASLUser final
|
||||
|
||||
namespace
|
||||
{
|
||||
/** Whether we should send extbans using their named form. */
|
||||
bool named_extbans = false;
|
||||
|
||||
// The SID of a server we are waiting to squit.
|
||||
Anope::string rsquit_id;
|
||||
|
||||
@@ -42,6 +45,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)
|
||||
{
|
||||
@@ -86,7 +105,7 @@ class InspIRCdProto final
|
||||
private:
|
||||
static Anope::string GetAccountNicks(NickAlias* na)
|
||||
{
|
||||
if (!na)
|
||||
if (!na || Config->GetModule("nickserv")->Get<bool>("nonicknameownership"))
|
||||
return {};
|
||||
|
||||
Anope::string nicks;
|
||||
@@ -509,9 +528,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 ¶m) override
|
||||
@@ -562,8 +584,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
|
||||
@@ -615,9 +640,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SendOper(User *u) override
|
||||
{
|
||||
if (spanningtree_proto_ver < 1206)
|
||||
return; // We can't force an oper on this version.
|
||||
|
||||
const Anope::map<Anope::string> tags = {
|
||||
{ "~automatic", "" },
|
||||
};
|
||||
Uplink::Send(tags, "SVSOPER", u->GetUID(), u->Account()->o->ot->GetName());
|
||||
}
|
||||
|
||||
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
|
||||
@@ -688,7 +726,8 @@ namespace InspIRCdExtBan
|
||||
|
||||
ChannelMode *Wrap(Anope::string ¶m) override
|
||||
{
|
||||
param = Anope::string(xbchar) + ":" + param;
|
||||
auto xbprefix = named_extbans || !xbchar ? xbname : Anope::string(xbchar);
|
||||
param = xbprefix + ":" + param;
|
||||
return ChannelModeVirtual<ChannelModeList>::Wrap(param);
|
||||
}
|
||||
|
||||
@@ -698,19 +737,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;
|
||||
}
|
||||
};
|
||||
@@ -726,10 +761,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
return Entry(this->name, real_mask).Matches(u);
|
||||
return Entry(this->name, e->GetMask()).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -744,10 +776,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
|
||||
Anope::string channel = mask.substr(2);
|
||||
|
||||
auto channel = e->GetMask();
|
||||
ChannelMode *cm = NULL;
|
||||
if (channel[0] != '#')
|
||||
{
|
||||
@@ -782,10 +811,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
|
||||
return u->IsIdentified() && real_mask.equals_ci(u->Account()->display);
|
||||
return u->IsIdentified() && e->GetMask().equals_ci(u->Account()->display);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -800,9 +826,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
return Anope::Match(u->realname, real_mask);
|
||||
return Anope::Match(u->realname, e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -817,9 +841,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
return Anope::Match(u->server->GetName(), real_mask);
|
||||
return Anope::Match(u->server->GetName(), e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -834,9 +856,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
return !u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask);
|
||||
return !u->fingerprint.empty() && Anope::Match(u->fingerprint, e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -851,9 +871,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
return !u->Account() && Entry("BAN", real_mask).Matches(u);
|
||||
return !u->Account() && Entry(this->base, e->GetMask()).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -872,9 +890,7 @@ namespace InspIRCdExtBan
|
||||
if (!opertype)
|
||||
return false; // Not an operator.
|
||||
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(2);
|
||||
return Anope::Match(opertype->replace_all_cs(' ', '_'), real_mask);
|
||||
return Anope::Match(opertype->replace_all_cs(' ', '_'), e->GetMask());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1060,19 +1076,25 @@ struct IRCDMessageCapab final
|
||||
|
||||
static bool ParseExtBan(const Anope::string &token, ExtBanInfo &extban)
|
||||
{
|
||||
// acting:foo=f matching:foo=f
|
||||
// A B A B
|
||||
// acting:foo=f matching:bar=b matching:baz
|
||||
// A B A B A
|
||||
auto a = token.find(':');
|
||||
if (a == Anope::string::npos)
|
||||
return false;
|
||||
|
||||
auto b = token.find(':', a + 1);
|
||||
auto b = token.find('=', a + 1);
|
||||
if (b == Anope::string::npos)
|
||||
return false;
|
||||
|
||||
{
|
||||
// ExtBan only has a name.
|
||||
extban.name = token.substr(a + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ExtBan has a name and letter.
|
||||
extban.name = token.substr(a + 1, b - a - 1);
|
||||
extban.letter = token[b + 1];
|
||||
}
|
||||
extban.type = token.substr(0, a);
|
||||
extban.name = token.substr(a + 1, b - a - 1);
|
||||
extban.letter = token[b + 1];
|
||||
|
||||
if (Anope::ProtocolDebug)
|
||||
Log(LOG_DEBUG) << "Parsed extban: type=" << extban.type << " name=" << extban.name << " letter=" << extban.letter;
|
||||
@@ -1542,6 +1564,8 @@ struct IRCDMessageCapab final
|
||||
auto [tokname, tokvalue] = ParseCapability(capab);
|
||||
if (tokname == "CHALLENGE")
|
||||
challenge = tokvalue;
|
||||
if (tokname == "EXTBANFORMAT")
|
||||
named_extbans = tokvalue.equals_ci("any") || tokvalue.equals_ci("name");
|
||||
else if (tokname == "MAXCHANNEL")
|
||||
IRCD->MaxChannel = Anope::Convert<size_t>(tokvalue, IRCD->MaxChannel);
|
||||
else if (tokname == "MAXHOST")
|
||||
@@ -2025,15 +2049,6 @@ struct IRCDMessageFJoin final
|
||||
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
Anope::string modes;
|
||||
if (params.size() >= 3)
|
||||
{
|
||||
for (unsigned i = 2; i < params.size() - 1; ++i)
|
||||
modes += " " + params[i];
|
||||
if (!modes.empty())
|
||||
modes.erase(modes.begin());
|
||||
}
|
||||
|
||||
std::list<Message::Join::SJoinUser> users;
|
||||
|
||||
spacesepstream sep(params[params.size() - 1]);
|
||||
@@ -2071,7 +2086,7 @@ struct IRCDMessageFJoin final
|
||||
}
|
||||
|
||||
auto ts = IRCD->ExtractTimestamp(params[1]);
|
||||
Message::Join::SJoin(source, params[0], ts, modes, users);
|
||||
Message::Join::SJoin(source, params[0], ts, params[2], { params.begin() + 3, params.end() - 1 }, users);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2083,15 +2098,10 @@ struct IRCDMessageFMode final
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
/* :source FMODE #test 12345678 +nto foo */
|
||||
|
||||
Anope::string modes = params[2];
|
||||
for (unsigned n = 3; n < params.size(); ++n)
|
||||
modes += " " + params[n];
|
||||
|
||||
Channel *c = Channel::Find(params[0]);
|
||||
auto ts = IRCD->ExtractTimestamp(params[1]);
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes, ts);
|
||||
c->SetModesInternal(source, params[2], { params.begin() + 3, params.end() }, ts);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2167,7 +2177,7 @@ struct IRCDMessageIJoin final
|
||||
|
||||
std::list<Message::Join::SJoinUser> users;
|
||||
users.push_back(user);
|
||||
Message::Join::SJoin(source, params[0], chants, "", users);
|
||||
Message::Join::SJoin(source, params[0], chants, "", {}, users);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2219,12 +2229,8 @@ struct IRCDMessageMode final
|
||||
{
|
||||
Channel *c = Channel::Find(params[0]);
|
||||
|
||||
Anope::string modes = params[1];
|
||||
for (unsigned n = 2; n < params.size(); ++n)
|
||||
modes += " " + params[n];
|
||||
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes);
|
||||
c->SetModesInternal(source, params[2], { params.begin() + 3, params.end() });
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2384,10 +2390,6 @@ struct IRCDMessageUID final
|
||||
size_t offset = params[8][0] == '+' ? 0 : 1;
|
||||
auto ts = IRCD->ExtractTimestamp(params[1]);
|
||||
|
||||
Anope::string modes = params[8+offset];
|
||||
for (unsigned i = 9+offset; i < params.size() - 1; ++i)
|
||||
modes += " " + params[i];
|
||||
|
||||
NickAlias *na = NULL;
|
||||
if (SASL::sasl)
|
||||
for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();)
|
||||
@@ -2405,7 +2407,7 @@ struct IRCDMessageUID final
|
||||
++it;
|
||||
}
|
||||
|
||||
User *u = User::OnIntroduce(params[2], params[5+offset], params[3], params[4], params[6+offset], source.GetServer(), params[params.size() - 1], ts, modes, params[0], na ? *na->nc : NULL);
|
||||
auto *u = User::OnIntroduce(params[2], params[5+offset], params[3], params[4], params[6+offset], source.GetServer(), params[params.size() - 1], ts, params[8 + offset], params[0], na ? *na->nc : NULL, { params.begin() + 9 + offset, params.end() - 1 });
|
||||
if (u)
|
||||
u->signon = IRCD->ExtractTimestamp(params[7+offset]);
|
||||
}
|
||||
|
||||
+10
-13
@@ -224,7 +224,7 @@ struct IRCDMessageChaninfo final
|
||||
bool created;
|
||||
Channel *c = Channel::FindOrCreate(params[0], created);
|
||||
|
||||
Anope::string modes = params[1];
|
||||
std::vector<Anope::string> modeparams;
|
||||
|
||||
if (params.size() == 3)
|
||||
{
|
||||
@@ -237,17 +237,17 @@ struct IRCDMessageChaninfo final
|
||||
switch(params[1][i])
|
||||
{
|
||||
case 'k':
|
||||
modes += " " + params[2];
|
||||
modeparams.push_back(params[2]);
|
||||
continue;
|
||||
case 'l':
|
||||
modes += " " + params[3];
|
||||
modeparams.push_back(params[3]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
c->ChangeTopicInternal(NULL, source.GetName(), params[4], Anope::CurTime);
|
||||
}
|
||||
|
||||
c->SetModesInternal(source, modes);
|
||||
c->SetModesInternal(source, params[1], modeparams);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -267,11 +267,13 @@ struct IRCDMessageJoin final
|
||||
User *user = source.GetUser();
|
||||
size_t pos = params[0].find('\7');
|
||||
Anope::string channel, modes;
|
||||
std::vector<Anope::string> modeparams;
|
||||
|
||||
if (pos != Anope::string::npos)
|
||||
{
|
||||
channel = params[0].substr(0, pos);
|
||||
modes = '+' + params[0].substr(pos+1, params[0].length()) + " " + user->nick;
|
||||
modes = '+' + params[0].substr(pos+1, params[0].length());
|
||||
modeparams.push_back(user->nick);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -287,7 +289,7 @@ struct IRCDMessageJoin final
|
||||
{
|
||||
Channel *c = Channel::Find(channel);
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes);
|
||||
c->SetModesInternal(source, modes, modeparams);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -367,17 +369,12 @@ struct IRCDMessageMode final
|
||||
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
Anope::string modes = params[1];
|
||||
|
||||
for (size_t i = 2; i < params.size(); ++i)
|
||||
modes += " " + params[i];
|
||||
|
||||
if (IRCD->IsChannelValid(params[0]))
|
||||
{
|
||||
Channel *c = Channel::Find(params[0]);
|
||||
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes);
|
||||
c->SetModesInternal(source, params[1], { params.begin() + 2, params.end() });
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -485,7 +482,7 @@ struct IRCDMessageNJoin final
|
||||
users.push_back(sju);
|
||||
}
|
||||
|
||||
Message::Join::SJoin(source, params[0], 0, "", users);
|
||||
Message::Join::SJoin(source, params[0], 0, "", {}, users);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -164,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 ¶m) 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);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class RatboxProto final
|
||||
}
|
||||
|
||||
public:
|
||||
RatboxProto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+")
|
||||
RatboxProto(Module *creator) : IRCDProto(creator, "ircd-ratbox 3+")
|
||||
{
|
||||
DefaultPseudoclientModes = "+oiS";
|
||||
CanSNLine = true;
|
||||
|
||||
+181
-146
@@ -14,7 +14,25 @@
|
||||
#include "modules/sasl.h"
|
||||
|
||||
typedef Anope::map<Anope::string> ModData;
|
||||
static Anope::string UplinkSID;
|
||||
|
||||
namespace
|
||||
{
|
||||
Anope::string UplinkSID;
|
||||
|
||||
bool IsExtBan(const Anope::string &str, Anope::string &name, Anope::string &value)
|
||||
{
|
||||
if (str[0] != '~')
|
||||
return false;
|
||||
|
||||
auto endpos = str.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1);
|
||||
if (endpos == Anope::string::npos || str[endpos] != ':' || endpos+1 == str.length())
|
||||
return false;
|
||||
|
||||
name = str.substr(1, endpos - 1);
|
||||
value = str.substr(endpos + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class UnrealIRCdProto final
|
||||
: public IRCDProto
|
||||
@@ -23,7 +41,10 @@ public:
|
||||
PrimitiveExtensibleItem<ModData> ClientModData;
|
||||
PrimitiveExtensibleItem<ModData> ChannelModData;
|
||||
|
||||
UnrealIRCdProto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4+"), ClientModData(creator, "ClientModData"), ChannelModData(creator, "ChannelModData")
|
||||
UnrealIRCdProto(Module *creator)
|
||||
: IRCDProto(creator, "UnrealIRCd 6+")
|
||||
, ClientModData(creator, "ClientModData")
|
||||
, ChannelModData(creator, "ChannelModData")
|
||||
{
|
||||
DefaultPseudoclientModes = "+BioqS";
|
||||
CanSVSNick = true;
|
||||
@@ -216,21 +237,16 @@ private:
|
||||
|
||||
void SendConnect() override
|
||||
{
|
||||
/*
|
||||
NICKv2 = Nick Version 2
|
||||
VHP = Sends hidden host
|
||||
UMODE2 = sends UMODE2 on user modes
|
||||
NICKIP = Sends IP on NICK
|
||||
SJ3 = Supports SJOIN
|
||||
NOQUIT = No Quit
|
||||
TKLEXT = Extended TKL we don't use it but best to have it
|
||||
MLOCK = Supports the MLOCK server command
|
||||
VL = Version Info
|
||||
SID = SID/UID mode
|
||||
*/
|
||||
Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password);
|
||||
|
||||
Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID", "MTAGS", "BIGLINES");
|
||||
// BIGLINES: enable sending lines up to 16384 characters in length.
|
||||
// EAUTH: communicates information about the local server.
|
||||
// MLOCK: enable receiving the MLOCK message when a mode lock changes.
|
||||
// MTAGS: enable receiving IRCv3 message tags.
|
||||
// NEXTBANS: enables receiving named extended bans.
|
||||
// SID: communicates the unique identifier of the local server.
|
||||
// VHP: enable receiving the vhost in UID.
|
||||
Uplink::Send("PROTOCTL", "BIGLINES", "MLOCK", "MTAGS", "NEXTBANS", "VHP");
|
||||
Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort());
|
||||
Uplink::Send("PROTOCTL", "SID=" + Me->GetSID());
|
||||
|
||||
@@ -299,12 +315,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 ¶m) 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 ¶m) override
|
||||
@@ -348,16 +364,14 @@ private:
|
||||
|
||||
bool IsExtbanValid(const Anope::string &mask) override
|
||||
{
|
||||
return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
|
||||
Anope::string name, value;
|
||||
return IsExtBan(mask, name, value);
|
||||
}
|
||||
|
||||
void SendLogin(User *u, NickAlias *na) override
|
||||
{
|
||||
/* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */
|
||||
if (Servers::Capab.count("ESVID") > 0 && !na->nc->HasExt("UNCONFIRMED"))
|
||||
if (!na->nc->HasExt("UNCONFIRMED"))
|
||||
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d", na->nc->display);
|
||||
else
|
||||
IRCD->SendMode(Config->GetClient("NickServ"), u, "+d", u->signon);
|
||||
}
|
||||
|
||||
void SendLogout(User *u) override
|
||||
@@ -448,54 +462,65 @@ private:
|
||||
|
||||
bool IsTagValid(const Anope::string &tname, const Anope::string &tvalue) override
|
||||
{
|
||||
if (Servers::Capab.count("MTAGS"))
|
||||
return true;
|
||||
return false;
|
||||
return !!Servers::Capab.count("MTAGS");
|
||||
}
|
||||
};
|
||||
|
||||
class UnrealExtBan
|
||||
: public ChannelModeVirtual<ChannelModeList>
|
||||
namespace UnrealExtBan
|
||||
{
|
||||
char ext;
|
||||
|
||||
public:
|
||||
UnrealExtBan(const Anope::string &mname, const Anope::string &basename, char extban) : ChannelModeVirtual<ChannelModeList>(mname, basename)
|
||||
, ext(extban)
|
||||
class Base
|
||||
: public ChannelModeVirtual<ChannelModeList>
|
||||
{
|
||||
}
|
||||
private:
|
||||
char xbchar;
|
||||
Anope::string xbname;
|
||||
|
||||
ChannelMode *Wrap(Anope::string ¶m) override
|
||||
{
|
||||
param = "~" + Anope::string(ext) + ":" + param;
|
||||
return ChannelModeVirtual<ChannelModeList>::Wrap(param);
|
||||
}
|
||||
public:
|
||||
Base(const Anope::string &mname, const Anope::string& uname, char uchar)
|
||||
: ChannelModeVirtual<ChannelModeList>(mname, "BAN")
|
||||
, xbchar(uchar)
|
||||
, xbname(uname)
|
||||
{
|
||||
}
|
||||
|
||||
ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) override
|
||||
{
|
||||
if (cm->type != MODE_LIST || param.length() < 4 || param[0] != '~' || param[1] != ext || param[2] != ':')
|
||||
return cm;
|
||||
ChannelMode *Wrap(Anope::string ¶m) override
|
||||
{
|
||||
auto prefix = Servers::Capab.count("NEXTBANS") ? xbname : Anope::string(xbchar);
|
||||
param = Anope::printf("~%s:%s", prefix.c_str(), param.c_str());
|
||||
return ChannelModeVirtual<ChannelModeList>::Wrap(param);
|
||||
}
|
||||
|
||||
param = param.substr(3);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) override
|
||||
{
|
||||
// The mask must be in the format ~<letter>:<value> or ~<name>:<value>.
|
||||
if (cm->type != MODE_LIST)
|
||||
return cm;
|
||||
|
||||
Anope::string name, value;
|
||||
if (!IsExtBan(param, name, value))
|
||||
return cm;
|
||||
|
||||
if (name.length() == 1 ? name[0] != xbchar : name != xbname)
|
||||
return cm;
|
||||
|
||||
param = value;
|
||||
return this;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
namespace UnrealExtban
|
||||
{
|
||||
class ChannelMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
ChannelMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
ChannelMatcher()
|
||||
: Base("CHANNELBAN", "channel", 'c')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string channel = mask.substr(3);
|
||||
|
||||
auto channel = e->GetMask();
|
||||
ChannelMode *cm = NULL;
|
||||
if (channel[0] != '#')
|
||||
{
|
||||
@@ -520,137 +545,113 @@ namespace UnrealExtban
|
||||
};
|
||||
|
||||
class EntryMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
EntryMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
EntryMatcher(const Anope::string &mname, const Anope::string &uname, char uchar)
|
||||
: Base(mname, uname, uchar)
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
|
||||
return Entry(this->name, real_mask).Matches(u);
|
||||
return Entry(this->base, e->GetMask()).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
class RealnameMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
RealnameMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
RealnameMatcher()
|
||||
: Base("REALNAMEBAN", "realname", 'r')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
|
||||
return Anope::Match(u->realname, real_mask);
|
||||
}
|
||||
};
|
||||
|
||||
class RegisteredMatcher final
|
||||
: public UnrealExtBan
|
||||
{
|
||||
public:
|
||||
RegisteredMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
return u->HasMode("REGISTERED") && mask.equals_ci(u->nick);
|
||||
return Anope::Match(u->realname, e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
class AccountMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
AccountMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
AccountMatcher()
|
||||
: Base("ACCOUNTBAN", "account", 'a')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
|
||||
if (real_mask == "0" && !u->Account()) /* ~a:0 is special and matches all unauthenticated users */
|
||||
if (e->GetMask() == "0" && !u->Account()) /* ~a:0 is special and matches all unauthenticated users */
|
||||
return true;
|
||||
|
||||
return u->Account() && Anope::Match(u->Account()->display, real_mask);
|
||||
return u->Account() && Anope::Match(u->Account()->display, e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
class FingerprintMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
FingerprintMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
FingerprintMatcher()
|
||||
: Base("SSLBAN", "certfp", 'S')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
return !u->fingerprint.empty() && Anope::Match(u->fingerprint, real_mask);
|
||||
return !u->fingerprint.empty() && Anope::Match(u->fingerprint, e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
class OperclassMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
OperclassMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
OperclassMatcher()
|
||||
: Base("OPERCLASSBAN", "operclass", 'O')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
ModData *moddata = u->GetExt<ModData>("ClientModData");
|
||||
return moddata != NULL && moddata->find("operclass") != moddata->end() && Anope::Match((*moddata)["operclass"], real_mask);
|
||||
return moddata != NULL && moddata->find("operclass") != moddata->end() && Anope::Match((*moddata)["operclass"], e->GetMask());
|
||||
}
|
||||
};
|
||||
|
||||
class TimedBanMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
TimedBanMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
TimedBanMatcher()
|
||||
: Base("TIMEDBAN", "time", 't')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
/* strip down the time (~t:1234:) and call other matchers */
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
auto real_mask = e->GetMask();
|
||||
real_mask = real_mask.substr(real_mask.find(":") + 1);
|
||||
return Entry("BAN", real_mask).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
class CountryMatcher final
|
||||
: public UnrealExtBan
|
||||
: public Base
|
||||
{
|
||||
public:
|
||||
CountryMatcher(const Anope::string &mname, const Anope::string &mbase, char c) : UnrealExtBan(mname, mbase, c)
|
||||
CountryMatcher()
|
||||
: Base("COUNTRYBAN", "country", 'C')
|
||||
{
|
||||
}
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
const Anope::string &mask = e->GetMask();
|
||||
Anope::string real_mask = mask.substr(3);
|
||||
ModData *moddata = u->GetExt<ModData>("ClientModData");
|
||||
if (moddata == NULL || moddata->find("geoip") == moddata->end())
|
||||
return false;
|
||||
@@ -660,7 +661,7 @@ namespace UnrealExtban
|
||||
while (sep.GetToken(tokenbuf))
|
||||
{
|
||||
if (tokenbuf.rfind("cc=", 0) == 0)
|
||||
return (tokenbuf.substr(3, 2) == real_mask);
|
||||
return (tokenbuf.substr(3, 2) == e->GetMask());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -846,17 +847,16 @@ struct IRCDMessageCapab final
|
||||
case 'b':
|
||||
ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
|
||||
|
||||
ModeManager::AddChannelMode(new UnrealExtban::ChannelMatcher("CHANNELBAN", "BAN", 'c'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("JOINBAN", "BAN", 'j'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("NONICKBAN", "BAN", 'n'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::EntryMatcher("QUIET", "BAN", 'q'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::RealnameMatcher("REALNAMEBAN", "BAN", 'r'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::RegisteredMatcher("REGISTEREDBAN", "BAN", 'R'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::AccountMatcher("ACCOUNTBAN", "BAN", 'a'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::FingerprintMatcher("SSLBAN", "BAN", 'S'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::TimedBanMatcher("TIMEDBAN", "BAN", 't'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::OperclassMatcher("OPERCLASSBAN", "BAN", 'O'));
|
||||
ModeManager::AddChannelMode(new UnrealExtban::CountryMatcher("COUNTRYBAN", "BAN", 'C'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::ChannelMatcher());
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::EntryMatcher("JOINBAN", "join", 'j'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::EntryMatcher("NONICKBAN", "nickchange", 'n'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::EntryMatcher("QUIET", "quiet", 'q'));
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::RealnameMatcher());
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::AccountMatcher());
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::FingerprintMatcher());
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::TimedBanMatcher());
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::OperclassMatcher());
|
||||
ModeManager::AddChannelMode(new UnrealExtBan::CountryMatcher());
|
||||
continue;
|
||||
case 'e':
|
||||
ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e'));
|
||||
@@ -1143,22 +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> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
bool server_source = source.GetServer() != NULL;
|
||||
Anope::string modes = params[1];
|
||||
for (unsigned i = 2; i < params.size() - (server_source ? 1 : 0); ++i)
|
||||
modes += " " + params[i];
|
||||
auto final_is_ts = server_ts && source.GetServer() != NULL;
|
||||
auto last_param = params.end() - (params.size() > 3 && final_is_ts ? 1 : 0);
|
||||
|
||||
if (IRCD->IsChannelValid(params[0]))
|
||||
{
|
||||
Channel *c = Channel::Find(params[0]);
|
||||
auto ts = server_source ? IRCD->ExtractTimestamp(params.back()) : 0;
|
||||
auto ts = final_is_ts ? IRCD->ExtractTimestamp(params.back()) : 0;
|
||||
|
||||
if (c)
|
||||
c->SetModesInternal(source, modes, ts);
|
||||
c->SetModesInternal(source, params[1], { params.begin() + 2, last_param }, ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1420,11 +1425,12 @@ struct IRCDMessageSJoin final
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags) override
|
||||
{
|
||||
Anope::string modes;
|
||||
std::vector<Anope::string> modeparams;
|
||||
if (params.size() >= 4)
|
||||
for (unsigned i = 2; i < params.size() - 1; ++i)
|
||||
modes += " " + params[i];
|
||||
if (!modes.empty())
|
||||
modes.erase(modes.begin());
|
||||
{
|
||||
modes = params[2];
|
||||
modeparams = { params.begin() + 3, params.end() };
|
||||
}
|
||||
|
||||
std::list<Anope::string> bans, excepts, invites;
|
||||
std::list<Message::Join::SJoinUser> users;
|
||||
@@ -1474,7 +1480,7 @@ struct IRCDMessageSJoin final
|
||||
}
|
||||
|
||||
auto ts = IRCD->ExtractTimestamp(params[0]);
|
||||
Message::Join::SJoin(source, params[1], ts, modes, users);
|
||||
Message::Join::SJoin(source, params[1], ts, modes, modeparams, users);
|
||||
|
||||
if (!bans.empty() || !excepts.empty() || !invites.empty())
|
||||
{
|
||||
@@ -1690,20 +1696,51 @@ class ProtoUnreal final
|
||||
IRCDMessageUmode2 message_umode2;
|
||||
|
||||
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
|
||||
@@ -1714,8 +1751,6 @@ public:
|
||||
void OnUserNickChange(User *u, const Anope::string &) override
|
||||
{
|
||||
u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED"));
|
||||
if (Servers::Capab.count("ESVID") == 0)
|
||||
IRCD->SendLogout(u);
|
||||
}
|
||||
|
||||
void OnChannelSync(Channel *c) override
|
||||
|
||||
+2
-12
@@ -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
|
||||
|
||||
+8
-8
@@ -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)
|
||||
|
||||
+28
-10
@@ -20,7 +20,11 @@
|
||||
|
||||
Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo");
|
||||
|
||||
BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes)
|
||||
BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes)
|
||||
: User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", {}, IRCD ? IRCD->UID_Retrieve() : "", NULL)
|
||||
, Serializable("BotInfo")
|
||||
, channels("ChannelInfo")
|
||||
, botmodes(bmodes)
|
||||
{
|
||||
this->lastmsg = this->created = Anope::CurTime;
|
||||
this->introduced = false;
|
||||
@@ -35,9 +39,16 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A
|
||||
// If we're synchronised with the uplink already, send the bot.
|
||||
if (Me && Me->IsSynced())
|
||||
{
|
||||
Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : IRCD->DefaultPseudoclientModes;
|
||||
if (!tmodes.empty())
|
||||
this->SetModesInternal(this, tmodes);
|
||||
spacesepstream modesep(this->botmodes.empty() ? IRCD->DefaultPseudoclientModes : "+" + this->botmodes);
|
||||
|
||||
Anope::string modechars;
|
||||
modesep.GetToken(modechars);
|
||||
|
||||
std::vector<Anope::string> modeparams;
|
||||
modesep.GetTokens(modeparams);
|
||||
|
||||
if (!modechars.empty())
|
||||
this->SetModesInternal(this, modechars, modeparams);
|
||||
|
||||
XLine x(this->nick, "Reserved for services");
|
||||
IRCD->SendSQLine(NULL, &x);
|
||||
@@ -75,12 +86,12 @@ BotInfo::~BotInfo()
|
||||
|
||||
void BotInfo::Serialize(Serialize::Data &data) const
|
||||
{
|
||||
data["nick"] << this->nick;
|
||||
data["user"] << this->ident;
|
||||
data["host"] << this->host;
|
||||
data["realname"] << this->realname;
|
||||
data["created"] << this->created;
|
||||
data["oper_only"] << this->oper_only;
|
||||
data.Store("nick", this->nick);
|
||||
data.Store("user", this->ident);
|
||||
data.Store("host", this->host);
|
||||
data.Store("realname", this->realname);
|
||||
data.Store("created", this->created);
|
||||
data.Store("oper_only", this->oper_only);
|
||||
|
||||
Extensible::ExtensibleSerialize(this, this, data);
|
||||
}
|
||||
@@ -254,6 +265,13 @@ CommandInfo *BotInfo::GetCommand(const Anope::string &cname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Anope::string BotInfo::GetQueryCommand() const
|
||||
{
|
||||
if (Config->ServiceAlias && !this->alias.empty())
|
||||
return Anope::printf("/%s", this->alias.c_str());
|
||||
return Anope::printf("/msg %s", this->nick.c_str());
|
||||
}
|
||||
|
||||
BotInfo *BotInfo::Find(const Anope::string &nick, bool nick_only)
|
||||
{
|
||||
if (!nick_only && IRCD != NULL && IRCD->RequiresID)
|
||||
|
||||
+13
-15
@@ -611,13 +611,13 @@ void Channel::SetModes(BotInfo *bi, bool enforce_mlock, const Anope::string &cmo
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts, bool enforce_mlock)
|
||||
void Channel::SetModesInternal(MessageSource &source, const Anope::string &modes, const std::vector<Anope::string> ¶ms, time_t ts, bool enforce_mlock)
|
||||
{
|
||||
if (!ts)
|
||||
;
|
||||
else if (ts > this->creation_time)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Dropping mode " << mode << " on " << this->name << ", " << ts << " > " << this->creation_time;
|
||||
Log(LOG_DEBUG) << "Dropping mode " << modes << " on " << this->name << ", " << ts << " > " << this->creation_time;
|
||||
return;
|
||||
}
|
||||
else if (ts < this->creation_time)
|
||||
@@ -631,20 +631,18 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
|
||||
/* Removing channel modes *may* delete this channel */
|
||||
Reference<Channel> this_reference(this);
|
||||
|
||||
spacesepstream sep_modes(mode);
|
||||
Anope::string m;
|
||||
|
||||
sep_modes.GetToken(m);
|
||||
|
||||
Anope::string modestring;
|
||||
Anope::string paramstring;
|
||||
int add = -1;
|
||||
bool changed = false;
|
||||
for (unsigned int i = 0, end = m.length(); i < end && this_reference; ++i)
|
||||
auto paramit = params.begin();
|
||||
for (const auto mchar : modes)
|
||||
{
|
||||
ChannelMode *cm;
|
||||
if (!this_reference)
|
||||
break;
|
||||
|
||||
switch (m[i])
|
||||
ChannelMode *cm;
|
||||
switch (mchar)
|
||||
{
|
||||
case '+':
|
||||
modestring += '+';
|
||||
@@ -657,10 +655,10 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
|
||||
default:
|
||||
if (add == -1)
|
||||
continue;
|
||||
cm = ModeManager::FindChannelModeByChar(m[i]);
|
||||
cm = ModeManager::FindChannelModeByChar(mchar);
|
||||
if (!cm)
|
||||
{
|
||||
Log(LOG_DEBUG) << "Channel::SetModeInternal: Unknown mode char " << m[i];
|
||||
Log(LOG_DEBUG) << "Channel::SetModeInternal: Unknown mode char " << mchar;
|
||||
continue;
|
||||
}
|
||||
modestring += cm->mchar;
|
||||
@@ -686,9 +684,9 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Anope::string token;
|
||||
if (sep_modes.GetToken(token))
|
||||
if (paramit != params.end())
|
||||
{
|
||||
auto token = *paramit++;
|
||||
User *u = NULL;
|
||||
if (cm->type == MODE_STATUS && (u = User::Find(token)))
|
||||
paramstring += " " + u->nick;
|
||||
@@ -703,7 +701,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
|
||||
this->RemoveModeInternal(source, cm, token, enforce_mlock);
|
||||
}
|
||||
else
|
||||
Log() << "warning: Channel::SetModesInternal() received more modes requiring params than params, modes: " << mode;
|
||||
Log() << "warning: Channel::SetModesInternal() received more modes requiring params than params, modes: " << modes;
|
||||
}
|
||||
|
||||
if (!this_reference)
|
||||
|
||||
+5
-5
@@ -199,7 +199,7 @@ void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcomma
|
||||
this->SendSyntax(source);
|
||||
bool has_help = source.service->commands.find("HELP") != source.service->commands.end();
|
||||
if (has_help)
|
||||
source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
|
||||
source.Reply(MORE_INFO, source.service->GetQueryCommand().c_str(), source.command.c_str());
|
||||
}
|
||||
|
||||
namespace
|
||||
@@ -226,13 +226,13 @@ namespace
|
||||
bool has_help = source.service->commands.find("HELP") != source.service->commands.end();
|
||||
if (has_help && similar.empty())
|
||||
{
|
||||
source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(),
|
||||
Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
|
||||
source.Reply(_("Unknown command \002%s\002. \"%s HELP\" for help."), message.c_str(),
|
||||
source.service->GetQueryCommand().c_str());
|
||||
}
|
||||
else if (has_help)
|
||||
{
|
||||
source.Reply(_("Unknown command \002%s\002. Did you mean \002%s\002? \"%s%s HELP\" for help."),
|
||||
message.c_str(), similar.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
|
||||
source.Reply(_("Unknown command \002%s\002. Did you mean \002%s\002? \"%s HELP\" for help."),
|
||||
message.c_str(), similar.c_str(), source.service->GetQueryCommand().c_str());
|
||||
}
|
||||
else if (similar.empty())
|
||||
{
|
||||
|
||||
+6
-6
@@ -121,7 +121,7 @@ template<typename T> static void ValidateNotZero(const Anope::string &block, con
|
||||
Conf::Conf() : Block("")
|
||||
{
|
||||
ReadTimeout = 0;
|
||||
UsePrivmsg = DefPrivmsg = false;
|
||||
DefPrivmsg = false;
|
||||
|
||||
this->LoadConf(ServicesConf);
|
||||
|
||||
@@ -179,7 +179,6 @@ Conf::Conf() : Block("")
|
||||
ValidateNotEmpty("serverinfo", "motd", serverinfo->Get<const Anope::string>("motd"));
|
||||
|
||||
ValidateNotZero("options", "readtimeout", options->Get<time_t>("readtimeout"));
|
||||
ValidateNotZero("options", "warningtimeout", options->Get<time_t>("warningtimeout"));
|
||||
|
||||
ValidateNotZero("networkinfo", "nicklen", networkinfo->Get<unsigned>("nicklen", "1"));
|
||||
ValidateNotZero("networkinfo", "userlen", networkinfo->Get<unsigned>("userlen", "1"));
|
||||
@@ -196,9 +195,7 @@ Conf::Conf() : Block("")
|
||||
}
|
||||
|
||||
this->ReadTimeout = options->Get<time_t>("readtimeout");
|
||||
this->UsePrivmsg = options->Get<bool>("useprivmsg");
|
||||
this->UseStrictPrivmsg = options->Get<bool>("usestrictprivmsg");
|
||||
this->StrictPrivmsg = !UseStrictPrivmsg ? "/msg " : "/";
|
||||
this->ServiceAlias = options->Get<bool>("servicealias");
|
||||
{
|
||||
std::vector<Anope::string> defaults;
|
||||
spacesepstream(this->GetModule("nickserv")->Get<const Anope::string>("defaults")).GetTokens(defaults);
|
||||
@@ -340,7 +337,8 @@ Conf::Conf() : Block("")
|
||||
&host = service->Get<const Anope::string>("host"),
|
||||
&gecos = service->Get<const Anope::string>("gecos"),
|
||||
&modes = service->Get<const Anope::string>("modes"),
|
||||
&channels = service->Get<const Anope::string>("channels");
|
||||
&channels = service->Get<const Anope::string>("channels"),
|
||||
&alias = service->Get<const Anope::string>("alias", nick.upper());
|
||||
|
||||
ValidateNotEmptyOrSpaces("service", "nick", nick);
|
||||
ValidateNotEmptyOrSpaces("service", "user", user);
|
||||
@@ -351,6 +349,8 @@ Conf::Conf() : Block("")
|
||||
BotInfo *bi = BotInfo::Find(nick, true);
|
||||
if (!bi)
|
||||
bi = new BotInfo(nick, user, host, gecos, modes);
|
||||
|
||||
bi->alias = alias;
|
||||
bi->conf = true;
|
||||
|
||||
std::vector<Anope::string> oldchannels = bi->botchannels;
|
||||
|
||||
+2
-2
@@ -337,7 +337,7 @@ bool Anope::Init(int ac, char **av)
|
||||
Log(LOG_TERMINAL) << "-v, --version";
|
||||
Log(LOG_TERMINAL) << "";
|
||||
Log(LOG_TERMINAL) << "Further support is available from https://www.anope.org/";
|
||||
Log(LOG_TERMINAL) << "Or visit us on IRC at irc.anope.org #anope";
|
||||
Log(LOG_TERMINAL) << "Or visit us on IRC at irc.teranova.net #anope";
|
||||
Anope::ReturnValue = EXIT_SUCCESS;
|
||||
return false;
|
||||
}
|
||||
@@ -488,7 +488,7 @@ bool Anope::Init(int ac, char **av)
|
||||
Log(LOG_TERMINAL) << "*** Support resources: Read through the anope.conf self-contained";
|
||||
Log(LOG_TERMINAL) << "*** documentation. Read the documentation files found in the 'docs'";
|
||||
Log(LOG_TERMINAL) << "*** folder. Visit our portal located at https://www.anope.org/. Join";
|
||||
Log(LOG_TERMINAL) << "*** our support channel on /server irc.anope.org channel #anope.";
|
||||
Log(LOG_TERMINAL) << "*** our support channel on /server irc.teranova.net channel #anope.";
|
||||
throw CoreException("Configuration file failed to validate");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ Mail::Message::~Message()
|
||||
|
||||
void Mail::Message::Run()
|
||||
{
|
||||
errno = 0;
|
||||
auto *pipe = popen(sendmail_path.c_str(), "w");
|
||||
if (!pipe)
|
||||
{
|
||||
|
||||
+6
-6
@@ -36,12 +36,12 @@ Memo::~Memo()
|
||||
|
||||
void Memo::Serialize(Serialize::Data &data) const
|
||||
{
|
||||
data["owner"] << this->owner;
|
||||
data.SetType("time", Serialize::Data::DT_INT); data["time"] << this->time;
|
||||
data["sender"] << this->sender;
|
||||
data["text"] << this->text;
|
||||
data["unread"] << this->unread;
|
||||
data["receipt"] << this->receipt;
|
||||
data.Store("owner", this->owner);
|
||||
data.Store("time", this->time);
|
||||
data.Store("sender", this->sender);
|
||||
data.Store("text", this->text);
|
||||
data.Store("unread", this->unread);
|
||||
data.Store("receipt", this->receipt);
|
||||
}
|
||||
|
||||
Serializable *Memo::Unserialize(Serializable *obj, Serialize::Data &data)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user