mirror of
https://github.com/anope/anope.git
synced 2026-06-19 02:04:45 +02:00
Compare commits
252 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 469a04e7e0 | |||
| 605b5d5717 | |||
| f7aa46fb33 | |||
| b4450294af | |||
| 57327a5e33 | |||
| 4a3c64291f | |||
| 036b3c9053 | |||
| 7da33344d1 | |||
| cbdb9f59f3 | |||
| 5d3d6bcead | |||
| 0cdc628db0 | |||
| 4a733c93d4 | |||
| 03d2378a9f | |||
| 5e027c196d | |||
| 3aeaef5b9a | |||
| 4d26070a92 | |||
| f601b04594 | |||
| ca169489b2 | |||
| 713c2eb704 | |||
| 660e0c78ac | |||
| 0862de6577 | |||
| 2cd511d3a3 | |||
| efe5fedde9 | |||
| c8c6845452 | |||
| bd62c4891e | |||
| 9535541f5a | |||
| 711a570d24 | |||
| cb9ccc443d | |||
| c681bdd2e3 | |||
| 74844c0f28 | |||
| 905207093b | |||
| 73a944fb74 | |||
| d1328d876a | |||
| faa85564fc | |||
| 8dec0c1f17 | |||
| 8098ed899a | |||
| 77c98f0750 | |||
| 8dbdfa9a44 | |||
| 685e99be02 | |||
| b14b7bd55e | |||
| 365769d14c | |||
| 01b901eba1 | |||
| 26de1d9f93 | |||
| 451fb82e54 | |||
| c02d51f523 | |||
| b95027ba28 | |||
| 5b476a2597 | |||
| bceeda8087 | |||
| ee9636bba2 | |||
| ddfb16de1a | |||
| 2555d0d637 | |||
| ed73d76751 | |||
| 4fe49af840 | |||
| beabbb3a20 | |||
| b4888c21ed | |||
| b75fa1c6ec | |||
| 3fbf39b25d | |||
| 15a833283b | |||
| 5a0d04bb81 | |||
| fbae3344ff | |||
| 95469fde30 | |||
| 9f46972f19 | |||
| 46a3afadb9 | |||
| 1b2f3bf369 | |||
| bb3b421385 | |||
| 1ee3d3d810 | |||
| 97c2e0957d | |||
| 09a5791bc6 | |||
| 8db5ecd736 | |||
| e9aa04a8f4 | |||
| 8eb23e7d48 | |||
| 093b3d258e | |||
| 48e6221cf0 | |||
| ef0c095712 | |||
| a0355dfd9d | |||
| 6fe2d8af97 | |||
| 90e5d0feaa | |||
| d79e22bfaa | |||
| a9fb6bab15 | |||
| dd968c07be | |||
| feb81c51d2 | |||
| aecf675e6b | |||
| bcaf406747 | |||
| f234a2bfab | |||
| 28d17a40ce | |||
| 7cfca37e2a | |||
| c38b6392c5 | |||
| ee38756982 | |||
| eea7d2eb77 | |||
| b15410fd3a | |||
| c83b2b73d7 | |||
| dfbb5264fa | |||
| f49a3e03c1 | |||
| 109d1744a0 | |||
| 470f8af97c | |||
| a1296a3b7c | |||
| f38fe242cd | |||
| 536ea2189a | |||
| ab0422b4d4 | |||
| 18bd33f9a4 | |||
| d436e4ca4a | |||
| 1372dc1953 | |||
| 9ef7352e69 | |||
| 2529ff6dae | |||
| 7bdf592f7e | |||
| f463b772b0 | |||
| eec897762c | |||
| f87c665b63 | |||
| 36d3fd1710 | |||
| d26a19b41d | |||
| a55b3742cb | |||
| 83556667fd | |||
| faf5f3128f | |||
| a53a797271 | |||
| 08583dc107 | |||
| c362a1e077 | |||
| 140208e5ee | |||
| 679d3c373f | |||
| 557eceeefc | |||
| 9704ccc8a6 | |||
| e62664138b | |||
| 3eadc1509f | |||
| 9910aa3cc6 | |||
| 2a53e5f80e | |||
| 2e8acfb98c | |||
| 48fa096943 | |||
| bf559d788f | |||
| 3bfc8e9a39 | |||
| a162f1d18e | |||
| a86873c93e | |||
| 05933e9f21 | |||
| ab2e34d817 | |||
| e7a8bcc30b | |||
| 34c6c664c9 | |||
| 4a3ee91c55 | |||
| 6f0d1af596 | |||
| 01feb5b489 | |||
| 8975b52cc3 | |||
| 7acbbbbf5b | |||
| 4fecafa612 | |||
| a4ded88e85 | |||
| 1b6aab0cd7 | |||
| c669820481 | |||
| ecc2fc6029 | |||
| e490202a1b | |||
| fd2412a5f6 | |||
| 07528ea8f2 | |||
| ce8a069eb5 | |||
| 2ba97aee6c | |||
| a674d81caf | |||
| efb61ed4a8 | |||
| 2e7d08c10b | |||
| 47b87e903b | |||
| ddeff72544 | |||
| 43995b4c6d | |||
| 512d23d60f | |||
| 0eb9152749 | |||
| 4403849126 | |||
| 9efebe5461 | |||
| 7198fa73d1 | |||
| 03ba592c48 | |||
| 57a06f72e2 | |||
| 3019ba6f43 | |||
| 2784cd17fc | |||
| 03cc9eb5c5 | |||
| 72b8f4609b | |||
| d36e53f702 | |||
| a36f14c1bf | |||
| 292e187524 | |||
| 16cab979da | |||
| fd7f542bd9 | |||
| 5ead326454 | |||
| a1c635b050 | |||
| d896bf9a1c | |||
| 49dd1c3409 | |||
| fce491e18c | |||
| 87d0fc8bb5 | |||
| f638d1078a | |||
| 8af2465a61 | |||
| 1b3f2567bc | |||
| 036d4514f0 | |||
| 80721d1873 | |||
| aa9e33cf74 | |||
| 86900175c8 | |||
| d5c1d6ebec | |||
| 35e328bcb6 | |||
| befb4b3644 | |||
| 4235df2b28 | |||
| a6c8a6a9f2 | |||
| 1a3ba00c24 | |||
| e8a2072792 | |||
| 4886b56edb | |||
| 15d29edae9 | |||
| 3009540a00 | |||
| a0ad3c4fef | |||
| 265006b691 | |||
| 11b3b8a5ff | |||
| 2783c82685 | |||
| 184e7b3f64 | |||
| 18377ac9fd | |||
| 184e14ea83 | |||
| 21125cf2cb | |||
| 0d20c47703 | |||
| 7f9a5e01c6 | |||
| eb9b12ed11 | |||
| 4a4c0886cc | |||
| 02476332ea | |||
| 49d3c97b67 | |||
| 97467cb2c8 | |||
| 6a43886807 | |||
| 5d56a2486e | |||
| eb138a02d6 | |||
| 2a4d0e3e89 | |||
| 9f7a2e4da2 | |||
| 25e995b0f5 | |||
| ad5da2a988 | |||
| 6ab7cf9689 | |||
| 099ead02a5 | |||
| f1d04a2f8e | |||
| aed53dbb47 | |||
| a507816701 | |||
| c41c828574 | |||
| 5fe41fb8a0 | |||
| 0ba566491e | |||
| 2a4d57a1ca | |||
| 71c433cc50 | |||
| 2b10cc84ea | |||
| cb6ef574e3 | |||
| 37e02a3594 | |||
| 7d1cfe9514 | |||
| 9870ee04dd | |||
| 1a286397e3 | |||
| 697dc89382 | |||
| 4d342d955d | |||
| c5eb349d41 | |||
| 7790a7f98c | |||
| 246f44b988 | |||
| a85112172d | |||
| 5f18cb018d | |||
| 872bc3fa5e | |||
| 1625a5af0c | |||
| 2e9a632e14 | |||
| 3c9d4e9daf | |||
| c792c7f62d | |||
| e512760364 | |||
| ac41137ce2 | |||
| 28aba58e25 | |||
| 4ec661c0bb | |||
| 87bdf73cb7 | |||
| 21c8e89671 | |||
| 8fbe36635c | |||
| 5cd4fefb4c |
+6
-4
@@ -220,11 +220,15 @@ find_package(Gettext)
|
||||
option(USE_RUN_CC_PL "Use run-cc.pl for building" OFF)
|
||||
|
||||
# Use the following directories as includes
|
||||
include_directories(${Anope_SOURCE_DIR}/include ${Anope_BINARY_DIR}/include ${Anope_BINARY_DIR}/lang)
|
||||
# Note that it is important the binary include directory comes before the
|
||||
# source include directory so the precompiled headers work correctly.
|
||||
include_directories(${Anope_BINARY_DIR}/include ${Anope_SOURCE_DIR}/include ${Anope_BINARY_DIR}/language)
|
||||
|
||||
# If using Windows, always add the _WIN32 define
|
||||
if(WIN32)
|
||||
add_definitions(-D_WIN32)
|
||||
# And include the windows specific folder for our anope_windows.h
|
||||
include_directories(${Anope_SOURCE_DIR}/src/win32)
|
||||
endif(WIN32)
|
||||
|
||||
# If using Visual Studio, set the C++ flags accordingly
|
||||
@@ -327,11 +331,9 @@ endif(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEB
|
||||
# Check for the existance of the following include files
|
||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_file(strings.h HAVE_STRINGS_H)
|
||||
check_include_file(sys/select.h HAVE_SYS_SELECT_H)
|
||||
check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
|
||||
|
||||
# Check for the existance of the following functions
|
||||
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
check_function_exists(setgrent HAVE_SETGRENT)
|
||||
check_function_exists(strcasecmp HAVE_STRCASECMP)
|
||||
check_function_exists(stricmp HAVE_STRICMP)
|
||||
@@ -449,7 +451,7 @@ endif(${Anope_SOURCE_DIR} STREQUAL ${Anope_BINARY_DIR})
|
||||
# Go into the following directories and run their CMakeLists.txt as well
|
||||
add_subdirectory(data)
|
||||
add_subdirectory(docs)
|
||||
add_subdirectory(lang)
|
||||
add_subdirectory(language)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(modules)
|
||||
add_subdirectory(include)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Configuration script for Services.
|
||||
#
|
||||
# Anope (c) 2003-2010 Anope team
|
||||
# Anope (c) 2003-2011 Anope team
|
||||
# Contact us at team@anope.org
|
||||
#
|
||||
# This program is free but copyrighted software; see the file COPYING for
|
||||
@@ -153,6 +153,17 @@ done
|
||||
|
||||
###########################################################################
|
||||
|
||||
which cmake > /dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
clear
|
||||
echo "Anope requires CMake 2.4 or newer to be configured, which can"
|
||||
echo "be downloaded at http://www.cmake.org/. If you have installed"
|
||||
echo "CMake already, ensure it is in your PATH environment variable."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
|
||||
if [ ! "$NO_INTRO" ] ; then
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
@@ -168,11 +179,11 @@ if [ ! "$NO_INTRO" ] ; then
|
||||
VERSION=`git describe --tags`
|
||||
VERSION_BUILD=`echo "$VERSION" | cut -d'-' -f2`
|
||||
VERSION_EXTRA=`echo "$VERSION" | cut -d'-' -f3`
|
||||
if [ "$VERSION_BUILD" == "$VERSION_EXTRA" ] ; then
|
||||
VERSION_EXTRA=""
|
||||
# Only do this if we are not on a tag, src/version.sh will be all we need then.
|
||||
if [ "$VERSION_BUILD" != "$VERSION_EXTRA" ] ; then
|
||||
echo "#define VERSION_BUILD $VERSION_BUILD" > include/version.h
|
||||
echo "#define VERSION_EXTRA \"-$VERSION_EXTRA\"" >> include/version.h
|
||||
fi
|
||||
echo "#define VERSION_BUILD $VERSION_BUILD" > include/version.h
|
||||
echo "#define VERSION_EXTRA \"$VERSION_EXTRA\"" >> include/version.h
|
||||
fi
|
||||
cat $SOURCE_DIR/.BANNER | sed "s/CURVER/$VERSION/" | sed "s@SOURCE_DIR@$SOURCE_DIR@" | $PAGER
|
||||
echo ""
|
||||
|
||||
@@ -20,7 +20,7 @@ endif(NOT WIN32)
|
||||
|
||||
# If we found everything we need set variables correctly for lang/CMakeLists.txt to use
|
||||
if(GETTEXT_FOUND)
|
||||
set(LIBINTL_INCLUDE "${GETTEXT_INCLUDE}/libintl.h")
|
||||
include_directories("${GETTEXT_INCLUDE}")
|
||||
set(GETTEXT_MSGFMT_EXECUTABLE ${GETTEXT_MSGFMT})
|
||||
|
||||
if(WIN32)
|
||||
|
||||
+700
-297
File diff suppressed because it is too large
Load Diff
+37
-45
@@ -3,7 +3,7 @@
|
||||
-- http://www.phpmyadmin.net
|
||||
--
|
||||
-- Host: localhost
|
||||
-- Generation Time: Oct 31, 2010 at 03:02 AM
|
||||
-- Generation Time: Apr 28, 2011 at 07:08 PM
|
||||
-- Server version: 5.1.50
|
||||
-- PHP Version: 5.3.3-pl1-gentoo
|
||||
|
||||
@@ -108,10 +108,6 @@ CREATE TABLE IF NOT EXISTS `anope_cs_info` (
|
||||
`forbidby` text NOT NULL,
|
||||
`forbidreason` text NOT NULL,
|
||||
`bantype` smallint(6) NOT NULL DEFAULT '0',
|
||||
`mlock_on` text NOT NULL,
|
||||
`mlock_off` text NOT NULL,
|
||||
`mlock_params` text NOT NULL,
|
||||
`entry_message` text NOT NULL,
|
||||
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`botnick` varchar(255) NOT NULL DEFAULT '',
|
||||
`botflags` text NOT NULL,
|
||||
@@ -151,6 +147,23 @@ CREATE TABLE IF NOT EXISTS `anope_cs_levels` (
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `anope_cs_mlock`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `anope_cs_mlock` (
|
||||
`channel` varchar(255) NOT NULL,
|
||||
`mode` varchar(127) NOT NULL,
|
||||
`status` int(11) NOT NULL,
|
||||
`setter` varchar(255) NOT NULL,
|
||||
`created` int(11) NOT NULL,
|
||||
`param` varchar(255) NOT NULL,
|
||||
UNIQUE KEY `entry` (`channel`,`mode`,`status`,`setter`,`param`),
|
||||
KEY `FK_anope_cs_mlock` (`channel`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `anope_cs_ttb`
|
||||
--
|
||||
@@ -270,7 +283,7 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core` (
|
||||
`email` text NOT NULL,
|
||||
`greet` text NOT NULL,
|
||||
`flags` text NOT NULL,
|
||||
`language` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`language` varchar(5) NOT NULL DEFAULT '',
|
||||
`channelcount` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`display`)
|
||||
@@ -290,21 +303,6 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core_metadata` (
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `anope_ns_request`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `anope_ns_request` (
|
||||
`nick` varchar(255) NOT NULL DEFAULT '',
|
||||
`passcode` text NOT NULL,
|
||||
`password` text NOT NULL,
|
||||
`email` text NOT NULL,
|
||||
`requested` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`nick`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `anope_os_akills`
|
||||
--
|
||||
@@ -371,83 +369,77 @@ CREATE TABLE IF NOT EXISTS `anope_os_xlines` (
|
||||
-- Constraints for table `anope_bs_badwords`
|
||||
--
|
||||
ALTER TABLE `anope_bs_badwords`
|
||||
ADD CONSTRAINT `FK_anope_bs_badwords_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_bs_badwords_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_bs_info_metadata`
|
||||
--
|
||||
ALTER TABLE `anope_bs_info_metadata`
|
||||
ADD CONSTRAINT `FK_anope_bs_info_metadata_botname` FOREIGN KEY (`botname`) REFERENCES `anope_bs_core` (`nick`) ON DELETE
|
||||
CASCADE ON UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_bs_info_metadata_botname` FOREIGN KEY (`botname`) REFERENCES `anope_bs_core` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_cs_access`
|
||||
--
|
||||
ALTER TABLE `anope_cs_access`
|
||||
ADD CONSTRAINT `FK_anope_cs_access_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
|
||||
UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_cs_access_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_cs_akick`
|
||||
--
|
||||
ALTER TABLE `anope_cs_akick`
|
||||
ADD CONSTRAINT `FK_anope_cs_akick_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
|
||||
UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_cs_akick_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_cs_info_metadata`
|
||||
--
|
||||
ALTER TABLE `anope_cs_info_metadata`
|
||||
ADD CONSTRAINT `FK_anope_cs_info_metadata_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE
|
||||
CASCADE ON UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_cs_info_metadata_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_cs_levels`
|
||||
--
|
||||
ALTER TABLE `anope_cs_levels`
|
||||
ADD CONSTRAINT `FK_anope_cs_levels_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
|
||||
UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_cs_levels_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_cs_mlock`
|
||||
--
|
||||
ALTER TABLE `anope_cs_mlock`
|
||||
ADD CONSTRAINT `FK_anope_cs_mlock_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_cs_ttb`
|
||||
--
|
||||
ALTER TABLE `anope_cs_ttb`
|
||||
ADD CONSTRAINT `FK_anope_cs_ttb_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON
|
||||
UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_cs_ttb_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_hs_core`
|
||||
--
|
||||
ALTER TABLE `anope_hs_core`
|
||||
ADD CONSTRAINT `FK_anope_hs_core_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE
|
||||
CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_hs_core_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_ms_info`
|
||||
--
|
||||
ALTER TABLE `anope_ms_info`
|
||||
ADD CONSTRAINT `FK_anope_ms_info_receiver` FOREIGN KEY (`receiver`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON
|
||||
UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_ms_info_receiver` FOREIGN KEY (`receiver`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_ns_access`
|
||||
--
|
||||
ALTER TABLE `anope_ns_access`
|
||||
ADD CONSTRAINT `FK_anope_ns_access_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_ns_access_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_ns_alias`
|
||||
--
|
||||
ALTER TABLE `anope_ns_alias`
|
||||
ADD CONSTRAINT `FK_anope_ns_alias_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_ns_alias_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Constraints for table `anope_ns_alias_metadata`
|
||||
--
|
||||
ALTER TABLE `anope_ns_alias_metadata`
|
||||
ADD CONSTRAINT `FK_anope_ns_alias_metadata_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
||||
ADD CONSTRAINT `FK_anope_ns_alias_metadata_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
Reported Bugs from Bugzilla: http://bugs.anope.org/
|
||||
---------------------------------------------------
|
||||
|
||||
|
||||
For all bug reports / updates please see http://bugs.anope.org
|
||||
|
||||
+209
-140
@@ -1,170 +1,239 @@
|
||||
Orginally pulled from: http://www.inspircd.org/wiki/Coding_Guidelines
|
||||
Yes, I'm aware the formatting of this document is ugly. It'll be fixed when someone cares. Read the wiki page if you want pretty for now.
|
||||
|
||||
---
|
||||
|
||||
|
||||
InspIRCd Coding Guidelines
|
||||
|
||||
The following are a set of guidelines for writing patches to InspIRCd, or for creating modules for distribution with the official package. These
|
||||
guidelines were written a time after InspIRCd development started, and so not all code yet follows these. This will be rectified with time.
|
||||
The following are a set of guidelines for writing patches to InspIRCd, or for
|
||||
creating modules for distribution with the official package. These guidelines
|
||||
were written a time after InspIRCd development started, and so not all code
|
||||
yet follows these. This will be rectified with time.
|
||||
|
||||
|
||||
1. Comments
|
||||
Multi Line
|
||||
Multiple line comments should follow the C-style comment, for example:
|
||||
/*
|
||||
* This is a multiple line comment, huzzah..
|
||||
*/
|
||||
|
||||
Single Line
|
||||
Single line comments should also be in the C style, for example:
|
||||
/* This is a boring one-line comment */
|
||||
* Multi Line
|
||||
Multiple line comments should follow the C-style comment, for example:
|
||||
/*
|
||||
* This is a multiple line comment, huzzah..
|
||||
*/
|
||||
|
||||
Doxygen commenting
|
||||
If you wish your comment to show in doxygen, the comment should be directly above the item you are documenting (a class, function, enum, etc)
|
||||
and the first line should be "/**". For example:
|
||||
/** This is a doxygen multiline comment.
|
||||
* Description of thingymebob here.
|
||||
*/
|
||||
The first line after the "**" is used as the short description of the item (up to the full stop) and everything afterwards as the detailed
|
||||
description.
|
||||
* Single Line
|
||||
Single line comments should also be in the C style, for example:
|
||||
/* This is a boring one-line comment */
|
||||
|
||||
Indentation
|
||||
Tabs. Tabs. ONLY TABS. Use a single tab for each level of indentation, for example:
|
||||
int main()
|
||||
{
|
||||
<tab>if (condition)
|
||||
<tab>{
|
||||
<tab><tab>code
|
||||
<tab>}
|
||||
}
|
||||
* Doxygen commenting
|
||||
If you wish your comment to show in doxygen, the comment should be directly
|
||||
above the item you are documenting (a class, function, enum, etc) and the
|
||||
first line should be "/**". For example:
|
||||
/** This is a doxygen multiline comment.
|
||||
* Description of thingymebob here.
|
||||
*/
|
||||
|
||||
The first line after the "**" is used as the short description of the item
|
||||
(up to the full stop) and everything afterwards as the detailed description.
|
||||
|
||||
|
||||
Separation
|
||||
Always put a space in between a keyword like if/while and the condition, for example:
|
||||
if (foo == bar)
|
||||
NOT
|
||||
if(foo == bar)
|
||||
2. Indentation
|
||||
|
||||
Braces
|
||||
Always put braces opening and closing blocks on separate lines, see the identation example. For example, place braces like this:
|
||||
if (apples == "green")
|
||||
{
|
||||
cout << "Apples are green" << endl;
|
||||
}
|
||||
Tabs. Tabs. ONLY TABS. Use a single tab for each level of indentation,
|
||||
for example:
|
||||
int main()
|
||||
{
|
||||
<tab>if (condition)
|
||||
<tab>{
|
||||
<tab><tab>code
|
||||
<tab>}
|
||||
}
|
||||
|
||||
and not:
|
||||
if (apples == "green") {
|
||||
cout << "Apples are green" << endl;
|
||||
}
|
||||
The one exception to this is if you are declaring a class method which is only one line long, in that case the following is acceptable in most cases:
|
||||
class foo : public bar
|
||||
{
|
||||
foo() { }
|
||||
getrandomfoo() { return rand(); }
|
||||
};
|
||||
|
||||
Templates
|
||||
Where possible, use templates rather than #defines. Avoid use of RTTI.
|
||||
Structs
|
||||
Structs should be declared in the following fashion:
|
||||
struct BodyPartBasket
|
||||
{
|
||||
int arms;
|
||||
int legs;
|
||||
int scrotalsacs;
|
||||
};
|
||||
and not like this:
|
||||
typedef struct
|
||||
{
|
||||
int arms;
|
||||
int legs;
|
||||
int scrotalsacs;
|
||||
} BodyPartBasket;
|
||||
The second way is not required in C++ to be able to do this:
|
||||
BodyPartBasket mybasket;
|
||||
Plus, placing the name at the bottom of the declaration makes readability more difficult (as you have to scroll down to the bottom of the
|
||||
struct to find its name).
|
||||
(where possible, call them classes rather than structs.)
|
||||
3. Separation
|
||||
|
||||
Variable naming
|
||||
Class and struct names should be in camel case with a leading capital letter, for example "MyBagOfBones" and not "my_bag_of_bones" or
|
||||
"mybagofbones". Variable names can be in either camel case with a leading capital letter or alternatively all lower case, so long as the same
|
||||
naming convention is adhered to throughout the class. No classes or variables should be named in capitals unless this makes sense for the
|
||||
name (for example "class DNS"). Constants and enum values should always be completely in CAPITALS and underscores may be used, for example:
|
||||
enum DecayState
|
||||
{
|
||||
DECAYED_MOULDY = 0,
|
||||
DECAYED_SMELLY = 1,
|
||||
DECAYED_MAGGOTS = 2
|
||||
};
|
||||
All value names in an enum should be started with the same text which should be related in some way to the enum's use. For example "DNS_CNAME,
|
||||
DNS_A, DNS_AAAA".
|
||||
Always put a space in between a keyword like if/while and the condition,
|
||||
for example:
|
||||
if (foo == bar)
|
||||
NOT
|
||||
if(foo == bar)
|
||||
|
||||
Use of references
|
||||
Wherever possible, when dealing with any complex class, pass a const reference rather than a copy of the class. For example:
|
||||
MyThingy::MyThingy(const std::string &thingyvalue)
|
||||
{
|
||||
}
|
||||
Of course, if you intended to change the string you can just omit the 'const'.
|
||||
|
||||
Use of char pointers
|
||||
Whenever you use char pointers (char*, char**) try to use const equivalents. This is much safer and avoids ugly and dangerous casts. For example:
|
||||
MyThingy::Thingify(const char* const* wotsits)
|
||||
{
|
||||
}
|
||||
If it is possible without performance loss, consider avoiding char pointers altogether and using std::string instead.
|
||||
4. Braces
|
||||
|
||||
Use of STL
|
||||
For more information on use of STL in InspIRCd, please see the separate STL FAQ.
|
||||
Always put braces opening and closing blocks on separate lines, see the
|
||||
identation example. For example, place braces like this:
|
||||
if (apples == "green")
|
||||
{
|
||||
cout << "Apples are green" << endl;
|
||||
}
|
||||
|
||||
Making copies of data
|
||||
Never ever make a copy of a piece of data unless it is absolutely necessary. For example, don't use strlcpy() to make a copy of the const char* string
|
||||
returned by std::string::c_str(), if the change can be done to the std::string itself. The same goes for unnecessary variable assignments, especially
|
||||
those which assign large classes.
|
||||
and not:
|
||||
if (apples == "green") {
|
||||
cout << "Apples are green" << endl;
|
||||
}
|
||||
|
||||
namespace std
|
||||
Avoid the following:
|
||||
using namespace std;
|
||||
It might take a bit more typing, but things work better if you don't set (then later assume) the namespace -- specify it explicitly when you want to
|
||||
use it.
|
||||
The one exception to this is if you are declaring a class method which is
|
||||
only one line long, in that case the following is acceptable in most cases:
|
||||
class foo : public bar
|
||||
{
|
||||
foo() { }
|
||||
getrandomfoo() { return rand(); }
|
||||
};
|
||||
|
||||
Linefeeds
|
||||
Unix linefeeds only please. We do not like to see our screens covered in ^M. :-)
|
||||
|
||||
Portability
|
||||
Always make sure your code is portable to all supported operating systems, remember of course that as of 1.1.8 this includes windows. Don't write code
|
||||
that only works on windows, or only works on Linux. Test your code on all platforms or ask for help from other developers who have the platforms you
|
||||
want to test on.
|
||||
5. Templates
|
||||
|
||||
new() and delete(), malloc() and free()
|
||||
Apart from the fact that using malloc() and free() is bad practice in C++ code, you must never use malloc() or free() in InspIRCd, within its modules
|
||||
or within the core. This is because if you use malloc() or free() in windows, the memory is claimed from the program's local heap. In windows, each
|
||||
shared object (module, dll) has its own heap, which is protected from other dlls and executables. To get around this issue and allow more posix-like
|
||||
memory access from other dlls in the program (other modules), InspIRCd overrides the operators new and delete to ensure that memory allocated by them
|
||||
comes from the windows global heap. If you use malloc() and free() for this, the ircd will segfault when another module tries to access the memory you
|
||||
have allocated!
|
||||
Where possible, use templates rather than #defines. Avoid use of RTTI.
|
||||
|
||||
strdup()
|
||||
As with malloc(), above, strdup() should be avoided. Where strdup() is absolutely necessary, use strnewdup() which is our strdup() implementation that
|
||||
calls operator new instead of using malloc(). char arrays allocated by strnewdup() should be deleted with operator delete[].
|
||||
|
||||
CoreExport and DllImport
|
||||
Prefix all types you want to import or export to other modules with CoreExport and DllImport macros. These do nothing in POSIX operating systems,
|
||||
however in windows these are expanded to the instructions __declspec(dllimport) and __declspec(dllexport) respectively depending on where they are
|
||||
used and how.
|
||||
6. Structs
|
||||
|
||||
External Dependencies
|
||||
If a module is compiled as standard, or the code is part of the core, you must not use any dependencies that are not available as standard on all
|
||||
supported operating systems beyond libstdc++, libc, and whatever else is currently required to build the core. Modules which use nonstandard
|
||||
dependencies belong in the modules/extra directory.
|
||||
Structs should be declared in the following fashion:
|
||||
struct BodyPartBasket
|
||||
{
|
||||
int arms;
|
||||
int legs;
|
||||
int scrotalsacs;
|
||||
};
|
||||
and not like this:
|
||||
typedef struct
|
||||
{
|
||||
int arms;
|
||||
int legs;
|
||||
int scrotalsacs;
|
||||
} BodyPartBasket;
|
||||
|
||||
Profiling and Performance
|
||||
It is one thing to assume that code performs bad, it is another thing to prove that it actually is. A lot of experienced programmers talk about
|
||||
'premature optimisation', and here is what it means: if you have a piece of code called once on startup that takes 10 seconds instead of one second to
|
||||
run, and a piece of code that takes 0.05 seconds to run when it should take 0.01, and it is called once per second, the second piece of code is the
|
||||
priority.
|
||||
In other words, make sure that what you think is slow, and a performance problem in Insp actually is.
|
||||
To do this, use the callgrind tool from Valgrind (valgrind --tool=cachegrind bin/inspircd -nofork -debug), and kcachegrind (or similar) to view the
|
||||
output files.
|
||||
The second way is not required in C++ to be able to do this:
|
||||
BodyPartBasket mybasket;
|
||||
|
||||
Plus, placing the name at the bottom of the declaration makes readability
|
||||
more difficult (as you have to scroll down to the bottom of the struct to
|
||||
find its name). (where possible, call them classes rather than structs.)
|
||||
|
||||
|
||||
7. Variable naming
|
||||
|
||||
Class and struct names should be in camel case with a leading capital letter,
|
||||
for example "MyBagOfBones" and not "my_bag_of_bones" or "mybagofbones".
|
||||
Variable names can be in either camel case with a leading capital letter or
|
||||
alternatively all lower case, so long as the same naming convention is
|
||||
adhered to throughout the class. No classes or variables should be named in
|
||||
capitals unless this makes sense for the name (for example "class DNS").
|
||||
Constants and enum values should always be completely in CAPITALS and
|
||||
underscores may be used, for example:
|
||||
enum DecayState
|
||||
{
|
||||
DECAYED_MOULDY = 0,
|
||||
DECAYED_SMELLY = 1,
|
||||
DECAYED_MAGGOTS = 2
|
||||
};
|
||||
All value names in an enum should be started with the same text which should
|
||||
be related in some way to the enum's use. For example "DNS_CNAME, DNS_A,
|
||||
DNS_AAAA".
|
||||
|
||||
|
||||
8. Use of references
|
||||
|
||||
Wherever possible, when dealing with any complex class, pass a const reference
|
||||
rather than a copy of the class. For example:
|
||||
MyThingy::MyThingy(const std::string &thingyvalue)
|
||||
{
|
||||
}
|
||||
Of course, if you intended to change the string you can just omit the 'const'.
|
||||
|
||||
|
||||
9. Use of char pointers
|
||||
|
||||
Whenever you use char pointers (char*, char**) try to use const equivalents.
|
||||
This is much safer and avoids ugly and dangerous casts. For example:
|
||||
MyThingy::Thingify(const char* const* wotsits)
|
||||
{
|
||||
}
|
||||
If it is possible without performance loss, consider avoiding char pointers
|
||||
altogether and using std::string instead.
|
||||
|
||||
|
||||
10. Use of STL
|
||||
|
||||
For more information on use of STL in InspIRCd, please see the separate
|
||||
STL FAQ.
|
||||
|
||||
|
||||
11. Making copies of data
|
||||
|
||||
Never ever make a copy of a piece of data unless it is absolutely necessary.
|
||||
For example, don't use strlcpy() to make a copy of the const char* string
|
||||
returned by std::string::c_str(), if the change can be done to the std::string
|
||||
itself. The same goes for unnecessary variable assignments, especially those
|
||||
which assign large classes.
|
||||
|
||||
|
||||
12. namespace std
|
||||
|
||||
Avoid the following:
|
||||
using namespace std;
|
||||
It might take a bit more typing, but things work better if you don't set
|
||||
(then later assume) the namespace -- specify it explicitly when you want to
|
||||
use it.
|
||||
|
||||
|
||||
13. Linefeeds
|
||||
|
||||
Unix linefeeds only please. We do not like to see our screens covered in ^M.
|
||||
|
||||
|
||||
14. Portability
|
||||
|
||||
Always make sure your code is portable to all supported operating systems,
|
||||
remember of course that as of 1.1.8 this includes windows. Don't write code
|
||||
that only works on windows, or only works on Linux. Test your code on all
|
||||
platforms or ask for help from other developers who have the platforms you
|
||||
want to test on.
|
||||
|
||||
* new() and delete(), malloc() and free()
|
||||
Apart from the fact that using malloc() and free() is bad practice in C++
|
||||
code, you must never use malloc() or free() in InspIRCd, within its modules
|
||||
or within the core. This is because if you use malloc() or free() in windows,
|
||||
the memory is claimed from the program's local heap.
|
||||
In windows, each shared object (module, dll) has its own heap, which is
|
||||
protected from other dlls and executables. To get around this issue and
|
||||
allow more posix-like memory access from other dlls in the program (other
|
||||
modules), InspIRCd overrides the operators new and delete to ensure that
|
||||
memory allocated by them comes from the windows global heap. If you use
|
||||
malloc() and free() for this, the ircd will segfault when another module
|
||||
tries to access the memory you have allocated!
|
||||
|
||||
* strdup()
|
||||
As with malloc(), above, strdup() should be avoided. Where strdup() is
|
||||
absolutely necessary, use strnewdup() which is our strdup() implementation
|
||||
that calls operator new instead of using malloc().
|
||||
char arrays allocated by strnewdup() should be deleted with operator delete[].
|
||||
|
||||
* CoreExport and DllImport
|
||||
Prefix all types you want to import or export to other modules with CoreExport
|
||||
and DllImport macros. These do nothing in POSIX operating systems, however
|
||||
in windows these are expanded to the instructions __declspec(dllimport) and
|
||||
__declspec(dllexport) respectively depending on where they are used and how.
|
||||
|
||||
|
||||
15. External Dependencies
|
||||
|
||||
If a module is compiled as standard, or the code is part of the core, you must
|
||||
not use any dependencies that are not available as standard on all supported
|
||||
operating systems beyond libstdc++, libc, and whatever else is currently
|
||||
required to build the core. Modules which use nonstandard dependencies belong
|
||||
in the modules/extra directory.
|
||||
|
||||
|
||||
16. Profiling and Performance
|
||||
|
||||
It is one thing to assume that code performs bad, it is another thing to prove
|
||||
that it actually is. A lot of experienced programmers talk about 'premature
|
||||
optimisation', and here is what it means: if you have a piece of code called
|
||||
once on startup that takes 10 seconds instead of one second to run, and a
|
||||
piece of code that takes 0.05 seconds to run when it should take 0.01, and
|
||||
it is called once per second, the second piece of code is the priority.
|
||||
|
||||
In other words, make sure that what you think is slow, and a performance
|
||||
problem in Insp actually is.
|
||||
To do this, use the callgrind tool from Valgrind (valgrind --tool=cachegrind
|
||||
bin/inspircd -nofork -debug), and kcachegrind (or similar) to view the output
|
||||
files.
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
Anope Version 1.9.4
|
||||
--------------------
|
||||
A Automatically set channel founder to the user with the highest access if there is no successor
|
||||
A /chanserv clone command to copy settings from one channel to another.
|
||||
A /chanserv mode command
|
||||
A Ability for users to delete their own access in channels
|
||||
A Added support for Plexus 3
|
||||
A Readded in support for /cs op/deop/etc to op/deop you in all channels
|
||||
A Added LDAP support
|
||||
A Added live SQL support
|
||||
A Added support for learning tracking/storing/locking all modes at runtime
|
||||
A Added m_alias
|
||||
A Added support for XMLRPC queries
|
||||
A Added /botserv set msg
|
||||
A Added /operserv config
|
||||
A Added /ns cert
|
||||
A Added /operserv login
|
||||
F Changed the GHOST command to not allow ghosting unidentified users if the RECOVER command exists
|
||||
F Some failed logic in /operserv exception that prevents proper exceptions from being added
|
||||
F Fixed the anope_os_sxlines MySQL table and code to work after restarting
|
||||
|
||||
Anope Version 1.9.3
|
||||
--------------------
|
||||
A Added italics BotServ kicks support
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
Anope Version 1.9.4
|
||||
-------------------
|
||||
** ADDED CONFIGURATION DIRECTIVES **
|
||||
memoserv:modules added ms_ignore
|
||||
chanserv:modules added cs_clone and cs_mode
|
||||
nickserv:suspendexpire and nickserv:forbidexpire added
|
||||
chanserv:suspendexpire and chanserv:forbidexpire added
|
||||
module added cs_entrymsg
|
||||
nickserv:modules added ns_ajoin, ns_cert
|
||||
options:nomlock added
|
||||
log:target added globops
|
||||
nickserv:confirmemailchanges added
|
||||
operserv:modules added os_config, os_login
|
||||
|
||||
** MODIFIED CONFIGURATION DIRECTIVES **
|
||||
operserv:notifications removed osglobal, osmode, oskick, osakill, ossnline, ossqline, osszline, osnoop, osjupe, getpass, setpass, forbid, drop
|
||||
renamed nickserv:preregexpire to nickserv:unconfirmedexpire
|
||||
|
||||
** DELETED CONFIGURATION DIRECTIVES **
|
||||
opertype:commands removed operserv/umode
|
||||
operserv:modules removed os_umode
|
||||
|
||||
Anope Version 1.9.3
|
||||
------------------
|
||||
** ADDED CONFIGURATION DIRECTIVES **
|
||||
|
||||
+6
-8
@@ -162,7 +162,7 @@ Note: You should also read the README and FAQ files!
|
||||
4) Starting Anope
|
||||
|
||||
Go into the directory where binaries were installed (by default, this is
|
||||
~/services). Type ./services to launch Anope.
|
||||
~/services/bin). Type ./services to launch Anope.
|
||||
|
||||
If there are syntax errors in the configuration file they will be
|
||||
displayed on the screen. Correct them until there are no errors anymore.
|
||||
@@ -180,21 +180,19 @@ Note: You should also read the README and FAQ files!
|
||||
5) Setting up a crontab
|
||||
|
||||
A crontab entry will allow you to check periodically whether Anope is
|
||||
still running, and restart it if not. You'll need to have Anope binaries
|
||||
and data installed in the same directory for this to work without
|
||||
modification.
|
||||
still running, and restart it if not.
|
||||
|
||||
First rename the example.chk script that is in Anope path (by default,
|
||||
this is ~/services) to services.chk 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 services.chk, and try to launch the
|
||||
this is ~/services/data) to services.chk 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 services.chk, 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/services/services.chk >/dev/null 2>&1
|
||||
*/5 * * * * /home/ircd/services/data/services.chk >/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
|
||||
|
||||
@@ -106,18 +106,10 @@ How To Add IRCd Support
|
||||
|
||||
23) TS6: Does the IRCd support TS6? Use 1 for yes, 0 for no.
|
||||
|
||||
24) Channel CIDR: Set to 1 if channel bans, excepts and invites
|
||||
support CIDR masks. Expected syntax: *!*@ip/mask.
|
||||
When set to 1, anope will only parse strict CIDR masks.
|
||||
IRCd's that try to correct invalid CIDR's (like nefarious)
|
||||
will need a custom implementation in the core.
|
||||
Contact the anope Dev Team if this is the case.
|
||||
Set to 0 if CIDR's are not supported by your IRCd.
|
||||
|
||||
25) Global TLD Prefix: Prefix used to send global messages, should probably
|
||||
24) Global TLD Prefix: Prefix used to send global messages, should probably
|
||||
be "$"
|
||||
|
||||
26) Max Modes: The max number of mode changes we can send in one line
|
||||
25) Max Modes: The max number of mode changes we can send in one line
|
||||
|
||||
3) Modes
|
||||
|
||||
@@ -155,12 +147,6 @@ How To Add IRCd Support
|
||||
|
||||
ModeManager::AddChannelMode(new ChannelModeOper('O'));
|
||||
|
||||
The CMODE_FLOOD param also has its own class, but due to the wide range of
|
||||
valid parameters accepted across IRCds, your protocol module MUST have the
|
||||
IsValid function for this.
|
||||
|
||||
bool ChannelModeFlood::IsValid(const Anope::string &value) { }
|
||||
|
||||
4) Functions and Events
|
||||
|
||||
A brief word about functions and events. All events are captured by creating a Message struct
|
||||
@@ -183,74 +169,19 @@ How To Add IRCd Support
|
||||
|
||||
5) CAPAB/PROTOCTL
|
||||
|
||||
Most IRCD send a CAPAB or PROTOCTL line so that they can work out what
|
||||
the other end of the connection is capable of doing. Anope has a function
|
||||
to read these lines and set itself up to to handle these events better.
|
||||
When adding support for your ircd, take the following steps.
|
||||
Most IRCDs send a CAPAB or PROTOCTL line so that they can work out what
|
||||
the other end of the connection is capable of doing. The protocol module should
|
||||
handle all of these without the cores knowledge with the exception of the following:
|
||||
|
||||
1) In the module constructor you must tell Anope what the uplink is capable of that
|
||||
isn't already passed in the CAPAB/PROTOCTL, you do this by something similar to:
|
||||
|
||||
CapabType c[] = { CAPAB_NOQUIT, CAPAB_NICKIP, CAPAB_ZIP, CAPAB_TOKEN, CAPAB_SSJ3, CAPAB_NICK2, CAPAB_VL, CAPAB_TLKEXT, CAPAB_CHANMODE, CAPAB_SJB64, CAPAB_NICKCHARS };
|
||||
for (unsigned i = 0; i < 11; ++i)
|
||||
Capab.SetFlag(c[i]);
|
||||
|
||||
Anything else given to Anope in the CAPAB/PROTOCTL message will be handled later by CapabParse.
|
||||
|
||||
The available CAPAB options are:
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Define | Description
|
||||
----------------|------------|-----------|--------------------------------
|
||||
----------------|---------------------------------------------------------
|
||||
CAPAB_NOQUIT | NOQUIT protocol support
|
||||
CAPAB_TSMODE | Chanmodes are timestamped
|
||||
CAPAB_UNCONNECT | UNCONNECT protocol support
|
||||
CAPAB_NICKIP | IP sent in the NICK line
|
||||
CAPAB_NSJOIN | Smart SJOIN support
|
||||
CAPAB_ZIP | Support for gzipped links
|
||||
CAPAB_BURST | Supports BURST command
|
||||
CAPAB_TS3 | Support for TS3 protocol
|
||||
CAPAB_TS5 | Support for TS5 protocol
|
||||
CAPAB_DKEY | DH-Key exchange using DKEY
|
||||
CAPAB_DOZIP | Link traffic will be gzipped
|
||||
CAPAB_DODKEY | Do DKEY with this link
|
||||
CAPAB_QS | Supports quit storm removal
|
||||
CAPAB_SCS | String Cache System support
|
||||
CAPAB_PT4 | Support for PT4 protocol
|
||||
CAPAB_UID | Support for UIDs
|
||||
CAPAB_KNOCK | Supports KNOCK
|
||||
CAPAB_CLIENT | Supports CLIENT
|
||||
CAPAB_IPV6 | Support for IPv6 addresses
|
||||
CAPAB_SSJ5 | Smart Join protocol 5 support
|
||||
CAPAB_SN2 | Support for SN2 protocol
|
||||
CAPAB_VHOST | Supports VHOST protocol
|
||||
CAPAB_TOKEN | Supports s2s tokens
|
||||
CAPAB_SSJ3 | Smart Join protocol 3 support
|
||||
CAPAB_NICK2 | Support for extended NICK (v2)
|
||||
CAPAB_UMODE2 | Supports UMODE2 command
|
||||
CAPAB_VL | VLine information in info field
|
||||
CAPAB_TLKEXT | Not 8, but 10 params in TKL's
|
||||
CAPAB_CHANMODE | Channel modes are passed here
|
||||
CAPAB_SJB64 | SJOIN timestamps are base64 encoded
|
||||
CAPAB_NICKCHARS | Character set used by the IRCD for nicks
|
||||
CAPAB_QS | Quitstorm - same as NOQUIT
|
||||
|
||||
2) Ensure that the CAPAB/PROTOCTL event his handled correctly.
|
||||
|
||||
A) In the function module constructor make sure that you have the
|
||||
following two lines:
|
||||
|
||||
Message message_capab("CAPAB", event_capab);
|
||||
|
||||
B) Add the function to handle the event
|
||||
|
||||
bool event_capab(const Anope::string &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
CapabParse(params);
|
||||
return true;
|
||||
}
|
||||
|
||||
This function should call the CapabParse function which parses
|
||||
the received CAPAB/PROTOCTL line.
|
||||
You can override the default OnCapab method in IRCdMessage if required.
|
||||
|
||||
6) IRCDProto Class
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ Anope Mutli Language Support
|
||||
If you have finished a language file translation and you want others to use it, please send it to team@anope.org
|
||||
(don't forget to mention clearly your (nick)name, your e-mail and the language name). You'll of course get full credit for it.
|
||||
|
||||
NOTE: There is no guarantee we will use your work so please do not be offended if we say no thanks.
|
||||
|
||||
3) Using langages with modules
|
||||
|
||||
Module authors can easially add the ability to have their modules translated by adding _() around the strings they
|
||||
|
||||
+284
-321
@@ -1,321 +1,284 @@
|
||||
Anope -- a set of IRC services for IRC networks
|
||||
-----------------------------------------------
|
||||
|
||||
Anope is 2003-2010 Anope Team <team@anope.org>.
|
||||
Based on Epona 2000-2002 PegSoft <epona@pegsoft.net>.
|
||||
Based on Services 1996-1999 Andrew Church <achurch@achurch.org>.
|
||||
|
||||
This program is free but copyrighted software; see the file COPYING for
|
||||
details.
|
||||
|
||||
Information about Anope may be found at http://www.anope.org/
|
||||
Information about Epona may be found at http://www.epona.org/
|
||||
Information about Services may be found at http://www.ircservices.esper.net/
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1) Credits
|
||||
2) Presentation
|
||||
3) Installation
|
||||
4) Command Line Options
|
||||
5) Messages Translation
|
||||
6) Contact and Mailing List
|
||||
|
||||
1) Credits
|
||||
|
||||
Anope is based on Lara's Epona version 1.4.14.
|
||||
Epona is based on Andy Church's IRC Services version 4.3.3.
|
||||
|
||||
The original credits:
|
||||
|
||||
* Mauritz Antunes
|
||||
Portuguese translation
|
||||
* Jose R. Holzmann, Raul S. Villarreal
|
||||
Spanish translation
|
||||
* Andrew Kempe <theshadow@shadowfire.org>
|
||||
News system
|
||||
* <d.duca@eurcom.net>
|
||||
Italian translation
|
||||
* <mikado@holyfire.com>
|
||||
Turkish translation
|
||||
* Andrew Kempe <theshadow@shadowfire.org>
|
||||
Session limiting
|
||||
|
||||
Epona credits:
|
||||
|
||||
* lara <lara@pegsoft.net>
|
||||
Main coding
|
||||
* CafeiN <oytuny@yahoo.com>
|
||||
Turkish translation
|
||||
* Sylvain Cresto aka tost <scresto@netsante.fr>
|
||||
FreeBSD 5 patch
|
||||
* Marcelo Conde Foscarini aka Bras <ircadmin@brmarket.net>
|
||||
Portuguese translation
|
||||
* Alvaro Toledo aka POLLITO <atoledo@keldon.org>
|
||||
Spanish translation
|
||||
* chemical <chemical@musicplay.de>
|
||||
German translation
|
||||
* shine <dh@shinewelt.de>
|
||||
German translation
|
||||
* Guven Guzelbey aka MeShGuL <guzelbey@cs.utk.edu>
|
||||
Turkish translation
|
||||
* Jordi Pujol <jordi.pujol@aujac.org>
|
||||
Catalan translation
|
||||
* Eva Dachs <evadachs@terra.es>
|
||||
Catalan translation
|
||||
* Toni Perez <toni.perez@aujac.org>
|
||||
Catalan translation
|
||||
* Sergios Karalis <sergios_k@hotmail.com>
|
||||
Greek translation
|
||||
* Thomas J. Stensas aka ShadowMaster <shadowmaster@shadow-realm.org>
|
||||
Ultimate 3.x support
|
||||
|
||||
Anope credits:
|
||||
|
||||
* Adam Kramer <ribosome@anope.org>
|
||||
* Adam <adam@anope.org>
|
||||
* Alvaro Toledo <atoledo@keldon.org>
|
||||
* Amanda Folson <amanda@anope.org>
|
||||
* Andrew Berquist <vash@anope.org>
|
||||
* Björn Stiddien <keeper@anope.org>
|
||||
* Charles Kingsley <chaz@anope.org>
|
||||
* Chris Hogben <heinz@anope.org>
|
||||
* Daniel Engel <dane@zero.org>
|
||||
* David <dv@diboo.net>
|
||||
* David Narayan <jester@phrixus.net>
|
||||
* David Robson <rob@anope.org>
|
||||
* Daniele Nicolucci <jollino@sogno.net>
|
||||
* Florian Schulze <certus@anope.org>
|
||||
* Gabriel Acevedo H. <drstein@anope.org>
|
||||
* Jan Milants <viper@anope.org>
|
||||
* Jens Voss <dukepyrolator@anope.org>
|
||||
* JH <jh@irc-chat.net>
|
||||
* Joris Vink <joris@anope.org>
|
||||
* Lucas Nussbaum <lucas@lucas-nussbaum.net>
|
||||
* Mark Summers <mark@goopler.net>
|
||||
* Matthew Beeching <jobe@invictachat.net>
|
||||
* Naram Qashat <cyberbotx@anope.org>
|
||||
* Pieter Bootsma <geniusdex@anope.org>
|
||||
* Robin Burchell <w00t@inspircd.org>
|
||||
* Thomas Juberg StensĂĄs <ShadowMaster@Shadow-Realm.org>
|
||||
* Trystan .S Lee <trystan@nomadirc.net>
|
||||
* openglx <openglx@brasnerd.com.br>
|
||||
|
||||
Anope Translations:
|
||||
|
||||
* GeniusDex <geniusdex@anope.org> (nl.l)
|
||||
* Kein <kein-of@yandex.ru> (ru.l)
|
||||
* Stuff <the.stuff@gmx.de> (de.l)
|
||||
* Gabriel Acevedo H. <drstein@anope.org> (es.l)
|
||||
* Janos Kapitany <sarkanyka@cjbchat.hu> (hun.l)
|
||||
* Szymon S'wierkosz <szymek@adres.pl> (pl.l)
|
||||
|
||||
Anope uses the strlcat() and strlcpy() functions from OpenSSH 2.5.1p2.
|
||||
These functions are copyrighted by Todd C. Miller:
|
||||
|
||||
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
2) Presentation
|
||||
|
||||
Anope is a set of Services for IRC networks that allows users to manage
|
||||
their nicks and channels in a secure and efficient way, and administrators
|
||||
to manage their network with powerful tools.
|
||||
|
||||
Currently available services are:
|
||||
|
||||
* NickServ, a powerful nickname manager that users can use to protect
|
||||
themselves against nick stealing. Each user has its own nickname
|
||||
group, that allows the user to register as many nicks as needed
|
||||
while still being able to take profit of his privileges and to
|
||||
modify the nick configuration. NickServ also has an optional
|
||||
password retrieval feature.
|
||||
|
||||
* ChanServ, a powerful channel manager that helps users to administer
|
||||
their channels in a totally customizable way. ChanServ has an
|
||||
internal list of privileged users and banned users that controls
|
||||
accesses on a per-channel basis. It eliminates all takeover
|
||||
problems, because of its powerful op/unban/invite and even mass
|
||||
deop and mass kick functions.
|
||||
|
||||
* MemoServ, an helpful companion that allows sending short messages
|
||||
to offline users, that they can then read when they come online
|
||||
later.
|
||||
|
||||
* BotServ, an original service that allows users to get a permanent,
|
||||
friendly bot on their channels in an easy way. Each bot can be
|
||||
configured to monitor the channels against floods, repetitions,
|
||||
caps writing, and swearing, and to take appropriate actions. It
|
||||
also can handle user-friendly commands (like !op, !deop, !voice,
|
||||
!devoice, !kick, and many others), say a short greet message when
|
||||
an user joins a channel, and even "take over" ChanServ actions such
|
||||
as auto-opping users, saying the entry notice, and so on. This
|
||||
service can be disabled if you want to save some bandwidth.
|
||||
|
||||
* OperServ, the IRCops' and IRC admins' black box, that allows them
|
||||
to manage the list of network bans (also known as AKILL (DALnet) or
|
||||
GLINE (Undernet)), to configure messages displayed to users when
|
||||
they log on, to set modes and to kick users from any channel, to
|
||||
send notices quickly to the entire network, and much more!
|
||||
|
||||
* HostServ, a neat service that allows users to show custom vHosts
|
||||
(virtual hosts) instead of their real IP address; this only works
|
||||
on daemons supporting ip cloaking, such as UnrealIRCd, UltimateIRCd
|
||||
and ViagraIRCd.
|
||||
|
||||
Anope currently works with:
|
||||
|
||||
* Bahamut 1.4.27 or later (including 1.8)
|
||||
* InspIRCd 1.1, 1.2, or 2.0
|
||||
* Ratbox 2.0.6 or later
|
||||
* UnrealIRCd 3.2 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.
|
||||
|
||||
|
||||
3) Installation
|
||||
|
||||
See the INSTALL file for instruction on installing Anope.
|
||||
|
||||
|
||||
4) Command Line Options
|
||||
|
||||
Normally, Anope can be run simply by invoking the "services" executable.
|
||||
Any of the following command-line options can be specified to change
|
||||
the behavior of Anope:
|
||||
|
||||
--debug Enable debugging mode; more info sent to log (give
|
||||
option more times for more info)
|
||||
--readonly Enable read-only mode; no changes to databases
|
||||
allowed
|
||||
--nofork Do not fork after startup; log messages will be
|
||||
written to terminal
|
||||
--noexpire Expiration routines won't be run at all
|
||||
--version Display the version of Anope
|
||||
--nothird Do not load the non-core modules specified
|
||||
--protocoldebug Debug each incoming message after protocol parsing
|
||||
--support Used for support, same as -debug -nofork -nothird
|
||||
|
||||
Upon starting, Anope will parse its command-line parameters then
|
||||
(assuming the -nofork option is not given) detach itself and run in the
|
||||
background. If Anope encounters a problem reading the database files or
|
||||
cannot connect to its uplink server, it will terminate immediately;
|
||||
otherwise, it will run until the connection is terminated (or a QUIT,
|
||||
SHUTDOWN, or RESTART command is sent; see OperServ's help).
|
||||
|
||||
In the case of an error, an appropriate error message will be written to
|
||||
the log file.
|
||||
|
||||
If Anope is run with the "--readonly" command-line option, it can serve as
|
||||
a "backup" to the full version of services. A "full" version of services
|
||||
(run without --readonly) will automatically reintroduce its pseudo-clients
|
||||
(NickServ, ChanServ, etc.), while a "backup" services will not, thus
|
||||
allowing full services to be brought up at any time without disrupting
|
||||
the network (and without having to take backup services down beforehand).
|
||||
|
||||
The "--debug" option is useful if you find or suspect a problem in Anope.
|
||||
Giving it once on the command line will cause all traffic to and from
|
||||
services as well as some other debugging information to be recorded in
|
||||
the log file; if you send a bug report, PLEASE include an excerpt from
|
||||
the log file WITH DEBUGGING ACTIVE; we cannot emphasize enough how
|
||||
important this is to tracking down problems. (You can also enable
|
||||
debugging while Services is running using OperServ's SET DEBUG command.)
|
||||
If you repeat use --debug=<level>, the debugging level will be increased,
|
||||
which provides more detailed information but may also slow Anope down
|
||||
considerably and make the log file grow dramatically faster. In general,
|
||||
a debug level of 1 is sufficient for the coding team to be able to trace
|
||||
a problem, because all network traffic is included and we can usually
|
||||
reproduce the problem.
|
||||
|
||||
5) Messages Translations
|
||||
|
||||
Anope has a powerful option in NickServ allowing users to choose what
|
||||
language it must use when sending messages to users. Messages are stored
|
||||
in language files (located in the lang directory).
|
||||
|
||||
Anope is currently provided with thirteen languages: Catalan, Dutch,
|
||||
English, French, German, Greek, Hungarian, Italian, Polish, Portuguese,
|
||||
Russian, Spanish and Turkish. If you want to translate Anope messages
|
||||
into another language, follow this instructions:
|
||||
|
||||
* Copy the lang/en_us.l file to a meaningful name (for example, if
|
||||
you would like to translate messages in Spanish, you would rename
|
||||
it to es.l).
|
||||
|
||||
* Edit the file with your favorite text editor. Carefully read the
|
||||
instructions given at the top of the file, and start translating
|
||||
the whole file. The file is big, so make sure you have some coffee
|
||||
available ;) Try to avoid the use of English words as much as
|
||||
possible. If the new language contains only a few 'special'
|
||||
characters, try and use latin representations of it, if possible.
|
||||
Remember that most clients are only capable of handling the
|
||||
ISO-8859-1 charset. Of course, if you are translating Anope to a
|
||||
language with a totally different charset, such as Russian, feel
|
||||
free to use the one that suites it best (and the one that is in use
|
||||
by most speakers of that language ;)).
|
||||
|
||||
* When this is done, you have two solutions: either patch Services
|
||||
source code so they take in account the new language file
|
||||
(basically, you'll have to modify lang/Makefile, language.c and
|
||||
maybe services.h), or send us the translated file so we can make
|
||||
the patch and include your language in the next Anope release.
|
||||
|
||||
* Note that there is a language tool on bin/langtool.pl that can aid
|
||||
the verification process on newly created language files. Try to
|
||||
use it before you submit a language file.
|
||||
|
||||
When new major releases come out, you'll not have to retranslate the
|
||||
whole file; the Changes.lang file will help you to know which messages
|
||||
were added, modified or deleted.
|
||||
|
||||
If you did a language file translation, and want to let others use it,
|
||||
please send it to team@anope.org (don't forget to mention clearly your
|
||||
(nick)name, your e-mail and the language name). You'll of course get full
|
||||
credit for it, and will even get future final major releases before
|
||||
anyone else to complete the translation!... ;)
|
||||
|
||||
6) Contact
|
||||
|
||||
For announcements and discussions about Anope, please visit our
|
||||
Portal and Forums at http://www.anope.org/ -- make sure you register
|
||||
yourself and your network to get full benefits.
|
||||
|
||||
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, just
|
||||
type "? report" for instructions on how to report a Bug. 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. The more precise you are,
|
||||
the sooner you'll be likely to get an answer.
|
||||
|
||||
If you think you found a bug, add it to the bug tracking system
|
||||
(http://bugs.anope.org) and - again - be as precise as possible. Also say
|
||||
whether the bug happens always or under what circumstances, and anything
|
||||
that could be useful to track your bug down. If you wrote a patch, send
|
||||
it over. :)
|
||||
Anope -- a set of IRC services for IRC networks
|
||||
-----------------------------------------------
|
||||
|
||||
Anope is 2003-2011 Anope Team <team@anope.org>.
|
||||
Based on Epona 2000-2002 PegSoft <epona@pegsoft.net>.
|
||||
Based on Services 1996-1999 Andrew Church <achurch@achurch.org>.
|
||||
|
||||
This program is free but copyrighted software; see the file COPYING for
|
||||
details.
|
||||
|
||||
Information about Anope may be found at http://www.anope.org/
|
||||
Information about Epona may be found at http://www.epona.org/
|
||||
Information about Services may be found at http://www.ircservices.esper.net/
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
1) Credits
|
||||
2) Presentation
|
||||
3) Installation
|
||||
4) Command Line Options
|
||||
5) Messages Translation
|
||||
6) Contact and Mailing List
|
||||
|
||||
1) Credits
|
||||
|
||||
Anope is based on Lara's Epona version 1.4.14.
|
||||
Epona is based on Andy Church's IRC Services version 4.3.3.
|
||||
|
||||
The original credits:
|
||||
|
||||
* Mauritz Antunes
|
||||
Portuguese translation
|
||||
* Jose R. Holzmann, Raul S. Villarreal
|
||||
Spanish translation
|
||||
* Andrew Kempe <theshadow@shadowfire.org>
|
||||
News system
|
||||
* <d.duca@eurcom.net>
|
||||
Italian translation
|
||||
* <mikado@holyfire.com>
|
||||
Turkish translation
|
||||
* Andrew Kempe <theshadow@shadowfire.org>
|
||||
Session limiting
|
||||
|
||||
Epona credits:
|
||||
|
||||
* lara <lara@pegsoft.net>
|
||||
Main coding
|
||||
* CafeiN <oytuny@yahoo.com>
|
||||
Turkish translation
|
||||
* Sylvain Cresto aka tost <scresto@netsante.fr>
|
||||
FreeBSD 5 patch
|
||||
* Marcelo Conde Foscarini aka Bras <ircadmin@brmarket.net>
|
||||
Portuguese translation
|
||||
* Alvaro Toledo aka POLLITO <atoledo@keldon.org>
|
||||
Spanish translation
|
||||
* chemical <chemical@musicplay.de>
|
||||
German translation
|
||||
* shine <dh@shinewelt.de>
|
||||
German translation
|
||||
* Guven Guzelbey aka MeShGuL <guzelbey@cs.utk.edu>
|
||||
Turkish translation
|
||||
* Jordi Pujol <jordi.pujol@aujac.org>
|
||||
Catalan translation
|
||||
* Eva Dachs <evadachs@terra.es>
|
||||
Catalan translation
|
||||
* Toni Perez <toni.perez@aujac.org>
|
||||
Catalan translation
|
||||
* Sergios Karalis <sergios_k@hotmail.com>
|
||||
Greek translation
|
||||
* Thomas J. Stensas aka ShadowMaster <shadowmaster@shadow-realm.org>
|
||||
Ultimate 3.x support
|
||||
|
||||
Anope credits:
|
||||
|
||||
* Adam Kramer <ribosome@anope.org>
|
||||
* Adam <adam@anope.org>
|
||||
* Alvaro Toledo <atoledo@keldon.org>
|
||||
* Amanda Folson <amanda@anope.org>
|
||||
* Andrew Berquist <vash@anope.org>
|
||||
* Björn Stiddien <keeper@anope.org>
|
||||
* Charles Kingsley <chaz@anope.org>
|
||||
* Chris Hogben <heinz@anope.org>
|
||||
* Daniel Engel <dane@zero.org>
|
||||
* David <dv@diboo.net>
|
||||
* David Narayan <jester@phrixus.net>
|
||||
* David Robson <rob@anope.org>
|
||||
* Daniele Nicolucci <jollino@sogno.net>
|
||||
* Florian Schulze <certus@anope.org>
|
||||
* Gabriel Acevedo H. <drstein@anope.org>
|
||||
* Jan Milants <viper@anope.org>
|
||||
* Jens Voss <dukepyrolator@anope.org>
|
||||
* JH <jh@irc-chat.net>
|
||||
* Joris Vink <joris@anope.org>
|
||||
* Lee Holmes <lethality@anope.org>
|
||||
* Lucas Nussbaum <lucas@lucas-nussbaum.net>
|
||||
* Mark Summers <mark@goopler.net>
|
||||
* Matthew Beeching <jobe@invictachat.net>
|
||||
* Naram Qashat <cyberbotx@anope.org>
|
||||
* Phil Lavin <phil@anope.org>
|
||||
* Pieter Bootsma <geniusdex@anope.org>
|
||||
* Robin Burchell <w00t@inspircd.org>
|
||||
* Sean Roe <therock247uk@anope.org>
|
||||
* Sebastian V <hal9000@anope.org>
|
||||
* Thomas Juberg StensĂĄs <ShadowMaster@Shadow-Realm.org>
|
||||
* Trystan .S Lee <trystan@nomadirc.net>
|
||||
* openglx <openglx@brasnerd.com.br>
|
||||
|
||||
Anope Translations:
|
||||
|
||||
* GeniusDex <geniusdex@anope.org> (nl.l)
|
||||
* Kein <kein-of@yandex.ru> (ru.l)
|
||||
* Maik Funke <Han@mefalcon.org> (de.l)
|
||||
* Gabriel Acevedo H. <drstein@anope.org> (es.l)
|
||||
* Janos Kapitany <sarkanyka@cjbchat.hu> (hun.l)
|
||||
* Szymon S'wierkosz <szymek@adres.pl> (pl.l)
|
||||
* Christopher N. <saka@epiknet.org> (fr.l)
|
||||
* Yusuf Kurekci <ysfm.20@gmail.com> (tr.l)
|
||||
|
||||
Anope uses the strlcat() and strlcpy() functions from OpenSSH 2.5.1p2.
|
||||
These functions are copyrighted by Todd C. Miller:
|
||||
|
||||
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
2) Presentation
|
||||
|
||||
Anope is a set of Services for IRC networks that allows users to manage
|
||||
their nicks and channels in a secure and efficient way, and administrators
|
||||
to manage their network with powerful tools.
|
||||
|
||||
Currently available services are:
|
||||
|
||||
* NickServ, a powerful nickname manager that users can use to protect
|
||||
themselves against nick stealing. Each user has its own nickname
|
||||
group, that allows the user to register as many nicks as needed
|
||||
while still being able to take profit of his privileges and to
|
||||
modify the nick configuration. NickServ also has an optional
|
||||
password retrieval feature.
|
||||
|
||||
* ChanServ, a powerful channel manager that helps users to administer
|
||||
their channels in a totally customizable way. ChanServ has an
|
||||
internal list of privileged users and banned users that controls
|
||||
accesses on a per-channel basis. It eliminates all takeover
|
||||
problems, because of its powerful op/unban/invite and even mass
|
||||
deop and mass kick functions.
|
||||
|
||||
* MemoServ, an helpful companion that allows sending short messages
|
||||
to offline users, that they can then read when they come online
|
||||
later.
|
||||
|
||||
* BotServ, an original service that allows users to get a permanent,
|
||||
friendly bot on their channels in an easy way. Each bot can be
|
||||
configured to monitor the channels against floods, repetitions,
|
||||
caps writing, and swearing, and to take appropriate actions. It
|
||||
also can handle user-friendly commands (like !op, !deop, !voice,
|
||||
!devoice, !kick, and many others), say a short greet message when
|
||||
an user joins a channel, and even "take over" ChanServ actions such
|
||||
as auto-opping users, saying the entry notice, and so on. This
|
||||
service can be disabled if you want to save some bandwidth.
|
||||
|
||||
* OperServ, the IRCops' and IRC admins' black box, that allows them
|
||||
to manage the list of network bans (also known as AKILL (DALnet) or
|
||||
GLINE (Undernet)), to configure messages displayed to users when
|
||||
they log on, to set modes and to kick users from any channel, to
|
||||
send notices quickly to the entire network, and much more!
|
||||
|
||||
* HostServ, a neat service that allows users to show custom vHosts
|
||||
(virtual hosts) instead of their real IP address; this only works
|
||||
on daemons supporting ip cloaking, such as UnrealIRCd.
|
||||
|
||||
Anope currently works with:
|
||||
|
||||
* Bahamut 1.4.27 or later (including 1.8)
|
||||
* InspIRCd 1.1, 1.2, or 2.0
|
||||
* Ratbox 2.0.6 or later
|
||||
* UnrealIRCd 3.2 or later
|
||||
* Plexus 3 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.
|
||||
|
||||
|
||||
3) Installation
|
||||
|
||||
See the INSTALL file for instruction on installing Anope.
|
||||
|
||||
|
||||
4) Command Line Options
|
||||
|
||||
Normally, Anope can be run simply by invoking the "services" executable.
|
||||
Any of the following command-line options can be specified to change
|
||||
the behavior of Anope:
|
||||
|
||||
--debug Enable debugging mode; more info sent to log (give
|
||||
option more times for more info)
|
||||
--readonly Enable read-only mode; no changes to databases
|
||||
allowed
|
||||
--nofork Do not fork after startup; log messages will be
|
||||
written to terminal
|
||||
--noexpire Expiration routines won't be run at all
|
||||
--version Display the version of Anope
|
||||
--nothird Do not load the non-core modules specified
|
||||
--protocoldebug Debug each incoming message after protocol parsing
|
||||
--support Used for support, same as -debug -nofork -nothird
|
||||
|
||||
Upon starting, Anope will parse its command-line parameters then
|
||||
(assuming the -nofork option is not given) detach itself and run in the
|
||||
background. If Anope encounters a problem reading the database files or
|
||||
cannot connect to its uplink server, it will terminate immediately;
|
||||
otherwise, it will run until the connection is terminated (or a QUIT,
|
||||
SHUTDOWN, or RESTART command is sent; see OperServ's help).
|
||||
|
||||
In the case of an error, an appropriate error message will be written to
|
||||
the log file.
|
||||
|
||||
If Anope is run with the "--readonly" command-line option, it can serve as
|
||||
a "backup" to the full version of services. A "full" version of services
|
||||
(run without --readonly) will automatically reintroduce its pseudo-clients
|
||||
(NickServ, ChanServ, etc.), while a "backup" services will not, thus
|
||||
allowing full services to be brought up at any time without disrupting
|
||||
the network (and without having to take backup services down beforehand).
|
||||
|
||||
The "--debug" option is useful if you find or suspect a problem in Anope.
|
||||
Giving it once on the command line will cause all traffic to and from
|
||||
services as well as some other debugging information to be recorded in
|
||||
the log file; if you send a bug report, PLEASE include an excerpt from
|
||||
the log file WITH DEBUGGING ACTIVE; we cannot emphasize enough how
|
||||
important this is to tracking down problems. (You can also enable
|
||||
debugging while Services is running using OperServ's SET DEBUG command.)
|
||||
If you repeat use --debug=<level>, the debugging level will be increased,
|
||||
which provides more detailed information but may also slow Anope down
|
||||
considerably and make the log file grow dramatically faster. In general,
|
||||
a debug level of 1 is sufficient for the coding team to be able to trace
|
||||
a problem, because all network traffic is included and we can usually
|
||||
reproduce the problem.
|
||||
|
||||
5) Messages Translations
|
||||
|
||||
Please see LANGUAGE for this information
|
||||
|
||||
6) Contact
|
||||
|
||||
For announcements and discussions about Anope, please visit our
|
||||
Portal and Forums at http://www.anope.org/ -- make sure you register
|
||||
yourself to get full benefits.
|
||||
|
||||
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
|
||||
precise as possible when asking a question, because we have no extraordinary
|
||||
powers and can't guess things if they aren't provided.
|
||||
|
||||
The more precise you are the sooner you'll be likely to get an answer.
|
||||
|
||||
If you think you found a bug, add it to the bug tracking system
|
||||
(http://bugs.anope.org) and - again - be as precise as possible. Also say
|
||||
whether the bug happens always or under what circumstances, and anything
|
||||
that could be useful to track your bug down. If you wrote a patch, send
|
||||
it over. :)
|
||||
|
||||
@@ -3,56 +3,43 @@ Legend:
|
||||
? = unsure
|
||||
+ = in progress
|
||||
|
||||
1.9.3
|
||||
1.9.4
|
||||
-----
|
||||
[x] Add in a subcommand system, ns_set, cs_set, etc.
|
||||
[x] Threading
|
||||
[x] Mail sending needs to be threaded
|
||||
[x] process_numlist needs to die
|
||||
[x] SList needs to die
|
||||
[x] SSL
|
||||
[x] Command handling system needs to die, strtok() needs to die more
|
||||
[x] Asynchronous DNS
|
||||
[x] Hashing system for storing just about everything needs to die
|
||||
[x] Add support for +k, +q, etc type umodes
|
||||
[x] Language system is disgusting, it must die.
|
||||
[x] Modules should also have a way to add strings programatically
|
||||
[x] Should be able to add many strings by dropping a file in a set location.
|
||||
[x] Config bailing on /os reload needs to be non fatal
|
||||
[x] AutoID needs to be able to live through /os restart, current system is just annoying.
|
||||
[x] SQL tables need to changed to have references etc
|
||||
[x] Merge NS INFO blah ALL with NS INFO blah, if you're requesting info, you really want the info anyway.
|
||||
[x] More "friendly" date displays of some things like registration time ("November 7th 2006 (2 years, 0 months, 0 days ago)")
|
||||
[?] Remote identification
|
||||
[x] Move a (lot) of stuff to class members as a defined interface rather than copypasta everywhere (ns_set, ns_saset!)
|
||||
[x] Store vhosts in SQL.
|
||||
[x] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
|
||||
[x] Allow users to delete their own access
|
||||
[x] ChanServ CLONE command
|
||||
[x] XMLRPC to execute commands and get data from Anope
|
||||
[+] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice
|
||||
[x] Method to store listmodes (more generically than AKICK, too) for e.g. +beI and extbans, etc.
|
||||
[ ] understanding extbans for /cs unban etc.
|
||||
[ ] (optional?) A way to confirm email changes by users
|
||||
[ ] Auto identify through SSL key
|
||||
[ ] Optional os_login system that can also use SSL keys.
|
||||
[ ] os_info module to show useful configuration settings to services opers.
|
||||
[ ] Remove nick requests. Instead use an unconfirmed nick group which cant recieve umode +r and auto expires after 1d?
|
||||
[ ] LDAP
|
||||
|
||||
Future
|
||||
------
|
||||
[+] Method to store listmodes (more generically than AKICK, too) for e.g. +beI and extbans, etc.
|
||||
[ ] XMLRPC to execute commands and get data from Anope
|
||||
[ ] NS IDENTIFY changes
|
||||
[?] Last failed identify? Maybe more useful for sopers only, so users don't get unnecessarily worried
|
||||
[?] Last successful login time/ip? perhaps both of these should be a new nick setting
|
||||
[ ] NS INFO: seperate field for last seen realhost, shown to SRA only
|
||||
[ ] NS SUSPEND: show suspender and reason, probably to sopers only (see CS SUSPEND)
|
||||
[ ] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
|
||||
[ ] Allow channel founders to change the fantasy trigger for their channel.
|
||||
[ ] CIDR Akills, session exceptions, etc
|
||||
[ ] Language charset stuff, including collation (1.9.1? phoenix?)
|
||||
[ ] fantasy: allow replies/notifications to fantasy commands to go to the channel via notice
|
||||
[?] Language charset stuff, including collation (1.9.1? phoenix?)
|
||||
[?] a way for a module to queue itself (or even another module) for unloading
|
||||
[ ] Useful/common "third party" modules to core distro
|
||||
[ ] NS AJOIN
|
||||
[ ] CS ENTRYMSG
|
||||
[x] CS ENTRYMSG
|
||||
[?] Don't allow soper accounts to expire
|
||||
[?] Reason for CS SET RESTRICTED
|
||||
[x] AKILL/SGLINE/etc..
|
||||
[x] Setter
|
||||
[x] Time added
|
||||
[+] Time modified (can they be modified?)
|
||||
[ ] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human)
|
||||
[x] Time until expiry/expiry time (YES, time until expiry *instead of* expiry time, more human)
|
||||
[x] Reason
|
||||
[ ] Unique IDs on each AKILL/blah so that networks may use them as ticket IDs
|
||||
[ ] HS ACTIVATE -ALL (rob sez this all needs reviewing)
|
||||
[?] Drop CS SET ENTRYMSG, replace with a 'news' type system? (limited to a configured number of items, default 3)
|
||||
|
||||
+2
-2
@@ -10,10 +10,10 @@ Anope Bundled Tools
|
||||
options. To use the SMTP client instead of sendmail, find the line in your
|
||||
services configuration file (services.conf) that defines sendmailpath. On
|
||||
that line, change the path to your services installation directory, then
|
||||
followed by "tools/anopesmtp" and the IP address of a valid SMTP server. It
|
||||
followed by "bin/anopesmtp" and the IP address of a valid SMTP server. It
|
||||
should look like this:
|
||||
|
||||
sendmailpath = "/home/anope/services/tools/anopesmtp 127.0.0.1"
|
||||
sendmailpath = "/home/anope/services/bin/anopesmtp 127.0.0.1"
|
||||
|
||||
If the SMTP client doesn't send mail, or if there's an other problem with
|
||||
it, you can compile it in debug mode. To do this, open anopesmtp.cpp, and look
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
Troubleshooting Guide for Anope 1.9
|
||||
------------------------------------------------
|
||||
|
||||
NOTE:
|
||||
An updated version of this guide can be found on our wiki:
|
||||
|
||||
http://wiki.anope.org/index.php/Troubleshooting
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
1) General
|
||||
1.1) Anope complains in the logfile about being unable to load the default
|
||||
language.
|
||||
1.2) Anope spricht kein Deutsch!, etc. (Anope doesn't speak my language!)
|
||||
1.3) I selected a language other than English, but sometimes Anope sends
|
||||
responses in English instead.
|
||||
1.4) Anope always dies after about five minutes, saying "FATAL ERROR! Can't
|
||||
back up nick.db".
|
||||
1.5) Anope crashed with a segmentation fault.
|
||||
1.6) I've found a bug that's not mentioned here or in the README or BUGS
|
||||
files. What should I do?
|
||||
1.7) My FreeBSD box complains about 'Shared object "nss_dns.so.1" not
|
||||
found'
|
||||
1.8) Anope and long (more then 30 character) nicknames.
|
||||
|
||||
2) Installation / Configuration
|
||||
2.1) When I run "make", I get an error message like "missing separator",
|
||||
"Unassociated shell command", "Unexpected end of line seen", etc.
|
||||
2.2) I get an error like "Makefile.inc not found".
|
||||
2.3) I typed "./services" at the command line, but nothing happened!
|
||||
2.4) Whenever I start Anope, I get a message on my IRC server saying
|
||||
"connection refused" or something similar, and Anope gives an error
|
||||
message from the server saying "Closing Link: ...".
|
||||
2.5) My IRC server is giving me messages like "Connection to
|
||||
services.whatever.net[127.0.0.1] activated" and then "Access denied --
|
||||
no N line". Why?
|
||||
2.6) When I say "/connect services.*", it doesn't work!
|
||||
2.7) Anope starts up okay, but if I try to register a nickname, it comes
|
||||
back with "Sorry, registration failed."
|
||||
2.8) Anope reports (via /stats u or /msg OperServ STATS) a different number
|
||||
of users online than I get from doing /lusers.
|
||||
|
||||
3) BotServ
|
||||
3.1) How do I add bots to BotServ?
|
||||
3.2) Why do kick triggers and fantasy commands fail to work with my Bahamut
|
||||
IRCd?
|
||||
|
||||
4) ChanServ
|
||||
4.1) Anope's channel mode setting doesn't work. I can't set modes with
|
||||
OperServ, and every time ChanServ tries to set a mode, my server
|
||||
reverses the change.
|
||||
4.2) Anope ignored the SET SUCCESSOR setting and deleted a channel when the
|
||||
founder expired.
|
||||
4.3) How to auto voice all those whom join my #channel?
|
||||
4.4) Channel options like RESTRICTED or SECUREOPS don't work. What's wrong?
|
||||
|
||||
5) OperServ
|
||||
5.1) Using the OperServ JUPE command results in server messages like
|
||||
"Server juped.server introduced by non-hub server services.my.net".
|
||||
5.2) When I add an AKILL, the users matching it don't get killed.
|
||||
5.3) Trying to use OperServ gives me "Access denied".
|
||||
5.4) I can't get /OS UMODES and /OS SVSNICK to work!
|
||||
5.5) What is a Super-Admin? How does it work? Why might it not work?
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
1) General
|
||||
|
||||
1.1) Anope complains in the logfile about being unable to load the default
|
||||
language.
|
||||
|
||||
You forgot to run "make install".
|
||||
|
||||
1.2) Anope spricht kein Deutsch!, etc. (Anope doesn't speak my language!)
|
||||
|
||||
See section 5 of the README file.
|
||||
|
||||
1.3) I selected a language other than English, but sometimes Anope sends
|
||||
responses in English instead.
|
||||
|
||||
Some language files are not complete--in other words, they only have a
|
||||
translation of some of the message Anope uses. In this case, the
|
||||
missing messages will be displayed in English. You can either wait for
|
||||
the primary translator to provide us with a translation, or do the
|
||||
translation yourself and send us the messages translated into your
|
||||
language.
|
||||
|
||||
1.4) Anope always dies after about five minutes, saying "FATAL ERROR! Can't
|
||||
back up nick.db".
|
||||
|
||||
Make sure that the user Anope runs as has write access to the data
|
||||
directory, and that the data directory actually exists (the latter
|
||||
shouldn't be a problem if you ran the Config script). This means Anope
|
||||
needs write and execute permission on the data directory itself and execute
|
||||
permission on every parent directory of the data directory.
|
||||
|
||||
1.5) Anope crashed with a segmentation fault.
|
||||
|
||||
See if you can reproduce this by doing a certain sequence of things. If
|
||||
so, please report it to us (see part 6 of README file). If not, you're
|
||||
probably out of luck; if you like, you can report it to us anyway, but
|
||||
chances are it won't get fixed if we don't have instructions on reproducing
|
||||
it. If you do have such a problem, you may find the crontab utility useful
|
||||
for dealing with it.
|
||||
|
||||
Also, see the DumpCore directive in the configuration file. It allows Anope
|
||||
to dump its core whenever it's segfaulting, usually calling it core and
|
||||
placing it into Anope's main directory. Open up gdb by issuing the
|
||||
following command at your shell:
|
||||
|
||||
* gdb services core
|
||||
|
||||
(of course replacing 'core' with the name of the core if different) and
|
||||
type 'bt' at the gdb prompt. After that, send us the output you got and
|
||||
keep the core file in a safe place, in case we need it to dig deeper into
|
||||
the problem.
|
||||
|
||||
1.6) I've found a bug that's not mentioned here or in the README or BUGS files.
|
||||
What should I do?
|
||||
|
||||
See section 6 of the README file.
|
||||
|
||||
1.7) My FreeBSD box complains about 'Shared object "nss_dns.so.1" not found'
|
||||
|
||||
We haven't figured out the exact cause yet, but as a quickfix you can
|
||||
delete the /etc/nsswitch.conf file. Please keep in mind that removing a
|
||||
configuration file can be dangerous, so only do this if you know what you
|
||||
are doing.
|
||||
|
||||
1.8) Anope and long (more then 30 character) nicknames.
|
||||
|
||||
By default, Anope only supports nicknames up to 30 characters (NICKLEN=30).
|
||||
If your IRCd allows for longer nicknames or has been modified to do so
|
||||
Anope will start logging a lot of ("NICK from nonexistent nick") messages.
|
||||
This is because once a user uses a nick that is too long for Anope to handle,
|
||||
Anope loses track of the user for the remainder of the session.
|
||||
It is POSSIBLE but not NOT RECOMMENDED to extend the maximum length of nicknames
|
||||
Anope can track, however this will also break database compatibility. DBs saved
|
||||
with Anope set to allow for example 40 chars cannot be read by a clean Anope
|
||||
installation and vice versa. So changing the maximum nick length is only possible
|
||||
when starting with fresh databases and even then the consequences of this are
|
||||
UNTESTED.
|
||||
In order to change the maximum internal nick length, change the NICKMAX setting
|
||||
in include/config.h, recompile anope and start without databases.
|
||||
|
||||
|
||||
2) Installation / Configuration
|
||||
|
||||
2.1) When I run "make", I get an error message like "missing separator",
|
||||
"Unassociated shell command", "Unexpected end of line seen", etc.
|
||||
|
||||
Your make program isn't compatible with the Makefile for Anope. The
|
||||
Makefile was designed to work with GNU make, and as such may not work on
|
||||
other systems' "make" programs. If you get an error from "make", obtain
|
||||
GNU make from ftp://prep.ai.mit.edu/pub/gnu/make/ (or wherever you prefer) and
|
||||
use it instead of your system's default "make". Note that GNU make may
|
||||
already be installed on your system; try using the command "gmake" instead
|
||||
of "make".
|
||||
|
||||
The make programs bundled with SunOS/Solaris and FreeBSD have been reported
|
||||
not to work; you will need to use GNU make on these systems.
|
||||
|
||||
2.2) I get an error like "Makefile.inc not found".
|
||||
|
||||
You forgot to run the Config script first. See the INSTALL file for
|
||||
compilation instructions.
|
||||
|
||||
2.3) I typed "./services" at the command line, but nothing happened!
|
||||
|
||||
Anope puts itself in the background when it starts, so you get your shell
|
||||
prompt right back. Meanwhile, Anope will continue setting up, then connect
|
||||
to the IRC server specified in services.conf (or on the command line). If
|
||||
it doesn't connect, you probably specified the wrong IRCd or RemoteServer in
|
||||
the configuration file. Check to make sure that you are actually running one of
|
||||
the supported IRCds, also. A list of supported IRCds can be found in the README
|
||||
file.
|
||||
|
||||
You can also check the log file (services.log by default) for error
|
||||
messages. Starting services with the -support command line option
|
||||
will prevent it from running in the background will output the
|
||||
messages written to the log file to the console as well. Please note that this
|
||||
will also prevent 3rd party modules from loading and will put Anope into
|
||||
debug mode.
|
||||
|
||||
2.4) Whenever I start Anope, I get a message on my IRC server saying
|
||||
"connection refused" or something similar, and Anope gives an error
|
||||
message from the server saying "Closing Link: ...".
|
||||
|
||||
See section 3 of the INSTALL file.
|
||||
|
||||
2.5) My IRC server is giving me messages like "Connection to
|
||||
services.whatever.net[127.0.0.1] activated" and then "Access denied -- no
|
||||
N line". Why?
|
||||
|
||||
This is typically caused by including a port number in the C:line for
|
||||
services, which tells your server to try to autoconnect to it (depending on
|
||||
the class (Y:line) settings). This is not what you want, because Anope
|
||||
will connect to the server itself, but does not listen for servers to
|
||||
connect to it. The solution is to remove the port number from the C:line.
|
||||
|
||||
2.6) When I say "/connect services.*", it doesn't work!
|
||||
|
||||
You cannot /connect services. When you start Anope, it will attempt to
|
||||
connect to the server you specified in services.conf. Please see the answer
|
||||
above for more information.
|
||||
|
||||
2.7) Anope starts up okay, but if I try to register a nickname, it comes back
|
||||
with "Sorry, registration failed."
|
||||
|
||||
Make sure you've selected the correct IRC server type in the configure
|
||||
script; see section 3 of the INSTALL file for details.
|
||||
|
||||
2.8) Anope reports (via /stats u or /msg OperServ STATS) a different number of
|
||||
users online than I get from doing /lusers.
|
||||
|
||||
Anope doesn't count its own pseudo-clients (NickServ, ChanServ, etc.) in
|
||||
its user count, while the IRC server does.
|
||||
|
||||
3) BotServ
|
||||
|
||||
3.1) How do I add bots to BotServ?
|
||||
|
||||
Read /msg BotServ HELP and /msg BotServ HELP BOT. Note that you need to be
|
||||
opered up and identified as a Services Administrator in Anope before you
|
||||
can use the BOT command.
|
||||
|
||||
3.2) Why do kick triggers and fantasy commands fail to work with my Bahamut
|
||||
IRCd?
|
||||
|
||||
Bahamut allows you to setup a server as 'serviceshub'. This will filter
|
||||
certain data that services usually don't need to process. This option also
|
||||
filters channel messages, because DALnet's services have no use for them.
|
||||
Anope parses the channel messages for kick triggers and fantasy commands.
|
||||
To make sure these work the server type of the hub they're linked to should
|
||||
be simply 'hub' and not 'serviceshub'.
|
||||
|
||||
|
||||
4) ChanServ
|
||||
|
||||
4.1) Anope's channel mode setting doesn't work. I can't set modes with
|
||||
OperServ, and every time ChanServ tries to set a mode, my server reverses
|
||||
the change.
|
||||
|
||||
Make sure EVERY server on your network has a U: line for Services in
|
||||
ircd.conf, for example:
|
||||
|
||||
U:services.whatever.net:*:*
|
||||
|
||||
4.2) Anope ignored the SET SUCCESSOR setting and deleted a channel when the
|
||||
founder expired.
|
||||
|
||||
Normally, this is because the successor had too many channels registered.
|
||||
In this case, you will see an entry in the log file like the following:
|
||||
|
||||
[date] Successor (SuccessorNick) of channel #somechannel owns too many
|
||||
channels, deleting channel #somechannel
|
||||
|
||||
If you don't get a message like this or you can verify that the successor
|
||||
wasn't running into the channel limit, please report it using the
|
||||
bug-reporting procedure in section 6 of the README file.
|
||||
|
||||
4.3) How to auto voice all those whom join my #channel?
|
||||
|
||||
Execute the following commands (/cs is an alias for /msg ChanServ):
|
||||
|
||||
/cs set #channel secure off
|
||||
/cs set #channel xop off
|
||||
/cs levels #channel set AUTOVOICE -1
|
||||
|
||||
4.4) Channel options like RESTRICTED or SECUREOPS don't work. What's wrong?
|
||||
|
||||
Make sure that you didn't put any of your normal IRCd's as a ULined server
|
||||
in Anope. Some access checks for clients from ULined servers are skipped to
|
||||
avoid fights between the ULined servers. This is usually only useful when
|
||||
you have a statistics server connected to your network.
|
||||
|
||||
5) OperServ
|
||||
|
||||
5.1) Using the OperServ JUPE command results in server messages like "Server
|
||||
juped.server introduced by non-hub server services.my.net".
|
||||
|
||||
Services' uplink must have an H: line for Services in the ircd.conf file,
|
||||
which looks something like:
|
||||
|
||||
H:*::services.whatever.net
|
||||
|
||||
5.2) When I add an AKILL, the users matching it don't get killed.
|
||||
|
||||
Use the AkillOnAdd configuration directive.
|
||||
|
||||
5.3) Trying to use OperServ gives me "Access denied".
|
||||
|
||||
Check that you're opered on your IRCd (ie, moded +o)
|
||||
Check that you're identified to a nickname listed within an opertype allowed to do the command you're trying.
|
||||
Check whether you can use /msg operserv staff
|
||||
|
||||
5.4) I can't get /OS UMODES and /OS SVSNICK to work!
|
||||
|
||||
You need to be a SuperAdmin to be able to use these commands.
|
||||
|
||||
5.5) What is a Super-Admin? How does it work? Why might it not work?
|
||||
|
||||
SuperAdmin's have extra privileges, including being founder on all
|
||||
channels. It must be activated on a per user basis and is only available to
|
||||
Services Roots. It is set using OperServ and is not persistent. It only
|
||||
works if SuperAdmin is not commented in the services configuration file,
|
||||
which is commented out by default. Read /msg OperServ HELP SET SUPERADMIN
|
||||
for further help.
|
||||
+1
-1
@@ -104,7 +104,7 @@ Anope for Windows
|
||||
Building Anope with gettext requires libintl, libiconv, libgcc and
|
||||
libmingex. We have precompiled these libraries for you that you may
|
||||
use if you want. They are avaiable at http://anope.org/downloads/anope-extra.zip
|
||||
The OpenSSL and MySQL header files and libraries are also included in
|
||||
The OpenSSL, MySQL, and OpenLDAP header files and libraries are also included in
|
||||
this package. Once downloaded and extracted, you should run install.bat
|
||||
then give Config the path to the new 'installed' directory.
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
Starting with Anope 1.9.4 XMLRPC using PHP's xmlrpc_encode_request and xmlrpc_decode functions is supported.
|
||||
This allows external applications, such as websites, to execute remote procedure calls to Anope in real time.
|
||||
|
||||
Currently there are 5 supported XMLRPC calls, provided by m_xmlrpc_main:
|
||||
|
||||
checkAuthetication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password
|
||||
is correct for the account name, useful for making login pages on websites.
|
||||
|
||||
command - Takes three parameters, a service name (BotServ, ChanServ, NickServ), a user name (whether online or not), and the command
|
||||
to execute. This will execute a the given command to Anope using the given service name. If the user given is online, the
|
||||
command reply will go to them, if not it is returned by XMLRPC.
|
||||
|
||||
stats - Takes no parameters, returns miscellaneous stats that can be found in the /operserv stats command.
|
||||
|
||||
channel - Takes one parameter, a channel name, and returns real time information regarding that channel, such as users, modes
|
||||
(ban lists and such), topic etc.
|
||||
|
||||
user - Takes one parameter, a user name, and returns real time information regarding that user.
|
||||
|
||||
XMLRPC was designed to be used with db_mysql, and will not return any information that can be pulled from the SQL
|
||||
database, such as accounts and registered channel information. It is instead used for pulling realtime data such
|
||||
as users and channels currently onlive. For examples on how to use these calls in PHP, see xmlrpc.php in docs/XMLRPC.
|
||||
|
||||
Also note that the parameter named "id" is reserved for query ID. If you pass a query to Anope containing a value for id. it will
|
||||
be stored by Anope and the same id will be passed back in the result.
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/* XMLRPC Functions
|
||||
*
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
*/
|
||||
|
||||
class AnopeXMLRPC
|
||||
{
|
||||
private $Host, $Bind, $Port;
|
||||
|
||||
private $Socket;
|
||||
|
||||
function __construct($Host, $Port, $Bind = NULL)
|
||||
{
|
||||
$this->Host = $Host;
|
||||
$this->Port = $Port;
|
||||
$this->Bind = $Bind;
|
||||
|
||||
$this->Socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if ($Bind && socket_bind($this->Socket, $this->Bind) == false)
|
||||
$his->Socket = false;
|
||||
if (socket_connect($this->Socket, $this->Host, $this->Port) == false)
|
||||
$this->Socket = false;
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
@socket_close($this->Socket);
|
||||
}
|
||||
|
||||
/** Run an XMLRPC command. Name should be a query name and params an array of parameters, eg:
|
||||
* $this->RunXMLRPC("checkAuthentication", array("adam", "qwerty"));
|
||||
* If successful returns back an array of useful information.
|
||||
*
|
||||
* Note that $params["id"] is reserved for query ID, you may set it to something if you wish.
|
||||
* If you do, the same ID will be passed back with the reply from Anope.
|
||||
*/
|
||||
function RunXMLRPC($name, $params)
|
||||
{
|
||||
$xmlquery = xmlrpc_encode_request($name, $params);
|
||||
socket_write($this->Socket, $xmlquery);
|
||||
|
||||
$inbuf = socket_read($this->Socket, 4096);
|
||||
$inbuf = substr($inbuf, strpos($inbuf, "\r\n\r\n") + 4);
|
||||
$response = xmlrpc_decode($inbuf);
|
||||
|
||||
if (isset($response[0]))
|
||||
return $response[0];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Do Command on Service as User, eg:
|
||||
* $anope->DoCommand("ChanServ", "Adam", "REGISTER #adam");
|
||||
* Returns an array of information regarding the command execution, if
|
||||
* If 'online' is set to yes, then the reply to the command was sent to the user on IRC.
|
||||
* If 'online' is set to no, then the reply to the command is in the array member 'return'
|
||||
*/
|
||||
function DoCommand($Service, $User, $Command)
|
||||
{
|
||||
return $this->RunXMLRPC("command", array($Service, $User, $Command));
|
||||
}
|
||||
|
||||
/** Check an account/nick name and password to see if they are valid
|
||||
* Returns the account display name if valid
|
||||
*/
|
||||
function CheckAuthentication($Account, $Pass)
|
||||
{
|
||||
$ret = $this->RunXMLRPC("checkAuthentication", array($Account, $Pass));
|
||||
|
||||
if ($ret && $ret["result"] == "Success")
|
||||
return $ret["account"];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns an array of misc stats regarding Anope
|
||||
*/
|
||||
function DoStats()
|
||||
{
|
||||
return $this->RunXMLRPC("stats", NULL);
|
||||
}
|
||||
|
||||
/* Look up data for a channel
|
||||
* Returns an array containing channel information, or an array of size one
|
||||
* (just containing the name) if the channel does not exist
|
||||
*/
|
||||
function DoChannel($Channel)
|
||||
{
|
||||
return $this->RunXMLRPC("channel", NULL);
|
||||
}
|
||||
|
||||
/* Like DoChannel(), but different.
|
||||
*/
|
||||
function DoUser($User)
|
||||
{
|
||||
return $this->RunXMLRPC("user", array($User));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
+28
-1
@@ -16,5 +16,32 @@ if(NOT WIN32)
|
||||
add_to_cpack_ignored_files("version.h$" TRUE)
|
||||
endif(NOT WIN32)
|
||||
|
||||
set(PCH_SOURCES_GCH "")
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
string(REPLACE " " ";" PCH_CXXFLAGS ${CXXFLAGS})
|
||||
file(GLOB INCLUDE_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
|
||||
remove_item_from_list(INCLUDE_SRCS "version.h")
|
||||
|
||||
set(PCH_SOURCES "module.h;modules.h;services.h")
|
||||
foreach(PCH_SOURCE ${PCH_SOURCES})
|
||||
set(PCH_EXTRAFLAGS "")
|
||||
if(DEBUG_BUILD)
|
||||
set(PCH_EXTRAFLAGS "-g")
|
||||
endif(DEBUG_BUILD)
|
||||
if(PCH_SOURCE STREQUAL "module.h")
|
||||
set(PCH_EXTRAFLAGS ${PCH_EXTRAFLAGS} -fPIC)
|
||||
endif(PCH_SOURCE STREQUAL "module.h")
|
||||
if(GETTEXT_INCLUDE)
|
||||
set(PCH_GETTEXT_INCLUDE "-I${GETTEXT_INCLUDE}")
|
||||
endif(GETTEXT_INCLUDE)
|
||||
|
||||
set(PCH_SOURCES_GCH "${PCH_SOURCES_GCH};${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch")
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch
|
||||
COMMAND ${CMAKE_CXX_COMPILER} ARGS ${PCH_CXXFLAGS} ${PCH_EXTRAFLAGS} ${PCH_GETTEXT_INCLUDE} -I${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${PCH_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch
|
||||
DEPENDS ${INCLUDE_SRCS} VERBATIM
|
||||
)
|
||||
endforeach(PCH_SOURCE ${PCH_SOURCES})
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# Add a custom target to the above file
|
||||
add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
add_custom_target(headers DEPENDS version ${CMAKE_CURRENT_BINARY_DIR}/version.h ${PCH_SOURCES_GCH})
|
||||
|
||||
+54
-29
@@ -5,15 +5,12 @@
|
||||
|
||||
class NickAlias;
|
||||
class NickCore;
|
||||
class NickRequest;
|
||||
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, NickAlias *, ci::hash, std::equal_to<ci::string> > nickalias_map;
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, NickCore *, ci::hash, std::equal_to<ci::string> > nickcore_map;
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, NickRequest *, ci::hash, std::equal_to<ci::string> > nickrequest_map;
|
||||
|
||||
extern CoreExport nickalias_map NickAliasList;
|
||||
extern CoreExport nickcore_map NickCoreList;
|
||||
extern CoreExport nickrequest_map NickRequestList;
|
||||
|
||||
/* NickServ nickname structures. */
|
||||
|
||||
@@ -41,6 +38,10 @@ enum NickNameFlag
|
||||
NS_END
|
||||
};
|
||||
|
||||
const Anope::string NickNameFlagStrings[] = {
|
||||
"BEGIN", "FORBIDDEN", "NO_EXPIRE", "HELD", "COLLIDED", ""
|
||||
};
|
||||
|
||||
/** Flags set on NickCores
|
||||
*/
|
||||
enum NickCoreFlag
|
||||
@@ -81,23 +82,17 @@ enum NickCoreFlag
|
||||
NI_AUTOOP,
|
||||
/* This nickcore is forbidden, which means the nickalias for it is aswell */
|
||||
NI_FORBIDDEN,
|
||||
/* If set means the nick core does not have their email addrses confirmed.
|
||||
*/
|
||||
NI_UNCONFIRMED,
|
||||
|
||||
NI_END
|
||||
};
|
||||
|
||||
class CoreExport NickRequest : public Extensible
|
||||
{
|
||||
public:
|
||||
NickRequest(const Anope::string &nickname);
|
||||
|
||||
~NickRequest();
|
||||
|
||||
Anope::string nick;
|
||||
Anope::string passcode;
|
||||
Anope::string password;
|
||||
Anope::string email;
|
||||
time_t requested;
|
||||
time_t lastmail; /* Unsaved */
|
||||
const Anope::string NickCoreFlagStrings[] = {
|
||||
"BEGIN", "KILLPROTECT", "SECURE", "MSG", "MEMO_HARDMAX", "MEMO_SIGNON", "MEMO_RECEIVE",
|
||||
"PRIVATE", "HIDE_EMAIL", "HIDE_MASK", "HIDE_QUIT", "KILL_QUICK", "KILL_IMMED",
|
||||
"MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "FORBIDDEN", "UNCONFIRMED", ""
|
||||
};
|
||||
|
||||
class NickCore;
|
||||
@@ -157,32 +152,21 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END
|
||||
Anope::string greet; /* Greet associated to the nick */
|
||||
Anope::string language; /* Language name */
|
||||
std::vector<Anope::string> access; /* Access list, vector of strings */
|
||||
std::vector<Anope::string> cert; /* ssl certificate list, vector of strings */
|
||||
MemoInfo memos;
|
||||
uint16 channelcount; /* Number of channels currently registered */
|
||||
|
||||
OperType *ot;
|
||||
Oper *o;
|
||||
|
||||
/* Unsaved data */
|
||||
time_t lastmail; /* Last time this nick record got a mail */
|
||||
std::list<NickAlias *> aliases; /* List of aliases */
|
||||
|
||||
/** Check whether this opertype has access to run the given command string.
|
||||
* @param cmdstr The string to check, e.g. botserv/set/private.
|
||||
* @return True if this opertype may run the specified command, false otherwise.
|
||||
*/
|
||||
virtual bool HasCommand(const Anope::string &cmdstr) const;
|
||||
|
||||
/** Checks whether this account is a services oper or not.
|
||||
* @return True if this account is a services oper, false otherwise.
|
||||
*/
|
||||
virtual bool IsServicesOper() const;
|
||||
|
||||
/** Check whether this opertype has access to the given special permission.
|
||||
* @param privstr The priv to check for, e.g. users/auspex.
|
||||
* @return True if this opertype has the specified priv, false otherwise.
|
||||
*/
|
||||
virtual bool HasPriv(const Anope::string &privstr) const;
|
||||
|
||||
/** Add an entry to the nick's access list
|
||||
*
|
||||
* @param entry The nick!ident@host entry to add to the access list
|
||||
@@ -222,6 +206,47 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END
|
||||
* Deletes all the memory allocated in the access list vector and then clears the vector.
|
||||
*/
|
||||
void ClearAccess();
|
||||
|
||||
/** Add an entry to the nick's certificate list
|
||||
*
|
||||
* @param entry The fingerprint to add to the cert list
|
||||
*
|
||||
* Adds a new entry into the cert list.
|
||||
*/
|
||||
void AddCert(const Anope::string &entry);
|
||||
|
||||
/** Get an entry from the nick's cert list by index
|
||||
*
|
||||
* @param entry Index in the certificaate list vector to retrieve
|
||||
* @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
|
||||
*
|
||||
* Retrieves an entry from the certificate list corresponding to the given index.
|
||||
*/
|
||||
Anope::string GetCert(unsigned entry) const;
|
||||
|
||||
/** Find an entry in the nick's cert list
|
||||
*
|
||||
* @param entry The fingerprint to search for
|
||||
* @return True if the fingerprint is found in the cert list, false otherwise
|
||||
*
|
||||
* Search for an fingerprint within the cert list.
|
||||
*/
|
||||
bool FindCert(const Anope::string &entry);
|
||||
|
||||
/** Erase a fingerprint from the nick's certificate list
|
||||
*
|
||||
* @param entry The fingerprint to remove
|
||||
*
|
||||
* Removes the specified fingerprint from the cert list.
|
||||
*/
|
||||
void EraseCert(const Anope::string &entry);
|
||||
|
||||
/** Clears the entire nick's cert list
|
||||
*
|
||||
* Deletes all the memory allocated in the certificate list vector and then clears the vector.
|
||||
*/
|
||||
void ClearCert();
|
||||
|
||||
};
|
||||
|
||||
/** Timer for colliding nicks to force people off of nicknames
|
||||
|
||||
+25
-4
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -20,6 +20,9 @@ class Message;
|
||||
|
||||
namespace Anope
|
||||
{
|
||||
template<typename T> class map : public std::map<string, T> { };
|
||||
template<typename T> class insensitive_map : public std::map<string, T, std::less<ci::string> > { };
|
||||
|
||||
/**
|
||||
* A wrapper string class around all the other string classes, this class will
|
||||
* allow us to only require one type of string everywhere that can be converted
|
||||
@@ -153,6 +156,11 @@ namespace Anope
|
||||
*/
|
||||
inline size_type length() const { return this->_string.length(); }
|
||||
|
||||
/**
|
||||
* Add a char to the end of the string.
|
||||
*/
|
||||
inline void push_back(char c) { return this->_string.push_back(c); }
|
||||
|
||||
/**
|
||||
* Resizes the string content to n characters.
|
||||
*/
|
||||
@@ -294,8 +302,12 @@ namespace Anope
|
||||
extern CoreExport time_t CurTime;
|
||||
|
||||
extern CoreExport string Version();
|
||||
|
||||
extern CoreExport string Build();
|
||||
extern CoreExport string VersionShort();
|
||||
extern CoreExport string VersionBuildString();
|
||||
extern CoreExport int VersionMajor();
|
||||
extern CoreExport int VersionMinor();
|
||||
extern CoreExport int VersionPatch();
|
||||
extern CoreExport int VersionBuild();
|
||||
|
||||
/** Check whether two strings match.
|
||||
* @param str The string to check against the pattern (e.g. foobar)
|
||||
@@ -324,6 +336,15 @@ namespace Anope
|
||||
extern CoreExport void Unhex(const Anope::string &src, Anope::string &dest);
|
||||
extern CoreExport void Unhex(const Anope::string &src, char *dest);
|
||||
|
||||
/** Returns a sequence of data formatted as the format argument specifies.
|
||||
** After the format parameter, the function expects at least as many
|
||||
** additional arguments as specified in format.
|
||||
* @param fmt Format of the Message
|
||||
* @param ... any number of parameters
|
||||
* @return a Anope::string
|
||||
*/
|
||||
extern CoreExport string printf(const char *fmt, ...);
|
||||
|
||||
/** Return the last error, uses errno/GetLastError() to determin this
|
||||
* @return An error message
|
||||
*/
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Robin Burchell <w00t@inspircd.org>
|
||||
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
|
||||
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
|
||||
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*/
|
||||
@@ -12,10 +12,8 @@
|
||||
|
||||
class BotInfo;
|
||||
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, BotInfo *, ci::hash, std::equal_to<ci::string> > botinfo_map;
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, BotInfo *, Anope::hash> botinfo_uid_map;
|
||||
extern CoreExport botinfo_map BotListByNick;
|
||||
extern CoreExport botinfo_uid_map BotListByUID;
|
||||
extern CoreExport Anope::insensitive_map<BotInfo *> BotListByNick;
|
||||
extern CoreExport Anope::map<BotInfo *> BotListByUID;
|
||||
|
||||
/** Flags settable on a bot
|
||||
*/
|
||||
@@ -31,6 +29,8 @@ enum BotFlag
|
||||
BI_END
|
||||
};
|
||||
|
||||
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "" };
|
||||
|
||||
class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
|
||||
{
|
||||
public:
|
||||
@@ -75,15 +75,15 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
|
||||
|
||||
/** Join this bot to a channel
|
||||
* @param c The channel
|
||||
* @param update_ts Assume we're updating the TS for this channel
|
||||
* @param status The status the bot should have on the channel
|
||||
*/
|
||||
void Join(Channel *c, bool update_ts = false);
|
||||
void Join(Channel *c, ChannelStatus *status = NULL);
|
||||
|
||||
/** Join this bot to a channel
|
||||
* @param chname The channel name
|
||||
* @param update_ts Assume we're updating the TS for this channel
|
||||
* @param status The status the bot should have on the channel
|
||||
*/
|
||||
void Join(const Anope::string &chname, bool update_ts = false);
|
||||
void Join(const Anope::string &chname, ChannelStatus *status = NULL);
|
||||
|
||||
/** Part this bot from a channel
|
||||
* @param c The channel
|
||||
|
||||
+15
-47
@@ -1,6 +1,6 @@
|
||||
/* Channel support
|
||||
*
|
||||
* (C) 2008-2010 Anope Team
|
||||
* (C) 2008-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -52,7 +52,7 @@ struct UserContainer
|
||||
|
||||
typedef std::list<UserContainer *> CUserList;
|
||||
|
||||
enum ChannelFlags
|
||||
enum ChannelFlag
|
||||
{
|
||||
/* Channel still exists when emptied */
|
||||
CH_PERSIST,
|
||||
@@ -62,15 +62,14 @@ enum ChannelFlags
|
||||
CH_LOGCHAN
|
||||
};
|
||||
|
||||
class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
|
||||
class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
|
||||
{
|
||||
public:
|
||||
typedef std::multimap<ChannelModeName, Anope::string> ModeList;
|
||||
private:
|
||||
/** A map of channel modes with their parameters set on this channel
|
||||
*/
|
||||
std::map<ChannelModeName, Anope::string> Params;
|
||||
|
||||
/* Modes set on the channel */
|
||||
Flags<ChannelModeName, CMODE_END * 2> modes;
|
||||
ModeList modes;
|
||||
|
||||
public:
|
||||
/** Default constructor
|
||||
@@ -87,10 +86,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
|
||||
ChannelInfo *ci; /* Corresponding ChannelInfo */
|
||||
time_t creation_time; /* When channel was created */
|
||||
|
||||
EList *bans;
|
||||
EList *excepts;
|
||||
EList *invites;
|
||||
|
||||
/* List of users in the channel */
|
||||
CUserList users;
|
||||
|
||||
@@ -146,16 +141,18 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
|
||||
*/
|
||||
bool HasUserStatus(User *u, ChannelModeName Name) const;
|
||||
|
||||
/** See if the channel has any modes at all
|
||||
* @return true or false
|
||||
*/
|
||||
inline bool HasModes() const { return modes.FlagCount(); }
|
||||
|
||||
/** See if a channel has a mode
|
||||
* @param Name The mode name
|
||||
* @return true or false
|
||||
* @return The number of modes set
|
||||
* @param param The optional mode param
|
||||
*/
|
||||
bool HasMode(ChannelModeName Name) const;
|
||||
size_t HasMode(ChannelModeName Name, const Anope::string ¶m = "");
|
||||
|
||||
/** Get a list of modes on a channel
|
||||
* @param Name A mode name to get the list of
|
||||
* @return a pair of iterators for the beginning and end of the list
|
||||
*/
|
||||
std::pair<ModeList::iterator, ModeList::iterator> GetModeList(ChannelModeName Name);
|
||||
|
||||
/** Set a mode internally on a channel, this is not sent out to the IRCd
|
||||
* @param cm The mode
|
||||
@@ -205,30 +202,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
|
||||
*/
|
||||
void RemoveMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m = "", bool EnforceMLock = true);
|
||||
|
||||
/** Clear all the modes from the channel
|
||||
* @param bi The client unsetting the modes
|
||||
* @param internal Only remove the modes internally
|
||||
*/
|
||||
void ClearModes(BotInfo *bi = NULL, bool internal = false);
|
||||
|
||||
/** Clear all the bans from the channel
|
||||
* @param bi The client unsetting the modes
|
||||
* @param internal Only remove the modes internally
|
||||
*/
|
||||
void ClearBans(BotInfo *bi = NULL, bool internal = false);
|
||||
|
||||
/** Clear all the excepts from the channel
|
||||
* @param bi The client unsetting the modes
|
||||
* @param internal Only remove the modes internally
|
||||
*/
|
||||
void ClearExcepts(BotInfo *bi = NULL, bool internal = false);
|
||||
|
||||
/** Clear all the invites from the channel
|
||||
* @param bi The client unsetting the modes
|
||||
* @param internal Only remove the modes internally
|
||||
*/
|
||||
void ClearInvites(BotInfo *bi = NULL, bool internal = false);
|
||||
|
||||
/** Get a param from the channel
|
||||
* @param Name The mode
|
||||
* @param Target a string to put the param into
|
||||
@@ -236,11 +209,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags>
|
||||
*/
|
||||
bool GetParam(ChannelModeName Name, Anope::string &Target) const;
|
||||
|
||||
/** Check if a mode is set and has a param
|
||||
* @param Name The mode
|
||||
*/
|
||||
bool HasParam(ChannelModeName Name) const;
|
||||
|
||||
/** Set a string of modes on the channel
|
||||
* @param bi The client setting the modes
|
||||
* @param EnforceMLock Should mlock be enforced on this mode change
|
||||
|
||||
+55
-15
@@ -1,9 +1,9 @@
|
||||
/* Declarations for command data.
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -29,9 +29,9 @@ enum CommandReturn
|
||||
};
|
||||
|
||||
extern CoreExport Command *FindCommand(BotInfo *bi, const Anope::string &cmd);
|
||||
extern CoreExport void mod_help_cmd(BotInfo *bi, User *u, const Anope::string &cmd);
|
||||
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, const Anope::string &message);
|
||||
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, const Anope::string &message);
|
||||
extern CoreExport void mod_help_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &cmd);
|
||||
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, const Anope::string &message);
|
||||
extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope::string &command, const Anope::string &message);
|
||||
|
||||
enum CommandFlag
|
||||
{
|
||||
@@ -43,10 +43,44 @@ enum CommandFlag
|
||||
CFLAG_DISABLE_FANTASY
|
||||
};
|
||||
|
||||
const Anope::string CommandFlagStrings[] = {
|
||||
"CFLAG_ALLOW_UNREGISTERED",
|
||||
"CFLAG_ALLOW_FORBIDDEN",
|
||||
"CFLAG_ALLOW_SUSPENDED",
|
||||
"CFLAG_ALLOW_UNREGISTEREDCHANNEL",
|
||||
"CFLAG_STRIP_CHANNEL",
|
||||
"CFLAG_DISABLE_FANTASY",
|
||||
""
|
||||
};
|
||||
|
||||
/* The source for a command */
|
||||
struct CoreExport CommandSource
|
||||
{
|
||||
/* User executing the command */
|
||||
User *u;
|
||||
/* Channel (if applicable) */
|
||||
ChannelInfo *ci;
|
||||
/* The service this command is on */
|
||||
BotInfo *owner;
|
||||
/* The service the reply should come from, *not* necessarily the service the command is on */
|
||||
BotInfo *service;
|
||||
/* Whether or not this was a fantasy command */
|
||||
bool fantasy;
|
||||
|
||||
std::list<Anope::string> reply;
|
||||
|
||||
void Reply(const char *message, ...);
|
||||
void Reply(const Anope::string &message);
|
||||
|
||||
void DoReply();
|
||||
};
|
||||
|
||||
/** Every services command is a class, inheriting from Command.
|
||||
*/
|
||||
class CoreExport Command : public Flags<CommandFlag>
|
||||
class CoreExport Command : public Flags<CommandFlag>, public Base
|
||||
{
|
||||
Anope::string desc;
|
||||
|
||||
public:
|
||||
/* Maximum paramaters accepted by this command */
|
||||
size_t MaxParams;
|
||||
@@ -72,28 +106,33 @@ class CoreExport Command : public Flags<CommandFlag>
|
||||
|
||||
virtual ~Command();
|
||||
|
||||
protected:
|
||||
void SetDesc(const Anope::string &d);
|
||||
|
||||
public:
|
||||
/** Execute this command.
|
||||
* @param u The user executing the command.
|
||||
* @param source The source
|
||||
* @param params Command parameters
|
||||
*/
|
||||
virtual CommandReturn Execute(User *u, const std::vector<Anope::string> &);
|
||||
virtual CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) = 0;
|
||||
|
||||
/** Called when HELP is requsted for the client this command is on.
|
||||
* @param u The user requesting help
|
||||
* @param source The source
|
||||
*/
|
||||
virtual void OnServHelp(User *u);
|
||||
virtual void OnServHelp(CommandSource &source);
|
||||
|
||||
/** Requested when the user is requesting help on this command. Help on this command should be sent to the user.
|
||||
* @param u The user requesting help
|
||||
* @param source The source
|
||||
* @param subcommand The subcommand the user is requesting help on, or an empty string. (e.g. /ns help set foo bar lol gives a subcommand of "FOO BAR LOL")
|
||||
* @return true if help was provided to the user, false otherwise.
|
||||
*/
|
||||
virtual bool OnHelp(User *u, const Anope::string &subcommand);
|
||||
virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand);
|
||||
|
||||
/** Requested when the user provides bad syntax to this command (not enough params, etc).
|
||||
* @param u The user executing the command.
|
||||
* @param source The source
|
||||
* @param subcommand The subcommand the user tried to use
|
||||
*/
|
||||
virtual void OnSyntaxError(User *u, const Anope::string &subcommand);
|
||||
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand);
|
||||
|
||||
/** Set which command permission (e.g. chanserv/forbid) is required for this command.
|
||||
* @param reststr The permission required to successfully execute this command
|
||||
@@ -101,9 +140,10 @@ class CoreExport Command : public Flags<CommandFlag>
|
||||
void SetPermission(const Anope::string &reststr);
|
||||
|
||||
/** Add a subcommand to this command
|
||||
* @param creator The creator of the subcommand
|
||||
* @param c The command
|
||||
*/
|
||||
virtual bool AddSubcommand(Command *c);
|
||||
virtual bool AddSubcommand(Module *creator, Command *c);
|
||||
|
||||
/** Delete a subcommand from this command
|
||||
* @param c The command
|
||||
|
||||
+106
-169
@@ -34,8 +34,6 @@ enum ConfigDataType
|
||||
DT_UINTEGER, // Unsigned Integer
|
||||
DT_LUINTEGER, // Long Unsigned Integer
|
||||
DT_CHARPTR, // Char pointer
|
||||
DT_CSSTRING, // std::string
|
||||
DT_CISTRING, // ci::string
|
||||
DT_STRING, // Anope::string
|
||||
DT_BOOLEAN, // Boolean
|
||||
DT_HOSTNAME, // Hostname syntax
|
||||
@@ -53,7 +51,7 @@ enum ConfigDataType
|
||||
* The callback function can then alter the values of the ValueItem
|
||||
* classes to validate the settings.
|
||||
*/
|
||||
class ValueItem
|
||||
class CoreExport ValueItem
|
||||
{
|
||||
private:
|
||||
/** Actual data */
|
||||
@@ -89,11 +87,7 @@ class ValueItem
|
||||
int GetInteger() const;
|
||||
/** Get value as a string */
|
||||
const char *GetString() const;
|
||||
/** Get value as an std::string */
|
||||
inline const std::string GetCSValue() const { return v.str(); }
|
||||
/** Get value as a ci::string */
|
||||
inline const ci::string GetCIValue() const { return v.ci_str(); }
|
||||
/** Get value as a ci::string */
|
||||
/** Get value as an Anope::string */
|
||||
inline const Anope::string &GetValue() const { return v; }
|
||||
/** Get value as a bool */
|
||||
bool GetBool() const;
|
||||
@@ -177,78 +171,6 @@ template<> class ValueContainer<char **> : public ValueContainerBase
|
||||
}
|
||||
};
|
||||
|
||||
/** This a specific version of ValueContainer to handle std::string specially
|
||||
*/
|
||||
template<> class ValueContainer<std::string *> : public ValueContainerBase
|
||||
{
|
||||
private:
|
||||
/** Contained item */
|
||||
std::string *val;
|
||||
public:
|
||||
/** Initialize with nothing */
|
||||
ValueContainer() : ValueContainerBase(), val(NULL) { }
|
||||
/** Initialize with an std::string */
|
||||
ValueContainer(std::string *Val) : ValueContainerBase(), val(Val) { }
|
||||
/** Initialize with a copy */
|
||||
ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
|
||||
ValueContainer &operator=(const ValueContainer &Val)
|
||||
{
|
||||
val = Val.val;
|
||||
return *this;
|
||||
}
|
||||
/** Change value to given std::string */
|
||||
void Set(const std::string &newval)
|
||||
{
|
||||
*val = newval;
|
||||
}
|
||||
/** Change value to given ci::string */
|
||||
void Set(const ci::string &newval)
|
||||
{
|
||||
*val = newval.c_str();
|
||||
}
|
||||
/** Change value to given char pointer */
|
||||
void Set(const char *newval)
|
||||
{
|
||||
*val = newval;
|
||||
}
|
||||
};
|
||||
|
||||
/** This a specific version of ValueContainer to handle ci::string specially
|
||||
*/
|
||||
template<> class ValueContainer<ci::string *> : public ValueContainerBase
|
||||
{
|
||||
private:
|
||||
/** Contained item */
|
||||
ci::string *val;
|
||||
public:
|
||||
/** Initialize with nothing */
|
||||
ValueContainer() : ValueContainerBase(), val(NULL) { }
|
||||
/** Initialize with an std::string */
|
||||
ValueContainer(ci::string *Val) : ValueContainerBase(), val(Val) { }
|
||||
/** Initialize with a copy */
|
||||
ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
|
||||
ValueContainer &operator=(const ValueContainer &Val)
|
||||
{
|
||||
val = Val.val;
|
||||
return *this;
|
||||
}
|
||||
/** Change value to given std::string */
|
||||
void Set(const std::string &newval)
|
||||
{
|
||||
*val = newval.c_str();
|
||||
}
|
||||
/** Change value to given ci::string */
|
||||
void Set(const ci::string &newval)
|
||||
{
|
||||
*val = newval;
|
||||
}
|
||||
/** Change value to given char pointer */
|
||||
void Set(const char *newval)
|
||||
{
|
||||
*val = newval;
|
||||
}
|
||||
};
|
||||
|
||||
/** This a specific version of ValueContainer to handle Anope::string specially
|
||||
*/
|
||||
template<> class ValueContainer<Anope::string *> : public ValueContainerBase
|
||||
@@ -268,16 +190,7 @@ template<> class ValueContainer<Anope::string *> : public ValueContainerBase
|
||||
val = Val.val;
|
||||
return *this;
|
||||
}
|
||||
/** Change value to given std::string */
|
||||
void Set(const std::string &newval)
|
||||
{
|
||||
*val = newval;
|
||||
}
|
||||
/** Change value to given ci::string */
|
||||
void Set(const ci::string &newval)
|
||||
{
|
||||
*val = newval;
|
||||
}
|
||||
|
||||
/** Change value to given Anope::string */
|
||||
void Set(const Anope::string &newval)
|
||||
{
|
||||
@@ -319,16 +232,6 @@ typedef ValueContainer<int *> ValueContainerInt;
|
||||
*/
|
||||
typedef ValueContainer<time_t *> ValueContainerTime;
|
||||
|
||||
/** A specialization of ValueContainer to hold a pointer to
|
||||
* an std::string
|
||||
*/
|
||||
typedef ValueContainer<std::string *> ValueContainerCSString;
|
||||
|
||||
/** A specialization of ValueContainer to hold a pointer to
|
||||
* an ci::string
|
||||
*/
|
||||
typedef ValueContainer<ci::string *> ValueContainerCIString;
|
||||
|
||||
/** A specialization of ValueContainer to hold a pointer to
|
||||
* an Anope::string
|
||||
*/
|
||||
@@ -348,43 +251,89 @@ typedef bool (*MultiValidator)(ServerConfig *, const Anope::string &, const Anop
|
||||
*/
|
||||
typedef bool (*MultiNotify)(ServerConfig *, const Anope::string &);
|
||||
|
||||
/** Holds a core configuration item and its callbacks
|
||||
bool ValidateNotEmpty(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateGuestPrefix(ServerConfig *conf, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data);
|
||||
bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateDefCon(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data);
|
||||
bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data);
|
||||
|
||||
/** Represents a configuration file
|
||||
*/
|
||||
struct InitialConfig
|
||||
class ConfigurationFile
|
||||
{
|
||||
/** Tag name */
|
||||
const Anope::string tag;
|
||||
/** Value name */
|
||||
const Anope::string value;
|
||||
/** Default, if not defined */
|
||||
const Anope::string default_value;
|
||||
/** Value containers */
|
||||
ValueContainerBase *val;
|
||||
/** Data types */
|
||||
int datatype;
|
||||
/** Validation function */
|
||||
Validator validation_function;
|
||||
Anope::string name;
|
||||
bool executable;
|
||||
FILE *fp;
|
||||
public:
|
||||
ConfigurationFile(const Anope::string &, bool);
|
||||
~ConfigurationFile();
|
||||
const Anope::string &GetName() const;
|
||||
|
||||
bool IsOpen() const;
|
||||
bool Open();
|
||||
void Close();
|
||||
bool End() const;
|
||||
Anope::string Read();
|
||||
};
|
||||
|
||||
/** Holds a core configuration item and its callbacks
|
||||
* where there may be more than one item
|
||||
/** Holds all of the core configuration items
|
||||
*/
|
||||
struct MultiConfig
|
||||
class CoreExport ConfigItems
|
||||
{
|
||||
/** Tag name */
|
||||
const Anope::string tag;
|
||||
/** One or more items within tag */
|
||||
const Anope::string items[17];
|
||||
/** One or more defaults for items within tags */
|
||||
const Anope::string items_default[17];
|
||||
/** One or more data types */
|
||||
int datatype[17];
|
||||
/** Initialization function */
|
||||
MultiNotify init_function;
|
||||
/** Validation function */
|
||||
MultiValidator validation_function;
|
||||
/** Completion function */
|
||||
MultiNotify finish_function;
|
||||
public:
|
||||
/** Holds a core configuration item and its callbacks
|
||||
*/
|
||||
struct Item
|
||||
{
|
||||
/** Tag name */
|
||||
Anope::string tag;
|
||||
/** Value name */
|
||||
Anope::string value;
|
||||
/** Default, if not defined */
|
||||
Anope::string default_value;
|
||||
/** Value containers */
|
||||
ValueContainerBase *val;
|
||||
/** Data types */
|
||||
int datatype;
|
||||
/** Validation function */
|
||||
Validator validation_function;
|
||||
} *Values;
|
||||
|
||||
/** Holds a core configuration item and its callbacks
|
||||
* where there may be more than one item
|
||||
*/
|
||||
struct MultiItem
|
||||
{
|
||||
/** Tag name */
|
||||
Anope::string tag;
|
||||
/** One or more items within tag */
|
||||
Anope::string items[17];
|
||||
/** One or more defaults for items within tags */
|
||||
Anope::string items_default[17];
|
||||
/** One or more data types */
|
||||
int datatype[17];
|
||||
/** Initialization function */
|
||||
MultiNotify init_function;
|
||||
/** Validation function */
|
||||
MultiValidator validation_function;
|
||||
/** Completion function */
|
||||
MultiNotify finish_function;
|
||||
} *MultiValues;
|
||||
|
||||
ConfigItems(ServerConfig *conf);
|
||||
~ConfigItems();
|
||||
};
|
||||
|
||||
/** This class holds the bulk of the runtime configuration for Anope.
|
||||
@@ -398,8 +347,6 @@ class CoreExport ServerConfig
|
||||
*/
|
||||
bool CheckOnce(const Anope::string &);
|
||||
public:
|
||||
/* Error from the config */
|
||||
std::ostringstream errstr;
|
||||
/** This holds all the information in the config file,
|
||||
* it's indexed by tag name to a vector of key/values.
|
||||
*/
|
||||
@@ -407,15 +354,16 @@ class CoreExport ServerConfig
|
||||
/** Construct a new ServerConfig
|
||||
*/
|
||||
ServerConfig();
|
||||
|
||||
/** Read the entire configuration into memory
|
||||
* and initialize this class. All other methods
|
||||
* should be used only by the core.
|
||||
*/
|
||||
void Read();
|
||||
/** Load 'filename' into 'target', with the new config parser everything is parsed into
|
||||
/** Load the configuration file into 'this'. With the new config parser everything is parsed into
|
||||
* tag/key/value at load-time rather than at read-value time.
|
||||
*/
|
||||
bool LoadConf(ConfigDataHash &, const Anope::string &);
|
||||
void LoadConf(ConfigurationFile &file);
|
||||
// Both these return true if the value existed or false otherwise
|
||||
/** Writes 'length' chars into 'result' as a string
|
||||
*/
|
||||
@@ -537,6 +485,9 @@ class CoreExport ServerConfig
|
||||
bool UsePrivmsg;
|
||||
/* Services only respond to full PRIVMSG client@services.server.name messages */
|
||||
bool UseStrictPrivMsg;
|
||||
/* This is not a configurable option.
|
||||
* Config::Config will set it depending on the value of UseStrictPrivMsg */
|
||||
Anope::string UseStrictPrivMsgString;
|
||||
/* Number of seconds between consecutive uses of the REGISTER command
|
||||
* Not to be confused with NSRegDelay */
|
||||
unsigned NickRegDelay;
|
||||
@@ -544,10 +495,12 @@ class CoreExport ServerConfig
|
||||
unsigned NewsCount;
|
||||
/* Default mlock modes */
|
||||
Anope::string MLock;
|
||||
/* Unmlockable modes */
|
||||
Anope::string NoMLock;
|
||||
/* Default botmodes on channels, defaults to ao */
|
||||
Anope::string BotModes;
|
||||
/* THe actual modes */
|
||||
std::vector<ChannelModeStatus *> BotModeList;
|
||||
ChannelStatus BotModeList;
|
||||
/* How many times to try and reconnect to the uplink before giving up */
|
||||
unsigned MaxRetries;
|
||||
/* How long to wait between connection attempts */
|
||||
@@ -593,12 +546,18 @@ class CoreExport ServerConfig
|
||||
time_t NSRegDelay;
|
||||
/* Time before the registering mail will be resent */
|
||||
time_t NSResendDelay;
|
||||
/* How long before nicks expir */
|
||||
/* How long before nicks expire */
|
||||
time_t NSExpire;
|
||||
/* Time before NickRequests expire */
|
||||
time_t NSRExpire;
|
||||
/* How long before suspended nicks expire */
|
||||
time_t NSSuspendExpire;
|
||||
/* How long before forbidden nicks expire */
|
||||
time_t NSForbidExpire;
|
||||
/* Time before unconfirmed nicks expire */
|
||||
time_t NSUnconfirmedExpire;
|
||||
/* Force email when registering */
|
||||
bool NSForceEmail;
|
||||
/* Force users to validate new email addresses */
|
||||
bool NSConfirmEmailChanges;
|
||||
/* Max number of nicks in a group */
|
||||
unsigned NSMaxAliases;
|
||||
/* Max number of allowed strings on the access list */
|
||||
@@ -623,6 +582,8 @@ class CoreExport ServerConfig
|
||||
bool NSModeOnID;
|
||||
/* Add the users hostnask their access list when they register */
|
||||
bool NSAddAccessOnReg;
|
||||
/* Maximum number of channels on AJoin */
|
||||
unsigned AJoinMax;
|
||||
|
||||
/* Default flags for newly registered channels */
|
||||
Flags<ChannelInfoFlag, CI_END> CSDefFlags;
|
||||
@@ -630,6 +591,10 @@ class CoreExport ServerConfig
|
||||
unsigned CSMaxReg;
|
||||
/* Time before a channel expires */
|
||||
time_t CSExpire;
|
||||
/* How long before suspended channels expire */
|
||||
time_t CSSuspendExpire;
|
||||
/* How long before forbidden channels expire */
|
||||
time_t CSForbidExpire;
|
||||
/* Default ban type to use for channels */
|
||||
int CSDefBantype;
|
||||
/* Max number of entries allowed on channel access lists */
|
||||
@@ -707,26 +672,6 @@ class CoreExport ServerConfig
|
||||
bool WallOper;
|
||||
/* Send a WALLOPS/GLOBOPS when a nonoper tries to use OperServ */
|
||||
bool WallBadOS;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the GLOBAL command */
|
||||
bool WallOSGlobal;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the MODE command */
|
||||
bool WallOSMode;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the CLEARMODES command */
|
||||
bool WallOSClearmodes;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the KICK command */
|
||||
bool WallOSKick;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the AKILL command */
|
||||
bool WallOSAkill;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the SNLINE command */
|
||||
bool WallOSSNLine;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the SQLINE command */
|
||||
bool WallOSSQLine;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the SZLINE command */
|
||||
bool WallOSSZLine;
|
||||
/* Send a WALLOPS/GLOBOPS when someone uses the NOOP command */
|
||||
bool WallOSNoOp;
|
||||
/* Send a WALLOPS/GLOBOPS when when someone uses the JUPE command */
|
||||
bool WallOSJupe;
|
||||
/* Send a WALLOPS/GLOBOPS when an akill expires */
|
||||
bool WallAkillExpire;
|
||||
/* Send a WALLOPS/GLOBOPS when SNLines expire */
|
||||
@@ -737,14 +682,6 @@ class CoreExport ServerConfig
|
||||
bool WallSZLineExpire;
|
||||
/* Send a WALLOPS/GLOBOPS when exceptions expire */
|
||||
bool WallExceptionExpire;
|
||||
/* Send a WALLOPS/GLOBOPS when DROP is used */
|
||||
bool WallDrop;
|
||||
/* Send a WALLOPS/GLOBOPS when FORBID is used */
|
||||
bool WallForbid;
|
||||
/* Send a WALLOPS/GLOBOPS when GETPASS is used */
|
||||
bool WallGetpass;
|
||||
/* Send a WALLOPS/GLOBOPS when SETPASS is used */
|
||||
bool WallSetpass;
|
||||
/* Add the akillers nick to the akill reason */
|
||||
bool AddAkiller;
|
||||
|
||||
@@ -823,7 +760,7 @@ class CoreExport ServerConfig
|
||||
/* List of available opertypes */
|
||||
std::list<OperType *> MyOperTypes;
|
||||
/* List of pairs of opers and their opertype from the config */
|
||||
std::list<std::pair<Anope::string, Anope::string> > Opers;
|
||||
std::vector<Oper *> Opers;
|
||||
};
|
||||
|
||||
/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
|
||||
@@ -871,7 +808,7 @@ class CoreExport ConfigReader
|
||||
long error;
|
||||
public:
|
||||
/** Default constructor.
|
||||
* This constructor initialises the ConfigReader class to read services.conf.
|
||||
* This constructor initialises the ConfigReader class to read the configuration file(s).
|
||||
*/
|
||||
ConfigReader();
|
||||
/** Overloaded constructor.
|
||||
|
||||
+11
-3
@@ -113,7 +113,7 @@ struct DNSPacket
|
||||
inline void FillBuffer(unsigned char *buffer);
|
||||
};
|
||||
|
||||
struct DNSRecord
|
||||
struct CoreExport DNSRecord
|
||||
{
|
||||
/* Name of the initial lookup */
|
||||
Anope::string name;
|
||||
@@ -130,9 +130,11 @@ struct DNSRecord
|
||||
/* Record length */
|
||||
unsigned short rdlength;
|
||||
|
||||
inline DNSRecord(const Anope::string &n);
|
||||
/* When this record was created in our cache */
|
||||
time_t created;
|
||||
|
||||
inline DNSRecord(const Anope::string &n);
|
||||
operator bool() const;
|
||||
};
|
||||
|
||||
/** The socket used to talk to the nameserver, uses UDP
|
||||
@@ -154,7 +156,7 @@ class DNSSocket : public ConnectionSocket
|
||||
|
||||
/** DNS manager, manages the connection and all requests
|
||||
*/
|
||||
class DNSManager : public Timer
|
||||
class CoreExport DNSManager : public Timer
|
||||
{
|
||||
std::multimap<Anope::string, DNSRecord *> cache;
|
||||
public:
|
||||
@@ -174,6 +176,12 @@ class DNSManager : public Timer
|
||||
void Tick(time_t now);
|
||||
|
||||
void Cleanup(Module *mod);
|
||||
|
||||
/** Does a BLOCKING DNS query and returns the first IP.
|
||||
* Only use this if you know what you are doing. Unless you specifically
|
||||
* need a blocking query use the DNSRequest system
|
||||
*/
|
||||
static DNSRecord BlockingQuery(const Anope::string &mask, QueryType qt);
|
||||
};
|
||||
|
||||
/** A DNS timeout, one is made for every DNS request to detect timeouts
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
|
||||
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ template<typename T> class ExtensibleItemRegular : public ExtensibleItemBase
|
||||
public:
|
||||
ExtensibleItemRegular(T item) : Item(item) { }
|
||||
virtual ~ExtensibleItemRegular() { }
|
||||
T GetItem() const { return Item; }
|
||||
T &GetItem() { return Item; }
|
||||
};
|
||||
|
||||
/** Class used to represent an extensible item that holds a pointer
|
||||
@@ -41,7 +41,7 @@ template<typename T> class ExtensibleItemPointer : public ExtensibleItemBase
|
||||
public:
|
||||
ExtensibleItemPointer(T *item) : Item(item) { }
|
||||
virtual ~ExtensibleItemPointer() { delete Item; }
|
||||
T *GetItem() const { return Item; }
|
||||
T *GetItem() { return Item; }
|
||||
};
|
||||
|
||||
/** Class used to represent an extensible item that holds a pointer to an arrray
|
||||
@@ -54,7 +54,7 @@ template<typename T> class ExtensibleItemPointerArray : public ExtensibleItemBas
|
||||
public:
|
||||
ExtensibleItemPointerArray(T *item) : Item(item) { }
|
||||
virtual ~ExtensibleItemPointerArray() { delete [] Item; }
|
||||
T *GetItem() const { return Item; }
|
||||
T *GetItem() { return Item; }
|
||||
};
|
||||
|
||||
class CoreExport Extensible : public Base
|
||||
@@ -108,7 +108,7 @@ class CoreExport Extensible : public Base
|
||||
*/
|
||||
void Extend(const Anope::string &key)
|
||||
{
|
||||
this->Extend(key, new ExtensibleItemRegular<char *>(NULL));
|
||||
this->Extend(key, new ExtensibleItemPointer<char *>(NULL));
|
||||
}
|
||||
|
||||
/** Shrink an Extensible class.
|
||||
|
||||
+51
-80
@@ -1,9 +1,9 @@
|
||||
/* Prototypes and external variable declarations.
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -23,12 +23,13 @@ E void ModuleRunTimeDirCleanUp();
|
||||
|
||||
E IRCDVar *ircd;
|
||||
E IRCDProto *ircdproto;
|
||||
E IRCdMessage *ircdmessage;
|
||||
|
||||
/**** actions.c ****/
|
||||
|
||||
E void kill_user(const Anope::string &source, const Anope::string &user, const Anope::string &reason);
|
||||
E void kill_user(const Anope::string &source, User *user, const Anope::string &reason);
|
||||
E bool bad_password(User *u);
|
||||
E void common_unban(ChannelInfo *ci, const Anope::string &nick);
|
||||
E void common_unban(ChannelInfo *ci, User *u, bool full = false);
|
||||
|
||||
E BotInfo *BotServ;
|
||||
E BotInfo *ChanServ;
|
||||
@@ -51,9 +52,10 @@ E BotInfo *findbot(const Anope::string &nick);
|
||||
*/
|
||||
E Anope::string normalizeBuffer(const Anope::string &);
|
||||
|
||||
E void check_ban(ChannelInfo *ci, User *u, int ttbtype);
|
||||
E void bot_kick(ChannelInfo *ci, User *u, const char *message, ...);
|
||||
E void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason);
|
||||
E void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason);
|
||||
E void bot_raw_mode(User *requester, ChannelInfo *ci, const Anope::string &mode, const Anope::string &nick);
|
||||
|
||||
/**** channels.c ****/
|
||||
|
||||
@@ -63,8 +65,6 @@ E Channel *findchan(const Anope::string &chan);
|
||||
|
||||
E User *nc_on_chan(Channel *c, const NickCore *nc);
|
||||
|
||||
E int get_access_level(ChannelInfo *ci, NickAlias *na);
|
||||
E int get_access_level(ChannelInfo *ci, NickCore *nc);
|
||||
E Anope::string get_xop_level(int level);
|
||||
|
||||
E void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts);
|
||||
@@ -75,18 +75,6 @@ E void MassChannelModes(BotInfo *bi, const Anope::string &modes);
|
||||
|
||||
E void chan_set_correct_modes(User *user, Channel *c, int give_modes);
|
||||
|
||||
E Entry *entry_create(const Anope::string &mask);
|
||||
E Entry *entry_add(EList *list, const Anope::string &mask);
|
||||
E void entry_delete(EList *list, Entry *e);
|
||||
E EList *list_create();
|
||||
E int entry_match(Entry *e, const Anope::string &nick, const Anope::string &user, const Anope::string &host, uint32 ip);
|
||||
E int entry_match_mask(Entry *e, const Anope::string &mask, uint32 ip);
|
||||
E Entry *elist_match(EList *list, const Anope::string &nick, const Anope::string &user, const Anope::string &host, uint32 ip);
|
||||
E Entry *elist_match_mask(EList *list, const Anope::string &mask, uint32 ip);
|
||||
E Entry *elist_match_user(EList *list, User *u);
|
||||
E Entry *elist_find_mask(EList *list, const Anope::string &mask);
|
||||
E long get_memuse(EList *list);
|
||||
|
||||
inline BotInfo *whosends(ChannelInfo *ci)
|
||||
{
|
||||
if (!ci || !ci->bi || !ci->c || !ci->botflags.HasFlag(BS_SYMBIOSIS) || !ci->c->FindUser(ci->bi))
|
||||
@@ -103,7 +91,7 @@ E void get_chanserv_stats(long *nrec, long *memuse);
|
||||
E void reset_levels(ChannelInfo *ci);
|
||||
E void cs_init();
|
||||
E void expire_chans();
|
||||
E void cs_remove_nick(const NickCore *nc);
|
||||
E void cs_remove_nick(NickCore *nc);
|
||||
|
||||
E void check_modes(Channel *c);
|
||||
E int check_valid_admin(User *user, Channel *chan, int servermode);
|
||||
@@ -112,19 +100,15 @@ E int check_valid_op(User *user, Channel *chan, int servermode);
|
||||
E ChannelInfo *cs_findchan(const Anope::string &chan);
|
||||
E int check_access(User *user, ChannelInfo *ci, int what);
|
||||
E bool IsFounder(User *user, ChannelInfo *ci);
|
||||
E int get_access(User *user, ChannelInfo *ci);
|
||||
E void update_cs_lastseen(User *user, ChannelInfo *ci);
|
||||
E int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret);
|
||||
E AutoKick *is_stuck(ChannelInfo *ci, const Anope::string &mask);
|
||||
E void stick_mask(ChannelInfo *ci, AutoKick *akick);
|
||||
E void stick_all(ChannelInfo *ci);
|
||||
|
||||
E int levelinfo_maxwidth;
|
||||
E Anope::string get_mlock_modes(ChannelInfo *ci, int complete);
|
||||
|
||||
/**** config.c ****/
|
||||
|
||||
E Anope::string services_conf;
|
||||
E ConfigurationFile services_conf;
|
||||
E ServerConfig *Config;
|
||||
|
||||
/* hostserv.c */
|
||||
@@ -134,7 +118,6 @@ E void HostServSyncVhosts(NickAlias *na);
|
||||
/**** encrypt.c ****/
|
||||
E int enc_encrypt(const Anope::string &src, Anope::string &dest);
|
||||
E int enc_decrypt(const Anope::string &src, Anope::string &dest);
|
||||
E int enc_check_password(Anope::string &plaintext, Anope::string &password);
|
||||
|
||||
/**** hostserv.c ****/
|
||||
E void get_hostserv_stats(long *nrec, long *memuse);
|
||||
@@ -151,17 +134,17 @@ E Uplink *uplink_server;
|
||||
/**** ircd.c ****/
|
||||
E void pmodule_ircd_proto(IRCDProto *);
|
||||
E void pmodule_ircd_var(IRCDVar *ircdvar);
|
||||
E void pmodule_ircd_message(IRCdMessage *message);
|
||||
|
||||
/**** language.cpp ****/
|
||||
E std::vector<Anope::string> languages;
|
||||
E void InitLanguages();
|
||||
E const Anope::string GetString(const Anope::string &language, LanguageString string);
|
||||
E const Anope::string GetString(LanguageString string);
|
||||
E const Anope::string GetString(const NickCore *nc, LanguageString string);
|
||||
E const Anope::string GetString(const User *u, LanguageString string);
|
||||
E const Anope::string GetString(const char *domain, Anope::string language, const Anope::string &string);
|
||||
E Anope::string language_strings[LANG_STRING_COUNT];
|
||||
E void SyntaxError(BotInfo *bi, User *u, const Anope::string &command, LanguageString message);
|
||||
E const Anope::string GetString(NickCore *nc, const char *string);
|
||||
E const Anope::string GetString(const Anope::string &domain, const Anope::string &lang, const char *string);
|
||||
E void PushLanguage(const Anope::string &, Anope::string);
|
||||
E void PopLanguage();
|
||||
E const char *anope_gettext(const char *string);
|
||||
E void SyntaxError(CommandSource &source, const Anope::string &command, const Anope::string &message);
|
||||
|
||||
/*** logger.cpp ***/
|
||||
E void InitLogChannels(ServerConfig *);
|
||||
@@ -204,43 +187,54 @@ class CoreExport UplinkSocket : public ConnectionSocket
|
||||
/**** memoserv.c ****/
|
||||
|
||||
E void ms_init();
|
||||
E void rsend_notify(User *u, Memo *m, const Anope::string &chan);
|
||||
E void rsend_notify(CommandSource &source, Memo *m, const Anope::string &chan);
|
||||
E void check_memos(User *u);
|
||||
E MemoInfo *getmemoinfo(const Anope::string &name, bool &ischan, bool &isforbid);
|
||||
E void memo_send(User *u, const Anope::string &name, const Anope::string &text, int z);
|
||||
E void memo_send(CommandSource &source, const Anope::string &name, const Anope::string &text, int z);
|
||||
|
||||
/**** messages.c ****/
|
||||
/**** messages.cpp ****/
|
||||
|
||||
E int m_nickcoll(const Anope::string &user);
|
||||
E int m_away(const Anope::string &source, const Anope::string &msg);
|
||||
E int m_kill(const Anope::string &nick, const Anope::string &msg);
|
||||
E int m_motd(const Anope::string &source);
|
||||
E int m_privmsg(const Anope::string &source, const Anope::string &receiver, const Anope::string &message);
|
||||
E bool m_stats(const Anope::string &source, const std::vector<Anope::string> &);
|
||||
E int m_whois(const Anope::string &source, const Anope::string &who);
|
||||
E bool m_time(const Anope::string &source, const std::vector<Anope::string> &);
|
||||
E bool m_version(const Anope::string &source, const std::vector<Anope::string> &);
|
||||
E void init_core_messages();
|
||||
|
||||
E bool OnStats(const Anope::string &source, const std::vector<Anope::string> &);
|
||||
E bool OnTime(const Anope::string &source, const std::vector<Anope::string> &);
|
||||
E bool OnVersion(const Anope::string &source, const std::vector<Anope::string> &);
|
||||
|
||||
E bool On436(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnAway(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnJoin(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnKick(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnKill(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnMode(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnNick(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnUID(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnPart(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnPing(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnPrivmsg(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnQuit(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnServer(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnSQuit(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnTopic(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnWhois(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnCapab(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnSJoin(const Anope::string &, const std::vector<Anope::string> &);
|
||||
E bool OnError(const Anope::string &, const std::vector<Anope::string> &);
|
||||
|
||||
/**** misc.c ****/
|
||||
|
||||
E bool IsFile(const Anope::string &filename);
|
||||
E int toupper(char);
|
||||
E int tolower(char);
|
||||
E char *strscpy(char *d, const char *s, size_t len);
|
||||
#ifndef HAVE_STRLCPY
|
||||
E size_t strlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
#ifndef HAVE_STRLCAT
|
||||
E size_t strlcat(char *, const char *, size_t);
|
||||
#endif
|
||||
E char *strnrepl(char *s, int32 size, const char *old, const char *nstr);
|
||||
E const char *merge_args(int argc, char **argv);
|
||||
E const char *merge_args(int argc, const char **argv);
|
||||
|
||||
E time_t dotime(const Anope::string &s);
|
||||
E Anope::string duration(const NickCore *nc, time_t seconds);
|
||||
E Anope::string expire_left(const NickCore *nc, time_t expires);
|
||||
E Anope::string duration(time_t seconds);
|
||||
E Anope::string expire_left(NickCore *nc, time_t expires);
|
||||
E Anope::string do_strftime(const time_t &t);
|
||||
E bool doValidHost(const Anope::string &host, int type);
|
||||
|
||||
@@ -264,25 +258,17 @@ E char *str_signed(unsigned char *str);
|
||||
E std::list<Anope::string> BuildStringList(const Anope::string &, char = ' ');
|
||||
E std::vector<Anope::string> BuildStringVector(const Anope::string &, char = ' ');
|
||||
|
||||
E uint32 cidr_to_netmask(uint16 cidr);
|
||||
E uint16 netmask_to_cidr(uint32 mask);
|
||||
|
||||
E bool str_is_wildcard(const Anope::string &str);
|
||||
E bool str_is_pure_wildcard(const Anope::string &str);
|
||||
|
||||
E bool str_is_cidr(const Anope::string &str, uint32 &ip, uint32 &mask, Anope::string &host);
|
||||
|
||||
/**** modes.cpp ****/
|
||||
/* Number of generic modes we support */
|
||||
E unsigned GenericChannelModes, GenericUserModes;
|
||||
E Flags<ChannelModeName, CMODE_END * 2> DefMLockOn;
|
||||
E Flags<ChannelModeName, CMODE_END * 2> DefMLockOff;
|
||||
E std::map<ChannelModeName, Anope::string> DefMLockParams;
|
||||
E std::multimap<ChannelModeName, ModeLock> def_mode_locks;
|
||||
E void SetDefaultMLock(ServerConfig *config);
|
||||
|
||||
/**** nickserv.c ****/
|
||||
|
||||
E NickRequest *findrequestnick(const Anope::string &nick);
|
||||
E void get_aliases_stats(long &count, long &mem);
|
||||
E void get_core_stats(long &count, long &mem);
|
||||
E void change_core_display(NickCore *nc);
|
||||
@@ -292,21 +278,12 @@ E int do_setmodes(User *u);
|
||||
E void ns_init();
|
||||
E int validate_user(User *u);
|
||||
E void expire_nicks();
|
||||
E void expire_requests();
|
||||
E NickAlias *findnick(const Anope::string &nick);
|
||||
E NickCore *findcore(const Anope::string &nick);
|
||||
E bool is_on_access(const User *u, const NickCore *nc);
|
||||
|
||||
/**** process.c ****/
|
||||
|
||||
E int allow_ignore;
|
||||
E std::list<IgnoreData *> ignore;
|
||||
|
||||
E void add_ignore(const Anope::string &nick, time_t delta);
|
||||
E IgnoreData *get_ignore(const Anope::string &nick);
|
||||
E int delete_ignore(const Anope::string &nick);
|
||||
E int clear_ignores();
|
||||
|
||||
E void process(const Anope::string &buf);
|
||||
|
||||
/**** send.c ****/
|
||||
@@ -322,8 +299,8 @@ E std::vector<Exception *> exceptions;
|
||||
E void get_session_stats(long &count, long &mem);
|
||||
E void get_exception_stats(long &count, long &mem);
|
||||
|
||||
E void add_session(const Anope::string &nick, const Anope::string &host, const Anope::string &hostip);
|
||||
E void del_session(const Anope::string &host);
|
||||
E void add_session(User *u);
|
||||
E void del_session(User *u);
|
||||
|
||||
E void expire_exceptions();
|
||||
|
||||
@@ -350,20 +327,14 @@ E void get_user_stats(long &count, long &mem);
|
||||
|
||||
E User *finduser(const Anope::string &nick);
|
||||
|
||||
E Anope::string TS6SID;
|
||||
|
||||
E User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, const Anope::string &ip, const Anope::string &vhost, const Anope::string &uid, const Anope::string &modes);
|
||||
|
||||
E void do_umode(const Anope::string &, const Anope::string &user, const Anope::string &modes);
|
||||
E void do_quit(const Anope::string &source, const Anope::string &reason);
|
||||
E void do_kill(const Anope::string &source, const Anope::string &reason);
|
||||
E void do_umode(const Anope::string &user, const Anope::string &modes);
|
||||
E void do_kill(User *user, const Anope::string &reason);
|
||||
|
||||
E bool is_oper(User *user);
|
||||
|
||||
E bool is_excepted(ChannelInfo *ci, User *user);
|
||||
E bool matches_list(Channel *c, User *user, ChannelModeName mode);
|
||||
E bool is_excepted_mask(ChannelInfo *ci, const Anope::string &mask);
|
||||
|
||||
E bool match_usermask(const Anope::string &mask, User *user);
|
||||
E Anope::string create_mask(User *u);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2010 InspIRCd Development Team
|
||||
* Copyright (C) 2009-2010 Anope Team <team@anope.org>
|
||||
* Copyright (C) 2002-2011 InspIRCd Development Team
|
||||
* Copyright (C) 2009-2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
@@ -170,7 +170,7 @@ namespace irc
|
||||
|
||||
/** Used to hash irc::strings for unordered_map
|
||||
*/
|
||||
struct hash
|
||||
struct CoreExport hash
|
||||
{
|
||||
/* VS 2008 specific code */
|
||||
enum { bucket_size = 4, min_buckets = 8 };
|
||||
@@ -241,7 +241,7 @@ namespace ci
|
||||
|
||||
/** Used to hash ci::strings for unordered_map
|
||||
*/
|
||||
struct hash
|
||||
struct CoreExport hash
|
||||
{
|
||||
/* VS 2008 specific code */
|
||||
enum { bucket_size = 4, min_buckets = 8 };
|
||||
|
||||
+115
-1551
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "anope.h"
|
||||
|
||||
extern CoreExport bool Mail(User *u, NickRequest *nr, BotInfo *service, const Anope::string &subject, const Anope::string &message);
|
||||
extern CoreExport bool Mail(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message);
|
||||
extern CoreExport bool Mail(NickCore *nc, const Anope::string &subject, const Anope::string &message);
|
||||
extern CoreExport bool MailValidate(const Anope::string &email);
|
||||
|
||||
+86
-84
@@ -1,7 +1,7 @@
|
||||
/* Mode support
|
||||
*
|
||||
* Copyright (C) 2008-2010 Adam <Adam@anope.org>
|
||||
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
|
||||
* Copyright (C) 2008-2011 Adam <Adam@anope.org>
|
||||
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*/
|
||||
@@ -16,14 +16,26 @@ enum UserModeName
|
||||
UMODE_BEGIN,
|
||||
|
||||
UMODE_SERV_ADMIN, UMODE_BOT, UMODE_CO_ADMIN, UMODE_FILTER, UMODE_HIDEOPER, UMODE_NETADMIN,
|
||||
UMODE_REGPRIV, UMODE_PROTECTED, UMODE_NO_CTCP, UMODE_WEBTV, UMODE_WHOIS, UMODE_ADMIN, UMODE_DEAF,
|
||||
UMODE_REGPRIV, UMODE_PROTECTED, UMODE_NO_CTCP, UMODE_WEBTV, UMODE_WEBIRC, UMODE_WHOIS, UMODE_ADMIN, UMODE_DEAF,
|
||||
UMODE_GLOBOPS, UMODE_HELPOP, UMODE_INVIS, UMODE_OPER, UMODE_PRIV, UMODE_GOD, UMODE_REGISTERED,
|
||||
UMODE_SNOMASK, UMODE_VHOST, UMODE_WALLOPS, UMODE_CLOAK, UMODE_SSL, UMODE_CALLERID, UMODE_COMMONCHANS,
|
||||
UMODE_HIDDEN, UMODE_STRIPCOLOR, UMODE_INVISIBLE_OPER,
|
||||
UMODE_SNOMASK, UMODE_VHOST, UMODE_WALLOPS, UMODE_CLOAK, UMODE_SSL, UMODE_SOFTCALLERID, UMODE_CALLERID,
|
||||
UMODE_COMMONCHANS, UMODE_HIDDEN, UMODE_STRIPCOLOR, UMODE_INVISIBLE_OPER, UMODE_RESTRICTED,
|
||||
|
||||
UMODE_END
|
||||
};
|
||||
|
||||
const Anope::string UserModeNameStrings[] = {
|
||||
"UMODE_BEGIN",
|
||||
|
||||
"UMODE_SERV_ADMIN", "UMODE_BOT", "UMODE_CO_ADMIN", "UMODE_FILTER", "UMODE_HIDEOPER", "UMODE_NETADMIN",
|
||||
"UMODE_REGPRIV", "UMODE_PROTECTED", "UMODE_NO_CTCP", "UMODE_WEBTV", "UMODE_WEBIRC", "UMODE_WHOIS", "UMODE_ADMIN", "UMODE_DEAF",
|
||||
"UMODE_GLOBOPS", "UMODE_HELPOP", "UMODE_INVIS", "UMODE_OPER", "UMODE_PRIV", "UMODE_GOD", "UMODE_REGISTERED",
|
||||
"UMODE_SNOMASK", "UMODE_VHOST", "UMODE_WALLOPS", "UMODE_CLOAK", "UMODE_SSL", "UMODE_SOFTCALLERID", "UMODE_CALLERID",
|
||||
"UMODE_COMMONCHANS", "UMODE_HIDDEN", "UMODE_STRIPCOLOR", "UMODE_INVISIBLE_OPER", "UMODE_RESTRICTED"
|
||||
|
||||
""
|
||||
};
|
||||
|
||||
/** All of the valid channel mode names
|
||||
*/
|
||||
enum ChannelModeName
|
||||
@@ -36,6 +48,7 @@ enum ChannelModeName
|
||||
CMODE_NOCTCP, CMODE_FILTER, CMODE_NOKNOCK, CMODE_REDIRECT, CMODE_REGMODERATED, CMODE_NONICK, CMODE_OPERONLY,
|
||||
CMODE_NOKICK, CMODE_REGISTEREDONLY, CMODE_STRIPCOLOR, CMODE_NONOTICE, CMODE_NOINVITE, CMODE_ALLINVITE,
|
||||
CMODE_BLOCKCAPS, CMODE_PERM, CMODE_NICKFLOOD, CMODE_JOINFLOOD, CMODE_DELAYEDJOIN, CMODE_NOREJOIN,
|
||||
CMODE_BANDWIDTH,
|
||||
|
||||
/* b/e/I */
|
||||
CMODE_BAN, CMODE_EXCEPT,
|
||||
@@ -48,6 +61,29 @@ enum ChannelModeName
|
||||
CMODE_END
|
||||
};
|
||||
|
||||
const Anope::string ChannelModeNameStrings[] = {
|
||||
"CMODE_BEGIN",
|
||||
|
||||
/* Channel modes */
|
||||
"CMODE_BLOCKCOLOR", "CMODE_FLOOD", "CMODE_INVITE", "CMODE_KEY", "CMODE_LIMIT", "CMODE_MODERATED", "CMODE_NOEXTERNAL",
|
||||
"CMODE_PRIVATE", "CMODE_REGISTERED", "CMODE_SECRET", "CMODE_TOPIC", "CMODE_AUDITORIUM", "CMODE_SSL", "CMODE_ADMINONLY",
|
||||
"CMODE_NOCTCP", "CMODE_FILTER", "CMODE_NOKNOCK", "CMODE_REDIRECT", "CMODE_REGMODERATED", "CMODE_NONICK", "CMODE_OPERONLY",
|
||||
"CMODE_NOKICK", "CMODE_REGISTEREDONLY", "CMODE_STRIPCOLOR", "CMODE_NONOTICE", "CMODE_NOINVITE", "CMODE_ALLINVITE",
|
||||
"CMODE_BLOCKCAPS", "CMODE_PERM", "CMODE_NICKFLOOD", "CMODE_JOINFLOOD", "CMODE_DELAYEDJOIN", "CMODE_NOREJOIN",
|
||||
"CMODE_BANDWIDTH",
|
||||
|
||||
/* b/e/I */
|
||||
"CMODE_BAN", "CMODE_EXCEPT",
|
||||
"CMODE_INVITEOVERRIDE",
|
||||
|
||||
/* v/h/o/a/q */
|
||||
"CMODE_VOICE", "CMODE_HALFOP", "CMODE_OP",
|
||||
"CMODE_PROTECT", "CMODE_OWNER",
|
||||
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
/** The different types of modes
|
||||
*/
|
||||
enum ModeType
|
||||
@@ -79,8 +115,6 @@ class CoreExport Mode : public Base
|
||||
public:
|
||||
/* Class of mode this is */
|
||||
ModeClass Class;
|
||||
/* The mode name, as a string */
|
||||
Anope::string NameAsString;
|
||||
/* Mode char for this */
|
||||
char ModeChar;
|
||||
/* Type of mode this is */
|
||||
@@ -88,11 +122,10 @@ class CoreExport Mode : public Base
|
||||
|
||||
/** Default constructor
|
||||
* @param mClass The type of mode this is
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
* @param type The mode type
|
||||
*/
|
||||
Mode(ModeClass mClass, const Anope::string &mNameAsString, char modeChar, ModeType type);
|
||||
Mode(ModeClass mClass, char modeChar, ModeType type);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
@@ -109,14 +142,17 @@ class CoreExport UserMode : public Mode
|
||||
|
||||
/** Default constructor
|
||||
* @param nName The mode name
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
*/
|
||||
UserMode(UserModeName mName, const Anope::string &mNameAsString, char modeChar);
|
||||
UserMode(UserModeName mName, char modeChar);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
virtual ~UserMode();
|
||||
|
||||
/** Returns the mode name as a string
|
||||
*/
|
||||
const Anope::string NameAsString();
|
||||
};
|
||||
|
||||
class CoreExport UserModeParam : public UserMode
|
||||
@@ -124,10 +160,9 @@ class CoreExport UserModeParam : public UserMode
|
||||
public:
|
||||
/** Default constructor
|
||||
* @param mName The mode name
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
*/
|
||||
UserModeParam(UserModeName mName, const Anope::string &mNameAsString, char modeChar);
|
||||
UserModeParam(UserModeName mName, char modeChar);
|
||||
|
||||
/** Check if the param is valid
|
||||
* @param value The param
|
||||
@@ -146,10 +181,9 @@ class CoreExport ChannelMode : public Mode
|
||||
|
||||
/** Default constructor
|
||||
* @param mName The mode name
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
*/
|
||||
ChannelMode(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar);
|
||||
ChannelMode(ChannelModeName mName, char modeChar);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
@@ -159,7 +193,11 @@ class CoreExport ChannelMode : public Mode
|
||||
* NOTE: User CAN be NULL, this is for checking if it can be locked with defcon
|
||||
* @param u The user, or NULL
|
||||
*/
|
||||
virtual bool CanSet(User *u) const { return true; }
|
||||
bool CanSet(User *u) const;
|
||||
|
||||
/** Returns the mode name as a string
|
||||
*/
|
||||
const Anope::string NameAsString();
|
||||
};
|
||||
|
||||
|
||||
@@ -170,10 +208,9 @@ class CoreExport ChannelModeList : public ChannelMode
|
||||
public:
|
||||
/** Default constructor
|
||||
* @param mName The mode name
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
*/
|
||||
ChannelModeList(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar);
|
||||
ChannelModeList(ChannelModeName mName, char modeChar);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
@@ -185,18 +222,25 @@ class CoreExport ChannelModeList : public ChannelMode
|
||||
*/
|
||||
virtual bool IsValid(const Anope::string &mask) const { return true; }
|
||||
|
||||
/** Add the mask to the channel, this should be overridden
|
||||
/** Checks if mask affects user
|
||||
* Should only be used for extbans or other weird ircd-specific things.
|
||||
* @param u The user
|
||||
* @param e The entry to match against
|
||||
* @return true on match
|
||||
*/
|
||||
virtual bool Matches(User *u, const Entry *e) { return false; }
|
||||
|
||||
/** Called when a mask is added to a channel
|
||||
* @param chan The channel
|
||||
* @param mask The mask
|
||||
*/
|
||||
virtual void AddMask(Channel *chan, const Anope::string &mask) { }
|
||||
virtual void OnAdd(Channel *chan, const Anope::string &mask) { }
|
||||
|
||||
/** Delete the mask from the channel, this should be overridden
|
||||
/** Called when a mask is removed from a channel
|
||||
* @param chan The channel
|
||||
* @param mask The mask
|
||||
*/
|
||||
virtual void DelMask(Channel *chan, const Anope::string &mask) { }
|
||||
|
||||
virtual void OnDel(Channel *chan, const Anope::string &mask) { }
|
||||
};
|
||||
|
||||
/** This is a mode with a paramater, eg +k/l. These modes should use/inherit from this
|
||||
@@ -206,11 +250,10 @@ class CoreExport ChannelModeParam : public ChannelMode
|
||||
public:
|
||||
/** Default constructor
|
||||
* @param mName The mode name
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
* @param MinusArg true if this mode sends no arg when unsetting
|
||||
*/
|
||||
ChannelModeParam(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar, bool MinusArg = false);
|
||||
ChannelModeParam(ChannelModeName mName, char modeChar, bool MinusArg = false);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
@@ -236,11 +279,10 @@ class CoreExport ChannelModeStatus : public ChannelMode
|
||||
|
||||
/** Default constructor
|
||||
* @param mName The mode name
|
||||
* @param mNameAsString The mode name as a string
|
||||
* @param modeChar The mode char
|
||||
* @param mSymbol The symbol for the mode, eg @ % +
|
||||
*/
|
||||
ChannelModeStatus(ChannelModeName mName, const Anope::string &mNameAsString, char modeChar, char mSymbol);
|
||||
ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
@@ -252,54 +294,17 @@ class CoreExport ChannelModeStatus : public ChannelMode
|
||||
class CoreExport ChannelModeBan : public ChannelModeList
|
||||
{
|
||||
public:
|
||||
ChannelModeBan(char modeChar) : ChannelModeList(CMODE_BAN, "CMODE_BAN", modeChar) { }
|
||||
ChannelModeBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { }
|
||||
|
||||
void AddMask(Channel *chan, const Anope::string &mask);
|
||||
|
||||
void DelMask(Channel *chan, const Anope::string &mask);
|
||||
void OnAdd(Channel *chan, const Anope::string &mask);
|
||||
};
|
||||
|
||||
/** Channel mode +e
|
||||
*/
|
||||
class CoreExport ChannelModeExcept : public ChannelModeList
|
||||
{
|
||||
public:
|
||||
ChannelModeExcept(char modeChar) : ChannelModeList(CMODE_EXCEPT, "CMODE_EXCEPT", modeChar) { }
|
||||
|
||||
void AddMask(Channel *chan, const Anope::string &mask);
|
||||
|
||||
void DelMask(Channel *chan, const Anope::string &mask);
|
||||
};
|
||||
|
||||
/** Channel mode +I
|
||||
*/
|
||||
class CoreExport ChannelModeInvex : public ChannelModeList
|
||||
{
|
||||
public:
|
||||
ChannelModeInvex(char modeChar) : ChannelModeList(CMODE_INVITEOVERRIDE, "CMODE_INVITEOVERRIDE", modeChar) { }
|
||||
|
||||
void AddMask(Channel *chan, const Anope::string &mask);
|
||||
|
||||
void DelMask(Channel *chan, const Anope::string &mask);
|
||||
};
|
||||
|
||||
|
||||
/** Channel mode +k (key)
|
||||
*/
|
||||
class CoreExport ChannelModeKey : public ChannelModeParam
|
||||
{
|
||||
public:
|
||||
ChannelModeKey(char modeChar) : ChannelModeParam(CMODE_KEY, "CMODE_KEY", modeChar) { }
|
||||
|
||||
bool IsValid(const Anope::string &value) const;
|
||||
};
|
||||
|
||||
/** Channel mode +f (flood)
|
||||
*/
|
||||
class ChannelModeFlood : public ChannelModeParam
|
||||
{
|
||||
public:
|
||||
ChannelModeFlood(char modeChar, bool minusNoArg = false) : ChannelModeParam(CMODE_FLOOD, "CMODE_FLOOD", modeChar, minusNoArg) { }
|
||||
ChannelModeKey(char modeChar) : ChannelModeParam(CMODE_KEY, modeChar) { }
|
||||
|
||||
bool IsValid(const Anope::string &value) const;
|
||||
};
|
||||
@@ -310,7 +315,7 @@ class ChannelModeFlood : public ChannelModeParam
|
||||
class CoreExport ChannelModeAdmin : public ChannelMode
|
||||
{
|
||||
public:
|
||||
ChannelModeAdmin(char modeChar) : ChannelMode(CMODE_ADMINONLY, "CMODE_ADMINONLY", modeChar) { }
|
||||
ChannelModeAdmin(char modeChar) : ChannelMode(CMODE_ADMINONLY, modeChar) { }
|
||||
|
||||
/* Opers only */
|
||||
bool CanSet(User *u) const;
|
||||
@@ -322,7 +327,7 @@ class CoreExport ChannelModeAdmin : public ChannelMode
|
||||
class CoreExport ChannelModeOper : public ChannelMode
|
||||
{
|
||||
public:
|
||||
ChannelModeOper(char modeChar) : ChannelMode(CMODE_OPERONLY, "CMODE_OPERONLY", modeChar) { }
|
||||
ChannelModeOper(char modeChar) : ChannelMode(CMODE_OPERONLY, modeChar) { }
|
||||
|
||||
/* Opers only */
|
||||
bool CanSet(User *u) const;
|
||||
@@ -334,7 +339,7 @@ class CoreExport ChannelModeOper : public ChannelMode
|
||||
class CoreExport ChannelModeRegistered : public ChannelMode
|
||||
{
|
||||
public:
|
||||
ChannelModeRegistered(char modeChar) : ChannelMode(CMODE_REGISTERED, "CMODE_REGISTERED", modeChar) { }
|
||||
ChannelModeRegistered(char modeChar) : ChannelMode(CMODE_REGISTERED, modeChar) { }
|
||||
|
||||
/* No one mlocks +r */
|
||||
bool CanSet(User *u) const;
|
||||
@@ -401,18 +406,9 @@ class CoreExport ModeManager
|
||||
static void StackerAddInternal(BotInfo *bi, Base *Object, Mode *mode, bool Set, const Anope::string &Param, StackerType Type);
|
||||
|
||||
public:
|
||||
/* List of all modes Anope knows about */
|
||||
static std::map<Anope::string, Mode *> Modes;
|
||||
|
||||
/* User modes */
|
||||
static std::map<char, UserMode *> UserModesByChar;
|
||||
static std::map<UserModeName, UserMode *> UserModesByName;
|
||||
/* Channel modes */
|
||||
static std::map<char, ChannelMode *> ChannelModesByChar;
|
||||
static std::map<ChannelModeName, ChannelMode *> ChannelModesByName;
|
||||
/* Although there are two different maps for UserModes and ChannelModes
|
||||
* the pointers in each are the same. This is used to increase efficiency.
|
||||
*/
|
||||
/* List of all modes Anope knows about */
|
||||
static std::vector<ChannelMode *> ChannelModes;
|
||||
static std::vector<UserMode *> UserModes;
|
||||
|
||||
/** Add a user mode to Anope
|
||||
* @param um A UserMode or UserMode derived class
|
||||
@@ -450,11 +446,17 @@ class CoreExport ModeManager
|
||||
*/
|
||||
static UserMode *FindUserModeByName(UserModeName Name);
|
||||
|
||||
/** Find a mode by name
|
||||
/** Find channel mode by string
|
||||
* @param name The mode name
|
||||
* @return The mode
|
||||
*/
|
||||
static Mode *FindModeByName(const Anope::string &name);
|
||||
static ChannelMode *FindChannelModeByString(const Anope::string &name);
|
||||
|
||||
/** Find user mode by string
|
||||
* @param name The mode name
|
||||
* @return The mode
|
||||
*/
|
||||
static UserMode *FindUserModeByString(const Anope::string &name);
|
||||
|
||||
/** Gets the channel mode char for a symbol (eg + returns v)
|
||||
* @param Value The symbol
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
#include "services.h"
|
||||
#include "commands.h"
|
||||
#include "modules.h"
|
||||
#define _(x) x
|
||||
|
||||
#endif // MODULE_H
|
||||
|
||||
+126
-79
@@ -1,9 +1,9 @@
|
||||
/* Modular support
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -165,9 +165,9 @@ extern CoreExport std::list<Module *> Modules;
|
||||
class Version
|
||||
{
|
||||
private:
|
||||
unsigned Major;
|
||||
unsigned Minor;
|
||||
unsigned Build;
|
||||
int Major;
|
||||
int Minor;
|
||||
int Build;
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
@@ -175,7 +175,7 @@ class Version
|
||||
* @param vMinor The minor version numbber
|
||||
* @param vBuild The build version numbber
|
||||
*/
|
||||
Version(unsigned vMajor, unsigned vMinor, unsigned vBuild);
|
||||
Version(int vMajor, int vMinor, int vBuild);
|
||||
|
||||
/** Destructor
|
||||
*/
|
||||
@@ -184,17 +184,17 @@ class Version
|
||||
/** Get the major version of Anope this was built against
|
||||
* @return The major version
|
||||
*/
|
||||
unsigned GetMajor() const;
|
||||
int GetMajor() const;
|
||||
|
||||
/** Get the minor version of Anope this was built against
|
||||
* @return The minor version
|
||||
*/
|
||||
unsigned GetMinor() const;
|
||||
int GetMinor() const;
|
||||
|
||||
/** Get the build version this was built against
|
||||
* @return The build version
|
||||
*/
|
||||
unsigned GetBuild() const;
|
||||
int GetBuild() const;
|
||||
};
|
||||
|
||||
/* Forward declaration of CallBack class for the Module class */
|
||||
@@ -284,11 +284,10 @@ class CoreExport Module : public Extensible
|
||||
Version GetVersion() const;
|
||||
|
||||
/** Send a message to a user in their language, if a translation is available
|
||||
* @param from Client to send the message from
|
||||
* @param to User to send the message to
|
||||
* @param source The source of the message
|
||||
* @param fmt The message
|
||||
*/
|
||||
void SendMessage(BotInfo *from, User *to, const char *fmt, ...);
|
||||
void SendMessage(CommandSource &source, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* Add a module provided command to the given service.
|
||||
@@ -365,27 +364,25 @@ class CoreExport Module : public Extensible
|
||||
* @param bi The bot the command is being run from
|
||||
* @param command The command
|
||||
* @param message The parameters used for the command
|
||||
* @param c The command class (if it exists)
|
||||
* @param ci If a tanasy command, the channel the comman was used on
|
||||
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
|
||||
*/
|
||||
virtual EventReturn OnPreCommandRun(User *u, BotInfo *bi, const Anope::string &command, const Anope::string &message, Command *c) { return EVENT_CONTINUE; }
|
||||
virtual EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called before a command is due to be executed.
|
||||
* @param u The user executing the command
|
||||
* @param service The service the command is associated with
|
||||
* @param source The source of the command
|
||||
* @param command The command the user is executing
|
||||
* @param params The parameters the user is sending
|
||||
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
|
||||
*/
|
||||
virtual EventReturn OnPreCommand(User *u, BotInfo *service, const Anope::string &command, const std::vector<Anope::string> ¶ms) { return EVENT_CONTINUE; }
|
||||
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> ¶ms) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called after a command has been executed.
|
||||
* @param u The user executing the command
|
||||
* @param service The service the command is associated with
|
||||
* @param source The source of the command
|
||||
* @param command The command the user executed
|
||||
* @param params The parameters the user sent
|
||||
*/
|
||||
virtual void OnPostCommand(User *u, BotInfo *service, const Anope::string &command, const std::vector<Anope::string> ¶ms) { }
|
||||
virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> ¶ms) { }
|
||||
|
||||
/** Called after the core has finished loading the databases, but before
|
||||
* we connect to the server
|
||||
@@ -407,7 +404,6 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual EventReturn OnEncrypt(const Anope::string &src, Anope::string &dest) { return EVENT_CONTINUE; }
|
||||
virtual EventReturn OnDecrypt(const Anope::string &hashm, const Anope::string &src, Anope::string &dest) { return EVENT_CONTINUE; }
|
||||
virtual EventReturn OnCheckPassword(const Anope::string &hashm, Anope::string &plaintext, Anope::string &password) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called on fantasy command
|
||||
* @param command The command
|
||||
@@ -426,10 +422,10 @@ class CoreExport Module : public Extensible
|
||||
virtual void OnBotNoFantasyAccess(const Anope::string &command, User *u, ChannelInfo *ci, const Anope::string ¶ms) { }
|
||||
|
||||
/** Called after a bot joins a channel
|
||||
* @param ci The channael
|
||||
* @param c The channel
|
||||
* @param bi The bot
|
||||
*/
|
||||
virtual void OnBotJoin(ChannelInfo *ci, BotInfo *bi) { }
|
||||
virtual void OnBotJoin(Channel *c, BotInfo *bi) { }
|
||||
|
||||
/** Called when a bot places a ban
|
||||
* @param u User being banned
|
||||
@@ -450,6 +446,11 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual void OnBadWordDel(ChannelInfo *ci, BadWord *bw) { }
|
||||
|
||||
/** Called in findbot()
|
||||
* @param nick The nick being looked up
|
||||
*/
|
||||
virtual void OnFindBot(const Anope::string &nick) { }
|
||||
|
||||
/** Called before a bot kicks a user
|
||||
* @param bi The bot sending the kick
|
||||
* @param c The channel the user is being kicked on
|
||||
@@ -498,10 +499,10 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual EventReturn OnPreChanExpire(ChannelInfo *ci) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when a channel expires
|
||||
* @param chname The channel name
|
||||
/** Called before a channel expires
|
||||
* @param ci The channel
|
||||
*/
|
||||
virtual void OnChanExpire(const Anope::string &chname) { }
|
||||
virtual void OnChanExpire(ChannelInfo *ci) { }
|
||||
|
||||
/** Called before Anope connects to its uplink
|
||||
* @param u The uplink we're going to connect to
|
||||
@@ -559,14 +560,6 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual EventReturn OnDatabaseReadMetadata(NickAlias *na, const Anope::string &key, const std::vector<Anope::string> ¶ms) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when nickrequest metadata is read from the database
|
||||
* @param nr The nickrequest
|
||||
* @parm key The metadata key
|
||||
* @param params The params from the database
|
||||
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to stop processing
|
||||
*/
|
||||
virtual EventReturn OnDatabaseReadMetadata(NickRequest *nr, const Anope::string &key, const std::vector<Anope::string> ¶ms) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when botinfo metadata is read from the database
|
||||
* @param bi The botinfo
|
||||
* @param key The metadata key
|
||||
@@ -595,12 +588,6 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickAlias *na) { }
|
||||
|
||||
/** Called when we are wrting metadata for a nickrequest
|
||||
* @param WriteMetata A callback function used to insert the metadata
|
||||
* @param nr The nick request
|
||||
*/
|
||||
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickRequest *nr) { }
|
||||
|
||||
/** Called when we are writing metadata for a botinfo
|
||||
* @param WriteMetata A callback function used to insert the metadata
|
||||
* @param bi The botinfo
|
||||
@@ -726,25 +713,23 @@ class CoreExport Module : public Extensible
|
||||
/** Called when access is deleted from a channel
|
||||
* @param ci The channel
|
||||
* @param u The user who removed the access
|
||||
* @param nc The user who was deleted
|
||||
* @param access The access entry being removed
|
||||
*/
|
||||
virtual void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc) { }
|
||||
virtual void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) { }
|
||||
|
||||
/** Called when access is changed
|
||||
* @param ci The channel
|
||||
* @param u The user who changed the access
|
||||
* @param nc The nick whos access was changed
|
||||
* @param level The level of the new access
|
||||
* @param u access The access changed
|
||||
*/
|
||||
virtual void OnAccessChange(ChannelInfo *ci, User *u, NickCore *nc, int level) { }
|
||||
virtual void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access) { }
|
||||
|
||||
/** Called when access is added
|
||||
* @param ci The channel
|
||||
* @param u The user who added the access
|
||||
* @para nc The nick who was added to access
|
||||
* @param level The level they were added at
|
||||
* @param access The access changed
|
||||
*/
|
||||
virtual void OnAccessAdd(ChannelInfo *ci, User *u, NickCore *nc, int level) { }
|
||||
virtual void OnAccessAdd(ChannelInfo *ci, User *u, ChanAccess *access) { }
|
||||
|
||||
/** Called when the access list is cleared
|
||||
* @param ci The channel
|
||||
@@ -815,16 +800,22 @@ class CoreExport Module : public Extensible
|
||||
virtual void OnAkickDel(User *u, ChannelInfo *ci, AutoKick *ak) { }
|
||||
|
||||
/** Called when a user requests info for a channel
|
||||
* @param u The user requesting info
|
||||
* @param source The user requesting info
|
||||
* @param ci The channel the user is requesting info for
|
||||
* @param ShowHidden true if we should show the user everything
|
||||
*/
|
||||
virtual void OnChanInfo(User *u, ChannelInfo *ci, bool ShowHidden) { }
|
||||
virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, bool ShowHidden) { }
|
||||
|
||||
/** Called on cs_findchan()
|
||||
* @param chname The name being looked up
|
||||
*/
|
||||
virtual void OnFindChan(const Anope::string &chname) { }
|
||||
|
||||
/** Called when a nick is dropped
|
||||
* @param nick The nick
|
||||
* @param u The user dropping the nick
|
||||
* @param na The nick
|
||||
*/
|
||||
virtual void OnNickDrop(const Anope::string &nick) { }
|
||||
virtual void OnNickDrop(User *u, NickAlias *na) { }
|
||||
|
||||
/** Called when a nick is forbidden
|
||||
* @param na The nick alias of the forbidden nick
|
||||
@@ -878,16 +869,6 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) { }
|
||||
|
||||
/** called from ns_register.c, after the NickRequest have been created
|
||||
* @param nr pointer to the NickRequest
|
||||
*/
|
||||
virtual void OnMakeNickRequest(NickRequest *nr) { }
|
||||
|
||||
/** called on delnickrequest()
|
||||
* @param nr pointer to the NickRequest
|
||||
*/
|
||||
virtual void OnDelNickRequest(NickRequest *nr) { }
|
||||
|
||||
/** called from NickCore::ClearAccess()
|
||||
* @param nc pointer to the NickCore
|
||||
*/
|
||||
@@ -905,12 +886,57 @@ class CoreExport Module : public Extensible
|
||||
*/
|
||||
virtual void OnNickEraseAccess(NickCore *nc, const Anope::string &entry) { }
|
||||
|
||||
/** called from NickCore::ClearCert()
|
||||
* @param nc pointer to the NickCore
|
||||
*/
|
||||
virtual void OnNickClearCert(NickCore *nc) { }
|
||||
|
||||
/** Called when a user adds an entry to their cert list
|
||||
* @param nc The nick
|
||||
* @param entry The entry
|
||||
*/
|
||||
virtual void OnNickAddCert(NickCore *nc, const Anope::string &entry) { }
|
||||
|
||||
/** Called from NickCore::EraseCert()
|
||||
* @param nc pointer to the NickCore
|
||||
* @param entry The fingerprint
|
||||
*/
|
||||
virtual void OnNickEraseCert(NickCore *nc, const Anope::string &entry) { }
|
||||
|
||||
/** Called when a user requests info for a nick
|
||||
* @param u The user requesting info
|
||||
* @param source The user requesting info
|
||||
* @param na The nick the user is requesting info from
|
||||
* @param ShowHidden true if we should show the user everything
|
||||
*/
|
||||
virtual void OnNickInfo(User *u, NickAlias *na, bool ShowHidden) { }
|
||||
virtual void OnNickInfo(CommandSource &source, NickAlias *na, bool ShowHidden) { }
|
||||
|
||||
/** Called in findnick()
|
||||
* Useful to modify the na returned by findnick()
|
||||
* @param nick The nick being looked up
|
||||
*/
|
||||
virtual void OnFindNick(const Anope::string &nick) { }
|
||||
|
||||
/** Called in findcore()
|
||||
* Useful to modify the nc returned by findcore()
|
||||
* @param nick The nick being looked up
|
||||
*/
|
||||
virtual void OnFindCore(const Anope::string &nick) { }
|
||||
|
||||
/** Check whether a users password is correct.
|
||||
* @param u The user
|
||||
* @param command The command the user is doing
|
||||
* @param params Command params
|
||||
* @param account The account the password should be checked against
|
||||
* @param password The password
|
||||
* @return EVENT_ALLOW to allow the password, EVENT_STOP to stop processing completely
|
||||
*/
|
||||
virtual EventReturn OnCheckAuthentication(User *u, Command *c, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when we get informed about a users SSL fingerprint
|
||||
* when we call this, the fingerprint should already be stored in the user struct
|
||||
* @param u pointer to the user
|
||||
*/
|
||||
virtual void OnFingerprint(User *u) { }
|
||||
|
||||
/** Called when a vhost is deleted
|
||||
* @param na The nickalias of the vhost
|
||||
@@ -991,20 +1017,18 @@ class CoreExport Module : public Extensible
|
||||
virtual void OnUserModeAdd(UserMode *um) { }
|
||||
|
||||
/** Called when a mode is about to be mlocked
|
||||
* @param ci The channel
|
||||
* @param Name The mode being mlocked
|
||||
* @param status true if its being mlocked +, false for -
|
||||
* @param param The param, if there is one and if status is true
|
||||
* @param ci The channel the mode is being locked on
|
||||
* @param lock The mode lock
|
||||
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
|
||||
*/
|
||||
virtual EventReturn OnMLock(ChannelInfo *ci, ChannelModeName Name, bool status, const Anope::string ¶m) { return EVENT_CONTINUE; }
|
||||
virtual EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when a mode is about to be unlocked
|
||||
* @param ci The channel
|
||||
* @param Name The mode being mlocked
|
||||
* @param ci The channel the mode is being unlocked from
|
||||
* @param mode The mode being unlocked
|
||||
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
|
||||
*/
|
||||
virtual EventReturn OnUnMLock(ChannelInfo *ci, ChannelModeName Name) { return EVENT_CONTINUE; }
|
||||
virtual EventReturn OnUnMLock(ChannelInfo *ci, ChannelMode *mode, const Anope::string ¶m) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called after a module is loaded
|
||||
* @param u The user loading the module, can be NULL
|
||||
@@ -1027,6 +1051,28 @@ class CoreExport Module : public Extensible
|
||||
* @param s Our uplink
|
||||
*/
|
||||
virtual void OnUplinkSync(Server *s) { }
|
||||
|
||||
/** Called when we receive a PRIVMSG for one of our clients
|
||||
* @param u The user sending the PRIVMSG
|
||||
* @param bi The target of the PRIVMSG
|
||||
* @param message The message
|
||||
* @return EVENT_STOP to halt processing
|
||||
*/
|
||||
virtual EventReturn OnBotPrivmsg(User *u, BotInfo *bi, const Anope::string &message) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when we receive a PRIVMSG for a registered channel we are in
|
||||
* @param u The source of the message
|
||||
* @param ci The channel
|
||||
* @param msg The message
|
||||
* @param Allow set to false to make the flood kickers halt
|
||||
* @return MOD_STOP to stop processing completely
|
||||
*/
|
||||
virtual EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow) { return EVENT_CONTINUE; }
|
||||
|
||||
/** Called when any object is destroyed
|
||||
* @param b The object
|
||||
*/
|
||||
virtual void OnObjectDestroy(Base *b) { }
|
||||
};
|
||||
|
||||
/** Implementation-specific flags which may be set in ModuleManager::Attach()
|
||||
@@ -1038,18 +1084,19 @@ enum Implementation
|
||||
I_OnPreNickExpire, I_OnNickExpire, I_OnNickForbidden, I_OnNickGroup, I_OnNickLogout, I_OnNickIdentify, I_OnNickDrop,
|
||||
I_OnNickRegister, I_OnNickSuspended, I_OnNickUnsuspended,
|
||||
I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay,
|
||||
I_OnDelNickRequest, I_OnMakeNickRequest, I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess,
|
||||
I_OnNickInfo,
|
||||
I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess,
|
||||
I_OnNickClearCert, I_OnNickAddCert, I_OnNickEraseCert,
|
||||
I_OnNickInfo, I_OnFindNick, I_OnFindCore, I_OnCheckAuthentication,
|
||||
|
||||
/* ChanServ */
|
||||
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange,
|
||||
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan, I_OnChannelCreate,
|
||||
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel,
|
||||
I_OnChanInfo,
|
||||
I_OnChanInfo, I_OnFindChan,
|
||||
|
||||
/* BotServ */
|
||||
I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign,
|
||||
I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel,
|
||||
I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel, I_OnFindBot,
|
||||
|
||||
/* HostServ */
|
||||
I_OnSetVhost, I_OnDeleteVhost,
|
||||
@@ -1059,7 +1106,7 @@ enum Implementation
|
||||
|
||||
/* Users */
|
||||
I_OnPreUserConnect, I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnUserLogoff, I_OnPreJoinChannel,
|
||||
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel,
|
||||
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnFingerprint,
|
||||
|
||||
/* OperServ */
|
||||
I_OnDefconLevel, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
|
||||
@@ -1077,9 +1124,9 @@ enum Implementation
|
||||
I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun,
|
||||
I_OnPreCommand, I_OnPostCommand, I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
|
||||
I_OnServerQuit, I_OnTopicUpdated,
|
||||
I_OnEncrypt, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword,
|
||||
I_OnEncrypt, I_OnDecrypt,
|
||||
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
|
||||
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync,
|
||||
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnObjectDestroy,
|
||||
I_END
|
||||
};
|
||||
|
||||
|
||||
+19
-1
@@ -1,6 +1,6 @@
|
||||
/* OperServ support
|
||||
*
|
||||
* (C) 2008-2010 Anope Team
|
||||
* (C) 2008-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -138,11 +138,13 @@ class CoreExport XLineManager
|
||||
*/
|
||||
virtual XLine *Add(BotInfo *bi, User *u, const Anope::string &mask, time_t expires, const Anope::string &reason);
|
||||
|
||||
private:
|
||||
/** Delete an XLine, eg, remove it from the IRCd.
|
||||
* @param x The xline
|
||||
*/
|
||||
virtual void Del(XLine *x);
|
||||
|
||||
public:
|
||||
/** Checks if a mask can/should be added to the XLineManager
|
||||
* @param mask The mask
|
||||
* @param expires When the mask would expire
|
||||
@@ -176,6 +178,12 @@ class CoreExport XLineManager
|
||||
* @param x The xline
|
||||
*/
|
||||
virtual void OnExpire(XLine *x);
|
||||
|
||||
/** Called to send an XLine to the IRCd
|
||||
* @param u The user, if we know it
|
||||
* @param x The xline
|
||||
*/
|
||||
virtual void Send(User *u, XLine *x) = 0;
|
||||
};
|
||||
|
||||
/* This is for AKILLS */
|
||||
@@ -189,6 +197,8 @@ class SGLineManager : public XLineManager
|
||||
void OnMatch(User *u, XLine *x);
|
||||
|
||||
void OnExpire(XLine *x);
|
||||
|
||||
void Send(User *u, XLine *x);
|
||||
};
|
||||
|
||||
class SNLineManager : public XLineManager
|
||||
@@ -201,6 +211,10 @@ class SNLineManager : public XLineManager
|
||||
void OnMatch(User *u, XLine *x);
|
||||
|
||||
void OnExpire(XLine *x);
|
||||
|
||||
void Send(User *u, XLine *x);
|
||||
|
||||
XLine *Check(User *u);
|
||||
};
|
||||
|
||||
class SQLineManager : public XLineManager
|
||||
@@ -214,6 +228,8 @@ class SQLineManager : public XLineManager
|
||||
|
||||
void OnExpire(XLine *x);
|
||||
|
||||
void Send(User *u, XLine *x);
|
||||
|
||||
static bool Check(Channel *c);
|
||||
};
|
||||
|
||||
@@ -227,6 +243,8 @@ class SZLineManager : public XLineManager
|
||||
void OnMatch(User *u, XLine *x);
|
||||
|
||||
void OnExpire(XLine *x);
|
||||
|
||||
void Send(User *u, XLine *x);
|
||||
};
|
||||
|
||||
#endif // OPERSERV_H
|
||||
|
||||
+37
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Robin Burchell <w00t@inspircd.org>
|
||||
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
|
||||
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
|
||||
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*/
|
||||
@@ -10,6 +10,25 @@
|
||||
|
||||
#include "hashcomp.h"
|
||||
|
||||
class OperType;
|
||||
|
||||
struct Oper
|
||||
{
|
||||
Anope::string name;
|
||||
Anope::string password;
|
||||
Anope::string certfp;
|
||||
OperType *ot;
|
||||
|
||||
Oper(const Anope::string &n, const Anope::string &p, const Anope::string &c, OperType *o) :
|
||||
name(n), password(p), certfp(c), ot(o) { }
|
||||
|
||||
/** Find an oper block by name
|
||||
* @param name The name
|
||||
* @return the oper block
|
||||
*/
|
||||
static Oper *Find(const Anope::string &name);
|
||||
};
|
||||
|
||||
class CoreExport OperType
|
||||
{
|
||||
private:
|
||||
@@ -36,6 +55,12 @@ class CoreExport OperType
|
||||
*/
|
||||
std::set<OperType *> inheritances;
|
||||
public:
|
||||
/** Find an oper type by name
|
||||
* @param name The name
|
||||
* @return The oper type
|
||||
*/
|
||||
static OperType *Find(const Anope::string &name);
|
||||
|
||||
/** Create a new opertype of the given name.
|
||||
* @param nname The opertype name, e.g. "sra".
|
||||
*/
|
||||
@@ -71,6 +96,16 @@ class CoreExport OperType
|
||||
* @param ot The opertype to inherit from
|
||||
*/
|
||||
void Inherits(OperType *ot);
|
||||
|
||||
/** Gets the icommands for this opertype
|
||||
* @return A list of commands
|
||||
*/
|
||||
const std::list<Anope::string> &GetCommands() const;
|
||||
|
||||
/** Gets the privileges for this opertype
|
||||
* @return A list of privileges
|
||||
*/
|
||||
const std::list<Anope::string> &GetPrivs() const;
|
||||
};
|
||||
|
||||
#endif // OPERTYPE_H
|
||||
|
||||
+122
-33
@@ -1,6 +1,6 @@
|
||||
/* Modular support
|
||||
*
|
||||
* (C) 2008-2010 Anope Team
|
||||
* (C) 2008-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -62,15 +62,70 @@ enum ChannelInfoFlag
|
||||
CI_END
|
||||
};
|
||||
|
||||
const Anope::string ChannelInfoFlagStrings[] = {
|
||||
"BEGIN", "INHABIT", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED",
|
||||
"PEACE", "SECURE", "FORBIDDEN", "NO_EXPIRE", "MEMO_HARDMAX", "OPNOTICE", "SECUREFOUNDER",
|
||||
"SIGNKICK", "SIGNKICK_LEVEL", "XOP", "SUSPENDED", "PERSIST", ""
|
||||
};
|
||||
|
||||
class CoreExport ChanAccess
|
||||
{
|
||||
Anope::string mask; /* Mask of the access entry */
|
||||
public:
|
||||
int16 level;
|
||||
NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */
|
||||
time_t last_seen;
|
||||
Anope::string creator;
|
||||
|
||||
ChanAccess(const Anope::string &umask);
|
||||
const Anope::string &GetMask();
|
||||
};
|
||||
|
||||
/** Flags for auto kick
|
||||
*/
|
||||
enum AutoKickFlag
|
||||
{
|
||||
/* Is by nick core, not mask */
|
||||
AK_ISNICK
|
||||
};
|
||||
|
||||
const Anope::string AutoKickFlagString[] = { "AK_ISNICK", "" };
|
||||
|
||||
/* AutoKick data. */
|
||||
class AutoKick : public Flags<AutoKickFlag>
|
||||
{
|
||||
public:
|
||||
AutoKick() : Flags<AutoKickFlag>(AutoKickFlagString) { }
|
||||
/* Only one of these can be in use */
|
||||
Anope::string mask;
|
||||
NickCore *nc;
|
||||
|
||||
Anope::string reason;
|
||||
Anope::string creator;
|
||||
time_t addtime;
|
||||
time_t last_used;
|
||||
};
|
||||
|
||||
struct ModeLock
|
||||
{
|
||||
bool set;
|
||||
ChannelModeName name;
|
||||
Anope::string param;
|
||||
Anope::string setter;
|
||||
time_t created;
|
||||
|
||||
ModeLock(bool s, ChannelModeName n, const Anope::string &p, const Anope::string &se = "", time_t c = Anope::CurTime) : set(s), name(n), param(p), setter(se), created(c) { }
|
||||
};
|
||||
|
||||
class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, CI_END>
|
||||
{
|
||||
private:
|
||||
std::map<ChannelModeName, Anope::string> Params; /* Map of parameters by mode name for mlock */
|
||||
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
|
||||
private:
|
||||
std::vector<ChanAccess *> access; /* List of authorized users */
|
||||
std::vector<AutoKick *> akick; /* List of users to kickban */
|
||||
std::vector<BadWord *> badwords; /* List of badwords */
|
||||
Flags<ChannelModeName, CMODE_END * 2> mlock_on; /* Modes mlocked on */
|
||||
Flags<ChannelModeName, CMODE_END * 2> mlock_off; /* Modes mlocked off */
|
||||
ModeList mode_locks;
|
||||
|
||||
public:
|
||||
/** Default constructor
|
||||
@@ -78,6 +133,11 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
*/
|
||||
ChannelInfo(const Anope::string &chname);
|
||||
|
||||
/** Copy constructor
|
||||
* @param ci The ChannelInfo to copy settings to
|
||||
*/
|
||||
ChannelInfo(ChannelInfo *ci);
|
||||
|
||||
/** Default destructor
|
||||
*/
|
||||
~ChannelInfo();
|
||||
@@ -94,14 +154,13 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
Anope::string last_topic_setter; /* Setter */
|
||||
time_t last_topic_time; /* Time */
|
||||
|
||||
// These two should be using extensible
|
||||
Anope::string forbidby;
|
||||
Anope::string forbidreason;
|
||||
|
||||
int16 bantype;
|
||||
int16 *levels; /* Access levels for commands */
|
||||
|
||||
Anope::string entry_message; /* Notice sent on entering channel */
|
||||
|
||||
MemoInfo memos;
|
||||
|
||||
Channel *c; /* Pointer to channel record (if channel is currently in use) */
|
||||
@@ -118,14 +177,15 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
|
||||
/** Add an entry to the channel access list
|
||||
*
|
||||
* @param nc The NickCore of the user that the access entry should be tied to
|
||||
* @param mask The mask of the access entry
|
||||
* @param level The channel access level the user has on the channel
|
||||
* @param creator The user who added the access
|
||||
* @param last_seen When the user was last seen within the channel
|
||||
* @return The new access class
|
||||
*
|
||||
* Creates a new access list entry and inserts it into the access list.
|
||||
*/
|
||||
void AddAccess(NickCore *nc, int16 level, const Anope::string &creator, int32 last_seen = 0);
|
||||
ChanAccess *AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen = 0);
|
||||
|
||||
/** Get an entry from the channel access list by index
|
||||
*
|
||||
@@ -136,15 +196,36 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
*/
|
||||
ChanAccess *GetAccess(unsigned index);
|
||||
|
||||
/** Get an entry from the channel access list by User
|
||||
*
|
||||
* @param u The User to find within the access list vector
|
||||
* @param level Optional channel access level to compare the access entries to
|
||||
* @return A ChanAccess struct corresponding to the User, or NULL if not found
|
||||
*
|
||||
* Retrieves an entry from the access list that matches the given User, optionally also matching a certain level.
|
||||
*/
|
||||
ChanAccess *GetAccess(User *u, int16 level = 0);
|
||||
|
||||
/** Get an entry from the channel access list by NickCore
|
||||
*
|
||||
* @param nc The NickCore to find within the access list vector
|
||||
* @param u The NickCore to find within the access list vector
|
||||
* @param level Optional channel access level to compare the access entries to
|
||||
* @return A ChanAccess struct corresponding to the NickCore, or NULL if not found
|
||||
*
|
||||
* Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level.
|
||||
*/
|
||||
ChanAccess *GetAccess(const NickCore *nc, int16 level = 0);
|
||||
ChanAccess *GetAccess(NickCore *nc, int16 level = 0);
|
||||
|
||||
/** Get an entry from the channel access list by mask
|
||||
*
|
||||
* @param u The mask to find within the access list vector
|
||||
* @param level Optional channel access level to compare the access entries to
|
||||
* @param wildcard True to match using wildcards
|
||||
* @return A ChanAccess struct corresponding to the mask, or NULL if not found
|
||||
*
|
||||
* Retrieves an entry from the access list that matches the given mask, optionally also matching a certain level.
|
||||
*/
|
||||
ChanAccess *GetAccess(const Anope::string &mask, int16 level = 0, bool wildcard = true);
|
||||
|
||||
/** Get the size of the accss vector for this channel
|
||||
* @return The access vector size
|
||||
@@ -159,6 +240,14 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
*/
|
||||
void EraseAccess(unsigned index);
|
||||
|
||||
/** Erase an entry from the channel access list
|
||||
*
|
||||
* @param taccess The access to remove
|
||||
*
|
||||
* Clears the memory used by the given access entry and removes it from the vector.
|
||||
*/
|
||||
void EraseAccess(ChanAccess *taccess);
|
||||
|
||||
/** Clear the entire channel access list
|
||||
*
|
||||
* Clears the entire access list by deleting every item and then clearing the vector.
|
||||
@@ -236,51 +325,51 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
|
||||
void LoadMLock();
|
||||
|
||||
/** Check if a mode is mlocked
|
||||
* @param Name The mode
|
||||
* @param mode The mode
|
||||
* @param An optional param
|
||||
* @param status True to check mlock on, false for mlock off
|
||||
* @return true on success, false on fail
|
||||
*/
|
||||
bool HasMLock(ChannelModeName Name, bool status) const;
|
||||
bool HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const;
|
||||
|
||||
/** Set a mlock
|
||||
* @param Name The mode
|
||||
* @param mode The mode
|
||||
* @param status True for mlock on, false for mlock off
|
||||
* @param param An optional param arg for + mlocked modes
|
||||
* @param setter Who is setting the mlock
|
||||
* @param created When the mlock was created
|
||||
* @return true on success, false on failure (module blocking)
|
||||
*/
|
||||
bool SetMLock(ChannelModeName Name, bool status, const Anope::string ¶m = "");
|
||||
bool SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m = "", Anope::string setter = "", time_t created = Anope::CurTime);
|
||||
|
||||
/** Remove a mlock
|
||||
* @param Name The mode
|
||||
* @return true on success, false on failure (module blcoking)
|
||||
* @param mode The mode
|
||||
* @param param The param of the mode, required if it is a list or status mode
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool RemoveMLock(ChannelModeName Name);
|
||||
bool RemoveMLock(ChannelMode *mode, const Anope::string ¶m = "");
|
||||
|
||||
/** Clear all mlocks on the channel
|
||||
*/
|
||||
void ClearMLock();
|
||||
|
||||
/** Get the number of mlocked modes for this channel
|
||||
* @param status true for mlock on, false for mlock off
|
||||
* @return The number of mlocked modes
|
||||
/** Get all of the mlocks for this channel
|
||||
* @return The mlocks
|
||||
*/
|
||||
size_t GetMLockCount(bool status) const;
|
||||
const std::multimap<ChannelModeName, ModeLock> &GetMLock() const;
|
||||
|
||||
/** Get a param from the channel
|
||||
* @param Name The mode
|
||||
* @param Target a string to put the param into
|
||||
* @return true on success
|
||||
/** Get a list of modes on a channel
|
||||
* @param Name The mode name to get a list of
|
||||
* @return a pair of iterators for the beginning and end of the list
|
||||
*/
|
||||
bool GetParam(ChannelModeName Name, Anope::string &Target) const;
|
||||
std::pair<ModeList::iterator, ModeList::iterator> GetModeList(ChannelModeName Name);
|
||||
|
||||
/** Check if a mode is set and has a param
|
||||
* @param Name The mode
|
||||
/** Get details for a specific mlock
|
||||
* @param mname The mode name
|
||||
* @param An optional param to match with
|
||||
* @return The MLock, if any
|
||||
*/
|
||||
bool HasParam(ChannelModeName Name) const;
|
||||
|
||||
/** Clear all the params from the channel
|
||||
*/
|
||||
void ClearParams();
|
||||
ModeLock *GetMLock(ChannelModeName mname, const Anope::string ¶m = "");
|
||||
|
||||
/** Check whether a user is permitted to be on this channel
|
||||
* @param u The user
|
||||
|
||||
+2
-33
@@ -4,10 +4,7 @@
|
||||
/* Anope */
|
||||
extern CoreExport Server *Me;
|
||||
|
||||
extern CoreExport void CapabParse(const std::vector<Anope::string> ¶ms);
|
||||
|
||||
extern CoreExport void do_server(const Anope::string &source, const Anope::string &servername, unsigned int hops, const Anope::string &descript, const Anope::string &numeric);
|
||||
extern CoreExport void do_squit(const Anope::string &source, const Anope::string &server);
|
||||
|
||||
extern CoreExport const char *ts6_uid_retrieve();
|
||||
extern CoreExport const char *ts6_sid_retrieve();
|
||||
@@ -21,33 +18,7 @@ enum CapabType
|
||||
CAPAB_NOQUIT,
|
||||
CAPAB_TSMODE,
|
||||
CAPAB_UNCONNECT,
|
||||
CAPAB_NICKIP,
|
||||
CAPAB_NSJOIN,
|
||||
CAPAB_ZIP,
|
||||
CAPAB_BURST,
|
||||
CAPAB_TS3,
|
||||
CAPAB_TS5,
|
||||
CAPAB_DKEY,
|
||||
CAPAB_DOZIP,
|
||||
CAPAB_DODKEY,
|
||||
CAPAB_QS,
|
||||
CAPAB_SCS,
|
||||
CAPAB_PT4,
|
||||
CAPAB_UID,
|
||||
CAPAB_KNOCK,
|
||||
CAPAB_CLIENT,
|
||||
CAPAB_IPV6,
|
||||
CAPAB_SSJ5,
|
||||
CAPAB_SN2,
|
||||
CAPAB_VHOST,
|
||||
CAPAB_TOKEN,
|
||||
CAPAB_SSJ3,
|
||||
CAPAB_NICK2,
|
||||
CAPAB_VL,
|
||||
CAPAB_TLKEXT,
|
||||
CAPAB_CHANMODE,
|
||||
CAPAB_SJB64,
|
||||
CAPAB_NICKCHARS,
|
||||
|
||||
CAPAB_END
|
||||
};
|
||||
@@ -73,6 +44,8 @@ enum ServerFlag
|
||||
SERVER_JUPED
|
||||
};
|
||||
|
||||
const Anope::string ServerFlagStrings[] = { "SERVER_NONE", "SERVER_SYNCING", "SERVER_JUPED", "" };
|
||||
|
||||
/** Class representing a server
|
||||
*/
|
||||
class CoreExport Server : public Flags<ServerFlag>
|
||||
@@ -159,10 +132,6 @@ class CoreExport Server : public Flags<ServerFlag>
|
||||
*/
|
||||
void DelLink(Server *s);
|
||||
|
||||
/** Remove all links from this server
|
||||
*/
|
||||
void ClearLinks();
|
||||
|
||||
/** Finish syncing this server and optionally all links to it
|
||||
* @param SyncLinks True to sync the links for this server too (if any)
|
||||
*/
|
||||
|
||||
+136
-139
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -43,6 +43,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <typeinfo>
|
||||
|
||||
#if GETTEXT_FOUND
|
||||
# include <libintl.h>
|
||||
# define _(x) anope_gettext(x)
|
||||
#else
|
||||
# define _(x) x
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# include <grp.h>
|
||||
@@ -50,6 +57,7 @@
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/time.h>
|
||||
# include <dirent.h>
|
||||
# ifdef HAVE_BACKTRACE
|
||||
# include <execinfo.h>
|
||||
@@ -59,31 +67,7 @@
|
||||
# define MARK_DEPRECATED __attribute((deprecated))
|
||||
# define DeleteFile unlink
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
# include <windows.h>
|
||||
# include <sys/timeb.h>
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# ifdef MODULE_COMPILE
|
||||
# define CoreExport __declspec(dllimport)
|
||||
# define DllExport __declspec(dllexport)
|
||||
# else
|
||||
# define CoreExport __declspec(dllexport)
|
||||
# define DllExport __declspec(dllimport)
|
||||
# endif
|
||||
/* VS2008 hates having this define before its own */
|
||||
# define vsnprintf _vsnprintf
|
||||
/* We have our own inet_pton and inet_ntop (Windows doesn't have its own) */
|
||||
# define inet_pton inet_pton_
|
||||
# define inet_ntop inet_ntop_
|
||||
# define setenv(x, y, z) SetEnvironmentVariable(x, y)
|
||||
# define unsetenv(x) SetEnvironmentVariable(x, NULL)
|
||||
# define MARK_DEPRECATED
|
||||
|
||||
extern CoreExport USHORT WindowsGetLanguage(const char *lang);
|
||||
extern CoreExport int inet_pton(int af, const char *src, void *dst);
|
||||
extern CoreExport const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
# include "anope_windows.h"
|
||||
#endif
|
||||
|
||||
/* Telling compilers about printf()-like functions: */
|
||||
@@ -93,18 +77,10 @@ extern CoreExport const char *inet_ntop(int af, const void *src, char *dst, size
|
||||
# define FORMAT(type, fmt, start)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
/* Some AIX boxes seem to have bogus includes that don't have these
|
||||
* prototypes. */
|
||||
@@ -128,18 +104,6 @@ extern int strncasecmp(const char *, const char *, size_t);
|
||||
#define tolower tolower_
|
||||
#define toupper toupper_
|
||||
|
||||
#ifdef __WINS__
|
||||
# ifndef BKCHECK
|
||||
# define BKCHECK
|
||||
extern "C" void __pfnBkCheck() {}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if INTTYPE_WORKAROUND
|
||||
# undef int16
|
||||
# undef int32
|
||||
#endif
|
||||
|
||||
/** This definition is used as shorthand for the various classes
|
||||
* and functions needed to make a module loadable by the OS.
|
||||
* It defines the class factory and external AnopeInit and AnopeFini functions.
|
||||
@@ -305,8 +269,11 @@ template<typename T, size_t Size = 32> class Flags
|
||||
{
|
||||
protected:
|
||||
std::bitset<Size> Flag_Values;
|
||||
const Anope::string *Flag_Strings;
|
||||
|
||||
public:
|
||||
Flags(const Anope::string *flag_strings) : Flag_Strings(flag_strings) { }
|
||||
|
||||
/** Add a flag to this item
|
||||
* @param Value The flag
|
||||
*/
|
||||
@@ -346,6 +313,23 @@ template<typename T, size_t Size = 32> class Flags
|
||||
{
|
||||
Flag_Values.reset();
|
||||
}
|
||||
|
||||
std::vector<Anope::string> ToString()
|
||||
{
|
||||
std::vector<Anope::string> ret;
|
||||
for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i)
|
||||
if (this->HasFlag(static_cast<T>(i)))
|
||||
ret.push_back(this->Flag_Strings[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FromString(const std::vector<Anope::string> &strings)
|
||||
{
|
||||
for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i)
|
||||
for (unsigned j = 0; j < strings.size(); ++j)
|
||||
if (this->Flag_Strings[i] == strings[j])
|
||||
this->SetFlag(static_cast<T>(i));
|
||||
}
|
||||
};
|
||||
|
||||
#include "sockets.h"
|
||||
@@ -356,12 +340,20 @@ template<typename T, size_t Size = 32> class Flags
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
class ConvertException : public CoreException
|
||||
{
|
||||
public:
|
||||
ConvertException(const Anope::string &reason = "") : CoreException(reason) { }
|
||||
|
||||
virtual ~ConvertException() throw() { }
|
||||
};
|
||||
|
||||
template<typename T> inline Anope::string stringify(const T &x)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
if (!(stream << x))
|
||||
throw CoreException("Stringify fail");
|
||||
throw ConvertException("Stringify fail");
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
@@ -373,11 +365,11 @@ template<typename T> inline void convert(const Anope::string &s, T &x, Anope::st
|
||||
char c;
|
||||
bool res = i >> x;
|
||||
if (!res)
|
||||
throw CoreException("Convert fail");
|
||||
throw ConvertException("Convert fail");
|
||||
if (failIfLeftoverChars)
|
||||
{
|
||||
if (i.get(c))
|
||||
throw CoreException("Convert fail");
|
||||
throw ConvertException("Convert fail");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -412,12 +404,11 @@ template<typename T> inline T convertTo(const Anope::string &s, bool failIfLefto
|
||||
class User;
|
||||
class NickCore;
|
||||
class NickAlias;
|
||||
class NickRequest;
|
||||
class BotInfo;
|
||||
class ChannelInfo;
|
||||
class Channel;
|
||||
class Server;
|
||||
struct EList;
|
||||
class Entry;
|
||||
struct Session;
|
||||
|
||||
#include "threadengine.h"
|
||||
@@ -432,7 +423,6 @@ struct IRCDVar
|
||||
{
|
||||
const char *name; /* Name of the IRCd command */
|
||||
const char *pseudoclient_mode; /* Mode used by BotServ Bots */
|
||||
int max_symbols; /* Chan Max Symbols */
|
||||
int svsnick; /* Supports SVSNICK */
|
||||
int vhost; /* Supports vhost */
|
||||
int snline; /* Supports SNline */
|
||||
@@ -441,8 +431,6 @@ struct IRCDVar
|
||||
int join2msg; /* Join 2 Message */
|
||||
int chansqline; /* Supports Channel Sqlines */
|
||||
int quitonkill; /* IRCD sends QUIT when kill */
|
||||
int svsmode_unban; /* svsmode can be used to unban */
|
||||
int reversekickcheck; /* Can reverse ban check */
|
||||
int vident; /* Supports vidents */
|
||||
int svshold; /* Supports svshold */
|
||||
int tsonmode; /* Timestamp on mode changes */
|
||||
@@ -452,11 +440,9 @@ struct IRCDVar
|
||||
int svsmode_ucmode; /* Can remove User Channel Modes with SVSMODE */
|
||||
int sglineenforce;
|
||||
int ts6; /* ircd is TS6 */
|
||||
int cidrchanbei; /* channel bans/excepts/invites support CIDR (syntax: +b *!*@192.168.0.0/15)
|
||||
* 0 for no support, 1 for strict cidr support, anything else
|
||||
* for ircd specific support (nefarious only cares about first /mask) */
|
||||
const char *globaltldprefix; /* TLD prefix used for Global */
|
||||
unsigned maxmodes; /* Max modes to send per line */
|
||||
int certfp; /* IRCd sends a SSL users certificate fingerprint */
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
@@ -467,17 +453,22 @@ enum MemoFlag
|
||||
{
|
||||
/* Memo is unread */
|
||||
MF_UNREAD,
|
||||
/* SEnder requests a receipt */
|
||||
/* Sender requests a receipt */
|
||||
MF_RECEIPT,
|
||||
/* Memo is a notification of receipt */
|
||||
MF_NOTIFYS
|
||||
};
|
||||
|
||||
const Anope::string MemoFlagStrings[] = {
|
||||
"MF_UNREAD", "MF_RECEIPT", "MF_NOTIFYS", ""
|
||||
};
|
||||
|
||||
/* Memo info structures. Since both nicknames and channels can have memos,
|
||||
* we encapsulate memo data in a MemoList to make it easier to handle. */
|
||||
class Memo : public Flags<MemoFlag>
|
||||
class CoreExport Memo : public Flags<MemoFlag>
|
||||
{
|
||||
public:
|
||||
Memo();
|
||||
time_t time; /* When it was sent */
|
||||
Anope::string sender;
|
||||
Anope::string text;
|
||||
@@ -485,12 +476,14 @@ class Memo : public Flags<MemoFlag>
|
||||
|
||||
struct CoreExport MemoInfo
|
||||
{
|
||||
unsigned memomax;
|
||||
int16 memomax;
|
||||
std::vector<Memo *> memos;
|
||||
std::vector<ci::string> ignores;
|
||||
|
||||
unsigned GetIndex(Memo *m) const;
|
||||
void Del(unsigned index);
|
||||
void Del(Memo *m);
|
||||
bool HasIgnore(User *u);
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
@@ -564,44 +557,6 @@ enum AccessLevel
|
||||
ACCESS_QOP = 10000
|
||||
};
|
||||
|
||||
/* Channel info structures. Stored similarly to the nicks, except that
|
||||
* the second character of the channel name, not the first, is used to
|
||||
* determine the list. (Hashing based on the first character of the name
|
||||
* wouldn't get very far. ;) ) */
|
||||
|
||||
/* Access levels for users. */
|
||||
struct ChanAccess
|
||||
{
|
||||
int16 level;
|
||||
NickCore *nc; /* Guaranteed to be non-NULL if in use, NULL if not */
|
||||
time_t last_seen;
|
||||
Anope::string creator;
|
||||
};
|
||||
|
||||
/** Flags for auto kick
|
||||
*/
|
||||
enum AutoKickFlag
|
||||
{
|
||||
/* Is by nick core, not mask */
|
||||
AK_ISNICK,
|
||||
/* This entry is stuck */
|
||||
AK_STUCK
|
||||
};
|
||||
|
||||
/* AutoKick data. */
|
||||
class AutoKick : public Flags<AutoKickFlag>
|
||||
{
|
||||
public:
|
||||
/* Only one of these can be in use */
|
||||
Anope::string mask;
|
||||
NickCore *nc;
|
||||
|
||||
Anope::string reason;
|
||||
Anope::string creator;
|
||||
time_t addtime;
|
||||
time_t last_used;
|
||||
};
|
||||
|
||||
/** Flags for badwords
|
||||
*/
|
||||
enum BadWordType
|
||||
@@ -631,11 +586,9 @@ enum ChannelAccess
|
||||
CA_SET, /* but not FOUNDER or PASSWORD */
|
||||
CA_UNBAN,
|
||||
CA_AUTOOP,
|
||||
CA_AUTODEOP, /* Maximum, not minimum */
|
||||
CA_AUTOVOICE,
|
||||
CA_OPDEOP, /* ChanServ commands OP and DEOP */
|
||||
CA_ACCESS_LIST,
|
||||
CA_CLEAR,
|
||||
CA_NOJOIN, /* Maximum */
|
||||
CA_ACCESS_CHANGE,
|
||||
CA_MEMO,
|
||||
@@ -661,6 +614,7 @@ enum ChannelAccess
|
||||
CA_BANME,
|
||||
CA_BAN,
|
||||
CA_TOPIC,
|
||||
CA_MODE,
|
||||
CA_INFO,
|
||||
CA_AUTOOWNER,
|
||||
CA_OWNER,
|
||||
@@ -703,9 +657,24 @@ enum BotServFlag
|
||||
BS_KICK_REPEAT,
|
||||
/* BotServ kicks for italics */
|
||||
BS_KICK_ITALICS,
|
||||
/* BotServ kicks for amsgs */
|
||||
BS_KICK_AMSGS,
|
||||
/* Send fantasy replies back to the channel via PRIVMSG */
|
||||
BS_MSG_PRIVMSG,
|
||||
/* Send fantasy replies back to the channel via NOTICE */
|
||||
BS_MSG_NOTICE,
|
||||
/* Send fantasy replies back to the channel via NOTICE to ops */
|
||||
BS_MSG_NOTICEOPS,
|
||||
BS_END
|
||||
};
|
||||
|
||||
const Anope::string BotServFlagStrings[] = {
|
||||
"BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "SYMBIOSIS", "GREET", "NOBOT",
|
||||
"KICK_BOLDs", "KICK_COLORS", "KICK_REVERSES", "KICK_UNDERLINES", "KICK_BADWORDS", "KICK_CAPS",
|
||||
"KICK_FLOOD", "KICK_REPEAT", "KICK_ITALICS", "KICK_AMSGS", "MSG_PRIVMSG", "MSG_NOTICE",
|
||||
"MSG_NOTICEOPS", ""
|
||||
};
|
||||
|
||||
/* Indices for TTB (Times To Ban) */
|
||||
enum
|
||||
{
|
||||
@@ -718,6 +687,7 @@ enum
|
||||
TTB_FLOOD,
|
||||
TTB_REPEAT,
|
||||
TTB_ITALICS,
|
||||
TTB_AMSGS,
|
||||
TTB_SIZE
|
||||
};
|
||||
|
||||
@@ -729,7 +699,6 @@ enum
|
||||
* user is kicked.
|
||||
*/
|
||||
|
||||
#include "language.h"
|
||||
#include "users.h"
|
||||
#include "account.h"
|
||||
#include "bots.h"
|
||||
@@ -745,7 +714,7 @@ struct LevelInfo
|
||||
{
|
||||
int what;
|
||||
Anope::string name;
|
||||
LanguageString desc;
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
#include "channels.h"
|
||||
@@ -755,7 +724,7 @@ struct LevelInfo
|
||||
enum EntryType
|
||||
{
|
||||
ENTRYTYPE_NONE,
|
||||
ENTRYTYPE_CIDR4,
|
||||
ENTRYTYPE_CIDR,
|
||||
ENTRYTYPE_NICK_WILD,
|
||||
ENTRYTYPE_NICK,
|
||||
ENTRYTYPE_USER_WILD,
|
||||
@@ -764,29 +733,32 @@ enum EntryType
|
||||
ENTRYTYPE_HOST
|
||||
};
|
||||
|
||||
class Entry : public Flags<EntryType>
|
||||
class CoreExport Entry : public Flags<EntryType>
|
||||
{
|
||||
ChannelModeName modename;
|
||||
|
||||
public:
|
||||
Entry *next, *prev;
|
||||
uint32 cidr_ip; /* IP mask for CIDR matching */
|
||||
uint32 cidr_mask; /* Netmask for CIDR matching */
|
||||
Anope::string nick, user, host, mask;
|
||||
};
|
||||
|
||||
struct EList
|
||||
{
|
||||
Entry *entries;
|
||||
int32 count;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Ignorance list data. */
|
||||
|
||||
struct IgnoreData
|
||||
{
|
||||
unsigned char cidr_len;
|
||||
Anope::string mask;
|
||||
time_t time; /* When do we stop ignoring them? */
|
||||
Anope::string nick, user, host;
|
||||
|
||||
/** Constructor
|
||||
* @param _host A full nick!ident@host/cidr mask
|
||||
* @param mode What mode this host is for - can be CMODE_BEGIN for unknown/no mode
|
||||
*/
|
||||
Entry(ChannelModeName mode, const Anope::string &_host);
|
||||
|
||||
/** Get the banned mask for this entry
|
||||
* @return The mask
|
||||
*/
|
||||
const Anope::string GetMask();
|
||||
|
||||
/** Check if this entry matches a user
|
||||
* @param u The user
|
||||
* @param full True to match against a users real host and IP
|
||||
* @return true on match
|
||||
*/
|
||||
bool Matches(User *u, bool full = false) const;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
@@ -804,7 +776,7 @@ struct NewsMessages
|
||||
{
|
||||
NewsType type;
|
||||
Anope::string name;
|
||||
LanguageString msgs[10];
|
||||
const char *msgs[10];
|
||||
};
|
||||
|
||||
struct NewsItem
|
||||
@@ -825,7 +797,6 @@ struct MailInfo
|
||||
FILE *pipe;
|
||||
User *sender;
|
||||
NickCore *recipient;
|
||||
NickRequest *recip;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
@@ -842,8 +813,7 @@ struct Exception
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, Session *, Anope::hash> session_map;
|
||||
extern CoreExport session_map SessionList;
|
||||
extern CoreExport Anope::map<Session *> SessionList;
|
||||
|
||||
struct Session
|
||||
{
|
||||
@@ -886,10 +856,13 @@ enum DefconLevel
|
||||
* Forward declaration reqired, because the base IRCDProto class uses some crap from in here.
|
||||
*/
|
||||
class IRCDProto;
|
||||
class IRCdMessage;
|
||||
struct Uplink;
|
||||
class ServerConfig;
|
||||
class ConfigurationFile;
|
||||
|
||||
#include "extern.h"
|
||||
#include "language.h"
|
||||
#include "operserv.h"
|
||||
#include "mail.h"
|
||||
#include "servers.h"
|
||||
@@ -918,10 +891,9 @@ class CoreExport IRCDProto
|
||||
virtual void SendSVSNOOP(const Anope::string &, int) { }
|
||||
virtual void SendTopic(BotInfo *, Channel *) = 0;
|
||||
virtual void SendVhostDel(User *) { }
|
||||
virtual void SendAkill(const XLine *) = 0;
|
||||
virtual void SendAkill(User *, const XLine *) = 0;
|
||||
virtual void SendAkillDel(const XLine *) = 0;
|
||||
virtual void SendSVSKill(const BotInfo *source, const User *user, const char *fmt, ...);
|
||||
virtual void SendSVSMode(const User *, int, const char **) = 0;
|
||||
virtual void SendMode(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
|
||||
virtual void SendMode(const BotInfo *bi, const User *u, const char *fmt, ...);
|
||||
virtual void SendClientIntroduction(const User *u, const Anope::string &) = 0;
|
||||
@@ -937,13 +909,12 @@ class CoreExport IRCDProto
|
||||
virtual void SendQuit(const User *u, const char *fmt, ...);
|
||||
virtual void SendPing(const Anope::string &servname, const Anope::string &who);
|
||||
virtual void SendPong(const Anope::string &servname, const Anope::string &who);
|
||||
virtual void SendJoin(const BotInfo *, const Anope::string &, time_t) = 0;
|
||||
virtual void SendJoin(BotInfo *, const ChannelContainer *);
|
||||
virtual void SendSQLineDel(const XLine *x) = 0;
|
||||
virtual void SendJoin(BotInfo *, Channel *, const ChannelStatus *) = 0;
|
||||
virtual void SendSQLineDel(const XLine *x) { }
|
||||
virtual void SendInvite(const BotInfo *bi, const Anope::string &chan, const Anope::string &nick);
|
||||
virtual void SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...);
|
||||
virtual void SendGlobops(const BotInfo *source, const char *fmt, ...);
|
||||
virtual void SendSQLine(const XLine *x) = 0;
|
||||
virtual void SendSQLine(User *, const XLine *x) { }
|
||||
virtual void SendSquit(const Anope::string &servname, const Anope::string &message);
|
||||
virtual void SendSVSO(const Anope::string &, const Anope::string &, const Anope::string &) { }
|
||||
virtual void SendChangeBotNick(const BotInfo *bi, const Anope::string &newnick);
|
||||
@@ -954,14 +925,11 @@ class CoreExport IRCDProto
|
||||
virtual void SendSVSHoldDel(const Anope::string &) { }
|
||||
virtual void SendSGLineDel(const XLine *) { }
|
||||
virtual void SendSZLineDel(const XLine *) { }
|
||||
virtual void SendSZLine(const XLine *) { }
|
||||
virtual void SendSGLine(const XLine *) { }
|
||||
virtual void SendBanDel(const Channel *, const Anope::string &) { }
|
||||
virtual void SendSVSModeChan(const Channel *, const Anope::string &, const Anope::string &) { }
|
||||
virtual void SendSZLine(User *u, const XLine *) { }
|
||||
virtual void SendSGLine(User *, const XLine *) { }
|
||||
virtual void SendUnregisteredNick(const User *) { }
|
||||
virtual void SendCTCP(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
|
||||
virtual void SendSVSJoin(const Anope::string &, const Anope::string &, const Anope::string &, const Anope::string &) { }
|
||||
virtual void SendSVSPart(const Anope::string &, const Anope::string &, const Anope::string &) { }
|
||||
virtual void SendSWhois(const Anope::string &, const Anope::string &, const Anope::string &) { }
|
||||
virtual void SendBOB() { }
|
||||
virtual void SendEOB() { }
|
||||
@@ -986,6 +954,35 @@ class CoreExport IRCDProto
|
||||
* @param u The user
|
||||
*/
|
||||
virtual void SetAutoIdentificationToken(User *u) { }
|
||||
|
||||
/** Send a channel creation message to the uplink.
|
||||
* On most TS6 IRCds this is a SJOIN with no nick
|
||||
*/
|
||||
virtual void SendChannel(Channel *c) { }
|
||||
};
|
||||
|
||||
class CoreExport IRCdMessage
|
||||
{
|
||||
public:
|
||||
virtual bool On436(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnAway(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnJoin(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnKick(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnKill(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnMode(const Anope::string &, const std::vector<Anope::string> &) = 0;
|
||||
virtual bool OnUID(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnNick(const Anope::string &, const std::vector<Anope::string> &) = 0;
|
||||
virtual bool OnPart(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnPing(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnPrivmsg(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnQuit(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnServer(const Anope::string &, const std::vector<Anope::string> &) = 0;
|
||||
virtual bool OnSQuit(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnTopic(const Anope::string &, const std::vector<Anope::string> &) = 0;
|
||||
virtual bool OnWhois(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnCapab(const Anope::string &, const std::vector<Anope::string> &);
|
||||
virtual bool OnSJoin(const Anope::string &, const std::vector<Anope::string> &) = 0;
|
||||
virtual bool OnError(const Anope::string &, const std::vector<Anope::string> &);
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
|
||||
+18
-4
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -80,6 +80,18 @@ union CoreExport sockaddrs
|
||||
void ntop(int type, const void *src);
|
||||
};
|
||||
|
||||
class CoreExport cidr
|
||||
{
|
||||
sockaddrs addr;
|
||||
Anope::string cidr_ip;
|
||||
unsigned char cidr_len;
|
||||
public:
|
||||
cidr(const Anope::string &ip);
|
||||
cidr(const Anope::string &ip, unsigned char len);
|
||||
Anope::string mask() const;
|
||||
bool match(sockaddrs &other);
|
||||
};
|
||||
|
||||
class SocketException : public CoreException
|
||||
{
|
||||
public:
|
||||
@@ -109,6 +121,8 @@ enum SocketFlag
|
||||
SF_WRITABLE
|
||||
};
|
||||
|
||||
static const Anope::string SocketFlagStrings[] = { "SF_DEAD", "SF_WRITABLE", "" };
|
||||
|
||||
class Socket;
|
||||
class ClientSocket;
|
||||
class ListenSocket;
|
||||
@@ -328,13 +342,13 @@ class CoreExport ConnectionSocket : public BufferedSocket
|
||||
void Connect(const Anope::string &TargetHost, int Port, const Anope::string &BindHost = "");
|
||||
};
|
||||
|
||||
class ClientSocket : public BufferedSocket
|
||||
class CoreExport ClientSocket : public BufferedSocket
|
||||
{
|
||||
public:
|
||||
/* Listen socket this connection came from */
|
||||
ListenSocket *LS;
|
||||
/* Clients address */
|
||||
sockaddrs clientaddr;
|
||||
public:
|
||||
|
||||
/** Constructor
|
||||
* @param ls Listen socket this connection is from
|
||||
|
||||
@@ -8,19 +8,16 @@
|
||||
#cmakedefine HAVE_STDINT_H 1
|
||||
#cmakedefine HAVE_STDDEF_H 1
|
||||
#cmakedefine HAVE_BACKTRACE 1
|
||||
#cmakedefine HAVE_GETTIMEOFDAY 1
|
||||
#cmakedefine HAVE_SETGRENT 1
|
||||
#cmakedefine HAVE_STRCASECMP 1
|
||||
#cmakedefine HAVE_STRICMP 1
|
||||
#cmakedefine HAVE_STRINGS_H 1
|
||||
#cmakedefine HAVE_STRLCAT 1
|
||||
#cmakedefine HAVE_STRLCPY 1
|
||||
#cmakedefine HAVE_SYS_SELECT_H 1
|
||||
#cmakedefine HAVE_UMASK 1
|
||||
#cmakedefine HAVE_EVENTFD 1
|
||||
#cmakedefine GETTEXT_FOUND 1
|
||||
#cmakedefine RUNGROUP "@RUNGROUP@"
|
||||
#define LIBINTL "@LIBINTL_INCLUDE@"
|
||||
|
||||
#cmakedefine HAVE_UINT8_T 1
|
||||
#cmakedefine HAVE_U_INT8_T 1
|
||||
@@ -104,9 +101,6 @@ typedef unsigned long uint32;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef MSVCPP
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
# define popen _popen
|
||||
# define pclose _pclose
|
||||
# define ftruncate _chsize
|
||||
|
||||
+11
-1
@@ -45,7 +45,7 @@ class CoreExport Thread : public Extensible
|
||||
{
|
||||
private:
|
||||
/* Set to true to tell the thread to finish and we are waiting for it */
|
||||
bool Exit;
|
||||
bool exit;
|
||||
|
||||
public:
|
||||
/* Handle for this thread */
|
||||
@@ -67,6 +67,10 @@ class CoreExport Thread : public Extensible
|
||||
*/
|
||||
void SetExitState();
|
||||
|
||||
/** Exit the thread. Note that the thread still must be joined to free resources!
|
||||
*/
|
||||
void Exit();
|
||||
|
||||
/** Returns the exit state of the thread
|
||||
* @return true if we want to exit
|
||||
*/
|
||||
@@ -99,6 +103,12 @@ class CoreExport Mutex
|
||||
/** Unlock the mutex, it must be locked first
|
||||
*/
|
||||
void Unlock();
|
||||
|
||||
/** Attempt to lock the mutex, will return true on success and false on fail
|
||||
* Does not block
|
||||
* @return true or false
|
||||
*/
|
||||
bool TryLock();
|
||||
};
|
||||
|
||||
class CoreExport Condition : public Mutex
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
/* Timer include stuff.
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
+40
-24
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Robin Burchell <w00t@inspircd.org>
|
||||
* Copyright (C) 2008-2010 Anope Team <team@anope.org>
|
||||
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
|
||||
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*/
|
||||
@@ -8,18 +8,13 @@
|
||||
#ifndef USERS_H
|
||||
#define USERS_H
|
||||
|
||||
/* Hash maps used for users. Note UserListByUID will not be used on non-TS6 IRCds, and should never
|
||||
* be assumed to have users
|
||||
*/
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, User *, ci::hash, std::equal_to<ci::string> > user_map;
|
||||
typedef unordered_map_namespace::unordered_map<Anope::string, User *, Anope::hash> user_uid_map;
|
||||
|
||||
extern CoreExport user_map UserListByNick;
|
||||
extern CoreExport user_uid_map UserListByUID;
|
||||
extern CoreExport Anope::insensitive_map<User *> UserListByNick;
|
||||
extern CoreExport Anope::map<User *> UserListByUID;
|
||||
|
||||
class CoreExport ChannelStatus : public Flags<ChannelModeName, CMODE_END * 2>
|
||||
{
|
||||
public:
|
||||
ChannelStatus();
|
||||
Anope::string BuildCharPrefixList() const;
|
||||
Anope::string BuildModePrefixList() const;
|
||||
};
|
||||
@@ -54,6 +49,7 @@ class CoreExport User : public Extensible
|
||||
Anope::string vhost; /* User's virtual hostname */
|
||||
Anope::string chost; /* User's cloaked hostname */
|
||||
Anope::string realname; /* Realname */
|
||||
Anope::string fingerprint; /* SSL Fingerprint */
|
||||
sockaddrs ip; /* User's IP */
|
||||
Server *server; /* Server user is connected to */
|
||||
time_t timestamp; /* Timestamp of the nick */
|
||||
@@ -90,7 +86,7 @@ class CoreExport User : public Extensible
|
||||
/** Update the nickname of a user record accordingly, should be
|
||||
* called from ircd protocol.
|
||||
*/
|
||||
virtual void SetNewNick(const Anope::string &newnick);
|
||||
void SetNewNick(const Anope::string &newnick);
|
||||
|
||||
/** Update the displayed (vhost) of a user record.
|
||||
* This is used (if set) instead of real host.
|
||||
@@ -145,25 +141,22 @@ class CoreExport User : public Extensible
|
||||
*/
|
||||
Anope::string GetMask() const;
|
||||
|
||||
/** Get the full display mask (nick!vident@vhost/chost)
|
||||
*/
|
||||
Anope::string GetDisplayedMask() const;
|
||||
|
||||
/** Updates the realname of the user record.
|
||||
*/
|
||||
void SetRealname(const Anope::string &realname);
|
||||
|
||||
/**
|
||||
* Send a message (notice or privmsg, depending on settings) to a user
|
||||
* @param source Sender nick
|
||||
* @param source Sender
|
||||
* @param fmt Format of the Message
|
||||
* @param ... any number of parameters
|
||||
*/
|
||||
virtual void SendMessage(const Anope::string &source, const char *fmt, ...) const;
|
||||
virtual void SendMessage(const Anope::string &source, const Anope::string &msg) const;
|
||||
|
||||
/** Send a language string message to a user
|
||||
* @param source Sender
|
||||
* @param message The message num
|
||||
* @param ... parameters
|
||||
*/
|
||||
void SendMessage(BotInfo *source, LanguageString message, ...) const;
|
||||
void SendMessage(BotInfo *source, const char *fmt, ...);
|
||||
virtual void SendMessage(BotInfo *source, Anope::string msg);
|
||||
|
||||
/** Collide a nick
|
||||
* See the comment in users.cpp
|
||||
@@ -171,6 +164,13 @@ class CoreExport User : public Extensible
|
||||
*/
|
||||
void Collide(NickAlias *na);
|
||||
|
||||
/** Identify the user to the Nick
|
||||
* updates last_seen, logs the user in,
|
||||
* send messages, checks for mails, set vhost and more
|
||||
* @param the NickAlias
|
||||
*/
|
||||
void Identify(NickAlias *na);
|
||||
|
||||
/** Login the user to a NickCore
|
||||
* @param core The account the user is useing
|
||||
*/
|
||||
@@ -184,19 +184,35 @@ class CoreExport User : public Extensible
|
||||
* @return The account or NULL
|
||||
*/
|
||||
virtual NickCore *Account();
|
||||
virtual const NickCore *Account() const;
|
||||
|
||||
/** Check if the user is identified for their nick
|
||||
* @param CheckNick True to check if the user is identified to the nickname they are on too
|
||||
* @return true or false
|
||||
*/
|
||||
virtual bool IsIdentified(bool CheckNick = false) const;
|
||||
virtual bool IsIdentified(bool CheckNick = false);
|
||||
|
||||
/** Check if the user is recognized for their nick (on the nicks access list)
|
||||
* @param CheckSecure Only returns true if the user has secure off
|
||||
* @return true or false
|
||||
*/
|
||||
virtual bool IsRecognized(bool CheckSecure = false) const;
|
||||
virtual bool IsRecognized(bool CheckSecure = false);
|
||||
|
||||
/** Check if the user is a services oper
|
||||
* @return true if they are an oper
|
||||
*/
|
||||
bool IsServicesOper();
|
||||
|
||||
/** Check whether this user has access to run the given command string.
|
||||
* @param cmdstr The string to check, e.g. botserv/set/private.
|
||||
* @return True if this user may run the specified command, false otherwise.
|
||||
*/
|
||||
bool HasCommand(const Anope::string &cmdstr);
|
||||
|
||||
/** Check whether this user has access to the given special permission.
|
||||
* @param privstr The priv to check for, e.g. users/auspex.
|
||||
* @return True if this user has the specified priv, false otherwise.
|
||||
*/
|
||||
bool HasPriv(const Anope::string &privstr);
|
||||
|
||||
/** Update the last usermask stored for a user, and check to see if they are recognized
|
||||
*/
|
||||
|
||||
+10
-3
@@ -1,9 +1,9 @@
|
||||
/* Build bumper
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for furhter details.
|
||||
* 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.
|
||||
@@ -54,12 +54,19 @@ int main(int argc, char *argv[])
|
||||
|
||||
std::string version_build = "#define VERSION_BUILD 1";
|
||||
std::string build = "#define BUILD 1";
|
||||
std::string version_extra;
|
||||
if (fd.is_open())
|
||||
{
|
||||
while (getline(fd, filebuf))
|
||||
{
|
||||
if (!filebuf.find("#define VERSION_BUILD"))
|
||||
version_build = filebuf;
|
||||
else if (!filebuf.find("#define VERSION_EXTRA"))
|
||||
{
|
||||
size_t q = filebuf.find('"');
|
||||
|
||||
version_extra = filebuf.substr(q + 1, filebuf.length() - q - 2);
|
||||
}
|
||||
else if (!filebuf.find("#define BUILD"))
|
||||
{
|
||||
size_t tab = filebuf.find(' ');
|
||||
@@ -89,7 +96,7 @@ int main(int argc, char *argv[])
|
||||
for (std::list<std::pair<std::string, std::string> >::iterator it = versions.begin(), it_end = versions.end(); it != it_end; ++it)
|
||||
{
|
||||
if (it->first == "EXTRA")
|
||||
fd << "#define VERSION_EXTRA \"" << it->second << "\"" << std::endl;
|
||||
fd << "#define VERSION_EXTRA \"" << (!version_extra.empty() ? version_extra : "") << (version_extra.find(it->second) == std::string::npos ? it->second : "") << "\"" << std::endl;
|
||||
else
|
||||
fd << "#define VERSION_" << it->first << " " << it->second << std::endl;
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
HLANG=`cat ../include/language.h | grep "^\s" | sed 's/[\t,]//g'`
|
||||
CPPLANG=`cat ../src/language.cpp | grep "\s\/\* [A-Z0-9_]* \*\/" | sed 's/\/\* \(.*\) \*\//\1/' | sed 's/\t//'`
|
||||
echo "${HLANG} ${CPPLANG}" | sed 's/ /\n/' | sort | uniq -u
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# Italian translations for ns_maxemail
|
||||
# Traduzioni italiane per il ns_maxemail
|
||||
# Copyright (C) 2010 Anope Team
|
||||
# This file is distributed under the same license as Anope IRC Services
|
||||
# Adam <adam@anope.org>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Anope\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-09-25 23:51-0400\n"
|
||||
"PO-Revision-Date: 2010-09-26 00:11-0400\n"
|
||||
"Last-Translator: Adam <adam@anope.org>\n"
|
||||
"Language-Team: Italian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ns_maxemail.cpp:33
|
||||
#, c-format
|
||||
msgid "The given email address has reached it's usage limit of %d users."
|
||||
msgstr "L'indirizzo email specificato ha raggiunto il suo limite d'utilizzo di %d utenti."
|
||||
|
||||
#: ns_maxemail.cpp:31
|
||||
msgid "The given email address has reached it's usage limit of 1 user."
|
||||
msgstr "L'indirizzo email specificato ha raggiunto il suo limite d'utilizzo di 1 utente."
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for string in `egrep "^.+[A-Z]+," ../include/language.h | sed "s/\t\(.*\),/\1/"` ; do
|
||||
CMD=`grep -RI $string {../src,../modules,../include} | grep -v "language\.cpp:.*\/\* $string" | grep -v "language\.h:"`
|
||||
if [ ! -n "$CMD" ] ; then
|
||||
echo "$string is unused"
|
||||
sed -i "s/\/\* $string \*\//\/* $string - UNUSED *\//" ../src/language.cpp
|
||||
sed -i "/$string,/d" ../include/language.h
|
||||
fi
|
||||
done
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
pushd ../src > /dev/null
|
||||
xgettext -C -s -d Anope -o ../lang/anope.pot --from-code=utf-8 --keyword=_ language.cpp
|
||||
popd > /dev/null
|
||||
|
||||
for f in *.po
|
||||
do
|
||||
msgmerge -v -s -U $f `echo $f | cut -d'.' -f1`.pot
|
||||
done
|
||||
@@ -24,7 +24,6 @@ if(GETTEXT_FOUND)
|
||||
MAIN_DEPENDENCY ${LANG_PO}
|
||||
)
|
||||
# Add to cpack ignored files if not on Windows.
|
||||
file(RELATIVE_PATH LANG_RELATIVE ${Anope_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${LANG_LANG})
|
||||
if(NOT WIN32)
|
||||
add_to_cpack_ignored_files("${LANG_MO}")
|
||||
endif(NOT WIN32)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2866
-3460
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm anope.pot
|
||||
touch anope.pot
|
||||
|
||||
cd ..
|
||||
FILES=`find ./ -name *.cpp -o -name *.h | grep -v /modules/extra/`
|
||||
for f in $FILES
|
||||
do
|
||||
xgettext -C -s -d Anope -j -o language/anope.pot --from-code=utf-8 --keyword=_ $f
|
||||
done
|
||||
|
||||
cd -
|
||||
|
||||
for f in *.po
|
||||
do
|
||||
msgmerge -v -s -U $f `echo $f | cut -d'.' -f1`.pot
|
||||
done
|
||||
|
||||
rm -f *~
|
||||
+15
-8
@@ -1,3 +1,5 @@
|
||||
add_subdirectory("extra/language")
|
||||
|
||||
# Get a list of ALL files and directories within the current directory
|
||||
file(GLOB MODULES_FOLDERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
|
||||
remove_item_from_list(MODULES_FOLDERS "CMakeFiles")
|
||||
@@ -75,10 +77,10 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
|
||||
set(WIN32_NO_LIBS)
|
||||
endif(WIN32)
|
||||
set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}")
|
||||
add_dependencies(${SO} ${PROGRAM_NAME})
|
||||
# For Windows only, have the module link to the export library of Anope as well as the wsock32 library (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
|
||||
add_dependencies(${SO} ${PROGRAM_NAME} module_language)
|
||||
# For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
|
||||
if(WIN32)
|
||||
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES})
|
||||
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES})
|
||||
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
|
||||
endif(WIN32)
|
||||
# Set the module to be installed to the module directory under the data directory
|
||||
@@ -86,12 +88,15 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
|
||||
DESTINATION data/modules
|
||||
)
|
||||
endif(HAS_FUNCTION)
|
||||
else(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES)
|
||||
message(" This is not a fatal error - ${SRC} will not be built.")
|
||||
endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES)
|
||||
endforeach(SRC)
|
||||
|
||||
# Get a list of ALL files and directories within this modules directory
|
||||
file(GLOB SUBMODULE_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${MODULE_FOLDER}/*")
|
||||
remove_item_from_list(SUBMODULE_DIRS "CMakeFiles")
|
||||
remove_item_from_list(SUBMODULE_DIRS "extra/language")
|
||||
|
||||
foreach(SUBDIR ${SUBMODULE_DIRS})
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
|
||||
@@ -149,7 +154,7 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
|
||||
endforeach(SRC)
|
||||
|
||||
# Continue if library and function requirements are met
|
||||
if(NOT SKIP AND HAS_FUNCTION)
|
||||
if(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION)
|
||||
# Remove duplicates from the linker flags
|
||||
if(SUBDIR_LDFLAGS)
|
||||
remove_list_duplicates(SUBDIR_LDFLAGS)
|
||||
@@ -169,17 +174,19 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
|
||||
# Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand
|
||||
add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS})
|
||||
set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}")
|
||||
add_dependencies(${SO} ${PROGRAM_NAME})
|
||||
# For Windows only, have the module link to the export library of Anope as well as the wsock32 library (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
|
||||
add_dependencies(${SO} ${PROGRAM_NAME} module_language)
|
||||
# For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version
|
||||
if(WIN32)
|
||||
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS})
|
||||
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS})
|
||||
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
|
||||
endif(WIN32)
|
||||
# Set the module to be installed to the module directory under the data directory
|
||||
install(TARGETS ${SO}
|
||||
DESTINATION data/modules
|
||||
)
|
||||
endif(NOT SKIP AND HAS_FUNCTION)
|
||||
else(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION)
|
||||
message(" This is not a fatal error - ${SUBDIR} will not be built.")
|
||||
endif(NOT SKIP_DEPENDS AND NOT SKIP_LIBRARIES AND HAS_FUNCTION)
|
||||
endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
|
||||
endforeach(SUBDIR)
|
||||
endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FOLDER}")
|
||||
|
||||
+15
-15
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,28 +18,30 @@ class CommandBSAct : public Command
|
||||
public:
|
||||
CommandBSAct() : Command("ACT", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Makes the bot do the equivalent of a \"/me\" command"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci = cs_findchan(params[0]);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Anope::string message = params[1];
|
||||
|
||||
if (!check_access(u, ci, CA_SAY))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!ci->bi)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
|
||||
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!ci->c || !ci->c->FindUser(ci->bi))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_NOT_ON_CHANNEL, ci->name.c_str());
|
||||
source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -56,21 +58,19 @@ class CommandBSAct : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "ACT", BOT_ACT_SYNTAX);
|
||||
SyntaxError(source, "ACT", _("ACT \037channel\037 \037text\037"));
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_ACT);
|
||||
source.Reply(_("Syntax: \002ACT \037channel\037 \037text\037\002\n"
|
||||
" \n"
|
||||
"Makes the bot do the equivalent of a \"/me\" command\n"
|
||||
"on the given channel using the given text."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_ACT);
|
||||
}
|
||||
};
|
||||
|
||||
class BSAct : public Module
|
||||
|
||||
+25
-26
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,44 +18,44 @@ class CommandBSAssign : public Command
|
||||
public:
|
||||
CommandBSAssign() : Command("ASSIGN", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Assigns a bot to a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string nick = params[1];
|
||||
BotInfo *bi;
|
||||
ChannelInfo *ci;
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &nick = params[1];
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_ASSIGN_READONLY);
|
||||
source.Reply(_(BOT_ASSIGN_READONLY));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!(bi = findbot(nick)))
|
||||
BotInfo *bi = findbot(nick);
|
||||
if (!bi)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, nick.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
ci = cs_findchan(chan);
|
||||
|
||||
if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->Account()->HasPriv("botserv/administration")))
|
||||
if (ci->botflags.HasFlag(BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !u->HasPriv("botserv/administration")))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (bi->HasFlag(BI_PRIVATE) && !u->Account()->HasCommand("botserv/assign/private"))
|
||||
if (bi->HasFlag(BI_PRIVATE) && !u->HasCommand("botserv/assign/private"))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (ci->bi && nick.equals_ci(ci->bi->nick))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_ASSIGN_ALREADY, ci->bi->nick.c_str(), chan.c_str());
|
||||
source.Reply(_("Bot \002%s\002 is already assigned to channel \002%s\002."), ci->bi->nick.c_str(), chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -63,24 +63,23 @@ class CommandBSAssign : public Command
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << bi->nick;
|
||||
|
||||
bi->Assign(u, ci);
|
||||
u->SendMessage(BotServ, BOT_ASSIGN_ASSIGNED, bi->nick.c_str(), ci->name.c_str());
|
||||
source.Reply(_("Bot \002%s\002 has been assigned to %s."), bi->nick.c_str(), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_ASSIGN);
|
||||
source.Reply(_("Syntax: \002ASSIGN \037chan\037 \037nick\037\002\n"
|
||||
" \n"
|
||||
"Assigns a bot pointed out by nick to the channel chan. You\n"
|
||||
"can then configure the bot for the channel so it fits\n"
|
||||
"your needs."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_ASSIGN);
|
||||
SyntaxError(source, "ASSIGN", _("ASSIGN \037chan\037 \037nick\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+102
-70
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -15,88 +15,88 @@
|
||||
|
||||
class BadwordsListCallback : public NumberList
|
||||
{
|
||||
User *u;
|
||||
ChannelInfo *ci;
|
||||
CommandSource &source;
|
||||
bool SentHeader;
|
||||
public:
|
||||
BadwordsListCallback(User *_u, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), u(_u), ci(_ci), SentHeader(false)
|
||||
BadwordsListCallback(CommandSource &_source, const Anope::string &list) : NumberList(list, false), source(_source), SentHeader(false)
|
||||
{
|
||||
}
|
||||
|
||||
~BadwordsListCallback()
|
||||
{
|
||||
if (!SentHeader)
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetBadWordCount())
|
||||
if (!Number || Number > source.ci->GetBadWordCount())
|
||||
return;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_("Bad words list for %s:\n"
|
||||
" Num Word Type"), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
DoList(u, ci, Number - 1, ci->GetBadWord(Number - 1));
|
||||
DoList(source, Number - 1, source.ci->GetBadWord(Number - 1));
|
||||
}
|
||||
|
||||
static void DoList(User *u, ChannelInfo *ci, unsigned Number, BadWord *bw)
|
||||
static void DoList(CommandSource &source, unsigned Number, BadWord *bw)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_LIST_FORMAT, Number + 1, bw->word.c_str(), bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : "")));
|
||||
source.Reply(_(" %3d %-30s %s"), Number + 1, bw->word.c_str(), bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : "")));
|
||||
}
|
||||
};
|
||||
|
||||
class BadwordsDelCallback : public NumberList
|
||||
{
|
||||
User *u;
|
||||
ChannelInfo *ci;
|
||||
CommandSource &source;
|
||||
Command *c;
|
||||
unsigned Deleted;
|
||||
bool override;
|
||||
public:
|
||||
BadwordsDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), c(_c), Deleted(0), override(false)
|
||||
BadwordsDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0), override(false)
|
||||
{
|
||||
if (!check_access(u, ci, CA_BADWORDS) && u->Account()->HasPriv("botserv/administration"))
|
||||
if (!check_access(source.u, source.ci, CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
|
||||
this->override = true;
|
||||
}
|
||||
|
||||
~BadwordsDelCallback()
|
||||
{
|
||||
if (!Deleted)
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s bad words list."), source.ci->name.c_str());
|
||||
else if (Deleted == 1)
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_DELETED_ONE, ci->name.c_str());
|
||||
source.Reply(_("Deleted 1 entry from %s bad words list."), source.ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_DELETED_SEVERAL, Deleted, ci->name.c_str());
|
||||
source.Reply(_("Deleted %d entries from %s bad words list."), Deleted, source.ci->name.c_str());
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetBadWordCount())
|
||||
if (!Number || Number > source.ci->GetBadWordCount())
|
||||
return;
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL " << ci->GetBadWord(Number -1 )->word;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "DEL " << source.ci->GetBadWord(Number - 1)->word;
|
||||
++Deleted;
|
||||
ci->EraseBadWord(Number - 1);
|
||||
source.ci->EraseBadWord(Number - 1);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandBSBadwords : public Command
|
||||
{
|
||||
private:
|
||||
CommandReturn DoList(User *u, ChannelInfo *ci, const Anope::string &word)
|
||||
CommandReturn DoList(CommandSource &source, const Anope::string &word)
|
||||
{
|
||||
bool override = !check_access(u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
|
||||
ChannelInfo *ci = source.ci;
|
||||
bool override = !check_access(source.u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST";
|
||||
|
||||
if (!ci->GetBadWordCount())
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str());
|
||||
source.Reply(_("%s bad words list is empty."), ci->name.c_str());
|
||||
else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
BadwordsListCallback list(u, ci, word);
|
||||
BadwordsListCallback list(source, word);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -113,21 +113,24 @@ class CommandBSBadwords : public Command
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_("Bad words list for %s:\n"
|
||||
" Num Word Type"), ci->name.c_str());
|
||||
|
||||
}
|
||||
|
||||
BadwordsListCallback::DoList(u, ci, i, bw);
|
||||
BadwordsListCallback::DoList(source, i, bw);
|
||||
}
|
||||
|
||||
if (!SentHeader)
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoAdd(User *u, ChannelInfo *ci, const Anope::string &word)
|
||||
CommandReturn DoAdd(CommandSource &source, const Anope::string &word)
|
||||
{
|
||||
ChannelInfo *ci = source.ci;
|
||||
size_t pos = word.rfind(' ');
|
||||
BadWordType type = BW_ANY;
|
||||
Anope::string realword = word;
|
||||
@@ -149,7 +152,7 @@ class CommandBSBadwords : public Command
|
||||
|
||||
if (ci->GetBadWordCount() >= Config->BSBadWordsMax)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_REACHED_LIMIT, Config->BSBadWordsMax);
|
||||
source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -159,26 +162,27 @@ class CommandBSBadwords : public Command
|
||||
|
||||
if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word))))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_ALREADY_EXISTS, bw->word.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << realword;
|
||||
bool override = !check_access(source.u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "ADD " << realword;
|
||||
ci->AddBadWord(realword, type);
|
||||
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_ADDED, realword.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoDelete(User *u, ChannelInfo *ci, const Anope::string &word)
|
||||
CommandReturn DoDelete(CommandSource &source, const Anope::string &word)
|
||||
{
|
||||
ChannelInfo *ci = source.ci;
|
||||
/* Special case: is it a number/list? Only do search if it isn't. */
|
||||
if (!word.empty() && isdigit(word[0]) && word.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
BadwordsDelCallback list(u, ci, this, word);
|
||||
BadwordsDelCallback list(source, this, word);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -196,90 +200,118 @@ class CommandBSBadwords : public Command
|
||||
|
||||
if (i == end)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_NOT_FOUND, word.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 not found on %s bad words list."), word.c_str(), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << badword->word;
|
||||
ci->EraseBadWord(i);
|
||||
bool override = !check_access(source.u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "DEL " << badword->word;
|
||||
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
|
||||
|
||||
ci->EraseBadWord(i);
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoClear(User *u, ChannelInfo *ci)
|
||||
CommandReturn DoClear(CommandSource &source)
|
||||
{
|
||||
bool override = !check_access(u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
|
||||
ChannelInfo *ci = source.ci;
|
||||
bool override = !check_access(source.u, ci, CA_BADWORDS);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "CLEAR";
|
||||
|
||||
ci->ClearBadWords();
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_CLEAR);
|
||||
source.Reply(_("Bad words list is now empty."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
public:
|
||||
CommandBSBadwords() : Command("BADWORDS", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Maintains bad words list"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string cmd = params[1];
|
||||
Anope::string word = params.size() > 2 ? params[2] : "";
|
||||
ChannelInfo *ci;
|
||||
const Anope::string &cmd = params[1];
|
||||
const Anope::string &word = params.size() > 2 ? params[2] : "";
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
bool need_args = cmd.equals_ci("LIST") || cmd.equals_ci("CLEAR");
|
||||
|
||||
if (!need_args && word.empty())
|
||||
{
|
||||
this->OnSyntaxError(u, cmd);
|
||||
this->OnSyntaxError(source, cmd);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
ci = cs_findchan(chan);
|
||||
|
||||
if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->Account()->HasPriv("botserv/administration")))
|
||||
if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BADWORDS_DISABLED);
|
||||
source.Reply(_("Sorry, channel bad words list modification is temporarily disabled."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (cmd.equals_ci("ADD"))
|
||||
return this->DoAdd(u, ci, word);
|
||||
return this->DoAdd(source, word);
|
||||
else if (cmd.equals_ci("DEL"))
|
||||
return this->DoDelete(u, ci, word);
|
||||
return this->DoDelete(source, word);
|
||||
else if (cmd.equals_ci("LIST"))
|
||||
return this->DoList(u, ci, word);
|
||||
return this->DoList(source, word);
|
||||
else if (cmd.equals_ci("CLEAR"))
|
||||
return this->DoClear(u, ci);
|
||||
return this->DoClear(source);
|
||||
else
|
||||
this->OnSyntaxError(u, "");
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_BADWORDS);
|
||||
source.Reply(_("Syntax: \002BADWORDS \037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]\002\n"
|
||||
" \002BADWORDS \037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}\002\n"
|
||||
" \002BADWORDS \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
|
||||
" \002BADWORDS \037channel\037 CLEAR\002\n"
|
||||
" \n"
|
||||
"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 BADWORDS\002.\n"
|
||||
" \n"
|
||||
"The \002BADWORDS ADD\002 command adds the given word to the\n"
|
||||
"badword list. If SINGLE is specified, a kick will be\n"
|
||||
"done only if a user says the entire word. If START is \n"
|
||||
"specified, a kick will be done if a user says a word\n"
|
||||
"that starts with \037word\037. If END is specified, a kick\n"
|
||||
"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->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
source.Reply(_("The \002BADWORDS DEL\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"
|
||||
" \n"
|
||||
"The \002BADWORDS LIST\002 command displays the bad words list. If\n"
|
||||
"a wildcard mask is given, only those entries matching the\n"
|
||||
"mask are displayed. If a list of entry numbers is given,\n"
|
||||
"only those entries are shown; for example:\n"
|
||||
" \002BADWORDS #channel LIST 2-5,7-9\002\n"
|
||||
" Lists bad words entries numbered 2 through 5 and\n"
|
||||
" 7 through 9.\n"
|
||||
" \n"
|
||||
"The \002BADWORDS CLEAR\002 command clears all entries of the\n"
|
||||
"bad words list."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_BADWORDS);
|
||||
SyntaxError(source, "BADWORDS", _("BADWORDS \037channel\037 {ADD|DEL|LIST|CLEAR} [\037word\037 | \037entry-list\037] [SINGLE|START|END]"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+93
-80
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -16,70 +16,70 @@
|
||||
class CommandBSBot : public Command
|
||||
{
|
||||
private:
|
||||
CommandReturn DoAdd(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string nick = params[1];
|
||||
Anope::string user = params[2];
|
||||
Anope::string host = params[3];
|
||||
Anope::string real = params[4];
|
||||
const Anope::string &nick = params[1];
|
||||
const Anope::string &user = params[2];
|
||||
const Anope::string &host = params[3];
|
||||
const Anope::string &real = params[4];
|
||||
BotInfo *bi;
|
||||
|
||||
if (findbot(nick))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BOT_ALREADY_EXISTS, nick.c_str());
|
||||
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (nick.length() > Config->NickLen)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (user.length() > Config->UserLen)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_LONG_IDENT, Config->UserLen);
|
||||
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (host.length() > Config->HostLen)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_LONG_HOST, Config->HostLen);
|
||||
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
/* Check the nick is valid re RFC 2812 */
|
||||
if (isdigit(nick[0]) || nick[0] == '-')
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
|
||||
if (!isvalidnick(nick[i]))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
/* check for hardcored ircd forbidden nicks */
|
||||
if (!ircdproto->IsNickValid(nick))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
/* Check the host is valid re RFC 2812 */
|
||||
if (!isValidHost(host, 3))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_HOST);
|
||||
source.Reply(_("Bot Hosts may only contain valid host characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i)
|
||||
if (!isalnum(user[i]))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_IDENT, Config->UserLen);
|
||||
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -89,73 +89,73 @@ class CommandBSBot : public Command
|
||||
*/
|
||||
if (findnick(nick))
|
||||
{
|
||||
u->SendMessage(BotServ, NICK_ALREADY_REGISTERED, nick.c_str());
|
||||
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!(bi = new BotInfo(nick, user, host, real)))
|
||||
{
|
||||
// XXX this cant happen?
|
||||
u->SendMessage(BotServ, BOT_BOT_CREATION_FAILED);
|
||||
source.Reply(_("Sorry, bot creation failed."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
Log(LOG_ADMIN, u, this) << "ADD " << bi->GetMask() << " " << bi->realname;
|
||||
Log(LOG_ADMIN, source.u, this) << "ADD " << bi->GetMask() << " " << bi->realname;
|
||||
|
||||
u->SendMessage(BotServ, BOT_BOT_ADDED, bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
|
||||
source.Reply(_("%s!%s@%s (%s) added to the bot list."), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
|
||||
|
||||
FOREACH_MOD(I_OnBotCreate, OnBotCreate(bi));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoChange(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoChange(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string oldnick = params[1];
|
||||
Anope::string nick = params.size() > 2 ? params[2] : "";
|
||||
Anope::string user = params.size() > 3 ? params[3] : "";
|
||||
Anope::string host = params.size() > 4 ? params[4] : "";
|
||||
Anope::string real = params.size() > 5 ? params[5] : "";
|
||||
const Anope::string &oldnick = params[1];
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
const Anope::string &user = params.size() > 3 ? params[3] : "";
|
||||
const Anope::string &host = params.size() > 4 ? params[4] : "";
|
||||
const Anope::string &real = params.size() > 5 ? params[5] : "";
|
||||
BotInfo *bi;
|
||||
|
||||
if (oldnick.empty() || nick.empty())
|
||||
{
|
||||
this->OnSyntaxError(u, "CHANGE");
|
||||
this->OnSyntaxError(source, "CHANGE");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!(bi = findbot(oldnick)))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, oldnick.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!oldnick.equals_ci(nick) && nickIsServices(oldnick, false))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, oldnick.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (nick.length() > Config->NickLen)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!user.empty() && user.length() > Config->UserLen)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_LONG_IDENT, Config->UserLen);
|
||||
source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!host.empty() && host.length() > Config->HostLen)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_LONG_HOST, Config->HostLen);
|
||||
source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!oldnick.equals_ci(nick) && nickIsServices(nick, false))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, oldnick.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), oldnick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -166,34 +166,34 @@ class CommandBSBot : public Command
|
||||
*/
|
||||
if (nick.equals_cs(bi->nick) && (!user.empty() ? user.equals_cs(bi->GetIdent()) : 1) && (!host.empty() ? host.equals_cs(bi->host) : 1) && (!real.empty() ? real.equals_cs(bi->realname) : 1))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BOT_ANY_CHANGES);
|
||||
source.Reply(_("Old info is equal to the new one."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
/* Check the nick is valid re RFC 2812 */
|
||||
if (isdigit(nick[0]) || nick[0] == '-')
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, end = nick.length(); i < end && i < Config->NickLen; ++i)
|
||||
if (!isvalidnick(nick[i]))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
/* check for hardcored ircd forbidden nicks */
|
||||
if (!ircdproto->IsNickValid(nick))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_NICK);
|
||||
source.Reply(_("Bot Nicks may only contain valid nick characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!host.empty() && !isValidHost(host, 3))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_HOST);
|
||||
source.Reply(_("Bot Hosts may only contain valid host characters."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -201,13 +201,13 @@ class CommandBSBot : public Command
|
||||
for (unsigned i = 0, end = user.length(); i < end && i < Config->UserLen; ++i)
|
||||
if (!isalnum(user[i]))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BAD_IDENT, Config->UserLen);
|
||||
source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!nick.equals_ci(bi->nick) && findbot(nick))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BOT_ALREADY_EXISTS, nick.c_str());
|
||||
source.Reply(_("Bot \002%s\002 already exists."), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ class CommandBSBot : public Command
|
||||
*/
|
||||
if (findnick(nick))
|
||||
{
|
||||
u->SendMessage(BotServ, NICK_ALREADY_REGISTERED, nick.c_str());
|
||||
source.Reply(_(NICK_ALREADY_REGISTERED), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ class CommandBSBot : public Command
|
||||
{
|
||||
ircdproto->SendChangeBotNick(bi, nick);
|
||||
XLine x(bi->nick, "Reserved for services");
|
||||
ircdproto->SendSQLine(&x);
|
||||
ircdproto->SendSQLine(NULL, &x);
|
||||
}
|
||||
|
||||
if (!nick.equals_cs(bi->nick))
|
||||
@@ -258,80 +258,78 @@ class CommandBSBot : public Command
|
||||
{
|
||||
ircdproto->SendClientIntroduction(bi, ircd->pseudoclient_mode);
|
||||
XLine x(bi->nick, "Reserved for services");
|
||||
ircdproto->SendSQLine(&x);
|
||||
ircdproto->SendSQLine(NULL, &x);
|
||||
bi->RejoinAll();
|
||||
}
|
||||
|
||||
u->SendMessage(BotServ, BOT_BOT_CHANGED, oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
|
||||
Log(LOG_ADMIN, u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
|
||||
source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)"), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
|
||||
Log(LOG_ADMIN, source.u, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname;
|
||||
|
||||
FOREACH_MOD(I_OnBotChange, OnBotChange(bi));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoDel(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string nick = params[1];
|
||||
const Anope::string &nick = params[1];
|
||||
BotInfo *bi;
|
||||
|
||||
if (nick.empty())
|
||||
{
|
||||
this->OnSyntaxError(u, "DEL");
|
||||
this->OnSyntaxError(source, "DEL");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!(bi = findbot(nick)))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, nick.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (nickIsServices(nick, false))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, nick.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi));
|
||||
|
||||
ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick.c_str());
|
||||
XLine x(bi->nick);
|
||||
ircdproto->SendSQLineDel(&x);
|
||||
|
||||
Log(LOG_ADMIN, u, this) << "DEL " << bi->nick;
|
||||
Log(LOG_ADMIN, source.u, this) << "DEL " << bi->nick;
|
||||
|
||||
source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str());
|
||||
delete bi;
|
||||
u->SendMessage(BotServ, BOT_BOT_DELETED, nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
public:
|
||||
CommandBSBot() : Command("BOT", 1, 6)
|
||||
{
|
||||
this->SetFlag(CFLAG_STRIP_CHANNEL);
|
||||
this->SetDesc(_("Maintains network bot list"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string cmd = params[0];
|
||||
const Anope::string &cmd = params[0];
|
||||
User *u = source.u;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BOT_READONLY);
|
||||
source.Reply(_("Sorry, bot modification is temporarily disabled."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (cmd.equals_ci("ADD"))
|
||||
{
|
||||
// ADD nick user host real - 5
|
||||
if (!u->Account()->HasCommand("botserv/bot/add"))
|
||||
if (!u->HasCommand("botserv/bot/add"))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (params.size() < 5)
|
||||
{
|
||||
this->OnSyntaxError(u, "ADD");
|
||||
this->OnSyntaxError(source, "ADD");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -340,63 +338,78 @@ class CommandBSBot : public Command
|
||||
if (tempparams.size() >= 6)
|
||||
tempparams[4] = tempparams[4] + " " + tempparams[5];
|
||||
|
||||
return this->DoAdd(u, tempparams);
|
||||
return this->DoAdd(source, tempparams);
|
||||
}
|
||||
else if (cmd.equals_ci("CHANGE"))
|
||||
{
|
||||
// CHANGE oldn newn user host real - 6
|
||||
// but only oldn and newn are required
|
||||
if (!u->Account()->HasCommand("botserv/bot/change"))
|
||||
if (!u->HasCommand("botserv/bot/change"))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (params.size() < 3)
|
||||
{
|
||||
this->OnSyntaxError(u, "CHANGE");
|
||||
this->OnSyntaxError(source, "CHANGE");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
return this->DoChange(u, params);
|
||||
return this->DoChange(source, params);
|
||||
}
|
||||
else if (cmd.equals_ci("DEL"))
|
||||
{
|
||||
// DEL nick
|
||||
if (!u->Account()->HasCommand("botserv/bot/del"))
|
||||
if (!u->HasCommand("botserv/bot/del"))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (params.size() < 1)
|
||||
{
|
||||
this->OnSyntaxError(u, "DEL");
|
||||
this->OnSyntaxError(source, "DEL");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
return this->DoDel(u, params);
|
||||
return this->DoDel(source, params);
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(u, "");
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_BOT);
|
||||
source.Reply(_("Syntax: \002BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\002\n"
|
||||
" \002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n"
|
||||
" \002BOT DEL \037nick\037\002\n"
|
||||
" \n"
|
||||
"Allows Services Operators to create, modify, and delete\n"
|
||||
"bots that users will be able to use on their own\n"
|
||||
"channels.\n"
|
||||
" \n"
|
||||
"\002BOT ADD\002 adds a bot with the given nickname, username,\n"
|
||||
"hostname and realname. Since no integrity checks are done \n"
|
||||
"for these settings, be really careful.\n"
|
||||
"\002BOT CHANGE\002 allows to change nickname, username, hostname\n"
|
||||
"or realname of a bot without actually delete it (and all\n"
|
||||
"the data associated with it).\n"
|
||||
"\002BOT DEL\002 removes the given bot from the bot list. \n"
|
||||
" \n"
|
||||
"\002Note\002: you cannot create a bot that has a nick that is\n"
|
||||
"currently registered. If an unregistered user is currently\n"
|
||||
"using the nick, they will be killed."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "BOT", BOT_BOT_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_BOT);
|
||||
SyntaxError(source, "BOT", _("BOT ADD \037nick\037 \037user\037 \037host\037 \037real\037\n"
|
||||
"\002BOT CHANGE \037oldnick\037 \037newnick\037 [\037user\037 [\037host\037 [\037real\037]]]\002\n"
|
||||
"\002BOT DEL \037nick\037\002"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+18
-24
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,65 +18,59 @@ class CommandBSBotList : public Command
|
||||
public:
|
||||
CommandBSBotList() : Command("BOTLIST", 0, 0)
|
||||
{
|
||||
this->SetDesc(_("Lists available bots"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
unsigned count = 0;
|
||||
|
||||
if (BotListByNick.empty())
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BOTLIST_EMPTY);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
for (botinfo_map::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
|
||||
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
|
||||
{
|
||||
BotInfo *bi = it->second;
|
||||
|
||||
if (!bi->HasFlag(BI_PRIVATE))
|
||||
{
|
||||
if (!count)
|
||||
u->SendMessage(BotServ, BOT_BOTLIST_HEADER);
|
||||
source.Reply(_("Bot list:"));
|
||||
++count;
|
||||
u->SendMessage(Config->s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
|
||||
source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size())
|
||||
if (u->HasCommand("botserv/botlist") && count < BotListByNick.size())
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_BOTLIST_PRIVATE_HEADER);
|
||||
source.Reply(_("Bots reserved to IRC operators:"));
|
||||
|
||||
for (botinfo_map::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
|
||||
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
|
||||
{
|
||||
BotInfo *bi = it->second;
|
||||
|
||||
if (bi->HasFlag(BI_PRIVATE))
|
||||
{
|
||||
u->SendMessage(Config->s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
|
||||
source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!count)
|
||||
u->SendMessage(BotServ, BOT_BOTLIST_EMPTY);
|
||||
source.Reply(_("There are no bots available at this time.\n"
|
||||
"Ask a Services Operator to create one!"));
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_BOTLIST_FOOTER, count);
|
||||
source.Reply(_("%d bots available."), count);
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_BOTLIST);
|
||||
source.Reply(_("Syntax: \002BOTLIST\002\n"
|
||||
" \n"
|
||||
"Lists all available bots on this network."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_BOTLIST);
|
||||
}
|
||||
};
|
||||
|
||||
class BSBotList : public Module
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -20,22 +20,35 @@ class CommandBSHelp : public Command
|
||||
{
|
||||
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
|
||||
this->SetFlag(CFLAG_STRIP_CHANNEL);
|
||||
this->SetDesc(_("Displays this list and give information about commands"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
mod_help_cmd(findbot(Config->s_BotServ), u, params[0]);
|
||||
mod_help_cmd(BotServ, source.u, NULL, params[0]);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
// Abuse syntax error to display general list help.
|
||||
u->SendMessage(BotServ, BOT_HELP);
|
||||
User *u = source.u;
|
||||
source.Reply(_("\002%s\002 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 \002%s%s \037command\037\002. For\n"
|
||||
"more information on a specific command, type\n"
|
||||
"\002%s%s HELP \037command\037\002."),
|
||||
BotServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str(),
|
||||
Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
for (CommandMap::const_iterator it = BotServ->Commands.begin(), it_end = BotServ->Commands.end(); it != it_end; ++it)
|
||||
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission)))
|
||||
it->second->OnServHelp(u);
|
||||
u->SendMessage(BotServ, BOT_HELP_FOOTER, Config->BSMinUsers);
|
||||
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
|
||||
it->second->OnServHelp(source);
|
||||
source.Reply(_("Bot will join a channel whenever there is at least\n"
|
||||
"\002%d\002 user(s) on it. Additionally, all %s commands\n"
|
||||
"can be used if fantasy is enabled by prefixing the command\n"
|
||||
"name with a %c."), Config->BSMinUsers, Config->s_ChanServ.c_str(), Config->BSFantasyCharacter[0]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+92
-73
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -17,7 +17,7 @@
|
||||
class CommandBSInfo : public Command
|
||||
{
|
||||
private:
|
||||
void send_bot_channels(User *u, BotInfo *bi)
|
||||
void send_bot_channels(CommandSource &source, BotInfo *bi)
|
||||
{
|
||||
Anope::string buf;
|
||||
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
|
||||
@@ -28,7 +28,7 @@ class CommandBSInfo : public Command
|
||||
{
|
||||
if (buf.length() + ci->name.length() > 300)
|
||||
{
|
||||
u->SendMessage(Config->s_BotServ, "%s", buf.c_str());
|
||||
source.Reply("%s", buf.c_str());
|
||||
buf.clear();
|
||||
}
|
||||
buf += " " + ci->name + " ";
|
||||
@@ -36,185 +36,204 @@ class CommandBSInfo : public Command
|
||||
}
|
||||
|
||||
if (!buf.empty())
|
||||
u->SendMessage(Config->s_BotServ, "%s", buf.c_str());
|
||||
source.Reply("%s", buf.c_str());
|
||||
return;
|
||||
}
|
||||
public:
|
||||
CommandBSInfo() : Command("INFO", 1, 1)
|
||||
{
|
||||
this->SetFlag(CFLAG_STRIP_CHANNEL);
|
||||
this->SetDesc(_("Allows you to see BotServ information about a channel or a bot"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
BotInfo *bi;
|
||||
ChannelInfo *ci;
|
||||
Anope::string query = params[0];
|
||||
const Anope::string &query = params[0];
|
||||
|
||||
int need_comma = 0;
|
||||
bool need_comma = false;
|
||||
char buf[BUFSIZE], *end;
|
||||
|
||||
if ((bi = findbot(query)))
|
||||
User *u = source.u;
|
||||
BotInfo *bi = findbot(query);
|
||||
ChannelInfo *ci;
|
||||
if (bi)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_INFO_BOT_HEADER, bi->nick.c_str());
|
||||
u->SendMessage(BotServ, BOT_INFO_BOT_MASK, bi->GetIdent().c_str(), bi->host.c_str());
|
||||
u->SendMessage(BotServ, BOT_INFO_BOT_REALNAME, bi->realname.c_str());
|
||||
u->SendMessage(BotServ, BOT_INFO_BOT_CREATED, do_strftime(bi->created).c_str());
|
||||
u->SendMessage(BotServ, BOT_INFO_BOT_OPTIONS, GetString(u, (bi->HasFlag(BI_PRIVATE) ? NICK_INFO_OPT_PRIVATE : NICK_INFO_OPT_NONE)).c_str());
|
||||
u->SendMessage(BotServ, BOT_INFO_BOT_USAGE, bi->chancount);
|
||||
source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
|
||||
source.Reply(_(" Mask : %s@%s"), bi->GetIdent().c_str(), bi->host.c_str());
|
||||
source.Reply(_(" Real name : %s"), bi->realname.c_str());
|
||||
source.Reply(_(" Created : %s"), do_strftime(bi->created).c_str());
|
||||
source.Reply(_(" Options : %s"), bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None"));
|
||||
source.Reply(_(" Used on : %d channel(s)"), bi->chancount);
|
||||
|
||||
if (u->Account()->HasPriv("botserv/administration"))
|
||||
this->send_bot_channels(u, bi);
|
||||
if (u->HasPriv("botserv/administration"))
|
||||
this->send_bot_channels(source, bi);
|
||||
}
|
||||
else if ((ci = cs_findchan(query)))
|
||||
{
|
||||
if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration"))
|
||||
if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("botserv/administration"))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
u->SendMessage(BotServ, CHAN_INFO_HEADER, ci->name.c_str());
|
||||
source.Reply(_(CHAN_INFO_HEADER), ci->name.c_str());
|
||||
if (ci->bi)
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_BOT, ci->bi->nick.c_str());
|
||||
source.Reply(_(" Bot nick : %s"), ci->bi->nick.c_str());
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_BOT_NONE);
|
||||
source.Reply(_(" Bot nick : not assigned yet."));
|
||||
|
||||
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
|
||||
{
|
||||
if (ci->ttb[TTB_BADWORDS])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BADWORDS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_BADWORDS]);
|
||||
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BADWORDS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BADWORDS, GetString(u, BOT_INFO_ACTIVE).c_str());
|
||||
source.Reply(_(" Bad words kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BADWORDS, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Bad words kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_BOLDS))
|
||||
{
|
||||
if (ci->ttb[TTB_BOLDS])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BOLDS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_BOLDS]);
|
||||
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_BOLDS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BOLDS, GetString(u, BOT_INFO_ACTIVE).c_str());
|
||||
source.Reply(_(" Bolds kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_BOLDS, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Bolds kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_CAPS))
|
||||
{
|
||||
if (ci->ttb[TTB_CAPS])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_CAPS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
|
||||
source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), _(ENABLED), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_CAPS_ON, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->capsmin, ci->capspercent);
|
||||
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), _(ENABLED), ci->capsmin, ci->capspercent);
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_CAPS_OFF, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Caps kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_COLORS))
|
||||
{
|
||||
if (ci->ttb[TTB_COLORS])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_COLORS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_COLORS]);
|
||||
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_COLORS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_COLORS, GetString(u, BOT_INFO_ACTIVE).c_str());
|
||||
source.Reply(_(" Colors kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_COLORS, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Colors kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
|
||||
{
|
||||
if (ci->ttb[TTB_FLOOD])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_FLOOD_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
|
||||
source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), _(ENABLED), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_FLOOD_ON, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->floodlines, ci->floodsecs);
|
||||
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), _(ENABLED), ci->floodlines, ci->floodsecs);
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_FLOOD_OFF, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Flood kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
|
||||
{
|
||||
if (ci->ttb[TTB_REPEAT])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REPEAT_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_REPEAT], ci->repeattimes);
|
||||
source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), _(ENABLED), ci->ttb[TTB_REPEAT], ci->repeattimes);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REPEAT_ON, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->repeattimes);
|
||||
source.Reply(_(" Repeat kicker : %s (%d times)"), _(ENABLED), ci->repeattimes);
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REPEAT_OFF, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Repeat kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_REVERSES))
|
||||
{
|
||||
if (ci->ttb[TTB_REVERSES])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REVERSES_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_REVERSES]);
|
||||
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_REVERSES]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REVERSES, GetString(u, BOT_INFO_ACTIVE).c_str());
|
||||
source.Reply(_(" Reverses kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_REVERSES, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Reverses kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES))
|
||||
{
|
||||
if (ci->ttb[TTB_UNDERLINES])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_UNDERLINES_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_UNDERLINES]);
|
||||
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_UNDERLINES]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_UNDERLINES, GetString(u, BOT_INFO_ACTIVE).c_str());
|
||||
source.Reply(_(" Underlines kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_UNDERLINES, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Underlines kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_ITALICS))
|
||||
{
|
||||
if (ci->ttb[TTB_ITALICS])
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_ITALICS_BAN, GetString(u, BOT_INFO_ACTIVE).c_str(), ci->ttb[TTB_ITALICS]);
|
||||
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_ITALICS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_ITALICS, GetString(u, BOT_INFO_ACTIVE).c_str());
|
||||
source.Reply(_(" Italics kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_KICK_ITALICS, GetString(u, BOT_INFO_INACTIVE).c_str());
|
||||
source.Reply(_(" Italics kicker : %s"), _(DISABLED));
|
||||
if (ci->botflags.HasFlag(BS_KICK_AMSGS))
|
||||
{
|
||||
if (ci->ttb[TTB_AMSGS])
|
||||
source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), _(ENABLED), ci->ttb[TTB_AMSGS]);
|
||||
else
|
||||
source.Reply(_(" AMSG kicker : %s"), _(ENABLED));
|
||||
}
|
||||
else
|
||||
source.Reply(_(" AMSG kicker : %s"), _(DISABLED));
|
||||
|
||||
if (ci->botflags.HasFlag(BS_MSG_PRIVMSG))
|
||||
source.Reply(_(" Fantasy reply : %s"), "PRIVMSG");
|
||||
else if (ci->botflags.HasFlag(BS_MSG_NOTICE))
|
||||
source.Reply(_(" Fantasy reply : %s"), "NOTICE");
|
||||
else if (ci->botflags.HasFlag(BS_MSG_NOTICEOPS))
|
||||
source.Reply(_(" Fantasy reply : %s"), "NOTICEOPS");
|
||||
|
||||
end = buf;
|
||||
*end = 0;
|
||||
if (ci->botflags.HasFlag(BS_DONTKICKOPS))
|
||||
{
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s", GetString(u, BOT_INFO_OPT_DONTKICKOPS).c_str());
|
||||
need_comma = 1;
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s", _("Ops protection"));
|
||||
need_comma = true;
|
||||
}
|
||||
if (ci->botflags.HasFlag(BS_DONTKICKVOICES))
|
||||
{
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_DONTKICKVOICES).c_str());
|
||||
need_comma = 1;
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Voices protection"));
|
||||
need_comma = true;
|
||||
}
|
||||
if (ci->botflags.HasFlag(BS_FANTASY))
|
||||
{
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_FANTASY).c_str());
|
||||
need_comma = 1;
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Fantasy"));
|
||||
need_comma = true;
|
||||
}
|
||||
if (ci->botflags.HasFlag(BS_GREET))
|
||||
{
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_GREET).c_str());
|
||||
need_comma = 1;
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Greet"));
|
||||
need_comma = true;
|
||||
}
|
||||
if (ci->botflags.HasFlag(BS_NOBOT))
|
||||
{
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_NOBOT).c_str());
|
||||
need_comma = 1;
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("No bot"));
|
||||
need_comma = true;
|
||||
}
|
||||
if (ci->botflags.HasFlag(BS_SYMBIOSIS))
|
||||
{
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", GetString(u, BOT_INFO_OPT_SYMBIOSIS).c_str());
|
||||
need_comma = 1;
|
||||
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Symbiosis"));
|
||||
need_comma = true;
|
||||
}
|
||||
u->SendMessage(BotServ, BOT_INFO_CHAN_OPTIONS, *buf ? buf : GetString(u, BOT_INFO_OPT_NONE).c_str());
|
||||
source.Reply(_(" Options : %s"), *buf ? buf : _("None"));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_INFO_NOT_FOUND, query.c_str());
|
||||
source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_INFO);
|
||||
source.Reply(_("Syntax: \002INFO {\037chan\037 | \037nick\037}\002\n"
|
||||
" \n"
|
||||
"Allows you to see %s information about a channel or a bot.\n"
|
||||
"If the parameter is a channel, then you'll get information\n"
|
||||
"such as enabled kickers. If the parameter is a nick,\n"
|
||||
"you'll get information about a bot, such as creation\n"
|
||||
"time or number of channels it is on."), NickServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "INFO", BOT_INFO_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_INFO);
|
||||
SyntaxError(source, "INFO", _("INFO {\037chan\037 | \037nick\037}"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+329
-127
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -19,27 +19,29 @@ class CommandBSKick : public Command
|
||||
public:
|
||||
CommandBSKick() : Command("KICK", 3, 6)
|
||||
{
|
||||
this->SetDesc(_("Configures kickers"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string option = params[1];
|
||||
Anope::string value = params[2];
|
||||
Anope::string ttb = params.size() > 3 ? params[3] : "";
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &option = params[1];
|
||||
const Anope::string &value = params[2];
|
||||
const Anope::string &ttb = params.size() > 3 ? params[3] : "";
|
||||
|
||||
ChannelInfo *ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (readonly)
|
||||
u->SendMessage(BotServ, BOT_KICK_DISABLED);
|
||||
source.Reply(_("Sorry, kicker configuration is temporarily disabled."));
|
||||
else if (chan.empty() || option.empty() || value.empty())
|
||||
SyntaxError(BotServ, u, "KICK", BOT_KICK_SYNTAX);
|
||||
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
|
||||
else if (!value.equals_ci("ON") && !value.equals_ci("OFF"))
|
||||
SyntaxError(BotServ, u, "KICK", BOT_KICK_SYNTAX);
|
||||
else if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration"))
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
|
||||
else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!ci->bi)
|
||||
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
|
||||
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
else
|
||||
{
|
||||
bool override = !check_access(u, ci, CA_SET);
|
||||
@@ -51,31 +53,36 @@ class CommandBSKick : public Command
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_BADWORDS] = convertTo<int16>(ttb, error, false);
|
||||
/* Only error if errno returns ERANGE or EINVAL or we are less then 0 - TSL */
|
||||
if (!error.empty() || ci->ttb[TTB_BADWORDS] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_BADWORDS] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_BADWORDS] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
/* leaving the debug behind since we might want to know what these are */
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BADWORDS];
|
||||
/* reset the value back to 0 - TSL */
|
||||
ci->ttb[TTB_BADWORDS] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_BADWORDS] = 0;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_BADWORDS);
|
||||
if (ci->ttb[TTB_BADWORDS])
|
||||
u->SendMessage(BotServ, BOT_KICK_BADWORDS_ON_BAN, ci->ttb[TTB_BADWORDS]);
|
||||
source.Reply(_("Bot will now kick \002bad words\002, and will place a ban after \n"
|
||||
"%d kicks for the same user. Use the BADWORDS command\n"
|
||||
"to add or remove a bad word."), ci->ttb[TTB_BADWORDS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_BADWORDS_ON);
|
||||
source.Reply(_("Bot will now kick \002bad words\002. Use the BADWORDS command\n"
|
||||
"to add or remove a bad word."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_BADWORDS);
|
||||
u->SendMessage(BotServ, BOT_KICK_BADWORDS_OFF);
|
||||
source.Reply(_("Bot won't kick \002bad words\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("BOLDS"))
|
||||
@@ -84,13 +91,16 @@ class CommandBSKick : public Command
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_BOLDS] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_BOLDS] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_BOLDS] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_BOLDS] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_BOLDS];
|
||||
ci->ttb[TTB_BOLDS] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
@@ -98,14 +108,14 @@ class CommandBSKick : public Command
|
||||
ci->ttb[TTB_BOLDS] = 0;
|
||||
ci->botflags.SetFlag(BS_KICK_BOLDS);
|
||||
if (ci->ttb[TTB_BOLDS])
|
||||
u->SendMessage(BotServ, BOT_KICK_BOLDS_ON_BAN, ci->ttb[TTB_BOLDS]);
|
||||
source.Reply(_("Bot will now kick \002bolds\002, and will place a ban after\n%d kicks to the same user."), ci->ttb[TTB_BOLDS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_BOLDS_ON);
|
||||
source.Reply(_("Bot will now kick \002bolds\002."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_BOLDS);
|
||||
u->SendMessage(BotServ, BOT_KICK_BOLDS_OFF);
|
||||
source.Reply(_("Bot won't kick \002bolds\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("CAPS"))
|
||||
@@ -117,43 +127,53 @@ class CommandBSKick : public Command
|
||||
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_CAPS] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_CAPS] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_CAPS] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_CAPS] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_CAPS];
|
||||
ci->ttb[TTB_CAPS] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_CAPS] = 0;
|
||||
|
||||
if (min.empty())
|
||||
ci->capsmin = 10;
|
||||
else
|
||||
ci->capsmin = min.is_number_only() ? convertTo<int16>(min) : 10;
|
||||
ci->capsmin = 10;
|
||||
try
|
||||
{
|
||||
ci->capsmin = convertTo<int16>(min);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
if (ci->capsmin < 1)
|
||||
ci->capsmin = 10;
|
||||
|
||||
if (percent.empty())
|
||||
ci->capspercent = 25;
|
||||
else
|
||||
ci->capspercent = percent.is_number_only() ? convertTo<int16>(percent) : 25;
|
||||
ci->capspercent = 25;
|
||||
try
|
||||
{
|
||||
ci->capspercent = convertTo<int16>(percent);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
if (ci->capspercent < 1 || ci->capspercent > 100)
|
||||
ci->capspercent = 25;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_CAPS);
|
||||
if (ci->ttb[TTB_CAPS])
|
||||
u->SendMessage(BotServ, BOT_KICK_CAPS_ON_BAN, ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]);
|
||||
source.Reply(_("Bot will now kick \002caps\002 (they must constitute at least\n"
|
||||
"%d characters and %d%% of the entire message), and will \n"
|
||||
"place a ban after %d kicks for the same user."), ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_CAPS_ON, ci->capsmin, ci->capspercent);
|
||||
source.Reply(_("Bot will now kick \002caps\002 (they must constitute at least\n"
|
||||
"%d characters and %d%% of the entire message)."), ci->capsmin, ci->capspercent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_CAPS);
|
||||
u->SendMessage(BotServ, BOT_KICK_CAPS_OFF);
|
||||
source.Reply(_("Bot won't kick \002caps\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("COLORS"))
|
||||
@@ -162,28 +182,32 @@ class CommandBSKick : public Command
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_COLORS] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_COLORS] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_COLORS] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_COLORS] < 1)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_COLORS];
|
||||
ci->ttb[TTB_COLORS] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_COLORS] = 0;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_COLORS);
|
||||
if (ci->ttb[TTB_COLORS])
|
||||
u->SendMessage(BotServ, BOT_KICK_COLORS_ON_BAN, ci->ttb[TTB_COLORS]);
|
||||
source.Reply(_("Bot will now kick \002colors\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_COLORS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_COLORS_ON);
|
||||
source.Reply(_("Bot will now kick \002colors\002."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_COLORS);
|
||||
u->SendMessage(BotServ, BOT_KICK_COLORS_OFF);
|
||||
source.Reply(_("Bot won't kick \002colors\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("FLOOD"))
|
||||
@@ -195,43 +219,52 @@ class CommandBSKick : public Command
|
||||
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_FLOOD] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_FLOOD] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_FLOOD] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_FLOOD] < 1)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_FLOOD];
|
||||
ci->ttb[TTB_FLOOD] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_FLOOD] = 0;
|
||||
|
||||
if (lines.empty())
|
||||
ci->floodlines = 6;
|
||||
else
|
||||
ci->floodlines = lines.is_number_only() ? convertTo<int16>(lines) : 6;
|
||||
ci->floodlines = 6;
|
||||
try
|
||||
{
|
||||
ci->floodlines = convertTo<int16>(lines);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
if (ci->floodlines < 2)
|
||||
ci->floodlines = 6;
|
||||
|
||||
if (secs.empty())
|
||||
ci->floodsecs = 10;
|
||||
else
|
||||
ci->floodsecs = secs.is_number_only() ? convertTo<int16>(secs) : 10;
|
||||
if (ci->floodsecs < 1 || ci->floodsecs > Config->BSKeepData)
|
||||
ci->floodsecs = 10;
|
||||
try
|
||||
{
|
||||
ci->floodsecs = convertTo<int16>(secs);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
if (ci->floodsecs < 1)
|
||||
ci->floodsecs = 10;
|
||||
if (ci->floodsecs > Config->BSKeepData)
|
||||
ci->floodsecs = Config->BSKeepData;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_FLOOD);
|
||||
if (ci->ttb[TTB_FLOOD])
|
||||
u->SendMessage(BotServ, BOT_KICK_FLOOD_ON_BAN, ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]);
|
||||
source.Reply(_("Bot will now kick \002flood\002 (%d lines in %d seconds and\nwill place a ban after %d kicks for the same user."), ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_FLOOD_ON, ci->floodlines, ci->floodsecs);
|
||||
source.Reply(_("Bot will now kick \002flood\002 (%d lines in %d seconds)."), ci->floodlines, ci->floodsecs);
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_FLOOD);
|
||||
u->SendMessage(BotServ, BOT_KICK_FLOOD_OFF);
|
||||
source.Reply(_("Bot won't kick \002flood\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("REPEAT"))
|
||||
@@ -242,36 +275,44 @@ class CommandBSKick : public Command
|
||||
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_REPEAT] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_REPEAT] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_REPEAT] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_REPEAT] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REPEAT];
|
||||
ci->ttb[TTB_REPEAT] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_REPEAT] = 0;
|
||||
|
||||
if (times.empty())
|
||||
ci->repeattimes = 3;
|
||||
else
|
||||
ci->repeattimes = times.is_number_only() ? convertTo<int16>(times) : 3;
|
||||
ci->repeattimes = 3;
|
||||
try
|
||||
{
|
||||
ci->repeattimes = convertTo<int16>(times);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
if (ci->repeattimes < 2)
|
||||
ci->repeattimes = 3;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_REPEAT);
|
||||
if (ci->ttb[TTB_REPEAT])
|
||||
u->SendMessage(BotServ, BOT_KICK_REPEAT_ON_BAN, ci->repeattimes, ci->ttb[TTB_REPEAT]);
|
||||
source.Reply(_("Bot will now kick \002repeats\002 (users that say %d times\n"
|
||||
"the same thing), and will place a ban after %d \n"
|
||||
"kicks for the same user."), ci->repeattimes, ci->ttb[TTB_REPEAT]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_REPEAT_ON, ci->repeattimes);
|
||||
source.Reply(_("Bot will now kick \002repeats\002 (users that say %d times\n"
|
||||
"the same thing)."), ci->repeattimes);
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_REPEAT);
|
||||
u->SendMessage(BotServ, BOT_KICK_REPEAT_OFF);
|
||||
source.Reply(_("Bot won't kick \002repeats\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("REVERSES"))
|
||||
@@ -280,13 +321,16 @@ class CommandBSKick : public Command
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_REVERSES] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_REVERSES] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_REVERSES] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_REVERSES] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_REVERSES];
|
||||
ci->ttb[TTB_REVERSES] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
@@ -294,14 +338,14 @@ class CommandBSKick : public Command
|
||||
ci->ttb[TTB_REVERSES] = 0;
|
||||
ci->botflags.SetFlag(BS_KICK_REVERSES);
|
||||
if (ci->ttb[TTB_REVERSES])
|
||||
u->SendMessage(BotServ, BOT_KICK_REVERSES_ON_BAN, ci->ttb[TTB_REVERSES]);
|
||||
source.Reply(_("Bot will now kick \002reverses\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_REVERSES]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_REVERSES_ON);
|
||||
source.Reply(_("Bot will now kick \002reverses\002."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_REVERSES);
|
||||
u->SendMessage(BotServ, BOT_KICK_REVERSES_OFF);
|
||||
source.Reply(_("Bot won't kick \002reverses\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("UNDERLINES"))
|
||||
@@ -310,28 +354,32 @@ class CommandBSKick : public Command
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_UNDERLINES] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_UNDERLINES] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_UNDERLINES] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_REVERSES] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_UNDERLINES];
|
||||
ci->ttb[TTB_UNDERLINES] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_UNDERLINES] = 0;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_UNDERLINES);
|
||||
if (ci->ttb[TTB_UNDERLINES])
|
||||
u->SendMessage(BotServ, BOT_KICK_UNDERLINES_ON_BAN, ci->ttb[TTB_UNDERLINES]);
|
||||
source.Reply(_("Bot will now kick \002underlines\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_UNDERLINES]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_UNDERLINES_ON);
|
||||
source.Reply(_("Bot will now kick \002underlines\002."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_UNDERLINES);
|
||||
u->SendMessage(BotServ, BOT_KICK_UNDERLINES_OFF);
|
||||
source.Reply(_("Bot won't kick \002underlines\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("ITALICS"))
|
||||
@@ -340,72 +388,192 @@ class CommandBSKick : public Command
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
Anope::string error;
|
||||
ci->ttb[TTB_ITALICS] = convertTo<int16>(ttb, error, false);
|
||||
if (!error.empty() || ci->ttb[TTB_ITALICS] < 0)
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_ITALICS] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_ITALICS] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
Log(LOG_DEBUG) << "remainder of ttb " << error << " ttb " << ci->ttb[TTB_ITALICS];
|
||||
ci->ttb[TTB_ITALICS] = 0;
|
||||
u->SendMessage(BotServ, BOT_KICK_BAD_TTB, ttb.c_str());
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_ITALICS] = 0;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_ITALICS);
|
||||
if (ci->ttb[TTB_ITALICS])
|
||||
u->SendMessage(BotServ, BOT_KICK_ITALICS_ON_BAN, ci->ttb[TTB_ITALICS]);
|
||||
source.Reply(_("Bot will now kick \002italics\002, and will place a ban after\n%d kicks for the same user."), ci->ttb[TTB_ITALICS]);
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_ITALICS_ON);
|
||||
source.Reply(_("Bot will now kick \002italics\002."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_ITALICS);
|
||||
u->SendMessage(BotServ, BOT_KICK_ITALICS_OFF);
|
||||
source.Reply(_("Bot won't kick \002italics\002 anymore."));
|
||||
}
|
||||
}
|
||||
else if (option.equals_ci("AMSGS"))
|
||||
{
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
if (!ttb.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
ci->ttb[TTB_AMSGS] = convertTo<int16>(ttb);
|
||||
if (ci->ttb[TTB_AMSGS] < 0)
|
||||
throw ConvertException();
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
ci->ttb[TTB_AMSGS] = 0;
|
||||
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
else
|
||||
ci->ttb[TTB_AMSGS] = 0;
|
||||
|
||||
ci->botflags.SetFlag(BS_KICK_AMSGS);
|
||||
if (ci->ttb[TTB_AMSGS])
|
||||
source.Reply(_("Bot will now kick for \002amsgs\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_AMSGS]);
|
||||
else
|
||||
source.Reply(_("Bot will now kick for \002amsgs\002"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_KICK_AMSGS);
|
||||
source.Reply(_("Bot won't kick for \002amsgs\002 anymore."));
|
||||
}
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_KICK_UNKNOWN, option.c_str());
|
||||
source.Reply(_(UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
|
||||
}
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
if (subcommand.empty())
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 \037option\037 \037parameters\037\002\n"
|
||||
" \n"
|
||||
"Configures bot kickers. \037option\037 can be one of:\n"
|
||||
" \n"
|
||||
" AMSGS Sets if the bot kicks for amsgs\n"
|
||||
" BOLDS Sets if the bot kicks bolds\n"
|
||||
" BADWORDS Sets if the bot kicks bad words\n"
|
||||
" CAPS Sets if the bot kicks caps\n"
|
||||
" COLORS Sets if the bot kicks colors\n"
|
||||
" FLOOD Sets if the bot kicks flooding users\n"
|
||||
" REPEAT Sets if the bot kicks users who repeat\n"
|
||||
" themselves\n"
|
||||
" REVERSES Sets if the bot kicks reverses\n"
|
||||
" UNDERLINES Sets if the bot kicks underlines\n"
|
||||
" ITALICS Sets if the bot kicks italics\n"
|
||||
" \n"
|
||||
"Type \002%s%s HELP KICK \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->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
else if (subcommand.equals_ci("BADWORDS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_BADWORDS);
|
||||
source.Reply(_("Syntax: \002KICK \037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the bad words kicker on or off. When enabled, this\n"
|
||||
"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"
|
||||
"more information.\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
else if (subcommand.equals_ci("BOLDS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_BOLDS);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 BOLDS {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the bolds kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who use bolds.\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("CAPS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_CAPS);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 CAPS {\037ON|OFF\037} [\037ttb\037 [\037min\037 [\037percent\037]]]\002\n"
|
||||
"Sets the caps kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who are talking in\n"
|
||||
"CAPS.\n"
|
||||
"The bot kicks only if there are at least \002min\002 caps\n"
|
||||
"and they constitute at least \002percent\002%% of the total \n"
|
||||
"text line (if not given, it defaults to 10 characters\n"
|
||||
"and 25%%).\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("COLORS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_COLORS);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 COLORS {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the colors kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who use colors.\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("FLOOD"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_FLOOD);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 FLOOD {\037ON|OFF\037} [\037ttb\037 [\037ln\037 [\037secs\037]]]\002\n"
|
||||
"Sets the flood kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who are flooding\n"
|
||||
"the channel using at least \002ln\002 lines in \002secs\002 seconds\n"
|
||||
"(if not given, it defaults to 6 lines in 10 seconds).\n"
|
||||
" \n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("REPEAT"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_REPEAT);
|
||||
source.Reply(_("Syntax: \002KICK \037#channel\037 REPEAT {\037ON|OFF\037} [\037ttb\037 [\037num\037]]\002\n"
|
||||
"Sets the repeat kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who are repeating\n"
|
||||
"themselves \002num\002 times (if num is not given, it\n"
|
||||
"defaults to 3).\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("REVERSES"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_REVERSES);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 REVERSES {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the reverses kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who use reverses.\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("UNDERLINES"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_UNDERLINES);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 UNDERLINES {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the underlines kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who use underlines.\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("ITALICS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_KICK_ITALICS);
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 ITALICS {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the italics kicker on or off. When enabled, this\n"
|
||||
"option tells the bot to kick users who use italics.\n"
|
||||
"ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else if (subcommand.equals_ci("AMSGS"))
|
||||
source.Reply(_("Syntax: \002KICK \037channel\037 AMSGS {\037ON|OFF\037} [\037ttb\037]\002\n"
|
||||
"Sets the amsg kicker on or off. When enabled, the bot will\n"
|
||||
"kick users who send the same message to multiple channels\n"
|
||||
"where BotServ bots are.\n"
|
||||
"Ttb is the number of times a user can be kicked\n"
|
||||
"before it get banned. Don't give ttb to disable\n"
|
||||
"the ban system once activated."));
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "KICK", BOT_KICK_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_KICK);
|
||||
SyntaxError(source, "KICK", _("KICK \037channel\037 \037option\037 {\037ON|\037} [\037settings\037]"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -420,6 +588,40 @@ class BSKick : public Module
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(BotServ, &commandbskick);
|
||||
|
||||
ModuleManager::Attach(I_OnPrivmsg, this);
|
||||
}
|
||||
|
||||
EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow)
|
||||
{
|
||||
Anope::string m, ch;
|
||||
time_t time;
|
||||
|
||||
if (u->GetExtRegular("bs_kick_lastmsg", m) && u->GetExtRegular("bs_kick_lasttime", time) && u->GetExtRegular("bs_kick_lastchan", ch))
|
||||
{
|
||||
if (time == Anope::CurTime && m == msg && ch != ci->name)
|
||||
{
|
||||
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
|
||||
{
|
||||
Channel *c = (*it)->chan;
|
||||
++it;
|
||||
|
||||
if (c->ci != NULL && c->ci->botflags.HasFlag(BS_KICK_AMSGS))
|
||||
{
|
||||
check_ban(c->ci, u, TTB_AMSGS);
|
||||
bot_kick(c->ci, u, _("Don't use AMSGs!"));
|
||||
}
|
||||
}
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
u->Extend("bs_kick_lastmsg", new ExtensibleItemRegular<Anope::string>(msg));
|
||||
u->Extend("bs_kick_lasttime", new ExtensibleItemRegular<time_t>(Anope::CurTime));
|
||||
u->Extend("bs_kick_lastchan", new ExtensibleItemRegular<Anope::string>(ci->name));
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+16
-20
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,38 +18,37 @@ class CommandBSSay : public Command
|
||||
public:
|
||||
CommandBSSay() : Command("SAY", 2, 2)
|
||||
{
|
||||
this->SetDesc(_("Makes the bot say the given text on the given channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci;
|
||||
const Anope::string &text = params[1];
|
||||
|
||||
Anope::string chan = params[0];
|
||||
Anope::string text = params[1];
|
||||
|
||||
ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (!check_access(u, ci, CA_SAY))
|
||||
{
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!ci->bi)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
|
||||
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!ci->c || !ci->c->FindUser(ci->bi))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_NOT_ON_CHANNEL, ci->name.c_str());
|
||||
source.Reply(_(BOT_NOT_ON_CHANNEL), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (text[0] == '\001')
|
||||
{
|
||||
this->OnSyntaxError(u, "");
|
||||
this->OnSyntaxError(source, "");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -62,20 +61,17 @@ class CommandBSSay : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_SAY);
|
||||
source.Reply(_("Syntax: \002SAY \037channel\037 \037text\037\002\n"
|
||||
" \n"
|
||||
"Makes the bot say the given text on the given channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "SAY", BOT_SAY_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_SAY);
|
||||
SyntaxError(source, "SAY", _("SAY \037channel\037 \037text\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+150
-56
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -19,49 +19,48 @@ class CommandBSSet : public Command
|
||||
CommandBSSet() : Command("SET", 3, 3)
|
||||
{
|
||||
this->SetFlag(CFLAG_STRIP_CHANNEL);
|
||||
this->SetDesc(_("Configures bot options"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string option = params[1];
|
||||
Anope::string value = params[2];
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &option = params[1];
|
||||
const Anope::string &value = params[2];
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_SET_DISABLED);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (u->Account()->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE"))
|
||||
source.Reply(_("Sorry, bot option setting is temporarily disabled."));
|
||||
else if (u->HasCommand("botserv/set/private") && option.equals_ci("PRIVATE"))
|
||||
{
|
||||
BotInfo *bi;
|
||||
|
||||
if (!(bi = findbot(chan)))
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_DOES_NOT_EXIST, chan.c_str());
|
||||
source.Reply(_(BOT_DOES_NOT_EXIST), chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
bi->SetFlag(BI_PRIVATE);
|
||||
u->SendMessage(BotServ, BOT_SET_PRIVATE_ON, bi->nick.c_str());
|
||||
source.Reply(_("Private mode of bot %s is now \002on\002."), bi->nick.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
bi->UnsetFlag(BI_PRIVATE);
|
||||
u->SendMessage(BotServ, BOT_SET_PRIVATE_OFF, bi->nick.c_str());
|
||||
source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET PRIVATE", BOT_SET_PRIVATE_SYNTAX);
|
||||
SyntaxError(source, "SET PRIVATE", _("SET \037botname\037 PRIVATE {\037ON|\037}"));
|
||||
return MOD_CONT;
|
||||
}
|
||||
else if (!(ci = cs_findchan(chan)))
|
||||
u->SendMessage(BotServ, CHAN_X_NOT_REGISTERED, chan.c_str());
|
||||
else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET))
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
|
||||
else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_SET))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else
|
||||
{
|
||||
bool override = !check_access(u, ci, CA_SET);
|
||||
@@ -72,135 +71,230 @@ class CommandBSSet : public Command
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_DONTKICKOPS);
|
||||
u->SendMessage(BotServ, BOT_SET_DONTKICKOPS_ON, ci->name.c_str());
|
||||
source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_DONTKICKOPS);
|
||||
u->SendMessage(BotServ, BOT_SET_DONTKICKOPS_OFF, ci->name.c_str());
|
||||
source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET DONTKICKOPS", BOT_SET_DONTKICKOPS_SYNTAX);
|
||||
SyntaxError(source, "SET DONTKICKOPS", _("SET \037channel\037 DONTKICKOPS {\037ON|\037}"));
|
||||
}
|
||||
else if (option.equals_ci("DONTKICKVOICES"))
|
||||
{
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_DONTKICKVOICES);
|
||||
u->SendMessage(BotServ, BOT_SET_DONTKICKVOICES_ON, ci->name.c_str());
|
||||
source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_DONTKICKVOICES);
|
||||
u->SendMessage(BotServ, BOT_SET_DONTKICKVOICES_OFF, ci->name.c_str());
|
||||
source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET DONTKICKVOICES", BOT_SET_DONTKICKVOICES_SYNTAX);
|
||||
SyntaxError(source, "SET DONTKICKVOICES", _("SET \037channel\037 DONTKICKVOICES {\037ON|\037}"));
|
||||
}
|
||||
else if (option.equals_ci("FANTASY"))
|
||||
{
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_FANTASY);
|
||||
u->SendMessage(BotServ, BOT_SET_FANTASY_ON, ci->name.c_str());
|
||||
source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_FANTASY);
|
||||
u->SendMessage(BotServ, BOT_SET_FANTASY_OFF, ci->name.c_str());
|
||||
source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET FANTASY", BOT_SET_FANTASY_SYNTAX);
|
||||
SyntaxError(source, "SET FANTASY", _("SET \037channel\037 FANTASY {\037ON|\037}"));
|
||||
}
|
||||
else if (option.equals_ci("GREET"))
|
||||
{
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_GREET);
|
||||
u->SendMessage(BotServ, BOT_SET_GREET_ON, ci->name.c_str());
|
||||
source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_GREET);
|
||||
u->SendMessage(BotServ, BOT_SET_GREET_OFF, ci->name.c_str());
|
||||
source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET GREET", BOT_SET_GREET_SYNTAX);
|
||||
SyntaxError(source, "SET GREET", _("SET \037channel\037 GREET {\037ON|\037}"));
|
||||
}
|
||||
else if (u->Account()->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT"))
|
||||
else if (u->HasCommand("botserv/set/nobot") && option.equals_ci("NOBOT"))
|
||||
{
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_NOBOT);
|
||||
if (ci->bi)
|
||||
ci->bi->UnAssign(u, ci);
|
||||
u->SendMessage(BotServ, BOT_SET_NOBOT_ON, ci->name.c_str());
|
||||
source.Reply(_("No Bot mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_NOBOT);
|
||||
u->SendMessage(BotServ, BOT_SET_NOBOT_OFF, ci->name.c_str());
|
||||
source.Reply(_("No Bot mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET NOBOT", BOT_SET_NOBOT_SYNTAX);
|
||||
SyntaxError(source, "SET NOBOT", _("SET \037botname\037 NOBOT {\037ON|\037}"));
|
||||
}
|
||||
else if (option.equals_ci("SYMBIOSIS"))
|
||||
{
|
||||
if (value.equals_ci("ON"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_SYMBIOSIS);
|
||||
u->SendMessage(BotServ, BOT_SET_SYMBIOSIS_ON, ci->name.c_str());
|
||||
source.Reply(_("Symbiosis mode is now \002on\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_SYMBIOSIS);
|
||||
u->SendMessage(BotServ, BOT_SET_SYMBIOSIS_OFF, ci->name.c_str());
|
||||
source.Reply(_("Symbiosis mode is now \002off\002 on channel %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(BotServ, u, "SET SYMBIOSIS", BOT_SET_SYMBIOSIS_SYNTAX);
|
||||
SyntaxError(source, "SET SYMBIOSIS", _("SET \037channel\037 SYMBIOSIS {\037ON|\037}"));
|
||||
}
|
||||
else if (option.equals_ci("MSG"))
|
||||
{
|
||||
if (value.equals_ci("OFF"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
|
||||
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
|
||||
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
|
||||
source.Reply(_("Fantasy replies will no longer be sent to %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("PRIVMSG"))
|
||||
{
|
||||
ci->botflags.SetFlag(BS_MSG_PRIVMSG);
|
||||
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
|
||||
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
|
||||
source.Reply(_("Fantasy replies will be sent via PRIVMSG to %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("NOTICE"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
|
||||
ci->botflags.SetFlag(BS_MSG_NOTICE);
|
||||
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
|
||||
source.Reply(_("Fantasy replies will be sent via NOTICE to %s."), ci->name.c_str());
|
||||
}
|
||||
else if (value.equals_ci("NOTICEOPS"))
|
||||
{
|
||||
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
|
||||
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
|
||||
ci->botflags.SetFlag(BS_MSG_NOTICEOPS);
|
||||
source.Reply(_("Fantasy replies will be sent via NOTICE to channel ops on %s."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(source, "SET MSG", _("SET \037channel\037 MSG {\037OFF|PRIVMSG|NOTICE|\037}"));
|
||||
}
|
||||
else
|
||||
u->SendMessage(BotServ, BOT_SET_UNKNOWN, option.c_str());
|
||||
source.Reply(_(UNKNOWN_OPTION), option.c_str(), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str(), this->name.c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
if (subcommand.empty())
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_SET);
|
||||
if (u->Account() && u->Account()->IsServicesOper())
|
||||
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_SET);
|
||||
source.Reply(_("Syntax: \002SET \037(channel | bot)\037 \037option\037 \037parameters\037\002\n"
|
||||
" \n"
|
||||
"Configures bot options. \037option\037 can be one of:\n"
|
||||
" \n"
|
||||
" DONTKICKOPS To protect ops against bot kicks\n"
|
||||
" DONTKICKVOICES To protect voices against bot kicks\n"
|
||||
" GREET Enable greet messages\n"
|
||||
" FANTASY Enable fantaisist commands\n"
|
||||
" SYMBIOSIS Allow the bot to act as a real bot\n"
|
||||
" MSG Configure how fantasy commands should be replied to\n"
|
||||
" \n"
|
||||
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
|
||||
"on a specific option.\n"
|
||||
"Note: access to this command is controlled by the\n"
|
||||
"level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
User *u = source.u;
|
||||
if (u->IsServicesOper())
|
||||
source.Reply(_("These options are reserved to Services Operators:\n"
|
||||
" \n"
|
||||
" NOBOT Prevent a bot from being assigned to \n"
|
||||
" a channel\n"
|
||||
" PRIVATE Prevent a bot from being assigned by\n"
|
||||
" non IRC operators"));
|
||||
}
|
||||
else if (subcommand.equals_ci("DONTKICKOPS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_SET_DONTKICKOPS);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 DONTKICKOPS {\037ON|OFF\037}\n"
|
||||
" \n"
|
||||
"Enables or disables \002ops protection\002 mode on a channel.\n"
|
||||
"When it is enabled, ops won't be kicked by the bot\n"
|
||||
"even if they don't match the NOKICK level."));
|
||||
else if (subcommand.equals_ci("DONTKICKVOICES"))
|
||||
u->SendMessage(BotServ, BOT_HELP_SET_DONTKICKVOICES);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 DONTKICKVOICES {\037ON|OFF\037}\n"
|
||||
" \n"
|
||||
"Enables or disables \002voices protection\002 mode on a channel.\n"
|
||||
"When it is enabled, voices won't be kicked by the bot\n"
|
||||
"even if they don't match the NOKICK level."));
|
||||
else if (subcommand.equals_ci("FANTASY"))
|
||||
u->SendMessage(BotServ, BOT_HELP_SET_FANTASY);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 FANTASY {\037ON|OFF\037}\n"
|
||||
"Enables or disables \002fantasy\002 mode on a channel.\n"
|
||||
"When it is enabled, users will be able to use\n"
|
||||
"commands !op, !deop, !voice, !devoice,\n"
|
||||
"!kick, !kb, !unban, !seen on a channel (find how \n"
|
||||
"to use them; try with or without nick for each, \n"
|
||||
"and with a reason for some?).\n"
|
||||
" \n"
|
||||
"Note that users wanting to use fantaisist\n"
|
||||
"commands MUST have enough level for both\n"
|
||||
"the FANTASIA and another level depending\n"
|
||||
"of the command if required (for example, to use \n"
|
||||
"!op, user must have enough access for the OPDEOP\n"
|
||||
"level)."));
|
||||
else if (subcommand.equals_ci("GREET"))
|
||||
u->SendMessage(BotServ, BOT_HELP_SET_GREET);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 GREET {\037ON|OFF\037}\n"
|
||||
" \n"
|
||||
"Enables or disables \002greet\002 mode on a channel.\n"
|
||||
"When it is enabled, the bot will display greet\n"
|
||||
"messages of users joining the channel, provided\n"
|
||||
"they have enough access to the channel."));
|
||||
else if (subcommand.equals_ci("SYMBIOSIS"))
|
||||
u->SendMessage(BotServ, BOT_HELP_SET_SYMBIOSIS, Config->s_ChanServ.c_str());
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 SYMBIOSIS {\037ON|OFF\037}\n"
|
||||
" \n"
|
||||
"Enables or disables \002symbiosis\002 mode on a channel.\n"
|
||||
"When it is enabled, the bot will do everything\n"
|
||||
"normally done by %s on channels, such as MODEs,\n"
|
||||
"KICKs, and even the entry message."), Config->s_ChanServ.c_str());
|
||||
else if (subcommand.equals_ci("NOBOT"))
|
||||
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_SET_NOBOT);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 NOBOT {\037ON|OFF\037}\002\n"
|
||||
" \n"
|
||||
"This option makes a channel be unassignable. If a bot \n"
|
||||
"is already assigned to the channel, it is unassigned\n"
|
||||
"automatically when you enable the option."));
|
||||
else if (subcommand.equals_ci("PRIVATE"))
|
||||
u->SendMessage(BotServ, BOT_SERVADMIN_HELP_SET_PRIVATE);
|
||||
source.Reply(_("Syntax: \002SET \037bot-nick\037 PRIVATE {\037ON|OFF\037}\002\n"
|
||||
"This option prevents a bot from being assigned to a\n"
|
||||
"channel by users that aren't IRC operators."));
|
||||
else if (subcommand.equals_ci("MSG"))
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 MSG {\037OFF|PRIVMSG|NOTICE|NOTICEOPS\037}\002\n"
|
||||
" \n"
|
||||
"Configures how fantasy commands should be returned to the channel. Off disables\n"
|
||||
"fantasy from replying to the channel. Privmsg, notice, and noticeops message the\n"
|
||||
"channel, notice the channel, and notice the channel ops respectively.\n"
|
||||
" \n"
|
||||
"Note that replies over one line will not use this setting to prevent spam, and will\n"
|
||||
"go directly to the user who executed it."));
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "SET", BOT_SET_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_SET);
|
||||
SyntaxError(source, "SET", _("SET \037(channel | bot)\037 \037option\037 \037settings\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* BotServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,47 +18,50 @@ class CommandBSUnassign : public Command
|
||||
public:
|
||||
CommandBSUnassign() : Command("UNASSIGN", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Unassigns a bot from a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
ChannelInfo *ci = cs_findchan(chan);
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (readonly)
|
||||
u->SendMessage(BotServ, BOT_ASSIGN_READONLY);
|
||||
else if (!u->Account()->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN))
|
||||
u->SendMessage(BotServ, ACCESS_DENIED);
|
||||
source.Reply(_(BOT_ASSIGN_READONLY));
|
||||
else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!ci->bi)
|
||||
u->SendMessage(BotServ, BOT_NOT_ASSIGNED);
|
||||
source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
|
||||
else if (ci->HasFlag(CI_PERSIST) && !cm)
|
||||
u->SendMessage(BotServ, BOT_UNASSIGN_PERSISTANT_CHAN);
|
||||
source.Reply(_("You can not unassign bots while persist is set on the channel."));
|
||||
else
|
||||
{
|
||||
bool override = !check_access(u, ci, CA_ASSIGN);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick;
|
||||
|
||||
ci->bi->UnAssign(u, ci);
|
||||
u->SendMessage(BotServ, BOT_UNASSIGN_UNASSIGNED, ci->name.c_str());
|
||||
source.Reply(_("There is no bot assigned to %s anymore."), ci->name.c_str());
|
||||
}
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_UNASSIGN);
|
||||
source.Reply(_("Syntax: \002UNASSIGN \037chan\037\002\n"
|
||||
" \n"
|
||||
"Unassigns a bot from a channel. When you use this command,\n"
|
||||
"the bot won't join the channel anymore. However, bot\n"
|
||||
"configuration for the channel is kept, so you will always\n"
|
||||
"be able to reassign a bot later without have to reconfigure\n"
|
||||
"it entirely."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(BotServ, u, "UNASSIGN", BOT_UNASSIGN_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(BotServ, BOT_HELP_CMD_UNASSIGN);
|
||||
SyntaxError(source, "UNASSIGN", _("UNASSIGN \037chan\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+320
-203
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -16,71 +16,71 @@
|
||||
class AccessListCallback : public NumberList
|
||||
{
|
||||
protected:
|
||||
User *u;
|
||||
ChannelInfo *ci;
|
||||
CommandSource &source;
|
||||
bool SentHeader;
|
||||
public:
|
||||
AccessListCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false)
|
||||
AccessListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
|
||||
{
|
||||
}
|
||||
|
||||
~AccessListCallback()
|
||||
{
|
||||
if (SentHeader)
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
|
||||
source.Reply(_("End of access list."), source.ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s access list."), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
virtual void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetAccessCount())
|
||||
if (!Number || Number > source.ci->GetAccessCount())
|
||||
return;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_(CHAN_ACCESS_LIST_HEADER), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
|
||||
DoList(source, Number - 1, source.ci->GetAccess(Number - 1));
|
||||
}
|
||||
|
||||
static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
|
||||
static void DoList(CommandSource &source, unsigned Number, ChanAccess *access)
|
||||
{
|
||||
if (ci->HasFlag(CI_XOP))
|
||||
if (source.ci->HasFlag(CI_XOP))
|
||||
{
|
||||
Anope::string xop = get_xop_level(access->level);
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str());
|
||||
source.Reply(_(" %3d %s %s"), Number + 1, xop.c_str(), access->GetMask().c_str());
|
||||
}
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str());
|
||||
source.Reply(_(" %3d %4d %s"), Number + 1, access->level, access->GetMask().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class AccessViewCallback : public AccessListCallback
|
||||
{
|
||||
public:
|
||||
AccessViewCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : AccessListCallback(_u, _ci, numlist)
|
||||
AccessViewCallback(CommandSource &_source, const Anope::string &numlist) : AccessListCallback(_source, numlist)
|
||||
{
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetAccessCount())
|
||||
if (!Number || Number > source.ci->GetAccessCount())
|
||||
return;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_(CHAN_ACCESS_LIST_HEADER), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
|
||||
DoList(source, Number - 1, source.ci->GetAccess(Number - 1));
|
||||
}
|
||||
|
||||
static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
|
||||
static void DoList(CommandSource &source, unsigned Number, ChanAccess *access)
|
||||
{
|
||||
ChannelInfo *ci = source.ci;
|
||||
Anope::string timebuf;
|
||||
if (ci->c && nc_on_chan(ci->c, access->nc))
|
||||
timebuf = "Now";
|
||||
@@ -92,54 +92,58 @@ class AccessViewCallback : public AccessListCallback
|
||||
if (ci->HasFlag(CI_XOP))
|
||||
{
|
||||
Anope::string xop = get_xop_level(access->level);
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
source.Reply(_(CHAN_ACCESS_VIEW_XOP_FORMAT), Number + 1, xop.c_str(), access->GetMask().c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
}
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
source.Reply(_(CHAN_ACCESS_VIEW_AXS_FORMAT), Number + 1, access->level, access->GetMask().c_str(), access->creator.c_str(), timebuf.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class AccessDelCallback : public NumberList
|
||||
{
|
||||
User *u;
|
||||
ChannelInfo *ci;
|
||||
CommandSource &source;
|
||||
Command *c;
|
||||
unsigned Deleted;
|
||||
Anope::string Nicks;
|
||||
bool Denied;
|
||||
bool override;
|
||||
public:
|
||||
AccessDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), c(_c), Deleted(0), Denied(false)
|
||||
AccessDelCallback(CommandSource &_source, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), c(_c), Deleted(0), Denied(false)
|
||||
{
|
||||
if (!check_access(u, ci, CA_ACCESS_CHANGE) && u->Account()->HasPriv("chanserv/access/modify"))
|
||||
if (!check_access(source.u, source.ci, CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify"))
|
||||
this->override = true;
|
||||
}
|
||||
|
||||
~AccessDelCallback()
|
||||
{
|
||||
if (Denied && !Deleted)
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!Deleted)
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s access list."), source.ci->name.c_str());
|
||||
else
|
||||
{
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, source.ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
|
||||
|
||||
if (Deleted == 1)
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_DELETED_ONE, ci->name.c_str());
|
||||
source.Reply(_("Deleted 1 entry from %s access list."), source.ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_DELETED_SEVERAL, Deleted, ci->name.c_str());
|
||||
source.Reply(_("Deleted %d entries from %s access list."), Deleted, source.ci->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetAccessCount())
|
||||
if (!Number || Number > source.ci->GetAccessCount())
|
||||
return;
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
ChanAccess *access = ci->GetAccess(Number - 1);
|
||||
|
||||
if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
if (u_level <= access->level && !u->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
Denied = true;
|
||||
return;
|
||||
@@ -147,11 +151,11 @@ class AccessDelCallback : public NumberList
|
||||
|
||||
++Deleted;
|
||||
if (!Nicks.empty())
|
||||
Nicks += ", " + access->nc->display;
|
||||
Nicks += ", " + access->GetMask();
|
||||
else
|
||||
Nicks = access->nc->display;
|
||||
Nicks = access->GetMask();
|
||||
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc));
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
|
||||
|
||||
ci->EraseAccess(Number - 1);
|
||||
}
|
||||
@@ -159,143 +163,138 @@ class AccessDelCallback : public NumberList
|
||||
|
||||
class CommandCSAccess : public Command
|
||||
{
|
||||
CommandReturn DoAdd(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoAdd(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string nick = params[2];
|
||||
int level = params[3].is_number_only() ? convertTo<int>(params[3]) : ACCESS_INVALID;
|
||||
int ulev = get_access(u, ci);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
Anope::string mask = params[2];
|
||||
int level = ACCESS_INVALID;
|
||||
|
||||
try
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
level = convertTo<int>(params[3]);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
if (level >= u_level && !u->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (!level)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_NONZERO);
|
||||
source.Reply(_("Access level must be non-zero."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
|
||||
source.Reply(_(CHAN_ACCESS_LEVEL_RANGE), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= ulev;
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= u_level;
|
||||
|
||||
NickAlias *na = findnick(nick);
|
||||
if (!na)
|
||||
NickAlias *na = findnick(mask);
|
||||
if (!na && mask.find_first_of("!@*") == Anope::string::npos)
|
||||
mask += "!*@*";
|
||||
else if (na && na->HasFlag(NS_FORBIDDEN))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_NICKS_ONLY);
|
||||
return MOD_CONT;
|
||||
}
|
||||
else if (na->HasFlag(NS_FORBIDDEN))
|
||||
{
|
||||
u->SendMessage(ChanServ, NICK_X_FORBIDDEN, nick.c_str());
|
||||
source.Reply(_(NICK_X_FORBIDDEN), mask.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
ChanAccess *access = ci->GetAccess(nc);
|
||||
ChanAccess *access = ci->GetAccess(mask, 0, false);
|
||||
if (access)
|
||||
{
|
||||
/* Don't allow lowering from a level >= ulev */
|
||||
if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
/* Don't allow lowering from a level >= u_level */
|
||||
if (access->level >= u_level && !u->HasPriv("chanserv/access/modify"))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (access->level == level)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display.c_str(), ci->name.c_str(), level);
|
||||
source.Reply(_("Access level for \002%s\002 on %s unchanged from \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
|
||||
return MOD_CONT;
|
||||
}
|
||||
access->level = level;
|
||||
|
||||
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
|
||||
FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access));
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev;
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LEVEL_CHANGED, nc->display.c_str(), ci->name.c_str(), level);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
|
||||
source.Reply(_("Access level for \002%s\002 on %s changed to \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (ci->GetAccessCount() >= Config->CSAccessMax)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_REACHED_LIMIT, Config->CSAccessMax);
|
||||
source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
ci->AddAccess(nc, level, u->nick);
|
||||
access = ci->AddAccess(mask, level, u->nick);
|
||||
|
||||
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
|
||||
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
|
||||
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev;
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_ADDED, nc->display.c_str(), ci->name.c_str(), level);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
|
||||
source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->GetMask().c_str(), ci->name.c_str(), level);
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoDel(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoDel(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string nick = params[2];
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &mask = params[2];
|
||||
|
||||
if (!ci->GetAccessCount())
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
|
||||
else if (isdigit(nick[0]) && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
source.Reply(_("%s access list is empty."), ci->name.c_str());
|
||||
else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AccessDelCallback list(u, ci, this, nick);
|
||||
AccessDelCallback list(source, this, mask);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
{
|
||||
NickAlias *na = findnick(nick);
|
||||
if (!na)
|
||||
{
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_REGISTERED, nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
NickCore *nc = na->nc;
|
||||
|
||||
unsigned i, end;
|
||||
ChanAccess *access = NULL;
|
||||
for (i = 0, end = ci->GetAccessCount(); i < end; ++i)
|
||||
{
|
||||
access = ci->GetAccess(i);
|
||||
|
||||
if (access->nc == nc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == end)
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str());
|
||||
else if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
ChanAccess *access = ci->GetAccess(mask, 0, false);
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
if (!access)
|
||||
source.Reply(_("\002%s\002 not found on %s access list."), mask.c_str(), ci->name.c_str());
|
||||
else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->HasPriv("chanserv/access/modify"))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_DELETED, access->nc->display.c_str(), ci->name.c_str());
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << na->nick << " (group: " << access->nc->display << ") from level " << access->level;
|
||||
source.Reply(_("\002%s\002 deleted from %s access list."), access->GetMask().c_str(), ci->name.c_str());
|
||||
bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && access->nc != u->Account();
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->GetMask() << " from level " << access->level;
|
||||
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
|
||||
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
|
||||
|
||||
ci->EraseAccess(i);
|
||||
ci->EraseAccess(access);
|
||||
}
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoList(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoList(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string nick = params.size() > 2 ? params[2] : "";
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
|
||||
if (!ci->GetAccessCount())
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
|
||||
source.Reply(_("%s access list is empty."), ci->name.c_str());
|
||||
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AccessListCallback list(u, ci, nick);
|
||||
AccessListCallback list(source, nick);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -306,36 +305,38 @@ class CommandCSAccess : public Command
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
|
||||
if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
|
||||
if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
|
||||
continue;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_(CHAN_ACCESS_LIST_HEADER), ci->name.c_str());
|
||||
}
|
||||
|
||||
AccessListCallback::DoList(u, ci, i, access);
|
||||
AccessListCallback::DoList(source, i, access);
|
||||
}
|
||||
|
||||
if (SentHeader)
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
|
||||
source.Reply(_("End of access list."), ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoView(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoView(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string nick = params.size() > 2 ? params[2] : "";
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
|
||||
if (!ci->GetAccessCount())
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
|
||||
source.Reply(_("%s access list is empty."), ci->name.c_str());
|
||||
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AccessViewCallback list(u, ci, nick);
|
||||
AccessViewCallback list(source, nick);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -346,38 +347,41 @@ class CommandCSAccess : public Command
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
|
||||
if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
|
||||
if (!nick.empty() && !Anope::Match(access->GetMask(), nick))
|
||||
continue;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_(CHAN_ACCESS_LIST_HEADER), ci->name.c_str());
|
||||
}
|
||||
|
||||
AccessViewCallback::DoList(u, ci, i, access);
|
||||
AccessViewCallback::DoList(source, i, access);
|
||||
}
|
||||
|
||||
if (SentHeader)
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
|
||||
source.Reply(_("End of access list."), ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoClear(User *u, ChannelInfo *ci)
|
||||
CommandReturn DoClear(CommandSource &source)
|
||||
{
|
||||
if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (!IsFounder(u, ci) && !u->HasPriv("chanserv/access/modify"))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else
|
||||
{
|
||||
ci->ClearAccess();
|
||||
|
||||
FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_CLEAR, ci->name.c_str());
|
||||
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
|
||||
|
||||
bool override = !IsFounder(u, ci);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
|
||||
@@ -389,88 +393,176 @@ class CommandCSAccess : public Command
|
||||
public:
|
||||
CommandCSAccess() : Command("ACCESS", 2, 4)
|
||||
{
|
||||
this->SetDesc(_("Modify the list of privileged users"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string cmd = params[1];
|
||||
Anope::string nick = params.size() > 2 ? params[2] : "";
|
||||
Anope::string s = params.size() > 3 ? params[3] : "";
|
||||
const Anope::string &cmd = params[1];
|
||||
const Anope::string &nick = params.size() > 2 ? params[2] : "";
|
||||
const Anope::string &s = params.size() > 3 ? params[3] : "";
|
||||
|
||||
ChannelInfo *ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
bool is_list = cmd.equals_ci("LIST") || cmd.equals_ci("VIEW");
|
||||
bool is_clear = cmd.equals_ci("CLEAR");
|
||||
bool is_del = cmd.equals_ci("DEL");
|
||||
|
||||
bool has_access = false;
|
||||
if (is_list && check_access(u, ci, CA_ACCESS_LIST))
|
||||
has_access = true;
|
||||
else if (check_access(u, ci, CA_ACCESS_CHANGE))
|
||||
has_access = true;
|
||||
else if (is_del)
|
||||
{
|
||||
NickAlias *na = findnick(nick);
|
||||
if (na && na->nc == u->Account())
|
||||
has_access = true;
|
||||
}
|
||||
|
||||
/* If LIST, we don't *require* any parameters, but we can take any.
|
||||
* If DEL, we require a nick and no level.
|
||||
* Else (ADD), we require a level (which implies a nick). */
|
||||
if (is_list || is_clear ? 0 : (cmd.equals_ci("DEL") ? (nick.empty() || !s.empty()) : s.empty()))
|
||||
this->OnSyntaxError(u, cmd);
|
||||
/* We still allow LIST in xOP mode, but not others */
|
||||
this->OnSyntaxError(source, cmd);
|
||||
else if (!has_access)
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
/* We still allow LIST and CLEAR in xOP mode, but not others */
|
||||
else if (ci->HasFlag(CI_XOP) && !is_list && !is_clear)
|
||||
{
|
||||
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_XOP_HOP, Config->s_ChanServ.c_str());
|
||||
source.Reply(_("You can't use this command. \n"
|
||||
"Use the AOP, SOP, HOP and VOP commands instead.\n"
|
||||
"Type \002%s%s HELP \037command\037\002 for more information."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_XOP, Config->s_ChanServ.c_str());
|
||||
source.Reply(_("You can't use this command. \n"
|
||||
"Use the AOP, SOP and VOP commands instead.\n"
|
||||
"Type \002%s%s HELP \037command\037\002 for more information."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
|
||||
}
|
||||
else if ((is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list")) || (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify")))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (readonly && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL") || cmd.equals_ci("CLEAR")))
|
||||
u->SendMessage(ChanServ, CHAN_ACCESS_DISABLED);
|
||||
else if (readonly && !is_list)
|
||||
source.Reply(_("Sorry, channel access list modification is temporarily disabled."));
|
||||
else if (cmd.equals_ci("ADD"))
|
||||
this->DoAdd(u, ci, params);
|
||||
this->DoAdd(source, params);
|
||||
else if (cmd.equals_ci("DEL"))
|
||||
this->DoDel(u, ci, params);
|
||||
this->DoDel(source, params);
|
||||
else if (cmd.equals_ci("LIST"))
|
||||
this->DoList(u, ci, params);
|
||||
this->DoList(source, params);
|
||||
else if (cmd.equals_ci("VIEW"))
|
||||
this->DoView(u, ci, params);
|
||||
this->DoView(source, params);
|
||||
else if (cmd.equals_ci("CLEAR"))
|
||||
this->DoClear(u, ci);
|
||||
this->DoClear(source);
|
||||
else
|
||||
this->OnSyntaxError(u, "");
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_ACCESS);
|
||||
u->SendMessage(ChanServ, CHAN_HELP_ACCESS_LEVELS);
|
||||
source.Reply(_("Syntax: \002ACCESS \037channel\037 ADD \037mask\037 \037level\037\002\n"
|
||||
" \002ACCESS \037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}\002\n"
|
||||
" \002ACCESS \037channel\037 LIST [\037mask\037 | \037list\037]\002\n"
|
||||
" \002ACCESS \037channel\037 VIEW [\037mask\037 | \037list\037]\002\n"
|
||||
" \002ACCESS \037channel\037 CLEAR\002\n"
|
||||
" \n"
|
||||
"Maintains the \002access list\002 for a channel. The access\n"
|
||||
"list specifies which users are allowed chanop status or\n"
|
||||
"access to %s commands on the channel. Different\n"
|
||||
"user levels allow for access to different subsets of\n"
|
||||
"privileges; \002%s%s HELP ACCESS LEVELS\002 for more\n"
|
||||
"specific information. Any nick not on the access list has\n"
|
||||
"a user level of 0.\n"
|
||||
" \n"
|
||||
"The \002ACCESS ADD\002 command adds the given mask to the\n"
|
||||
"access list with the given user level; if the mask is\n"
|
||||
"already present on the list, its access level is changed to\n"
|
||||
"the level specified in the command. The \037level\037 specified\n"
|
||||
"must be less than that of the user giving the command, and\n"
|
||||
"if the \037mask\037 is already on the access list, the current\n"
|
||||
"access level of that nick must be less than the access level\n"
|
||||
"of the user giving the command. When a user joins the channel\n"
|
||||
"the access they receive is from the highest level entry in the\n"
|
||||
"access list.\n"
|
||||
" \n"
|
||||
"The \002ACCESS DEL\002 command removes the given nick from the\n"
|
||||
"access list. If a list of entry numbers is given, those\n"
|
||||
"entries are deleted. (See the example for LIST below.)\n"
|
||||
"You may remove yourself from an access list, even if you\n"
|
||||
"do not have access to modify that list otherwise.\n"
|
||||
" \n"
|
||||
"The \002ACCESS LIST\002 command displays the access list. If\n"
|
||||
"a wildcard mask is given, only those entries matching the\n"
|
||||
"mask are displayed. If a list of entry numbers is given,\n"
|
||||
"only those entries are shown; for example:\n"
|
||||
" \002ACCESS #channel LIST 2-5,7-9\002\n"
|
||||
" Lists access entries numbered 2 through 5 and\n"
|
||||
" 7 through 9.\n"
|
||||
" \n"
|
||||
"The \002ACCESS VIEW\002 command displays the access list similar\n"
|
||||
"to \002ACCESS LIST\002 but shows the creator and last used time.\n"
|
||||
" \n"
|
||||
"The \002ACCESS CLEAR\002 command clears all entries of the\n"
|
||||
"access list."),
|
||||
ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
|
||||
source.Reply(_("\002User access levels\002\n"
|
||||
" \n"
|
||||
"By default, the following access levels are defined:\n"
|
||||
" \n"
|
||||
" \002Founder\002 Full access to %s functions; automatic\n"
|
||||
" opping upon entering channel. Note\n"
|
||||
" that only one person may have founder\n"
|
||||
" status (it cannot be given using the\n"
|
||||
" \002ACCESS\002 command).\n"
|
||||
" \002 10\002 Access to AKICK command; automatic opping.\n"
|
||||
" \002 5\002 Automatic opping.\n"
|
||||
" \002 3\002 Automatic voicing.\n"
|
||||
" \002 0\002 No special privileges; can be opped by other\n"
|
||||
" ops (unless \002secure-ops\002 is set).\n"
|
||||
" \002 <0\002 May not be opped.\n"
|
||||
" \n"
|
||||
"These levels may be changed, or new ones added, using the\n"
|
||||
"\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n"
|
||||
"information."), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX);
|
||||
SyntaxError(source, "ACCESS", _("ACCESS \037channel\037 {ADD|DEL|LIST|VIEW|CLEAR} [\037mask\037 [\037level\037] | \037entry-list\037]"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSLevels : public Command
|
||||
{
|
||||
CommandReturn DoSet(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoSet(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string what = params[2];
|
||||
Anope::string lev = params[3];
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
Anope::string error;
|
||||
int level = (lev.is_number_only() ? convertTo<int>(lev, error, false) : 0);
|
||||
if (!lev.is_number_only())
|
||||
error = "1";
|
||||
const Anope::string &what = params[2];
|
||||
const Anope::string &lev = params[3];
|
||||
|
||||
int level;
|
||||
|
||||
if (lev.equals_ci("FOUNDER"))
|
||||
{
|
||||
level = ACCESS_FOUNDER;
|
||||
error.clear();
|
||||
else
|
||||
{
|
||||
level = 1;
|
||||
try
|
||||
{
|
||||
level = convertTo<int>(lev);
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
this->OnSyntaxError(source, "SET");
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error.empty())
|
||||
this->OnSyntaxError(u, "SET");
|
||||
else if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
|
||||
if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
|
||||
source.Reply(_("Level must be between %d and %d inclusive."), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
|
||||
else
|
||||
{
|
||||
for (int i = 0; levelinfo[i].what >= 0; ++i)
|
||||
@@ -484,25 +576,28 @@ class CommandCSLevels : public Command
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << levelinfo[i].name << " to " << level;
|
||||
|
||||
if (level == ACCESS_FOUNDER)
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name.c_str(), ci->name.c_str());
|
||||
source.Reply(_("Level for %s on channel %s changed to founder only."), levelinfo[i].name.c_str(), ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_CHANGED, levelinfo[i].name.c_str(), ci->name.c_str(), level);
|
||||
source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), levelinfo[i].name.c_str(), ci->name.c_str(), level);
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_UNKNOWN, what.c_str(), Config->s_ChanServ.c_str());
|
||||
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->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoDisable(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn DoDisable(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string what = params[2];
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &what = params[2];
|
||||
|
||||
/* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
|
||||
if (what.equals_ci("FOUNDER"))
|
||||
if (!what.equals_ci("FOUNDER"))
|
||||
for (int i = 0; levelinfo[i].what >= 0; ++i)
|
||||
{
|
||||
if (what.equals_ci(levelinfo[i].name))
|
||||
@@ -513,19 +608,21 @@ class CommandCSLevels : public Command
|
||||
bool override = !check_access(u, ci, CA_FOUNDER);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << levelinfo[i].name;
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_DISABLED, levelinfo[i].name.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 disabled on channel %s."), levelinfo[i].name.c_str(), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_UNKNOWN, what.c_str(), Config->s_ChanServ.c_str());
|
||||
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->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoList(User *u, ChannelInfo *ci)
|
||||
CommandReturn DoList(CommandSource &source)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_HEADER, ci->name.c_str());
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
|
||||
|
||||
if (!levelinfo_maxwidth)
|
||||
for (int i = 0; levelinfo[i].what >= 0; ++i)
|
||||
@@ -543,75 +640,78 @@ class CommandCSLevels : public Command
|
||||
{
|
||||
j = levelinfo[i].what;
|
||||
|
||||
if (j == CA_AUTOOP || j == CA_AUTODEOP || j == CA_AUTOVOICE || j == CA_NOJOIN)
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name.c_str());
|
||||
source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, levelinfo[i].name.c_str());
|
||||
}
|
||||
else if (j == ACCESS_FOUNDER)
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_FOUNDER, levelinfo_maxwidth, levelinfo[i].name.c_str());
|
||||
source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, levelinfo[i].name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_LIST_NORMAL, levelinfo_maxwidth, levelinfo[i].name.c_str(), j);
|
||||
source.Reply(_(" %-*s %d"), levelinfo_maxwidth, levelinfo[i].name.c_str(), j);
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
CommandReturn DoReset(User *u, ChannelInfo *ci)
|
||||
CommandReturn DoReset(CommandSource &source)
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
reset_levels(ci);
|
||||
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
|
||||
|
||||
bool override = !check_access(u, ci, CA_FOUNDER);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET";
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_RESET, ci->name.c_str());
|
||||
source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
public:
|
||||
CommandCSLevels() : Command("LEVELS", 2, 4)
|
||||
{
|
||||
this->SetDesc(_("Redefine the meanings of access levels"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string cmd = params[1];
|
||||
Anope::string what = params.size() > 2 ? params[2] : "";
|
||||
Anope::string s = params.size() > 3 ? params[3] : "";
|
||||
const Anope::string &cmd = params[1];
|
||||
const Anope::string &what = params.size() > 2 ? params[2] : "";
|
||||
const Anope::string &s = params.size() > 3 ? params[3] : "";
|
||||
|
||||
ChannelInfo *ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
/* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
|
||||
* one; else, we want none.
|
||||
*/
|
||||
if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
|
||||
this->OnSyntaxError(u, cmd);
|
||||
this->OnSyntaxError(source, cmd);
|
||||
else if (ci->HasFlag(CI_XOP))
|
||||
u->SendMessage(ChanServ, CHAN_LEVELS_XOP);
|
||||
else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_("Levels are not available as xOP is enabled on this channel."));
|
||||
else if (!check_access(u, ci, CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (cmd.equals_ci("SET"))
|
||||
this->DoSet(u, ci, params);
|
||||
this->DoSet(source, params);
|
||||
else if (cmd.equals_ci("DIS") || cmd.equals_ci("DISABLE"))
|
||||
this->DoDisable(u, ci, params);
|
||||
this->DoDisable(source, params);
|
||||
else if (cmd.equals_ci("LIST"))
|
||||
this->DoList(u, ci);
|
||||
this->DoList(source);
|
||||
else if (cmd.equals_ci("RESET"))
|
||||
this->DoReset(u, ci);
|
||||
this->DoReset(source);
|
||||
else
|
||||
this->OnSyntaxError(u, "");
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
if (subcommand.equals_ci("DESC"))
|
||||
{
|
||||
int i;
|
||||
u->SendMessage(ChanServ, CHAN_HELP_LEVELS_DESC);
|
||||
source.Reply(_("The following feature/function names are understood. Note\n"
|
||||
"that the leves for NOJOIN is the maximum level,\n"
|
||||
"while all others are minimum levels."));
|
||||
if (!levelinfo_maxwidth)
|
||||
for (i = 0; levelinfo[i].what >= 0; ++i)
|
||||
{
|
||||
@@ -620,22 +720,39 @@ class CommandCSLevels : public Command
|
||||
levelinfo_maxwidth = len;
|
||||
}
|
||||
for (i = 0; levelinfo[i].what >= 0; ++i)
|
||||
u->SendMessage(ChanServ, CHAN_HELP_LEVELS_DESC_FORMAT, levelinfo_maxwidth, levelinfo[i].name.c_str(), GetString(u, levelinfo[i].desc).c_str());
|
||||
source.Reply(_(" %-*s %s"), levelinfo_maxwidth, levelinfo[i].name.c_str(), GetString(source.u->Account(), levelinfo[i].desc).c_str());
|
||||
}
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_HELP_LEVELS);
|
||||
source.Reply(_("Syntax: \002LEVELS \037channel\037 SET \037type\037 \037level\037\002\n"
|
||||
" \002LEVELS \037channel\037 {DIS | DISABLE} \037type\037\002\n"
|
||||
" \002LEVELS \037channel\037 LIST\002\n"
|
||||
" \002LEVELS \037channel\037 RESET\002\n"
|
||||
" \n"
|
||||
"The \002LEVELS\002 command allows fine control over the meaning of\n"
|
||||
"the numeric access levels used for channels. With this\n"
|
||||
"command, you can define the access level required for most\n"
|
||||
"of %s's functions. (The \002SET FOUNDER\002 and this command\n"
|
||||
"are always restricted to the channel founder.)\n"
|
||||
" \n"
|
||||
"\002LEVELS SET\002 allows the access level for a function or group of\n"
|
||||
"functions to be changed. \002LEVELS DISABLE\002 (or \002DIS\002 for short)\n"
|
||||
"disables an automatic feature or disallows access to a\n"
|
||||
"function by anyone, INCLUDING the founder (although, the founder\n"
|
||||
"can always reenable it).\n"
|
||||
" \n"
|
||||
"\002LEVELS LIST\002 shows the current levels for each function or\n"
|
||||
"group of functions. \002LEVELS RESET\002 resets the levels to the\n"
|
||||
"default levels of a newly-created channel (see\n"
|
||||
"\002HELP ACCESS LEVELS\002).\n"
|
||||
" \n"
|
||||
"For a list of the features and functions whose levels can be\n"
|
||||
"set, see \002HELP LEVELS DESC\002."), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_ACCESS);
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_LEVELS);
|
||||
SyntaxError(source, "LEVELS", _("LEVELS \037channel\037 {SET | DIS[ABLE] | LIST | RESET} [\037item\037 [\037level\037]]"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+149
-174
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -54,114 +54,118 @@ static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope
|
||||
class AkickListCallback : public NumberList
|
||||
{
|
||||
protected:
|
||||
User *u;
|
||||
ChannelInfo *ci;
|
||||
CommandSource &source;
|
||||
bool SentHeader;
|
||||
public:
|
||||
AkickListCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false)
|
||||
AkickListCallback(CommandSource &_source, const Anope::string &numlist) : NumberList(numlist, false), source(_source), SentHeader(false)
|
||||
{
|
||||
}
|
||||
|
||||
~AkickListCallback()
|
||||
{
|
||||
if (!SentHeader)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s autokick list."), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
virtual void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetAkickCount())
|
||||
if (!Number || Number > source.ci->GetAkickCount())
|
||||
return;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
|
||||
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
|
||||
}
|
||||
|
||||
static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
|
||||
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() :akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : GetString(u, NO_REASON).c_str());
|
||||
source.Reply(_(" %3d %s (%s)"), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
|
||||
}
|
||||
};
|
||||
|
||||
class AkickViewCallback : public AkickListCallback
|
||||
{
|
||||
public:
|
||||
AkickViewCallback(User *_u, ChannelInfo *_ci, const Anope::string &numlist) : AkickListCallback(_u, _ci, numlist)
|
||||
AkickViewCallback(CommandSource &_source, const Anope::string &numlist) : AkickListCallback(_source, numlist)
|
||||
{
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetAkickCount())
|
||||
if (!Number || Number > source.ci->GetAkickCount())
|
||||
return;
|
||||
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_("Autokick list for %s:"), source.ci->name.c_str());
|
||||
}
|
||||
|
||||
DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
|
||||
DoList(source, Number - 1, source.ci->GetAkick(Number - 1));
|
||||
}
|
||||
|
||||
static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
|
||||
static void DoList(CommandSource &source, unsigned index, AutoKick *akick)
|
||||
{
|
||||
Anope::string timebuf;
|
||||
|
||||
if (akick->addtime)
|
||||
timebuf = do_strftime(akick->addtime);
|
||||
else
|
||||
timebuf = GetString(u, UNKNOWN);
|
||||
timebuf = _(UNKNOWN);
|
||||
|
||||
u->SendMessage(ChanServ, akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : GetString(u, UNKNOWN).c_str(), timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : GetString(u, NO_REASON).c_str());
|
||||
source.Reply(_(CHAN_AKICK_VIEW_FORMAT), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : UNKNOWN, timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
|
||||
|
||||
if (akick->last_used)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LAST_USED, do_strftime(akick->last_used).c_str());
|
||||
source.Reply(_(" Last used %s"), do_strftime(akick->last_used).c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class AkickDelCallback : public NumberList
|
||||
{
|
||||
User *u;
|
||||
ChannelInfo *ci;
|
||||
CommandSource &source;
|
||||
Command *c;
|
||||
unsigned Deleted;
|
||||
public:
|
||||
AkickDelCallback(User *_u, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), u(_u), ci(_ci), c(_c), Deleted(0)
|
||||
AkickDelCallback(CommandSource &_source, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), c(_c), Deleted(0)
|
||||
{
|
||||
}
|
||||
|
||||
~AkickDelCallback()
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users";
|
||||
|
||||
if (!Deleted)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
|
||||
else if (Deleted == 1)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_DELETED_ONE, ci->name.c_str());
|
||||
source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_DELETED_SEVERAL, Deleted, ci->name.c_str());
|
||||
source.Reply(_("Deleted %d entries from %s autokick list."), Deleted, ci->name.c_str());
|
||||
}
|
||||
|
||||
void HandleNumber(unsigned Number)
|
||||
{
|
||||
if (!Number || Number > ci->GetAkickCount())
|
||||
if (!Number || Number > source.ci->GetAkickCount())
|
||||
return;
|
||||
|
||||
++Deleted;
|
||||
ci->EraseAkick(Number - 1);
|
||||
source.ci->EraseAkick(Number - 1);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSAKick : public Command
|
||||
{
|
||||
void DoAdd(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
void DoAdd(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
Anope::string mask = params[2];
|
||||
Anope::string reason = params.size() > 3 ? params[3] : "";
|
||||
NickAlias *na = findnick(mask);
|
||||
@@ -179,7 +183,7 @@ class CommandCSAKick : public Command
|
||||
{
|
||||
if (na->HasFlag(NS_FORBIDDEN))
|
||||
{
|
||||
u->SendMessage(ChanServ, NICK_X_FORBIDDEN, mask.c_str());
|
||||
source.Reply(_(NICK_X_FORBIDDEN), mask.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -189,7 +193,7 @@ class CommandCSAKick : public Command
|
||||
/* Check excepts BEFORE we get this far */
|
||||
if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted_mask(ci, mask))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
|
||||
source.Reply(_(CHAN_EXCEPTED), mask.c_str(), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -197,9 +201,11 @@ class CommandCSAKick : public Command
|
||||
* or whether the mask matches a user with higher/equal access - Viper */
|
||||
if (ci->HasFlag(CI_PEACE) && nc)
|
||||
{
|
||||
if (nc == ci->founder || get_access_level(ci, nc) >= get_access(u, ci))
|
||||
ChanAccess *nc_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
|
||||
int16 nc_level = nc_access ? nc_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
if (nc == ci->founder || nc_level >= u_level)
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -207,13 +213,17 @@ class CommandCSAKick : public Command
|
||||
{
|
||||
/* Match against all currently online users with equal or
|
||||
* higher access. - Viper */
|
||||
for (user_map::const_iterator it = UserListByNick.begin(), it_end = UserListByNick.end(); it != it_end; ++it)
|
||||
for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(), it_end = UserListByNick.end(); it != it_end; ++it)
|
||||
{
|
||||
User *u2 = it->second;
|
||||
|
||||
if ((check_access(u2, ci, CA_FOUNDER) || get_access(u2, ci) >= get_access(u, ci)) && match_usermask(mask, u2))
|
||||
ChanAccess *u2_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u);
|
||||
int16 u2_level = u2_access ? u2_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
Entry entry_mask(CMODE_BEGIN, mask);
|
||||
|
||||
if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && entry_mask.Matches(u2))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -227,12 +237,14 @@ class CommandCSAKick : public Command
|
||||
if (na2->HasFlag(NS_FORBIDDEN))
|
||||
continue;
|
||||
|
||||
if (na2->nc && (na2->nc == ci->founder || get_access_level(ci, na2->nc) >= get_access(u, ci)))
|
||||
ChanAccess *na2_access = ci->GetAccess(na2->nc), *u_access = ci->GetAccess(u);
|
||||
int16 na2_level = na2_access ? na2_access->level : 0, u_level = u_access ? u_access->level : 0;
|
||||
if (na2->nc && (na2->nc == ci->founder || na2_level >= u_level))
|
||||
{
|
||||
Anope::string buf = na2->nick + "!" + na2->last_usermask;
|
||||
if (Anope::Match(buf, mask))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -244,14 +256,14 @@ class CommandCSAKick : public Command
|
||||
akick = ci->GetAkick(j);
|
||||
if (akick->HasFlag(AK_ISNICK) ? akick->nc == nc : mask.equals_ci(akick->mask))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_ALREADY_EXISTS, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ci->GetAkickCount() >= Config->CSAutokickMax)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_REACHED_LIMIT, Config->CSAutokickMax);
|
||||
source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->CSAutokickMax);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -265,110 +277,30 @@ class CommandCSAKick : public Command
|
||||
|
||||
FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_ADDED, mask.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||
|
||||
this->DoEnforce(u, ci);
|
||||
this->DoEnforce(source);
|
||||
}
|
||||
|
||||
void DoStick(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
void DoDel(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
NickAlias *na;
|
||||
NickCore *nc;
|
||||
Anope::string mask = params[2];
|
||||
unsigned i, end;
|
||||
AutoKick *akick;
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (!ci->GetAkickCount())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
na = findnick(mask);
|
||||
nc = na ? na->nc : NULL;
|
||||
|
||||
for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
|
||||
{
|
||||
akick = ci->GetAkick(i);
|
||||
|
||||
if (akick->HasFlag(AK_ISNICK))
|
||||
continue;
|
||||
if (mask.equals_ci(akick->mask))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == end)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "STICK " << akick->mask;
|
||||
|
||||
akick->SetFlag(AK_STUCK);
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_STUCK, akick->mask.c_str(), ci->name.c_str());
|
||||
|
||||
if (ci->c)
|
||||
stick_mask(ci, akick);
|
||||
}
|
||||
|
||||
void DoUnStick(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
NickAlias *na;
|
||||
NickCore *nc;
|
||||
AutoKick *akick;
|
||||
unsigned i, end;
|
||||
Anope::string mask = params[2];
|
||||
|
||||
if (!ci->GetAkickCount())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
na = findnick(mask);
|
||||
nc = na ? na->nc : NULL;
|
||||
|
||||
for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
|
||||
{
|
||||
akick = ci->GetAkick(i);
|
||||
|
||||
if (akick->HasFlag(AK_ISNICK))
|
||||
continue;
|
||||
if (mask.equals_ci(akick->mask))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == end)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "UNSTICK " << akick->mask;
|
||||
|
||||
akick->UnsetFlag(AK_STUCK);
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_UNSTUCK, akick->mask.c_str(), ci->name.c_str());
|
||||
}
|
||||
|
||||
void DoDel(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string mask = params[2];
|
||||
const Anope::string &mask = params[2];
|
||||
AutoKick *akick;
|
||||
unsigned i, end;
|
||||
|
||||
if (!ci->GetAkickCount())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
|
||||
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special case: is it a number/list? Only do search if it isn't. */
|
||||
if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AkickDelCallback list(u, ci, this, mask);
|
||||
AkickDelCallback list(source, this, mask);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -386,7 +318,7 @@ class CommandCSAKick : public Command
|
||||
|
||||
if (i == ci->GetAkickCount())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 not found on %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -395,26 +327,29 @@ class CommandCSAKick : public Command
|
||||
|
||||
ci->EraseAkick(i);
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_DELETED, mask.c_str(), ci->name.c_str());
|
||||
source.Reply(_("\002%s\002 deleted from %s autokick list."), mask.c_str(), ci->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void DoList(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
void DoList(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string mask = params.size() > 2 ? params[2] : "";
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &mask = params.size() > 2 ? params[2] : "";
|
||||
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
|
||||
|
||||
if (!ci->GetAkickCount())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
|
||||
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AkickListCallback list(u, ci, mask);
|
||||
AkickListCallback list(source, mask);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -436,33 +371,36 @@ class CommandCSAKick : public Command
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
|
||||
}
|
||||
|
||||
AkickListCallback::DoList(u, ci, i, akick);
|
||||
AkickListCallback::DoList(source, i, akick);
|
||||
}
|
||||
|
||||
if (!SentHeader)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void DoView(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms)
|
||||
void DoView(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string mask = params.size() > 2 ? params[2] : "";
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
const Anope::string &mask = params.size() > 2 ? params[2] : "";
|
||||
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "VIEW";
|
||||
|
||||
if (!ci->GetAkickCount())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_EMPTY, ci->name.c_str());
|
||||
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
|
||||
{
|
||||
AkickViewCallback list(u, ci, mask);
|
||||
AkickViewCallback list(source, mask);
|
||||
list.Process();
|
||||
}
|
||||
else
|
||||
@@ -484,25 +422,27 @@ class CommandCSAKick : public Command
|
||||
if (!SentHeader)
|
||||
{
|
||||
SentHeader = true;
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
|
||||
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
|
||||
}
|
||||
|
||||
AkickViewCallback::DoList(u, ci, i, akick);
|
||||
AkickViewCallback::DoList(source, i, akick);
|
||||
}
|
||||
|
||||
if (!SentHeader)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_NO_MATCH, ci->name.c_str());
|
||||
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void DoEnforce(User *u, ChannelInfo *ci)
|
||||
void DoEnforce(CommandSource &source)
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
int count = 0;
|
||||
|
||||
if (!c)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, ci->name.c_str());
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -517,73 +457,108 @@ class CommandCSAKick : public Command
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ENFORCE, affects " << count << " users";
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_ENFORCE_DONE, ci->name.c_str(), count);
|
||||
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
|
||||
}
|
||||
|
||||
void DoClear(User *u, ChannelInfo *ci)
|
||||
void DoClear(CommandSource &source)
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
bool override = !check_access(u, ci, CA_AKICK);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
|
||||
|
||||
ci->ClearAkick();
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_CLEAR, ci->name.c_str());
|
||||
source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
|
||||
}
|
||||
|
||||
public:
|
||||
CommandCSAKick() : Command("AKICK", 2, 4)
|
||||
{
|
||||
this->SetDesc(_("Maintain the AutoKick list"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string cmd = params[1];
|
||||
Anope::string mask = params.size() > 2 ? params[2] : "";
|
||||
|
||||
ChannelInfo *ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("STICK") || cmd.equals_ci("UNSTICK") || cmd.equals_ci("DEL")))
|
||||
this->OnSyntaxError(u, cmd);
|
||||
else if (!check_access(u, ci, CA_AKICK) && !u->Account()->HasPriv("chanserv/access/modify"))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
|
||||
this->OnSyntaxError(source, cmd);
|
||||
else if (!check_access(u, ci, CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
|
||||
u->SendMessage(ChanServ, CHAN_AKICK_DISABLED);
|
||||
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
|
||||
else if (cmd.equals_ci("ADD"))
|
||||
this->DoAdd(u, ci, params);
|
||||
else if (cmd.equals_ci("STICK"))
|
||||
this->DoStick(u, ci, params);
|
||||
else if (cmd.equals_ci("UNSTICK"))
|
||||
this->DoUnStick(u, ci, params);
|
||||
this->DoAdd(source, params);
|
||||
else if (cmd.equals_ci("DEL"))
|
||||
this->DoDel(u, ci, params);
|
||||
this->DoDel(source, params);
|
||||
else if (cmd.equals_ci("LIST"))
|
||||
this->DoList(u, ci, params);
|
||||
this->DoList(source, params);
|
||||
else if (cmd.equals_ci("VIEW"))
|
||||
this->DoView(u, ci, params);
|
||||
this->DoView(source, params);
|
||||
else if (cmd.equals_ci("ENFORCE"))
|
||||
this->DoEnforce(u, ci);
|
||||
this->DoEnforce(source);
|
||||
else if (cmd.equals_ci("CLEAR"))
|
||||
this->DoClear(u, ci);
|
||||
this->DoClear(source);
|
||||
else
|
||||
this->OnSyntaxError(u, "");
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_AKICK);
|
||||
source.Reply(_("Syntax: \002AKICK \037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]\002\n"
|
||||
" \002AKICK \037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}\002\n"
|
||||
" \002AKICK \037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]\002\n"
|
||||
" \002AKICK \037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]\002\n"
|
||||
" \002AKICK \037channel\037 ENFORCE\002\n"
|
||||
" \002AKICK \037channel\037 CLEAR\002\n"
|
||||
" \n"
|
||||
"Maintains the \002AutoKick list\002 for a channel. If a user\n"
|
||||
"on the AutoKick list attempts to join the channel,\n"
|
||||
"%s will ban that user from the channel, then kick\n"
|
||||
"the user.\n"
|
||||
" \n"
|
||||
"The \002AKICK ADD\002 command adds the given nick or usermask\n"
|
||||
"to the AutoKick list. If a \037reason\037 is given with\n"
|
||||
"the command, that reason will be used when the user is\n"
|
||||
"kicked; if not, the default reason is \"You have been\n"
|
||||
"banned from the channel\".\n"
|
||||
"When akicking a \037registered nick\037 the nickserv account\n"
|
||||
"will be added to the akick list instead of the mask.\n"
|
||||
"All users within that nickgroup will then be akicked.\n"),
|
||||
ChanServ->nick.c_str());
|
||||
source.Reply(_(
|
||||
" \n"
|
||||
"The \002AKICK DEL\002 command removes the given nick or mask\n"
|
||||
"from the AutoKick list. It does not, however, remove any\n"
|
||||
"bans placed by an AutoKick; those must be removed\n"
|
||||
"manually.\n"
|
||||
" \n"
|
||||
"The \002AKICK LIST\002 command displays the AutoKick list, or\n"
|
||||
"optionally only those AutoKick entries which match the\n"
|
||||
"given mask.\n"
|
||||
" \n"
|
||||
"The \002AKICK VIEW\002 command is a more verbose version of\n"
|
||||
"\002AKICK LIST\002 command.\n"
|
||||
" \n"
|
||||
"The \002AKICK ENFORCE\002 command causes %s to enforce the\n"
|
||||
"current AKICK list by removing those users who match an\n"
|
||||
"AKICK mask.\n"
|
||||
" \n"
|
||||
"The \002AKICK CLEAR\002 command clears all entries of the\n"
|
||||
"akick list."), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_AKICK);
|
||||
SyntaxError(source, "AKICK", _("AKICK \037channel\037 {ADD | DEL | LIST | VIEW | ENFORCE | CLEAR} [\037nick-or-usermask\037] [\037reason\037]"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+34
-37
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -16,43 +16,42 @@
|
||||
class CommandCSBan : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSBan(const Anope::string &cname) : Command(cname, 2, 3)
|
||||
CommandCSBan(const Anope::string &cname) : Command("BAN", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Bans a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string target = params[1];
|
||||
Anope::string reason = params.size() > 2 ? params[2] : "Requested";
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &target = params[1];
|
||||
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
|
||||
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci;
|
||||
User *u2;
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
bool is_same = target.equals_ci(u->nick);
|
||||
User *u2 = is_same ? u : finduser(target);
|
||||
|
||||
int is_same;
|
||||
|
||||
is_same = target.equals_ci(u->nick);
|
||||
|
||||
if (c)
|
||||
ci = c->ci;
|
||||
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
|
||||
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
|
||||
|
||||
if (!c)
|
||||
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (is_same ? !(u2 = u) : !(u2 = finduser(target)))
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, target.c_str());
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
|
||||
else if (!u2)
|
||||
source.Reply(_(NICK_X_NOT_IN_USE), target.c_str());
|
||||
else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (!is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
/*
|
||||
* Dont ban/kick the user on channels where he is excepted
|
||||
* to prevent services <-> server wars.
|
||||
*/
|
||||
else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2))
|
||||
u->SendMessage(ChanServ, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
|
||||
else if (matches_list(ci->c, u2, CMODE_EXCEPT))
|
||||
source.Reply(_(CHAN_EXCEPTED), u2->nick.c_str(), ci->name.c_str());
|
||||
else if (u2->IsProtected())
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else
|
||||
{
|
||||
Anope::string mask;
|
||||
@@ -76,36 +75,34 @@ class CommandCSBan : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_BAN);
|
||||
source.Reply(_("Syntax: \002BAN \037#channel\037 \037nick\037 [\037reason\037]\002\n"
|
||||
" \n"
|
||||
"Bans a selected nick on a channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 access \n"
|
||||
"and above on the channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "BAN", CHAN_BAN_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
if (this->name.equals_ci("BAN"))
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_BAN);
|
||||
SyntaxError(source, "BAN", _("BAN \037#channel\037 \037nick\037 [\037reason\037]"));
|
||||
}
|
||||
};
|
||||
|
||||
class CSBan : public Module
|
||||
{
|
||||
CommandCSBan commandcsban, commandcskb;
|
||||
CommandCSBan commandcsban;
|
||||
|
||||
public:
|
||||
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcsban("BAN"), commandcskb("KB")
|
||||
CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcsban("BAN")
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(ChanServ, &commandcsban);
|
||||
this->AddCommand(ChanServ, &commandcskb);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 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 CommandCSClear : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSClear() : Command("CLEAR", 2, 2)
|
||||
{
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string what = params[1];
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci = c ? c->ci : NULL;
|
||||
Anope::string modebuf;
|
||||
|
||||
ChannelMode *owner = ModeManager::FindChannelModeByName(CMODE_OWNER);
|
||||
ChannelMode *admin = ModeManager::FindChannelModeByName(CMODE_PROTECT);
|
||||
ChannelMode *op = ModeManager::FindChannelModeByName(CMODE_OP);
|
||||
ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP);
|
||||
ChannelMode *voice = ModeManager::FindChannelModeByName(CMODE_VOICE);
|
||||
|
||||
if (c)
|
||||
// XXX
|
||||
Log(LOG_COMMAND, u, this, ci) << what;
|
||||
|
||||
if (!c)
|
||||
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (!check_access(u, ci, CA_CLEAR))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (what.equals_ci("bans"))
|
||||
{
|
||||
c->ClearBans();
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_CLEARED_BANS, chan.c_str());
|
||||
}
|
||||
else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && what.equals_ci("excepts"))
|
||||
{
|
||||
c->ClearExcepts();
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_CLEARED_EXCEPTS, chan.c_str());
|
||||
}
|
||||
else if (ModeManager::FindChannelModeByName(CMODE_INVITE) && what.equals_ci("invites"))
|
||||
{
|
||||
c->ClearInvites();
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_CLEARED_INVITES, chan.c_str());
|
||||
}
|
||||
else if (what.equals_ci("modes"))
|
||||
{
|
||||
c->ClearModes();
|
||||
check_modes(c);
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_CLEARED_MODES, chan.c_str());
|
||||
}
|
||||
else if (what.equals_ci("ops"))
|
||||
{
|
||||
if (ircd->svsmode_ucmode)
|
||||
{
|
||||
if (owner)
|
||||
{
|
||||
modebuf = "-" + owner->ModeChar;
|
||||
|
||||
ircdproto->SendSVSModeChan(c, modebuf, "");
|
||||
}
|
||||
if (admin)
|
||||
{
|
||||
modebuf = "-" + admin->ModeChar;
|
||||
|
||||
ircdproto->SendSVSModeChan(c, modebuf, "");
|
||||
}
|
||||
if (op)
|
||||
{
|
||||
modebuf = "-" + op->ModeChar;
|
||||
|
||||
ircdproto->SendSVSModeChan(c, modebuf, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
|
||||
{
|
||||
UserContainer *uc = *it;
|
||||
|
||||
if (uc->Status->HasFlag(CMODE_OWNER))
|
||||
c->RemoveMode(NULL, owner, uc->user->nick);
|
||||
if (uc->Status->HasFlag(CMODE_PROTECT))
|
||||
c->RemoveMode(NULL, admin, uc->user->nick);
|
||||
if (uc->Status->HasFlag(CMODE_OP))
|
||||
c->RemoveMode(NULL, op, uc->user->nick);
|
||||
}
|
||||
}
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_CLEARED_OPS, chan.c_str());
|
||||
}
|
||||
else if ((halfop && what.equals_ci("hops")) || (voice && what.equals_ci("voices")))
|
||||
{
|
||||
ChannelMode *cm = what.equals_ci("hops") ? halfop : voice;
|
||||
|
||||
if (ircd->svsmode_ucmode)
|
||||
{
|
||||
modebuf = "-" + cm->ModeChar;
|
||||
|
||||
ircdproto->SendSVSModeChan(c, modebuf, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
|
||||
{
|
||||
UserContainer *uc = *it;
|
||||
|
||||
if (uc->Status->HasFlag(cm->Name))
|
||||
c->RemoveMode(NULL, cm, uc->user->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (what.equals_ci("users"))
|
||||
{
|
||||
Anope::string buf = "CLEAR USERS command from " + u->nick;
|
||||
|
||||
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
|
||||
{
|
||||
UserContainer *uc = *it++;
|
||||
|
||||
c->Kick(NULL, uc->user, "%s", buf.c_str());
|
||||
}
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_CLEARED_USERS, chan.c_str());
|
||||
}
|
||||
else
|
||||
SyntaxError(ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CLEAR);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_CLEAR);
|
||||
}
|
||||
};
|
||||
|
||||
class CSClear : public Module
|
||||
{
|
||||
CommandCSClear commandcsclear;
|
||||
|
||||
public:
|
||||
CSClear(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(ChanServ, &commandcsclear);
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSClear)
|
||||
@@ -0,0 +1,84 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2011 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 CommandCSClearUsers : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSClearUsers() : Command("CLEARUSERS", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Tells ChanServ to clear (kick) all users on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
const Anope::string &chan = params[0];
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
|
||||
Anope::string modebuf;
|
||||
|
||||
if (!c)
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
|
||||
else if (!check_access(u, ci, CA_FOUNDER))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
|
||||
Anope::string buf = "CLEARUSERS command from " + u->nick + " (" + u->Account()->display + ")";
|
||||
|
||||
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
|
||||
{
|
||||
UserContainer *uc = *it++;
|
||||
|
||||
c->Kick(NULL, uc->user, "%s", buf.c_str());
|
||||
}
|
||||
|
||||
source.Reply(_("All users have been kicked from \2%s\2."), chan.c_str());
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002CLEARUSERS \037channel\037\002\n"
|
||||
" \n"
|
||||
"Tells %s to clear (kick) all users certain settings on a channel."
|
||||
" \n"
|
||||
"By default, limited to those with founder access on the\n"
|
||||
"channel."), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "CLEAR", _("CLEARUSERS \037channel\037"));
|
||||
}
|
||||
};
|
||||
|
||||
class CSClearUsers : public Module
|
||||
{
|
||||
CommandCSClearUsers commandcsclearusers;
|
||||
|
||||
public:
|
||||
CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(ChanServ, &commandcsclearusers);
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSClearUsers)
|
||||
@@ -0,0 +1,184 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2011 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 CommandCSClone : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSClone() : Command("CLONE", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Copy all settings from one channel to another"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
const Anope::string &channel = params[0];
|
||||
const Anope::string &target = params[1];
|
||||
Anope::string what = params.size() > 2 ? params[2] : "";
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (!check_access(u, ci, CA_SET))
|
||||
{
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
ChannelInfo *target_ci = cs_findchan(target);
|
||||
if (!target_ci)
|
||||
{
|
||||
source.Reply(_(CHAN_X_NOT_REGISTERED), target.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (!IsFounder(u, ci) || !IsFounder(u, target_ci))
|
||||
{
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
|
||||
{
|
||||
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (what.equals_ci("ALL"))
|
||||
what.clear();
|
||||
|
||||
if (what.empty())
|
||||
{
|
||||
delete target_ci;
|
||||
target_ci = new ChannelInfo(ci);
|
||||
target_ci->name = target;
|
||||
RegisteredChannelList[target_ci->name] = target_ci;
|
||||
target_ci->c = findchan(target_ci->name);
|
||||
if (target_ci->c)
|
||||
{
|
||||
target_ci->c->ci = target_ci;
|
||||
|
||||
check_modes(target_ci->c);
|
||||
|
||||
ChannelMode *cm;
|
||||
if (u->FindChannel(target_ci->c) != NULL)
|
||||
{
|
||||
/* On most ircds you do not receive the admin/owner mode till its registered */
|
||||
if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
|
||||
target_ci->c->SetMode(NULL, cm, u->nick);
|
||||
else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
|
||||
target_ci->c->RemoveMode(NULL, cm, u->nick);
|
||||
}
|
||||
|
||||
/* Mark the channel as persistant */
|
||||
if (target_ci->c->HasMode(CMODE_PERM))
|
||||
target_ci->SetFlag(CI_PERSIST);
|
||||
/* Persist may be in def cflags, set it here */
|
||||
else if (target_ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM)))
|
||||
target_ci->c->SetMode(NULL, CMODE_PERM);
|
||||
|
||||
if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL)
|
||||
target_ci->bi->Join(target_ci->c);
|
||||
}
|
||||
|
||||
if (target_ci->c && !target_ci->c->topic.empty())
|
||||
{
|
||||
target_ci->last_topic = target_ci->c->topic;
|
||||
target_ci->last_topic_setter = target_ci->c->topic_setter;
|
||||
target_ci->last_topic_time = target_ci->c->topic_time;
|
||||
}
|
||||
else
|
||||
target_ci->last_topic_setter = Config->s_ChanServ;
|
||||
|
||||
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci));
|
||||
|
||||
source.Reply(_("All settings from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
|
||||
}
|
||||
else if (what.equals_ci("ACCESS"))
|
||||
{
|
||||
target_ci->ClearAccess();
|
||||
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
|
||||
{
|
||||
ChanAccess *access = ci->GetAccess(i);
|
||||
target_ci->AddAccess(access->GetMask(), access->level, access->creator, access->last_seen);
|
||||
}
|
||||
|
||||
source.Reply(_("All access entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
|
||||
}
|
||||
else if (what.equals_ci("AKICK"))
|
||||
{
|
||||
target_ci->ClearAkick();
|
||||
for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
|
||||
{
|
||||
AutoKick *akick = ci->GetAkick(i);
|
||||
if (akick->HasFlag(AK_ISNICK))
|
||||
target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
|
||||
else
|
||||
target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
|
||||
}
|
||||
|
||||
source.Reply(_("All akick entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
|
||||
}
|
||||
else if (what.equals_ci("BADWORDS"))
|
||||
{
|
||||
target_ci->ClearBadWords();
|
||||
for (unsigned i = 0; i < ci->GetBadWordCount(); ++i)
|
||||
{
|
||||
BadWord *bw = ci->GetBadWord(i);
|
||||
target_ci->AddBadWord(bw->word, bw->type);
|
||||
}
|
||||
|
||||
source.Reply(_("All badword entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->OnSyntaxError(source, "");
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
Log(LOG_COMMAND, u, this, ci) << "to clone it to " << target_ci->name;
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002CLONE \037channel\037 \037target\037 [all | access | akick | badwords]\002\n"
|
||||
" \n"
|
||||
"Copies all settings, access, akicks, etc from channel to the\n"
|
||||
"target channel. If access, akick, or badwords is specified then only\n"
|
||||
"the respective settings are transferred. You must have founder level\n"
|
||||
"access to \037channel\037 and \037target\037."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "CLONE", _("CLONE \037channel\037 \037target\037"));
|
||||
}
|
||||
};
|
||||
|
||||
class CSClone : public Module
|
||||
{
|
||||
CommandCSClone commandcsclone;
|
||||
|
||||
public:
|
||||
CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(ChanServ, &commandcsclone);
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSClone)
|
||||
+28
-23
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -20,36 +20,39 @@ class CommandCSDrop : public Command
|
||||
{
|
||||
this->SetFlag(CFLAG_ALLOW_FORBIDDEN);
|
||||
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
|
||||
this->SetDesc(_("Cancel the registration of a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
ChannelInfo *ci;
|
||||
const Anope::string &chan = params[0];
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_DROP_DISABLED); // XXX: READ_ONLY_MODE?
|
||||
source.Reply(_("Sorry, channel de-registration is temporarily disabled.")); // XXX: READ_ONLY_MODE?
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
ci = cs_findchan(chan);
|
||||
|
||||
if (ci->HasFlag(CI_FORBIDDEN) && !u->Account()->HasCommand("chanserv/drop"))
|
||||
if (ci->HasFlag(CI_FORBIDDEN) && !u->HasCommand("chanserv/drop"))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN, chan.c_str());
|
||||
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (ci->HasFlag(CI_SUSPENDED) && !u->Account()->HasCommand("chanserv/drop"))
|
||||
if (ci->HasFlag(CI_SUSPENDED) && !u->HasCommand("chanserv/drop"))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN, chan.c_str());
|
||||
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop"))
|
||||
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -69,31 +72,33 @@ class CommandCSDrop : public Command
|
||||
|
||||
delete ci;
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_DROPPED, chan.c_str());
|
||||
source.Reply(_("Channel \002%s\002 has been dropped."), chan.c_str());
|
||||
|
||||
FOREACH_MOD(I_OnChanDrop, OnChanDrop(chan));
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
if (u->Account() && u->Account()->IsServicesOper())
|
||||
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP_DROP);
|
||||
User *u = source.u;
|
||||
if (u->IsServicesOper())
|
||||
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
|
||||
" \n"
|
||||
"Unregisters the named channel. Only \002Services Operators\002\n"
|
||||
"can drop a channel for which they have not identified."));
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_HELP_DROP);
|
||||
source.Reply(_("Syntax: \002DROP \037channel\037\002\n"
|
||||
" \n"
|
||||
"Unregisters the named channel. Can only be used by\n"
|
||||
"\002channel founder\002."));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "DROP", CHAN_DROP_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_DROP);
|
||||
SyntaxError(source, "DROP", _("DROP \037channel\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+31
-35
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -19,31 +19,32 @@ class CommandCSForbid : public Command
|
||||
CommandCSForbid() : Command("FORBID", 1, 2, "chanserv/forbid")
|
||||
{
|
||||
this->SetFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL);
|
||||
this->SetDesc(_("Prevent a channel from being used"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci;
|
||||
Anope::string chan = params[0];
|
||||
Anope::string reason = params.size() > 1 ? params[1] : "";
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &reason = params.size() > 1 ? params[1] : "";
|
||||
|
||||
Channel *c;
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (Config->ForceForbidReason && reason.empty())
|
||||
{
|
||||
SyntaxError(ChanServ, u, "FORBID", CHAN_FORBID_SYNTAX_REASON);
|
||||
SyntaxError(source, "FORBID", _("FORBID \037channel\037 \037reason\037"));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (chan[0] != '#')
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_SYMBOL_REQUIRED);
|
||||
source.Reply(_(CHAN_SYMBOL_REQUIRED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(ChanServ, READ_ONLY_MODE);
|
||||
source.Reply(_(READ_ONLY_MODE));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -51,67 +52,62 @@ class CommandCSForbid : public Command
|
||||
delete ci;
|
||||
|
||||
ci = new ChannelInfo(chan);
|
||||
if (!ci)
|
||||
{
|
||||
// this cant happen?
|
||||
//Alog() << Config->s_ChanServ << ": Valid FORBID for " << ci->name << " by " << u->nick << " failed";
|
||||
u->SendMessage(ChanServ, CHAN_FORBID_FAILED, chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
ci->SetFlag(CI_FORBIDDEN);
|
||||
ci->forbidby = u->nick;
|
||||
ci->forbidreason = reason;
|
||||
|
||||
if ((c = findchan(ci->name)))
|
||||
Channel *c = ci->c;
|
||||
if (c)
|
||||
{
|
||||
/* Before banning everyone, it might be prudent to clear +e and +I lists..
|
||||
* to prevent ppl from rejoining.. ~ Viper */
|
||||
c->ClearExcepts();
|
||||
c->ClearInvites();
|
||||
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = c->GetModeList(CMODE_EXCEPT);
|
||||
for (; modes.first != modes.second; ++modes.first)
|
||||
c->RemoveMode(NULL, CMODE_EXCEPT, modes.first->second);
|
||||
modes = c->GetModeList(CMODE_INVITEOVERRIDE);
|
||||
for (; modes.first != modes.second; ++modes.first)
|
||||
c->RemoveMode(NULL, CMODE_INVITEOVERRIDE, modes.first->second);
|
||||
|
||||
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
|
||||
{
|
||||
UserContainer *uc = *it++;
|
||||
|
||||
if (is_oper(uc->user))
|
||||
if (uc->user->HasMode(UMODE_OPER))
|
||||
continue;
|
||||
|
||||
c->Kick(ChanServ, uc->user, "%s", !reason.empty() ? reason.c_str() : GetString(uc->user, CHAN_FORBID_REASON).c_str());
|
||||
c->Kick(ChanServ, uc->user, "%s", !reason.empty() ? reason.c_str() : GetString(uc->user->Account(), "This channel has been forbidden.").c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (ircd->chansqline)
|
||||
{
|
||||
XLine x(chan, "Forbidden");
|
||||
ircdproto->SendSQLine(&x);
|
||||
ircdproto->SendSQLine(NULL, &x);
|
||||
}
|
||||
|
||||
if (Config->WallForbid)
|
||||
ircdproto->SendGlobops(ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
|
||||
Log(LOG_ADMIN, u, this, ci) << (!ci->forbidreason.empty() ? ci->forbidreason : "No reason");
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_FORBID_SUCCEEDED, chan.c_str());
|
||||
source.Reply(_("Channel \002%s\002 is now forbidden."), chan.c_str());
|
||||
|
||||
FOREACH_MOD(I_OnChanForbidden, OnChanForbidden(ci));
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP_FORBID);
|
||||
source.Reply(_("Syntax: \002FORBID \037channel\037 [\037reason\037]\002\n"
|
||||
" \n"
|
||||
"Disallows anyone from registering or using the given\n"
|
||||
"channel. May be cancelled by dropping the channel.\n"
|
||||
" \n"
|
||||
"Reason may be required on certain networks."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "FORBID", CHAN_FORBID_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_FORBID);
|
||||
SyntaxError(source, "FORBID", _("FORBID \037channel\037 [\037reason\037]"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+17
-19
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,49 +18,47 @@ class CommandCSGetKey : public Command
|
||||
public:
|
||||
CommandCSGetKey() : Command("GETKEY", 1, 1)
|
||||
{
|
||||
this->SetDesc(_("Returns the key of the given channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
ChannelInfo *ci;
|
||||
Anope::string key;
|
||||
const Anope::string &chan = params[0];
|
||||
|
||||
ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (!check_access(u, ci, CA_GETKEY) && !u->Account()->HasCommand("chanserv/getkey"))
|
||||
if (!check_access(u, ci, CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
Anope::string key;
|
||||
if (!ci->c || !ci->c->GetParam(CMODE_KEY, key))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_GETKEY_NOKEY, chan.c_str());
|
||||
source.Reply(_("The channel \002%s\002 has no key."), chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool override = !check_access(u, ci, CA_GETKEY);
|
||||
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_GETKEY_KEY, chan.c_str(), key.c_str());
|
||||
source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_GETKEY);
|
||||
source.Reply(_("Syntax: \002GETKEY \037channel\037\002\n"
|
||||
" \n"
|
||||
"Returns the key of the given channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "GETKEY", CHAN_GETKEY_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_GETKEY);
|
||||
SyntaxError(source, "GETKEY", _("GETKEY \037channel\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+25
-10
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -20,25 +20,40 @@ class CommandCSHelp : public Command
|
||||
{
|
||||
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
|
||||
this->SetFlag(CFLAG_STRIP_CHANNEL);
|
||||
this->SetDesc(_("Displays this list and give information about commands"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
mod_help_cmd(ChanServ, u, params[0]);
|
||||
mod_help_cmd(ChanServ, source.u, NULL, params[0]);
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP);
|
||||
User *u = source.u;
|
||||
source.Reply(_("\002%s\002 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"
|
||||
"\002%s%s \037command\037\002. For more information on a\n"
|
||||
"specific command, type \002%s%s HELP \037command\037\002."),
|
||||
ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
|
||||
ChanServ->nick.c_str());
|
||||
for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it)
|
||||
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || (u->Account() && u->Account()->HasCommand(it->second->permission)))
|
||||
it->second->OnServHelp(u);
|
||||
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
|
||||
it->second->OnServHelp(source);
|
||||
if (Config->CSExpire >= 86400)
|
||||
u->SendMessage(ChanServ, CHAN_HELP_EXPIRES, Config->CSExpire / 86400);
|
||||
if (u->Account() && u->Account()->IsServicesOper())
|
||||
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP);
|
||||
source.Reply(_("Note that any channel which is not used for %d days\n"
|
||||
"(i.e. which no user on the channel's access list enters\n"
|
||||
"for that period of time) will be automatically dropped."), Config->CSExpire / 86400);
|
||||
if (u->IsServicesOper())
|
||||
source.Reply(_(" \n"
|
||||
"Services Operators can also drop any channel without needing\n"
|
||||
"to identify via password, and may view the access, AKICK,\n"
|
||||
"and level setting lists for any channel."));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+54
-55
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -27,27 +27,30 @@ class CommandCSInfo : public Command
|
||||
}
|
||||
|
||||
public:
|
||||
CommandCSInfo() : Command("INFO", 1, 1)
|
||||
CommandCSInfo() : Command("INFO", 1, 2)
|
||||
{
|
||||
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
|
||||
this->SetFlag(CFLAG_ALLOW_SUSPENDED);
|
||||
this->SetFlag(CFLAG_ALLOW_FORBIDDEN);
|
||||
this->SetDesc(_("Lists information about the named registered channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex");
|
||||
bool show_all = false;
|
||||
const Anope::string &chan = params[0];
|
||||
|
||||
ChannelInfo *ci = cs_findchan(chan);
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
bool has_auspex = u->IsIdentified() && u->HasPriv("chanserv/auspex");
|
||||
bool show_all = false;
|
||||
|
||||
if (ci->HasFlag(CI_FORBIDDEN))
|
||||
{
|
||||
if (is_oper(u) && !ci->forbidby.empty())
|
||||
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN_OPER, chan.c_str(), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : GetString(u, NO_REASON).c_str());
|
||||
if (u->HasMode(UMODE_OPER) && !ci->forbidby.empty())
|
||||
source.Reply(_(CHAN_X_FORBIDDEN_OPER), chan.c_str(), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : _(NO_REASON));
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_X_FORBIDDEN, chan.c_str());
|
||||
source.Reply(_(CHAN_X_FORBIDDEN), chan.c_str());
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
@@ -56,78 +59,74 @@ class CommandCSInfo : public Command
|
||||
if (has_auspex || check_access(u, ci, CA_INFO))
|
||||
show_all = true;
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_INFO_HEADER, chan.c_str());
|
||||
u->SendMessage(ChanServ, CHAN_INFO_NO_FOUNDER, ci->founder->display.c_str());
|
||||
source.Reply(_(CHAN_INFO_HEADER), chan.c_str());
|
||||
source.Reply(_(" Founder: %s"), ci->founder->display.c_str());
|
||||
|
||||
if (show_all && ci->successor)
|
||||
u->SendMessage(ChanServ, CHAN_INFO_NO_SUCCESSOR, ci->successor->display.c_str());
|
||||
source.Reply(_(" Successor: %s"), ci->successor->display.c_str());
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_INFO_DESCRIPTION, ci->desc.c_str());
|
||||
u->SendMessage(ChanServ, CHAN_INFO_TIME_REGGED, do_strftime(ci->time_registered).c_str());
|
||||
u->SendMessage(ChanServ, CHAN_INFO_LAST_USED, do_strftime(ci->last_used).c_str());
|
||||
source.Reply(_(" Description: %s"), ci->desc.c_str());
|
||||
source.Reply(_(" Registered: %s"), do_strftime(ci->time_registered).c_str());
|
||||
source.Reply(_(" Last used: %s"), do_strftime(ci->last_used).c_str());
|
||||
|
||||
if (!ci->last_topic.empty() && (show_all || (!ci->HasMLock(CMODE_SECRET, true) && (!ci->c || !ci->c->HasMode(CMODE_SECRET)))))
|
||||
ModeLock *secret = ci->GetMLock(CMODE_SECRET);
|
||||
if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode(CMODE_SECRET)))))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_INFO_LAST_TOPIC, ci->last_topic.c_str());
|
||||
u->SendMessage(ChanServ, CHAN_INFO_TOPIC_SET_BY, ci->last_topic_setter.c_str());
|
||||
source.Reply(_(" Last topic: %s"), ci->last_topic.c_str());
|
||||
source.Reply(_(" Topic set by: %s"), ci->last_topic_setter.c_str());
|
||||
}
|
||||
|
||||
if (!ci->entry_message.empty() && show_all)
|
||||
u->SendMessage(ChanServ, CHAN_INFO_ENTRYMSG, ci->entry_message.c_str());
|
||||
|
||||
if (show_all)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_INFO_BANTYPE, ci->bantype);
|
||||
source.Reply(_(" Ban type: %d"), ci->bantype);
|
||||
Anope::string optbuf;
|
||||
|
||||
CheckOptStr(optbuf, CI_KEEPTOPIC, GetString(u, CHAN_INFO_OPT_KEEPTOPIC), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_OPNOTICE, GetString(u, CHAN_INFO_OPT_OPNOTICE), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_PEACE, GetString(u, CHAN_INFO_OPT_PEACE), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_PRIVATE, GetString(u, NICK_INFO_OPT_PRIVATE), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_RESTRICTED, GetString(u, CHAN_INFO_OPT_RESTRICTED), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SECURE, GetString(u, CHAN_INFO_OPT_SECURE), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SECUREFOUNDER, GetString(u, CHAN_INFO_OPT_SECUREFOUNDER), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SECUREOPS, GetString(u, CHAN_INFO_OPT_SECUREOPS), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_KEEPTOPIC, _("Topic Retention"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_OPNOTICE, _("OP Notice"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_PEACE, _("Peace"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_PRIVATE, _("Private"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_RESTRICTED, _("Restricted Access"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SECURE, _("Secure"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SECUREFOUNDER, _("Secure Founder"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SECUREOPS, _("Secure Ops"), ci, u->Account());
|
||||
if (ci->HasFlag(CI_SIGNKICK))
|
||||
CheckOptStr(optbuf, CI_SIGNKICK, GetString(u, CHAN_INFO_OPT_SIGNKICK), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SIGNKICK, _("Signed kicks"), ci, u->Account());
|
||||
else
|
||||
CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, GetString(u, CHAN_INFO_OPT_SIGNKICK), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_TOPICLOCK, GetString(u, CHAN_INFO_OPT_TOPICLOCK), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_XOP, GetString(u, CHAN_INFO_OPT_XOP), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_PERSIST, GetString(u, CHAN_INFO_OPT_PERSIST), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, _("Signed kicks"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_TOPICLOCK, _("Topic Lock"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_XOP, _("xOP lists system"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_PERSIST, _("Persistant"), ci, u->Account());
|
||||
CheckOptStr(optbuf, CI_NO_EXPIRE, _("No expire"), ci, u->Account());
|
||||
|
||||
u->SendMessage(ChanServ, NICK_INFO_OPTIONS, optbuf.empty() ? GetString(u, NICK_INFO_OPT_NONE).c_str() : optbuf.c_str());
|
||||
u->SendMessage(ChanServ, CHAN_INFO_MODE_LOCK, get_mlock_modes(ci, 1).c_str());
|
||||
source.Reply(_(NICK_INFO_OPTIONS), optbuf.empty() ? _("None") : optbuf.c_str());
|
||||
source.Reply(_(" Mode lock: %s"), get_mlock_modes(ci, 1).c_str());
|
||||
|
||||
// XXX: we could just as easily (and tidily) merge this in with the flags display above.
|
||||
if (ci->HasFlag(CI_NO_EXPIRE))
|
||||
u->SendMessage(ChanServ, CHAN_INFO_NO_EXPIRE);
|
||||
else
|
||||
u->SendMessage(ChanServ, CHAN_INFO_EXPIRE, do_strftime(ci->last_used + Config->CSExpire).c_str());
|
||||
if (!ci->HasFlag(CI_NO_EXPIRE))
|
||||
source.Reply(_(" Expires on: %s"), do_strftime(ci->last_used + Config->CSExpire).c_str());
|
||||
}
|
||||
if (ci->HasFlag(CI_SUSPENDED))
|
||||
u->SendMessage(ChanServ, CHAN_X_SUSPENDED, ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : GetString(u, NO_REASON).c_str());
|
||||
source.Reply(_(" Suspended: [%s] %s"), ci->forbidby.c_str(), !ci->forbidreason.empty() ? ci->forbidreason.c_str() : _(NO_REASON));
|
||||
|
||||
FOREACH_MOD(I_OnChanInfo, OnChanInfo(u, ci, show_all));
|
||||
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, show_all));
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_INFO);
|
||||
|
||||
source.Reply(_("Syntax: \002INFO \037channel\037\002\n"
|
||||
" \n"
|
||||
"Lists information about the named registered channel,\n"
|
||||
"including its founder, time of registration, last time\n"
|
||||
"used, description, and mode lock, if any. If \002ALL\002 is \n"
|
||||
"specified, the entry message and successor will also \n"
|
||||
"be displayed."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "INFO", CHAN_INFO_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_INFO);
|
||||
SyntaxError(source, "INFO", _("INFO \037channel\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+24
-21
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,18 +18,20 @@ class CommandCSInvite : public Command
|
||||
public:
|
||||
CommandCSInvite() : Command("INVITE", 1, 3)
|
||||
{
|
||||
this->SetDesc(_("Tells ChanServ to invite you into a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Channel *c;
|
||||
ChannelInfo *ci;
|
||||
User *u2;
|
||||
const Anope::string &chan = params[0];
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
|
||||
if (!(c = findchan(chan)))
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -37,17 +39,18 @@ class CommandCSInvite : public Command
|
||||
|
||||
if (!check_access(u, ci, CA_INVITE))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
User *u2;
|
||||
if (params.size() == 1)
|
||||
u2 = u;
|
||||
else
|
||||
{
|
||||
if (!(u2 = finduser(params[1])))
|
||||
{
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, params[1].c_str());
|
||||
source.Reply(_(NICK_X_NOT_IN_USE), params[1].c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
}
|
||||
@@ -56,30 +59,30 @@ class CommandCSInvite : public Command
|
||||
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
|
||||
|
||||
if (c->FindUser(u2))
|
||||
u->SendMessage(ChanServ, CHAN_INVITE_ALREADY_IN, c->name.c_str());
|
||||
source.Reply(_("You are already in \002%s\002! "), c->name.c_str());
|
||||
else
|
||||
{
|
||||
ircdproto->SendInvite(whosends(ci), chan, u2->nick);
|
||||
u->SendMessage(whosends(ci), CHAN_INVITE_OTHER_SUCCESS, u2->nick.c_str(), c->name.c_str());
|
||||
u2->SendMessage(whosends(ci), CHAN_INVITE_SUCCESS, c->name.c_str());
|
||||
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
|
||||
u2->SendMessage(whosends(ci), _("You have been invited to \002%s\002."), c->name.c_str());
|
||||
}
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_INVITE);
|
||||
source.Reply(_("Syntax: \002INVITE \037channel\037\002\n"
|
||||
" \n"
|
||||
"Tells %s to invite you into the given channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 and above\n"
|
||||
"on the channel."), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "INVITE", CHAN_INVITE_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_INVITE);
|
||||
SyntaxError(source, "INVITE", _("INVITE \037channel\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+33
-36
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -16,39 +16,38 @@
|
||||
class CommandCSKick : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSKick(const Anope::string &cname) : Command(cname, 2, 3)
|
||||
CommandCSKick() : Command("KICK", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Kicks a selected nick from a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string target = params[1];
|
||||
Anope::string reason = params.size() > 2 ? params[2] : "Requested";
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &target = params[1];
|
||||
const Anope::string &reason = params.size() > 2 ? params[2] : "Requested";
|
||||
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci;
|
||||
User *u2;
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = ci->c;
|
||||
bool is_same = target.equals_ci(u->nick);
|
||||
User *u2 = is_same ? u : finduser(target);
|
||||
|
||||
int is_same;
|
||||
|
||||
is_same = target.equals_cs(u->nick) ? 1 : target.equals_ci(u->nick);
|
||||
|
||||
if (c)
|
||||
ci = c->ci;
|
||||
ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2);
|
||||
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
|
||||
|
||||
if (!c)
|
||||
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (is_same ? !(u2 = u) : !(u2 = finduser(target)))
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, target.c_str());
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
|
||||
else if (!u2)
|
||||
source.Reply(_(NICK_X_NOT_IN_USE), target.c_str());
|
||||
else if (!is_same ? !check_access(u, ci, CA_KICK) : !check_access(u, ci, CA_KICKME))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (!is_same && (ci->HasFlag(CI_PEACE)) && get_access(u2, ci) >= get_access(u, ci))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_level >= u_level)
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (u2->IsProtected())
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!c->FindUser(u2))
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
|
||||
source.Reply(_(NICK_X_NOT_ON_CHAN), u2->nick.c_str(), c->name.c_str());
|
||||
else
|
||||
{
|
||||
// XXX
|
||||
@@ -62,36 +61,34 @@ class CommandCSKick : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_KICK);
|
||||
source.Reply(_("Syntax: \002KICK \037#channel\037 \037nick\037 [\037reason\037]\002\n"
|
||||
" \n"
|
||||
"Kicks a selected nick on a channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 access \n"
|
||||
"and above on the channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "KICK", CHAN_KICK_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
if (this->name.equals_ci("KICK"))
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_KICK);
|
||||
SyntaxError(source, "KICK", _("KICK \037#channel\037 \037nick\037 [\037reason\037]"));
|
||||
}
|
||||
};
|
||||
|
||||
class CSKick : public Module
|
||||
{
|
||||
CommandCSKick commandcskick, commandcsk;
|
||||
CommandCSKick commandcskick;
|
||||
|
||||
public:
|
||||
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandcskick("KICK"), commandcsk("K")
|
||||
CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(ChanServ, &commandcskick);
|
||||
this->AddCommand(ChanServ, &commandcsk);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+35
-44
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -16,57 +16,48 @@
|
||||
|
||||
class CommandCSList : public Command
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CommandCSList() : Command("LIST", 1, 2)
|
||||
{
|
||||
this->SetFlag(CFLAG_STRIP_CHANNEL);
|
||||
this->SetDesc(_("Lists all registered channels matching the given pattern"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
|
||||
Anope::string pattern = params[0];
|
||||
unsigned nchans;
|
||||
char buf[BUFSIZE];
|
||||
bool is_servadmin = u->Account()->HasCommand("chanserv/list");
|
||||
bool is_servadmin = u->HasCommand("chanserv/list");
|
||||
int count = 0, from = 0, to = 0;
|
||||
bool forbidden = false, suspended = false, channoexpire = false;
|
||||
|
||||
if (Config->CSListOpersOnly && !is_oper(u))
|
||||
if (Config->CSListOpersOnly && !u->HasMode(UMODE_OPER))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
return MOD_STOP;
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (pattern[0] == '#')
|
||||
{
|
||||
Anope::string tmp = myStrGetToken(pattern.substr(1), '-', 0); /* Read FROM out */
|
||||
if (tmp.empty())
|
||||
Anope::string n1 = myStrGetToken(pattern.substr(1), '-', 0), /* Read FROM out */
|
||||
n2 = myStrGetTokenRemainder(pattern, '-', 1);
|
||||
|
||||
try
|
||||
{
|
||||
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
|
||||
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
|
||||
from = convertTo<int>(n1);
|
||||
to = convertTo<int>(n2);
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
source.Reply(_(LIST_INCORRECT_RANGE));
|
||||
source.Reply(_("To search for channels starting with #, search for the channel\n"
|
||||
"name without the #-sign prepended (\002anope\002 instead of \002#anope\002)."));
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (!tmp.is_number_only())
|
||||
{
|
||||
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
|
||||
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
|
||||
return MOD_CONT;
|
||||
}
|
||||
from = convertTo<int>(tmp);
|
||||
tmp = myStrGetTokenRemainder(pattern, '-', 1); /* Read TO out */
|
||||
if (tmp.empty())
|
||||
{
|
||||
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
|
||||
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (!tmp.is_number_only())
|
||||
{
|
||||
u->SendMessage(ChanServ, LIST_INCORRECT_RANGE);
|
||||
u->SendMessage(ChanServ, CS_LIST_INCORRECT_RANGE);
|
||||
return MOD_CONT;
|
||||
}
|
||||
to = convertTo<int>(tmp);
|
||||
|
||||
pattern = "*";
|
||||
}
|
||||
|
||||
@@ -89,7 +80,7 @@ public:
|
||||
|
||||
Anope::string spattern = "#" + pattern;
|
||||
|
||||
u->SendMessage(ChanServ, NICK_LIST_HEADER, pattern.c_str());
|
||||
source.Reply(_(LIST_HEADER), pattern.c_str());
|
||||
|
||||
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
|
||||
{
|
||||
@@ -119,30 +110,30 @@ public:
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%-20s %s", ci->name.c_str(), !ci->desc.empty() ? ci->desc.c_str() : "");
|
||||
|
||||
u->SendMessage(Config->s_ChanServ, " %c%s", noexpire_char, buf);
|
||||
source.Reply(" %c%s", noexpire_char, buf);
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_LIST_END, nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
|
||||
source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_LIST);
|
||||
source.Reply(_("Syntax: \002LIST \037pattern\037\002\n"
|
||||
" \n"
|
||||
"Lists all registered channels matching the given pattern.\n"
|
||||
"(Channels with the \002PRIVATE\002 option set are not listed.)\n"
|
||||
"Note that a preceding '#' specifies a range, channel names\n"
|
||||
"are to be written without '#'."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "LIST", NICK_LIST_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_LIST);
|
||||
SyntaxError(source, "LIST", _(NICK_LIST_SYNTAX));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2011 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 CommandCSMode : public Command
|
||||
{
|
||||
bool CanSet(User *u, ChannelInfo *ci, ChannelModeName mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case CMODE_OWNER:
|
||||
return check_access(u, ci, CA_OWNER);
|
||||
case CMODE_PROTECT:
|
||||
return check_access(u, ci, CA_PROTECT);
|
||||
case CMODE_OP:
|
||||
return check_access(u, ci, CA_OPDEOP);
|
||||
case CMODE_HALFOP:
|
||||
return check_access(u, ci, CA_HALFOP);
|
||||
case CMODE_VOICE:
|
||||
return check_access(u, ci, CA_VOICE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DoLock(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
const Anope::string &subcommand = params[2];
|
||||
const Anope::string ¶m = params.size() > 3 ? params[3] : "";
|
||||
|
||||
if (subcommand.equals_ci("ADD") && !param.empty())
|
||||
{
|
||||
spacesepstream sep(param);
|
||||
Anope::string modes;
|
||||
|
||||
sep.GetToken(modes);
|
||||
|
||||
int adding = -1;
|
||||
for (size_t i = 0; i < modes.length(); ++i)
|
||||
{
|
||||
switch (modes[i])
|
||||
{
|
||||
case '+':
|
||||
adding = 1;
|
||||
break;
|
||||
case '-':
|
||||
adding = 0;
|
||||
break;
|
||||
default:
|
||||
if (adding == -1)
|
||||
break;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
|
||||
if (!cm || !cm->CanSet(u))
|
||||
{
|
||||
source.Reply(_("Unknown mode character %c ignored."), modes[i]);
|
||||
break;
|
||||
}
|
||||
Anope::string mode_param;
|
||||
if (((cm->Type == MODE_STATUS || cm->Type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->Type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
|
||||
source.Reply(_("Missing parameter for mode %c."), cm->ModeChar);
|
||||
else
|
||||
{
|
||||
ci->SetMLock(cm, adding, mode_param, u->nick);
|
||||
if (!mode_param.empty())
|
||||
mode_param = " " + mode_param;
|
||||
source.Reply(_("%c%c%s locked on %s"), adding ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ci->c)
|
||||
check_modes(ci->c);
|
||||
}
|
||||
else if (subcommand.equals_ci("DEL") && !param.empty())
|
||||
{
|
||||
spacesepstream sep(param);
|
||||
Anope::string modes;
|
||||
|
||||
sep.GetToken(modes);
|
||||
|
||||
int adding = -1;
|
||||
for (size_t i = 0; i < modes.length(); ++i)
|
||||
{
|
||||
switch (modes[i])
|
||||
{
|
||||
case '+':
|
||||
adding = 1;
|
||||
break;
|
||||
case '-':
|
||||
adding = 0;
|
||||
break;
|
||||
default:
|
||||
if (adding == -1)
|
||||
break;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
|
||||
if (!cm || !cm->CanSet(u))
|
||||
{
|
||||
source.Reply(_("Unknown mode character %c ignored."), modes[i]);
|
||||
break;
|
||||
}
|
||||
Anope::string mode_param;
|
||||
if (!cm->Type == MODE_REGULAR && !sep.GetToken(mode_param))
|
||||
source.Reply(_("Missing parameter for mode %c."), cm->ModeChar);
|
||||
else
|
||||
{
|
||||
if (ci->RemoveMLock(cm, mode_param))
|
||||
{
|
||||
if (!mode_param.empty())
|
||||
mode_param = " " + mode_param;
|
||||
source.Reply(_("%c%c%s has been unlocked from %s."), adding == 1 ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
source.Reply(_("%c is not locked on %s."), cm->ModeChar, ci->name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (subcommand.equals_ci("LIST"))
|
||||
{
|
||||
const std::multimap<ChannelModeName, ModeLock> &mlocks = ci->GetMLock();
|
||||
if (mlocks.empty())
|
||||
{
|
||||
source.Reply(_("Channel %s has no mode locks."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
source.Reply(_("Mode locks for %s:"), ci->name.c_str());
|
||||
for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
|
||||
{
|
||||
const ModeLock &ml = it->second;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name);
|
||||
if (!cm)
|
||||
continue;
|
||||
|
||||
Anope::string modeparam = ml.param;
|
||||
if (!modeparam.empty())
|
||||
modeparam = " " + modeparam;
|
||||
source.Reply(_("%c%c%s, by %s on %s"), ml.set ? '+' : '-', cm->ModeChar, modeparam.c_str(), ml.setter.c_str(), do_strftime(ml.created).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(source, subcommand);
|
||||
}
|
||||
|
||||
void DoSet(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
spacesepstream sep(params.size() > 3 ? params[3] : "");
|
||||
Anope::string modes = params[2], param;
|
||||
|
||||
Log(LOG_COMMAND, u, this, ci) << "to set " << params[2];
|
||||
|
||||
int adding = -1;
|
||||
for (size_t i = 0; i < modes.length(); ++i)
|
||||
{
|
||||
switch (modes[i])
|
||||
{
|
||||
case '+':
|
||||
adding = 1;
|
||||
break;
|
||||
case '-':
|
||||
adding = 0;
|
||||
break;
|
||||
case '*':
|
||||
if (adding == -1)
|
||||
break;
|
||||
for (unsigned j = 0; j < ModeManager::ChannelModes.size(); ++j)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::ChannelModes[j];
|
||||
if (cm->CanSet(u))
|
||||
{
|
||||
if (cm->Type == MODE_REGULAR || (!adding && cm->Type == MODE_PARAM))
|
||||
{
|
||||
if (adding)
|
||||
ci->c->SetMode(NULL, cm);
|
||||
else
|
||||
ci->c->RemoveMode(NULL, cm);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (adding == -1)
|
||||
break;
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
|
||||
if (!cm || !cm->CanSet(u))
|
||||
continue;
|
||||
switch (cm->Type)
|
||||
{
|
||||
case MODE_REGULAR:
|
||||
if (adding)
|
||||
ci->c->SetMode(NULL, cm);
|
||||
else
|
||||
ci->c->RemoveMode(NULL, cm);
|
||||
break;
|
||||
case MODE_PARAM:
|
||||
if (adding && !sep.GetToken(param))
|
||||
break;
|
||||
if (adding)
|
||||
ci->c->SetMode(NULL, cm, param);
|
||||
else
|
||||
ci->c->RemoveMode(NULL, cm);
|
||||
break;
|
||||
case MODE_STATUS:
|
||||
{
|
||||
if (!sep.GetToken(param))
|
||||
break;
|
||||
|
||||
if (!this->CanSet(u, ci, cm->Name))
|
||||
{
|
||||
source.Reply(_("You do not have access to set mode %c."), cm->ModeChar);
|
||||
break;
|
||||
}
|
||||
|
||||
ChanAccess *u_access = ci->GetAccess(u);
|
||||
int16 u_level = u_access ? u_access->level : 0;
|
||||
|
||||
if (str_is_wildcard(param))
|
||||
{
|
||||
for (CUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
|
||||
{
|
||||
UserContainer *uc = *it;
|
||||
|
||||
ChanAccess *targ_access = ci->GetAccess(uc->user);
|
||||
int16 t_level = targ_access ? targ_access->level : 0;
|
||||
|
||||
if (t_level > u_level)
|
||||
{
|
||||
source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Anope::Match(uc->user->GetMask(), param))
|
||||
{
|
||||
if (adding)
|
||||
ci->c->SetMode(NULL, cm, uc->user->nick);
|
||||
else
|
||||
ci->c->RemoveMode(NULL, cm, uc->user->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
User *target = finduser(param);
|
||||
if (target != NULL)
|
||||
{
|
||||
ChanAccess *targ_access = ci->GetAccess(target);
|
||||
int16 t_level = targ_access ? targ_access->level : 0;
|
||||
if (t_level > u_level)
|
||||
{
|
||||
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (adding)
|
||||
ci->c->SetMode(NULL, cm, param);
|
||||
else
|
||||
ci->c->RemoveMode(NULL, cm, param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MODE_LIST:
|
||||
if (!sep.GetToken(param))
|
||||
break;
|
||||
if (adding)
|
||||
ci->c->SetMode(NULL, cm, param);
|
||||
else
|
||||
{
|
||||
std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = ci->c->GetModeList(cm->Name);
|
||||
for (; its.first != its.second;)
|
||||
{
|
||||
const Anope::string &mask = its.first->second;
|
||||
++its.first;
|
||||
|
||||
if (Anope::Match(mask, param))
|
||||
ci->c->RemoveMode(NULL, cm, mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CommandCSMode() : Command("MODE", 3, 4)
|
||||
{
|
||||
this->SetDesc(_("Control modes and mode locks on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
const Anope::string &subcommand = params[1];
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
|
||||
if (!ci || !ci->c)
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), ci->name.c_str());
|
||||
else if (!check_access(u, ci, CA_MODE) && !u->HasCommand("chanserv/mode"))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (subcommand.equals_ci("LOCK"))
|
||||
this->DoLock(source, params);
|
||||
else if (subcommand.equals_ci("SET"))
|
||||
this->DoSet(source, params);
|
||||
else
|
||||
this->OnSyntaxError(source, "");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002MODE \037channel\037 LOCK {ADD|DEL|LIST} [\037what\037]\002\n"
|
||||
" \002MODE \037channel\037 SET \037modes\037\002\n"
|
||||
" \n"
|
||||
"Mainly controls mode locks and mode access (which is different from channel access)\n"
|
||||
"on a channel.\n"
|
||||
" \n"
|
||||
"The \002MODE LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n"
|
||||
"If a mode is locked on or off, services will not allow that mode to be changed.\n"
|
||||
"Example:\n"
|
||||
" \002MODE #channel LOCK ADD +bmnt *!*@*aol*\002\n"
|
||||
" \n"
|
||||
"The \002MODE SET\002 command allows you to set modes through services. Wildcards * and ? may\n"
|
||||
"be given as parameters for list and status modes.\n"
|
||||
"Example:\n"
|
||||
" \002MODE #channel SET +v *\002\n"
|
||||
" Sets voice status to all users in the channel.\n"
|
||||
" \n"
|
||||
" \002MODE #channel SET -b ~c:*\n"
|
||||
" Clears all extended bans that start with ~c:"));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "MODE", _("MODE \037channel\037 {LOCK|SET} [\037modes\037 | {ADD|DEL|LIST} [\037what\037]]"));
|
||||
}
|
||||
};
|
||||
|
||||
class CSMode : public Module
|
||||
{
|
||||
CommandCSMode commandcsmode;
|
||||
|
||||
public:
|
||||
CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
this->SetType(CORE);
|
||||
|
||||
this->AddCommand(ChanServ, &commandcsmode);
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(CSMode)
|
||||
+304
-252
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -13,381 +13,433 @@
|
||||
|
||||
#include "module.h"
|
||||
|
||||
/** do_util: not a command, but does the job of others
|
||||
* @param u The user doing the command
|
||||
* @param com The command calling this function
|
||||
* @param cm A channel mode class
|
||||
* @param chan The channel its being set on
|
||||
* @param nick The nick the modes being set on
|
||||
* @param set Is the mode being set or removed
|
||||
* @param level The acecss level required to set this mode on someone else
|
||||
* @param levelself The access level required to set this mode on yourself
|
||||
* @param name The name, eg "OP" or "HALFOP"
|
||||
* @param notice Flag required on a channel to send a notice
|
||||
*/
|
||||
static CommandReturn do_util(User *u, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, const Anope::string &name, ChannelInfoFlag notice)
|
||||
|
||||
class CommandModeBase : public Command
|
||||
{
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci = c ? c->ci : NULL;
|
||||
User *u2;
|
||||
|
||||
Anope::string realnick = (!nick.empty() ? nick : u->nick);
|
||||
bool is_same = u->nick.equals_ci(realnick);
|
||||
|
||||
if (!c)
|
||||
u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str());
|
||||
else if (is_same ? !(u2 = u) : !(u2 = finduser(realnick)))
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_IN_USE, realnick.c_str());
|
||||
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (!set && !is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (!set && u2->IsProtected() && !is_same)
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
else if (!c->FindUser(u2))
|
||||
u->SendMessage(ChanServ, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
|
||||
else
|
||||
protected:
|
||||
/** do_util: not a command, but does the job of others
|
||||
* @param source The source of the command
|
||||
* @param com The command calling this function
|
||||
* @param cm A channel mode class
|
||||
* @param chan The channel its being set on
|
||||
* @param nick The nick the modes being set on
|
||||
* @param set Is the mode being set or removed
|
||||
* @param level The acecss level required to set this mode on someone else
|
||||
* @param levelself The access level required to set this mode on yourself
|
||||
* @param notice Flag required on a channel to send a notice
|
||||
*/
|
||||
CommandReturn do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, ChannelInfoFlag notice)
|
||||
{
|
||||
if (set)
|
||||
c->SetMode(NULL, cm, u2->nick);
|
||||
User *u = source.u;
|
||||
|
||||
if (chan.empty())
|
||||
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it)
|
||||
do_mode(source, com, cm, (*it)->chan->name, u->nick, set, level, levelself, notice);
|
||||
else
|
||||
c->RemoveMode(NULL, cm, u2->nick);
|
||||
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself, notice);
|
||||
|
||||
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
|
||||
if (notice && ci->HasFlag(notice))
|
||||
ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", name.c_str(), u2->nick.c_str(), u->nick.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
class CommandCSOp : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSOp() : Command("OP", 1, 2)
|
||||
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, int level, int levelself, ChannelInfoFlag notice)
|
||||
{
|
||||
}
|
||||
User *u = source.u;
|
||||
User *u2 = finduser(nick);
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci = c ? c->ci : NULL;
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
|
||||
bool is_same = u == u2;
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, "OP", CI_OPNOTICE);
|
||||
}
|
||||
ChanAccess *u_access = ci ? ci->GetAccess(u) : NULL, *u2_access = ci && u2 ? ci->GetAccess(u2) : NULL;
|
||||
uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0;
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_OP);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "OP", CHAN_OP_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_OP);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSDeOp : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSDeOp() : Command("DEOP", 1, 2)
|
||||
{
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, "DEOP", CI_OPNOTICE);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_DEOP);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "DEOP", CHAN_DEOP_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEOP);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSVoice : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSVoice() : Command("VOICE", 1, 2)
|
||||
{
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, "VOICE", CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_VOICE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "VOICE", CHAN_VOICE_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_VOICE);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSDeVoice : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSDeVoice() : Command("DEVOICE", 1, 2)
|
||||
{
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, "DEVOICE", CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_DEVOICE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "DEVOICE", CHAN_DEVOICE_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEVOICE);
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSHalfOp : public Command
|
||||
{
|
||||
public:
|
||||
CommandCSHalfOp() : Command("HALFOP", 1, 2)
|
||||
{
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
|
||||
|
||||
if (!cm)
|
||||
if (!c)
|
||||
source.Reply(_(CHAN_X_NOT_IN_USE), chan.c_str());
|
||||
else if (!ci)
|
||||
source.Reply(_(CHAN_X_NOT_REGISTERED), chan.c_str());
|
||||
else if (!u2)
|
||||
source.Reply(_(NICK_X_NOT_IN_USE), nick.c_str());
|
||||
else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level))
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level)
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!set && u2->IsProtected() && !is_same)
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
else if (!c->FindUser(u2))
|
||||
source.Reply(_(NICK_X_NOT_ON_CHAN), u2->nick.c_str(), c->name.c_str());
|
||||
else
|
||||
{
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (set)
|
||||
c->SetMode(NULL, cm, u2->nick);
|
||||
else
|
||||
c->RemoveMode(NULL, cm, u2->nick);
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, "HALFOP", CI_BEGIN);
|
||||
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
|
||||
if (notice && ci->HasFlag(notice))
|
||||
ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
|
||||
public:
|
||||
CommandModeBase(const Anope::string &cname) : Command(cname, 0, 2) { }
|
||||
};
|
||||
|
||||
class CommandCSOp : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSOp() : CommandModeBase("OP")
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_HALFOP);
|
||||
this->SetDesc(_("Gives Op status to a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
|
||||
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, CI_OPNOTICE);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002OP [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Ops a selected nick on a channel. If nick is not given,\n"
|
||||
"it will op you. If channel is not given, it will op you\n"
|
||||
"on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 access \n"
|
||||
"and above on the channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "HALFOP", CHAN_HALFOP_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_HALFOP);
|
||||
SyntaxError(source, "OP", _("OP [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSDeHalfOp : public Command
|
||||
class CommandCSDeOp : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSDeHalfOp() : Command("DEHALFOP", 1, 2)
|
||||
CommandCSDeOp() : CommandModeBase("DEOP")
|
||||
{
|
||||
this->SetDesc(_("Deops a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
|
||||
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, CI_OPNOTICE);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002DEOP [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Deops a selected nick on a channel. If nick is not given,\n"
|
||||
"it will deop you. If channel is not given, it will deop\n"
|
||||
"you on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 access \n"
|
||||
"and above on the channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "DEOP", _("DEOP [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSVoice : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSVoice() : CommandModeBase("VOICE")
|
||||
{
|
||||
this->SetDesc(_("Voices a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
|
||||
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002VOICE [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Voices a selected nick on a channel. If nick is not given,\n"
|
||||
"it will voice you. If channel is not given, it will voice you\n"
|
||||
"on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 access \n"
|
||||
"and above on the channel, or to VOPs or those with level 3 \n"
|
||||
"and above for self voicing."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "VOICE", _("VOICE [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSDeVoice : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSDeVoice() : CommandModeBase("DEVOICE")
|
||||
{
|
||||
this->SetDesc(_("Devoices a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
|
||||
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002DEVOICE [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Devoices a selected nick on a channel. If nick is not given,\n"
|
||||
"it will devoice you. If channel is not given, it will devoice\n"
|
||||
"you on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs or those with level 5 access \n"
|
||||
"and above on the channel, or to VOPs or those with level 3 \n"
|
||||
"and above for self devoicing."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "DEVOICE", _("DEVOICE [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSHalfOp : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSHalfOp() : CommandModeBase("HALFOP")
|
||||
{
|
||||
this->SetDesc(_("Halfops a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
|
||||
|
||||
if (!cm)
|
||||
return MOD_CONT;
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, "DEHALFOP", CI_BEGIN);
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_DEHALFOP);
|
||||
source.Reply(_("Syntax: \002HALFOP [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Halfops a selected nick on a channel. If nick is not given,\n"
|
||||
"it will halfop you. If channel is not given, it will halfop\n"
|
||||
"you on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs and those with level 5 access \n"
|
||||
"and above on the channel, or to HOPs or those with level 4 \n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "DEHALFOP", CHAN_DEHALFOP_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEHALFOP);
|
||||
SyntaxError(source, "HALFOP", _("HALFOP [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSProtect : public Command
|
||||
class CommandCSDeHalfOp : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSProtect() : Command("PROTECT", 1, 2)
|
||||
CommandCSDeHalfOp() : CommandModeBase("DEHALFOP")
|
||||
{
|
||||
this->SetDesc(_("Dehalfops a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP);
|
||||
|
||||
if (!cm)
|
||||
return MOD_CONT;
|
||||
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
source.Reply(_("Syntax: \002DEHALFOP [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Dehalfops a selected nick on a channel. If nick is not given,\n"
|
||||
"it will dehalfop you. If channel is not given, it will dehalfop\n"
|
||||
"you on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to AOPs and those with level 5 access \n"
|
||||
"and above on the channel, or to HOPs or those with level 4 \n"
|
||||
"and above for self dehalfopping."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(source, "DEHALFOP", _("DEHALFOP [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSProtect : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSProtect() : CommandModeBase("PROTECT")
|
||||
{
|
||||
this->SetDesc(_("Protects a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
|
||||
|
||||
if (!cm)
|
||||
return MOD_CONT;
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, "PROTECT", CI_BEGIN);
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_PROTECT);
|
||||
source.Reply(_("Syntax: \002PROTECT [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Protects a selected nick on a channel. If nick is not given,\n"
|
||||
"it will protect you. If channel is not given, it will protect\n"
|
||||
"you on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to the founder, or to SOPs or those with \n"
|
||||
"level 10 and above on the channel for self protecting."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "PROTECT", CHAN_PROTECT_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_PROTECT);
|
||||
SyntaxError(source, "PROTECT", _("PROTECT [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSDeProtect : public Command
|
||||
class CommandCSDeProtect : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSDeProtect() : Command("DEPROTECT", 1, 2)
|
||||
CommandCSDeProtect() : CommandModeBase("DEPROTECT")
|
||||
{
|
||||
this->SetDesc(_("Deprotects a selected nick on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT);
|
||||
|
||||
if (!cm)
|
||||
return MOD_CONT;
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, "DEPROTECT", CI_BEGIN);
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_DEPROTECT);
|
||||
source.Reply(_("Syntax: \002DEPROTECT [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Deprotects a selected nick on a channel. If nick is not given,\n"
|
||||
"it will deprotect you. If channel is not given, it will deprotect\n"
|
||||
"you on every channel.\n"
|
||||
" \n"
|
||||
"By default, limited to the founder, or to SOPs or those with \n"));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "DEPROTECT", CHAN_DEPROTECT_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEPROTECT);
|
||||
SyntaxError(source, "DEPROTECT", _("DEROTECT [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSOwner : public Command
|
||||
class CommandCSOwner : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSOwner() : Command("OWNER", 1, 2)
|
||||
CommandCSOwner() : CommandModeBase("OWNER")
|
||||
{
|
||||
this->SetDesc(_("Gives you owner status on channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
|
||||
|
||||
if (!cm)
|
||||
return MOD_CONT;
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, "OWNER", CI_BEGIN);
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_OWNER);
|
||||
source.Reply(_("Syntax: \002OWNER [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Gives the selected nick owner status on \002channel\002. If nick is not\n"
|
||||
"given, it will give you owner. If channel is not given, it will\n"
|
||||
"give you owner on every channel.\n"
|
||||
" \n"
|
||||
"Limited to those with founder access on the channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "OWNER", CHAN_OWNER_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_OWNER);
|
||||
SyntaxError(source, "OWNER", _("OWNER [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
class CommandCSDeOwner : public Command
|
||||
class CommandCSDeOwner : public CommandModeBase
|
||||
{
|
||||
public:
|
||||
CommandCSDeOwner() : Command("DEOWNER", 1, 2)
|
||||
CommandCSDeOwner() : CommandModeBase("DEOWNER")
|
||||
{
|
||||
this->SetDesc(_("Removes your owner status on a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER);
|
||||
|
||||
if (!cm)
|
||||
return MOD_CONT;
|
||||
|
||||
return do_util(u, this, cm, params[0], params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, "DEOWNER", CI_BEGIN);
|
||||
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, CI_BEGIN);
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_DEOWNER);
|
||||
source.Reply(_("Syntax: \002DEOWNER [\037#channel\037] [\037nick\037]\002\n"
|
||||
" \n"
|
||||
"Removes owner status from the selected nick on \002channel\002. If nick\n"
|
||||
"is not given, it will deowner you. If channel is not given, it will\n"
|
||||
"deowner you on every channel.\n"
|
||||
" \n"
|
||||
"Limited to those with founder access on the channel."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "DEOWNER", CHAN_DEOWNER_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_DEOWNER);
|
||||
SyntaxError(source, "DEOWNER", _("DEOWNER [\037#channel\037] [\037nick\037]\002"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -19,39 +19,39 @@ class CommandCSRegister : public Command
|
||||
CommandCSRegister() : Command("REGISTER", 2, 2)
|
||||
{
|
||||
this->SetFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL);
|
||||
this->SetDesc(_("Register a channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string chan = params[0];
|
||||
Anope::string desc = params[1];
|
||||
const Anope::string &chan = params[0];
|
||||
const Anope::string &chdesc = params[1];
|
||||
|
||||
User *u = source.u;
|
||||
ChannelInfo *ci = source.ci;
|
||||
Channel *c = findchan(chan);
|
||||
ChannelInfo *ci;
|
||||
ChannelMode *cm;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_REGISTER_DISABLED);
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
if (chan[0] == '&')
|
||||
u->SendMessage(ChanServ, CHAN_REGISTER_NOT_LOCAL);
|
||||
source.Reply(_("Sorry, channel registration is temporarily disabled."));
|
||||
else if (u->Account()->HasFlag(NI_UNCONFIRMED))
|
||||
source.Reply(_("You must confirm your account before you can register a channel."));
|
||||
else if (chan[0] == '&')
|
||||
source.Reply(_("Local channels cannot be registered."));
|
||||
else if (chan[0] != '#')
|
||||
u->SendMessage(ChanServ, CHAN_SYMBOL_REQUIRED);
|
||||
source.Reply(_(CHAN_SYMBOL_REQUIRED));
|
||||
else if (!ircdproto->IsChannelValid(chan))
|
||||
u->SendMessage(ChanServ, CHAN_X_INVALID, chan.c_str());
|
||||
else if ((ci = cs_findchan(chan)))
|
||||
u->SendMessage(ChanServ, CHAN_ALREADY_REGISTERED, chan.c_str());
|
||||
source.Reply(_(CHAN_X_INVALID), chan.c_str());
|
||||
else if (ci)
|
||||
source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
|
||||
else if (c && !c->HasUserStatus(u, CMODE_OP))
|
||||
u->SendMessage(ChanServ, CHAN_MUST_BE_CHANOP);
|
||||
else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
|
||||
u->SendMessage(ChanServ, u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg);
|
||||
source.Reply(_("You must be a channel operator to register the channel."));
|
||||
else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
|
||||
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? _(CHAN_EXCEEDED_CHANNEL_LIMIT) : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
|
||||
else
|
||||
{
|
||||
ci = new ChannelInfo(chan);
|
||||
ci->founder = u->Account();
|
||||
ci->desc = desc;
|
||||
ci->desc = chdesc;
|
||||
|
||||
if (c && !c->topic.empty())
|
||||
{
|
||||
@@ -65,17 +65,22 @@ class CommandCSRegister : public Command
|
||||
ci->bi = NULL;
|
||||
++ci->founder->channelcount;
|
||||
Log(LOG_COMMAND, u, this, ci);
|
||||
u->SendMessage(ChanServ, CHAN_REGISTERED, chan.c_str(), u->nick.c_str());
|
||||
source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str());
|
||||
|
||||
/* Implement new mode lock */
|
||||
if (c)
|
||||
{
|
||||
check_modes(c);
|
||||
/* On most ircds you do not receive the admin/owner mode till its registered */
|
||||
if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
|
||||
c->SetMode(NULL, cm, u->nick);
|
||||
else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
|
||||
c->RemoveMode(NULL, cm, u->nick);
|
||||
|
||||
ChannelMode *cm;
|
||||
if (u->FindChannel(c) != NULL)
|
||||
{
|
||||
/* On most ircds you do not receive the admin/owner mode till its registered */
|
||||
if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER)))
|
||||
c->SetMode(NULL, cm, u->nick);
|
||||
else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT)))
|
||||
c->RemoveMode(NULL, cm, u->nick);
|
||||
}
|
||||
|
||||
/* Mark the channel as persistant */
|
||||
if (c->HasMode(CMODE_PERM))
|
||||
@@ -90,15 +95,35 @@ class CommandCSRegister : public Command
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_REGISTER, Config->s_ChanServ.c_str());
|
||||
source.Reply(_("Syntax: \002REGISTER \037channel\037 \037description\037\002\n"
|
||||
" \n"
|
||||
"Registers a channel in the %s database. In order\n"
|
||||
"to use this command, you must first be a channel operator\n"
|
||||
"on the channel you're trying to register.\n"
|
||||
"The description, which \002must\002 be included, is a\n"
|
||||
"general description of the channel's purpose.\n"
|
||||
" \n"
|
||||
"When you register a channel, you are recorded as the\n"
|
||||
"\"founder\" of the channel. The channel founder is allowed\n"
|
||||
"to change all of the channel settings for the channel;\n"
|
||||
"%s will also automatically give the founder\n"
|
||||
"channel-operator privileges when s/he enters the channel.\n"
|
||||
"See the \002ACCESS\002 command (\002%s%s HELP ACCESS\002) for\n"
|
||||
"information on giving a subset of these privileges to\n"
|
||||
"other channel users.\n"
|
||||
" \n"
|
||||
"NOTICE: In order to register a channel, you must have\n"
|
||||
"first registered your nickname. If you haven't,\n"
|
||||
"\002%s%s HELP\002 for information on how to do so."),
|
||||
ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX);
|
||||
SyntaxError(source, "REGISTER", _("REGISTER \037channel\037 \037description\037"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+33
-20
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -21,6 +21,7 @@ class CommandCSSASet : public Command
|
||||
public:
|
||||
CommandCSSASet() : Command("SASET", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Forcefully set channel options and information"));
|
||||
}
|
||||
|
||||
~CommandCSSASet()
|
||||
@@ -28,11 +29,20 @@ class CommandCSSASet : public Command
|
||||
this->subcommands.clear();
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_SET_DISABLED);
|
||||
source.Reply(_(CHAN_SET_DISABLED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
// XXX Remove after 1.9.4 release
|
||||
if (params[1].equals_ci("MLOCK"))
|
||||
{
|
||||
source.Reply(_(CHAN_SET_MLOCK_DEPRECATED), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -40,30 +50,36 @@ class CommandCSSASet : public Command
|
||||
|
||||
if (c)
|
||||
{
|
||||
ChannelInfo *ci = cs_findchan(params[0]);
|
||||
ChannelInfo *ci = source.ci;
|
||||
Anope::string cmdparams = ci->name;
|
||||
for (std::vector<Anope::string>::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it)
|
||||
cmdparams += " " + *it;
|
||||
Log(LOG_ADMIN, u, this, ci) << params[1] << " " << cmdparams;
|
||||
mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
|
||||
mod_run_cmd(ChanServ, u, NULL, c, params[1], cmdparams);
|
||||
}
|
||||
else
|
||||
{
|
||||
u->SendMessage(ChanServ, NICK_SET_UNKNOWN_OPTION, params[1].c_str());
|
||||
u->SendMessage(ChanServ, MORE_INFO, Config->s_ChanServ.c_str(), "SET");
|
||||
source.Reply(_("Unknown SASET option \002%s\002."), params[1].c_str());
|
||||
source.Reply(_(MORE_INFO), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), "SET");
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
if (subcommand.empty())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SASET_HEAD);
|
||||
source.Reply(_("Syntax: SASET \002channel\002 \037option\037 \037parameters\037\n"
|
||||
" \n"
|
||||
"Allows Services Operators to forcefully change settings\n"
|
||||
"on channels.\n"
|
||||
" \n"
|
||||
"Available options:"));
|
||||
for (subcommand_map::iterator it = this->subcommands.begin(), it_end = this->subcommands.end(); it != it_end; ++it)
|
||||
it->second->OnServHelp(u);
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SASET_TAIL);
|
||||
it->second->OnServHelp(source);
|
||||
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information on a\n"
|
||||
"particular option."), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -71,24 +87,21 @@ class CommandCSSASet : public Command
|
||||
Command *c = this->FindCommand(subcommand);
|
||||
|
||||
if (c)
|
||||
return c->OnHelp(u, subcommand);
|
||||
return c->OnHelp(source, subcommand);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
|
||||
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_SASET);
|
||||
}
|
||||
|
||||
bool AddSubcommand(Command *c)
|
||||
bool AddSubcommand(Module *creator, Command *c)
|
||||
{
|
||||
c->module = creator;
|
||||
c->service = this->service;
|
||||
return this->subcommands.insert(std::make_pair(c->name, c)).second;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,44 +18,43 @@ class CommandCSSASetNoexpire : public Command
|
||||
public:
|
||||
CommandCSSASetNoexpire() : Command("NOEXPIRE", 2, 2, "chanserv/saset/noexpire")
|
||||
{
|
||||
this->SetDesc(_("Prevent the channel from expiring"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci = cs_findchan(params[0]);
|
||||
ChannelInfo *ci = source.ci;
|
||||
if (!ci)
|
||||
throw CoreException("NULL ci in CommandCSSASetNoexpire");
|
||||
|
||||
if (params[1].equals_ci("ON"))
|
||||
{
|
||||
ci->SetFlag(CI_NO_EXPIRE);
|
||||
u->SendMessage(ChanServ, CHAN_SET_NOEXPIRE_ON, ci->name.c_str());
|
||||
source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str());
|
||||
}
|
||||
else if (params[1].equals_ci("OFF"))
|
||||
{
|
||||
ci->UnsetFlag(CI_NO_EXPIRE);
|
||||
u->SendMessage(ChanServ, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str());
|
||||
source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str());
|
||||
}
|
||||
else
|
||||
this->OnSyntaxError(u, "NOEXPIRE");
|
||||
this->OnSyntaxError(source, "NOEXPIRE");
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_SERVADMIN_HELP_SET_NOEXPIRE);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 NOEXPIRE {ON | OFF}\002\n"
|
||||
" \n"
|
||||
"Sets whether the given channel will expire. Setting this\n"
|
||||
"to ON prevents the channel from expiring."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "SET NOEXPIRE", CHAN_SET_NOEXPIRE_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET_NOEXPIRE);
|
||||
SyntaxError(source, "SET NOEXPIRE", _("SET \037channel\037 NOEXPIRE {ON | OFF}"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,7 +70,7 @@ class CSSetNoexpire : public Module
|
||||
|
||||
Command *c = FindCommand(ChanServ, "SASET");
|
||||
if (c)
|
||||
c->AddSubcommand(&commandcssasetnoexpire);
|
||||
c->AddSubcommand(this, &commandcssasetnoexpire);
|
||||
}
|
||||
|
||||
~CSSetNoexpire()
|
||||
|
||||
+34
-21
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -21,6 +21,7 @@ class CommandCSSet : public Command
|
||||
public:
|
||||
CommandCSSet() : Command("SET", 2, 3)
|
||||
{
|
||||
this->SetDesc(_("Set channel options and information"));
|
||||
}
|
||||
|
||||
~CommandCSSet()
|
||||
@@ -28,16 +29,25 @@ class CommandCSSet : public Command
|
||||
this->subcommands.clear();
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
User *u = source.u;
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_SET_DISABLED);
|
||||
source.Reply(_(CHAN_SET_DISABLED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
if (!check_access(u, cs_findchan(params[0]), CA_SET))
|
||||
{
|
||||
u->SendMessage(ChanServ, ACCESS_DENIED);
|
||||
source.Reply(_(ACCESS_DENIED));
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
// XXX Remove after 1.9.4 release
|
||||
if (params[1].equals_ci("MLOCK"))
|
||||
{
|
||||
source.Reply(_(CHAN_SET_MLOCK_DEPRECATED), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
@@ -45,29 +55,35 @@ class CommandCSSet : public Command
|
||||
|
||||
if (c)
|
||||
{
|
||||
ChannelInfo *ci = cs_findchan(params[0]);
|
||||
ChannelInfo *ci = source.ci;
|
||||
Anope::string cmdparams = ci->name;
|
||||
for (std::vector<Anope::string>::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it)
|
||||
cmdparams += " " + *it;
|
||||
mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
|
||||
mod_run_cmd(ChanServ, u, NULL, c, params[1], cmdparams);
|
||||
}
|
||||
else
|
||||
{
|
||||
u->SendMessage(ChanServ, NICK_SET_UNKNOWN_OPTION, params[1].c_str());
|
||||
u->SendMessage(ChanServ, MORE_INFO, Config->s_ChanServ.c_str(), "SET");
|
||||
source.Reply(_(NICK_SET_UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), params[1].c_str());
|
||||
source.Reply(_(MORE_INFO), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), "SET");
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &subcommand)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
if (subcommand.empty())
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SET_HEAD);
|
||||
source.Reply(_("Syntax: \002SET \037channel\037 \037option\037 \037parameters\037\002\n"
|
||||
" \n"
|
||||
"Allows the channel founder to set various channel options\n"
|
||||
"and other information.\n"
|
||||
" \n"
|
||||
"Available options:"));
|
||||
for (subcommand_map::iterator it = this->subcommands.begin(), it_end = this->subcommands.end(); it != it_end; ++it)
|
||||
it->second->OnServHelp(u);
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SET_TAIL);
|
||||
it->second->OnServHelp(source);
|
||||
source.Reply(_("Type \002%s%s HELP SET \037option\037\002 for more information on a\n"
|
||||
"particular option."), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -75,24 +91,21 @@ class CommandCSSet : public Command
|
||||
Command *c = this->FindCommand(subcommand);
|
||||
|
||||
if (c)
|
||||
return c->OnHelp(u, subcommand);
|
||||
return c->OnHelp(source, subcommand);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &subcommand)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
|
||||
{
|
||||
SyntaxError(ChanServ, u, "SET", CHAN_SET_SYNTAX);
|
||||
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET);
|
||||
}
|
||||
|
||||
bool AddSubcommand(Command *c)
|
||||
bool AddSubcommand(Module *creator, Command *c)
|
||||
{
|
||||
c->module = creator;
|
||||
c->service = this->service;
|
||||
return this->subcommands.insert(std::make_pair(c->name, c)).second;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,44 +18,48 @@ class CommandCSSetBanType : public Command
|
||||
public:
|
||||
CommandCSSetBanType(const Anope::string &cpermission = "") : Command("BANTYPE", 2, 2, cpermission)
|
||||
{
|
||||
this->SetDesc(_("Set how Services make bans on the channel"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci = cs_findchan(params[0]);
|
||||
ChannelInfo *ci = source.ci;
|
||||
if (!ci)
|
||||
throw CoreException("NULL ci in CommandCSSetBanType");
|
||||
|
||||
Anope::string end;
|
||||
|
||||
int16 bantype = convertTo<int16>(params[1], end, false);
|
||||
|
||||
if (!end.empty() || bantype < 0 || bantype > 3)
|
||||
u->SendMessage(ChanServ, CHAN_SET_BANTYPE_INVALID, params[1].c_str());
|
||||
else
|
||||
try
|
||||
{
|
||||
ci->bantype = bantype;
|
||||
u->SendMessage(ChanServ, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(), ci->bantype);
|
||||
ci->bantype = convertTo<int16>(params[1]);
|
||||
source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype);
|
||||
}
|
||||
catch (const ConvertException &)
|
||||
{
|
||||
source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str());
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SET_BANTYPE, "SET");
|
||||
source.Reply(_("Syntax: \002%s \037channel\037 BANTYPE \037bantype\037\002\n"
|
||||
" \n"
|
||||
"Sets the ban type that will be used by services whenever\n"
|
||||
"they need to ban someone from your channel.\n"
|
||||
" \n"
|
||||
"bantype is a number between 0 and 3 that means:\n"
|
||||
" \n"
|
||||
"0: ban in the form *!user@host\n"
|
||||
"1: ban in the form *!*user@host\n"
|
||||
"2: ban in the form *!*@host\n"
|
||||
"3: ban in the form *!*user@*.domain"), this->name.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
// XXX
|
||||
SyntaxError(ChanServ, u, "SET", CHAN_SET_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET_BANTYPE);
|
||||
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,16 +70,10 @@ class CommandCSSASetBanType : public CommandCSSetBanType
|
||||
{
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SET_BANTYPE, "SASET");
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
// XXX
|
||||
SyntaxError(ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
|
||||
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,11 +90,11 @@ class CSSetBanType : public Module
|
||||
|
||||
Command *c = FindCommand(ChanServ, "SET");
|
||||
if (c)
|
||||
c->AddSubcommand(&commandcssetbantype);
|
||||
c->AddSubcommand(this, &commandcssetbantype);
|
||||
|
||||
c = FindCommand(ChanServ, "SASET");
|
||||
if (c)
|
||||
c->AddSubcommand(&commandcssasetbantype);
|
||||
c->AddSubcommand(this, &commandcssasetbantype);
|
||||
}
|
||||
|
||||
~CSSetBanType()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ChanServ core functions
|
||||
*
|
||||
* (C) 2003-2010 Anope Team
|
||||
* (C) 2003-2011 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
@@ -18,36 +18,35 @@ class CommandCSSetDescription : public Command
|
||||
public:
|
||||
CommandCSSetDescription(const Anope::string &cpermission = "") : Command("DESC", 2, 2, cpermission)
|
||||
{
|
||||
this->SetDesc(_("Set the channel description"));
|
||||
}
|
||||
|
||||
CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms)
|
||||
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
ChannelInfo *ci = cs_findchan(params[0]);
|
||||
ChannelInfo *ci = source.ci;
|
||||
if (!ci)
|
||||
throw CoreException("NULL ci in CommandCSSetDescription");
|
||||
|
||||
ci->desc = params[1];
|
||||
|
||||
u->SendMessage(ChanServ, CHAN_DESC_CHANGED, ci->name.c_str(), ci->desc.c_str());
|
||||
source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str());
|
||||
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &)
|
||||
bool OnHelp(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SET_DESC, "SET");
|
||||
source.Reply(_("Syntax: \002%s \037channel\037 DESC \037description\037\002\n"
|
||||
" \n"
|
||||
"Sets the description for the channel, which shows up with\n"
|
||||
"the \002LIST\002 and \002INFO\002 commands."), this->name.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
// XXX
|
||||
SyntaxError(ChanServ, u, "SET", CHAN_SET_SYNTAX);
|
||||
}
|
||||
|
||||
void OnServHelp(User *u)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_CMD_SET_DESC);
|
||||
SyntaxError(source, "SET", _(CHAN_SET_SYNTAX));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,16 +57,10 @@ class CommandCSSASetDescription : public CommandCSSetDescription
|
||||
{
|
||||
}
|
||||
|
||||
bool OnHelp(User *u, const Anope::string &)
|
||||
{
|
||||
u->SendMessage(ChanServ, CHAN_HELP_SET_DESC, "SASET");
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnSyntaxError(User *u, const Anope::string &)
|
||||
void OnSyntaxError(CommandSource &source, const Anope::string &)
|
||||
{
|
||||
// XXX
|
||||
SyntaxError(ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
|
||||
SyntaxError(source, "SASET", _(CHAN_SASET_SYNTAX));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -84,11 +77,11 @@ class CSSetDescription : public Module
|
||||
|
||||
Command *c = FindCommand(ChanServ, "SET");
|
||||
if (c)
|
||||
c->AddSubcommand(&commandcssetdescription);
|
||||
c->AddSubcommand(this, &commandcssetdescription);
|
||||
|
||||
c = FindCommand(ChanServ, "SASET");
|
||||
if (c)
|
||||
c->AddSubcommand(&commandcssasetdescription);
|
||||
c->AddSubcommand(this, &commandcssasetdescription);
|
||||
}
|
||||
|
||||
~CSSetDescription()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user